From fcc2c88a3236439f74cabbd1f88b741bdc391861 Mon Sep 17 00:00:00 2001 From: jsolman Date: Tue, 15 Jan 2019 18:09:12 -0800 Subject: [PATCH 1/2] Add MemoryPool Unit tests. Fix bug on initital start of Persisting the Genesis block. --- neo.UnitTests/TestDataCache.cs | 16 ++- neo.UnitTests/UT_MemoryPool.cs | 189 +++++++++++++++++++++++++++++++++ neo/Ledger/MemoryPool.cs | 6 +- 3 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 neo.UnitTests/UT_MemoryPool.cs diff --git a/neo.UnitTests/TestDataCache.cs b/neo.UnitTests/TestDataCache.cs index d2d3afdabf..68f3b07da7 100644 --- a/neo.UnitTests/TestDataCache.cs +++ b/neo.UnitTests/TestDataCache.cs @@ -10,6 +10,17 @@ public class TestDataCache : DataCache where TKey : IEquatable, ISerializable where TValue : class, ICloneable, ISerializable, new() { + private readonly TValue _defaultValue; + + public TestDataCache() + { + _defaultValue = null; + } + + public TestDataCache(TValue defaultValue) + { + this._defaultValue = defaultValue; + } public override void DeleteInternal(TKey key) { } @@ -25,12 +36,13 @@ protected override IEnumerable> FindInternal(byte[] k protected override TValue GetInternal(TKey key) { - throw new NotImplementedException(); + if (_defaultValue == null) throw new NotImplementedException(); + return _defaultValue; } protected override TValue TryGetInternal(TKey key) { - return null; + return _defaultValue; } protected override void UpdateInternal(TKey key, TValue value) diff --git a/neo.UnitTests/UT_MemoryPool.cs b/neo.UnitTests/UT_MemoryPool.cs new file mode 100644 index 0000000000..380ac121d8 --- /dev/null +++ b/neo.UnitTests/UT_MemoryPool.cs @@ -0,0 +1,189 @@ +using System; +using System.Linq; +using System.Reflection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Neo.Ledger; +using FluentAssertions; +using Neo.Cryptography.ECC; +using Neo.IO.Wrappers; +using Neo.Network.P2P.Payloads; +using Neo.Persistence; + +namespace Neo.UnitTests +{ + [TestClass] + public class UT_MemoryPool + { + private Random _random = new Random(); + + private MemoryPool unit; + + [TestInitialize] + public void TestSetup() + { + var mockSnapshot = new Mock(); + mockSnapshot.SetupGet(p => p.Blocks).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Transactions).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Accounts).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.UnspentCoins).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.SpentCoins).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Validators).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Assets).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.HeaderHashList).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache()); + mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache()); + mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache()); + + var mockStore = new Mock(); + + var defaultTx = CreateRandomHashInvocationTransaction(); + defaultTx.Outputs = new TransactionOutput[1]; + defaultTx.Outputs[0] = new TransactionOutput + { + AssetId = Blockchain.UtilityToken.Hash, + Value = new Fixed8(1000000), // 0.001 GAS (enough to be a high priority TX + ScriptHash = UInt160.Zero // doesn't matter for our purposes. + }; + + mockStore.Setup(p => p.GetBlocks()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetTransactions()).Returns(new TestDataCache(new TransactionState + { + BlockIndex = 1, + Transaction = defaultTx + })); + + mockStore.Setup(p => p.GetAccounts()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetUnspentCoins()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetSpentCoins()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetValidators()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetAssets()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetContracts()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetStorages()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object); + + Console.WriteLine("initialize NeoSystem"); + var mockNeoSystem = new NeoSystem(mockStore.Object);// new Mock(mockStore.Object); + // NeoSystem mockNeoSystem = null; + + // Create a MemoryPool with capacity of 100 + unit = new MemoryPool(mockNeoSystem, 100); + + // Verify capacity equals the amount specified + unit.Capacity.ShouldBeEquivalentTo(100); + + unit.VerifiedCount.ShouldBeEquivalentTo(0); + unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + unit.Count.ShouldBeEquivalentTo(0); + } + + private Transaction CreateRandomHashInvocationTransaction() + { + var tx = new InvocationTransaction(); + var randomBytes = new byte[16]; + _random.NextBytes(randomBytes); + tx.Script = randomBytes; + tx.Attributes = new TransactionAttribute[0]; + tx.Inputs = new CoinReference[0]; + tx.Outputs = new TransactionOutput[0]; + tx.Witnesses = new Witness[0]; + // Force getting the references + // Console.WriteLine($"Reference Count: {tx.References.Count}"); + return tx; + } + + private Transaction CreateMockHighPriorityTransaction() + { + var tx = CreateRandomHashInvocationTransaction(); + tx.Inputs = new CoinReference[1]; + // Any input will trigger reading the transaction output and get our mocked transaction output. + tx.Inputs[0] = new CoinReference + { + PrevHash = UInt256.Zero, + PrevIndex = 0 + }; + return tx; + } + + + private Transaction CreateMockLowPriorityTransaction() + { + return CreateRandomHashInvocationTransaction(); + } + + private void AddTransactions(int count, bool isHighPriority=false) + { + for (int i = 0; i < count; i++) + { + var lowPrioTx = isHighPriority ? CreateMockHighPriorityTransaction(): CreateMockLowPriorityTransaction(); + Console.WriteLine($"created tx: {lowPrioTx.Hash}"); + unit.TryAdd(lowPrioTx.Hash, lowPrioTx); + } + } + + private void AddLowPriorityTransactions(int count) => AddTransactions(count); + public void AddHighPriorityTransactions(int count) => AddTransactions(count, true); + + + [TestMethod] + public void LowPriorityCapacityTest() + { + // Add over the capacity items, verify that the verified count increases each time + AddLowPriorityTransactions(50); + unit.VerifiedCount.ShouldBeEquivalentTo(50); + AddLowPriorityTransactions(51); + Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); + unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(100); + unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(0); + + unit.VerifiedCount.ShouldBeEquivalentTo(100); + unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + unit.Count.ShouldBeEquivalentTo(100); + } + + [TestMethod] + public void HighPriorityCapacityTest() + { + // Add over the capacity items, verify that the verified count increases each time + AddHighPriorityTransactions(101); + + Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); + unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(0); + unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(100); + + unit.VerifiedCount.ShouldBeEquivalentTo(100); + unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + unit.Count.ShouldBeEquivalentTo(100); + } + + [TestMethod] + public void HighPriorityPushesOutLowPriority() + { + // Add over the capacity items, verify that the verified count increases each time + AddLowPriorityTransactions(70); + AddHighPriorityTransactions(40); + + Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); + unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(60); + unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(40); + unit.Count.ShouldBeEquivalentTo(100); + } + + [TestMethod] + public void LowPriorityDoesNotPushOutHighPrority() + { + AddHighPriorityTransactions(70); + AddLowPriorityTransactions(40); + + unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(30); + unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(70); + unit.Count.ShouldBeEquivalentTo(100); + } + } +} \ No newline at end of file diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 1d05679934..174934b2ef 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -92,6 +92,10 @@ public int CompareTo(PoolItem otherItem) private readonly SortedSet _unverifiedSortedHighPriorityTransactions = new SortedSet(); private readonly SortedSet _unverifiedSortedLowPriorityTransactions = new SortedSet(); + // internal methods to aid in unit testing + internal int SortedLowPrioTxCount => _sortedLowPrioTransactions.Count; + internal int SortedHighPrioTxCount => _sortedHighPrioTransactions.Count; + private int _maxTxPerBlock; private int _maxLowPriorityTxPerBlock; @@ -401,7 +405,7 @@ internal void UpdatePoolForBlockPersisted(Block block, Snapshot snapshot) // If we know about headers of future blocks, no point in verifying transactions from the unverified tx pool // until we get caught up. - if (block.Index < Blockchain.Singleton.HeaderHeight) + if (block.Index > 0 && block.Index < Blockchain.Singleton.HeaderHeight) return; if (Plugin.Policies.Count == 0) From ffc3651e6a32508b328cf514882a94860fe48015 Mon Sep 17 00:00:00 2001 From: jsolman Date: Tue, 15 Jan 2019 19:16:57 -0800 Subject: [PATCH 2/2] Only create the NeoSystem once. Add additional unit test. --- neo.UnitTests/UT_MemoryPool.cs | 175 +++++++++++++++++++-------------- neo/Ledger/MemoryPool.cs | 14 ++- 2 files changed, 109 insertions(+), 80 deletions(-) diff --git a/neo.UnitTests/UT_MemoryPool.cs b/neo.UnitTests/UT_MemoryPool.cs index 380ac121d8..e9094ece93 100644 --- a/neo.UnitTests/UT_MemoryPool.cs +++ b/neo.UnitTests/UT_MemoryPool.cs @@ -15,72 +15,78 @@ namespace Neo.UnitTests [TestClass] public class UT_MemoryPool { - private Random _random = new Random(); + private static NeoSystem TheNeoSystem; - private MemoryPool unit; + private readonly Random _random = new Random(); + + private MemoryPool _unit; [TestInitialize] public void TestSetup() { - var mockSnapshot = new Mock(); - mockSnapshot.SetupGet(p => p.Blocks).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Transactions).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Accounts).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.UnspentCoins).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.SpentCoins).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Validators).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Assets).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.HeaderHashList).Returns(new TestDataCache()); - mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache()); - mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache()); - mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache()); - - var mockStore = new Mock(); - - var defaultTx = CreateRandomHashInvocationTransaction(); - defaultTx.Outputs = new TransactionOutput[1]; - defaultTx.Outputs[0] = new TransactionOutput + if (TheNeoSystem == null) { - AssetId = Blockchain.UtilityToken.Hash, - Value = new Fixed8(1000000), // 0.001 GAS (enough to be a high priority TX - ScriptHash = UInt160.Zero // doesn't matter for our purposes. - }; - - mockStore.Setup(p => p.GetBlocks()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetTransactions()).Returns(new TestDataCache(new TransactionState + var mockSnapshot = new Mock(); + mockSnapshot.SetupGet(p => p.Blocks).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Transactions).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Accounts).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.UnspentCoins).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.SpentCoins).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Validators).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Assets).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.HeaderHashList) + .Returns(new TestDataCache()); + mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache()); + mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache()); + mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache()); + + var mockStore = new Mock(); + + var defaultTx = CreateRandomHashInvocationTransaction(); + defaultTx.Outputs = new TransactionOutput[1]; + defaultTx.Outputs[0] = new TransactionOutput { - BlockIndex = 1, - Transaction = defaultTx - })); - - mockStore.Setup(p => p.GetAccounts()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetUnspentCoins()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetSpentCoins()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetValidators()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetAssets()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetContracts()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetStorages()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache()); - mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache()); - mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache()); - mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache()); - mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object); - - Console.WriteLine("initialize NeoSystem"); - var mockNeoSystem = new NeoSystem(mockStore.Object);// new Mock(mockStore.Object); - // NeoSystem mockNeoSystem = null; + AssetId = Blockchain.UtilityToken.Hash, + Value = new Fixed8(1000000), // 0.001 GAS (enough to be a high priority TX + ScriptHash = UInt160.Zero // doesn't matter for our purposes. + }; + + mockStore.Setup(p => p.GetBlocks()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetTransactions()).Returns(new TestDataCache( + new TransactionState + { + BlockIndex = 1, + Transaction = defaultTx + })); + + mockStore.Setup(p => p.GetAccounts()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetUnspentCoins()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetSpentCoins()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetValidators()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetAssets()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetContracts()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetStorages()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache()); + mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object); + + Console.WriteLine("initialize NeoSystem"); + TheNeoSystem = new NeoSystem(mockStore.Object); // new Mock(mockStore.Object); + } // Create a MemoryPool with capacity of 100 - unit = new MemoryPool(mockNeoSystem, 100); + _unit = new MemoryPool(TheNeoSystem, 100); // Verify capacity equals the amount specified - unit.Capacity.ShouldBeEquivalentTo(100); + _unit.Capacity.ShouldBeEquivalentTo(100); - unit.VerifiedCount.ShouldBeEquivalentTo(0); - unit.UnVerifiedCount.ShouldBeEquivalentTo(0); - unit.Count.ShouldBeEquivalentTo(0); + _unit.VerifiedCount.ShouldBeEquivalentTo(0); + _unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + _unit.Count.ShouldBeEquivalentTo(0); } private Transaction CreateRandomHashInvocationTransaction() @@ -123,7 +129,7 @@ private void AddTransactions(int count, bool isHighPriority=false) { var lowPrioTx = isHighPriority ? CreateMockHighPriorityTransaction(): CreateMockLowPriorityTransaction(); Console.WriteLine($"created tx: {lowPrioTx.Hash}"); - unit.TryAdd(lowPrioTx.Hash, lowPrioTx); + _unit.TryAdd(lowPrioTx.Hash, lowPrioTx); } } @@ -136,15 +142,15 @@ public void LowPriorityCapacityTest() { // Add over the capacity items, verify that the verified count increases each time AddLowPriorityTransactions(50); - unit.VerifiedCount.ShouldBeEquivalentTo(50); + _unit.VerifiedCount.ShouldBeEquivalentTo(50); AddLowPriorityTransactions(51); - Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); - unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(100); - unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(0); + Console.WriteLine($"VerifiedCount: {_unit.VerifiedCount} LowPrioCount {_unit.SortedLowPrioTxCount} HighPrioCount {_unit.SortedHighPrioTxCount}"); + _unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(100); + _unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(0); - unit.VerifiedCount.ShouldBeEquivalentTo(100); - unit.UnVerifiedCount.ShouldBeEquivalentTo(0); - unit.Count.ShouldBeEquivalentTo(100); + _unit.VerifiedCount.ShouldBeEquivalentTo(100); + _unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + _unit.Count.ShouldBeEquivalentTo(100); } [TestMethod] @@ -153,13 +159,13 @@ public void HighPriorityCapacityTest() // Add over the capacity items, verify that the verified count increases each time AddHighPriorityTransactions(101); - Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); - unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(0); - unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(100); + Console.WriteLine($"VerifiedCount: {_unit.VerifiedCount} LowPrioCount {_unit.SortedLowPrioTxCount} HighPrioCount {_unit.SortedHighPrioTxCount}"); + _unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(0); + _unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(100); - unit.VerifiedCount.ShouldBeEquivalentTo(100); - unit.UnVerifiedCount.ShouldBeEquivalentTo(0); - unit.Count.ShouldBeEquivalentTo(100); + _unit.VerifiedCount.ShouldBeEquivalentTo(100); + _unit.UnVerifiedCount.ShouldBeEquivalentTo(0); + _unit.Count.ShouldBeEquivalentTo(100); } [TestMethod] @@ -169,10 +175,10 @@ public void HighPriorityPushesOutLowPriority() AddLowPriorityTransactions(70); AddHighPriorityTransactions(40); - Console.WriteLine($"VerifiedCount: {unit.VerifiedCount} LowPrioCount {unit.SortedLowPrioTxCount} HighPrioCount {unit.SortedHighPrioTxCount}"); - unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(60); - unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(40); - unit.Count.ShouldBeEquivalentTo(100); + Console.WriteLine($"VerifiedCount: {_unit.VerifiedCount} LowPrioCount {_unit.SortedLowPrioTxCount} HighPrioCount {_unit.SortedHighPrioTxCount}"); + _unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(60); + _unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(40); + _unit.Count.ShouldBeEquivalentTo(100); } [TestMethod] @@ -181,9 +187,28 @@ public void LowPriorityDoesNotPushOutHighPrority() AddHighPriorityTransactions(70); AddLowPriorityTransactions(40); - unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(30); - unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(70); - unit.Count.ShouldBeEquivalentTo(100); + _unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(30); + _unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(70); + _unit.Count.ShouldBeEquivalentTo(100); + } + + [TestMethod] + public void BlockPersistMovesTxToUnverified() + { + AddLowPriorityTransactions(30); + AddHighPriorityTransactions(70); + + + var block = new Block + { + Transactions = _unit.GetSortedVerifiedTransactions().Take(10) + .Concat(_unit.GetSortedVerifiedTransactions().Where(x => x.IsLowPriority).Take(5)).ToArray() + }; + _unit.UpdatePoolForBlockPersisted(block, Blockchain.Singleton.GetSnapshot()); + _unit.SortedLowPrioTxCount.ShouldBeEquivalentTo(0); + _unit.SortedHighPrioTxCount.ShouldBeEquivalentTo(0); + _unit.UnverifiedSortedHighPrioTxCount.ShouldBeEquivalentTo(60); + _unit.UnverifiedSortedLowPrioTxCount.ShouldBeEquivalentTo(25); } } } \ No newline at end of file diff --git a/neo/Ledger/MemoryPool.cs b/neo/Ledger/MemoryPool.cs index 174934b2ef..67de6f05a1 100644 --- a/neo/Ledger/MemoryPool.cs +++ b/neo/Ledger/MemoryPool.cs @@ -73,13 +73,14 @@ public int CompareTo(PoolItem otherItem) /// private readonly Dictionary _unsortedTransactions = new Dictionary(); /// - /// Stores the verified low priority sorted transactions currently in the pool. - /// - private readonly SortedSet _sortedLowPrioTransactions = new SortedSet(); - /// /// Stores the verified high priority sorted transactins currently in the pool. /// private readonly SortedSet _sortedHighPrioTransactions = new SortedSet(); + /// + /// Stores the verified low priority sorted transactions currently in the pool. + /// + private readonly SortedSet _sortedLowPrioTransactions = new SortedSet(); + /// /// Store the unverified transactions currently in the pool. @@ -93,8 +94,11 @@ public int CompareTo(PoolItem otherItem) private readonly SortedSet _unverifiedSortedLowPriorityTransactions = new SortedSet(); // internal methods to aid in unit testing - internal int SortedLowPrioTxCount => _sortedLowPrioTransactions.Count; internal int SortedHighPrioTxCount => _sortedHighPrioTransactions.Count; + internal int SortedLowPrioTxCount => _sortedLowPrioTransactions.Count; + internal int UnverifiedSortedHighPrioTxCount => _unverifiedSortedHighPriorityTransactions.Count; + internal int UnverifiedSortedLowPrioTxCount => _unverifiedSortedLowPriorityTransactions.Count; + private int _maxTxPerBlock; private int _maxLowPriorityTxPerBlock;