From 6a06d05927aef486ca11c2bacf812d94cf09e514 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Tue, 31 Dec 2019 15:59:26 +0800 Subject: [PATCH 01/17] change contract state --- neo/Ledger/ContractState.cs | 45 +++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/neo/Ledger/ContractState.cs b/neo/Ledger/ContractState.cs index c369e5d59f..df700c9e88 100644 --- a/neo/Ledger/ContractState.cs +++ b/neo/Ledger/ContractState.cs @@ -29,14 +29,45 @@ public UInt160 ScriptHash } } - int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize(); + int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize() + sizeof(bool) + RedirectionHash.ToArray().GetVarSize(); + + private UInt160 _redirectionHash = UInt160.Zero; + public virtual UInt160 RedirectionHash + { + get + { + return _redirectionHash; + } + + set + { + _redirectionHash = value; + } + } + + private bool isDeleted = false; + + public virtual bool IsDeleted + { + get + { + return isDeleted; + } + + set + { + isDeleted = value; + } + } ContractState ICloneable.Clone() { return new ContractState { Script = Script, - Manifest = Manifest.Clone() + Manifest = Manifest.Clone(), + RedirectionHash = RedirectionHash, + IsDeleted = IsDeleted }; } @@ -44,18 +75,24 @@ void ISerializable.Deserialize(BinaryReader reader) { Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); + RedirectionHash = reader.ReadSerializable(); + IsDeleted = reader.ReadBoolean(); } void ICloneable.FromReplica(ContractState replica) { Script = replica.Script; Manifest = replica.Manifest.Clone(); + RedirectionHash = replica.RedirectionHash; + IsDeleted = replica.IsDeleted; } void ISerializable.Serialize(BinaryWriter writer) { writer.WriteVarBytes(Script); writer.Write(Manifest); + writer.Write(RedirectionHash); + writer.Write(IsDeleted); } public JObject ToJson() @@ -64,6 +101,8 @@ public JObject ToJson() json["hash"] = ScriptHash.ToString(); json["script"] = Script.ToHexString(); json["manifest"] = Manifest.ToJson(); + json["redirectionHash"] = RedirectionHash.ToString(); + json["isDeleted"] = IsDeleted; return json; } @@ -72,6 +111,8 @@ public static ContractState FromJson(JObject json) ContractState contractState = new ContractState(); contractState.Script = json["script"].AsString().HexToBytes(); contractState.Manifest = ContractManifest.FromJson(json["manifest"]); + contractState.RedirectionHash = UInt160.Parse(json["RedirectionHash"].AsString()); + contractState.IsDeleted = json["isDeleted"].AsBoolean(); return contractState; } From 284d2d49d469fe7da9b6387004486a651aa84c3e Mon Sep 17 00:00:00 2001 From: doubiliu Date: Tue, 31 Dec 2019 16:33:31 +0800 Subject: [PATCH 02/17] change interopService of contract&storage --- .../SmartContract/InteropService.Contract.cs | 80 +++++++++++++------ .../SmartContract/InteropService.Storage.cs | 79 +++++++++++++++--- .../neo.UnitTests/Ledger/UT_ContractState.cs | 6 +- 3 files changed, 126 insertions(+), 39 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index e6df9d8aa8..9ca15c905d 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -41,6 +41,8 @@ private static bool Contract_Create(ApplicationEngine engine) Script = script, Manifest = ContractManifest.Parse(manifest) }; + contract.RedirectionHash = UInt160.Zero; + contract.IsDeleted = false; if (!contract.Manifest.IsValid(hash)) return false; @@ -56,50 +58,76 @@ private static bool Contract_Update(ApplicationEngine engine) var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString(); if (manifest.Length > ContractManifest.MaxLength) return false; - var contract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (contract is null) return false; - + var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); + if (oldcontract is null) return false; + if (oldcontract.IsDeleted) return false; + ContractState newcontract = null; if (script.Length > 0) { UInt160 hash_new = script.ToScriptHash(); if (hash_new.Equals(engine.CurrentScriptHash)) return false; if (engine.Snapshot.Contracts.TryGet(hash_new) != null) return false; - contract = new ContractState + newcontract = new ContractState { Script = script, - Manifest = contract.Manifest + Manifest = oldcontract.Manifest }; - contract.Manifest.Abi.Hash = hash_new; - engine.Snapshot.Contracts.Add(hash_new, contract); - if (contract.HasStorage) + if (oldcontract.RedirectionHash.Equals(UInt160.Zero)) + { + newcontract.RedirectionHash = oldcontract.ScriptHash; + } + else + { + newcontract.RedirectionHash = oldcontract.RedirectionHash; + } + newcontract.IsDeleted = false; + newcontract.Manifest.Abi.Hash = hash_new; + engine.Snapshot.Contracts.Add(hash_new, newcontract); + if (oldcontract.RedirectionHash.Equals(UInt160.Zero)) { - foreach (var (key, value) in engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).ToArray()) - { - engine.Snapshot.Storages.Add(new StorageKey - { - ScriptHash = hash_new, - Key = key.Key - }, new StorageItem - { - Value = value.Value, - IsConstant = false - }); - } + oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); + oldcontract.IsDeleted = true; + } + else + { + Contract_UnAppend_Destroy(engine); } - Contract_Destroy(engine); } if (manifest.Length > 0) { - contract = engine.Snapshot.Contracts.GetAndChange(contract.ScriptHash); - contract.Manifest = ContractManifest.Parse(manifest); - if (!contract.Manifest.IsValid(contract.ScriptHash)) return false; - if (!contract.HasStorage && engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).Any()) return false; + newcontract = engine.Snapshot.Contracts.GetAndChange(newcontract.ScriptHash); + newcontract.Manifest = ContractManifest.Parse(manifest); + if (!newcontract.Manifest.IsValid(newcontract.ScriptHash)) return false; + if (!newcontract.HasStorage && engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).Any()) return false; } return true; } private static bool Contract_Destroy(ApplicationEngine engine) + { + UInt160 hash = engine.CurrentScriptHash; + ContractState contract = engine.Snapshot.Contracts.TryGet(hash); + if (contract == null) return true; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) + { + ContractState initcontract = engine.Snapshot.Contracts.TryGet(contract.RedirectionHash); + if (initcontract != null) + { + engine.Snapshot.Contracts.Delete(contract.RedirectionHash); + if (initcontract.HasStorage) + foreach (var (key, _) in engine.Snapshot.Storages.Find(contract.RedirectionHash.ToArray())) + engine.Snapshot.Storages.Delete(key); + } + } + engine.Snapshot.Contracts.Delete(hash); + if (contract.HasStorage) + foreach (var (key, _) in engine.Snapshot.Storages.Find(hash.ToArray())) + engine.Snapshot.Storages.Delete(key); + return true; + } + + private static bool Contract_UnAppend_Destroy(ApplicationEngine engine) { UInt160 hash = engine.CurrentScriptHash; ContractState contract = engine.Snapshot.Contracts.TryGet(hash); @@ -142,6 +170,8 @@ private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHa ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); if (contract is null) return false; + if (contract.IsDeleted) return false; + ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; if (currentManifest != null && !currentManifest.CanCall(contract.Manifest, method.GetString())) diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index ebf826b7f5..d82916bcdc 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -44,11 +44,25 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte if (context.IsReadOnly) return false; if (!CheckStorageContext(engine, context)) return false; - StorageKey skey = new StorageKey + ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + if (contract == null) return false; + StorageKey skey; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) + { + skey = new StorageKey + { + ScriptHash = contract.RedirectionHash, + Key = key + }; + } + else { - ScriptHash = context.ScriptHash, - Key = key - }; + skey = new StorageKey + { + ScriptHash = context.ScriptHash, + Key = key + }; + } if (engine.Snapshot.Storages.TryGet(skey)?.IsConstant == true) return false; @@ -110,11 +124,26 @@ private static bool Storage_Get(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey + + ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + if (contract == null) return false; + StorageItem item = null; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) { - ScriptHash = context.ScriptHash, - Key = key - }); + item = engine.Snapshot.Storages.TryGet(new StorageKey + { + ScriptHash = contract.RedirectionHash, + Key = key + }); + } + else + { + item = engine.Snapshot.Storages.TryGet(new StorageKey + { + ScriptHash = context.ScriptHash, + Key = key + }); + } engine.CurrentContext.EvaluationStack.Push(item?.Value ?? StackItem.Null); return true; } @@ -128,7 +157,17 @@ private static bool Storage_Find(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - byte[] prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); + ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + if (contract == null) return false; + byte[] prefix_key; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) + { + prefix_key = StorageKey.CreateSearchPrefix(contract.RedirectionHash, prefix); + } + else + { + prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, 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; @@ -164,11 +203,25 @@ private static bool Storage_Delete(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (context.IsReadOnly) return false; if (!CheckStorageContext(engine, context)) return false; - StorageKey key = new StorageKey + ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + if (contract == null) return false; + StorageKey key = null; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) { - ScriptHash = context.ScriptHash, - Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() - }; + key = new StorageKey + { + ScriptHash = contract.RedirectionHash, + Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() + }; + } + else + { + key = new StorageKey + { + ScriptHash = context.ScriptHash, + Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() + }; + } if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false; engine.Snapshot.Storages.Delete(key); return true; diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 670f31d757..77070f420e 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -78,13 +78,15 @@ public void TestDeserialize() } ((ContractState)newContract).Manifest.ToJson().ToString().Should().Be(contract.Manifest.ToJson().ToString()); ((ContractState)newContract).Script.Should().BeEquivalentTo(contract.Script); + ((ContractState)newContract).RedirectionHash.Should().BeEquivalentTo(contract.RedirectionHash); + ((ContractState)newContract).IsDeleted.Should().Be(contract.IsDeleted); } [TestMethod] public void TestGetSize() { ISerializable newContract = contract; - newContract.Size.Should().Be(368); + newContract.Size.Should().Be(390); } [TestMethod] @@ -94,6 +96,8 @@ public void TestToJson() json["hash"].AsString().Should().Be("0x820944cfdc70976602d71b0091445eedbc661bc5"); json["script"].AsString().Should().Be("AQ=="); json["manifest"].AsString().Should().Be(manifest.ToJson().AsString()); + json["redirectionHash"].AsString().Should().Be(UInt160.Zero.ToString()); + json["isDeleted"].AsBoolean().Should().Be(false); } } } From fa7305bb2c6e5d7bc2de3d39def101f0c0df0c3a Mon Sep 17 00:00:00 2001 From: doubiliu Date: Tue, 31 Dec 2019 17:34:31 +0800 Subject: [PATCH 03/17] change UT --- tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 959eeecae8..0e746b1e41 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -218,6 +218,7 @@ public void TestContract_Update() Signature = signature } }; + manifest.Features = ContractFeatures.HasStorage; var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract(); state.Manifest.Features = ContractFeatures.HasStorage; @@ -243,8 +244,6 @@ public void TestContract_Update() // 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); From 5c89d4501f5c540bd4a8a4480247bcca3dc0fee3 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 11:39:06 +0800 Subject: [PATCH 04/17] Refactoring --- src/neo/Ledger/ContractState.cs | 2 +- .../SmartContract/InteropService.Contract.cs | 4 +- .../SmartContract/InteropService.Storage.cs | 83 ++++--------------- 3 files changed, 19 insertions(+), 70 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 6ac4ae05b6..f540fe0037 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -31,7 +31,7 @@ public UInt160 ScriptHash } } - int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize() + sizeof(bool) + RedirectionHash.ToArray().GetVarSize(); + int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize() + sizeof(bool) + RedirectionHash.Size; private UInt160 _redirectionHash = UInt160.Zero; public virtual UInt160 RedirectionHash diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 9ca15c905d..3691564ebb 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -168,9 +168,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null) return false; - - if (contract.IsDeleted) return false; + if (contract is null|| contract.IsDeleted) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index d82916bcdc..3cfe15305d 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -29,6 +29,10 @@ private static bool CheckStorageContext(ApplicationEngine engine, StorageContext ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); if (contract == null) return false; if (!contract.HasStorage) return false; + if (!contract.RedirectionHash.Equals(UInt160.Zero)) + { + context.ScriptHash = contract.RedirectionHash; + } return true; } @@ -44,25 +48,11 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte if (context.IsReadOnly) return false; if (!CheckStorageContext(engine, context)) return false; - ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); - if (contract == null) return false; - StorageKey skey; - if (!contract.RedirectionHash.Equals(UInt160.Zero)) + StorageKey skey = new StorageKey { - skey = new StorageKey - { - ScriptHash = contract.RedirectionHash, - Key = key - }; - } - else - { - skey = new StorageKey - { - ScriptHash = context.ScriptHash, - Key = key - }; - } + ScriptHash = context.ScriptHash, + Key = key + }; if (engine.Snapshot.Storages.TryGet(skey)?.IsConstant == true) return false; @@ -124,26 +114,11 @@ private static bool Storage_Get(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - - ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); - if (contract == null) return false; - StorageItem item = null; - if (!contract.RedirectionHash.Equals(UInt160.Zero)) - { - item = engine.Snapshot.Storages.TryGet(new StorageKey - { - ScriptHash = contract.RedirectionHash, - Key = key - }); - } - else + StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey { - item = engine.Snapshot.Storages.TryGet(new StorageKey - { - ScriptHash = context.ScriptHash, - Key = key - }); - } + ScriptHash = context.ScriptHash, + Key = key + }); engine.CurrentContext.EvaluationStack.Push(item?.Value ?? StackItem.Null); return true; } @@ -157,17 +132,7 @@ private static bool Storage_Find(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (!CheckStorageContext(engine, context)) return false; byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); - if (contract == null) return false; - byte[] prefix_key; - if (!contract.RedirectionHash.Equals(UInt160.Zero)) - { - prefix_key = StorageKey.CreateSearchPrefix(contract.RedirectionHash, prefix); - } - else - { - prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); - } + 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.AsSpan().StartsWith(prefix)).GetEnumerator())); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator)); return true; @@ -203,25 +168,11 @@ private static bool Storage_Delete(ApplicationEngine engine) StorageContext context = _interface.GetInterface(); if (context.IsReadOnly) return false; if (!CheckStorageContext(engine, context)) return false; - ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); - if (contract == null) return false; - StorageKey key = null; - if (!contract.RedirectionHash.Equals(UInt160.Zero)) + StorageKey key = new StorageKey { - key = new StorageKey - { - ScriptHash = contract.RedirectionHash, - Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() - }; - } - else - { - key = new StorageKey - { - ScriptHash = context.ScriptHash, - Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() - }; - } + ScriptHash = context.ScriptHash, + Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() + }; if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false; engine.Snapshot.Storages.Delete(key); return true; From 8228c9d8ef800e0680592af69cde99751967fd59 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 14:41:02 +0800 Subject: [PATCH 05/17] little change --- src/neo/Ledger/ContractState.cs | 29 ++----------------- .../SmartContract/InteropService.Contract.cs | 3 -- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index f540fe0037..86cd86a801 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -33,34 +33,9 @@ public UInt160 ScriptHash int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize() + sizeof(bool) + RedirectionHash.Size; - private UInt160 _redirectionHash = UInt160.Zero; - public virtual UInt160 RedirectionHash - { - get - { - return _redirectionHash; - } - - set - { - _redirectionHash = value; - } - } - - private bool isDeleted = false; + public UInt160 RedirectionHash = UInt160.Zero; - public virtual bool IsDeleted - { - get - { - return isDeleted; - } - - set - { - isDeleted = value; - } - } + public bool IsDeleted = false; ContractState ICloneable.Clone() { diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 3691564ebb..6264d9eb47 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -41,9 +41,6 @@ private static bool Contract_Create(ApplicationEngine engine) Script = script, Manifest = ContractManifest.Parse(manifest) }; - contract.RedirectionHash = UInt160.Zero; - contract.IsDeleted = false; - if (!contract.Manifest.IsValid(hash)) return false; engine.Snapshot.Contracts.Add(hash, contract); From 32239b78c6e3c5f2a967d3b767971fa7c3746ea0 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 14:45:17 +0800 Subject: [PATCH 06/17] format --- src/neo/SmartContract/InteropService.Contract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 6264d9eb47..757928fbb8 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -165,7 +165,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null|| contract.IsDeleted) return false; + if (contract is null || contract.IsDeleted) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; From 93b24289c91381f7bd95430399983c9ea8f74f1f Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 14:51:41 +0800 Subject: [PATCH 07/17] Fix UT --- tests/neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 77070f420e..3973b6e71a 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -86,7 +86,7 @@ public void TestDeserialize() public void TestGetSize() { ISerializable newContract = contract; - newContract.Size.Should().Be(390); + newContract.Size.Should().Be(389); } [TestMethod] From bc64b3f81b2cf7759676de4a0983b166bdce7112 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 14:58:54 +0800 Subject: [PATCH 08/17] Fix UT --- src/neo/Ledger/ContractState.cs | 14 +++++++------- src/neo/SmartContract/InteropService.Contract.cs | 8 ++++---- tests/neo.UnitTests/Ledger/UT_ContractState.cs | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 86cd86a801..9827a62b6a 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -35,7 +35,7 @@ public UInt160 ScriptHash public UInt160 RedirectionHash = UInt160.Zero; - public bool IsDeleted = false; + public bool IsUpdated = false; ContractState ICloneable.Clone() { @@ -44,7 +44,7 @@ ContractState ICloneable.Clone() Script = Script, Manifest = Manifest.Clone(), RedirectionHash = RedirectionHash, - IsDeleted = IsDeleted + IsUpdated = IsUpdated }; } @@ -53,7 +53,7 @@ void ISerializable.Deserialize(BinaryReader reader) Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); RedirectionHash = reader.ReadSerializable(); - IsDeleted = reader.ReadBoolean(); + IsUpdated = reader.ReadBoolean(); } void ICloneable.FromReplica(ContractState replica) @@ -61,7 +61,7 @@ void ICloneable.FromReplica(ContractState replica) Script = replica.Script; Manifest = replica.Manifest.Clone(); RedirectionHash = replica.RedirectionHash; - IsDeleted = replica.IsDeleted; + IsUpdated = replica.IsUpdated; } void ISerializable.Serialize(BinaryWriter writer) @@ -69,7 +69,7 @@ void ISerializable.Serialize(BinaryWriter writer) writer.WriteVarBytes(Script); writer.Write(Manifest); writer.Write(RedirectionHash); - writer.Write(IsDeleted); + writer.Write(IsUpdated); } public JObject ToJson() @@ -79,7 +79,7 @@ public JObject ToJson() json["script"] = Convert.ToBase64String(Script); json["manifest"] = Manifest.ToJson(); json["redirectionHash"] = RedirectionHash.ToString(); - json["isDeleted"] = IsDeleted; + json["isUpdated"] = IsUpdated; return json; } @@ -89,7 +89,7 @@ public static ContractState FromJson(JObject json) contractState.Script = Convert.FromBase64String(json["script"].AsString()); contractState.Manifest = ContractManifest.FromJson(json["manifest"]); contractState.RedirectionHash = UInt160.Parse(json["RedirectionHash"].AsString()); - contractState.IsDeleted = json["isDeleted"].AsBoolean(); + contractState.IsUpdated = json["isUpdated"].AsBoolean(); return contractState; } diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 757928fbb8..a9e1b7cef6 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -57,7 +57,7 @@ private static bool Contract_Update(ApplicationEngine engine) var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); if (oldcontract is null) return false; - if (oldcontract.IsDeleted) return false; + if (oldcontract.IsUpdated) return false; ContractState newcontract = null; if (script.Length > 0) { @@ -77,13 +77,13 @@ private static bool Contract_Update(ApplicationEngine engine) { newcontract.RedirectionHash = oldcontract.RedirectionHash; } - newcontract.IsDeleted = false; + newcontract.IsUpdated = false; newcontract.Manifest.Abi.Hash = hash_new; engine.Snapshot.Contracts.Add(hash_new, newcontract); if (oldcontract.RedirectionHash.Equals(UInt160.Zero)) { oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); - oldcontract.IsDeleted = true; + oldcontract.IsUpdated = true; } else { @@ -165,7 +165,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null || contract.IsDeleted) return false; + if (contract is null || contract.IsUpdated) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 3973b6e71a..82d8ac5b0b 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -79,7 +79,7 @@ public void TestDeserialize() ((ContractState)newContract).Manifest.ToJson().ToString().Should().Be(contract.Manifest.ToJson().ToString()); ((ContractState)newContract).Script.Should().BeEquivalentTo(contract.Script); ((ContractState)newContract).RedirectionHash.Should().BeEquivalentTo(contract.RedirectionHash); - ((ContractState)newContract).IsDeleted.Should().Be(contract.IsDeleted); + ((ContractState)newContract).IsUpdated.Should().Be(contract.IsUpdated); } [TestMethod] @@ -97,7 +97,7 @@ public void TestToJson() json["script"].AsString().Should().Be("AQ=="); json["manifest"].AsString().Should().Be(manifest.ToJson().AsString()); json["redirectionHash"].AsString().Should().Be(UInt160.Zero.ToString()); - json["isDeleted"].AsBoolean().Should().Be(false); + json["isUpdated"].AsBoolean().Should().Be(false); } } } From 351d3b4a1f02b5229175c07f53147388439b6e4a Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 16:42:46 +0800 Subject: [PATCH 09/17] little change --- .../SmartContract/InteropService.Contract.cs | 3 +-- .../SmartContract/InteropService.Storage.cs | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index a9e1b7cef6..f506560088 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -56,8 +56,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (manifest.Length > ContractManifest.MaxLength) return false; var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldcontract is null) return false; - if (oldcontract.IsUpdated) return false; + if (oldcontract is null|| oldcontract.IsUpdated) return false; ContractState newcontract = null; if (script.Length > 0) { diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index 3cfe15305d..680cf48ee7 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -24,11 +24,16 @@ public static class Storage public static readonly InteropDescriptor PutEx = Register("System.Storage.PutEx", Storage_PutEx, GetStoragePrice, TriggerType.Application, CallFlags.AllowModifyStates); public static readonly InteropDescriptor Delete = Register("System.Storage.Delete", Storage_Delete, 0_01000000, TriggerType.Application, CallFlags.AllowModifyStates); - private static bool CheckStorageContext(ApplicationEngine engine, StorageContext context) + private static bool CheckStorageContext(ApplicationEngine engine, StorageContext context, out ContractState contract) { - ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); if (contract == null) return false; if (!contract.HasStorage) return false; + return true; + } + + private static bool RedirectionStorageContext(StorageContext context, ContractState contract) + { if (!contract.RedirectionHash.Equals(UInt160.Zero)) { context.ScriptHash = contract.RedirectionHash; @@ -46,8 +51,8 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte if (key.Length > MaxKeySize) return false; if (value.Length > MaxValueSize) return false; if (context.IsReadOnly) return false; - if (!CheckStorageContext(engine, context)) return false; - + if (!CheckStorageContext(engine, context,out ContractState contract)) return false; + RedirectionStorageContext(context,contract); StorageKey skey = new StorageKey { ScriptHash = context.ScriptHash, @@ -112,7 +117,8 @@ private static bool Storage_Get(ApplicationEngine engine) if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { StorageContext context = _interface.GetInterface(); - if (!CheckStorageContext(engine, context)) return false; + if (!CheckStorageContext(engine, context,out ContractState contract)) return false; + RedirectionStorageContext(context, contract); byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey { @@ -130,7 +136,8 @@ private static bool Storage_Find(ApplicationEngine engine) if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { StorageContext context = _interface.GetInterface(); - if (!CheckStorageContext(engine, context)) return false; + if (!CheckStorageContext(engine, context, out ContractState contract)) return false; + RedirectionStorageContext(context, contract); byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().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.AsSpan().StartsWith(prefix)).GetEnumerator())); @@ -167,7 +174,8 @@ private static bool Storage_Delete(ApplicationEngine engine) { StorageContext context = _interface.GetInterface(); if (context.IsReadOnly) return false; - if (!CheckStorageContext(engine, context)) return false; + if (!CheckStorageContext(engine, context, out ContractState contract)) return false; + RedirectionStorageContext(context, contract); StorageKey key = new StorageKey { ScriptHash = context.ScriptHash, From 8a658bfdb51824e00d71b7df94b7df48e9c23d2a Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 16:51:52 +0800 Subject: [PATCH 10/17] Fix format --- src/neo/SmartContract/InteropService.Storage.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index 680cf48ee7..230662f26e 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -51,8 +51,8 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte if (key.Length > MaxKeySize) return false; if (value.Length > MaxValueSize) return false; if (context.IsReadOnly) return false; - if (!CheckStorageContext(engine, context,out ContractState contract)) return false; - RedirectionStorageContext(context,contract); + if (!CheckStorageContext(engine, context, out ContractState contract)) return false; + RedirectionStorageContext(context, contract); StorageKey skey = new StorageKey { ScriptHash = context.ScriptHash, @@ -117,7 +117,7 @@ private static bool Storage_Get(ApplicationEngine engine) if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { StorageContext context = _interface.GetInterface(); - if (!CheckStorageContext(engine, context,out ContractState contract)) return false; + if (!CheckStorageContext(engine, context, out ContractState contract)) return false; RedirectionStorageContext(context, contract); byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey From 1421fc413b1c31149915bceecb0406dc9c653443 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 16:58:43 +0800 Subject: [PATCH 11/17] Fix format --- src/neo/SmartContract/InteropService.Contract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index f506560088..8f145cd767 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -56,7 +56,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (manifest.Length > ContractManifest.MaxLength) return false; var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldcontract is null|| oldcontract.IsUpdated) return false; + if (oldcontract is null || oldcontract.IsUpdated) return false; ContractState newcontract = null; if (script.Length > 0) { From cb1bb228ec57c2046e6f4f742431b219fef2a2c1 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Thu, 2 Jan 2020 17:12:44 +0800 Subject: [PATCH 12/17] small change --- src/neo/SmartContract/InteropService.Storage.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index 230662f26e..ca157027ca 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -32,13 +32,12 @@ private static bool CheckStorageContext(ApplicationEngine engine, StorageContext return true; } - private static bool RedirectionStorageContext(StorageContext context, ContractState contract) + private static void RedirectionStorageContext(StorageContext context, ContractState contract) { if (!contract.RedirectionHash.Equals(UInt160.Zero)) { context.ScriptHash = contract.RedirectionHash; } - return true; } private static long GetStoragePrice(EvaluationStack stack) From 5606dcc9a83b95b1c98a56430e190524b0ab3d4c Mon Sep 17 00:00:00 2001 From: doubiliu Date: Fri, 3 Jan 2020 11:05:04 +0800 Subject: [PATCH 13/17] Remove duplicate code --- src/neo/Ledger/ContractState.cs | 2 + .../SmartContract/InteropService.Contract.cs | 43 ++++++------------- .../SmartContract/InteropService.Storage.cs | 2 +- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 9827a62b6a..c0cafbc110 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -35,6 +35,8 @@ public UInt160 ScriptHash public UInt160 RedirectionHash = UInt160.Zero; + public bool HasRedirection => !RedirectionHash.Equals(UInt160.Zero); + public bool IsUpdated = false; ContractState ICloneable.Clone() diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 8f145cd767..d7344fb1bd 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -68,26 +68,19 @@ private static bool Contract_Update(ApplicationEngine engine) Script = script, Manifest = oldcontract.Manifest }; - if (oldcontract.RedirectionHash.Equals(UInt160.Zero)) - { - newcontract.RedirectionHash = oldcontract.ScriptHash; - } - else + if (oldcontract.HasRedirection) { newcontract.RedirectionHash = oldcontract.RedirectionHash; + DeleteContractByHash(engine, oldcontract.ScriptHash, out _); } - newcontract.IsUpdated = false; - newcontract.Manifest.Abi.Hash = hash_new; - engine.Snapshot.Contracts.Add(hash_new, newcontract); - if (oldcontract.RedirectionHash.Equals(UInt160.Zero)) + else { + newcontract.RedirectionHash = oldcontract.ScriptHash; oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); oldcontract.IsUpdated = true; } - else - { - Contract_UnAppend_Destroy(engine); - } + newcontract.Manifest.Abi.Hash = hash_new; + engine.Snapshot.Contracts.Add(hash_new, newcontract); } if (manifest.Length > 0) { @@ -103,30 +96,20 @@ private static bool Contract_Update(ApplicationEngine engine) private static bool Contract_Destroy(ApplicationEngine engine) { UInt160 hash = engine.CurrentScriptHash; - ContractState contract = engine.Snapshot.Contracts.TryGet(hash); - if (contract == null) return true; - if (!contract.RedirectionHash.Equals(UInt160.Zero)) + if (DeleteContractByHash(engine, hash, out ContractState contract)) { - ContractState initcontract = engine.Snapshot.Contracts.TryGet(contract.RedirectionHash); - if (initcontract != null) + if (contract != null && contract.HasRedirection) { - engine.Snapshot.Contracts.Delete(contract.RedirectionHash); - if (initcontract.HasStorage) - foreach (var (key, _) in engine.Snapshot.Storages.Find(contract.RedirectionHash.ToArray())) - engine.Snapshot.Storages.Delete(key); + DeleteContractByHash(engine, contract.RedirectionHash, out _); } + return true; } - engine.Snapshot.Contracts.Delete(hash); - if (contract.HasStorage) - foreach (var (key, _) in engine.Snapshot.Storages.Find(hash.ToArray())) - engine.Snapshot.Storages.Delete(key); - return true; + return false; } - private static bool Contract_UnAppend_Destroy(ApplicationEngine engine) + private static bool DeleteContractByHash(ApplicationEngine engine, UInt160 hash, out ContractState contract) { - UInt160 hash = engine.CurrentScriptHash; - ContractState contract = engine.Snapshot.Contracts.TryGet(hash); + contract = engine.Snapshot.Contracts.TryGet(hash); if (contract == null) return true; engine.Snapshot.Contracts.Delete(hash); if (contract.HasStorage) diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index ca157027ca..f7e967071b 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -34,7 +34,7 @@ private static bool CheckStorageContext(ApplicationEngine engine, StorageContext private static void RedirectionStorageContext(StorageContext context, ContractState contract) { - if (!contract.RedirectionHash.Equals(UInt160.Zero)) + if (contract.HasRedirection) { context.ScriptHash = contract.RedirectionHash; } From 87fd0fd703b1687bb3f76f5882a0c7021c45cfe9 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Fri, 3 Jan 2020 15:30:04 +0800 Subject: [PATCH 14/17] Refactoring --- src/neo/Ledger/ContractState.cs | 16 +++---- .../SmartContract/InteropService.Contract.cs | 6 +-- .../SmartContract/InteropService.Storage.cs | 45 +++++++++---------- src/neo/SmartContract/StorageContext.cs | 1 + .../neo.UnitTests/Ledger/UT_ContractState.cs | 4 +- .../SmartContract/UT_InteropService.NEO.cs | 3 +- .../SmartContract/UT_InteropService.cs | 30 +++++++++---- 7 files changed, 58 insertions(+), 47 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index c0cafbc110..a0ae8a6a0d 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -37,7 +37,7 @@ public UInt160 ScriptHash public bool HasRedirection => !RedirectionHash.Equals(UInt160.Zero); - public bool IsUpdated = false; + public bool IsUpgraded = false; ContractState ICloneable.Clone() { @@ -46,7 +46,7 @@ ContractState ICloneable.Clone() Script = Script, Manifest = Manifest.Clone(), RedirectionHash = RedirectionHash, - IsUpdated = IsUpdated + IsUpgraded = IsUpgraded }; } @@ -55,7 +55,7 @@ void ISerializable.Deserialize(BinaryReader reader) Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); RedirectionHash = reader.ReadSerializable(); - IsUpdated = reader.ReadBoolean(); + IsUpgraded = reader.ReadBoolean(); } void ICloneable.FromReplica(ContractState replica) @@ -63,7 +63,7 @@ void ICloneable.FromReplica(ContractState replica) Script = replica.Script; Manifest = replica.Manifest.Clone(); RedirectionHash = replica.RedirectionHash; - IsUpdated = replica.IsUpdated; + IsUpgraded = replica.IsUpgraded; } void ISerializable.Serialize(BinaryWriter writer) @@ -71,7 +71,7 @@ void ISerializable.Serialize(BinaryWriter writer) writer.WriteVarBytes(Script); writer.Write(Manifest); writer.Write(RedirectionHash); - writer.Write(IsUpdated); + writer.Write(IsUpgraded); } public JObject ToJson() @@ -81,7 +81,7 @@ public JObject ToJson() json["script"] = Convert.ToBase64String(Script); json["manifest"] = Manifest.ToJson(); json["redirectionHash"] = RedirectionHash.ToString(); - json["isUpdated"] = IsUpdated; + json["isUpgraded"] = IsUpgraded; return json; } @@ -90,8 +90,8 @@ public static ContractState FromJson(JObject json) ContractState contractState = new ContractState(); contractState.Script = Convert.FromBase64String(json["script"].AsString()); contractState.Manifest = ContractManifest.FromJson(json["manifest"]); - contractState.RedirectionHash = UInt160.Parse(json["RedirectionHash"].AsString()); - contractState.IsUpdated = json["isUpdated"].AsBoolean(); + contractState.RedirectionHash = UInt160.Parse(json["redirectionHash"].AsString()); + contractState.IsUpgraded = json["isUpgraded"].AsBoolean(); return contractState; } diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index d7344fb1bd..3638db4489 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -56,7 +56,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (manifest.Length > ContractManifest.MaxLength) return false; var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldcontract is null || oldcontract.IsUpdated) return false; + if (oldcontract is null || oldcontract.IsUpgraded) return false; ContractState newcontract = null; if (script.Length > 0) { @@ -77,7 +77,7 @@ private static bool Contract_Update(ApplicationEngine engine) { newcontract.RedirectionHash = oldcontract.ScriptHash; oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); - oldcontract.IsUpdated = true; + oldcontract.IsUpgraded = true; } newcontract.Manifest.Abi.Hash = hash_new; engine.Snapshot.Contracts.Add(hash_new, newcontract); @@ -147,7 +147,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null || contract.IsUpdated) return false; + if (contract is null || contract.IsUpgraded) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index f7e967071b..3ef64d5eab 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -24,22 +24,14 @@ public static class Storage public static readonly InteropDescriptor PutEx = Register("System.Storage.PutEx", Storage_PutEx, GetStoragePrice, TriggerType.Application, CallFlags.AllowModifyStates); public static readonly InteropDescriptor Delete = Register("System.Storage.Delete", Storage_Delete, 0_01000000, TriggerType.Application, CallFlags.AllowModifyStates); - private static bool CheckStorageContext(ApplicationEngine engine, StorageContext context, out ContractState contract) + private static bool CheckStorageContext(ApplicationEngine engine, StorageContext context) { - contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); + ContractState contract = engine.Snapshot.Contracts.TryGet(context.ScriptHash); if (contract == null) return false; if (!contract.HasStorage) return false; return true; } - private static void RedirectionStorageContext(StorageContext context, ContractState contract) - { - if (contract.HasRedirection) - { - context.ScriptHash = contract.RedirectionHash; - } - } - private static long GetStoragePrice(EvaluationStack stack) { return (stack.Peek(1).GetByteLength() + stack.Peek(2).GetByteLength()) * GasPerByte; @@ -50,11 +42,10 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte if (key.Length > MaxKeySize) return false; if (value.Length > MaxValueSize) return false; if (context.IsReadOnly) return false; - if (!CheckStorageContext(engine, context, out ContractState contract)) return false; - RedirectionStorageContext(context, contract); + if (!CheckStorageContext(engine, context)) return false; StorageKey skey = new StorageKey { - ScriptHash = context.ScriptHash, + ScriptHash = context.PreDataKey, Key = key }; @@ -76,20 +67,26 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte private static bool Storage_GetContext(ApplicationEngine engine) { + ContractState contract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); + if (contract == null) return false; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext { ScriptHash = engine.CurrentScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = contract.HasRedirection ? contract.RedirectionHash : engine.CurrentScriptHash })); return true; } private static bool Storage_GetReadOnlyContext(ApplicationEngine engine) { + ContractState contract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); + if (contract == null) return false; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext { ScriptHash = engine.CurrentScriptHash, - IsReadOnly = true + IsReadOnly = true, + PreDataKey = contract.HasRedirection ? contract.RedirectionHash : engine.CurrentScriptHash })); return true; } @@ -103,7 +100,8 @@ private static bool Storage_AsReadOnly(ApplicationEngine engine) context = new StorageContext { ScriptHash = context.ScriptHash, - IsReadOnly = true + IsReadOnly = true, + PreDataKey = context.PreDataKey }; engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(context)); return true; @@ -116,12 +114,11 @@ private static bool Storage_Get(ApplicationEngine engine) if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { StorageContext context = _interface.GetInterface(); - if (!CheckStorageContext(engine, context, out ContractState contract)) return false; - RedirectionStorageContext(context, contract); + if (!CheckStorageContext(engine, context)) return false; byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey { - ScriptHash = context.ScriptHash, + ScriptHash = context.PreDataKey, Key = key }); engine.CurrentContext.EvaluationStack.Push(item?.Value ?? StackItem.Null); @@ -135,10 +132,9 @@ private static bool Storage_Find(ApplicationEngine engine) if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { StorageContext context = _interface.GetInterface(); - if (!CheckStorageContext(engine, context, out ContractState contract)) return false; - RedirectionStorageContext(context, contract); + if (!CheckStorageContext(engine, context)) return false; byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); - byte[] prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); + byte[] prefix_key = StorageKey.CreateSearchPrefix(context.PreDataKey, 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; @@ -173,11 +169,10 @@ private static bool Storage_Delete(ApplicationEngine engine) { StorageContext context = _interface.GetInterface(); if (context.IsReadOnly) return false; - if (!CheckStorageContext(engine, context, out ContractState contract)) return false; - RedirectionStorageContext(context, contract); + if (!CheckStorageContext(engine, context)) return false; StorageKey key = new StorageKey { - ScriptHash = context.ScriptHash, + ScriptHash = context.PreDataKey, Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray() }; if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false; diff --git a/src/neo/SmartContract/StorageContext.cs b/src/neo/SmartContract/StorageContext.cs index 9937caa4f8..7cac98295c 100644 --- a/src/neo/SmartContract/StorageContext.cs +++ b/src/neo/SmartContract/StorageContext.cs @@ -4,5 +4,6 @@ internal class StorageContext { public UInt160 ScriptHash; public bool IsReadOnly; + public UInt160 PreDataKey; } } diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 82d8ac5b0b..9edf588d26 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -79,7 +79,7 @@ public void TestDeserialize() ((ContractState)newContract).Manifest.ToJson().ToString().Should().Be(contract.Manifest.ToJson().ToString()); ((ContractState)newContract).Script.Should().BeEquivalentTo(contract.Script); ((ContractState)newContract).RedirectionHash.Should().BeEquivalentTo(contract.RedirectionHash); - ((ContractState)newContract).IsUpdated.Should().Be(contract.IsUpdated); + ((ContractState)newContract).IsUpgraded.Should().Be(contract.IsUpgraded); } [TestMethod] @@ -97,7 +97,7 @@ public void TestToJson() json["script"].AsString().Should().Be("AQ=="); json["manifest"].AsString().Should().Be(manifest.ToJson().AsString()); json["redirectionHash"].AsString().Should().Be(UInt160.Zero.ToString()); - json["isUpdated"].AsBoolean().Should().Be(false); + json["isUpgraded"].AsBoolean().Should().Be(false); } } } diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 0e746b1e41..907d05f85c 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -278,7 +278,8 @@ public void TestStorage_Find() engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash })); InteropService.Invoke(engine, InteropService.Storage.Find).Should().BeTrue(); var iterator = ((InteropInterface)engine.CurrentContext.EvaluationStack.Pop()).GetInterface(); diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 1fa676af60..c3db310214 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -480,7 +480,11 @@ public void TestBlockchain_GetContract() [TestMethod] public void TestStorage_GetContext() { - var engine = GetEngine(); + var snapshot = Blockchain.Singleton.GetSnapshot(); + var state = TestUtils.GetContract(); + snapshot.Contracts.Add(state.ScriptHash, state); + var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); + 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); @@ -490,7 +494,11 @@ public void TestStorage_GetContext() [TestMethod] public void TestStorage_GetReadOnlyContext() { - var engine = GetEngine(); + var snapshot = Blockchain.Singleton.GetSnapshot(); + var state = TestUtils.GetContract(); + snapshot.Contracts.Add(state.ScriptHash, state); + var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); + 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); @@ -524,7 +532,8 @@ public void TestStorage_Get() engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash })); InteropService.Invoke(engine, InteropService.Storage.Get).Should().BeTrue(); engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString()); @@ -536,7 +545,8 @@ public void TestStorage_Get() engine.CurrentContext.EvaluationStack.Push(new InteropInterface(new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash })); InteropService.Invoke(engine, InteropService.Storage.Get).Should().BeFalse(); @@ -560,7 +570,8 @@ public void TestStorage_Put() var storageContext = new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash }; engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); InteropService.Invoke(engine, InteropService.Storage.Put).Should().BeFalse(); @@ -661,7 +672,8 @@ public void TestStorage_PutEx() var storageContext = new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash }; engine.CurrentContext.EvaluationStack.Push((int)StorageFlags.None); engine.CurrentContext.EvaluationStack.Push(value); @@ -700,7 +712,8 @@ public void TestStorage_Delete() var storageContext = new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash }; engine.CurrentContext.EvaluationStack.Push(key); engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); @@ -731,7 +744,8 @@ public void TestStorageContext_AsReadOnly() var storageContext = new StorageContext { ScriptHash = state.ScriptHash, - IsReadOnly = false + IsReadOnly = false, + PreDataKey = state.ScriptHash }; engine.CurrentContext.EvaluationStack.Push(new InteropInterface(storageContext)); InteropService.Invoke(engine, InteropService.Storage.AsReadOnly).Should().BeTrue(); From eaba8befbc7d721a0eaaaccc078e6ca901e1269f Mon Sep 17 00:00:00 2001 From: doubiliu Date: Mon, 6 Jan 2020 13:34:56 +0800 Subject: [PATCH 15/17] Add a test case --- src/neo/Ledger/ContractState.cs | 14 +++++----- .../SmartContract/InteropService.Contract.cs | 6 ++--- .../neo.UnitTests/Ledger/UT_ContractState.cs | 4 +-- .../SmartContract/UT_InteropService.NEO.cs | 27 +++++++++++++++++++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index a0ae8a6a0d..86735308bd 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -37,7 +37,7 @@ public UInt160 ScriptHash public bool HasRedirection => !RedirectionHash.Equals(UInt160.Zero); - public bool IsUpgraded = false; + public bool HasUpgraded = false; ContractState ICloneable.Clone() { @@ -46,7 +46,7 @@ ContractState ICloneable.Clone() Script = Script, Manifest = Manifest.Clone(), RedirectionHash = RedirectionHash, - IsUpgraded = IsUpgraded + HasUpgraded = HasUpgraded }; } @@ -55,7 +55,7 @@ void ISerializable.Deserialize(BinaryReader reader) Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); RedirectionHash = reader.ReadSerializable(); - IsUpgraded = reader.ReadBoolean(); + HasUpgraded = reader.ReadBoolean(); } void ICloneable.FromReplica(ContractState replica) @@ -63,7 +63,7 @@ void ICloneable.FromReplica(ContractState replica) Script = replica.Script; Manifest = replica.Manifest.Clone(); RedirectionHash = replica.RedirectionHash; - IsUpgraded = replica.IsUpgraded; + HasUpgraded = replica.HasUpgraded; } void ISerializable.Serialize(BinaryWriter writer) @@ -71,7 +71,7 @@ void ISerializable.Serialize(BinaryWriter writer) writer.WriteVarBytes(Script); writer.Write(Manifest); writer.Write(RedirectionHash); - writer.Write(IsUpgraded); + writer.Write(HasUpgraded); } public JObject ToJson() @@ -81,7 +81,7 @@ public JObject ToJson() json["script"] = Convert.ToBase64String(Script); json["manifest"] = Manifest.ToJson(); json["redirectionHash"] = RedirectionHash.ToString(); - json["isUpgraded"] = IsUpgraded; + json["hasUpgraded"] = HasUpgraded; return json; } @@ -91,7 +91,7 @@ public static ContractState FromJson(JObject json) contractState.Script = Convert.FromBase64String(json["script"].AsString()); contractState.Manifest = ContractManifest.FromJson(json["manifest"]); contractState.RedirectionHash = UInt160.Parse(json["redirectionHash"].AsString()); - contractState.IsUpgraded = json["isUpgraded"].AsBoolean(); + contractState.HasUpgraded = json["hasUpgraded"].AsBoolean(); return contractState; } diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index 3638db4489..bd0a6caaa6 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -56,7 +56,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (manifest.Length > ContractManifest.MaxLength) return false; var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldcontract is null || oldcontract.IsUpgraded) return false; + if (oldcontract is null || oldcontract.HasUpgraded) return false; ContractState newcontract = null; if (script.Length > 0) { @@ -77,7 +77,7 @@ private static bool Contract_Update(ApplicationEngine engine) { newcontract.RedirectionHash = oldcontract.ScriptHash; oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); - oldcontract.IsUpgraded = true; + oldcontract.HasUpgraded = true; } newcontract.Manifest.Abi.Hash = hash_new; engine.Snapshot.Contracts.Add(hash_new, newcontract); @@ -147,7 +147,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null || contract.IsUpgraded) return false; + if (contract is null || contract.HasUpgraded) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 9edf588d26..dc74d7bed5 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -79,7 +79,7 @@ public void TestDeserialize() ((ContractState)newContract).Manifest.ToJson().ToString().Should().Be(contract.Manifest.ToJson().ToString()); ((ContractState)newContract).Script.Should().BeEquivalentTo(contract.Script); ((ContractState)newContract).RedirectionHash.Should().BeEquivalentTo(contract.RedirectionHash); - ((ContractState)newContract).IsUpgraded.Should().Be(contract.IsUpgraded); + ((ContractState)newContract).HasUpgraded.Should().Be(contract.HasUpgraded); } [TestMethod] @@ -97,7 +97,7 @@ public void TestToJson() json["script"].AsString().Should().Be("AQ=="); json["manifest"].AsString().Should().Be(manifest.ToJson().AsString()); json["redirectionHash"].AsString().Should().Be(UInt160.Zero.ToString()); - json["isUpgraded"].AsBoolean().Should().Be(false); + json["hasUpgraded"].AsBoolean().Should().Be(false); } } } diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 907d05f85c..a523290a55 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -250,6 +250,33 @@ public void TestContract_Update() engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Contract.Update).Should().BeFalse(); + + //Secondary upgrade + byte[] newContract = new byte[script.Length]; + System.Array.Copy(script, newContract, script.Length); + newContract[newContract.Length - 1] = 0x03; + + var manifest2 = ContractManifest.CreateDefault(newContract.ToScriptHash()); + byte[] privkey2 = { 0x01,0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; + KeyPair key2 = new KeyPair(privkey2); + ECPoint pubkey2 = key2.PublicKey; + byte[] signature2 = Crypto.Sign(newContract.ToScriptHash().ToArray(), privkey2, pubkey2.EncodePoint(false).Skip(1).ToArray()); + manifest2.Groups = new ContractGroup[] + { + new ContractGroup() + { + PubKey = pubkey2, + Signature = signature2 + } + }; + manifest2.Features = ContractFeatures.HasStorage; + + engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); + engine.LoadScript(script); + engine.CurrentContext.EvaluationStack.Push(manifest2.ToString()); + engine.CurrentContext.EvaluationStack.Push(newContract); + InteropService.Invoke(engine, InteropService.Contract.Update).Should().BeTrue(); } [TestMethod] From 0224e697ea48c38a821028b671d12ff39692fc4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Naz=C3=A1rio=20Coelho?= Date: Mon, 6 Jan 2020 17:32:35 -0300 Subject: [PATCH 16/17] variable renaming --- .../SmartContract/InteropService.Contract.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index bd0a6caaa6..ffb2a47f03 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -55,8 +55,8 @@ private static bool Contract_Update(ApplicationEngine engine) var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString(); if (manifest.Length > ContractManifest.MaxLength) return false; - var oldcontract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldcontract is null || oldcontract.HasUpgraded) return false; + var oldContract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); + if (oldContract is null || oldContract.HasUpgraded) return false; ContractState newcontract = null; if (script.Length > 0) { @@ -66,18 +66,18 @@ private static bool Contract_Update(ApplicationEngine engine) newcontract = new ContractState { Script = script, - Manifest = oldcontract.Manifest + Manifest = oldContract.Manifest }; - if (oldcontract.HasRedirection) + if (oldContract.HasRedirection) { - newcontract.RedirectionHash = oldcontract.RedirectionHash; - DeleteContractByHash(engine, oldcontract.ScriptHash, out _); + newcontract.RedirectionHash = oldContract.RedirectionHash; + DeleteContractByHash(engine, oldContract.ScriptHash, out _); } else { - newcontract.RedirectionHash = oldcontract.ScriptHash; - oldcontract = engine.Snapshot.Contracts.GetAndChange(oldcontract.ScriptHash); - oldcontract.HasUpgraded = true; + newcontract.RedirectionHash = oldContract.ScriptHash; + oldContract = engine.Snapshot.Contracts.GetAndChange(oldContract.ScriptHash); + oldContract.HasUpgraded = true; } newcontract.Manifest.Abi.Hash = hash_new; engine.Snapshot.Contracts.Add(hash_new, newcontract); From e5ce3bc18235183286412a13f10d603a085f246d Mon Sep 17 00:00:00 2001 From: doubiliu Date: Tue, 7 Jan 2020 10:40:36 +0800 Subject: [PATCH 17/17] variable renaming --- src/neo/Ledger/ContractState.cs | 14 +++++++------- src/neo/SmartContract/InteropService.Contract.cs | 6 +++--- tests/neo.UnitTests/Ledger/UT_ContractState.cs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 86735308bd..9ab50be79b 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -37,7 +37,7 @@ public UInt160 ScriptHash public bool HasRedirection => !RedirectionHash.Equals(UInt160.Zero); - public bool HasUpgraded = false; + public bool WasUpgraded = false; ContractState ICloneable.Clone() { @@ -46,7 +46,7 @@ ContractState ICloneable.Clone() Script = Script, Manifest = Manifest.Clone(), RedirectionHash = RedirectionHash, - HasUpgraded = HasUpgraded + WasUpgraded = WasUpgraded }; } @@ -55,7 +55,7 @@ void ISerializable.Deserialize(BinaryReader reader) Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable(); RedirectionHash = reader.ReadSerializable(); - HasUpgraded = reader.ReadBoolean(); + WasUpgraded = reader.ReadBoolean(); } void ICloneable.FromReplica(ContractState replica) @@ -63,7 +63,7 @@ void ICloneable.FromReplica(ContractState replica) Script = replica.Script; Manifest = replica.Manifest.Clone(); RedirectionHash = replica.RedirectionHash; - HasUpgraded = replica.HasUpgraded; + WasUpgraded = replica.WasUpgraded; } void ISerializable.Serialize(BinaryWriter writer) @@ -71,7 +71,7 @@ void ISerializable.Serialize(BinaryWriter writer) writer.WriteVarBytes(Script); writer.Write(Manifest); writer.Write(RedirectionHash); - writer.Write(HasUpgraded); + writer.Write(WasUpgraded); } public JObject ToJson() @@ -81,7 +81,7 @@ public JObject ToJson() json["script"] = Convert.ToBase64String(Script); json["manifest"] = Manifest.ToJson(); json["redirectionHash"] = RedirectionHash.ToString(); - json["hasUpgraded"] = HasUpgraded; + json["wasUpgraded"] = WasUpgraded; return json; } @@ -91,7 +91,7 @@ public static ContractState FromJson(JObject json) contractState.Script = Convert.FromBase64String(json["script"].AsString()); contractState.Manifest = ContractManifest.FromJson(json["manifest"]); contractState.RedirectionHash = UInt160.Parse(json["redirectionHash"].AsString()); - contractState.HasUpgraded = json["hasUpgraded"].AsBoolean(); + contractState.WasUpgraded = json["wasUpgraded"].AsBoolean(); return contractState; } diff --git a/src/neo/SmartContract/InteropService.Contract.cs b/src/neo/SmartContract/InteropService.Contract.cs index ffb2a47f03..133fadf7ea 100644 --- a/src/neo/SmartContract/InteropService.Contract.cs +++ b/src/neo/SmartContract/InteropService.Contract.cs @@ -56,7 +56,7 @@ private static bool Contract_Update(ApplicationEngine engine) if (manifest.Length > ContractManifest.MaxLength) return false; var oldContract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash); - if (oldContract is null || oldContract.HasUpgraded) return false; + if (oldContract is null || oldContract.WasUpgraded) return false; ContractState newcontract = null; if (script.Length > 0) { @@ -77,7 +77,7 @@ private static bool Contract_Update(ApplicationEngine engine) { newcontract.RedirectionHash = oldContract.ScriptHash; oldContract = engine.Snapshot.Contracts.GetAndChange(oldContract.ScriptHash); - oldContract.HasUpgraded = true; + oldContract.WasUpgraded = true; } newcontract.Manifest.Abi.Hash = hash_new; engine.Snapshot.Contracts.Add(hash_new, newcontract); @@ -147,7 +147,7 @@ private static bool Contract_CallEx(ApplicationEngine engine) private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, StackItem method, StackItem args, CallFlags flags) { ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash); - if (contract is null || contract.HasUpgraded) return false; + if (contract is null || contract.WasUpgraded) return false; ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index dc74d7bed5..1f8ca2b451 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -79,7 +79,7 @@ public void TestDeserialize() ((ContractState)newContract).Manifest.ToJson().ToString().Should().Be(contract.Manifest.ToJson().ToString()); ((ContractState)newContract).Script.Should().BeEquivalentTo(contract.Script); ((ContractState)newContract).RedirectionHash.Should().BeEquivalentTo(contract.RedirectionHash); - ((ContractState)newContract).HasUpgraded.Should().Be(contract.HasUpgraded); + ((ContractState)newContract).WasUpgraded.Should().Be(contract.WasUpgraded); } [TestMethod] @@ -97,7 +97,7 @@ public void TestToJson() json["script"].AsString().Should().Be("AQ=="); json["manifest"].AsString().Should().Be(manifest.ToJson().AsString()); json["redirectionHash"].AsString().Should().Be(UInt160.Zero.ToString()); - json["hasUpgraded"].AsBoolean().Should().Be(false); + json["wasUpgraded"].AsBoolean().Should().Be(false); } } }