From ed28e32d01eabb855ba7c856aa894a111e812fa6 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 25 Nov 2019 20:06:21 +0100 Subject: [PATCH 1/8] Update changes --- src/neo/SmartContract/InteropService.NEO.cs | 17 ++++++-- .../Iterators/PrimitiveWrapper.cs | 42 +++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/neo/SmartContract/Iterators/PrimitiveWrapper.cs diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index 10798c053d..7312b9f21d 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -259,11 +259,20 @@ private static bool Storage_Find(ApplicationEngine engine) private static bool Enumerator_Create(ApplicationEngine engine) { - if (engine.CurrentContext.EvaluationStack.Pop() is VMArray array) + switch (engine.CurrentContext.EvaluationStack.Pop()) { - IEnumerator enumerator = new ArrayWrapper(array); - engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); - return true; + case VMArray array: + { + IEnumerator enumerator = new ArrayWrapper(array); + engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); + return true; + } + case PrimitiveType primitive: + { + IEnumerator enumerator = new PrimitiveWrapper(primitive); + engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); + return true; + } } return false; } diff --git a/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs b/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs new file mode 100644 index 0000000000..f857755f2e --- /dev/null +++ b/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs @@ -0,0 +1,42 @@ +using Neo.VM; +using Neo.VM.Types; +using System; + +namespace Neo.SmartContract.Iterators +{ + internal class PrimitiveWrapper : IIterator + { + private readonly byte[] value; + private int index = -1; + + public PrimitiveWrapper(PrimitiveType array) + { + this.value = array.GetSpan().ToArray(); + } + + public void Dispose() { } + + public PrimitiveType Key() + { + if (index < 0) + throw new InvalidOperationException(); + return index; + } + + public bool Next() + { + int next = index + 1; + if (next >= value.Length) + return false; + index = next; + return true; + } + + public StackItem Value() + { + if (index < 0) + throw new InvalidOperationException(); + return new Integer(value[index]); + } + } +} From 206c8aadfb34a34f94cbd79689c4ef59207625e8 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 Nov 2019 11:13:54 +0800 Subject: [PATCH 2/8] Fix UT --- tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 3e60b91591..fee6ea6a86 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -308,7 +308,7 @@ public void TestEnumerator_Create() .Should().Be(new byte[] { 0x01 }.ToHexString()); engine.CurrentContext.EvaluationStack.Push(1); - InteropService.Invoke(engine, InteropService.Neo_Enumerator_Create).Should().BeFalse(); + InteropService.Invoke(engine, InteropService.Neo_Enumerator_Create).Should().BeTrue(); } [TestMethod] From b4f1234016d8b3e8cdf6318c32a6add0fe58a487 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 Nov 2019 11:17:16 +0800 Subject: [PATCH 3/8] Rename --- src/neo/SmartContract/InteropService.NEO.cs | 2 +- .../Iterators/{PrimitiveWrapper.cs => ByteArrayWrapper.cs} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/neo/SmartContract/Iterators/{PrimitiveWrapper.cs => ByteArrayWrapper.cs} (89%) diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index 7312b9f21d..dfff90ac18 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -269,7 +269,7 @@ private static bool Enumerator_Create(ApplicationEngine engine) } case PrimitiveType primitive: { - IEnumerator enumerator = new PrimitiveWrapper(primitive); + IEnumerator enumerator = new ByteArrayWrapper(primitive); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); return true; } diff --git a/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs similarity index 89% rename from src/neo/SmartContract/Iterators/PrimitiveWrapper.cs rename to src/neo/SmartContract/Iterators/ByteArrayWrapper.cs index f857755f2e..776bb64b23 100644 --- a/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs +++ b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs @@ -4,12 +4,12 @@ namespace Neo.SmartContract.Iterators { - internal class PrimitiveWrapper : IIterator + internal class ByteArrayWrapper : IIterator { private readonly byte[] value; private int index = -1; - public PrimitiveWrapper(PrimitiveType array) + public ByteArrayWrapper(PrimitiveType array) { this.value = array.GetSpan().ToArray(); } From d294ad6ec5d173f0046f79efcb8b8b2797b7e4f0 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 Nov 2019 11:21:51 +0800 Subject: [PATCH 4/8] Update ByteArrayWrapper.cs --- src/neo/SmartContract/Iterators/ByteArrayWrapper.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs index 776bb64b23..d5baff7da0 100644 --- a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs +++ b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs @@ -1,4 +1,3 @@ -using Neo.VM; using Neo.VM.Types; using System; @@ -6,12 +5,12 @@ namespace Neo.SmartContract.Iterators { internal class ByteArrayWrapper : IIterator { - private readonly byte[] value; + private readonly byte[] array; private int index = -1; - public ByteArrayWrapper(PrimitiveType array) + public ByteArrayWrapper(PrimitiveType value) { - this.value = array.GetSpan().ToArray(); + this.array = value.ToByteArray().ToArray(); } public void Dispose() { } @@ -26,7 +25,7 @@ public PrimitiveType Key() public bool Next() { int next = index + 1; - if (next >= value.Length) + if (next >= array.Length) return false; index = next; return true; @@ -36,7 +35,7 @@ public StackItem Value() { if (index < 0) throw new InvalidOperationException(); - return new Integer(value[index]); + return new Integer(array[index]); } } } From 1c4750492319fd89400bb29e44438f13777cf87a Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 Nov 2019 11:27:33 +0800 Subject: [PATCH 5/8] Support Neo.Iterator.Create --- src/neo/SmartContract/InteropService.NEO.cs | 23 ++++++++++--------- .../SmartContract/UT_InteropService.NEO.cs | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index dfff90ac18..a133e882fa 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -259,22 +259,20 @@ private static bool Storage_Find(ApplicationEngine engine) private static bool Enumerator_Create(ApplicationEngine engine) { + IEnumerator enumerator; switch (engine.CurrentContext.EvaluationStack.Pop()) { case VMArray array: - { - IEnumerator enumerator = new ArrayWrapper(array); - engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); - return true; - } + enumerator = new ArrayWrapper(array); + break; case PrimitiveType primitive: - { - IEnumerator enumerator = new ByteArrayWrapper(primitive); - engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); - return true; - } + enumerator = new ByteArrayWrapper(primitive); + break; + default: + return false; } - return false; + engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(enumerator)); + return true; } private static bool Enumerator_Next(ApplicationEngine engine) @@ -321,6 +319,9 @@ private static bool Iterator_Create(ApplicationEngine engine) case Map map: iterator = new MapWrapper(map); break; + case PrimitiveType primitive: + iterator = new ByteArrayWrapper(primitive); + break; default: return false; } diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index fee6ea6a86..7c2e7c994b 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -395,7 +395,7 @@ public void TestIterator_Create() ret.GetInterface().Value().GetBigInteger().Should().Be(2); engine.CurrentContext.EvaluationStack.Push(1); - InteropService.Invoke(engine, InteropService.Neo_Iterator_Create).Should().BeFalse(); + InteropService.Invoke(engine, InteropService.Neo_Iterator_Create).Should().BeTrue(); } [TestMethod] From 84698fe131237d31d9eed3be32a9e97474c4fe97 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 26 Nov 2019 10:46:46 +0100 Subject: [PATCH 6/8] Add ut and Rename --- src/neo/SmartContract/InteropService.NEO.cs | 4 +- ...yteArrayWrapper.cs => PrimitiveWrapper.cs} | 4 +- .../Iterators/UT_PrimitiveWrapper.cs | 49 +++++++++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) rename src/neo/SmartContract/Iterators/{ByteArrayWrapper.cs => PrimitiveWrapper.cs} (89%) create mode 100644 tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index a133e882fa..ef3ba13049 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -266,7 +266,7 @@ private static bool Enumerator_Create(ApplicationEngine engine) enumerator = new ArrayWrapper(array); break; case PrimitiveType primitive: - enumerator = new ByteArrayWrapper(primitive); + enumerator = new PrimitiveWrapper(primitive); break; default: return false; @@ -320,7 +320,7 @@ private static bool Iterator_Create(ApplicationEngine engine) iterator = new MapWrapper(map); break; case PrimitiveType primitive: - iterator = new ByteArrayWrapper(primitive); + iterator = new PrimitiveWrapper(primitive); break; default: return false; diff --git a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs b/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs similarity index 89% rename from src/neo/SmartContract/Iterators/ByteArrayWrapper.cs rename to src/neo/SmartContract/Iterators/PrimitiveWrapper.cs index d5baff7da0..33c8a2b1c6 100644 --- a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs +++ b/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs @@ -3,12 +3,12 @@ namespace Neo.SmartContract.Iterators { - internal class ByteArrayWrapper : IIterator + internal class PrimitiveWrapper : IIterator { private readonly byte[] array; private int index = -1; - public ByteArrayWrapper(PrimitiveType value) + public PrimitiveWrapper(PrimitiveType value) { this.array = value.ToByteArray().ToArray(); } diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs new file mode 100644 index 0000000000..00fe49e4d7 --- /dev/null +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs @@ -0,0 +1,49 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.SmartContract.Iterators; +using Neo.VM; +using Neo.VM.Types; +using System; + +namespace Neo.UnitTests.SmartContract.Iterators +{ + [TestClass] + public class UT_PrimitiveWrapper + { + [TestMethod] + public void TestGeneratorAndDispose() + { + PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new ByteArray(new byte[0])); + Assert.IsNotNull(arrayWrapper); + Action action = () => arrayWrapper.Dispose(); + action.Should().NotThrow(); + } + + [TestMethod] + public void TestKeyAndValue() + { + PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new byte[] { 0x01, 0x02 }); + Action action1 = () => arrayWrapper.Key(); + action1.Should().Throw(); + Action action2 = () => arrayWrapper.Value(); + action2.Should().Throw(); + arrayWrapper.Next(); + Assert.AreEqual(0x00, arrayWrapper.Key().GetBigInteger()); + Assert.AreEqual(0x01, arrayWrapper.Value()); + arrayWrapper.Next(); + Assert.AreEqual(0x01, arrayWrapper.Key().GetBigInteger()); + Assert.AreEqual(0x02, arrayWrapper.Value()); + } + + [TestMethod] + public void TestNext() + { + PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new byte[] { 0x01, 0x02 }); + Assert.AreEqual(true, arrayWrapper.Next()); + Assert.AreEqual(0x01, arrayWrapper.Value()); + Assert.AreEqual(true, arrayWrapper.Next()); + Assert.AreEqual(0x02, arrayWrapper.Value()); + Assert.AreEqual(false, arrayWrapper.Next()); + } + } +} From 0f61fb693293fedac8c968718fc7f7a253507980 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 26 Nov 2019 11:13:54 +0100 Subject: [PATCH 7/8] Cover line --- tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 7c2e7c994b..57680ec7ef 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -382,6 +382,10 @@ public void TestIterator_Create() ret.GetInterface().Value().GetSpan().ToHexString() .Should().Be(new byte[] { 0x01 }.ToHexString()); + var interop = new InteropInterface(1); + engine.CurrentContext.EvaluationStack.Push(interop); + InteropService.Invoke(engine, InteropService.Neo_Iterator_Create).Should().BeFalse(); + var map = new Map { { new Integer(1), new Integer(2) }, From 4f8401800215f0d4d28056ad323665c525d42672 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 26 Nov 2019 12:32:00 +0100 Subject: [PATCH 8/8] Revert rename --- src/neo/SmartContract/InteropService.NEO.cs | 4 ++-- .../Iterators/{PrimitiveWrapper.cs => ByteArrayWrapper.cs} | 4 ++-- .../SmartContract/Iterators/UT_PrimitiveWrapper.cs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/neo/SmartContract/Iterators/{PrimitiveWrapper.cs => ByteArrayWrapper.cs} (89%) diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index ef3ba13049..a133e882fa 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -266,7 +266,7 @@ private static bool Enumerator_Create(ApplicationEngine engine) enumerator = new ArrayWrapper(array); break; case PrimitiveType primitive: - enumerator = new PrimitiveWrapper(primitive); + enumerator = new ByteArrayWrapper(primitive); break; default: return false; @@ -320,7 +320,7 @@ private static bool Iterator_Create(ApplicationEngine engine) iterator = new MapWrapper(map); break; case PrimitiveType primitive: - iterator = new PrimitiveWrapper(primitive); + iterator = new ByteArrayWrapper(primitive); break; default: return false; diff --git a/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs similarity index 89% rename from src/neo/SmartContract/Iterators/PrimitiveWrapper.cs rename to src/neo/SmartContract/Iterators/ByteArrayWrapper.cs index 33c8a2b1c6..d5baff7da0 100644 --- a/src/neo/SmartContract/Iterators/PrimitiveWrapper.cs +++ b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs @@ -3,12 +3,12 @@ namespace Neo.SmartContract.Iterators { - internal class PrimitiveWrapper : IIterator + internal class ByteArrayWrapper : IIterator { private readonly byte[] array; private int index = -1; - public PrimitiveWrapper(PrimitiveType value) + public ByteArrayWrapper(PrimitiveType value) { this.array = value.ToByteArray().ToArray(); } diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs index 00fe49e4d7..d8fd144812 100644 --- a/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs @@ -13,7 +13,7 @@ public class UT_PrimitiveWrapper [TestMethod] public void TestGeneratorAndDispose() { - PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new ByteArray(new byte[0])); + ByteArrayWrapper arrayWrapper = new ByteArrayWrapper(new ByteArray(new byte[0])); Assert.IsNotNull(arrayWrapper); Action action = () => arrayWrapper.Dispose(); action.Should().NotThrow(); @@ -22,7 +22,7 @@ public void TestGeneratorAndDispose() [TestMethod] public void TestKeyAndValue() { - PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new byte[] { 0x01, 0x02 }); + ByteArrayWrapper arrayWrapper = new ByteArrayWrapper(new byte[] { 0x01, 0x02 }); Action action1 = () => arrayWrapper.Key(); action1.Should().Throw(); Action action2 = () => arrayWrapper.Value(); @@ -38,7 +38,7 @@ public void TestKeyAndValue() [TestMethod] public void TestNext() { - PrimitiveWrapper arrayWrapper = new PrimitiveWrapper(new byte[] { 0x01, 0x02 }); + ByteArrayWrapper arrayWrapper = new ByteArrayWrapper(new byte[] { 0x01, 0x02 }); Assert.AreEqual(true, arrayWrapper.Next()); Assert.AreEqual(0x01, arrayWrapper.Value()); Assert.AreEqual(true, arrayWrapper.Next());