private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message) { TR.Enter(); Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}"); if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived)) { TR.Exit(); return; } if (payload.ValidatorIndex != context.PrimaryIndex) { return; } if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp()) { Log($"Timestamp incorrect: {payload.Timestamp}"); TR.Exit(); return; } context.State |= ConsensusState.RequestReceived; context.Timestamp = payload.Timestamp; context.Nonce = message.Nonce; context.NextConsensus = message.NextConsensus; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary <UInt256, Transaction>(); if (!Crypto.Default.VerifySignature(context.MakeHeader().GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) { TR.Exit(); return; } context.Signatures = new byte[context.Validators.Length][]; context.Signatures[payload.ValidatorIndex] = message.Signature; Dictionary <UInt256, Transaction> mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash); foreach (UInt256 hash in context.TransactionHashes.Skip(1)) { if (mempool.TryGetValue(hash, out Transaction tx)) { if (!AddTransaction(tx, false)) { TR.Exit(); return; } } } if (!AddTransaction(message.MinerTransaction, true)) { TR.Exit(); return; } if (context.Transactions.Count < context.TransactionHashes.Length) { UInt256[] hashes = context.TransactionHashes.Where(i => !context.Transactions.ContainsKey(i)).ToArray(); LocalNode.AllowHashes(hashes); InvPayload msg = InvPayload.Create(InventoryType.TX, hashes); foreach (RemoteNode node in localNode.GetRemoteNodes()) { node.EnqueueMessage("getdata", msg); } } TR.Exit(); }
private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message) { Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}"); if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived)) { return; } if (payload.ValidatorIndex != context.PrimaryIndex) { return; } if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp()) { Log($"Timestamp incorrect: {payload.Timestamp}"); return; } context.State |= ConsensusState.RequestReceived; context.Timestamp = payload.Timestamp; context.Nonce = message.Nonce; context.CurrentConsensus = message.CurrentConsensus; context.NextConsensus = message.NextConsensus; context.TransactionHashes = message.TransactionHashes; if (context.TransactionHashes.Length > MaxTransactionsPerBlock) { return; } context.Transactions = new Dictionary <UInt256, Transaction>(); if (!Crypto.Default.VerifySignature(context.MakeHeader().GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) { return; } context.Signatures = new byte[context.Validators.Length][]; context.Signatures[payload.ValidatorIndex] = message.Signature; Dictionary <UInt256, Transaction> mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash); foreach (UInt256 hash in context.TransactionHashes.Skip(1)) { if (mempool.TryGetValue(hash, out Transaction tx)) { if (!AddTransaction(tx, false)) { return; } } } if (!AddTransaction(message.MinerTransaction, true)) { return; } LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys)); if (context.Transactions.Count < context.TransactionHashes.Length) { localNode.SynchronizeMemoryPool(); } }
private void OnPerpareRequestReceived(ConsensusPayload payload, PerpareRequest message) { Log($"{nameof(OnPerpareRequestReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex} tx:{message.TransactionHashes.Length}"); if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived)) { return; } if (payload.MinerIndex != context.PrimaryIndex) { return; } if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp()) { Log($"Timestamp incorrect:{payload.Timestamp}"); return; } context.State |= ConsensusState.RequestReceived; context.Timestamp = payload.Timestamp; context.Nonce = message.Nonce; context.NextMiner = message.NextMiner; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary <UInt256, Transaction>(); if (!context.MakeHeader().VerifySignature(context.Miners[payload.MinerIndex], message.Signature)) { return; } context.Signatures = new byte[context.Miners.Length][]; context.Signatures[payload.MinerIndex] = message.Signature; if (!AddTransaction(message.MinerTransaction)) { return; } Dictionary <UInt256, Transaction> mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash); foreach (UInt256 hash in context.TransactionHashes.Skip(1)) { if (mempool.ContainsKey(hash)) { if (!AddTransaction(mempool[hash])) { return; } } } LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys)); if (context.Transactions.Count < context.TransactionHashes.Length) { LocalNode.SynchronizeMemoryPool(); } }