From a1291a6c38e01c4f322c2131f49ff31c2e2633a0 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 6 Feb 2024 17:33:31 +0100 Subject: [PATCH] Fix ut (#3113) * Fix ut * Clean code * clean * Rename to Clear * Revert remove * Clean using * Rename to Reset * AggressiveInlining --------- Co-authored-by: Jimmy --- benchmarks/Neo.Benchmarks/Benchmarks.cs | 3 +- src/Neo.CLI/CLI/MainService.cs | 4 ++- src/Neo/NeoSystem.cs | 11 +++---- src/Neo/Persistence/MemoryStore.cs | 30 +++++++++++++------ src/Neo/Persistence/StoreFactory.cs | 14 ++++++++- tests/Neo.UnitTests/Ledger/UT_Blockchain.cs | 6 ++++ tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs | 4 +-- .../Network/P2P/Payloads/UT_Transaction.cs | 6 ++++ .../SmartContract/Native/UT_RoleManagement.cs | 6 ++++ tests/Neo.UnitTests/TestBlockchain.cs | 11 ++++++- tests/Neo.UnitTests/Wallets/UT_Wallet.cs | 9 ------ 11 files changed, 73 insertions(+), 31 deletions(-) diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.cs b/benchmarks/Neo.Benchmarks/Benchmarks.cs index 3df349e61e..5c3389407c 100644 --- a/benchmarks/Neo.Benchmarks/Benchmarks.cs +++ b/benchmarks/Neo.Benchmarks/Benchmarks.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Network.P2P.Payloads; +using Neo.Persistence; using Neo.SmartContract; using Neo.VM; using System.Diagnostics; @@ -19,7 +20,7 @@ namespace Neo; static class Benchmarks { private static readonly ProtocolSettings protocol = ProtocolSettings.Load("config.json"); - private static readonly NeoSystem system = new(protocol); + private static readonly NeoSystem system = new(protocol, new MemoryStore()); public static void NeoIssue2725() { diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs index 68b82de8cc..abd23121f7 100644 --- a/src/Neo.CLI/CLI/MainService.cs +++ b/src/Neo.CLI/CLI/MainService.cs @@ -17,6 +17,7 @@ using Neo.Ledger; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; +using Neo.Persistence; using Neo.Plugins; using Neo.SmartContract; using Neo.SmartContract.Manifest; @@ -376,7 +377,8 @@ public async void Start(CommandLineOptions options) ProtocolSettings protocol = ProtocolSettings.Load("config.json"); CustomProtocolSettings(options, protocol); CustomApplicationSettings(options, Settings.Default); - NeoSystem = new NeoSystem(protocol, Settings.Default.Storage.Engine, string.Format(Settings.Default.Storage.Path, protocol.Network.ToString("X8"))); + var store = StoreFactory.GetStore(Settings.Default.Storage.Engine, string.Format(Settings.Default.Storage.Path, protocol.Network.ToString("X8"))); + NeoSystem = new NeoSystem(protocol, store); NeoSystem.AddService(this); LocalNode = NeoSystem.LocalNode.Ask(new LocalNode.GetInstance()).Result; diff --git a/src/Neo/NeoSystem.cs b/src/Neo/NeoSystem.cs index 3a148d612d..4713c284ff 100644 --- a/src/Neo/NeoSystem.cs +++ b/src/Neo/NeoSystem.cs @@ -97,7 +97,6 @@ public class NeoSystem : IDisposable internal RelayCache RelayCache { get; } = new(100); private ImmutableList services = ImmutableList.Empty; - private readonly string storage_engine; private readonly IStore store; private ChannelsConfig start_message = null; private int suspend = 0; @@ -114,14 +113,12 @@ static NeoSystem() /// Initializes a new instance of the class. /// /// The protocol settings of the . - /// The storage engine used to create the objects. If this parameter is , a default in-memory storage engine will be used. - /// The path of the storage. If is the default in-memory storage engine, this parameter is ignored. - public NeoSystem(ProtocolSettings settings, string storageEngine = null, string storagePath = null) + /// The to use. + public NeoSystem(ProtocolSettings settings, IStore storage) { this.Settings = settings; this.GenesisBlock = CreateGenesisBlock(settings); - this.storage_engine = storageEngine ?? nameof(MemoryStore); - this.store = LoadStore(storagePath); + this.store = storage; this.MemPool = new MemoryPool(this); this.Blockchain = ActorSystem.ActorOf(Ledger.Blockchain.Props(this)); this.LocalNode = ActorSystem.ActorOf(Network.P2P.LocalNode.Props(this)); @@ -218,7 +215,7 @@ public void EnsureStopped(IActorRef actor) /// The loaded . public IStore LoadStore(string path) { - return StoreFactory.GetStore(storage_engine, path); + return StoreFactory.GetStore(store.GetType().Name, path); } /// diff --git a/src/Neo/Persistence/MemoryStore.cs b/src/Neo/Persistence/MemoryStore.cs index 91d542a94b..191b89ea4f 100644 --- a/src/Neo/Persistence/MemoryStore.cs +++ b/src/Neo/Persistence/MemoryStore.cs @@ -13,6 +13,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; namespace Neo.Persistence { @@ -21,33 +22,36 @@ namespace Neo.Persistence /// public class MemoryStore : IStore { - private readonly ConcurrentDictionary innerData = new(ByteArrayEqualityComparer.Default); + private readonly ConcurrentDictionary _innerData = new(ByteArrayEqualityComparer.Default); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Delete(byte[] key) { - innerData.TryRemove(key, out _); + _innerData.TryRemove(key, out _); } public void Dispose() { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ISnapshot GetSnapshot() { - return new MemorySnapshot(innerData); + return new MemorySnapshot(_innerData); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Put(byte[] key, byte[] value) { - innerData[key[..]] = value[..]; + _innerData[key[..]] = value[..]; } public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward) { if (direction == SeekDirection.Backward && keyOrPrefix?.Length == 0) yield break; - ByteArrayComparer comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse; - IEnumerable> records = innerData; + var comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse; + IEnumerable> records = _innerData; if (keyOrPrefix?.Length > 0) records = records.Where(p => comparer.Compare(p.Key, keyOrPrefix) >= 0); records = records.OrderBy(p => p.Key, comparer); @@ -55,15 +59,23 @@ public void Put(byte[] key, byte[] value) yield return (pair.Key[..], pair.Value[..]); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] TryGet(byte[] key) { - innerData.TryGetValue(key, out byte[] value); - return value?[..]; + if (!_innerData.TryGetValue(key, out byte[] value)) return null; + return value[..]; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(byte[] key) { - return innerData.ContainsKey(key); + return _innerData.ContainsKey(key); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void Reset() + { + _innerData.Clear(); } } } diff --git a/src/Neo/Persistence/StoreFactory.cs b/src/Neo/Persistence/StoreFactory.cs index 66d600f546..622c152acf 100644 --- a/src/Neo/Persistence/StoreFactory.cs +++ b/src/Neo/Persistence/StoreFactory.cs @@ -25,7 +25,13 @@ private class MemoryStoreProvider : IStoreProvider static StoreFactory() { - RegisterProvider(new MemoryStoreProvider()); + var memProvider = new MemoryStoreProvider(); + RegisterProvider(memProvider); + + // Default cases + + providers.Add("", memProvider); + providers.Add(null, memProvider); } public static void RegisterProvider(IStoreProvider provider) @@ -33,6 +39,12 @@ public static void RegisterProvider(IStoreProvider provider) providers.Add(provider.Name, provider); } + /// + /// Get store from name + /// + /// The storage engine used to create the objects. If this parameter is , a default in-memory storage engine will be used. + /// The path of the storage. If is the default in-memory storage engine, this parameter is ignored. + /// The storage engine. public static IStore GetStore(string storageEngine, string path) { return providers[storageEngine].GetStore(path); diff --git a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs index c6e818cdf7..491b4fe21e 100644 --- a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs +++ b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs @@ -48,6 +48,12 @@ public void Initialize() system.MemPool.TryAdd(txSample, TestBlockchain.GetTestSnapshot()); } + [TestCleanup] + public void Clean() + { + TestBlockchain.ResetStore(); + } + [TestMethod] public void TestValidTransaction() { diff --git a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs index 06324b6675..784a1d9b5e 100644 --- a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -57,7 +57,7 @@ public void TestSetup() TimeProvider.ResetToDefault(); // Create a MemoryPool with capacity of 100 - _unit = new MemoryPool(new NeoSystem(TestProtocolSettings.Default with { MemoryPoolMaxTransactions = 100 })); + _unit = new MemoryPool(new NeoSystem(TestProtocolSettings.Default with { MemoryPoolMaxTransactions = 100 }, new MemoryStore())); // Verify capacity equals the amount specified _unit.Capacity.Should().Be(100); @@ -648,7 +648,7 @@ public void TestGetVerifiedTransactions() [TestMethod] public void TestReVerifyTopUnverifiedTransactionsIfNeeded() { - _unit = new MemoryPool(new NeoSystem(TestProtocolSettings.Default with { MemoryPoolMaxTransactions = 600 })); + _unit = new MemoryPool(new NeoSystem(TestProtocolSettings.Default with { MemoryPoolMaxTransactions = 600 }, new MemoryStore())); AddTransaction(CreateTransaction(100000001)); AddTransaction(CreateTransaction(100000001)); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index ecb6d1874b..43755374d3 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -38,6 +38,12 @@ public void TestSetup() uut = new Transaction(); } + [TestCleanup] + public void Clean() + { + TestBlockchain.ResetStore(); + } + [TestMethod] public void Script_Get() { diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs index 419ce213fc..a87c630194 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs @@ -36,6 +36,12 @@ public void TestSetup() _snapshot = TestBlockchain.GetTestSnapshot(); } + [TestCleanup] + public void Clean() + { + TestBlockchain.ResetStore(); + } + [TestMethod] public void TestSetAndGet() { diff --git a/tests/Neo.UnitTests/TestBlockchain.cs b/tests/Neo.UnitTests/TestBlockchain.cs index 5e24aca099..cbdd6c1c12 100644 --- a/tests/Neo.UnitTests/TestBlockchain.cs +++ b/tests/Neo.UnitTests/TestBlockchain.cs @@ -9,6 +9,8 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Akka.Actor; +using Neo.Ledger; using Neo.Persistence; using System; @@ -18,11 +20,18 @@ public static class TestBlockchain { public static readonly NeoSystem TheNeoSystem; public static readonly UInt160[] DefaultExtensibleWitnessWhiteList; + private static readonly MemoryStore Store = new(); static TestBlockchain() { Console.WriteLine("initialize NeoSystem"); - TheNeoSystem = new NeoSystem(TestProtocolSettings.Default, null, null); + TheNeoSystem = new NeoSystem(TestProtocolSettings.Default, Store); + } + + internal static void ResetStore() + { + Store.Reset(); + TheNeoSystem.Blockchain.Ask(new Blockchain.Initialize()).Wait(); } internal static DataCache GetTestSnapshot() diff --git a/tests/Neo.UnitTests/Wallets/UT_Wallet.cs b/tests/Neo.UnitTests/Wallets/UT_Wallet.cs index 17604cd75c..d134c6aed3 100644 --- a/tests/Neo.UnitTests/Wallets/UT_Wallet.cs +++ b/tests/Neo.UnitTests/Wallets/UT_Wallet.cs @@ -221,13 +221,11 @@ public void TestGetAvailable() var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); wallet.GetAvailable(snapshot, NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; - snapshot.Commit(); } [TestMethod] @@ -243,14 +241,12 @@ public void TestGetBalance() var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 10000 * NativeContract.GAS.Factor; - snapshot.Commit(); wallet.GetBalance(snapshot, UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(BigInteger.Zero, 0)); wallet.GetBalance(snapshot, NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8)); entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; - snapshot.Commit(); } [TestMethod] @@ -345,8 +341,6 @@ public void TestMakeTransaction1() var entry2 = snapshot.GetAndChange(key, () => new StorageItem(new NeoToken.NeoAccountState())); entry2.GetInteroperable().Balance = 10000 * NativeContract.NEO.Factor; - snapshot.Commit(); - var tx = wallet.MakeTransaction(snapshot, new TransferOutput[] { new TransferOutput() @@ -374,7 +368,6 @@ public void TestMakeTransaction1() entry2 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry1.GetInteroperable().Balance = 0; entry2.GetInteroperable().Balance = 0; - snapshot.Commit(); } [TestMethod] @@ -393,7 +386,6 @@ public void TestMakeTransaction2() var key = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash); var entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 1000000 * NativeContract.GAS.Factor; - snapshot.Commit(); var tx = wallet.MakeTransaction(snapshot, Array.Empty(), account.ScriptHash, new[]{ new Signer() { @@ -408,7 +400,6 @@ public void TestMakeTransaction2() entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState())); entry.GetInteroperable().Balance = 0; - snapshot.Commit(); } [TestMethod]