From 5e5dbce249c98a0623c5148ef5f37e1f9f833f03 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Fri, 23 Feb 2024 14:48:00 +0100 Subject: [PATCH 1/7] Update core --- neo | 2 +- .../InvalidTypes/InvalidUInt160.cs | 14 ++++- .../InvalidTypes/InvalidUInt256.cs | 14 ++++- .../SmartContract.cs | 10 ++- .../TestingApplicationEngine.cs | 62 ++++++++++++------- .../TestingStandards/Nep17Tests.cs | 9 ++- .../TestingStandards/OwnableTests.cs | 3 +- .../UnitTest_NativeContracts.cs | 2 +- .../UnitTest_Types.cs | 2 +- .../Services/ContractTest.cs | 2 +- .../TestBlockchain.cs | 2 +- .../neocontractnep17/Nep17ContractTests.cs | 3 +- .../Extensions.cs | 2 +- .../TestEngineTests.cs | 2 +- 14 files changed, 88 insertions(+), 41 deletions(-) diff --git a/neo b/neo index febcc2153..66ef246be 160000 --- a/neo +++ b/neo @@ -1 +1 @@ -Subproject commit febcc2153ccf83ca8118a72ede4d5f05ce8b67ea +Subproject commit 66ef246beb6bdc4b259cf503e345ff695725ebbb diff --git a/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt160.cs b/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt160.cs index c578928aa..b3de122b9 100644 --- a/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt160.cs +++ b/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt160.cs @@ -2,14 +2,24 @@ namespace Neo.SmartContract.Testing.InvalidTypes { public class InvalidUInt160 { + /// + /// Zero + /// + public static readonly UInt160 Zero = UInt160.Zero; + /// /// Null UInt160 /// public static readonly UInt160? Null = null; /// - /// This will be an invalid UInt160 + /// This will be an invalid UInt160 (ByteString) + /// + public static readonly UInt160 InvalidLength = new(); + + /// + /// This will be an invalid UInt160 (Integer) /// - public static readonly UInt160 Invalid = new(); + public static readonly UInt160 InvalidType = new(); } } diff --git a/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt256.cs b/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt256.cs index 90a63ab8b..72f3bcd9c 100644 --- a/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt256.cs +++ b/src/Neo.SmartContract.Testing/InvalidTypes/InvalidUInt256.cs @@ -2,14 +2,24 @@ namespace Neo.SmartContract.Testing.InvalidTypes { public class InvalidUInt256 { + /// + /// Zero + /// + public static readonly UInt160 Zero = UInt160.Zero; + /// /// Null UInt256 /// public static readonly UInt256? Null = null; /// - /// This will be an invalid UInt256 + /// This will be an invalid UInt256 (ByteString) + /// + public static readonly UInt256 InvalidLength = new(); + + /// + /// This will be an invalid UInt256 (Integer) /// - public static readonly UInt256 Invalid = new(); + public static readonly UInt256 InvalidType = new(); } } diff --git a/src/Neo.SmartContract.Testing/SmartContract.cs b/src/Neo.SmartContract.Testing/SmartContract.cs index 96dc93fe5..279297b61 100644 --- a/src/Neo.SmartContract.Testing/SmartContract.cs +++ b/src/Neo.SmartContract.Testing/SmartContract.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; @@ -61,11 +62,16 @@ internal StackItem Invoke(string methodName, params object[] args) { var arg = args[i]; - if (ReferenceEquals(arg, InvalidTypes.InvalidUInt160.Invalid) || - ReferenceEquals(arg, InvalidTypes.InvalidUInt256.Invalid)) + if (ReferenceEquals(arg, InvalidTypes.InvalidUInt160.InvalidLength) || + ReferenceEquals(arg, InvalidTypes.InvalidUInt256.InvalidLength)) { arg = System.Array.Empty(); } + else if (ReferenceEquals(arg, InvalidTypes.InvalidUInt160.InvalidType) || + ReferenceEquals(arg, InvalidTypes.InvalidUInt256.InvalidType)) + { + arg = BigInteger.Zero; + } script.EmitPush(arg); } diff --git a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs index 2417bfb6d..9da27f677 100644 --- a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs +++ b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs @@ -25,6 +25,44 @@ internal class TestingApplicationEngine : ApplicationEngine /// public TestEngine Engine { get; } + /// + /// Override CallingScriptHash + /// + public override UInt160 CallingScriptHash + { + get + { + var currentHash = InstructionContext.GetScriptHash(); + var hash = Engine.OnGetCallingScriptHash?.Invoke(currentHash); + + if (hash is not null) + { + return hash; + } + + return base.CallingScriptHash; + } + } + + /// + /// Override EntryScriptHash + /// + public override UInt160 EntryScriptHash + { + get + { + var currentHash = InstructionContext.GetScriptHash(); + var hash = Engine.OnGetEntryScriptHash?.Invoke(currentHash); + + if (hash is not null) + { + return hash; + } + + return base.EntryScriptHash; + } + } + public TestingApplicationEngine(TestEngine engine, TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock) : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) { @@ -165,30 +203,8 @@ private void RecoverCoverage(Instruction instruction) protected override void OnSysCall(InteropDescriptor descriptor) { - if (descriptor == System_Runtime_GetEntryScriptHash) - { - var currentHash = InstructionContext.GetScriptHash(); - var hash = Engine.OnGetEntryScriptHash?.Invoke(currentHash); - - if (hash is not null) - { - Push(Convert(hash)); - return; - } - } - else if (descriptor == System_Runtime_GetCallingScriptHash) - { - var currentHash = InstructionContext.GetScriptHash(); - var hash = Engine.OnGetCallingScriptHash?.Invoke(currentHash); - - if (hash is not null) - { - Push(Convert(hash)); - return; - } - } // descriptor.Hash == 1381727586 && descriptor.Name == "System.Contract.Call" && descriptor.Parameters.Count == 4) - else if (descriptor == System_Contract_Call) + if (descriptor == System_Contract_Call) { // Check if the syscall is a contract call and we need to mock it because it was defined by the user diff --git a/src/Neo.SmartContract.Testing/TestingStandards/Nep17Tests.cs b/src/Neo.SmartContract.Testing/TestingStandards/Nep17Tests.cs index b28ea28f3..1571b331c 100644 --- a/src/Neo.SmartContract.Testing/TestingStandards/Nep17Tests.cs +++ b/src/Neo.SmartContract.Testing/TestingStandards/Nep17Tests.cs @@ -122,7 +122,8 @@ public virtual void TestBalanceOf() { Assert.AreEqual(0, Contract.BalanceOf(Bob.Account)); Assert.ThrowsException(() => Contract.BalanceOf(InvalidUInt160.Null)); - Assert.ThrowsException(() => Contract.BalanceOf(InvalidUInt160.Invalid)); + Assert.ThrowsException(() => Contract.BalanceOf(InvalidUInt160.InvalidLength)); + Assert.ThrowsException(() => Contract.BalanceOf(InvalidUInt160.InvalidType)); } [TestMethod] @@ -156,8 +157,10 @@ public virtual void TestTransfer() Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(Alice.Account, InvalidUInt160.Null, 0))); Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(Alice.Account, Bob.Account, -1))); - Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(InvalidUInt160.Invalid, Bob.Account, -1))); - Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(Alice.Account, InvalidUInt160.Invalid, 0))); + Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(InvalidUInt160.InvalidLength, Bob.Account, -1))); + Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(InvalidUInt160.InvalidType, Bob.Account, -1))); + Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(Alice.Account, InvalidUInt160.InvalidLength, 0))); + Assert.ThrowsException(() => Assert.IsTrue(Contract.Transfer(Alice.Account, InvalidUInt160.InvalidType, 0))); // Invoke transfer without signature diff --git a/src/Neo.SmartContract.Testing/TestingStandards/OwnableTests.cs b/src/Neo.SmartContract.Testing/TestingStandards/OwnableTests.cs index 3ab6cf3bb..7a264c42e 100644 --- a/src/Neo.SmartContract.Testing/TestingStandards/OwnableTests.cs +++ b/src/Neo.SmartContract.Testing/TestingStandards/OwnableTests.cs @@ -98,7 +98,8 @@ public virtual void TestSetGetOwner() Engine.SetTransactionSigners(Alice); Assert.ThrowsException(() => Contract.Owner = UInt160.Zero); Assert.ThrowsException(() => Contract.Owner = InvalidUInt160.Null); - Assert.ThrowsException(() => Contract.Owner = InvalidUInt160.Invalid); + Assert.ThrowsException(() => Contract.Owner = InvalidUInt160.InvalidLength); + Assert.ThrowsException(() => Contract.Owner = InvalidUInt160.InvalidType); Contract.Owner = Bob.Account; Assert.AreEqual(Bob.Account, Contract.Owner); diff --git a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NativeContracts.cs b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NativeContracts.cs index 30d5bcb39..5c4a4290e 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NativeContracts.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NativeContracts.cs @@ -18,7 +18,7 @@ public class Contract_NativeContracts public void Test_Init() { snapshot = new TestDataCache(); - genesisBlock = new NeoSystem(TestProtocolSettings.Default, new MemoryStore()).GenesisBlock; + genesisBlock = new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider()).GenesisBlock; } [TestMethod] diff --git a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Types.cs b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Types.cs index 118db1e18..238e84c3f 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Types.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Types.cs @@ -399,7 +399,7 @@ public void tuple2_Test() [TestMethod] public void event_Test() { - var system = new NeoSystem(TestProtocolSettings.Default, new MemoryStore()); + var system = new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider()); using var testengine = new TestEngine(verificable: new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } }, diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/ContractTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/ContractTest.cs index 7f32dd4a5..04cd38698 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/ContractTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/ContractTest.cs @@ -19,7 +19,7 @@ public class ContractTest [TestInitialize] public void Init() { - var system = new NeoSystem(TestProtocolSettings.Default, new MemoryStore()); + var system = new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider()); _engine = new TestEngine.TestEngine(verificable: new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } }, diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestBlockchain.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestBlockchain.cs index 54c308a5f..d6747f527 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestBlockchain.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestBlockchain.cs @@ -17,7 +17,7 @@ public static class TestBlockchain static TestBlockchain() { - TheNeoSystem = new NeoSystem(TestProtocolSettings.Default, new MemoryStore()); + TheNeoSystem = new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider()); } public static StorageKey CreateStorageKey(this NativeContract contract, byte prefix, ISerializable key = null) diff --git a/tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Nep17ContractTests.cs b/tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Nep17ContractTests.cs index b5c2d2b53..de1c4de00 100644 --- a/tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Nep17ContractTests.cs +++ b/tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Nep17ContractTests.cs @@ -163,7 +163,8 @@ public void TestDeployWithOwner() // Try with invalid owners Assert.ThrowsException(() => Engine.Deploy(NefFile, Manifest, UInt160.Zero)); - Assert.ThrowsException(() => Engine.Deploy(NefFile, Manifest, InvalidUInt160.Invalid)); + Assert.ThrowsException(() => Engine.Deploy(NefFile, Manifest, InvalidUInt160.InvalidLength)); + Assert.ThrowsException(() => Engine.Deploy(NefFile, Manifest, InvalidUInt160.InvalidType)); // Test SetOwner notification diff --git a/tests/Neo.SmartContract.TestEngine/Extensions.cs b/tests/Neo.SmartContract.TestEngine/Extensions.cs index c0035738c..e19600258 100644 --- a/tests/Neo.SmartContract.TestEngine/Extensions.cs +++ b/tests/Neo.SmartContract.TestEngine/Extensions.cs @@ -14,7 +14,7 @@ public static void ContractAdd(this DataCache snapshot, ContractState contract) public static void DeployNativeContracts(this DataCache snapshot, Block? persistingBlock = null) { - persistingBlock ??= new NeoSystem(TestProtocolSettings.Default, new MemoryStore()).GenesisBlock; + persistingBlock ??= new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider()).GenesisBlock; var method = typeof(SmartContract.Native.ContractManagement).GetMethod("OnPersist", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var engine = new TestEngine(TriggerType.OnPersist, null, snapshot, persistingBlock); diff --git a/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs b/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs index d40c9b802..046044776 100644 --- a/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs +++ b/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs @@ -23,7 +23,7 @@ public void GenerateNativeArtifacts() { foreach (var n in Neo.SmartContract.Native.NativeContract.Contracts) { - var manifest = n.Manifest; + var manifest = n.GetContractState(ProtocolSettings.Default, uint.MaxValue).Manifest; var source = manifest.GetArtifactsSource(manifest.Name, generateProperties: true); var fullPath = Path.GetFullPath($"../../../../../src/Neo.SmartContract.Testing/Native/{manifest.Name}.cs"); From d9aa157f08d0a13a4feba693a60d86e406ef116f Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Fri, 23 Feb 2024 14:51:07 +0100 Subject: [PATCH 2/7] fix issue --- src/Neo.SmartContract.Testing/README.md | 1 - src/Neo.SmartContract.Testing/TestingApplicationEngine.cs | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Neo.SmartContract.Testing/README.md b/src/Neo.SmartContract.Testing/README.md index d8613ceb0..5c0e89ac6 100644 --- a/src/Neo.SmartContract.Testing/README.md +++ b/src/Neo.SmartContract.Testing/README.md @@ -473,4 +473,3 @@ The currently known limitations are: - Receive events during the deploy, because the object is returned after performing the deploy, it is not possible to intercept notifications for the deploy unless the contract is previously created with `FromHash` knowing the hash of the contract to be created. - It is possible that if the contract is updated, the coverage calculation may be incorrect. The update method of a contract can be tested, but if the same script and abi as the original are not used, it can result in a coverage calculation error. -- Some native contracts use the values of `CallingScriptHash` and `EntryScriptHash` for certain actions, such as `CheckWitness`, so overriding the syscalls with `OnGetEntryScriptHash` and `OnGetCallingScriptHash` could fail. diff --git a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs index 9da27f677..682131b60 100644 --- a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs +++ b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs @@ -32,8 +32,7 @@ public override UInt160 CallingScriptHash { get { - var currentHash = InstructionContext.GetScriptHash(); - var hash = Engine.OnGetCallingScriptHash?.Invoke(currentHash); + var hash = Engine.OnGetCallingScriptHash?.Invoke(CurrentScriptHash); if (hash is not null) { @@ -51,8 +50,7 @@ public override UInt160 EntryScriptHash { get { - var currentHash = InstructionContext.GetScriptHash(); - var hash = Engine.OnGetEntryScriptHash?.Invoke(currentHash); + var hash = Engine.OnGetEntryScriptHash?.Invoke(CurrentScriptHash); if (hash is not null) { From e00cbe4e17a9b0160b46f379b7a53bd9b2f2bc54 Mon Sep 17 00:00:00 2001 From: Shargon Date: Fri, 23 Feb 2024 06:39:07 -0800 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Jimmy --- .../TestingApplicationEngine.cs | 30 ++----------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs index 682131b60..11e53c7b5 100644 --- a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs +++ b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs @@ -28,38 +28,12 @@ internal class TestingApplicationEngine : ApplicationEngine /// /// Override CallingScriptHash /// - public override UInt160 CallingScriptHash - { - get - { - var hash = Engine.OnGetCallingScriptHash?.Invoke(CurrentScriptHash); - - if (hash is not null) - { - return hash; - } - - return base.CallingScriptHash; - } - } + public override UInt160 CallingScriptHash => Engine.OnGetCallingScriptHash?.Invoke(CurrentScriptHash) ?? base.CallingScriptHash; /// /// Override EntryScriptHash /// - public override UInt160 EntryScriptHash - { - get - { - var hash = Engine.OnGetEntryScriptHash?.Invoke(CurrentScriptHash); - - if (hash is not null) - { - return hash; - } - - return base.EntryScriptHash; - } - } + public override UInt160 EntryScriptHash => Engine.OnGetEntryScriptHash?.Invoke(CurrentScriptHash) ?? base.EntryScriptHash; public TestingApplicationEngine(TestEngine engine, TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock) : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) From d647f9666e3c92c87b3e48fe3f2eabb6668e9877 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Fri, 23 Feb 2024 18:46:37 +0100 Subject: [PATCH 4/7] Add expected hash to OnXScriptHash --- src/Neo.SmartContract.Testing/TestEngine.cs | 10 ++++++---- .../TestingApplicationEngine.cs | 20 ++++++++++++++++--- .../TestEngineTests.cs | 4 ++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Neo.SmartContract.Testing/TestEngine.cs b/src/Neo.SmartContract.Testing/TestEngine.cs index e87236c6f..aecfff398 100644 --- a/src/Neo.SmartContract.Testing/TestEngine.cs +++ b/src/Neo.SmartContract.Testing/TestEngine.cs @@ -22,6 +22,8 @@ namespace Neo.SmartContract.Testing { public class TestEngine { + public delegate UInt160? OnGetScriptHash(UInt160 current, UInt160 expected); + internal readonly Dictionary Coverage = new(); private readonly Dictionary> _contracts = new(); private readonly Dictionary> _customMocks = new(); @@ -146,15 +148,15 @@ public UInt160 CommitteeAddress /// /// On GetEntryScriptHash - /// The argument is the ExecutingScriptHash, and it must return the new EntryScriptHash, or null if we don't want to make any change + /// The argument is the ExecutingScriptHash and the expected return, and it must return the new EntryScriptHash, or null if we don't want to make any change /// - public Func? OnGetEntryScriptHash { get; set; } = null; + public OnGetScriptHash? OnGetEntryScriptHash { get; set; } = null; /// /// On GetCallingScriptHash - /// The argument is the ExecutingScriptHash, and it must return the new CallingScriptHash, or null if we don't want to make any change + /// The argument is the ExecutingScriptHash and the expected return, and it must return the new CallingScriptHash, or null if we don't want to make any change /// - public Func? OnGetCallingScriptHash { get; set; } = null; + public OnGetScriptHash? OnGetCallingScriptHash { get; set; } = null; /// /// Gas diff --git a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs index 11e53c7b5..e95bf5927 100644 --- a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs +++ b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs @@ -28,15 +28,29 @@ internal class TestingApplicationEngine : ApplicationEngine /// /// Override CallingScriptHash /// - public override UInt160 CallingScriptHash => Engine.OnGetCallingScriptHash?.Invoke(CurrentScriptHash) ?? base.CallingScriptHash; + public override UInt160 CallingScriptHash + { + get + { + var expected = base.CallingScriptHash; + return Engine.OnGetCallingScriptHash?.Invoke(CurrentScriptHash, expected) ?? expected; + } + } /// /// Override EntryScriptHash /// - public override UInt160 EntryScriptHash => Engine.OnGetEntryScriptHash?.Invoke(CurrentScriptHash) ?? base.EntryScriptHash; + public override UInt160 EntryScriptHash + { + get + { + var expected = base.EntryScriptHash; + return Engine.OnGetEntryScriptHash?.Invoke(CurrentScriptHash, expected) ?? expected; + } + } public TestingApplicationEngine(TestEngine engine, TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock) - : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) + : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) { Engine = engine; } diff --git a/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs b/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs index 046044776..c29debcc9 100644 --- a/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs +++ b/tests/Neo.SmartContract.Testing.UnitTests/TestEngineTests.cs @@ -42,7 +42,7 @@ public void TestOnGetEntryScriptHash() Assert.AreEqual("0xfa99b1aeedab84a47856358515e7f982341aa767", engine.Execute(script).ConvertTo(typeof(UInt160)).ToString()); - engine.OnGetEntryScriptHash = current => UInt160.Parse("0x0000000000000000000000000000000000000001"); + engine.OnGetEntryScriptHash = (current, expected) => UInt160.Parse("0x0000000000000000000000000000000000000001"); Assert.AreEqual("0x0000000000000000000000000000000000000001", engine.Execute(script).ConvertTo(typeof(UInt160)).ToString()); } @@ -57,7 +57,7 @@ public void TestOnGetCallingScriptHash() Assert.AreEqual(StackItem.Null, engine.Execute(script)); - engine.OnGetCallingScriptHash = current => UInt160.Parse("0x0000000000000000000000000000000000000001"); + engine.OnGetCallingScriptHash = (current, expected) => UInt160.Parse("0x0000000000000000000000000000000000000001"); Assert.AreEqual("0x0000000000000000000000000000000000000001", engine.Execute(script).ConvertTo(typeof(UInt160)).ToString()); } From 60a161077930cdb22b486750dc450b639ec9d70b Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Fri, 23 Feb 2024 18:55:08 +0100 Subject: [PATCH 5/7] Add storage methods --- .../SmartContract.cs | 1 + .../{ => Storage}/SmartContractStorage.cs | 66 ++++++++++++++++++- .../Storage/TestStorageTests.cs | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) rename src/Neo.SmartContract.Testing/{ => Storage}/SmartContractStorage.cs (69%) diff --git a/src/Neo.SmartContract.Testing/SmartContract.cs b/src/Neo.SmartContract.Testing/SmartContract.cs index 279297b61..38360cbbf 100644 --- a/src/Neo.SmartContract.Testing/SmartContract.cs +++ b/src/Neo.SmartContract.Testing/SmartContract.cs @@ -1,4 +1,5 @@ using Neo.SmartContract.Testing.Extensions; +using Neo.SmartContract.Testing.Storage; using Neo.VM; using Neo.VM.Types; using System; diff --git a/src/Neo.SmartContract.Testing/SmartContractStorage.cs b/src/Neo.SmartContract.Testing/Storage/SmartContractStorage.cs similarity index 69% rename from src/Neo.SmartContract.Testing/SmartContractStorage.cs rename to src/Neo.SmartContract.Testing/Storage/SmartContractStorage.cs index 9ea108558..a521471a6 100644 --- a/src/Neo.SmartContract.Testing/SmartContractStorage.cs +++ b/src/Neo.SmartContract.Testing/Storage/SmartContractStorage.cs @@ -3,7 +3,7 @@ using System.Buffers.Binary; using System.Numerics; -namespace Neo.SmartContract.Testing +namespace Neo.SmartContract.Testing.Storage { public class SmartContractStorage { @@ -34,6 +34,18 @@ private int GetContractId() return _contractId.Value; } + /// + /// Check if the entry exist + /// + /// Key + public bool Contains(byte key) => Contains(new byte[] { key }); + + /// + /// Check if the entry exist + /// + /// Key + public bool Contains(string key) => Contains(Utility.StrictUTF8.GetBytes(key)); + /// /// Check if the entry exist /// @@ -45,6 +57,18 @@ public bool Contains(ReadOnlyMemory key) return entry != null; } + /// + /// Read an entry from the smart contract storage + /// + /// Key + public ReadOnlyMemory Get(byte key) => Get(new byte[] { key }); + + /// + /// Read an entry from the smart contract storage + /// + /// Key + public ReadOnlyMemory Get(string key) => Get(Utility.StrictUTF8.GetBytes(key)); + /// /// Read an entry from the smart contract storage /// @@ -62,6 +86,20 @@ public ReadOnlyMemory Get(ReadOnlyMemory key) return null; } + /// + /// Put an entry in the smart contract storage + /// + /// Key + /// Value + public void Put(byte key, ReadOnlyMemory value) => Put(new byte[] { key }, value); + + /// + /// Put an entry in the smart contract storage + /// + /// Key + /// Value + public void Put(string key, ReadOnlyMemory value) => Put(Utility.StrictUTF8.GetBytes(key), value); + /// /// Put an entry in the smart contract storage /// @@ -75,6 +113,20 @@ public void Put(ReadOnlyMemory key, ReadOnlyMemory value) entry.Value = value; } + /// + /// Put an entry in the smart contract storage + /// + /// Key + /// Value + public void Put(byte key, BigInteger value) => Put(new byte[] { key }, value); + + /// + /// Put an entry in the smart contract storage + /// + /// Key + /// Value + public void Put(string key, BigInteger value) => Put(Utility.StrictUTF8.GetBytes(key), value); + /// /// Put an entry in the smart contract storage /// @@ -88,6 +140,18 @@ public void Put(ReadOnlyMemory key, BigInteger value) entry.Set(value); } + /// + /// Remove an entry from the smart contract storage + /// + /// Key + public void Remove(byte key) => Remove(new byte[] { key }); + + /// + /// Remove an entry from the smart contract storage + /// + /// Key + public void Remove(string key) => Remove(Utility.StrictUTF8.GetBytes(key)); + /// /// Remove an entry from the smart contract storage /// diff --git a/tests/Neo.SmartContract.Testing.UnitTests/Storage/TestStorageTests.cs b/tests/Neo.SmartContract.Testing.UnitTests/Storage/TestStorageTests.cs index 6b085ecd4..1b024a5c1 100644 --- a/tests/Neo.SmartContract.Testing.UnitTests/Storage/TestStorageTests.cs +++ b/tests/Neo.SmartContract.Testing.UnitTests/Storage/TestStorageTests.cs @@ -21,6 +21,7 @@ public void TestCheckpoint() // Check that all it works + Assert.IsTrue(engine.Native.NEO.Storage.Contains(1)); // Prefix_VotersCount Assert.AreEqual(100_000_000, engine.Native.NEO.TotalSupply); // Create checkpoint From 81c3cf1d4bc4ce2fdefee01cac64270598a8ac9e Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Fri, 23 Feb 2024 18:56:55 +0100 Subject: [PATCH 6/7] clean change --- src/Neo.SmartContract.Testing/TestingApplicationEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs index e95bf5927..f0f81c6a6 100644 --- a/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs +++ b/src/Neo.SmartContract.Testing/TestingApplicationEngine.cs @@ -50,7 +50,7 @@ public override UInt160 EntryScriptHash } public TestingApplicationEngine(TestEngine engine, TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock) - : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) + : base(trigger, container, snapshot, persistingBlock, engine.ProtocolSettings, engine.Gas, null) { Engine = engine; } From 5d3273b3ad364b0361eb4ce301d65d76f227d7c3 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Sat, 24 Feb 2024 00:08:09 +0100 Subject: [PATCH 7/7] Update neo --- neo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo b/neo index 66ef246be..d4564d157 160000 --- a/neo +++ b/neo @@ -1 +1 @@ -Subproject commit 66ef246beb6bdc4b259cf503e345ff695725ebbb +Subproject commit d4564d1570d14dd4a253a88b14910026432da42f