From 21e49d5006267119f3e5fb40f4dd7ec50de94282 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Wed, 23 Oct 2019 15:08:34 +0800 Subject: [PATCH 01/17] Keep track of sender fee to avoid duplicate computation --- neo.UnitTests/Ledger/UT_MemoryPool.cs | 5 ++- .../Network/P2P/Payloads/UT_Transaction.cs | 2 +- neo/Consensus/ConsensusContext.cs | 20 +++++++++ neo/Consensus/ConsensusService.cs | 4 +- neo/Ledger/Blockchain.cs | 4 +- neo/Ledger/MemoryPool.cs | 42 ++++++++++++++++++- neo/Network/P2P/Payloads/Transaction.cs | 10 ++--- 7 files changed, 75 insertions(+), 12 deletions(-) diff --git a/neo.UnitTests/Ledger/UT_MemoryPool.cs b/neo.UnitTests/Ledger/UT_MemoryPool.cs index 27c4d37715..6f9022bef1 100644 --- a/neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -13,6 +13,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Numerics; namespace Neo.UnitTests.Ledger { @@ -73,8 +74,8 @@ private Transaction CreateTransactionWithFee(long fee) var randomBytes = new byte[16]; random.NextBytes(randomBytes); Mock mock = new Mock(); - mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny>())).Returns(true); - mock.Setup(p => p.Verify(It.IsAny(), It.IsAny>())).Returns(true); + mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true); + mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true); mock.Object.Script = randomBytes; mock.Object.Sender = UInt160.Zero; mock.Object.NetworkFee = fee; diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index d52867e99e..f048907934 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -798,7 +798,7 @@ public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length() }; UInt160[] hashes = txSimple.GetScriptHashesForVerifying(snapshot); Assert.AreEqual(2, hashes.Length); - Assert.IsFalse(txSimple.Reverify(snapshot, new Transaction[0])); + Assert.IsFalse(txSimple.Reverify(snapshot, BigInteger.Zero)); } [TestMethod] diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index 463bdc0407..7bc90d7e1b 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Numerics; using System.Runtime.CompilerServices; namespace Neo.Consensus @@ -29,6 +30,7 @@ internal class ConsensusContext : IDisposable, ISerializable public int MyIndex; public UInt256[] TransactionHashes; public Dictionary Transactions; + public Dictionary SenderFee; public ConsensusPayload[] PreparationPayloads; public ConsensusPayload[] CommitPayloads; public ConsensusPayload[] ChangeViewPayloads; @@ -110,6 +112,22 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); + SenderFee = new Dictionary(); + foreach (Transaction tx in Transactions.Values) + AddSenderFee(tx); + } + + public void AddSenderFee(Transaction tx) + { + if (!SenderFee.ContainsKey(tx.Sender)) + SenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + else + SenderFee[tx.Sender] += tx.SystemFee + tx.NetworkFee; + } + + public BigInteger GetSenderFee(UInt160 sender) + { + return SenderFee.ContainsKey(sender) ? SenderFee[sender] : BigInteger.Zero; } public void Dispose() @@ -245,6 +263,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); + SenderFee = new Dictionary(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); @@ -258,6 +277,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); + AddSenderFee(tx); } TransactionHashes = hashes.ToArray(); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index a65916b5aa..bae0f0319e 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -61,7 +61,7 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, ConsensusC private bool AddTransaction(Transaction tx, bool verify) { - if (verify && !tx.Verify(context.Snapshot, context.Transactions.Values)) + if (verify && !tx.Verify(context.Snapshot, context.GetSenderFee(tx.Sender))) { Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); RequestChangeView(ChangeViewReason.TxInvalid); @@ -74,6 +74,7 @@ private bool AddTransaction(Transaction tx, bool verify) return false; } context.Transactions[tx.Hash] = tx; + context.AddSenderFee(tx); return CheckPrepareResponse(); } @@ -423,6 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); + context.SenderFee = new Dictionary(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/Blockchain.cs b/neo/Ledger/Blockchain.cs index 50393d4c8e..ea2a5fc596 100644 --- a/neo/Ledger/Blockchain.cs +++ b/neo/Ledger/Blockchain.cs @@ -244,7 +244,7 @@ private void OnFillMemoryPool(IEnumerable transactions) // First remove the tx if it is unverified in the pool. MemPool.TryRemoveUnVerified(tx.Hash, out _); // Verify the the transaction - if (!tx.Verify(currentSnapshot, MemPool.GetVerifiedTransactions())) + if (!tx.Verify(currentSnapshot, MemPool.GetSenderFee(tx.Sender))) continue; // Add to the memory pool MemPool.TryAdd(tx.Hash, tx); @@ -370,7 +370,7 @@ private RelayResultReason OnNewTransaction(Transaction transaction, bool relay) return RelayResultReason.AlreadyExists; if (!MemPool.CanTransactionFitInPool(transaction)) return RelayResultReason.OutOfMemory; - if (!transaction.Verify(currentSnapshot, MemPool.GetVerifiedTransactions())) + if (!transaction.Verify(currentSnapshot, MemPool.GetSenderFee(transaction.Sender))) return RelayResultReason.Invalid; if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot)) return RelayResultReason.PolicyFail; diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 10ee5f9d0b..e1fda61383 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -9,6 +9,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Runtime.CompilerServices; using System.Threading; @@ -38,6 +39,11 @@ public class MemoryPool : IReadOnlyCollection /// private readonly ReaderWriterLockSlim _txRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + /// + /// Store all verified unsorted transactions' senders' fee currently in the pool. + /// + private readonly Dictionary _senderFee = new Dictionary(); + /// /// Store all verified unsorted transactions currently in the pool. /// @@ -165,6 +171,36 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public BigInteger GetSenderFee(UInt160 sender) + { + _txRwLock.EnterReadLock(); + try + { + if (_senderFee.ContainsKey(sender)) + return _senderFee[sender]; + else + return BigInteger.Zero; + } + finally + { + _txRwLock.ExitReadLock(); + } + } + + private void AddSenderFee(Transaction tx) + { + if (!_senderFee.ContainsKey(tx.Sender)) + _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + else + _senderFee[tx.Sender] += tx.SystemFee + tx.NetworkFee; + } + + private void RemoveSenderFee(Transaction tx) + { + _senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; + if (_senderFee[tx.Sender] == 0) _senderFee.Remove(tx.Sender); + } + public IEnumerable GetVerifiedTransactions() { _txRwLock.EnterReadLock(); @@ -268,6 +304,7 @@ internal bool TryAdd(UInt256 hash, Transaction tx) try { _unsortedTransactions.Add(hash, poolItem); + AddSenderFee(tx); _sortedTransactions.Add(poolItem); if (Count > Capacity) @@ -310,6 +347,7 @@ private bool TryRemoveVerified(UInt256 hash, out PoolItem item) return false; _unsortedTransactions.Remove(hash); + RemoveSenderFee(item.Tx); _sortedTransactions.Remove(item); return true; @@ -337,6 +375,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); + _senderFee.Clear(); _sortedTransactions.Clear(); } @@ -409,7 +448,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end. foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count)) { - if (item.Tx.Reverify(snapshot, _unsortedTransactions.Select(p => p.Value.Tx))) + if (item.Tx.Reverify(snapshot, GetSenderFee(item.Tx.Sender))) reverifiedItems.Add(item); else // Transaction no longer valid -- it will be removed from unverifiedTxPool. invalidItems.Add(item); @@ -432,6 +471,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, { if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { + AddSenderFee(item.Tx); verifiedSortedTxPool.Add(item); if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) diff --git a/neo/Network/P2P/Payloads/Transaction.cs b/neo/Network/P2P/Payloads/Transaction.cs index af38ef6dcc..b51e2f7b2f 100644 --- a/neo/Network/P2P/Payloads/Transaction.cs +++ b/neo/Network/P2P/Payloads/Transaction.cs @@ -130,7 +130,7 @@ public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot) return hashes.OrderBy(p => p).ToArray(); } - public virtual bool Reverify(Snapshot snapshot, IEnumerable mempool) + public virtual bool Reverify(Snapshot snapshot, BigInteger currentFee) { if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement) return false; @@ -139,7 +139,7 @@ public virtual bool Reverify(Snapshot snapshot, IEnumerable mempool BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender); BigInteger fee = SystemFee + NetworkFee; if (balance < fee) return false; - fee += mempool.Where(p => p != this && p.Sender.Equals(Sender)).Select(p => (BigInteger)(p.SystemFee + p.NetworkFee)).Sum(); + fee += currentFee; if (balance < fee) return false; UInt160[] hashes = GetScriptHashesForVerifying(snapshot); if (hashes.Length != Witnesses.Length) return false; @@ -206,12 +206,12 @@ public static Transaction FromJson(JObject json) bool IInventory.Verify(Snapshot snapshot) { - return Verify(snapshot, Enumerable.Empty()); + return Verify(snapshot, BigInteger.Zero); } - public virtual bool Verify(Snapshot snapshot, IEnumerable mempool) + public virtual bool Verify(Snapshot snapshot, BigInteger currentFee) { - if (!Reverify(snapshot, mempool)) return false; + if (!Reverify(snapshot, currentFee)) return false; int size = Size; if (size > MaxTransactionSize) return false; long net_fee = NetworkFee - size * NativeContract.Policy.GetFeePerByte(snapshot); From 512cc20ccd51e6f0c4f47c69a7d345ff084c6a2e Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Wed, 23 Oct 2019 15:26:15 +0800 Subject: [PATCH 02/17] Code optimization --- neo/Network/P2P/Payloads/Transaction.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/neo/Network/P2P/Payloads/Transaction.cs b/neo/Network/P2P/Payloads/Transaction.cs index b51e2f7b2f..096208bd8e 100644 --- a/neo/Network/P2P/Payloads/Transaction.cs +++ b/neo/Network/P2P/Payloads/Transaction.cs @@ -137,9 +137,7 @@ public virtual bool Reverify(Snapshot snapshot, BigInteger currentFee) if (NativeContract.Policy.GetBlockedAccounts(snapshot).Intersect(GetScriptHashesForVerifying(snapshot)).Count() > 0) return false; BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender); - BigInteger fee = SystemFee + NetworkFee; - if (balance < fee) return false; - fee += currentFee; + BigInteger fee = SystemFee + NetworkFee + currentFee; if (balance < fee) return false; UInt160[] hashes = GetScriptHashesForVerifying(snapshot); if (hashes.Length != Witnesses.Length) return false; From fd6e49c6270a3bb98bb6e7bab79e4dd562ef5de4 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 23 Oct 2019 11:09:07 +0200 Subject: [PATCH 03/17] Optimize --- neo/Ledger/MemoryPool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index e1fda61383..f24321a57c 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -176,8 +176,8 @@ public BigInteger GetSenderFee(UInt160 sender) _txRwLock.EnterReadLock(); try { - if (_senderFee.ContainsKey(sender)) - return _senderFee[sender]; + if (_senderFee.TryGetValue(sender, out var value)) + return value; else return BigInteger.Zero; } From ff11bb75d2a5ac2bbd1e557cd28af4b086e814a0 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 23 Oct 2019 11:13:47 +0200 Subject: [PATCH 04/17] Optimize --- neo/Consensus/ConsensusContext.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index 7bc90d7e1b..f91dfa3c59 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -119,15 +119,18 @@ public void Deserialize(BinaryReader reader) public void AddSenderFee(Transaction tx) { - if (!SenderFee.ContainsKey(tx.Sender)) - SenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + if (SenderFee.TryGetValue(sender, out var value)) + SenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; else - SenderFee[tx.Sender] += tx.SystemFee + tx.NetworkFee; + SenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); } public BigInteger GetSenderFee(UInt160 sender) { - return SenderFee.ContainsKey(sender) ? SenderFee[sender] : BigInteger.Zero; + if (SenderFee.TryGetValue(sender, out var value)) + return value; + else + return BigInteger.Zero; } public void Dispose() From e12e5d4bef8728c3476af846dc8967b3df2908c9 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 23 Oct 2019 11:16:26 +0200 Subject: [PATCH 05/17] Optimize --- neo/Ledger/MemoryPool.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index f24321a57c..6dd1fab848 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -189,10 +189,10 @@ public BigInteger GetSenderFee(UInt160 sender) private void AddSenderFee(Transaction tx) { - if (!_senderFee.ContainsKey(tx.Sender)) - _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + if (_senderFee.TryGetValue(sender, out var value)) + _senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; else - _senderFee[tx.Sender] += tx.SystemFee + tx.NetworkFee; + _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); } private void RemoveSenderFee(Transaction tx) From fd2fa7cd66eb23f7254b9ae637c2aad3da8c357a Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Wed, 23 Oct 2019 17:24:20 +0800 Subject: [PATCH 06/17] Code optimization --- neo/Ledger/MemoryPool.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 6dd1fab848..9b40787820 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -174,22 +174,17 @@ public IEnumerator GetEnumerator() public BigInteger GetSenderFee(UInt160 sender) { _txRwLock.EnterReadLock(); - try - { - if (_senderFee.TryGetValue(sender, out var value)) - return value; - else - return BigInteger.Zero; - } - finally - { - _txRwLock.ExitReadLock(); - } + bool recorded = _senderFee.TryGetValue(sender, out var value); + _txRwLock.ExitReadLock(); + if (recorded) + return value; + else + return BigInteger.Zero; } private void AddSenderFee(Transaction tx) { - if (_senderFee.TryGetValue(sender, out var value)) + if (_senderFee.TryGetValue(tx.Sender, out var value)) _senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; else _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); From bd99e8d9efba5c36a4d19023640cb20a0e4943ef Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Wed, 23 Oct 2019 17:25:46 +0800 Subject: [PATCH 07/17] Correction --- neo/Consensus/ConsensusContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index f91dfa3c59..420b96159b 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -119,7 +119,7 @@ public void Deserialize(BinaryReader reader) public void AddSenderFee(Transaction tx) { - if (SenderFee.TryGetValue(sender, out var value)) + if (SenderFee.TryGetValue(tx.Sender, out var value)) SenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; else SenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); From 85499421bad043b0015094dd895be3309cbf67d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Naz=C3=A1rio=20Coelho?= Date: Thu, 31 Oct 2019 16:19:18 -0300 Subject: [PATCH 08/17] Renaming currentFee to totalSenderFeeFromPool --- neo/Network/P2P/Payloads/Transaction.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neo/Network/P2P/Payloads/Transaction.cs b/neo/Network/P2P/Payloads/Transaction.cs index 096208bd8e..70f4c2be1f 100644 --- a/neo/Network/P2P/Payloads/Transaction.cs +++ b/neo/Network/P2P/Payloads/Transaction.cs @@ -130,14 +130,14 @@ public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot) return hashes.OrderBy(p => p).ToArray(); } - public virtual bool Reverify(Snapshot snapshot, BigInteger currentFee) + public virtual bool Reverify(Snapshot snapshot, BigInteger totalSenderFeeFromPool) { if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement) return false; if (NativeContract.Policy.GetBlockedAccounts(snapshot).Intersect(GetScriptHashesForVerifying(snapshot)).Count() > 0) return false; BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender); - BigInteger fee = SystemFee + NetworkFee + currentFee; + BigInteger fee = SystemFee + NetworkFee + totalSenderFeeFromPool; if (balance < fee) return false; UInt160[] hashes = GetScriptHashesForVerifying(snapshot); if (hashes.Length != Witnesses.Length) return false; From 5d7d8e95b5a360a939a6b5a7a09be941deeed751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Naz=C3=A1rio=20Coelho?= Date: Thu, 31 Oct 2019 16:20:03 -0300 Subject: [PATCH 09/17] Renaming on Verify as well --- neo/Network/P2P/Payloads/Transaction.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neo/Network/P2P/Payloads/Transaction.cs b/neo/Network/P2P/Payloads/Transaction.cs index 70f4c2be1f..8dcc8f2205 100644 --- a/neo/Network/P2P/Payloads/Transaction.cs +++ b/neo/Network/P2P/Payloads/Transaction.cs @@ -207,9 +207,9 @@ bool IInventory.Verify(Snapshot snapshot) return Verify(snapshot, BigInteger.Zero); } - public virtual bool Verify(Snapshot snapshot, BigInteger currentFee) + public virtual bool Verify(Snapshot snapshot, BigInteger totalSenderFeeFromPool) { - if (!Reverify(snapshot, currentFee)) return false; + if (!Reverify(snapshot, totalSenderFeeFromPool)) return false; int size = Size; if (size > MaxTransactionSize) return false; long net_fee = NetworkFee - size * NativeContract.Policy.GetFeePerByte(snapshot); From ae7cd581998be8d36c6545e789f0f7ec908e238c Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Fri, 1 Nov 2019 13:55:59 +0800 Subject: [PATCH 10/17] Add consideration for null Transactions --- neo/Consensus/ConsensusContext.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index 420b96159b..af846fa1bf 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -113,8 +113,11 @@ public void Deserialize(BinaryReader reader) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); SenderFee = new Dictionary(); - foreach (Transaction tx in Transactions.Values) - AddSenderFee(tx); + if (Transactions != null) + { + foreach (Transaction tx in Transactions.Values) + AddSenderFee(tx); + } } public void AddSenderFee(Transaction tx) From 73dfe47deba972ea854a60b753b0210846702a28 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Mon, 4 Nov 2019 11:42:31 +0800 Subject: [PATCH 11/17] Move sender fee recording systems to class SendersMonitor --- neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs | 74 +++++++++++++++ neo/Consensus/ConsensusContext.cs | 26 +----- neo/Consensus/ConsensusService.cs | 6 +- neo/Ledger/Blockchain.cs | 4 +- neo/Ledger/MemoryPool.cs | 41 +-------- neo/Ledger/SendersFeeMonitor.cs | 96 ++++++++++++++++++++ 6 files changed, 184 insertions(+), 63 deletions(-) create mode 100644 neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs create mode 100644 neo/Ledger/SendersFeeMonitor.cs diff --git a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs new file mode 100644 index 0000000000..662b02c92e --- /dev/null +++ b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs @@ -0,0 +1,74 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Neo.Ledger; +using Neo.Network.P2P.Payloads; +using Neo.Persistence; +using System; +using System.Numerics; + +namespace Neo.UnitTests.Ledger +{ + [TestClass] + public class UT_SendersFeeMonitor + { + private Transaction CreateTransactionWithFee(long networkFee, long systemFee) + { + Random random = new Random(); + var randomBytes = new byte[16]; + random.NextBytes(randomBytes); + Mock mock = new Mock(); + mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true); + mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true); + mock.Object.Script = randomBytes; + mock.Object.Sender = UInt160.Zero; + mock.Object.NetworkFee = networkFee; + mock.Object.SystemFee = systemFee; + mock.Object.Attributes = new TransactionAttribute[0]; + mock.Object.Cosigners = new Cosigner[0]; + mock.Object.Witnesses = new[] + { + new Witness + { + InvocationScript = new byte[0], + VerificationScript = new byte[0] + } + }; + return mock.Object; + } + + [TestMethod] + public void TestMemPoolSenderFee() + { + Transaction transaction = CreateTransactionWithFee(1, 2); + BigInteger originalValue = SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender); + SendersFeeMonitor.AddMemPoolSenderFee(transaction); + SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(3 + originalValue); + SendersFeeMonitor.AddMemPoolSenderFee(transaction); + SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(6 + originalValue); + SendersFeeMonitor.RemoveMemPoolSenderFee(transaction); + SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(3 + originalValue); + SendersFeeMonitor.RemoveMemPoolSenderFee(transaction); + SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(originalValue); + SendersFeeMonitor.ClearMemPoolSenderFee(); + SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(0); + } + + [TestMethod] + public void TestConsensusSenderFee() + { + Transaction transaction = CreateTransactionWithFee(1, 2); + BigInteger originalValue = SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender); + SendersFeeMonitor.AddConsensusSenderFee(transaction); + SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(3 + originalValue); + SendersFeeMonitor.AddConsensusSenderFee(transaction); + SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(6 + originalValue); + SendersFeeMonitor.RemoveConsensusSenderFee(transaction); + SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(3 + originalValue); + SendersFeeMonitor.RemoveConsensusSenderFee(transaction); + SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(originalValue); + SendersFeeMonitor.ClearConsensusSenderFee(); + SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(0); + } + } +} diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index af846fa1bf..4c5b012668 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -12,7 +12,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Numerics; using System.Runtime.CompilerServices; namespace Neo.Consensus @@ -30,7 +29,6 @@ internal class ConsensusContext : IDisposable, ISerializable public int MyIndex; public UInt256[] TransactionHashes; public Dictionary Transactions; - public Dictionary SenderFee; public ConsensusPayload[] PreparationPayloads; public ConsensusPayload[] CommitPayloads; public ConsensusPayload[] ChangeViewPayloads; @@ -112,30 +110,14 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); - SenderFee = new Dictionary(); + SendersFeeMonitor.ClearConsensusSenderFee(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) - AddSenderFee(tx); + SendersFeeMonitor.AddConsensusSenderFee(tx); } } - public void AddSenderFee(Transaction tx) - { - if (SenderFee.TryGetValue(tx.Sender, out var value)) - SenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; - else - SenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); - } - - public BigInteger GetSenderFee(UInt160 sender) - { - if (SenderFee.TryGetValue(sender, out var value)) - return value; - else - return BigInteger.Zero; - } - public void Dispose() { Snapshot?.Dispose(); @@ -269,7 +251,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); - SenderFee = new Dictionary(); + SendersFeeMonitor.ClearConsensusSenderFee(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); @@ -283,7 +265,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); - AddSenderFee(tx); + SendersFeeMonitor.AddConsensusSenderFee(tx); } TransactionHashes = hashes.ToArray(); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index bae0f0319e..03ad389588 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -61,7 +61,7 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, ConsensusC private bool AddTransaction(Transaction tx, bool verify) { - if (verify && !tx.Verify(context.Snapshot, context.GetSenderFee(tx.Sender))) + if (verify && !tx.Verify(context.Snapshot, SendersFeeMonitor.GetConsensusSenderFee(tx.Sender))) { Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); RequestChangeView(ChangeViewReason.TxInvalid); @@ -74,7 +74,7 @@ private bool AddTransaction(Transaction tx, bool verify) return false; } context.Transactions[tx.Hash] = tx; - context.AddSenderFee(tx); + SendersFeeMonitor.AddConsensusSenderFee(tx); return CheckPrepareResponse(); } @@ -424,7 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); - context.SenderFee = new Dictionary(); + SendersFeeMonitor.ClearConsensusSenderFee(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/Blockchain.cs b/neo/Ledger/Blockchain.cs index ea2a5fc596..450acf8bd7 100644 --- a/neo/Ledger/Blockchain.cs +++ b/neo/Ledger/Blockchain.cs @@ -244,7 +244,7 @@ private void OnFillMemoryPool(IEnumerable transactions) // First remove the tx if it is unverified in the pool. MemPool.TryRemoveUnVerified(tx.Hash, out _); // Verify the the transaction - if (!tx.Verify(currentSnapshot, MemPool.GetSenderFee(tx.Sender))) + if (!tx.Verify(currentSnapshot, SendersFeeMonitor.GetMemPoolSenderFee(tx.Sender))) continue; // Add to the memory pool MemPool.TryAdd(tx.Hash, tx); @@ -370,7 +370,7 @@ private RelayResultReason OnNewTransaction(Transaction transaction, bool relay) return RelayResultReason.AlreadyExists; if (!MemPool.CanTransactionFitInPool(transaction)) return RelayResultReason.OutOfMemory; - if (!transaction.Verify(currentSnapshot, MemPool.GetSenderFee(transaction.Sender))) + if (!transaction.Verify(currentSnapshot, SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender))) return RelayResultReason.Invalid; if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot)) return RelayResultReason.PolicyFail; diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 28da4a6483..ca1feccbd6 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -9,7 +9,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Numerics; using System.Runtime.CompilerServices; using System.Threading; @@ -39,11 +38,6 @@ public class MemoryPool : IReadOnlyCollection /// private readonly ReaderWriterLockSlim _txRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - /// - /// Store all verified unsorted transactions' senders' fee currently in the pool. - /// - private readonly Dictionary _senderFee = new Dictionary(); - /// /// Store all verified unsorted transactions currently in the pool. /// @@ -171,31 +165,6 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public BigInteger GetSenderFee(UInt160 sender) - { - _txRwLock.EnterReadLock(); - bool recorded = _senderFee.TryGetValue(sender, out var value); - _txRwLock.ExitReadLock(); - if (recorded) - return value; - else - return BigInteger.Zero; - } - - private void AddSenderFee(Transaction tx) - { - if (_senderFee.TryGetValue(tx.Sender, out var value)) - _senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; - else - _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); - } - - private void RemoveSenderFee(Transaction tx) - { - _senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; - if (_senderFee[tx.Sender] == 0) _senderFee.Remove(tx.Sender); - } - public IEnumerable GetVerifiedTransactions() { _txRwLock.EnterReadLock(); @@ -299,7 +268,7 @@ internal bool TryAdd(UInt256 hash, Transaction tx) try { _unsortedTransactions.Add(hash, poolItem); - AddSenderFee(tx); + SendersFeeMonitor.AddMemPoolSenderFee(tx); _sortedTransactions.Add(poolItem); if (Count > Capacity) @@ -342,7 +311,7 @@ private bool TryRemoveVerified(UInt256 hash, out PoolItem item) return false; _unsortedTransactions.Remove(hash); - RemoveSenderFee(item.Tx); + SendersFeeMonitor.RemoveMemPoolSenderFee(item.Tx); _sortedTransactions.Remove(item); return true; @@ -370,7 +339,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); - _senderFee.Clear(); + SendersFeeMonitor.ClearMemPoolSenderFee(); _sortedTransactions.Clear(); } @@ -443,7 +412,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end. foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count)) { - if (item.Tx.Reverify(snapshot, GetSenderFee(item.Tx.Sender))) + if (item.Tx.Reverify(snapshot, SendersFeeMonitor.GetMemPoolSenderFee(item.Tx.Sender))) reverifiedItems.Add(item); else // Transaction no longer valid -- it will be removed from unverifiedTxPool. invalidItems.Add(item); @@ -466,7 +435,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, { if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { - AddSenderFee(item.Tx); + SendersFeeMonitor.AddMemPoolSenderFee(item.Tx); verifiedSortedTxPool.Add(item); if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs new file mode 100644 index 0000000000..c853b1ca60 --- /dev/null +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -0,0 +1,96 @@ +using Neo.Network.P2P.Payloads; +using System.Collections.Generic; +using System.Numerics; +using System.Threading; + +namespace Neo.Ledger +{ + public class SendersFeeMonitor + { + private static readonly ReaderWriterLockSlim _memPoolSenderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + + private static readonly ReaderWriterLockSlim _consensusSenderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + + /// + /// Store all verified unsorted transactions' senders' fee currently in the memory pool. + /// + private static readonly Dictionary _memPoolSenderFee = new Dictionary(); + + /// + /// Store all verified unsorted transactions' senders' fee currently in the consensus context. + /// + private static readonly Dictionary _consensusSenderFee = new Dictionary(); + + public static BigInteger GetMemPoolSenderFee(UInt160 sender) + { + _memPoolSenderFeeRwLock.EnterReadLock(); + bool recorded = _memPoolSenderFee.TryGetValue(sender, out var value); + _memPoolSenderFeeRwLock.ExitReadLock(); + if (recorded) + return value; + else + return BigInteger.Zero; + } + + public static void AddMemPoolSenderFee(Transaction tx) + { + _memPoolSenderFeeRwLock.EnterWriteLock(); + if (_memPoolSenderFee.TryGetValue(tx.Sender, out var value)) + _memPoolSenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; + else + _memPoolSenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + _memPoolSenderFeeRwLock.ExitWriteLock(); + } + + public static void RemoveMemPoolSenderFee(Transaction tx) + { + _memPoolSenderFeeRwLock.EnterWriteLock(); + _memPoolSenderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; + if (_memPoolSenderFee[tx.Sender] == 0) _memPoolSenderFee.Remove(tx.Sender); + _memPoolSenderFeeRwLock.ExitWriteLock(); + } + + public static void ClearMemPoolSenderFee() + { + _memPoolSenderFeeRwLock.EnterWriteLock(); + _memPoolSenderFee.Clear(); + _memPoolSenderFeeRwLock.ExitWriteLock(); + } + + public static BigInteger GetConsensusSenderFee(UInt160 sender) + { + _consensusSenderFeeRwLock.EnterReadLock(); + bool recorded = _consensusSenderFee.TryGetValue(sender, out var value); + _consensusSenderFeeRwLock.ExitReadLock(); + if (recorded) + return value; + else + return BigInteger.Zero; + } + + public static void AddConsensusSenderFee(Transaction tx) + { + _consensusSenderFeeRwLock.EnterWriteLock(); + if (_consensusSenderFee.TryGetValue(tx.Sender, out var value)) + _consensusSenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; + else + _consensusSenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + _consensusSenderFeeRwLock.ExitWriteLock(); + } + + public static void RemoveConsensusSenderFee(Transaction tx) + { + _consensusSenderFeeRwLock.EnterWriteLock(); + _consensusSenderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; + if (_consensusSenderFee[tx.Sender] == 0) _consensusSenderFee.Remove(tx.Sender); + _consensusSenderFeeRwLock.ExitWriteLock(); + } + + public static void ClearConsensusSenderFee() + { + _consensusSenderFeeRwLock.EnterWriteLock(); + _consensusSenderFee.Clear(); + _consensusSenderFeeRwLock.ExitWriteLock(); + } + } +} From ef84a44e7b6e7bbe582a50d33278a08c78999397 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Tue, 5 Nov 2019 11:28:36 +0800 Subject: [PATCH 12/17] Code optimization --- neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs | 40 +++------ neo/Consensus/ConsensusContext.cs | 13 ++- neo/Consensus/ConsensusService.cs | 6 +- neo/Ledger/Blockchain.cs | 4 +- neo/Ledger/MemoryPool.cs | 15 ++-- neo/Ledger/SendersFeeMonitor.cs | 85 +++++--------------- 6 files changed, 57 insertions(+), 106 deletions(-) diff --git a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs index 662b02c92e..c79d21cef1 100644 --- a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs +++ b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs @@ -41,34 +41,18 @@ private Transaction CreateTransactionWithFee(long networkFee, long systemFee) public void TestMemPoolSenderFee() { Transaction transaction = CreateTransactionWithFee(1, 2); - BigInteger originalValue = SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender); - SendersFeeMonitor.AddMemPoolSenderFee(transaction); - SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(3 + originalValue); - SendersFeeMonitor.AddMemPoolSenderFee(transaction); - SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(6 + originalValue); - SendersFeeMonitor.RemoveMemPoolSenderFee(transaction); - SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(3 + originalValue); - SendersFeeMonitor.RemoveMemPoolSenderFee(transaction); - SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(originalValue); - SendersFeeMonitor.ClearMemPoolSenderFee(); - SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender).Should().Be(0); - } - - [TestMethod] - public void TestConsensusSenderFee() - { - Transaction transaction = CreateTransactionWithFee(1, 2); - BigInteger originalValue = SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender); - SendersFeeMonitor.AddConsensusSenderFee(transaction); - SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(3 + originalValue); - SendersFeeMonitor.AddConsensusSenderFee(transaction); - SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(6 + originalValue); - SendersFeeMonitor.RemoveConsensusSenderFee(transaction); - SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(3 + originalValue); - SendersFeeMonitor.RemoveConsensusSenderFee(transaction); - SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(originalValue); - SendersFeeMonitor.ClearConsensusSenderFee(); - SendersFeeMonitor.GetConsensusSenderFee(transaction.Sender).Should().Be(0); + SendersFeeMonitor sendersFeeMonitor = new SendersFeeMonitor(); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); + sendersFeeMonitor.AddSenderFee(transaction); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3); + sendersFeeMonitor.AddSenderFee(transaction); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(6); + sendersFeeMonitor.RemoveSenderFee(transaction); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3); + sendersFeeMonitor.RemoveSenderFee(transaction); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); + sendersFeeMonitor.ClearSenderFee(); + sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); } } } diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index 4c5b012668..f3e9082e47 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -37,6 +37,11 @@ internal class ConsensusContext : IDisposable, ISerializable // if this node never heard from validator i, LastSeenMessage[i] will be -1. public int[] LastSeenMessage; + /// + /// Store all verified unsorted transactions' senders' fee currently in the consensus context. + /// + public readonly SendersFeeMonitor senderFeeMonitor = new SendersFeeMonitor(); + public Snapshot Snapshot { get; private set; } private KeyPair keyPair; private int _witnessSize; @@ -110,11 +115,11 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); - SendersFeeMonitor.ClearConsensusSenderFee(); + senderFeeMonitor.ClearSenderFee(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) - SendersFeeMonitor.AddConsensusSenderFee(tx); + senderFeeMonitor.AddSenderFee(tx); } } @@ -251,7 +256,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); - SendersFeeMonitor.ClearConsensusSenderFee(); + senderFeeMonitor.ClearSenderFee(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); @@ -265,7 +270,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); - SendersFeeMonitor.AddConsensusSenderFee(tx); + senderFeeMonitor.AddSenderFee(tx); } TransactionHashes = hashes.ToArray(); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index 03ad389588..a3d935901d 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -61,7 +61,7 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, ConsensusC private bool AddTransaction(Transaction tx, bool verify) { - if (verify && !tx.Verify(context.Snapshot, SendersFeeMonitor.GetConsensusSenderFee(tx.Sender))) + if (verify && !tx.Verify(context.Snapshot, context.senderFeeMonitor.GetSenderFee(tx.Sender))) { Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); RequestChangeView(ChangeViewReason.TxInvalid); @@ -74,7 +74,7 @@ private bool AddTransaction(Transaction tx, bool verify) return false; } context.Transactions[tx.Hash] = tx; - SendersFeeMonitor.AddConsensusSenderFee(tx); + context.senderFeeMonitor.AddSenderFee(tx); return CheckPrepareResponse(); } @@ -424,7 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); - SendersFeeMonitor.ClearConsensusSenderFee(); + context.senderFeeMonitor.ClearSenderFee(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/Blockchain.cs b/neo/Ledger/Blockchain.cs index 450acf8bd7..a9a65f9cf3 100644 --- a/neo/Ledger/Blockchain.cs +++ b/neo/Ledger/Blockchain.cs @@ -244,7 +244,7 @@ private void OnFillMemoryPool(IEnumerable transactions) // First remove the tx if it is unverified in the pool. MemPool.TryRemoveUnVerified(tx.Hash, out _); // Verify the the transaction - if (!tx.Verify(currentSnapshot, SendersFeeMonitor.GetMemPoolSenderFee(tx.Sender))) + if (!tx.Verify(currentSnapshot, MemPool.senderFeeMonitor.GetSenderFee(tx.Sender))) continue; // Add to the memory pool MemPool.TryAdd(tx.Hash, tx); @@ -370,7 +370,7 @@ private RelayResultReason OnNewTransaction(Transaction transaction, bool relay) return RelayResultReason.AlreadyExists; if (!MemPool.CanTransactionFitInPool(transaction)) return RelayResultReason.OutOfMemory; - if (!transaction.Verify(currentSnapshot, SendersFeeMonitor.GetMemPoolSenderFee(transaction.Sender))) + if (!transaction.Verify(currentSnapshot, MemPool.senderFeeMonitor.GetSenderFee(transaction.Sender))) return RelayResultReason.Invalid; if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot)) return RelayResultReason.PolicyFail; diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index ca1feccbd6..40e50dd94c 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -69,6 +69,11 @@ public class MemoryPool : IReadOnlyCollection /// public int Capacity { get; } + /// + /// Store all verified unsorted transactions' senders' fee currently in the memory pool. + /// + public readonly SendersFeeMonitor senderFeeMonitor = new SendersFeeMonitor(); + /// /// Total count of transactions in the pool. /// @@ -268,7 +273,7 @@ internal bool TryAdd(UInt256 hash, Transaction tx) try { _unsortedTransactions.Add(hash, poolItem); - SendersFeeMonitor.AddMemPoolSenderFee(tx); + senderFeeMonitor.AddSenderFee(tx); _sortedTransactions.Add(poolItem); if (Count > Capacity) @@ -311,7 +316,7 @@ private bool TryRemoveVerified(UInt256 hash, out PoolItem item) return false; _unsortedTransactions.Remove(hash); - SendersFeeMonitor.RemoveMemPoolSenderFee(item.Tx); + senderFeeMonitor.RemoveSenderFee(item.Tx); _sortedTransactions.Remove(item); return true; @@ -339,7 +344,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); - SendersFeeMonitor.ClearMemPoolSenderFee(); + senderFeeMonitor.ClearSenderFee(); _sortedTransactions.Clear(); } @@ -412,7 +417,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end. foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count)) { - if (item.Tx.Reverify(snapshot, SendersFeeMonitor.GetMemPoolSenderFee(item.Tx.Sender))) + if (item.Tx.Reverify(snapshot, senderFeeMonitor.GetSenderFee(item.Tx.Sender))) reverifiedItems.Add(item); else // Transaction no longer valid -- it will be removed from unverifiedTxPool. invalidItems.Add(item); @@ -435,7 +440,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, { if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { - SendersFeeMonitor.AddMemPoolSenderFee(item.Tx); + senderFeeMonitor.AddSenderFee(item.Tx); verifiedSortedTxPool.Add(item); if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs index c853b1ca60..5bd78b89ad 100644 --- a/neo/Ledger/SendersFeeMonitor.cs +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -7,90 +7,47 @@ namespace Neo.Ledger { public class SendersFeeMonitor { - private static readonly ReaderWriterLockSlim _memPoolSenderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - - private static readonly ReaderWriterLockSlim _consensusSenderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private readonly ReaderWriterLockSlim _senderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); /// /// Store all verified unsorted transactions' senders' fee currently in the memory pool. /// - private static readonly Dictionary _memPoolSenderFee = new Dictionary(); - - /// - /// Store all verified unsorted transactions' senders' fee currently in the consensus context. - /// - private static readonly Dictionary _consensusSenderFee = new Dictionary(); - - public static BigInteger GetMemPoolSenderFee(UInt160 sender) - { - _memPoolSenderFeeRwLock.EnterReadLock(); - bool recorded = _memPoolSenderFee.TryGetValue(sender, out var value); - _memPoolSenderFeeRwLock.ExitReadLock(); - if (recorded) - return value; - else - return BigInteger.Zero; - } - - public static void AddMemPoolSenderFee(Transaction tx) - { - _memPoolSenderFeeRwLock.EnterWriteLock(); - if (_memPoolSenderFee.TryGetValue(tx.Sender, out var value)) - _memPoolSenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; - else - _memPoolSenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); - _memPoolSenderFeeRwLock.ExitWriteLock(); - } - - public static void RemoveMemPoolSenderFee(Transaction tx) - { - _memPoolSenderFeeRwLock.EnterWriteLock(); - _memPoolSenderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; - if (_memPoolSenderFee[tx.Sender] == 0) _memPoolSenderFee.Remove(tx.Sender); - _memPoolSenderFeeRwLock.ExitWriteLock(); - } - - public static void ClearMemPoolSenderFee() - { - _memPoolSenderFeeRwLock.EnterWriteLock(); - _memPoolSenderFee.Clear(); - _memPoolSenderFeeRwLock.ExitWriteLock(); - } + private readonly Dictionary _senderFee = new Dictionary(); - public static BigInteger GetConsensusSenderFee(UInt160 sender) + public BigInteger GetSenderFee(UInt160 sender) { - _consensusSenderFeeRwLock.EnterReadLock(); - bool recorded = _consensusSenderFee.TryGetValue(sender, out var value); - _consensusSenderFeeRwLock.ExitReadLock(); + _senderFeeRwLock.EnterReadLock(); + bool recorded = _senderFee.TryGetValue(sender, out var value); + _senderFeeRwLock.ExitReadLock(); if (recorded) return value; else return BigInteger.Zero; } - public static void AddConsensusSenderFee(Transaction tx) + public void AddSenderFee(Transaction tx) { - _consensusSenderFeeRwLock.EnterWriteLock(); - if (_consensusSenderFee.TryGetValue(tx.Sender, out var value)) - _consensusSenderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; + _senderFeeRwLock.EnterWriteLock(); + if (_senderFee.TryGetValue(tx.Sender, out var value)) + _senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee; else - _consensusSenderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); - _consensusSenderFeeRwLock.ExitWriteLock(); + _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee); + _senderFeeRwLock.ExitWriteLock(); } - public static void RemoveConsensusSenderFee(Transaction tx) + public void RemoveSenderFee(Transaction tx) { - _consensusSenderFeeRwLock.EnterWriteLock(); - _consensusSenderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; - if (_consensusSenderFee[tx.Sender] == 0) _consensusSenderFee.Remove(tx.Sender); - _consensusSenderFeeRwLock.ExitWriteLock(); + _senderFeeRwLock.EnterWriteLock(); + _senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; + if (_senderFee[tx.Sender] == 0) _senderFee.Remove(tx.Sender); + _senderFeeRwLock.ExitWriteLock(); } - public static void ClearConsensusSenderFee() + public void ClearSenderFee() { - _consensusSenderFeeRwLock.EnterWriteLock(); - _consensusSenderFee.Clear(); - _consensusSenderFeeRwLock.ExitWriteLock(); + _senderFeeRwLock.EnterWriteLock(); + _senderFee.Clear(); + _senderFeeRwLock.ExitWriteLock(); } } } From a3b6dd5d3567c6f158e33361419d47a27eb094c2 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Tue, 5 Nov 2019 13:36:19 +0800 Subject: [PATCH 13/17] Capitalize public items --- neo/Consensus/ConsensusContext.cs | 10 +++++----- neo/Consensus/ConsensusService.cs | 6 +++--- neo/Ledger/Blockchain.cs | 4 ++-- neo/Ledger/MemoryPool.cs | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index f3e9082e47..2d2da073cb 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -40,7 +40,7 @@ internal class ConsensusContext : IDisposable, ISerializable /// /// Store all verified unsorted transactions' senders' fee currently in the consensus context. /// - public readonly SendersFeeMonitor senderFeeMonitor = new SendersFeeMonitor(); + public readonly SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); public Snapshot Snapshot { get; private set; } private KeyPair keyPair; @@ -115,11 +115,11 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); - senderFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ClearSenderFee(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) - senderFeeMonitor.AddSenderFee(tx); + SendersFeeMonitor.AddSenderFee(tx); } } @@ -256,7 +256,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); - senderFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ClearSenderFee(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); @@ -270,7 +270,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); - senderFeeMonitor.AddSenderFee(tx); + SendersFeeMonitor.AddSenderFee(tx); } TransactionHashes = hashes.ToArray(); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index a3d935901d..7e3cd92deb 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -61,7 +61,7 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, ConsensusC private bool AddTransaction(Transaction tx, bool verify) { - if (verify && !tx.Verify(context.Snapshot, context.senderFeeMonitor.GetSenderFee(tx.Sender))) + if (verify && !tx.Verify(context.Snapshot, context.SendersFeeMonitor.GetSenderFee(tx.Sender))) { Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); RequestChangeView(ChangeViewReason.TxInvalid); @@ -74,7 +74,7 @@ private bool AddTransaction(Transaction tx, bool verify) return false; } context.Transactions[tx.Hash] = tx; - context.senderFeeMonitor.AddSenderFee(tx); + context.SendersFeeMonitor.AddSenderFee(tx); return CheckPrepareResponse(); } @@ -424,7 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); - context.senderFeeMonitor.ClearSenderFee(); + context.SendersFeeMonitor.ClearSenderFee(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/Blockchain.cs b/neo/Ledger/Blockchain.cs index a9a65f9cf3..dea46ae3e8 100644 --- a/neo/Ledger/Blockchain.cs +++ b/neo/Ledger/Blockchain.cs @@ -244,7 +244,7 @@ private void OnFillMemoryPool(IEnumerable transactions) // First remove the tx if it is unverified in the pool. MemPool.TryRemoveUnVerified(tx.Hash, out _); // Verify the the transaction - if (!tx.Verify(currentSnapshot, MemPool.senderFeeMonitor.GetSenderFee(tx.Sender))) + if (!tx.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(tx.Sender))) continue; // Add to the memory pool MemPool.TryAdd(tx.Hash, tx); @@ -370,7 +370,7 @@ private RelayResultReason OnNewTransaction(Transaction transaction, bool relay) return RelayResultReason.AlreadyExists; if (!MemPool.CanTransactionFitInPool(transaction)) return RelayResultReason.OutOfMemory; - if (!transaction.Verify(currentSnapshot, MemPool.senderFeeMonitor.GetSenderFee(transaction.Sender))) + if (!transaction.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(transaction.Sender))) return RelayResultReason.Invalid; if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot)) return RelayResultReason.PolicyFail; diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 40e50dd94c..183ad5386d 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -72,7 +72,7 @@ public class MemoryPool : IReadOnlyCollection /// /// Store all verified unsorted transactions' senders' fee currently in the memory pool. /// - public readonly SendersFeeMonitor senderFeeMonitor = new SendersFeeMonitor(); + public readonly SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); /// /// Total count of transactions in the pool. @@ -273,7 +273,7 @@ internal bool TryAdd(UInt256 hash, Transaction tx) try { _unsortedTransactions.Add(hash, poolItem); - senderFeeMonitor.AddSenderFee(tx); + SendersFeeMonitor.AddSenderFee(tx); _sortedTransactions.Add(poolItem); if (Count > Capacity) @@ -316,7 +316,7 @@ private bool TryRemoveVerified(UInt256 hash, out PoolItem item) return false; _unsortedTransactions.Remove(hash); - senderFeeMonitor.RemoveSenderFee(item.Tx); + SendersFeeMonitor.RemoveSenderFee(item.Tx); _sortedTransactions.Remove(item); return true; @@ -344,7 +344,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); - senderFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ClearSenderFee(); _sortedTransactions.Clear(); } @@ -417,7 +417,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end. foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count)) { - if (item.Tx.Reverify(snapshot, senderFeeMonitor.GetSenderFee(item.Tx.Sender))) + if (item.Tx.Reverify(snapshot, SendersFeeMonitor.GetSenderFee(item.Tx.Sender))) reverifiedItems.Add(item); else // Transaction no longer valid -- it will be removed from unverifiedTxPool. invalidItems.Add(item); @@ -440,7 +440,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, { if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { - senderFeeMonitor.AddSenderFee(item.Tx); + SendersFeeMonitor.AddSenderFee(item.Tx); verifiedSortedTxPool.Add(item); if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) From 9e5c80e6fd0068ab208e7cc58cb3153eb7164653 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Tue, 5 Nov 2019 15:14:44 +0800 Subject: [PATCH 14/17] Code optimization --- neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs | 2 +- neo/Consensus/ConsensusContext.cs | 4 ++-- neo/Consensus/ConsensusService.cs | 2 +- neo/Ledger/MemoryPool.cs | 2 +- neo/Ledger/SendersFeeMonitor.cs | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs index c79d21cef1..e561bbb724 100644 --- a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs +++ b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs @@ -51,7 +51,7 @@ public void TestMemPoolSenderFee() sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3); sendersFeeMonitor.RemoveSenderFee(transaction); sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); - sendersFeeMonitor.ClearSenderFee(); + sendersFeeMonitor.ResetSenderFee(); sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); } } diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index 2d2da073cb..a6299c1c9a 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -115,7 +115,7 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); - SendersFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ResetSenderFee(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) @@ -256,7 +256,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); - SendersFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ResetSenderFee(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index 7e3cd92deb..38001637cb 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -424,7 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); - context.SendersFeeMonitor.ClearSenderFee(); + context.SendersFeeMonitor.ResetSenderFee(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 183ad5386d..cb088fcaa1 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -344,7 +344,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); - SendersFeeMonitor.ClearSenderFee(); + SendersFeeMonitor.ResetSenderFee(); _sortedTransactions.Clear(); } diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs index 5bd78b89ad..c83aafa968 100644 --- a/neo/Ledger/SendersFeeMonitor.cs +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -12,7 +12,7 @@ public class SendersFeeMonitor /// /// Store all verified unsorted transactions' senders' fee currently in the memory pool. /// - private readonly Dictionary _senderFee = new Dictionary(); + private Dictionary _senderFee = new Dictionary(); public BigInteger GetSenderFee(UInt160 sender) { @@ -43,10 +43,10 @@ public void RemoveSenderFee(Transaction tx) _senderFeeRwLock.ExitWriteLock(); } - public void ClearSenderFee() + public void ResetSenderFee() { _senderFeeRwLock.EnterWriteLock(); - _senderFee.Clear(); + _senderFee = new Dictionary(); _senderFeeRwLock.ExitWriteLock(); } } From c0bd129e0f4cda0b3549e5b735f5108dcc764f20 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Tue, 5 Nov 2019 15:28:37 +0800 Subject: [PATCH 15/17] Code optimization --- neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs | 2 -- neo/Consensus/ConsensusContext.cs | 6 +++--- neo/Consensus/ConsensusService.cs | 2 +- neo/Ledger/MemoryPool.cs | 4 ++-- neo/Ledger/SendersFeeMonitor.cs | 9 +-------- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs index e561bbb724..81fb0d9354 100644 --- a/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs +++ b/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs @@ -51,8 +51,6 @@ public void TestMemPoolSenderFee() sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3); sendersFeeMonitor.RemoveSenderFee(transaction); sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); - sendersFeeMonitor.ResetSenderFee(); - sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0); } } } diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs index a6299c1c9a..e7c2649782 100644 --- a/neo/Consensus/ConsensusContext.cs +++ b/neo/Consensus/ConsensusContext.cs @@ -40,7 +40,7 @@ internal class ConsensusContext : IDisposable, ISerializable /// /// Store all verified unsorted transactions' senders' fee currently in the consensus context. /// - public readonly SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); + public SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); public Snapshot Snapshot { get; private set; } private KeyPair keyPair; @@ -115,7 +115,7 @@ public void Deserialize(BinaryReader reader) if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); - SendersFeeMonitor.ResetSenderFee(); + SendersFeeMonitor = new SendersFeeMonitor(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) @@ -256,7 +256,7 @@ internal void EnsureMaxBlockSize(IEnumerable txs) txs = txs.Take((int)maxTransactionsPerBlock); List hashes = new List(); Transactions = new Dictionary(); - SendersFeeMonitor.ResetSenderFee(); + SendersFeeMonitor = new SendersFeeMonitor(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs index 38001637cb..0728e2779d 100644 --- a/neo/Consensus/ConsensusService.cs +++ b/neo/Consensus/ConsensusService.cs @@ -424,7 +424,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m context.Block.ConsensusData.Nonce = message.Nonce; context.TransactionHashes = message.TransactionHashes; context.Transactions = new Dictionary(); - context.SendersFeeMonitor.ResetSenderFee(); + context.SendersFeeMonitor = new SendersFeeMonitor(); for (int i = 0; i < context.PreparationPayloads.Length; i++) if (context.PreparationPayloads[i] != null) if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash)) diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index cb088fcaa1..8f37855a5c 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -72,7 +72,7 @@ public class MemoryPool : IReadOnlyCollection /// /// Store all verified unsorted transactions' senders' fee currently in the memory pool. /// - public readonly SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); + public SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor(); /// /// Total count of transactions in the pool. @@ -344,7 +344,7 @@ internal void InvalidateVerifiedTransactions() // Clear the verified transactions now, since they all must be reverified. _unsortedTransactions.Clear(); - SendersFeeMonitor.ResetSenderFee(); + SendersFeeMonitor = new SendersFeeMonitor(); _sortedTransactions.Clear(); } diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs index c83aafa968..274f2e40ec 100644 --- a/neo/Ledger/SendersFeeMonitor.cs +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -12,7 +12,7 @@ public class SendersFeeMonitor /// /// Store all verified unsorted transactions' senders' fee currently in the memory pool. /// - private Dictionary _senderFee = new Dictionary(); + private readonly Dictionary _senderFee = new Dictionary(); public BigInteger GetSenderFee(UInt160 sender) { @@ -42,12 +42,5 @@ public void RemoveSenderFee(Transaction tx) if (_senderFee[tx.Sender] == 0) _senderFee.Remove(tx.Sender); _senderFeeRwLock.ExitWriteLock(); } - - public void ResetSenderFee() - { - _senderFeeRwLock.EnterWriteLock(); - _senderFee = new Dictionary(); - _senderFeeRwLock.ExitWriteLock(); - } } } From 0f60099de5e7a8474df46a8e815efb903b6bcd34 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 6 Nov 2019 12:58:42 +0100 Subject: [PATCH 16/17] Optimization --- neo/Ledger/SendersFeeMonitor.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs index 274f2e40ec..66331f8bc0 100644 --- a/neo/Ledger/SendersFeeMonitor.cs +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -17,12 +17,10 @@ public class SendersFeeMonitor public BigInteger GetSenderFee(UInt160 sender) { _senderFeeRwLock.EnterReadLock(); - bool recorded = _senderFee.TryGetValue(sender, out var value); + if (!_senderFee.TryGetValue(sender, out var value)) + value = BigInteger.Zero; _senderFeeRwLock.ExitReadLock(); - if (recorded) - return value; - else - return BigInteger.Zero; + return value; } public void AddSenderFee(Transaction tx) From bb3a0f536b0b7990ff3d9c930329877be5d3c713 Mon Sep 17 00:00:00 2001 From: Jin Qiao Date: Thu, 7 Nov 2019 10:42:13 +0800 Subject: [PATCH 17/17] Code optimization --- neo/Ledger/SendersFeeMonitor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/neo/Ledger/SendersFeeMonitor.cs b/neo/Ledger/SendersFeeMonitor.cs index 66331f8bc0..efe3ac6ebe 100644 --- a/neo/Ledger/SendersFeeMonitor.cs +++ b/neo/Ledger/SendersFeeMonitor.cs @@ -36,8 +36,7 @@ public void AddSenderFee(Transaction tx) public void RemoveSenderFee(Transaction tx) { _senderFeeRwLock.EnterWriteLock(); - _senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee; - if (_senderFee[tx.Sender] == 0) _senderFee.Remove(tx.Sender); + if ((_senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee) == 0) _senderFee.Remove(tx.Sender); _senderFeeRwLock.ExitWriteLock(); } }