Esempio n. 1
0
        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();
            }
        }
Esempio n. 3
0
        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();
            }
        }