Skip to content

Commit

Permalink
Only create the NeoSystem once. Add additional unit test.
Browse files Browse the repository at this point in the history
  • Loading branch information
jsolman committed Jan 16, 2019
1 parent fcc2c88 commit ffc3651
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 80 deletions.
175 changes: 100 additions & 75 deletions neo.UnitTests/UT_MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Snapshot>();
mockSnapshot.SetupGet(p => p.Blocks).Returns(new TestDataCache<UInt256, BlockState>());
mockSnapshot.SetupGet(p => p.Transactions).Returns(new TestDataCache<UInt256, TransactionState>());
mockSnapshot.SetupGet(p => p.Accounts).Returns(new TestDataCache<UInt160, AccountState>());
mockSnapshot.SetupGet(p => p.UnspentCoins).Returns(new TestDataCache<UInt256, UnspentCoinState>());
mockSnapshot.SetupGet(p => p.SpentCoins).Returns(new TestDataCache<UInt256, SpentCoinState>());
mockSnapshot.SetupGet(p => p.Validators).Returns(new TestDataCache<ECPoint, ValidatorState>());
mockSnapshot.SetupGet(p => p.Assets).Returns(new TestDataCache<UInt256, AssetState>());
mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache<UInt160, ContractState>());
mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache<StorageKey, StorageItem>());
mockSnapshot.SetupGet(p => p.HeaderHashList).Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache<ValidatorsCountState>());
mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache<HashIndexState>());
mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache<HashIndexState>());

var mockStore = new Mock<Store>();

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<UInt256, BlockState>());
mockStore.Setup(p => p.GetTransactions()).Returns(new TestDataCache<UInt256, TransactionState>(new TransactionState
var mockSnapshot = new Mock<Snapshot>();
mockSnapshot.SetupGet(p => p.Blocks).Returns(new TestDataCache<UInt256, BlockState>());
mockSnapshot.SetupGet(p => p.Transactions).Returns(new TestDataCache<UInt256, TransactionState>());
mockSnapshot.SetupGet(p => p.Accounts).Returns(new TestDataCache<UInt160, AccountState>());
mockSnapshot.SetupGet(p => p.UnspentCoins).Returns(new TestDataCache<UInt256, UnspentCoinState>());
mockSnapshot.SetupGet(p => p.SpentCoins).Returns(new TestDataCache<UInt256, SpentCoinState>());
mockSnapshot.SetupGet(p => p.Validators).Returns(new TestDataCache<ECPoint, ValidatorState>());
mockSnapshot.SetupGet(p => p.Assets).Returns(new TestDataCache<UInt256, AssetState>());
mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache<UInt160, ContractState>());
mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache<StorageKey, StorageItem>());
mockSnapshot.SetupGet(p => p.HeaderHashList)
.Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache<ValidatorsCountState>());
mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache<HashIndexState>());
mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache<HashIndexState>());

var mockStore = new Mock<Store>();

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<UInt160, AccountState>());
mockStore.Setup(p => p.GetUnspentCoins()).Returns(new TestDataCache<UInt256, UnspentCoinState>());
mockStore.Setup(p => p.GetSpentCoins()).Returns(new TestDataCache<UInt256, SpentCoinState>());
mockStore.Setup(p => p.GetValidators()).Returns(new TestDataCache<ECPoint, ValidatorState>());
mockStore.Setup(p => p.GetAssets()).Returns(new TestDataCache<UInt256, AssetState>());
mockStore.Setup(p => p.GetContracts()).Returns(new TestDataCache<UInt160, ContractState>());
mockStore.Setup(p => p.GetStorages()).Returns(new TestDataCache<StorageKey, StorageItem>());
mockStore.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache<ValidatorsCountState>());
mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object);

Console.WriteLine("initialize NeoSystem");
var mockNeoSystem = new NeoSystem(mockStore.Object);// new Mock<NeoSystem>(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<UInt256, BlockState>());
mockStore.Setup(p => p.GetTransactions()).Returns(new TestDataCache<UInt256, TransactionState>(
new TransactionState
{
BlockIndex = 1,
Transaction = defaultTx
}));

mockStore.Setup(p => p.GetAccounts()).Returns(new TestDataCache<UInt160, AccountState>());
mockStore.Setup(p => p.GetUnspentCoins()).Returns(new TestDataCache<UInt256, UnspentCoinState>());
mockStore.Setup(p => p.GetSpentCoins()).Returns(new TestDataCache<UInt256, SpentCoinState>());
mockStore.Setup(p => p.GetValidators()).Returns(new TestDataCache<ECPoint, ValidatorState>());
mockStore.Setup(p => p.GetAssets()).Returns(new TestDataCache<UInt256, AssetState>());
mockStore.Setup(p => p.GetContracts()).Returns(new TestDataCache<UInt160, ContractState>());
mockStore.Setup(p => p.GetStorages()).Returns(new TestDataCache<StorageKey, StorageItem>());
mockStore.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache<ValidatorsCountState>());
mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object);

Console.WriteLine("initialize NeoSystem");
TheNeoSystem = new NeoSystem(mockStore.Object); // new Mock<NeoSystem>(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()
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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);
}
}
}
14 changes: 9 additions & 5 deletions neo/Ledger/MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ public int CompareTo(PoolItem otherItem)
/// </summary>
private readonly Dictionary<UInt256, PoolItem> _unsortedTransactions = new Dictionary<UInt256, PoolItem>();
/// <summary>
/// Stores the verified low priority sorted transactions currently in the pool.
/// </summary>
private readonly SortedSet<PoolItem> _sortedLowPrioTransactions = new SortedSet<PoolItem>();
/// <summary>
/// Stores the verified high priority sorted transactins currently in the pool.
/// </summary>
private readonly SortedSet<PoolItem> _sortedHighPrioTransactions = new SortedSet<PoolItem>();
/// <summary>
/// Stores the verified low priority sorted transactions currently in the pool.
/// </summary>
private readonly SortedSet<PoolItem> _sortedLowPrioTransactions = new SortedSet<PoolItem>();


/// <summary>
/// Store the unverified transactions currently in the pool.
Expand All @@ -93,8 +94,11 @@ public int CompareTo(PoolItem otherItem)
private readonly SortedSet<PoolItem> _unverifiedSortedLowPriorityTransactions = new SortedSet<PoolItem>();

// 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;
Expand Down

0 comments on commit ffc3651

Please sign in to comment.