From eb8f03d70b112c2e42dfb439316c967e6858d8ec Mon Sep 17 00:00:00 2001 From: erikzhang Date: Thu, 11 Jun 2020 15:38:38 +0800 Subject: [PATCH 1/4] Check the parameters count --- src/neo/SmartContract/ApplicationEngine.Contract.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index 31407a596c..ed2557f356 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -139,6 +139,7 @@ private void CallContractInternal(UInt160 contractHash, string method, Array arg ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method); if (md is null) throw new InvalidOperationException(); + if (args.Count != md.Parameters.Length) throw new InvalidOperationException(); int rvcount = md.ReturnType == ContractParameterType.Void ? 0 : 1; ExecutionContext context_new = LoadScript(contract.Script, rvcount); state = context_new.GetState(); From 26f5c41cd13722f718a692a8e7df1fe5fef967ea Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 11 Jun 2020 10:27:33 +0200 Subject: [PATCH 2/4] Fix UT --- .../SmartContract/UT_InteropService.cs | 24 +++++++++++++++---- .../SmartContract/UT_Syscalls.cs | 8 +++++++ tests/neo.UnitTests/TestUtils.cs | 8 +++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 399f063ec7..20df416778 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -52,11 +52,17 @@ public void Runtime_GetNotifications_Test() scriptHash2 = script.ToArray().ToScriptHash(); snapshot.Contracts.Delete(scriptHash2); - snapshot.Contracts.Add(scriptHash2, new ContractState() + var state = new ContractState() { Script = script.ToArray(), Manifest = TestUtils.CreateDefaultManifest(scriptHash2, "test"), - }); + }; + state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] + { + new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, + new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} + }; + snapshot.Contracts.Add(scriptHash2, state); } // Wrong length @@ -217,8 +223,6 @@ public void TestExecutionEngine_GetCallingScriptHash() // Test real using ScriptBuilder scriptA = new ScriptBuilder(); - scriptA.Emit(OpCode.DROP); // Drop arguments - scriptA.Emit(OpCode.DROP); // Drop method scriptA.EmitSysCall(ApplicationEngine.System_Runtime_GetCallingScriptHash); var contract = new ContractState() @@ -230,7 +234,7 @@ public void TestExecutionEngine_GetCallingScriptHash() engine.Snapshot.Contracts.Add(contract.ScriptHash, contract); using ScriptBuilder scriptB = new ScriptBuilder(); - scriptB.EmitAppCall(contract.ScriptHash, "test", 0, 1); + scriptB.EmitAppCall(contract.ScriptHash, "test"); engine.LoadScript(scriptB.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -601,6 +605,11 @@ public void TestContract_Call() { var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract("method"); + state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] + { + new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, + new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} + }; state.Manifest.Features = ContractFeatures.HasStorage; string method = "method"; var args = new VM.Types.Array { 0, 1 }; @@ -628,6 +637,11 @@ public void TestContract_CallEx() var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract("method"); + state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] + { + new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, + new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} + }; state.Manifest.Features = ContractFeatures.HasStorage; snapshot.Contracts.Add(state.ScriptHash, state); diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 848079aef3..1590682742 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -345,6 +345,14 @@ public void System_Runtime_GetInvocationCounter() contracts.Add(contractA.ScriptHash, contractA); contracts.Add(contractB.ScriptHash, contractB); contracts.Add(contractC.ScriptHash, contractC); + + contractA.Manifest.Abi.Methods[0].Parameters = + contractB.Manifest.Abi.Methods[0].Parameters = + contractC.Manifest.Abi.Methods[0].Parameters = new Neo.SmartContract.Manifest.ContractParameterDefinition[] + { + new Neo.SmartContract.Manifest.ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, + new Neo.SmartContract.Manifest.ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} + }; } // Call A,B,B,C diff --git a/tests/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs index fd8e6fd620..c621bb6747 100644 --- a/tests/neo.UnitTests/TestUtils.cs +++ b/tests/neo.UnitTests/TestUtils.cs @@ -25,19 +25,19 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash, string method Abi = new ContractAbi() { Hash = hash, - Events = new ContractEventDescriptor[0], - Methods = method == null ? new ContractMethodDescriptor[0] : new ContractMethodDescriptor[] + Events = Array.Empty(), + Methods = method == null ? Array.Empty() : new ContractMethodDescriptor[] { new ContractMethodDescriptor() { Name = method, - Parameters = new ContractParameterDefinition[0], + Parameters = Array.Empty(), ReturnType = ContractParameterType.Integer } } }, Features = ContractFeatures.NoProperty, - Groups = new ContractGroup[0], + Groups = Array.Empty(), SafeMethods = WildcardContainer.Create(), Trusts = WildcardContainer.Create(), Extra = null, From 4755e40cfaa1da32d8fd65631f3ce73ccd4b92bd Mon Sep 17 00:00:00 2001 From: erikzhang Date: Thu, 11 Jun 2020 16:34:26 +0800 Subject: [PATCH 3/4] Revert "Fix UT" This reverts commit 26f5c41cd13722f718a692a8e7df1fe5fef967ea. --- .../SmartContract/UT_InteropService.cs | 24 ++++--------------- .../SmartContract/UT_Syscalls.cs | 8 ------- tests/neo.UnitTests/TestUtils.cs | 8 +++---- 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 20df416778..399f063ec7 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -52,17 +52,11 @@ public void Runtime_GetNotifications_Test() scriptHash2 = script.ToArray().ToScriptHash(); snapshot.Contracts.Delete(scriptHash2); - var state = new ContractState() + snapshot.Contracts.Add(scriptHash2, new ContractState() { Script = script.ToArray(), Manifest = TestUtils.CreateDefaultManifest(scriptHash2, "test"), - }; - state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] - { - new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, - new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} - }; - snapshot.Contracts.Add(scriptHash2, state); + }); } // Wrong length @@ -223,6 +217,8 @@ public void TestExecutionEngine_GetCallingScriptHash() // Test real using ScriptBuilder scriptA = new ScriptBuilder(); + scriptA.Emit(OpCode.DROP); // Drop arguments + scriptA.Emit(OpCode.DROP); // Drop method scriptA.EmitSysCall(ApplicationEngine.System_Runtime_GetCallingScriptHash); var contract = new ContractState() @@ -234,7 +230,7 @@ public void TestExecutionEngine_GetCallingScriptHash() engine.Snapshot.Contracts.Add(contract.ScriptHash, contract); using ScriptBuilder scriptB = new ScriptBuilder(); - scriptB.EmitAppCall(contract.ScriptHash, "test"); + scriptB.EmitAppCall(contract.ScriptHash, "test", 0, 1); engine.LoadScript(scriptB.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -605,11 +601,6 @@ public void TestContract_Call() { var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract("method"); - state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] - { - new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, - new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} - }; state.Manifest.Features = ContractFeatures.HasStorage; string method = "method"; var args = new VM.Types.Array { 0, 1 }; @@ -637,11 +628,6 @@ public void TestContract_CallEx() var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract("method"); - state.Manifest.Abi.Methods[0].Parameters = new ContractParameterDefinition[] - { - new ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, - new ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} - }; state.Manifest.Features = ContractFeatures.HasStorage; snapshot.Contracts.Add(state.ScriptHash, state); diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 1590682742..848079aef3 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -345,14 +345,6 @@ public void System_Runtime_GetInvocationCounter() contracts.Add(contractA.ScriptHash, contractA); contracts.Add(contractB.ScriptHash, contractB); contracts.Add(contractC.ScriptHash, contractC); - - contractA.Manifest.Abi.Methods[0].Parameters = - contractB.Manifest.Abi.Methods[0].Parameters = - contractC.Manifest.Abi.Methods[0].Parameters = new Neo.SmartContract.Manifest.ContractParameterDefinition[] - { - new Neo.SmartContract.Manifest.ContractParameterDefinition(){ Name="a", Type= ContractParameterType.Integer}, - new Neo.SmartContract.Manifest.ContractParameterDefinition(){ Name="b", Type= ContractParameterType.Integer} - }; } // Call A,B,B,C diff --git a/tests/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs index c621bb6747..fd8e6fd620 100644 --- a/tests/neo.UnitTests/TestUtils.cs +++ b/tests/neo.UnitTests/TestUtils.cs @@ -25,19 +25,19 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash, string method Abi = new ContractAbi() { Hash = hash, - Events = Array.Empty(), - Methods = method == null ? Array.Empty() : new ContractMethodDescriptor[] + Events = new ContractEventDescriptor[0], + Methods = method == null ? new ContractMethodDescriptor[0] : new ContractMethodDescriptor[] { new ContractMethodDescriptor() { Name = method, - Parameters = Array.Empty(), + Parameters = new ContractParameterDefinition[0], ReturnType = ContractParameterType.Integer } } }, Features = ContractFeatures.NoProperty, - Groups = Array.Empty(), + Groups = new ContractGroup[0], SafeMethods = WildcardContainer.Create(), Trusts = WildcardContainer.Create(), Extra = null, From 0a7552708a30524361b11581e973173c2f2577e8 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Thu, 11 Jun 2020 16:34:47 +0800 Subject: [PATCH 4/4] Fix UT --- .../SmartContract/UT_InteropService.cs | 14 ++++---- .../SmartContract/UT_SmartContractHelper.cs | 2 +- .../SmartContract/UT_Syscalls.cs | 6 ++-- tests/neo.UnitTests/TestUtils.cs | 35 ++++++++++++------- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 399f063ec7..5b83133e37 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -55,7 +55,7 @@ public void Runtime_GetNotifications_Test() snapshot.Contracts.Add(scriptHash2, new ContractState() { Script = script.ToArray(), - Manifest = TestUtils.CreateDefaultManifest(scriptHash2, "test"), + Manifest = TestUtils.CreateManifest(scriptHash2, "test", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer), }); } @@ -223,7 +223,7 @@ public void TestExecutionEngine_GetCallingScriptHash() var contract = new ContractState() { - Manifest = TestUtils.CreateDefaultManifest(scriptA.ToArray().ToScriptHash(), "test"), + Manifest = TestUtils.CreateManifest(scriptA.ToArray().ToScriptHash(), "test", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer), Script = scriptA.ToArray() }; engine = GetEngine(true, true, false); @@ -600,10 +600,10 @@ public void TestStorageContext_AsReadOnly() public void TestContract_Call() { var snapshot = Blockchain.Singleton.GetSnapshot(); - var state = TestUtils.GetContract("method"); - state.Manifest.Features = ContractFeatures.HasStorage; string method = "method"; var args = new VM.Types.Array { 0, 1 }; + var state = TestUtils.GetContract(method, args.Count); + state.Manifest.Features = ContractFeatures.HasStorage; snapshot.Contracts.Add(state.ScriptHash, state); var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true); @@ -627,12 +627,12 @@ public void TestContract_CallEx() { var snapshot = Blockchain.Singleton.GetSnapshot(); - var state = TestUtils.GetContract("method"); + string method = "method"; + var args = new VM.Types.Array { 0, 1 }; + var state = TestUtils.GetContract(method, args.Count); state.Manifest.Features = ContractFeatures.HasStorage; snapshot.Contracts.Add(state.ScriptHash, state); - string method = "method"; - var args = new VM.Types.Array { 0, 1 }; foreach (var flags in new CallFlags[] { CallFlags.None, CallFlags.AllowCall, CallFlags.AllowModifyStates, CallFlags.All }) { diff --git a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index 3677041aa2..0f4e9f5f74 100644 --- a/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -139,7 +139,7 @@ public void TestVerifyWitnesses() Header header3 = new Header() { PrevHash = index3, Witness = new Witness { VerificationScript = new byte[0] } }; snapshot3.Contracts.Add(UInt160.Zero, new ContractState() { - Manifest = TestUtils.CreateDefaultManifest(UInt160.Zero, "verify"), + Manifest = TestUtils.CreateManifest(UInt160.Zero, "verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 100)); } diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 848079aef3..96b2ac0345 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -339,9 +339,9 @@ public void System_Runtime_GetInvocationCounter() contracts.Delete(contractA.ScriptHash); contracts.Delete(contractB.ScriptHash); contracts.Delete(contractC.ScriptHash); - contractA.Manifest = TestUtils.CreateDefaultManifest(contractA.ScriptHash, "dummyMain"); - contractB.Manifest = TestUtils.CreateDefaultManifest(contractA.ScriptHash, "dummyMain"); - contractC.Manifest = TestUtils.CreateDefaultManifest(contractA.ScriptHash, "dummyMain"); + contractA.Manifest = TestUtils.CreateManifest(contractA.ScriptHash, "dummyMain", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer); + contractB.Manifest = TestUtils.CreateManifest(contractA.ScriptHash, "dummyMain", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer); + contractC.Manifest = TestUtils.CreateManifest(contractA.ScriptHash, "dummyMain", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer); contracts.Add(contractA.ScriptHash, contractA); contracts.Add(contractB.ScriptHash, contractB); contracts.Add(contractC.ScriptHash, contractC); diff --git a/tests/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs index fd8e6fd620..ef380908dd 100644 --- a/tests/neo.UnitTests/TestUtils.cs +++ b/tests/neo.UnitTests/TestUtils.cs @@ -17,7 +17,7 @@ public static class TestUtils { public static readonly Random TestRandom = new Random(1337); // use fixed seed for guaranteed determinism - public static ContractManifest CreateDefaultManifest(UInt160 hash, string method = null) + public static ContractManifest CreateDefaultManifest(UInt160 hash) { return new ContractManifest() { @@ -26,15 +26,7 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash, string method { Hash = hash, Events = new ContractEventDescriptor[0], - Methods = method == null ? new ContractMethodDescriptor[0] : new ContractMethodDescriptor[] - { - new ContractMethodDescriptor() - { - Name = method, - Parameters = new ContractParameterDefinition[0], - ReturnType = ContractParameterType.Integer - } - } + Methods = new ContractMethodDescriptor[0] }, Features = ContractFeatures.NoProperty, Groups = new ContractGroup[0], @@ -44,6 +36,25 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash, string method }; } + public static ContractManifest CreateManifest(UInt160 hash, string method, ContractParameterType returnType, params ContractParameterType[] parameterTypes) + { + ContractManifest manifest = CreateDefaultManifest(hash); + manifest.Abi.Methods = new ContractMethodDescriptor[] + { + new ContractMethodDescriptor() + { + Name = method, + Parameters = parameterTypes.Select((p, i) => new ContractParameterDefinition + { + Name = $"p{i}", + Type = p + }).ToArray(), + ReturnType = returnType + } + }; + return manifest; + } + public static byte[] GetByteArray(int length, byte firstByte) { byte[] array = new byte[length]; @@ -82,13 +93,13 @@ public static Transaction GetTransaction() }; } - internal static ContractState GetContract(string method = null) + internal static ContractState GetContract(string method = "test", int parametersCount = 0) { return new ContractState { Id = 0x43000000, Script = new byte[] { 0x01, 0x01, 0x01, 0x01 }, - Manifest = CreateDefaultManifest(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"), method) + Manifest = CreateManifest(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"), method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray()) }; }