From 13c9d45e22460a24046c6b124717f5fc69a9731f Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 21 Aug 2019 13:25:48 +0200 Subject: [PATCH 01/14] Optimized StorageMap --- .../Services/Neo/Helper.cs | 40 ++++++++++++++----- .../Services/Neo/StorageMap.cs | 2 +- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index 58ba27444..d5c6fc5e6 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -9,67 +9,85 @@ public static StorageMap CreateMap(this StorageContext context, string prefix) return new StorageMap { Context = context, - Prefix = prefix + Prefix = prefix.AsByteArray().Concat(new byte[] { 0x00 }) + }; + } + + public static StorageMap CreateMap(this StorageContext context, byte[] prefix) + { + return new StorageMap + { + Context = context, + Prefix = prefix.Concat(new byte[] { 0x00 }) + }; + } + + public static StorageMap CreateMap(this StorageContext context, byte prefix) + { + return new StorageMap + { + Context = context, + Prefix = new byte[] { prefix, 0x00 } }; } public static void Delete(this StorageMap map, byte[] key) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key); + byte[] k = map.Prefix.Concat(key); Storage.Delete(map.Context, k); } public static void Delete(this StorageMap map, string key) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray()); + byte[] k = map.Prefix.Concat(key.AsByteArray()); Storage.Delete(map.Context, k); } public static byte[] Get(this StorageMap map, byte[] key) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key); + byte[] k = map.Prefix.Concat(key); return Storage.Get(map.Context, k); } public static byte[] Get(this StorageMap map, string key) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray()); + byte[] k = map.Prefix.Concat(key.AsByteArray()); return Storage.Get(map.Context, k); } public static void Put(this StorageMap map, byte[] key, byte[] value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key); + byte[] k = map.Prefix.Concat(key); Storage.Put(map.Context, k, value); } public static void Put(this StorageMap map, byte[] key, BigInteger value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key); + byte[] k = map.Prefix.Concat(key); Storage.Put(map.Context, k, value); } public static void Put(this StorageMap map, byte[] key, string value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key); + byte[] k = map.Prefix.Concat(key); Storage.Put(map.Context, k, value); } public static void Put(this StorageMap map, string key, byte[] value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray()); + byte[] k = map.Prefix.Concat(key.AsByteArray()); Storage.Put(map.Context, k, value); } public static void Put(this StorageMap map, string key, BigInteger value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray()); + byte[] k = map.Prefix.Concat(key.AsByteArray()); Storage.Put(map.Context, k, value); } public static void Put(this StorageMap map, string key, string value) { - byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray()); + byte[] k = map.Prefix.Concat(key.AsByteArray()); Storage.Put(map.Context, k, value); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/StorageMap.cs b/src/Neo.SmartContract.Framework/Services/Neo/StorageMap.cs index 7e2375cbb..ac6596808 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/StorageMap.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/StorageMap.cs @@ -3,6 +3,6 @@ public class StorageMap { internal StorageContext Context; - internal string Prefix; + internal byte[] Prefix; } } From 791ed5d23c9a46d15db0d2d1ba6490601283dc54 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sat, 24 Aug 2019 08:46:16 +0200 Subject: [PATCH 02/14] Remove 0s --- src/Neo.SmartContract.Framework/Services/Neo/Helper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index d5c6fc5e6..7d7bc2570 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -9,7 +9,7 @@ public static StorageMap CreateMap(this StorageContext context, string prefix) return new StorageMap { Context = context, - Prefix = prefix.AsByteArray().Concat(new byte[] { 0x00 }) + Prefix = prefix.AsByteArray() }; } @@ -18,7 +18,7 @@ public static StorageMap CreateMap(this StorageContext context, byte[] prefix) return new StorageMap { Context = context, - Prefix = prefix.Concat(new byte[] { 0x00 }) + Prefix = prefix }; } @@ -27,7 +27,7 @@ public static StorageMap CreateMap(this StorageContext context, byte prefix) return new StorageMap { Context = context, - Prefix = new byte[] { prefix, 0x00 } + Prefix = new byte[] { prefix } }; } From 644d78458dbd21d2d7dcf925cc9a4018a9ac6caf Mon Sep 17 00:00:00 2001 From: Shargon Date: Sun, 25 Aug 2019 16:46:21 +0200 Subject: [PATCH 03/14] Add unit test for storage access --- .../Services/Neo/Helper.cs | 2 +- .../TestClasses/Contract_StorageMap.cs | 90 +++++++++ .../UnitTest_ABI_Event.cs | 2 +- .../UnitTest_AutoEntrypoint.cs | 6 +- .../UnitTest_Shift.cs | 4 +- .../UnitTest_StorageMap.cs | 135 +++++++++++++ .../Utils/NeonTestTool.cs | 17 +- .../Utils/TestEngine.cs | 182 ++++++++++++++++-- .../Utils/TestStorageContext.cs | 8 + 9 files changed, 415 insertions(+), 31 deletions(-) create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index 7d7bc2570..8fbf24268 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -27,7 +27,7 @@ public static StorageMap CreateMap(this StorageContext context, byte prefix) return new StorageMap { Context = context, - Prefix = new byte[] { prefix } + Prefix = (byte[])(object)prefix }; } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs new file mode 100644 index 000000000..9968a9157 --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs @@ -0,0 +1,90 @@ +using Neo.SmartContract.Framework.Services.Neo; + +namespace Neo.Compiler.MSIL.TestClasses +{ + class Contract_StorageMap : SmartContract.Framework.SmartContract + { + // There is no main here, it can be auto generation. + + #region Byte + + public static bool TestPutByte(byte prefix, byte[] key, byte[] value) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + storage.Put(key, value); + return true; + } + + public static bool TestDeleteByte(byte prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + var exists = value.Length > 0; + storage.Delete(key); + return exists; + } + + public static byte[] TestGetByte(byte prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + return value; + } + + #endregion + + #region String + + public static bool TestPutString(string prefix, byte[] key, byte[] value) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + storage.Put(key, value); + return true; + } + + public static bool TestDeleteString(string prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + var exists = value.Length > 0; + storage.Delete(key); + return exists; + } + + public static byte[] TestGetString(string prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + return value; + } + + #endregion + + #region ByteArray + + public static bool TestPutByteArray(byte[] prefix, byte[] key, byte[] value) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + storage.Put(key, value); + return true; + } + + public static bool TestDeleteByteArray(byte[] prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + var exists = value.Length > 0; + storage.Delete(key); + return exists; + } + + public static byte[] TestGetByteArray(byte[] prefix, byte[] key) + { + var storage = Storage.CurrentContext.CreateMap(prefix); + var value = storage.Get(key); + return value; + } + + #endregion + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ABI_Event.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ABI_Event.cs index f70574252..6d66a52e1 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ABI_Event.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ABI_Event.cs @@ -13,7 +13,7 @@ public void Test_ABI_Event() { var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_Event.cs"); - var abi = testengine.scriptEntry.finialABI; + var abi = testengine.ScriptEntry.finialABI; Console.WriteLine("abi=" + abi.ToString()); var events = abi["events"].AsList()[0].ToString(); Console.WriteLine("event abi info =" + events); diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_AutoEntrypoint.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_AutoEntrypoint.cs index d4b986878..d84abdd32 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_AutoEntrypoint.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_AutoEntrypoint.cs @@ -13,7 +13,7 @@ public void Test_AutoEntry() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs"); - testengine.scriptEntry.DumpAVM(); + testengine.ScriptEntry.DumpAVM(); var result = testengine.GetMethod("call01").Run();//new test method01 StackItem wantresult = new byte[] { 1, 2, 3, 4 }; @@ -28,7 +28,7 @@ public void Test_AutoEntry_private() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs"); - testengine.scriptEntry.DumpAVM(); + testengine.ScriptEntry.DumpAVM(); StackItem[] _params = new StackItem[] { "privateMethod", new StackItem[0] }; var result = testengine.ExecuteTestCase(_params);//new test method02 @@ -43,7 +43,7 @@ public void Test_AutoEntry_call02() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs"); - testengine.scriptEntry.DumpAVM(); + testengine.ScriptEntry.DumpAVM(); var result = testengine.ExecuteTestCaseStandard("call02", "hello", 33);//old test method StackItem wantresult = new byte[0]; diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Shift.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Shift.cs index 223f02dcc..27ea832c3 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Shift.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Shift.cs @@ -16,7 +16,7 @@ public void Test_Shift() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_shift.cs"); - testengine.scriptEntry.DumpAVM(); + testengine.ScriptEntry.DumpAVM(); var result = testengine.ExecuteTestCaseStandard("testfunc"); } @@ -26,7 +26,7 @@ public void Test_Shift_BigInteger() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_shift_bigint.cs"); - testengine.scriptEntry.DumpAVM(); + testengine.ScriptEntry.DumpAVM(); StackItem[] _params = new StackItem[] { "testfunc", new StackItem[0] }; var result = testengine.ExecuteTestCase(_params); diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs new file mode 100644 index 000000000..d7bffd4dd --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs @@ -0,0 +1,135 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Compiler.MSIL.Utils; +using Neo.VM.Types; +using System.Linq; + +namespace Neo.Compiler.MSIL +{ + [TestClass] + public class UnitTest_StorageMap + { + private void Put(TestEngine testengine, string method, byte[] prefix, byte[] key, byte[] value) + { + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key), new ByteArray(value)); + var rItem = result.Pop(); + Assert.IsInstanceOfType(rItem, typeof(Integer)); + Assert.AreEqual(1, rItem.GetBigInteger()); + + Assert.AreEqual(1, + testengine.Storages + .Count(a => + a.Key.Key.SequenceEqual(prefix.Concat(key)) && + a.Value.Value.SequenceEqual(value) && + !a.Value.IsConstant + )); + } + + private byte[] Get(TestEngine testengine, string method, byte[] prefix, byte[] key) + { + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key)); + Assert.AreEqual(1, result.Count); + var rItem = result.Pop(); + Assert.IsInstanceOfType(rItem, typeof(ByteArray)); + + Assert.AreEqual(1, testengine.Storages.Count(a => a.Key.Key.SequenceEqual(prefix.Concat(key)))); + + return rItem.GetByteArray(); + } + + private bool Delete(TestEngine testengine, string method, byte[] prefix, byte[] key) + { + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key)); + Assert.AreEqual(1, result.Count); + var rItem = result.Pop(); + Assert.IsInstanceOfType(rItem, typeof(Boolean)); + + Assert.AreEqual(0, testengine.Storages.Count(a => a.Key.Key.SequenceEqual(prefix.Concat(key)))); + + return rItem.GetBoolean(); + } + + [TestMethod] + public void Test_Byte() + { + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); + + var prefix = new byte[] { 0xFF }; + var key = new byte[] { 0x01, 0x02, 0x03 }; + var value = new byte[] { 0x04, 0x05, 0x06 }; + + // Put + + Put(testengine, "TestPutByte", prefix, key, value); + + // Get + + var getVal = Get(testengine, "TestGetByte", prefix, key); + + CollectionAssert.AreEqual(value, getVal); + + // Delete + + var del = Delete(testengine, "TestDeleteByte", prefix, key); + Assert.IsTrue(del); + del = Delete(testengine, "TestDeleteByte", prefix, key); + Assert.IsFalse(del); + } + + [TestMethod] + public void Test_ByteArray() + { + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); + + var prefix = new byte[] { 0x00, 0xFF }; + var key = new byte[] { 0x01, 0x02, 0x03 }; + var value = new byte[] { 0x04, 0x05, 0x06 }; + + // Put + + Put(testengine, "TestPutByteArray", prefix, key, value); + + // Get + + var getVal = Get(testengine, "TestGetByteArray", prefix, key); + + CollectionAssert.AreEqual(value, getVal); + + // Delete + + var del = Delete(testengine, "TestDeleteByteArray", prefix, key); + Assert.IsTrue(del); + del = Delete(testengine, "TestDeleteByteArray", prefix, key); + Assert.IsFalse(del); + } + + [TestMethod] + public void Test_String() + { + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); + + var prefix = new byte[] { 0x00, 0xFF }; + var key = new byte[] { 0x01, 0x02, 0x03 }; + var value = new byte[] { 0x04, 0x05, 0x06 }; + + // Put + + Put(testengine, "TestPutString", prefix, key, value); + + // Get + + var getVal = Get(testengine, "TestGetString", prefix, key); + + CollectionAssert.AreEqual(value, getVal); + + // Delete + + var del = Delete(testengine, "TestDeleteString", prefix, key); + Assert.IsTrue(del); + del = Delete(testengine, "TestDeleteString", prefix, key); + Assert.IsFalse(del); + } + } +} \ No newline at end of file diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs index 82f634bc4..1595bad44 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs @@ -3,15 +3,22 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.SmartContract.Framework; using Neo.VM; -using System; -using System.Collections.Generic; using System.IO; +using System.Security.Cryptography; using System.Text; namespace Neo.Compiler.MSIL.Utils { internal static class NeonTestTool { + public static UInt160 ScriptHash(this ExecutionContext context) + { + using (var sha = SHA1.Create()) + { + return new UInt160(sha.ComputeHash(((byte[])context.Script))); + } + } + public static string Bytes2HexString(byte[] data) { StringBuilder sb = new StringBuilder(); @@ -21,6 +28,7 @@ public static string Bytes2HexString(byte[] data) } return sb.ToString(); } + public static byte[] HexString2Bytes(string str) { if (str.IndexOf("0x") == 0) @@ -63,8 +71,5 @@ public static BuildScript BuildScript(string filename) return bs; } } - - - } -} +} \ No newline at end of file diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs index ebda9f8f4..e109c3828 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs @@ -1,22 +1,35 @@ +using Neo.Ledger; using Neo.VM; +using Neo.VM.Types; using System; using System.Collections.Generic; using System.Linq; -using System.Text; namespace Neo.Compiler.MSIL.Utils { class TestEngine : ExecutionEngine { + public const int MaxStorageKeySize = 64; + public const int MaxStorageValueSize = ushort.MaxValue; + static IDictionary scriptsAll = new Dictionary(); - IDictionary scripts = new Dictionary(); - public BuildScript scriptEntry + public readonly IDictionary Scripts; + + public readonly IDictionary Storages; + + public BuildScript ScriptEntry { get; private set; } + public TestEngine() + { + Scripts = new Dictionary(); + Storages = new Dictionary(); + } + public void AddAppcallScript(string filename, string specScriptID) { @@ -29,7 +42,7 @@ public void AddAppcallScript(string filename, string specScriptID) scriptsAll[filename] = NeonTestTool.BuildScript(filename); } - scripts[specScriptID.ToLower()] = scriptsAll[filename]; + Scripts[specScriptID.ToLower()] = scriptsAll[filename]; } public void AddEntryScript(string filename) @@ -39,8 +52,9 @@ public void AddEntryScript(string filename) scriptsAll[filename] = NeonTestTool.BuildScript(filename); } - scriptEntry = scriptsAll[filename]; + ScriptEntry = scriptsAll[filename]; } + public class ContractMethod { TestEngine engine; @@ -55,14 +69,17 @@ public StackItem Run(params StackItem[] _params) return this.engine.ExecuteTestCaseStandard(methodname, _params).Pop(); } } + public ContractMethod GetMethod(string methodname) { return new ContractMethod(this, methodname); } - public RandomAccessStack ExecuteTestCaseStandard(string methodname,params StackItem[] _params) + + public RandomAccessStack ExecuteTestCaseStandard(string methodname, params StackItem[] _params) { //var engine = new ExecutionEngine(); - this.LoadScript(scriptEntry.finalAVM); + this.State = VMState.BREAK; // Required for allow to reuse the same TestEngine + this.LoadScript(ScriptEntry.finalAVM); this.InvocationStack.Peek().InstructionPointer = 0; this.CurrentContext.EvaluationStack.Push(_params); this.CurrentContext.EvaluationStack.Push(methodname); @@ -78,13 +95,13 @@ public RandomAccessStack ExecuteTestCaseStandard(string methodname,pa this.CurrentContext.CurrentInstruction.OpCode); this.ExecuteNext(); } - var stack = this.ResultStack; - return stack; + return this.ResultStack; } + public RandomAccessStack ExecuteTestCase(StackItem[] _params) { //var engine = new ExecutionEngine(); - this.LoadScript(scriptEntry.finalAVM); + this.LoadScript(ScriptEntry.finalAVM); this.InvocationStack.Peek().InstructionPointer = 0; if (_params != null) { @@ -108,30 +125,158 @@ public RandomAccessStack ExecuteTestCase(StackItem[] _params) var stack = this.ResultStack; return stack; } + protected override bool OnSysCall(uint method) { - if (method == Neo.SmartContract.InteropService.System_Contract_Call) + if (method == SmartContract.InteropService.System_Contract_Call) { //a appcall return Contract_Call(); } - else if (method == Neo.SmartContract.InteropService.System_Runtime_Log) + else if (method == SmartContract.InteropService.System_Runtime_Log) { return Contract_Log(); } - else if (method == Neo.SmartContract.InteropService.System_Runtime_Notify) + else if (method == SmartContract.InteropService.System_Runtime_Notify) { return Contract_Log(); } + // Storages + else if (method == SmartContract.InteropService.System_Storage_GetContext) + { + return Contract_Storage_GetContext(); + } + else if (method == SmartContract.InteropService.System_Storage_GetReadOnlyContext) + { + return Contract_Storage_GetReadOnlyContext(); + } + else if (method == SmartContract.InteropService.System_Storage_Get) + { + return Contract_Storage_Get(); + } + else if (method == SmartContract.InteropService.System_Storage_Delete) + { + return Contract_Storage_Delete(); + } + else if (method == SmartContract.InteropService.System_Storage_Put) + { + return Contract_Storage_Put(); + } + return base.OnSysCall(method); } + #region Storage + + private bool Contract_Storage_GetContext() + { + CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new TestStorageContext + { + ScriptHash = CurrentContext.ScriptHash(), + IsReadOnly = false + })); + return true; + } + + private bool Contract_Storage_GetReadOnlyContext() + { + CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new TestStorageContext + { + ScriptHash = CurrentContext.ScriptHash(), + IsReadOnly = true + })); + return true; + } + + private bool Contract_Storage_Delete() + { + if (CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) + { + TestStorageContext context = _interface.GetInterface(); + if (context.IsReadOnly) return false; + + StorageKey key = new StorageKey + { + ScriptHash = context.ScriptHash, + Key = CurrentContext.EvaluationStack.Pop().GetByteArray() + }; + if (Storages.TryGetValue(key, out var item) && item.IsConstant == true) return false; + Storages.Remove(key); + return true; + } + return false; + } + + private bool Contract_Storage_Get() + { + if (CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) + { + TestStorageContext context = _interface.GetInterface(); + byte[] key = CurrentContext.EvaluationStack.Pop().GetByteArray(); + + if (Storages.TryGetValue(new StorageKey + { + ScriptHash = context.ScriptHash, + Key = key + }, out var item)) + { + CurrentContext.EvaluationStack.Push(item.Value); + } + else + { + CurrentContext.EvaluationStack.Push(new byte[0]); + } + return true; + } + return false; + } + + private bool Contract_Storage_Put() + { + if (!(CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)) + return false; + TestStorageContext context = _interface.GetInterface(); + byte[] key = CurrentContext.EvaluationStack.Pop().GetByteArray(); + byte[] value = CurrentContext.EvaluationStack.Pop().GetByteArray(); + return PutEx(context, key, value, StorageFlags.None); + } + + private bool PutEx(TestStorageContext context, byte[] key, byte[] value, StorageFlags flags) + { + if (key.Length > MaxStorageKeySize) return false; + if (value.Length > MaxStorageValueSize) return false; + if (context.IsReadOnly) return false; + + StorageKey skey = new StorageKey + { + ScriptHash = context.ScriptHash, + Key = key + }; + + if (Storages.TryGetValue(skey, out var item) && item.IsConstant == true) return false; + + if (value.Length == 0 && !flags.HasFlag(StorageFlags.Constant)) + { + // If put 'value' is empty (and non-const), we remove it (implicit `Storage.Delete`) + Storages.Remove(skey); + } + else + { + item = Storages[skey] = new StorageItem(); + item.Value = value; + item.IsConstant = flags.HasFlag(StorageFlags.Constant); + } + return true; + } + + #endregion + private bool Contract_Call() { StackItem item0 = this.CurrentContext.EvaluationStack.Pop(); var contractid = item0.GetByteArray(); var contractkey = NeonTestTool.Bytes2HexString(contractid.Reverse().ToArray()).ToLower(); - var contract = scripts[contractkey]; + var contract = Scripts[contractkey]; if (contract is null) return false; StackItem item1 = this.CurrentContext.EvaluationStack.Pop(); @@ -141,12 +286,14 @@ private bool Contract_Call() context_new.EvaluationStack.Push(item1); return true; } + private bool Contract_Log() { StackItem item0 = this.CurrentContext.EvaluationStack.Pop(); DumpItem(item0); return true; } + public bool CheckAsciiChar(string s) { for (int i = 0; i < s.Length; i++) @@ -157,6 +304,7 @@ public bool CheckAsciiChar(string s) } return true; } + private void DumpItemShort(StackItem item, int space = 0) { var spacestr = ""; @@ -173,6 +321,7 @@ private void DumpItemShort(StackItem item, int space = 0) } Console.WriteLine(spacestr + line); } + private void DumpItem(StackItem item, int space = 0) { var spacestr = ""; @@ -198,11 +347,9 @@ private void DumpItem(StackItem item, int space = 0) Console.WriteLine("---Value---"); DumpItem(subitem.Value, space + 1); } - } else { - Console.WriteLine(spacestr + "--as num:" + item.GetBigInteger()); Console.WriteLine(spacestr + "--as bin:" + NeonTestTool.Bytes2HexString(item.GetByteArray())); @@ -213,9 +360,8 @@ private void DumpItem(StackItem item, int space = 0) { Console.WriteLine(spacestr + "--as str:" + item.GetString()); } - } } } } -} +} \ No newline at end of file diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs new file mode 100644 index 000000000..f1489f7ff --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs @@ -0,0 +1,8 @@ +namespace Neo.Compiler.MSIL.Utils +{ + class TestStorageContext + { + public bool IsReadOnly { get; set; } + public UInt160 ScriptHash { get; set; } + } +} \ No newline at end of file From 50a723cb839bae8a83707f0624b08a19e21b7609 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sun, 25 Aug 2019 16:51:50 +0200 Subject: [PATCH 04/14] Add comments --- tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs index 1595bad44..3a5d558fb 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs @@ -11,6 +11,11 @@ namespace Neo.Compiler.MSIL.Utils { internal static class NeonTestTool { + /// + /// Is not the official script hash, just a unique hash related to the script used for unit test purpose + /// + /// Context + /// UInt160 public static UInt160 ScriptHash(this ExecutionContext context) { using (var sha = SHA1.Create()) From c595344fcd33501239fb399882a4480897daecd3 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 09:39:49 +0200 Subject: [PATCH 05/14] Changed unit test, for don't pass the prefix --- .../TestClasses/Contract_StorageMap.cs | 30 +++++++++++-------- .../UnitTest_StorageMap.cs | 10 +++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs index 9968a9157..37903ac11 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StorageMap.cs @@ -8,25 +8,25 @@ class Contract_StorageMap : SmartContract.Framework.SmartContract #region Byte - public static bool TestPutByte(byte prefix, byte[] key, byte[] value) + public static bool TestPutByte(byte[] key, byte[] value) { - var storage = Storage.CurrentContext.CreateMap(prefix); + var storage = Storage.CurrentContext.CreateMap(0xAA); storage.Put(key, value); return true; } - public static bool TestDeleteByte(byte prefix, byte[] key) + public static bool TestDeleteByte(byte[] key) { - var storage = Storage.CurrentContext.CreateMap(prefix); + var storage = Storage.CurrentContext.CreateMap(0xAA); var value = storage.Get(key); var exists = value.Length > 0; storage.Delete(key); return exists; } - public static byte[] TestGetByte(byte prefix, byte[] key) + public static byte[] TestGetByte(byte[] key) { - var storage = Storage.CurrentContext.CreateMap(prefix); + var storage = Storage.CurrentContext.CreateMap(0xAA); var value = storage.Get(key); return value; } @@ -35,15 +35,17 @@ public static byte[] TestGetByte(byte prefix, byte[] key) #region String - public static bool TestPutString(string prefix, byte[] key, byte[] value) + public static bool TestPutString(byte[] key, byte[] value) { + var prefix = "aa"; var storage = Storage.CurrentContext.CreateMap(prefix); storage.Put(key, value); return true; } - public static bool TestDeleteString(string prefix, byte[] key) + public static bool TestDeleteString(byte[] key) { + var prefix = "aa"; var storage = Storage.CurrentContext.CreateMap(prefix); var value = storage.Get(key); var exists = value.Length > 0; @@ -51,8 +53,9 @@ public static bool TestDeleteString(string prefix, byte[] key) return exists; } - public static byte[] TestGetString(string prefix, byte[] key) + public static byte[] TestGetString(byte[] key) { + var prefix = "aa"; var storage = Storage.CurrentContext.CreateMap(prefix); var value = storage.Get(key); return value; @@ -62,15 +65,17 @@ public static byte[] TestGetString(string prefix, byte[] key) #region ByteArray - public static bool TestPutByteArray(byte[] prefix, byte[] key, byte[] value) + public static bool TestPutByteArray(byte[] key, byte[] value) { + var prefix = new byte[] { 0x00, 0xFF }; var storage = Storage.CurrentContext.CreateMap(prefix); storage.Put(key, value); return true; } - public static bool TestDeleteByteArray(byte[] prefix, byte[] key) + public static bool TestDeleteByteArray(byte[] key) { + var prefix = new byte[] { 0x00, 0xFF }; var storage = Storage.CurrentContext.CreateMap(prefix); var value = storage.Get(key); var exists = value.Length > 0; @@ -78,8 +83,9 @@ public static bool TestDeleteByteArray(byte[] prefix, byte[] key) return exists; } - public static byte[] TestGetByteArray(byte[] prefix, byte[] key) + public static byte[] TestGetByteArray(byte[] key) { + var prefix = new byte[] { 0x00, 0xFF }; var storage = Storage.CurrentContext.CreateMap(prefix); var value = storage.Get(key); return value; diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs index d7bffd4dd..64db1c814 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs @@ -10,7 +10,7 @@ public class UnitTest_StorageMap { private void Put(TestEngine testengine, string method, byte[] prefix, byte[] key, byte[] value) { - var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key), new ByteArray(value)); + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(key), new ByteArray(value)); var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(Integer)); Assert.AreEqual(1, rItem.GetBigInteger()); @@ -26,7 +26,7 @@ private void Put(TestEngine testengine, string method, byte[] prefix, byte[] key private byte[] Get(TestEngine testengine, string method, byte[] prefix, byte[] key) { - var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key)); + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(key)); Assert.AreEqual(1, result.Count); var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(ByteArray)); @@ -38,7 +38,7 @@ private byte[] Get(TestEngine testengine, string method, byte[] prefix, byte[] k private bool Delete(TestEngine testengine, string method, byte[] prefix, byte[] key) { - var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(prefix), new ByteArray(key)); + var result = testengine.ExecuteTestCaseStandard(method, new ByteArray(key)); Assert.AreEqual(1, result.Count); var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(Boolean)); @@ -54,7 +54,7 @@ public void Test_Byte() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); - var prefix = new byte[] { 0xFF }; + var prefix = new byte[] { 0xAA, 0x00 }; // The byte is consider as a number, so 0x00 is append at the end var key = new byte[] { 0x01, 0x02, 0x03 }; var value = new byte[] { 0x04, 0x05, 0x06 }; @@ -110,7 +110,7 @@ public void Test_String() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); - var prefix = new byte[] { 0x00, 0xFF }; + var prefix = new byte[] { 0x61, 0x61 }; var key = new byte[] { 0x01, 0x02, 0x03 }; var value = new byte[] { 0x04, 0x05, 0x06 }; From 301e891abe7de5b9ead53ec961229f8d6f69e1e6 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 09:42:30 +0200 Subject: [PATCH 06/14] Fix comment --- tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs index 64db1c814..62111bcdf 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs @@ -54,7 +54,7 @@ public void Test_Byte() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); - var prefix = new byte[] { 0xAA, 0x00 }; // The byte is consider as a number, so 0x00 is append at the end + var prefix = new byte[] { 0xAA, 0x00 }; // The byte is considered a number, so 0x00 is append at the end var key = new byte[] { 0x01, 0x02, 0x03 }; var value = new byte[] { 0x04, 0x05, 0x06 }; From 0f496ec0e1ddc053103838353e929af970117021 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 09:46:27 +0200 Subject: [PATCH 07/14] Change to AsByteArray --- src/Neo.SmartContract.Framework/Services/Neo/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index 8fbf24268..b2042aac1 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -27,7 +27,7 @@ public static StorageMap CreateMap(this StorageContext context, byte prefix) return new StorageMap { Context = context, - Prefix = (byte[])(object)prefix + Prefix = prefix.AsByteArray() }; } From d5387608554c70655e9802343ff5ea77cae63da7 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 09:50:26 +0200 Subject: [PATCH 08/14] Fix AsByteArray from byte --- src/Neo.SmartContract.Framework/Helper.cs | 3 ++- tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 576e2860e..3ef4b465d 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -8,7 +8,8 @@ public static class Helper /// /// Converts byte to byte[]. /// - [Script] + [OpCode(OpCode.PUSH1)] + [OpCode(OpCode.LEFT)] public extern static byte[] AsByteArray(this byte source); /// diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs index 62111bcdf..f247fce8b 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs @@ -54,7 +54,7 @@ public void Test_Byte() var testengine = new TestEngine(); testengine.AddEntryScript("./TestClasses/Contract_StorageMap.cs"); - var prefix = new byte[] { 0xAA, 0x00 }; // The byte is considered a number, so 0x00 is append at the end + var prefix = new byte[] { 0xAA }; var key = new byte[] { 0x01, 0x02, 0x03 }; var value = new byte[] { 0x04, 0x05, 0x06 }; From e290835acd669e6fa4c80c00ab041ad840ebdb05 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 09:59:29 +0200 Subject: [PATCH 09/14] ToByteArray --- src/Neo.SmartContract.Framework/Helper.cs | 7 ++++++- src/Neo.SmartContract.Framework/Services/Neo/Helper.cs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 3ef4b465d..31cc215c8 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -5,12 +5,17 @@ namespace Neo.SmartContract.Framework { public static class Helper { + /// + /// Converts byte to byte[] consider the byte as a BigInteger (0x00 at the end) + /// + public extern static byte[] AsByteArray(this byte source); + /// /// Converts byte to byte[]. /// [OpCode(OpCode.PUSH1)] [OpCode(OpCode.LEFT)] - public extern static byte[] AsByteArray(this byte source); + public extern static byte[] ToByteArray(this byte source); /// /// Converts sbyte to byte[]. diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index b2042aac1..00c1da643 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -27,7 +27,7 @@ public static StorageMap CreateMap(this StorageContext context, byte prefix) return new StorageMap { Context = context, - Prefix = prefix.AsByteArray() + Prefix = prefix.ToByteArray() }; } From fe036f726131dd64f7b03044b3d7db459dd0c1c5 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 10:01:18 +0200 Subject: [PATCH 10/14] Fix comment --- src/Neo.SmartContract.Framework/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 31cc215c8..9f5c298da 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -6,7 +6,7 @@ namespace Neo.SmartContract.Framework public static class Helper { /// - /// Converts byte to byte[] consider the byte as a BigInteger (0x00 at the end) + /// Converts byte to byte[] considering the byte as a BigInteger (0x00 at the end) /// public extern static byte[] AsByteArray(this byte source); From b9ea4d67dfefc89b445b675474a64290b93a2d29 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 10:08:10 +0200 Subject: [PATCH 11/14] Move and fix --- src/Neo.SmartContract.Framework/Helper.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 9f5c298da..3ea9342e4 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -8,15 +8,9 @@ public static class Helper /// /// Converts byte to byte[] considering the byte as a BigInteger (0x00 at the end) /// + [Script] public extern static byte[] AsByteArray(this byte source); - /// - /// Converts byte to byte[]. - /// - [OpCode(OpCode.PUSH1)] - [OpCode(OpCode.LEFT)] - public extern static byte[] ToByteArray(this byte source); - /// /// Converts sbyte to byte[]. /// @@ -138,6 +132,13 @@ public static class Helper // return (byte) source; //} + /// + /// Converts byte to byte[]. + /// + [OpCode(OpCode.PUSH1)] + [OpCode(OpCode.LEFT)] + public extern static byte[] ToByteArray(this byte source); + /// /// Converts parameter to sbyte from (big)integer range -128-255; faults if out-of-range. /// Examples: 256 -> fault; -1 -> -1 [0xff]; 255 -> -1 [0xff]; 0 -> 0 [0x00]; 10 -> 10 [0x0a]; 127 -> 127 [0x7f]; 128 -> -128 [0x80] From ea59a5e6b7fbf55bf716c3fa59ab2d0ca0187531 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 21:47:26 +0200 Subject: [PATCH 12/14] Clean blank lines --- .../Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs index f247fce8b..47a8f79be 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StorageMap.cs @@ -14,7 +14,6 @@ private void Put(TestEngine testengine, string method, byte[] prefix, byte[] key var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(Integer)); Assert.AreEqual(1, rItem.GetBigInteger()); - Assert.AreEqual(1, testengine.Storages .Count(a => @@ -30,9 +29,7 @@ private byte[] Get(TestEngine testengine, string method, byte[] prefix, byte[] k Assert.AreEqual(1, result.Count); var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(ByteArray)); - Assert.AreEqual(1, testengine.Storages.Count(a => a.Key.Key.SequenceEqual(prefix.Concat(key)))); - return rItem.GetByteArray(); } @@ -42,9 +39,7 @@ private bool Delete(TestEngine testengine, string method, byte[] prefix, byte[] Assert.AreEqual(1, result.Count); var rItem = result.Pop(); Assert.IsInstanceOfType(rItem, typeof(Boolean)); - Assert.AreEqual(0, testengine.Storages.Count(a => a.Key.Key.SequenceEqual(prefix.Concat(key)))); - return rItem.GetBoolean(); } @@ -65,7 +60,6 @@ public void Test_Byte() // Get var getVal = Get(testengine, "TestGetByte", prefix, key); - CollectionAssert.AreEqual(value, getVal); // Delete @@ -93,7 +87,6 @@ public void Test_ByteArray() // Get var getVal = Get(testengine, "TestGetByteArray", prefix, key); - CollectionAssert.AreEqual(value, getVal); // Delete @@ -121,7 +114,6 @@ public void Test_String() // Get var getVal = Get(testengine, "TestGetString", prefix, key); - CollectionAssert.AreEqual(value, getVal); // Delete @@ -132,4 +124,4 @@ public void Test_String() Assert.IsFalse(del); } } -} \ No newline at end of file +} From 137e9b250c194649a3a7fc8a11b7e208a09a8551 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 22:00:27 +0200 Subject: [PATCH 13/14] Fix format --- src/Neo.SmartContract.Framework/Services/Neo/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs index b9cfcb1ec..18b2a9d2b 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Helper.cs @@ -18,7 +18,7 @@ public static StorageMap CreateMap(this StorageContext context, byte[] prefix) return new StorageMap { Context = context, - Prefix = prefix + Prefix = prefix }; } From 402a20f6664c462567d1ad523a7ef4e2d6341923 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 26 Aug 2019 22:04:10 +0200 Subject: [PATCH 14/14] Fix format --- tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs | 2 +- tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs | 2 +- tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs index d2422a264..6d54e3f60 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs @@ -77,4 +77,4 @@ public static BuildScript BuildScript(string filename) } } } -} \ No newline at end of file +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs index e109c3828..56cdf9648 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestEngine.cs @@ -364,4 +364,4 @@ private void DumpItem(StackItem item, int space = 0) } } } -} \ No newline at end of file +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs index f1489f7ff..ab88c80d9 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/TestStorageContext.cs @@ -5,4 +5,4 @@ class TestStorageContext public bool IsReadOnly { get; set; } public UInt160 ScriptHash { get; set; } } -} \ No newline at end of file +}