Ejemplo n.º 1
0
 private bool AddTransaction(Transaction tx, bool verify)
 {
     if (Blockchain.Default.ContainsTransaction(tx.Hash) ||
         (verify && !tx.Verify(context.Transactions.Values)) ||
         !CheckPolicy(tx))
     {
         Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}");
         RequestChangeView();
         return(false);
     }
     context.Transactions[tx.Hash] = tx;
     if (context.TransactionHashes.Length == context.Transactions.Count)
     {
         if (Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(context.Transactions.Values).ToArray()).Equals(context.NextConsensus))
         {
             Log($"send perpare response");
             // 设置共识状态为已发送签名
             context.State |= ConsensusState.SignatureSent;
             // 添加本地签名到签名列表
             context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
             // 广播共识响应
             SignAndRelay(context.MakePrepareResponse(context.Signatures[context.MyIndex]));
             // 检查签名状态是否符合共识要求
             CheckSignatures();
         }
         else
         {
             RequestChangeView();
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 2
0
 private bool AddTransaction(Transaction tx, bool verify)
 {
     if (context.Snapshot.ContainsTransaction(tx.Hash) ||
         (verify && !tx.Verify(context.Snapshot, context.Transactions.Values)) ||
         !Plugin.CheckPolicy(tx))
     {
         Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
         RequestChangeView();
         return(false);
     }
     context.Transactions[tx.Hash] = tx;
     if (context.TransactionHashes.Length == context.Transactions.Count)
     {
         if (context.VerifyRequest())
         {
             Log($"send prepare response");
             context.State |= ConsensusState.SignatureSent;
             context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
             SignAndRelay(context.MakePrepareResponse(context.Signatures[context.MyIndex]));
             CheckSignatures();
         }
         else
         {
             RequestChangeView();
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 3
0
        private void OnTimer(Timer timer)
        {
            if (timer.Height != context.BlockIndex || timer.ViewNumber != context.ViewNumber)
            {
                return;
            }
            Log($"timeout: height={timer.Height} view={timer.ViewNumber} state={context.State}");

            Log($"send prepare request: height={timer.Height} view={timer.ViewNumber}");
            {
                FillContext();
                context.Timestamp = Math.Max(DateTime.UtcNow.ToTimestamp(), context.Snapshot.GetHeader(context.PrevHash).Timestamp + 1);
                context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
                if (context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
                {
                    Contract contract            = Contract.CreateSignatureContract(context.Validators[0]);
                    Block    block               = context.MakeHeader();
                    ContractParametersContext sc = new ContractParametersContext(block);
                    wallet.Sign(sc);
                    sc.Verifiable.Witnesses = sc.GetWitnesses();
                    block.Transactions      = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray();
                    Log($"relay block: {block.Hash}");
                    system.LocalNode.Tell(new LocalNode.Relay {
                        Inventory = block
                    });
                }
            }
            ChangeTimer(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer.ViewNumber + 1)));
        }
Ejemplo n.º 4
0
        private bool AddTransaction(Transaction tx, bool verify)
        {
            ReportNeoBlockchain reportObj = new ReportNeoBlockchain("[NeoConsensusService-AddTransaction]");

            if (Blockchain.Default.ContainsTransaction(tx.Hash) ||
                (verify && !tx.Verify(context.Transactions.Values)) ||
                !CheckPolicy(tx))
            {
                Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}");
                RequestChangeView();
                return(false);
            }
            context.Transactions[tx.Hash] = tx;
            if (context.TransactionHashes.Length == context.Transactions.Count)
            {
                if (Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(context.Transactions.Values).ToArray()).Equals(context.NextConsensus))
                {
                    Log($"send perpare response");
                    context.State |= ConsensusState.SignatureSent;
                    context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
                    SignAndRelay(context.MakePrepareResponse(context.Signatures[context.MyIndex]));
                    CheckSignatures();
                }
                else
                {
                    RequestChangeView();
                    return(false);
                }
            }

            reportObj.appendElapsedTime();
            return(true);
        }
Ejemplo n.º 5
0
        private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message)
        {
            if (context.State.HasFlag(ConsensusState.RequestReceived))
            {
                return;
            }
            if (payload.ValidatorIndex != context.PrimaryIndex)
            {
                return;
            }
            Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}");
            if (!context.State.HasFlag(ConsensusState.Backup))
            {
                return;
            }
            if (payload.Timestamp <= context.Snapshot.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.UtcNow.AddMinutes(10).ToTimestamp())
            {
                Log($"Timestamp incorrect: {payload.Timestamp}", LogLevel.Warning);
                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>();
            byte[] hashData = context.MakeHeader().GetHashData();
            if (!Crypto.Default.VerifySignature(hashData, message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false)))
            {
                return;
            }
            for (int i = 0; i < context.Signatures.Length; i++)
            {
                if (context.Signatures[i] != null)
                {
                    if (!Crypto.Default.VerifySignature(hashData, context.Signatures[i], context.Validators[i].EncodePoint(false)))
                    {
                        context.Signatures[i] = null;
                    }
                }
            }
            context.Signatures[payload.ValidatorIndex] = message.Signature;
            Dictionary <UInt256, Transaction> mempool = Blockchain.Singleton.GetMemoryPool().ToDictionary(p => p.Hash);
            List <Transaction> unverified             = new List <Transaction>();

            foreach (UInt256 hash in context.TransactionHashes.Skip(1))
            {
                if (mempool.TryGetValue(hash, out Transaction tx))
                {
                    if (!AddTransaction(tx, false))
                    {
                        return;
                    }
                }
                else
                {
                    tx = Blockchain.Singleton.GetUnverifiedTransaction(hash);
                    if (tx != null)
                    {
                        unverified.Add(tx);
                    }
                }
            }
            foreach (Transaction tx in unverified)
            {
                if (!AddTransaction(tx, true))
                {
                    return;
                }
            }
            if (!AddTransaction(message.MinerTransaction, true))
            {
                return;
            }
            if (context.Transactions.Count < context.TransactionHashes.Length)
            {
                UInt256[] hashes = context.TransactionHashes.Where(i => !context.Transactions.ContainsKey(i)).ToArray();
                system.TaskManager.Tell(new TaskManager.RestartTasks
                {
                    Payload = InvPayload.Create(InventoryType.TX, hashes)
                });
            }
        }