From 9a272e1765c394488b3a24a6cf1f50effdf93dc2 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Fri, 17 Jan 2020 08:05:46 -0600 Subject: [PATCH] Contract Guid by counter (#1405) --- src/neo/Ledger/ContractIdState.cs | 42 ++++++++++++++ src/neo/Ledger/ContractState.cs | 13 +++-- src/neo/Ledger/StorageKey.cs | 16 +++--- src/neo/Persistence/ClonedView.cs | 2 + src/neo/Persistence/Prefixes.cs | 1 + src/neo/Persistence/ReadOnlyView.cs | 1 + src/neo/Persistence/SnapshotView.cs | 2 + src/neo/Persistence/StoreView.cs | 3 + src/neo/SmartContract/ApplicationEngine.cs | 2 - .../SmartContract/InteropService.Contract.cs | 9 +-- .../SmartContract/InteropService.Native.cs | 2 +- .../SmartContract/InteropService.Storage.cs | 14 ++--- .../SmartContract/Native/NativeContract.cs | 5 +- .../SmartContract/Native/PolicyContract.cs | 1 + .../SmartContract/Native/Tokens/GasToken.cs | 2 + .../SmartContract/Native/Tokens/NeoToken.cs | 4 +- src/neo/SmartContract/StorageContext.cs | 2 +- tests/neo.UnitTests/Consensus/UT_Consensus.cs | 2 +- .../neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- tests/neo.UnitTests/Ledger/UT_MemoryPool.cs | 6 +- tests/neo.UnitTests/Ledger/UT_StorageKey.cs | 44 +++++++------- .../Native/Tokens/UT_GasToken.cs | 2 +- .../Native/Tokens/UT_NeoToken.cs | 2 +- .../Native/Tokens/UT_Nep5Token.cs | 8 ++- .../SmartContract/Native/UT_NativeContract.cs | 3 + .../SmartContract/Native/UT_PolicyContract.cs | 2 +- .../SmartContract/UT_InteropService.NEO.cs | 18 +----- .../SmartContract/UT_InteropService.cs | 57 +++++++------------ .../SmartContract/UT_StorageContext.cs | 23 -------- tests/neo.UnitTests/UT_DataCache.cs | 42 +++++++------- 30 files changed, 167 insertions(+), 165 deletions(-) create mode 100644 src/neo/Ledger/ContractIdState.cs delete mode 100644 tests/neo.UnitTests/SmartContract/UT_StorageContext.cs diff --git a/src/neo/Ledger/ContractIdState.cs b/src/neo/Ledger/ContractIdState.cs new file mode 100644 index 0000000000..827a8d8a6c --- /dev/null +++ b/src/neo/Ledger/ContractIdState.cs @@ -0,0 +1,42 @@ +using Neo.IO; +using System; +using System.IO; + +namespace Neo.Ledger +{ + public class ContractIdState : ICloneable, ISerializable + { + public int Id; + + int ISerializable.Size => sizeof(int); + + ContractIdState ICloneable.Clone() + { + return new ContractIdState + { + Id = Id + }; + } + + void ISerializable.Deserialize(BinaryReader reader) + { + Id = reader.ReadInt32(); + if (Id < 0) throw new FormatException(); + } + + void ICloneable.FromReplica(ContractIdState replica) + { + Id = replica.Id; + } + + void ISerializable.Serialize(BinaryWriter writer) + { + writer.Write(Id); + } + + internal void Set(int value) + { + Id = value; + } + } +} diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 0f41d62ec8..74a0bb30fd 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -12,7 +12,7 @@ namespace Neo.Ledger { public class ContractState : ICloneable, ISerializable, IInteroperable { - public Guid Guid; + public int Id; public byte[] Script; public ContractManifest Manifest; @@ -32,13 +32,13 @@ public UInt160 ScriptHash } } - int ISerializable.Size => 16 + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize(); + int ISerializable.Size => sizeof(uint) + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize(); ContractState ICloneable.Clone() { return new ContractState { - Guid = Guid, + Id = Id, Script = Script, Manifest = Manifest.Clone() }; @@ -46,21 +46,21 @@ ContractState ICloneable.Clone() void ISerializable.Deserialize(BinaryReader reader) { - Guid = new Guid(reader.ReadBytes(16)); + Id = reader.ReadInt32(); Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); } void ICloneable.FromReplica(ContractState replica) { - Guid = replica.Guid; + Id = replica.Id; Script = replica.Script; Manifest = replica.Manifest.Clone(); } void ISerializable.Serialize(BinaryWriter writer) { - writer.Write(Guid.ToByteArray()); + writer.Write(Id); writer.WriteVarBytes(Script); writer.Write(Manifest); } @@ -68,6 +68,7 @@ void ISerializable.Serialize(BinaryWriter writer) public JObject ToJson() { JObject json = new JObject(); + json["id"] = Id; json["hash"] = ScriptHash.ToString(); json["script"] = Convert.ToBase64String(Script); json["manifest"] = Manifest.ToJson(); diff --git a/src/neo/Ledger/StorageKey.cs b/src/neo/Ledger/StorageKey.cs index 00de8b0b84..af7258f2ce 100644 --- a/src/neo/Ledger/StorageKey.cs +++ b/src/neo/Ledger/StorageKey.cs @@ -7,12 +7,12 @@ namespace Neo.Ledger { public class StorageKey : IEquatable, ISerializable { - public Guid Guid; + public int Id; public byte[] Key; - int ISerializable.Size => 16 + (Key.Length / 16 + 1) * 17; + int ISerializable.Size => sizeof(int) + (Key.Length / 16 + 1) * 17; - internal static byte[] CreateSearchPrefix(Guid guid, byte[] prefix) + internal static byte[] CreateSearchPrefix(int id, byte[] prefix) { using (MemoryStream ms = new MemoryStream()) { @@ -27,13 +27,13 @@ internal static byte[] CreateSearchPrefix(Guid guid, byte[] prefix) } if (remain > 0) ms.Write(prefix, index, remain); - return Helper.Concat(guid.ToByteArray(), ms.ToArray()); + return Helper.Concat(BitConverter.GetBytes(id), ms.ToArray()); } } void ISerializable.Deserialize(BinaryReader reader) { - Guid = new Guid(reader.ReadBytes(16)); + Id = reader.ReadInt32(); Key = reader.ReadBytesWithGrouping(); } @@ -43,7 +43,7 @@ public bool Equals(StorageKey other) return false; if (ReferenceEquals(this, other)) return true; - return Guid.Equals(other.Guid) && MemoryExtensions.SequenceEqual(Key, other.Key); + return Id == other.Id && MemoryExtensions.SequenceEqual(Key, other.Key); } public override bool Equals(object obj) @@ -54,12 +54,12 @@ public override bool Equals(object obj) public override int GetHashCode() { - return Guid.GetHashCode() + (int)Key.Murmur32(0); + return Id.GetHashCode() + (int)Key.Murmur32(0); } void ISerializable.Serialize(BinaryWriter writer) { - writer.Write(Guid.ToByteArray()); + writer.Write(Id); writer.WriteBytesWithGrouping(Key); } } diff --git a/src/neo/Persistence/ClonedView.cs b/src/neo/Persistence/ClonedView.cs index f820b8f31b..307438b2db 100644 --- a/src/neo/Persistence/ClonedView.cs +++ b/src/neo/Persistence/ClonedView.cs @@ -13,6 +13,7 @@ internal class ClonedView : StoreView public override DataCache, HeaderHashList> HeaderHashList { get; } public override MetaDataCache BlockHashIndex { get; } public override MetaDataCache HeaderHashIndex { get; } + public override MetaDataCache ContractId { get; } public ClonedView(StoreView view) { @@ -24,6 +25,7 @@ public ClonedView(StoreView view) this.HeaderHashList = view.HeaderHashList.CreateSnapshot(); this.BlockHashIndex = view.BlockHashIndex.CreateSnapshot(); this.HeaderHashIndex = view.HeaderHashIndex.CreateSnapshot(); + this.ContractId = view.ContractId.CreateSnapshot(); } } } diff --git a/src/neo/Persistence/Prefixes.cs b/src/neo/Persistence/Prefixes.cs index dad8540787..4cf7860b00 100644 --- a/src/neo/Persistence/Prefixes.cs +++ b/src/neo/Persistence/Prefixes.cs @@ -11,6 +11,7 @@ internal static class Prefixes public const byte IX_HeaderHashList = 0x80; public const byte IX_CurrentBlock = 0xc0; public const byte IX_CurrentHeader = 0xc1; + public const byte IX_CurrentContractId = 0xc2; /* Prefixes 0xf0 to 0xff are reserved for external use. * diff --git a/src/neo/Persistence/ReadOnlyView.cs b/src/neo/Persistence/ReadOnlyView.cs index 18bf05fae5..db9af7f175 100644 --- a/src/neo/Persistence/ReadOnlyView.cs +++ b/src/neo/Persistence/ReadOnlyView.cs @@ -19,6 +19,7 @@ public class ReadOnlyView : StoreView public override DataCache, HeaderHashList> HeaderHashList => new StoreDataCache, HeaderHashList>(store, Prefixes.IX_HeaderHashList); public override MetaDataCache BlockHashIndex => new StoreMetaDataCache(store, Prefixes.IX_CurrentBlock); public override MetaDataCache HeaderHashIndex => new StoreMetaDataCache(store, Prefixes.IX_CurrentHeader); + public override MetaDataCache ContractId => new StoreMetaDataCache(store, Prefixes.IX_CurrentContractId); public ReadOnlyView(IReadOnlyStore store) { diff --git a/src/neo/Persistence/SnapshotView.cs b/src/neo/Persistence/SnapshotView.cs index 3b20025cd0..5084f3665c 100644 --- a/src/neo/Persistence/SnapshotView.cs +++ b/src/neo/Persistence/SnapshotView.cs @@ -19,6 +19,7 @@ public class SnapshotView : StoreView, IDisposable public override DataCache, HeaderHashList> HeaderHashList { get; } public override MetaDataCache BlockHashIndex { get; } public override MetaDataCache HeaderHashIndex { get; } + public override MetaDataCache ContractId { get; } public SnapshotView(IStore store) { @@ -30,6 +31,7 @@ public SnapshotView(IStore store) HeaderHashList = new StoreDataCache, HeaderHashList>(snapshot, Prefixes.IX_HeaderHashList); BlockHashIndex = new StoreMetaDataCache(snapshot, Prefixes.IX_CurrentBlock); HeaderHashIndex = new StoreMetaDataCache(snapshot, Prefixes.IX_CurrentHeader); + ContractId = new StoreMetaDataCache(snapshot, Prefixes.IX_CurrentContractId); } public override void Commit() diff --git a/src/neo/Persistence/StoreView.cs b/src/neo/Persistence/StoreView.cs index 4c2a1eed78..62a4afae1e 100644 --- a/src/neo/Persistence/StoreView.cs +++ b/src/neo/Persistence/StoreView.cs @@ -18,11 +18,13 @@ public abstract class StoreView public abstract DataCache, HeaderHashList> HeaderHashList { get; } public abstract MetaDataCache BlockHashIndex { get; } public abstract MetaDataCache HeaderHashIndex { get; } + public abstract MetaDataCache ContractId { get; } public uint Height => BlockHashIndex.Get().Index; public uint HeaderHeight => HeaderHashIndex.Get().Index; public UInt256 CurrentBlockHash => BlockHashIndex.Get().Hash; public UInt256 CurrentHeaderHash => HeaderHashIndex.Get().Hash; + public int CurrentContractId => ContractId.Get().Id; public StoreView Clone() { @@ -38,6 +40,7 @@ public virtual void Commit() HeaderHashList.Commit(); BlockHashIndex.Commit(); HeaderHashIndex.Commit(); + ContractId.Commit(); } public bool ContainsBlock(UInt256 hash) diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index c65fb0d409..53bc8c68a8 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -30,7 +30,6 @@ public partial class ApplicationEngine : ExecutionEngine public UInt160 EntryScriptHash => EntryContext?.GetState().ScriptHash; public IReadOnlyList Notifications => notifications; internal Dictionary InvocationCounter { get; } = new Dictionary(); - internal uint SyscallCounter { get; private set; } public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false) { @@ -81,7 +80,6 @@ protected override bool OnSysCall(uint method) { if (!AddGas(InteropService.GetPrice(method, CurrentContext.EvaluationStack))) return false; - SyscallCounter++; return InteropService.Invoke(this, method); } diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 62c307b665..2875d21dd4 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -28,11 +28,6 @@ private static long GetDeploymentPrice(EvaluationStack stack) return Storage.GasPerByte * size; } - internal static Guid GetDeterministicGuid(Transaction tx, uint nonce) - { - return new Guid(Concat(tx.Hash.ToArray(), BitConverter.GetBytes(nonce)).Sha256().AsSpan(0, 16)); - } - private static bool Contract_Create(ApplicationEngine engine) { byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); @@ -46,7 +41,7 @@ private static bool Contract_Create(ApplicationEngine engine) if (contract != null) return false; contract = new ContractState { - Guid = GetDeterministicGuid((Transaction)engine.ScriptContainer, engine.SyscallCounter), + Id = engine.Snapshot.ContractId.GetAndChange().Id++, Script = script, Manifest = ContractManifest.Parse(manifest) }; @@ -75,7 +70,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (engine.Snapshot.Contracts.TryGet(hash_new) != null) return false; contract = new ContractState { - Guid = contract.Guid, + Id = contract.Id, Script = script, Manifest = contract.Manifest }; diff --git a/src/neo/SmartContract/InteropService.Native.cs b/src/neo/SmartContract/InteropService.Native.cs index 9c639061a1..da3263b4a2 100644 --- a/src/neo/SmartContract/InteropService.Native.cs +++ b/src/neo/SmartContract/InteropService.Native.cs @@ -22,7 +22,7 @@ private static bool Native_Deploy(ApplicationEngine engine) { engine.Snapshot.Contracts.Add(contract.Hash, new ContractState { - Guid = contract.Guid, + Id = contract.Id, Script = contract.Script, Manifest = contract.Manifest }); diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index 77fb8079de..3355a5f83c 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -37,7 +37,7 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte StorageKey skey = new StorageKey { - Guid = context.Guid, + Id = context.Id, Key = key }; @@ -64,7 +64,7 @@ private static bool Storage_GetContext(ApplicationEngine engine) if (!contract.HasStorage) return false; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext { - Guid = contract.Guid, + Id = contract.Id, IsReadOnly = false })); return true; @@ -77,7 +77,7 @@ private static bool Storage_GetReadOnlyContext(ApplicationEngine engine) if (!contract.HasStorage) return false; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext { - Guid = contract.Guid, + Id = contract.Id, IsReadOnly = true })); return true; @@ -91,7 +91,7 @@ private static bool Storage_AsReadOnly(ApplicationEngine engine) if (!context.IsReadOnly) context = new StorageContext { - Guid = context.Guid, + Id = context.Id, IsReadOnly = true }; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(context)); @@ -108,7 +108,7 @@ private static bool Storage_Get(ApplicationEngine engine) byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey { - Guid = context.Guid, + Id = context.Id, Key = key }); engine.CurrentContext.EvaluationStack.Push(item?.Value ?? StackItem.Null); @@ -123,7 +123,7 @@ private static bool Storage_Find(ApplicationEngine engine) { StorageContext context = _interface.GetInterface(); byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Guid, prefix); + byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix); StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.AsSpan().StartsWith(prefix)).GetEnumerator())); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator)); return true; @@ -160,7 +160,7 @@ private static bool Storage_Delete(ApplicationEngine engine) if (context.IsReadOnly) return false; StorageKey key = new StorageKey { - Guid = context.Guid, + Id = context.Id, Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() }; if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false; diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index 4abb8766d0..b7c7f85251 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -28,7 +28,7 @@ public abstract class NativeContract public uint ServiceHash { get; } public byte[] Script { get; } public UInt160 Hash { get; } - public Guid Guid { get; } + public abstract int Id { get; } public ContractManifest Manifest { get; } public virtual string[] SupportedStandards { get; } = { "NEP-10" }; @@ -41,7 +41,6 @@ protected NativeContract() this.Script = sb.ToArray(); } this.Hash = Script.ToScriptHash(); - this.Guid = InteropService.Contract.GetDeterministicGuid(Blockchain.GenesisBlock.Transactions[0], ServiceHash); this.Manifest = ContractManifest.CreateDefault(this.Hash); List descriptors = new List(); List safeMethods = new List(); @@ -73,7 +72,7 @@ protected StorageKey CreateStorageKey(byte prefix, byte[] key = null) { StorageKey storageKey = new StorageKey { - Guid = Guid, + Id = Id, Key = new byte[sizeof(byte) + (key?.Length ?? 0)] }; storageKey.Key[0] = prefix; diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 2e48520380..1fc2976613 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -23,6 +23,7 @@ public sealed class PolicyContract : NativeContract private const byte Prefix_FeePerByte = 10; private const byte Prefix_BlockedAccounts = 15; private const byte Prefix_MaxBlockSize = 16; + public override int Id => -1; public PolicyContract() { diff --git a/src/neo/SmartContract/Native/Tokens/GasToken.cs b/src/neo/SmartContract/Native/Tokens/GasToken.cs index daa57b6747..77a41f8071 100644 --- a/src/neo/SmartContract/Native/Tokens/GasToken.cs +++ b/src/neo/SmartContract/Native/Tokens/GasToken.cs @@ -20,6 +20,8 @@ public sealed class GasToken : Nep5Token public override string Symbol => "gas"; public override byte Decimals => 8; + public override int Id => -3; + private const byte Prefix_SystemFeeAmount = 15; internal GasToken() diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index 2d281529f8..856a736cc7 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -24,6 +24,8 @@ public sealed class NeoToken : Nep5Token public override byte Decimals => 0; public BigInteger TotalAmount { get; } + public override int Id => -2; + private const byte Prefix_Validator = 33; private const byte Prefix_ValidatorsCount = 15; private const byte Prefix_NextValidators = 14; @@ -201,7 +203,7 @@ private StackItem GetRegisteredValidators(ApplicationEngine engine, Array args) public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetRegisteredValidators(StoreView snapshot) { - byte[] prefix_key = StorageKey.CreateSearchPrefix(Guid, new[] { Prefix_Validator }); + byte[] prefix_key = StorageKey.CreateSearchPrefix(Id, new[] { Prefix_Validator }); return snapshot.Storages.Find(prefix_key).Select(p => ( p.Key.Key.AsSerializable(1), diff --git a/src/neo/SmartContract/StorageContext.cs b/src/neo/SmartContract/StorageContext.cs index e7bf015c9f..e8f7489762 100644 --- a/src/neo/SmartContract/StorageContext.cs +++ b/src/neo/SmartContract/StorageContext.cs @@ -4,7 +4,7 @@ namespace Neo.SmartContract { internal class StorageContext { - public Guid Guid; + public int Id; public bool IsReadOnly; } } diff --git a/tests/neo.UnitTests/Consensus/UT_Consensus.cs b/tests/neo.UnitTests/Consensus/UT_Consensus.cs index 97ebacfdbe..c7a0687729 100644 --- a/tests/neo.UnitTests/Consensus/UT_Consensus.cs +++ b/tests/neo.UnitTests/Consensus/UT_Consensus.cs @@ -915,7 +915,7 @@ private StorageKey CreateStorageKeyForNativeNeo(byte prefix) { StorageKey storageKey = new StorageKey { - ScriptHash = NativeContract.NEO.Hash, + Id = NativeContract.NEO.Id, Key = new byte[sizeof(byte)] }; storageKey.Key[0] = prefix; diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 670f31d757..8f730a20c0 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -84,7 +84,7 @@ public void TestDeserialize() public void TestGetSize() { ISerializable newContract = contract; - newContract.Size.Should().Be(368); + newContract.Size.Should().Be(372); } [TestMethod] diff --git a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs index 38a456bcf3..86ad694641 100644 --- a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -485,8 +485,8 @@ public void TestUpdatePoolForBlockPersisted() }; var key1 = CreateStorageKey(Prefix_MaxTransactionsPerBlock); var key2 = CreateStorageKey(Prefix_FeePerByte); - key1.ScriptHash = NativeContract.Policy.Hash; - key2.ScriptHash = NativeContract.Policy.Hash; + key1.Id = NativeContract.Policy.Id; + key2.Id = NativeContract.Policy.Id; snapshot.Storages.Add(key1, item1); snapshot.Storages.Add(key2, item2); @@ -510,7 +510,7 @@ public StorageKey CreateStorageKey(byte prefix, byte[] key = null) { StorageKey storageKey = new StorageKey { - ScriptHash = null, + Id = 0, Key = new byte[sizeof(byte) + (key?.Length ?? 0)] }; storageKey.Key[0] = prefix; diff --git a/tests/neo.UnitTests/Ledger/UT_StorageKey.cs b/tests/neo.UnitTests/Ledger/UT_StorageKey.cs index 1941cbc0cc..e71cdba716 100644 --- a/tests/neo.UnitTests/Ledger/UT_StorageKey.cs +++ b/tests/neo.UnitTests/Ledger/UT_StorageKey.cs @@ -18,30 +18,30 @@ public void TestSetup() } [TestMethod] - public void ScriptHash_Get() + public void Id_Get() { - uut.ScriptHash.Should().BeNull(); + uut.Id.Should().Be(0); } [TestMethod] public void Size() { - var ut = new StorageKey() { Key = new byte[17], ScriptHash = UInt160.Zero }; + var ut = new StorageKey() { Key = new byte[17], Id = 0 }; ut.ToArray().Length.Should().Be(((ISerializable)ut).Size); - ut = new StorageKey() { Key = new byte[0], ScriptHash = UInt160.Zero }; + ut = new StorageKey() { Key = new byte[0], Id = 0 }; ut.ToArray().Length.Should().Be(((ISerializable)ut).Size); - ut = new StorageKey() { Key = new byte[16], ScriptHash = UInt160.Zero }; + ut = new StorageKey() { Key = new byte[16], Id = 0 }; ut.ToArray().Length.Should().Be(((ISerializable)ut).Size); } [TestMethod] - public void ScriptHash_Set() + public void Id_Set() { - UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42)); - uut.ScriptHash = val; - uut.ScriptHash.Should().Be(val); + int val = 1; + uut.Id = val; + uut.Id.Should().Be(val); } [TestMethod] @@ -75,14 +75,14 @@ public void Equals_Null() [TestMethod] public void Equals_SameHash_SameKey() { - UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42)); + int val = 0x42000000; byte[] keyVal = TestUtils.GetByteArray(10, 0x42); StorageKey newSk = new StorageKey { - ScriptHash = val, + Id = val, Key = keyVal }; - uut.ScriptHash = val; + uut.Id = val; uut.Key = keyVal; uut.Equals(newSk).Should().BeTrue(); @@ -91,14 +91,14 @@ public void Equals_SameHash_SameKey() [TestMethod] public void Equals_DiffHash_SameKey() { - UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42)); + int val = 0x42000000; byte[] keyVal = TestUtils.GetByteArray(10, 0x42); StorageKey newSk = new StorageKey { - ScriptHash = val, + Id = val, Key = keyVal }; - uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x88)); + uut.Id = 0x78000000; uut.Key = keyVal; uut.Equals(newSk).Should().BeFalse(); @@ -108,14 +108,14 @@ public void Equals_DiffHash_SameKey() [TestMethod] public void Equals_SameHash_DiffKey() { - UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42)); + int val = 0x42000000; byte[] keyVal = TestUtils.GetByteArray(10, 0x42); StorageKey newSk = new StorageKey { - ScriptHash = val, + Id = val, Key = keyVal }; - uut.ScriptHash = val; + uut.Id = val; uut.Key = TestUtils.GetByteArray(10, 0x88); uut.Equals(newSk).Should().BeFalse(); @@ -124,9 +124,9 @@ public void Equals_SameHash_DiffKey() [TestMethod] public void GetHashCode_Get() { - uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42)); + uut.Id = 0x42000000; uut.Key = TestUtils.GetByteArray(10, 0x42); - uut.GetHashCode().Should().Be(806209853); + uut.GetHashCode().Should().Be(1374529787); } [TestMethod] @@ -143,13 +143,13 @@ public void TestDeserialize() using (BinaryWriter writer = new BinaryWriter(ms)) using (BinaryReader reader = new BinaryReader(ms)) { - uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42)); + uut.Id = 0x42000000; uut.Key = TestUtils.GetByteArray(10, 0x42); ((ISerializable)uut).Serialize(writer); ms.Seek(0, SeekOrigin.Begin); StorageKey dest = new StorageKey(); ((ISerializable)dest).Deserialize(reader); - dest.ScriptHash.Should().Be(uut.ScriptHash); + dest.Id.Should().Be(uut.Id); dest.Key.Should().BeEquivalentTo(uut.Key); } } diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs index 51caa8db9c..614322aa20 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs @@ -164,7 +164,7 @@ public void TestGetSysFeeAmount2() byte[] key = BitConverter.GetBytes(1); StorageKey storageKey = new StorageKey { - ScriptHash = NativeContract.GAS.Hash, + Id = NativeContract.GAS.Id, Key = new byte[sizeof(byte) + key.Length] }; storageKey.Key[0] = 15; diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs index 6111c9b052..6533b07541 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs @@ -704,7 +704,7 @@ internal static StorageKey CreateStorageKey(byte prefix, byte[] key = null) { StorageKey storageKey = new StorageKey { - ScriptHash = NativeContract.NEO.Hash, + Id = NativeContract.NEO.Id, Key = new byte[sizeof(byte) + (key?.Length ?? 0)] }; storageKey.Key[0] = prefix; diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs index 3cb10defe3..2e86994da3 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs @@ -33,7 +33,7 @@ public void TestTotalSupply() script = sb.ToArray(); } var Hash = script.ToScriptHash(); - key.ScriptHash = Hash; + key.Id = 0x10000005; snapshot.Storages.Add(key, item); TestNep5Token test = new TestNep5Token(); @@ -65,7 +65,7 @@ public void TestTotalSupplyDecimal() script = sb.ToArray(); } var Hash = script.ToScriptHash(); - key.ScriptHash = Hash; + key.Id = test.Id; snapshot.Storages.Add(key, item); @@ -78,7 +78,7 @@ public StorageKey CreateStorageKey(byte prefix, byte[] key = null) { StorageKey storageKey = new StorageKey { - ScriptHash = null, + Id = 0, Key = new byte[sizeof(byte) + (key?.Length ?? 0)] }; storageKey.Key[0] = prefix; @@ -97,6 +97,8 @@ public class TestNep5Token : Nep5Token public override string ServiceName => "test"; + public override int Id => 0x10000005; + public new StackItem TotalSupply(ApplicationEngine engine, VM.Types.Array args) { return base.TotalSupply(engine, args); diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 71cfd3c093..2252e60d8a 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -89,6 +89,9 @@ public void TestTestCall() public class TestNativeContract : NativeContract { public override string ServiceName => "test"; + + public override int Id => 0x10000006; + public StackItem TestOnPersist(ApplicationEngine engine, VMArray args) { return OnPersist(engine, args); diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 0b15d0732d..a173585182 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -234,7 +234,7 @@ public void TestCheckPolicy() StorageKey storageKey = new StorageKey { - ScriptHash = NativeContract.Policy.Hash, + Id = NativeContract.Policy.Id, Key = new byte[sizeof(byte)] }; storageKey.Key[0] = 15; diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 959eeecae8..814f55cb67 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -229,7 +229,7 @@ public void TestContract_Update() var storageKey = new StorageKey { - ScriptHash = state.ScriptHash, + Id = state.Id, Key = new byte[] { 0x01 } }; snapshot.Contracts.Add(state.ScriptHash, state); @@ -239,18 +239,6 @@ public void TestContract_Update() engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Contract.Update).Should().BeTrue(); - - // Remove Storage flag with something stored - - state.Manifest.Features = ContractFeatures.NoProperty; - snapshot.Contracts.Add(state.ScriptHash, state); - snapshot.Storages.Add(storageKey, storageItem); - - engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); - engine.LoadScript(state.Script); - engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); - engine.CurrentContext.EvaluationStack.Push(script); - InteropService.Invoke(engine, InteropService.Contract.Update).Should().BeFalse(); } [TestMethod] @@ -267,7 +255,7 @@ public void TestStorage_Find() }; var storageKey = new StorageKey { - ScriptHash = state.ScriptHash, + Id = state.Id, Key = new byte[] { 0x01 } }; snapshot.Contracts.Add(state.ScriptHash, state); @@ -278,7 +266,7 @@ public void TestStorage_Find() engine.CurrentContext.EvaluationStack.Push(new byte[] { 0x01 }); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false })); InteropService.Invoke(engine, InteropService.Storage.Find).Should().BeTrue(); diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 1fa676af60..7ad570ef0f 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -480,20 +480,26 @@ public void TestBlockchain_GetContract() [TestMethod] public void TestStorage_GetContext() { - var engine = GetEngine(); + var engine = GetEngine(false, true); + var state = TestUtils.GetContract(); + state.Manifest.Features = ContractFeatures.HasStorage; + engine.Snapshot.Contracts.Add(state.ScriptHash, state); + engine.LoadScript(state.Script); InteropService.Invoke(engine, InteropService.Storage.GetContext).Should().BeTrue(); var ret = (InteropInterface)engine.CurrentContext.EvaluationStack.Pop(); - ret.GetInterface().ScriptHash.Should().Be(engine.CurrentScriptHash); ret.GetInterface().IsReadOnly.Should().BeFalse(); } [TestMethod] public void TestStorage_GetReadOnlyContext() { - var engine = GetEngine(); + var engine = GetEngine(false, true); + var state = TestUtils.GetContract(); + state.Manifest.Features = ContractFeatures.HasStorage; + engine.Snapshot.Contracts.Add(state.ScriptHash, state); + engine.LoadScript(state.Script); InteropService.Invoke(engine, InteropService.Storage.GetReadOnlyContext).Should().BeTrue(); var ret = (InteropInterface)engine.CurrentContext.EvaluationStack.Pop(); - ret.GetInterface().ScriptHash.Should().Be(engine.CurrentScriptHash); ret.GetInterface().IsReadOnly.Should().BeTrue(); } @@ -506,7 +512,7 @@ public void TestStorage_Get() var storageKey = new StorageKey { - ScriptHash = state.ScriptHash, + Id = state.Id, Key = new byte[] { 0x01 } }; @@ -523,25 +529,11 @@ public void TestStorage_Get() engine.CurrentContext.EvaluationStack.Push(new byte[] { 0x01 }); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false })); InteropService.Invoke(engine, InteropService.Storage.Get).Should().BeTrue(); engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString()); - - snapshot.Contracts.Delete(state.ScriptHash); - engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); - engine.LoadScript(new byte[] { 0x01 }); - engine.CurrentContext.EvaluationStack.Push(new byte[] { 0x01 }); - engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext - { - ScriptHash = state.ScriptHash, - IsReadOnly = false - })); - InteropService.Invoke(engine, InteropService.Storage.Get).Should().BeFalse(); - - engine.CurrentContext.EvaluationStack.Push(1); - InteropService.Invoke(engine, InteropService.Storage.Get).Should().BeFalse(); } [TestMethod] @@ -559,11 +551,11 @@ public void TestStorage_Put() var state = TestUtils.GetContract(); var storageContext = new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false }; engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); - InteropService.Invoke(engine, InteropService.Storage.Put).Should().BeFalse(); + InteropService.Invoke(engine, InteropService.Storage.Put).Should().BeTrue(); //key.Length > MaxStorageKeySize key = new byte[InteropService.Storage.MaxKeySize + 1]; @@ -596,7 +588,7 @@ public void TestStorage_Put() var storageKey = new StorageKey { - ScriptHash = state.ScriptHash, + Id = state.Id, Key = new byte[] { 0x01 } }; var storageItem = new StorageItem @@ -644,7 +636,7 @@ public void TestStorage_PutEx() state.Manifest.Features = ContractFeatures.HasStorage; var storageKey = new StorageKey { - ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42)), + Id = 0x42000000, Key = new byte[] { 0x01 } }; var storageItem = new StorageItem @@ -660,7 +652,7 @@ public void TestStorage_PutEx() var value = new byte[] { 0x02 }; var storageContext = new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false }; engine.CurrentContext.EvaluationStack.Push((int)StorageFlags.None); @@ -683,7 +675,7 @@ public void TestStorage_Delete() state.Manifest.Features = ContractFeatures.HasStorage; var storageKey = new StorageKey { - ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42)), + Id = 0x42000000, Key = new byte[] { 0x01 } }; var storageItem = new StorageItem @@ -699,7 +691,7 @@ public void TestStorage_Delete() var key = new byte[] { 0x01 }; var storageContext = new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false }; engine.CurrentContext.EvaluationStack.Push(key); @@ -711,13 +703,6 @@ public void TestStorage_Delete() engine.CurrentContext.EvaluationStack.Push(key); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); InteropService.Invoke(engine, InteropService.Storage.Delete).Should().BeFalse(); - - //CheckStorageContext fail - storageContext.IsReadOnly = false; - state.Manifest.Features = ContractFeatures.NoProperty; - engine.CurrentContext.EvaluationStack.Push(key); - engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); - InteropService.Invoke(engine, InteropService.Storage.Delete).Should().BeFalse(); } [TestMethod] @@ -730,7 +715,7 @@ public void TestStorageContext_AsReadOnly() var state = TestUtils.GetContract(); var storageContext = new StorageContext { - ScriptHash = state.ScriptHash, + Id = state.Id, IsReadOnly = false }; engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); @@ -855,7 +840,7 @@ public void TestContract_Destroy() var storageKey = new StorageKey { - ScriptHash = scriptHash, + Id = 0x43000000, Key = new byte[] { 0x01 } }; snapshot.Contracts.Add(scriptHash, state); diff --git a/tests/neo.UnitTests/SmartContract/UT_StorageContext.cs b/tests/neo.UnitTests/SmartContract/UT_StorageContext.cs deleted file mode 100644 index d1210169dd..0000000000 --- a/tests/neo.UnitTests/SmartContract/UT_StorageContext.cs +++ /dev/null @@ -1,23 +0,0 @@ -using FluentAssertions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.IO; -using Neo.SmartContract; - -namespace Neo.UnitTests.SmartContract -{ - [TestClass] - public class UT_StorageContext - { - [TestMethod] - public void TestToArray() - { - UInt160 script_hash = new byte[] { 0x00 }.ToScriptHash(); - StorageContext context = new StorageContext() - { - ScriptHash = script_hash, - IsReadOnly = true - }; - context.ScriptHash.ToArray().Should().BeEquivalentTo(new byte[] { 0x00 }.ToScriptHash().ToArray()); - } - } -} diff --git a/tests/neo.UnitTests/UT_DataCache.cs b/tests/neo.UnitTests/UT_DataCache.cs index 0cee679316..4b8ad1de74 100644 --- a/tests/neo.UnitTests/UT_DataCache.cs +++ b/tests/neo.UnitTests/UT_DataCache.cs @@ -21,40 +21,40 @@ public void TestCachedFind_Between() var storages = snapshot.Storages; var cache = new CloneCache(storages); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); storages.Add ( - new StorageKey() { Key = new byte[] { 0x01, 0x01 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); storages.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x01 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x01 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); storages.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x03 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x03 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); cache.Add ( - new StorageKey() { Key = new byte[] { 0x01, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x01, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); cache.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); CollectionAssert.AreEqual( - cache.Find(new byte[21]).Select(u => u.Key.Key[1]).ToArray(), + cache.Find(new byte[5]).Select(u => u.Key.Key[1]).ToArray(), new byte[] { 0x01, 0x02, 0x03 } ); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); } [TestMethod] @@ -64,35 +64,33 @@ public void TestCachedFind_Last() var storages = snapshot.Storages; var cache = new CloneCache(storages); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); storages.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x01 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x01 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); storages.Add ( - new StorageKey() { Key = new byte[] { 0x01, 0x01 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x01, 0x01 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); cache.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); cache.Add ( - new StorageKey() { Key = new byte[] { 0x01, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x01, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); - - CollectionAssert.AreEqual( - cache.Find(new byte[21]).Select(u => u.Key.Key[1]).ToArray(), + CollectionAssert.AreEqual(cache.Find(new byte[5]).Select(u => u.Key.Key[1]).ToArray(), new byte[] { 0x01, 0x02 } ); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); } [TestMethod] @@ -102,25 +100,25 @@ public void TestCachedFind_Empty() var storages = snapshot.Storages; var cache = new CloneCache(storages); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); cache.Add ( - new StorageKey() { Key = new byte[] { 0x00, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x00, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); cache.Add ( - new StorageKey() { Key = new byte[] { 0x01, 0x02 }, ScriptHash = UInt160.Zero }, + new StorageKey() { Key = new byte[] { 0x01, 0x02 }, Id = 0 }, new StorageItem() { IsConstant = false, Value = new byte[] { } } ); CollectionAssert.AreEqual( - cache.Find(new byte[21]).Select(u => u.Key.Key[1]).ToArray(), + cache.Find(new byte[5]).Select(u => u.Key.Key[1]).ToArray(), new byte[] { 0x02 } ); - storages.DeleteWhere((k, v) => k.ScriptHash == UInt160.Zero); + storages.DeleteWhere((k, v) => k.Id == 0); } } }