From 5765ae81493e571896bf82323c7cb91f4dedbc93 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 29 Dec 2020 15:58:34 +0800 Subject: [PATCH] Simplify Iterator APIs --- .../ApplicationEngine.Enumerator.cs | 36 ---------- .../ApplicationEngine.Iterator.cs | 21 ++---- .../ApplicationEngine.Storage.cs | 20 +++--- .../SmartContract/Enumerators/IEnumerator.cs | 11 --- .../Enumerators/IteratorKeysWrapper.cs | 30 -------- .../Enumerators/IteratorValuesWrapper.cs | 30 -------- .../Enumerators/StorageKeyEnumerator.cs | 36 ---------- src/neo/SmartContract/FindOptions.cs | 17 +++++ .../SmartContract/Iterators/ArrayWrapper.cs | 7 -- .../Iterators/ByteArrayWrapper.cs | 7 -- src/neo/SmartContract/Iterators/IIterator.cs | 7 +- src/neo/SmartContract/Iterators/MapWrapper.cs | 12 ++-- .../Iterators/StorageIterator.cs | 33 +++++++-- .../SmartContract/Native/NonfungibleToken.cs | 7 +- .../Enumerators/UT_IteratorKeysWrapper.cs | 36 ---------- .../Enumerators/UT_IteratorValuesWrapper.cs | 37 ---------- .../Enumerators/UT_StorageKeyEnumerator.cs | 69 ------------------- .../Iterators/UT_ArrayWrapper.cs | 3 - .../SmartContract/Iterators/UT_MapWrapper.cs | 11 +-- .../Iterators/UT_PrimitiveWrapper.cs | 4 -- .../Iterators/UT_StorageIterator.cs | 6 +- .../SmartContract/UT_InteropService.NEO.cs | 69 +++---------------- 22 files changed, 87 insertions(+), 422 deletions(-) delete mode 100644 src/neo/SmartContract/ApplicationEngine.Enumerator.cs delete mode 100644 src/neo/SmartContract/Enumerators/IEnumerator.cs delete mode 100644 src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs delete mode 100644 src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs delete mode 100644 src/neo/SmartContract/Enumerators/StorageKeyEnumerator.cs create mode 100644 src/neo/SmartContract/FindOptions.cs delete mode 100644 tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs delete mode 100644 tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs delete mode 100644 tests/neo.UnitTests/SmartContract/Enumerators/UT_StorageKeyEnumerator.cs diff --git a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs b/src/neo/SmartContract/ApplicationEngine.Enumerator.cs deleted file mode 100644 index f0e5839651..0000000000 --- a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Neo.SmartContract.Enumerators; -using Neo.SmartContract.Iterators; -using Neo.VM.Types; -using System; -using Array = Neo.VM.Types.Array; - -namespace Neo.SmartContract -{ - partial class ApplicationEngine - { - public static readonly InteropDescriptor System_Enumerator_Create = Register("System.Enumerator.Create", nameof(CreateEnumerator), 1 << 4, CallFlags.None); - public static readonly InteropDescriptor System_Enumerator_Next = Register("System.Enumerator.Next", nameof(EnumeratorNext), 1 << 15, CallFlags.None); - public static readonly InteropDescriptor System_Enumerator_Value = Register("System.Enumerator.Value", nameof(EnumeratorValue), 1 << 4, CallFlags.None); - - protected internal IEnumerator CreateEnumerator(StackItem item) - { - return item switch - { - Array array => new ArrayWrapper(array), - VM.Types.Buffer buffer => new ByteArrayWrapper(buffer), - PrimitiveType primitive => new ByteArrayWrapper(primitive), - _ => throw new ArgumentException() - }; - } - - protected internal bool EnumeratorNext(IEnumerator enumerator) - { - return enumerator.Next(); - } - - protected internal StackItem EnumeratorValue(IEnumerator enumerator) - { - return enumerator.Value(); - } - } -} diff --git a/src/neo/SmartContract/ApplicationEngine.Iterator.cs b/src/neo/SmartContract/ApplicationEngine.Iterator.cs index 685d195f2a..f8f6be2af7 100644 --- a/src/neo/SmartContract/ApplicationEngine.Iterator.cs +++ b/src/neo/SmartContract/ApplicationEngine.Iterator.cs @@ -1,4 +1,3 @@ -using Neo.SmartContract.Enumerators; using Neo.SmartContract.Iterators; using Neo.VM.Types; using System; @@ -9,35 +8,29 @@ namespace Neo.SmartContract partial class ApplicationEngine { public static readonly InteropDescriptor System_Iterator_Create = Register("System.Iterator.Create", nameof(CreateIterator), 1 << 4, CallFlags.None); - public static readonly InteropDescriptor System_Iterator_Key = Register("System.Iterator.Key", nameof(IteratorKey), 1 << 4, CallFlags.None); - public static readonly InteropDescriptor System_Iterator_Keys = Register("System.Iterator.Keys", nameof(IteratorKeys), 1 << 4, CallFlags.None); - public static readonly InteropDescriptor System_Iterator_Values = Register("System.Iterator.Values", nameof(IteratorValues), 1 << 4, CallFlags.None); + public static readonly InteropDescriptor System_Iterator_Next = Register("System.Iterator.Next", nameof(IteratorNext), 1 << 15, CallFlags.None); + public static readonly InteropDescriptor System_Iterator_Value = Register("System.Iterator.Value", nameof(IteratorValue), 1 << 4, CallFlags.None); protected internal IIterator CreateIterator(StackItem item) { return item switch { Array array => new ArrayWrapper(array), - Map map => new MapWrapper(map), + Map map => new MapWrapper(map, ReferenceCounter), VM.Types.Buffer buffer => new ByteArrayWrapper(buffer), PrimitiveType primitive => new ByteArrayWrapper(primitive), _ => throw new ArgumentException() }; } - protected internal PrimitiveType IteratorKey(IIterator iterator) + protected internal bool IteratorNext(IIterator iterator) { - return iterator.Key(); + return iterator.Next(); } - protected internal IEnumerator IteratorKeys(IIterator iterator) + protected internal StackItem IteratorValue(IIterator iterator) { - return new IteratorKeysWrapper(iterator); - } - - protected internal IEnumerator IteratorValues(IIterator iterator) - { - return new IteratorValuesWrapper(iterator); + return iterator.Value(); } } } diff --git a/src/neo/SmartContract/ApplicationEngine.Storage.cs b/src/neo/SmartContract/ApplicationEngine.Storage.cs index 2d542f7501..6cf08539bf 100644 --- a/src/neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/neo/SmartContract/ApplicationEngine.Storage.cs @@ -1,5 +1,4 @@ using Neo.Ledger; -using Neo.SmartContract.Enumerators; using Neo.SmartContract.Iterators; using Neo.SmartContract.Native; using System; @@ -17,7 +16,6 @@ partial class ApplicationEngine public static readonly InteropDescriptor System_Storage_AsReadOnly = Register("System.Storage.AsReadOnly", nameof(AsReadOnly), 1 << 4, CallFlags.ReadStates); public static readonly InteropDescriptor System_Storage_Get = Register("System.Storage.Get", nameof(Get), 1 << 15, CallFlags.ReadStates); public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 1 << 15, CallFlags.ReadStates); - public static readonly InteropDescriptor System_Storage_FindKeys = Register("System.Storage.FindKeys", nameof(FindKeys), 1 << 15, CallFlags.ReadStates); public static readonly InteropDescriptor System_Storage_Put = Register("System.Storage.Put", nameof(Put), 0, CallFlags.WriteStates); public static readonly InteropDescriptor System_Storage_PutEx = Register("System.Storage.PutEx", nameof(PutEx), 0, CallFlags.WriteStates); public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 0, CallFlags.WriteStates); @@ -62,22 +60,20 @@ protected internal byte[] Get(StorageContext context, byte[] key) })?.Value; } - protected internal IIterator Find(StorageContext context, byte[] prefix) + protected internal IIterator Find(StorageContext context, byte[] prefix, FindOptions options) { + if (options.HasFlag(FindOptions.KeysOnly) && options.HasFlag(FindOptions.ValuesOnly)) + throw new ArgumentException(); + if (options.HasFlag(FindOptions.PickField0) && options.HasFlag(FindOptions.PickField1)) + throw new ArgumentException(); + if ((options.HasFlag(FindOptions.PickField0) || options.HasFlag(FindOptions.PickField1)) && !options.HasFlag(FindOptions.DeserializeValues)) + throw new ArgumentException(); byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix); - StorageIterator iterator = new StorageIterator(Snapshot.Storages.Find(prefix_key).GetEnumerator()); + StorageIterator iterator = new StorageIterator(Snapshot.Storages.Find(prefix_key).GetEnumerator(), options, ReferenceCounter); Disposables.Add(iterator); return iterator; } - protected internal IEnumerator FindKeys(StorageContext context, byte[] prefix, byte removePrefix) - { - byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix); - StorageKeyEnumerator enumerator = new StorageKeyEnumerator(Snapshot.Storages.Find(prefix_key).Select(p => p.Key).GetEnumerator(), removePrefix); - Disposables.Add(enumerator); - return enumerator; - } - protected internal void Put(StorageContext context, byte[] key, byte[] value) { PutExInternal(context, key, value, StorageFlags.None); diff --git a/src/neo/SmartContract/Enumerators/IEnumerator.cs b/src/neo/SmartContract/Enumerators/IEnumerator.cs deleted file mode 100644 index 77da74bd43..0000000000 --- a/src/neo/SmartContract/Enumerators/IEnumerator.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Neo.VM.Types; -using System; - -namespace Neo.SmartContract.Enumerators -{ - public interface IEnumerator : IDisposable - { - bool Next(); - StackItem Value(); - } -} diff --git a/src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs b/src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs deleted file mode 100644 index a7a7f040a4..0000000000 --- a/src/neo/SmartContract/Enumerators/IteratorKeysWrapper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Neo.SmartContract.Iterators; -using Neo.VM.Types; - -namespace Neo.SmartContract.Enumerators -{ - internal class IteratorKeysWrapper : IEnumerator - { - private readonly IIterator iterator; - - public IteratorKeysWrapper(IIterator iterator) - { - this.iterator = iterator; - } - - public void Dispose() - { - iterator.Dispose(); - } - - public bool Next() - { - return iterator.Next(); - } - - public StackItem Value() - { - return iterator.Key(); - } - } -} diff --git a/src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs b/src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs deleted file mode 100644 index 5e285938cf..0000000000 --- a/src/neo/SmartContract/Enumerators/IteratorValuesWrapper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Neo.SmartContract.Iterators; -using Neo.VM.Types; - -namespace Neo.SmartContract.Enumerators -{ - internal class IteratorValuesWrapper : IEnumerator - { - private readonly IIterator iterator; - - public IteratorValuesWrapper(IIterator iterator) - { - this.iterator = iterator; - } - - public void Dispose() - { - iterator.Dispose(); - } - - public bool Next() - { - return iterator.Next(); - } - - public StackItem Value() - { - return iterator.Value(); - } - } -} diff --git a/src/neo/SmartContract/Enumerators/StorageKeyEnumerator.cs b/src/neo/SmartContract/Enumerators/StorageKeyEnumerator.cs deleted file mode 100644 index 3bb5b4e9db..0000000000 --- a/src/neo/SmartContract/Enumerators/StorageKeyEnumerator.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Neo.Ledger; -using Neo.VM.Types; -using System.Collections.Generic; - -namespace Neo.SmartContract.Enumerators -{ - internal class StorageKeyEnumerator : IEnumerator - { - private readonly IEnumerator enumerator; - private readonly byte removePrefix; - - public StorageKeyEnumerator(IEnumerator enumerator, byte removePrefix) - { - this.enumerator = enumerator; - this.removePrefix = removePrefix; - } - - public void Dispose() - { - enumerator.Dispose(); - } - - public bool Next() - { - return enumerator.MoveNext(); - } - - public StackItem Value() - { - byte[] key = enumerator.Current.Key; - if (removePrefix > 0) - key = key[removePrefix..]; - return key; - } - } -} diff --git a/src/neo/SmartContract/FindOptions.cs b/src/neo/SmartContract/FindOptions.cs new file mode 100644 index 0000000000..5c42929ae3 --- /dev/null +++ b/src/neo/SmartContract/FindOptions.cs @@ -0,0 +1,17 @@ +using System; + +namespace Neo.SmartContract +{ + [Flags] + public enum FindOptions : byte + { + None = 0, + + KeysOnly = 1 << 0, + RemovePrefix = 1 << 1, + ValuesOnly = 1 << 2, + DeserializeValues = 1 << 3, + PickField0 = 1 << 4, + PickField1 = 1 << 5 + } +} diff --git a/src/neo/SmartContract/Iterators/ArrayWrapper.cs b/src/neo/SmartContract/Iterators/ArrayWrapper.cs index c010466c99..aa460df093 100644 --- a/src/neo/SmartContract/Iterators/ArrayWrapper.cs +++ b/src/neo/SmartContract/Iterators/ArrayWrapper.cs @@ -18,13 +18,6 @@ public void Dispose() { } - public PrimitiveType Key() - { - if (index < 0) - throw new InvalidOperationException(); - return index; - } - public bool Next() { int next = index + 1; diff --git a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs index c26ca2b0e1..2750def603 100644 --- a/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs +++ b/src/neo/SmartContract/Iterators/ByteArrayWrapper.cs @@ -20,13 +20,6 @@ public ByteArrayWrapper(VM.Types.Buffer value) public void Dispose() { } - public PrimitiveType Key() - { - if (index < 0) - throw new InvalidOperationException(); - return index; - } - public bool Next() { int next = index + 1; diff --git a/src/neo/SmartContract/Iterators/IIterator.cs b/src/neo/SmartContract/Iterators/IIterator.cs index c5c866891a..d131b75977 100644 --- a/src/neo/SmartContract/Iterators/IIterator.cs +++ b/src/neo/SmartContract/Iterators/IIterator.cs @@ -1,10 +1,11 @@ -using Neo.SmartContract.Enumerators; using Neo.VM.Types; +using System; namespace Neo.SmartContract.Iterators { - public interface IIterator : IEnumerator + public interface IIterator : IDisposable { - PrimitiveType Key(); + bool Next(); + StackItem Value(); } } diff --git a/src/neo/SmartContract/Iterators/MapWrapper.cs b/src/neo/SmartContract/Iterators/MapWrapper.cs index 783993a43c..17dbb394d4 100644 --- a/src/neo/SmartContract/Iterators/MapWrapper.cs +++ b/src/neo/SmartContract/Iterators/MapWrapper.cs @@ -1,3 +1,4 @@ +using Neo.VM; using Neo.VM.Types; using System.Collections.Generic; @@ -6,10 +7,12 @@ namespace Neo.SmartContract.Iterators internal class MapWrapper : IIterator { private readonly IEnumerator> enumerator; + private readonly ReferenceCounter referenceCounter; - public MapWrapper(IEnumerable> map) + public MapWrapper(IEnumerable> map, ReferenceCounter referenceCounter) { this.enumerator = map.GetEnumerator(); + this.referenceCounter = referenceCounter; } public void Dispose() @@ -17,11 +20,6 @@ public void Dispose() enumerator.Dispose(); } - public PrimitiveType Key() - { - return enumerator.Current.Key; - } - public bool Next() { return enumerator.MoveNext(); @@ -29,7 +27,7 @@ public bool Next() public StackItem Value() { - return enumerator.Current.Value; + return new Struct(referenceCounter) { enumerator.Current.Key, enumerator.Current.Value }; } } } diff --git a/src/neo/SmartContract/Iterators/StorageIterator.cs b/src/neo/SmartContract/Iterators/StorageIterator.cs index a42875e1aa..bcca51b471 100644 --- a/src/neo/SmartContract/Iterators/StorageIterator.cs +++ b/src/neo/SmartContract/Iterators/StorageIterator.cs @@ -1,4 +1,5 @@ using Neo.Ledger; +using Neo.VM; using Neo.VM.Types; using System.Collections.Generic; @@ -7,10 +8,14 @@ namespace Neo.SmartContract.Iterators internal class StorageIterator : IIterator { private readonly IEnumerator<(StorageKey Key, StorageItem Value)> enumerator; + private readonly FindOptions options; + private readonly ReferenceCounter referenceCounter; - public StorageIterator(IEnumerator<(StorageKey, StorageItem)> enumerator) + public StorageIterator(IEnumerator<(StorageKey, StorageItem)> enumerator, FindOptions options, ReferenceCounter referenceCounter) { this.enumerator = enumerator; + this.options = options; + this.referenceCounter = referenceCounter; } public void Dispose() @@ -18,11 +23,6 @@ public void Dispose() enumerator.Dispose(); } - public PrimitiveType Key() - { - return enumerator.Current.Key.Key; - } - public bool Next() { return enumerator.MoveNext(); @@ -30,7 +30,26 @@ public bool Next() public StackItem Value() { - return enumerator.Current.Value.Value; + byte[] key = enumerator.Current.Key.Key; + byte[] value = enumerator.Current.Value.Value; + + if (options.HasFlag(FindOptions.RemovePrefix)) + key = key[1..]; + + StackItem item = options.HasFlag(FindOptions.DeserializeValues) + ? BinarySerializer.Deserialize(value, 1024, (uint)value.Length, referenceCounter) + : value; + + if (options.HasFlag(FindOptions.PickField0)) + item = ((Array)item)[0]; + else if (options.HasFlag(FindOptions.PickField1)) + item = ((Array)item)[1]; + + if (options.HasFlag(FindOptions.KeysOnly)) + return key; + if (options.HasFlag(FindOptions.ValuesOnly)) + return item; + return new Struct(referenceCounter) { key, item }; } } } diff --git a/src/neo/SmartContract/Native/NonfungibleToken.cs b/src/neo/SmartContract/Native/NonfungibleToken.cs index a5f4aec75c..45969da8b5 100644 --- a/src/neo/SmartContract/Native/NonfungibleToken.cs +++ b/src/neo/SmartContract/Native/NonfungibleToken.cs @@ -2,7 +2,6 @@ using Neo.IO.Json; using Neo.Ledger; using Neo.Persistence; -using Neo.SmartContract.Enumerators; using Neo.SmartContract.Iterators; using Neo.SmartContract.Manifest; using Neo.VM; @@ -114,12 +113,12 @@ public BigInteger BalanceOf(StoreView snapshot, UInt160 owner) } [ContractMethod(0_01000000, CallFlags.ReadStates)] - public IEnumerator TokensOf(StoreView snapshot, UInt160 owner) + public IIterator TokensOf(StoreView snapshot, UInt160 owner) { if (owner is null) { - var keys = snapshot.Storages.Find(new[] { Prefix_Token }).Select(p => p.Key); - return new StorageKeyEnumerator(keys.GetEnumerator(), 1); + var results = snapshot.Storages.Find(new[] { Prefix_Token }).GetEnumerator(); + return new StorageIterator(results, FindOptions.ValuesOnly | FindOptions.DeserializeValues | FindOptions.PickField1, null); } else { diff --git a/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs deleted file mode 100644 index 12b82be599..0000000000 --- a/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorKeysWrapper.cs +++ /dev/null @@ -1,36 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.SmartContract.Enumerators; -using Neo.SmartContract.Iterators; -using Neo.VM.Types; -using System; -using System.Collections.Generic; - -namespace Neo.UnitTests.SmartContract.Enumerators -{ - [TestClass] - public class UT_IteratorKeysWrapper - { - [TestMethod] - public void TestGeneratorAndDispose() - { - IteratorKeysWrapper iteratorKeysWrapper = new IteratorKeysWrapper(new ArrayWrapper(new List())); - Assert.IsNotNull(iteratorKeysWrapper); - Action action = () => iteratorKeysWrapper.Dispose(); - action.Should().NotThrow(); - } - - [TestMethod] - public void TestNextAndValue() - { - StackItem stackItem = new VM.Types.Boolean(true); - List list = new List(); - list.Add(stackItem); - ArrayWrapper wrapper = new ArrayWrapper(list); - IteratorKeysWrapper iteratorKeysWrapper = new IteratorKeysWrapper(wrapper); - Action action = () => iteratorKeysWrapper.Next(); - action.Should().NotThrow(); - Assert.AreEqual(new VM.Types.Integer(0), iteratorKeysWrapper.Value()); - } - } -} diff --git a/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs deleted file mode 100644 index 2e8bf5709b..0000000000 --- a/tests/neo.UnitTests/SmartContract/Enumerators/UT_IteratorValuesWrapper.cs +++ /dev/null @@ -1,37 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.SmartContract.Enumerators; -using Neo.SmartContract.Iterators; -using Neo.VM.Types; -using System; -using System.Collections.Generic; - -namespace Neo.UnitTests.SmartContract.Enumerators -{ - - [TestClass] - public class UT_IteratorValuesWrapper - { - [TestMethod] - public void TestGeneratorAndDispose() - { - IteratorValuesWrapper iteratorValuesWrapper = new IteratorValuesWrapper(new ArrayWrapper(new List())); - Assert.IsNotNull(iteratorValuesWrapper); - Action action = () => iteratorValuesWrapper.Dispose(); - action.Should().NotThrow(); - } - - [TestMethod] - public void TestNextAndValue() - { - StackItem stackItem = new VM.Types.Boolean(true); - List list = new List(); - list.Add(stackItem); - ArrayWrapper wrapper = new ArrayWrapper(list); - IteratorValuesWrapper iteratorValuesWrapper = new IteratorValuesWrapper(wrapper); - Action action = () => iteratorValuesWrapper.Next(); - action.Should().NotThrow(); - Assert.AreEqual(stackItem, iteratorValuesWrapper.Value()); - } - } -} diff --git a/tests/neo.UnitTests/SmartContract/Enumerators/UT_StorageKeyEnumerator.cs b/tests/neo.UnitTests/SmartContract/Enumerators/UT_StorageKeyEnumerator.cs deleted file mode 100644 index 6a69e8638c..0000000000 --- a/tests/neo.UnitTests/SmartContract/Enumerators/UT_StorageKeyEnumerator.cs +++ /dev/null @@ -1,69 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Ledger; -using Neo.SmartContract.Enumerators; -using System; -using System.Collections.Generic; - -namespace Neo.UnitTests.SmartContract.Enumerators -{ - [TestClass] - public class UT_StorageKeyEnumerator - { - private class TestEnumeratorDispose : IEnumerator - { - public bool IsDisposed { get; private set; } - public StorageKey Current => throw new NotImplementedException(); - object System.Collections.IEnumerator.Current => throw new NotImplementedException(); - public void Dispose() - { - IsDisposed = true; - } - public bool MoveNext() => throw new NotImplementedException(); - public void Reset() => throw new NotImplementedException(); - } - - [TestMethod] - public void TestGeneratorAndDispose() - { - var enumerator = new TestEnumeratorDispose(); - var iterator = new StorageKeyEnumerator(enumerator, 0); - Action action = () => iterator.Dispose(); - enumerator.IsDisposed.Should().BeFalse(); - action.Should().NotThrow(); - enumerator.IsDisposed.Should().BeTrue(); - } - - [TestMethod] - public void TestNextAndValue() - { - var list = new List - { - new StorageKey() { Id = 1, Key = new byte[] { 1, 2, 3 } }, - new StorageKey() { Id = 1, Key = new byte[] { 4, 5, 6 } } - }; - - // With prefix - - var iterator = new StorageKeyEnumerator(list.GetEnumerator(), 0); - Action actionTrue = () => iterator.Next().Should().BeTrue(); - actionTrue.Should().NotThrow(); - CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, iterator.Value().GetSpan().ToArray()); - actionTrue.Should().NotThrow(); - CollectionAssert.AreEqual(new byte[] { 4, 5, 6 }, iterator.Value().GetSpan().ToArray()); - Action actionFalse = () => iterator.Next().Should().BeFalse(); - actionFalse.Should().NotThrow(); - - // Without prefix - - iterator = new StorageKeyEnumerator(list.GetEnumerator(), 2); - actionTrue = () => iterator.Next().Should().BeTrue(); - actionTrue.Should().NotThrow(); - CollectionAssert.AreEqual(new byte[] { 3 }, iterator.Value().GetSpan().ToArray()); - actionTrue.Should().NotThrow(); - CollectionAssert.AreEqual(new byte[] { 6 }, iterator.Value().GetSpan().ToArray()); - actionFalse = () => iterator.Next().Should().BeFalse(); - actionFalse.Should().NotThrow(); - } - } -} diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs index c997bb7fd6..18e2463c40 100644 --- a/tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_ArrayWrapper.cs @@ -26,12 +26,9 @@ public void TestKeyAndValue() StackItem stackItem = new Integer(0); list.Add(stackItem); ArrayWrapper arrayWrapper = new ArrayWrapper(list); - Action action1 = () => arrayWrapper.Key(); - action1.Should().Throw(); Action action2 = () => arrayWrapper.Value(); action2.Should().Throw(); arrayWrapper.Next(); - Assert.AreEqual(stackItem, arrayWrapper.Key()); Assert.AreEqual(stackItem, arrayWrapper.Value()); } diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs index 7ce7c7e845..7f7d663f72 100644 --- a/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_MapWrapper.cs @@ -13,7 +13,7 @@ public class UT_MapWrapper [TestMethod] public void TestGeneratorAndDispose() { - MapWrapper mapWrapper = new MapWrapper(new List>()); + MapWrapper mapWrapper = new MapWrapper(new List>(), null); Assert.IsNotNull(mapWrapper); Action action = () => mapWrapper.Dispose(); action.Should().NotThrow(); @@ -26,16 +26,17 @@ public void TestKeyAndValue() Integer stackItem1 = new Integer(0); StackItem stackItem2 = new Integer(1); list.Add(new KeyValuePair(stackItem1, stackItem2)); - MapWrapper mapWrapper = new MapWrapper(list); + MapWrapper mapWrapper = new MapWrapper(list, null); mapWrapper.Next(); - Assert.AreEqual(stackItem1, mapWrapper.Key()); - Assert.AreEqual(stackItem2, mapWrapper.Value()); + Struct @struct = (Struct)mapWrapper.Value(); + Assert.AreEqual(stackItem1, @struct[0]); + Assert.AreEqual(stackItem2, @struct[1]); } [TestMethod] public void TestNext() { - MapWrapper mapWrapper = new MapWrapper(new List>()); + MapWrapper mapWrapper = new MapWrapper(new List>(), null); Assert.AreEqual(false, mapWrapper.Next()); } } diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs index c097986de3..58b48e9503 100644 --- a/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_PrimitiveWrapper.cs @@ -22,15 +22,11 @@ public void TestGeneratorAndDispose() public void TestKeyAndValue() { ByteArrayWrapper arrayWrapper = new ByteArrayWrapper(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().GetInteger()); Assert.AreEqual(0x01, arrayWrapper.Value()); arrayWrapper.Next(); - Assert.AreEqual(0x01, arrayWrapper.Key().GetInteger()); Assert.AreEqual(0x02, arrayWrapper.Value()); } diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs index 72cb823d70..806c4d4817 100644 --- a/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs +++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs @@ -1,6 +1,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Ledger; +using Neo.SmartContract; using Neo.SmartContract.Iterators; using Neo.VM.Types; using System; @@ -14,7 +15,7 @@ public class UT_StorageIterator [TestMethod] public void TestGeneratorAndDispose() { - StorageIterator storageIterator = new StorageIterator(new List<(StorageKey, StorageItem)>().GetEnumerator()); + StorageIterator storageIterator = new StorageIterator(new List<(StorageKey, StorageItem)>().GetEnumerator(), FindOptions.None, null); Assert.IsNotNull(storageIterator); Action action = () => storageIterator.Dispose(); action.Should().NotThrow(); @@ -29,9 +30,8 @@ public void TestKeyAndValueAndNext() StorageItem storageItem = new StorageItem(); storageItem.Value = new byte[1]; list.Add((storageKey, storageItem)); - StorageIterator storageIterator = new StorageIterator(list.GetEnumerator()); + StorageIterator storageIterator = new StorageIterator(list.GetEnumerator(), FindOptions.ValuesOnly, null); storageIterator.Next(); - Assert.AreEqual(new ByteString(new byte[1]), storageIterator.Key()); Assert.AreEqual(new ByteString(new byte[1]), storageIterator.Value()); } } diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 73146fefbd..98cfcc1f14 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -285,38 +285,25 @@ public void TestStorage_Find() { Id = state.Id, IsReadOnly = false - }, new byte[] { 0x01 }); + }, new byte[] { 0x01 }, FindOptions.ValuesOnly); iterator.Next(); var ele = iterator.Value(); ele.GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString()); } [TestMethod] - public void TestEnumerator_Create() + public void TestIterator_Next() { var engine = GetEngine(); var arr = new VMArray { new byte[]{ 0x01 }, new byte[]{ 0x02 } }; - var ret = engine.CreateEnumerator(arr); - ret.Next(); - ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); - } - - [TestMethod] - public void TestEnumerator_Next() - { - var engine = GetEngine(); - var arr = new VMArray { - new byte[]{ 0x01 }, - new byte[]{ 0x02 } - }; - engine.EnumeratorNext(new ArrayWrapper(arr)).Should().BeTrue(); + engine.IteratorNext(new ArrayWrapper(arr)).Should().BeTrue(); } [TestMethod] - public void TestEnumerator_Value() + public void TestIterator_Value() { var engine = GetEngine(); var arr = new VMArray { @@ -325,7 +312,7 @@ public void TestEnumerator_Value() }; var wrapper = new ArrayWrapper(arr); wrapper.Next(); - engine.EnumeratorValue(wrapper).GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + engine.IteratorValue(wrapper).GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); } [TestMethod] @@ -350,49 +337,9 @@ public void TestIterator_Create() }; ret = engine.CreateIterator(map); ret.Next(); - ret.Key().GetInteger().Should().Be(1); - ret.Value().GetInteger().Should().Be(2); - } - - [TestMethod] - public void TestIterator_Key() - { - var engine = GetEngine(); - var arr = new VMArray { - new byte[]{ 0x01 }, - new byte[]{ 0x02 } - }; - var wrapper = new ArrayWrapper(arr); - wrapper.Next(); - engine.IteratorKey(wrapper).GetInteger().Should().Be(0); - } - - [TestMethod] - public void TestIterator_Keys() - { - var engine = GetEngine(); - var arr = new VMArray { - new byte[]{ 0x01 }, - new byte[]{ 0x02 } - }; - var wrapper = new ArrayWrapper(arr); - var ret = engine.IteratorKeys(wrapper); - ret.Next(); - ret.Value().GetInteger().Should().Be(0); - } - - [TestMethod] - public void TestIterator_Values() - { - var engine = GetEngine(); - var arr = new VMArray { - new byte[]{ 0x01 }, - new byte[]{ 0x02 } - }; - var wrapper = new ArrayWrapper(arr); - var ret = engine.IteratorValues(wrapper); - ret.Next(); - ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString()); + Struct @struct = (Struct)ret.Value(); + @struct[0].GetInteger().Should().Be(1); + @struct[1].GetInteger().Should().Be(2); } [TestMethod]