From 65748d0f4f9a47f3a54809fdf07a8cc0ab11fe92 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Sat, 3 Aug 2019 15:41:33 +0800 Subject: [PATCH 1/2] Fixes `GetRegisteredValidators()` --- neo/Ledger/StorageKey.cs | 19 +++++++++++++++++++ neo/SmartContract/InteropService.NEO.cs | 18 +----------------- neo/SmartContract/Native/Tokens/NeoToken.cs | 3 ++- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/neo/Ledger/StorageKey.cs b/neo/Ledger/StorageKey.cs index f975b7a422..187a895aa3 100644 --- a/neo/Ledger/StorageKey.cs +++ b/neo/Ledger/StorageKey.cs @@ -13,6 +13,25 @@ public class StorageKey : IEquatable, ISerializable int ISerializable.Size => ScriptHash.Size + (Key.Length / 16 + 1) * 17; + internal static byte[] CreateSearchPrefix(UInt160 hash, byte[] prefix) + { + using (MemoryStream ms = new MemoryStream()) + { + int index = 0; + int remain = prefix.Length; + while (remain >= 16) + { + ms.Write(prefix, index, 16); + ms.WriteByte(16); + index += 16; + remain -= 16; + } + if (remain > 0) + ms.Write(prefix, index, remain); + return hash.ToArray().Concat(ms.ToArray()).ToArray(); + } + } + void ISerializable.Deserialize(BinaryReader reader) { ScriptHash = reader.ReadSerializable(); diff --git a/neo/SmartContract/InteropService.NEO.cs b/neo/SmartContract/InteropService.NEO.cs index 669a9b7073..91b941649f 100644 --- a/neo/SmartContract/InteropService.NEO.cs +++ b/neo/SmartContract/InteropService.NEO.cs @@ -10,7 +10,6 @@ using Neo.VM; using Neo.VM.Types; using System; -using System.IO; using System.Linq; using VMArray = Neo.VM.Types.Array; @@ -345,22 +344,7 @@ private static bool Storage_Find(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(); - byte[] prefix_key; - using (MemoryStream ms = new MemoryStream()) - { - int index = 0; - int remain = prefix.Length; - while (remain >= 16) - { - ms.Write(prefix, index, 16); - ms.WriteByte(16); - index += 16; - remain -= 16; - } - if (remain > 0) - ms.Write(prefix, index, remain); - prefix_key = context.ScriptHash.ToArray().Concat(ms.ToArray()).ToArray(); - } + byte[] prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.Take(prefix.Length).SequenceEqual(prefix)).GetEnumerator())); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator)); return true; diff --git a/neo/SmartContract/Native/Tokens/NeoToken.cs b/neo/SmartContract/Native/Tokens/NeoToken.cs index 6de1ac1970..f1b1595f74 100644 --- a/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -201,7 +201,8 @@ private StackItem GetRegisteredValidators(ApplicationEngine engine, VMArray args public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetRegisteredValidators(Snapshot snapshot) { - return snapshot.Storages.Find(new[] { Prefix_Validator }).Select(p => + byte[] prefix_key = StorageKey.CreateSearchPrefix(Hash, new[] { Prefix_Validator }); + return snapshot.Storages.Find(prefix_key).Select(p => ( p.Key.Key.Skip(1).ToArray().AsSerializable(), ValidatorState.FromByteArray(p.Value.Value).Votes From 248a2ade478255fdec29139ac8a5cd362b25413e Mon Sep 17 00:00:00 2001 From: Shargon Date: Sat, 3 Aug 2019 10:01:27 +0200 Subject: [PATCH 2/2] Add unit test --- .../SmartContract/Native/Tokens/UT_NeoToken.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs index 9a22bab3c4..efa3c2446c 100644 --- a/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs +++ b/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs @@ -128,6 +128,20 @@ public void Check_RegisterValidator() ret.Result.Should().BeTrue(); snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 1); // New validator + + // Check GetRegisteredValidators + + var validators = NativeContract.NEO.GetRegisteredValidators(snapshot).OrderBy(u => u.PublicKey).ToArray(); + var check = Blockchain.StandbyValidators.Select(u => u.EncodePoint(true)).ToList(); + check.Add(point); // Add the new member + + for (int x = 0; x < validators.Length; x++) + { + Assert.AreEqual(1, check.RemoveAll(u => u.SequenceEqual(validators[x].PublicKey.EncodePoint(true)))); + Assert.AreEqual(0, validators[x].Votes); + } + + Assert.AreEqual(0, check.Count); } [TestMethod] @@ -357,4 +371,4 @@ internal static void CheckBalance(byte[] account, DataCache