private async Task SendConsensusRequestAsync() { if (!context.Valid) { return; } BlockConsensusRequest request = context.CreateRequest(wallet); //TODO: 签名 //request.Script = wallet.Sign(request); await localnode.RelayAsync(request); }
private async void StartMine(CancellationToken token) { while (wallet == null && !token.IsCancellationRequested) { await Task.Delay(100); } while (!token.IsCancellationRequested) { ECPoint[] miners = Blockchain.Default.GetMiners(); bool is_miner = false; foreach (Account account in wallet.GetAccounts()) { if (miners.Contains(account.PublicKey)) { is_miner = true; break; } } if (!is_miner) { try { await Task.Delay(Blockchain.TimePerBlock, token); } catch (TaskCanceledException) { } continue; } Block header = Blockchain.Default.GetHeader(Blockchain.Default.CurrentBlockHash); if (header == null) { continue; } TimeSpan timespan = header.Timestamp.ToDateTime() + Blockchain.TimePerBlock - DateTime.Now; if (timespan > TimeSpan.Zero) { try { await Task.Delay(timespan, token); } catch (TaskCanceledException) { } if (token.IsCancellationRequested) { break; } } byte[] nonce_data = new byte[sizeof(ulong)]; using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { rng.GetBytes(nonce_data); } ulong nonce = BitConverter.ToUInt64(nonce_data, 0); List <Transaction> transactions = Blockchain.Default.GetMemoryPool().ToList(); transactions.Insert(0, CreateGenerationTransaction(transactions, header.Height + 1, nonce)); Block block = new Block { PrevBlock = header.Hash, Timestamp = DateTime.Now.ToTimestamp(), Height = header.Height + 1, Nonce = nonce, NextMiner = Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(transactions).ToArray()), Transactions = transactions.ToArray() }; block.RebuildMerkleRoot(); wallet.Sign(block, miners); await LocalNode.RelayAsync(block); while (Blockchain.Default.CurrentBlockHash != block.Hash && !token.IsCancellationRequested) { await Task.Delay(100, token); } } stopped = true; }