From 6dbc4156be032c66736e9736878f3cd8c138d2b1 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Fri, 11 Nov 2016 23:03:22 +0800 Subject: [PATCH] fix bug of tx verification --- src/AntShares/Consensus/ConsensusService.cs | 5 ++--- src/AntShares/Core/AgencyTransaction.cs | 4 ++-- src/AntShares/Core/Block.cs | 2 +- src/AntShares/Core/ClaimTransaction.cs | 6 ++++-- src/AntShares/Core/IssueTransaction.cs | 15 ++++----------- src/AntShares/Core/Transaction.cs | 9 ++++++++- src/AntShares/Network/LocalNode.cs | 12 +----------- src/AntShares/project.json | 2 +- 8 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/AntShares/Consensus/ConsensusService.cs b/src/AntShares/Consensus/ConsensusService.cs index 32cc412b58..599a27c74e 100644 --- a/src/AntShares/Consensus/ConsensusService.cs +++ b/src/AntShares/Consensus/ConsensusService.cs @@ -34,9 +34,8 @@ public ConsensusService(LocalNode localNode, Wallet wallet, string log_dictionar private bool AddTransaction(Transaction tx) { - if (context.Transactions.SelectMany(p => p.Value.GetAllInputs()).Intersect(tx.GetAllInputs()).Count() > 0 || - Blockchain.Default.ContainsTransaction(tx.Hash) || - !tx.Verify() || + if (Blockchain.Default.ContainsTransaction(tx.Hash) || + !tx.Verify(context.Transactions.Values) || !CheckPolicy(tx)) { Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}"); diff --git a/src/AntShares/Core/AgencyTransaction.cs b/src/AntShares/Core/AgencyTransaction.cs index a0a788abc7..c533ddf0da 100644 --- a/src/AntShares/Core/AgencyTransaction.cs +++ b/src/AntShares/Core/AgencyTransaction.cs @@ -141,9 +141,9 @@ protected override void SerializeExclusiveData(BinaryWriter writer) /// 验证交易 /// /// 返回验证的结果 - public override bool Verify() + public override bool Verify(IEnumerable mempool) { - if (!base.Verify()) return false; + if (!base.Verify(mempool)) return false; foreach (Order order in Orders) if (!order.VerifySignature()) return false; diff --git a/src/AntShares/Core/Block.cs b/src/AntShares/Core/Block.cs index b4410e9c2e..697505e1a8 100644 --- a/src/AntShares/Core/Block.cs +++ b/src/AntShares/Core/Block.cs @@ -187,7 +187,7 @@ public bool Verify(bool completely) if (NextMiner != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) return false; foreach (Transaction tx in Transactions) - if (!tx.Verify()) return false; + if (!tx.Verify(Transactions.Where(p => !p.Hash.Equals(tx.Hash)))) return false; Transaction tx_gen = Transactions.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction); if (tx_gen?.Outputs.Sum(p => p.Value) != CalculateNetFee(Transactions)) return false; } diff --git a/src/AntShares/Core/ClaimTransaction.cs b/src/AntShares/Core/ClaimTransaction.cs index 76d24b25b9..a4d9f9d845 100644 --- a/src/AntShares/Core/ClaimTransaction.cs +++ b/src/AntShares/Core/ClaimTransaction.cs @@ -81,9 +81,11 @@ public override JObject ToJson() /// 验证交易 /// /// 返回验证结果 - public override bool Verify() + public override bool Verify(IEnumerable mempool) { - if (!base.Verify()) return false; + if (!base.Verify(mempool)) return false; + if (mempool.OfType().SelectMany(p => p.Claims).Intersect(Claims).Count() > 0) + return false; TransactionResult result = GetTransactionResults().FirstOrDefault(p => p.AssetId == Blockchain.AntCoin.Hash); if (result == null || result.Amount > Fixed8.Zero) return false; try diff --git a/src/AntShares/Core/IssueTransaction.cs b/src/AntShares/Core/IssueTransaction.cs index 44fe353fbb..69209e1f92 100644 --- a/src/AntShares/Core/IssueTransaction.cs +++ b/src/AntShares/Core/IssueTransaction.cs @@ -1,5 +1,4 @@ -using AntShares.Network; -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -52,14 +51,9 @@ public override UInt160[] GetScriptHashesForVerifying() /// 验证交易 /// /// 返回验证后的结果 - public override bool Verify() + public override bool Verify(IEnumerable mempool) { - return Verify(false); - } - - internal bool Verify(bool mempool) - { - if (!base.Verify()) return false; + if (!base.Verify(mempool)) return false; TransactionResult[] results = GetTransactionResults()?.Where(p => p.Amount < Fixed8.Zero).ToArray(); if (results == null) return false; foreach (TransactionResult r in results) @@ -70,8 +64,7 @@ internal bool Verify(bool mempool) if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.Statistics)) return false; Fixed8 quantity_issued = Blockchain.Default.GetQuantityIssued(r.AssetId); - if (mempool) - quantity_issued += LocalNode.GetMemoryPool().OfType().SelectMany(p => p.Outputs).Where(p => p.AssetId == r.AssetId).Sum(p => p.Value); + quantity_issued += mempool.OfType().SelectMany(p => p.Outputs).Where(p => p.AssetId == r.AssetId).Sum(p => p.Value); if (tx.Amount - quantity_issued < -r.Amount) return false; } return true; diff --git a/src/AntShares/Core/Transaction.cs b/src/AntShares/Core/Transaction.cs index 20205ea00d..339fefb414 100644 --- a/src/AntShares/Core/Transaction.cs +++ b/src/AntShares/Core/Transaction.cs @@ -316,15 +316,22 @@ public virtual JObject ToJson() return json; } + bool IInventory.Verify() + { + return Verify(Enumerable.Empty()); + } + /// /// 验证交易 /// /// 返回验证的结果 - public virtual bool Verify() + public virtual bool Verify(IEnumerable mempool) { if (Blockchain.Default.ContainsTransaction(Hash)) return true; if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes)) return false; + if (mempool.SelectMany(p => p.GetAllInputs()).Intersect(GetAllInputs()).Count() > 0) + return false; if (Blockchain.Default.IsDoubleSpend(this)) return false; foreach (var group in Outputs.GroupBy(p => p.AssetId)) diff --git a/src/AntShares/Network/LocalNode.cs b/src/AntShares/Network/LocalNode.cs index 7219682db9..c6a0c88dac 100644 --- a/src/AntShares/Network/LocalNode.cs +++ b/src/AntShares/Network/LocalNode.cs @@ -97,18 +97,8 @@ private bool AddTransaction(Transaction tx) lock (MemoryPool) { if (MemoryPool.ContainsKey(tx.Hash)) return false; - if (MemoryPool.Values.SelectMany(p => p.GetAllInputs()).Intersect(tx.GetAllInputs()).Count() > 0) - return false; if (Blockchain.Default.ContainsTransaction(tx.Hash)) return false; - if (tx is IssueTransaction) - { - IssueTransaction issue = (IssueTransaction)tx; - if (!issue.Verify(true)) return false; - } - else - { - if (!tx.Verify()) return false; - } + if (!tx.Verify(MemoryPool.Values)) return false; AddingTransactionEventArgs args = new AddingTransactionEventArgs(tx); AddingTransaction?.Invoke(this, args); if (!args.Cancel) MemoryPool.Add(tx.Hash, tx); diff --git a/src/AntShares/project.json b/src/AntShares/project.json index 9d50f631cf..560afd75a2 100644 --- a/src/AntShares/project.json +++ b/src/AntShares/project.json @@ -2,7 +2,7 @@ "authors": [ "The Antshares team" ], "copyright": "2015-2016 The Antshares team", "title": "AntShares", - "version": "1.2.0", + "version": "1.3.1", "buildOptions": { "allowUnsafe": true, "copyToOutput": {