From 742945c3766803bb4167f4dcb28174fb3b07904a Mon Sep 17 00:00:00 2001 From: ShawnYun Date: Wed, 29 Jul 2020 15:47:18 +0800 Subject: [PATCH] Add ContractCall and UTs, delete Appcall (#327) * add ConTractCall and UTs, delete Appcall * fix * Disable warnings * spilt and fix * del ID * fix Neo and Policy, Add UT * del blank line * fix internal Co-authored-by: erikzhang Co-authored-by: Shargon --- src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs | 30 +++++-- src/Neo.Compiler.MSIL/MSIL/Converter.cs | 2 +- .../AppcallAttribute.cs | 33 -------- .../ContractAttribute.cs | 33 ++++++++ .../Services/Neo/GAS.cs | 16 ++++ .../Services/Neo/NEO.cs | 27 +++++++ .../Services/Neo/Native.cs | 14 ---- .../Services/Neo/Policy.cs | 24 ++++++ .../TestClasses/Contract1.cs | 11 +++ .../TestClasses/Contract_ContractCall.cs | 24 ++++++ .../TestClasses/Contract_appcall.cs | 20 ----- .../UnitTest_Appcall.cs | 34 -------- .../UnitTest_ContractCall.cs | 49 ++++++++++++ .../Utils/NeonTestTool.cs | 2 + .../Services/Neo/NativeTest.cs | 80 +++++++++++++++++-- .../TestClasses/Contract_Native.cs | 55 +++++++++++-- 16 files changed, 334 insertions(+), 120 deletions(-) delete mode 100644 src/Neo.SmartContract.Framework/AppcallAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/ContractAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/Services/Neo/GAS.cs create mode 100644 src/Neo.SmartContract.Framework/Services/Neo/NEO.cs delete mode 100644 src/Neo.SmartContract.Framework/Services/Neo/Native.cs create mode 100644 src/Neo.SmartContract.Framework/Services/Neo/Policy.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_ContractCall.cs delete mode 100644 tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_appcall.cs delete mode 100644 tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Appcall.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ContractCall.cs diff --git a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs index acbcacab3..0710983f9 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs @@ -162,7 +162,7 @@ public bool IsSysCall(Mono.Cecil.MethodDefinition defs, out string name) } */ - public bool IsAppCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) + public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) { if (defs == null) { @@ -170,9 +170,9 @@ public bool IsAppCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) return false; } - foreach (var attr in defs.CustomAttributes) + foreach (var attr in defs.DeclaringType.CustomAttributes) { - if (attr.AttributeType.Name == "AppcallAttribute") + if (attr.AttributeType.Name == "ContractAttribute") { var type = attr.ConstructorArguments[0].Type; var a = attr.ConstructorArguments[0]; @@ -462,16 +462,18 @@ private int ConvertCall(OpCode src, NeoMethod to) calltype = 2; } } - else if (IsAppCall(defs, out callhash)) + else if (IsContractCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) - {//this is a call + { + //this is a call calltype = 1; } else - {//maybe a syscall // or other + { + //maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //All types of display implicit conversion are ignored @@ -738,7 +740,8 @@ private int ConvertCall(OpCode src, NeoMethod to) //opcode call } else - {// reverse the arguments order + { + // reverse the arguments order //this become very diffcult @@ -829,8 +832,21 @@ private int ConvertCall(OpCode src, NeoMethod to) } else if (calltype == 4) { + // Package the arguments into an array. + ConvertPushNumber(pcount, null, to); + Convert1by1(VM.OpCode.PACK, null, to); + + // Push call method name, the first letter should be lowercase. + var methodName = defs.Body.Method.Name; + ConvertPushString(methodName[..1].ToLowerInvariant() + methodName[1..], src, to); + + // Push contract hash. ConvertPushDataArray(callhash, src, to); Insert1(VM.OpCode.SYSCALL, "", to, BitConverter.GetBytes(ApplicationEngine.System_Contract_Call)); + + // If the return type is void, insert a DROP. + if (defs.ReturnType.FullName is "System.Void") + Insert1(VM.OpCode.DROP, "", to); } else if (calltype == 5) { diff --git a/src/Neo.Compiler.MSIL/MSIL/Converter.cs b/src/Neo.Compiler.MSIL/MSIL/Converter.cs index 3bfea1619..abdd9f8a4 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Converter.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Converter.cs @@ -109,7 +109,7 @@ public NeoModule Convert(ILModule _in, ConvOption option = null) nm.paramtypes.Add(new NeoParam(src.name, src.type)); } - if (IsAppCall(m.Value.method, out byte[] outcall)) + if (IsContractCall(m.Value.method, out byte[] outcall)) continue; if (IsNonCall(m.Value.method)) continue; diff --git a/src/Neo.SmartContract.Framework/AppcallAttribute.cs b/src/Neo.SmartContract.Framework/AppcallAttribute.cs deleted file mode 100644 index 2ee89255d..000000000 --- a/src/Neo.SmartContract.Framework/AppcallAttribute.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Globalization; - -namespace Neo.SmartContract.Framework -{ - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor)] - public class AppcallAttribute : Attribute - { - public byte[] ScriptHash { get; } - - public AppcallAttribute(byte[] scriptHash) - { - if (scriptHash == null) throw new ArgumentNullException(); - if (scriptHash.Length != 20) throw new ArgumentException(); - this.ScriptHash = scriptHash; - } - - public AppcallAttribute(string scriptHash) - { - if (scriptHash == null) throw new ArgumentNullException(); - - if (scriptHash.StartsWith("0x")) - { - scriptHash = scriptHash.Remove(0, 2); - } - - if (scriptHash.Length != 40) throw new ArgumentException(); - this.ScriptHash = new byte[scriptHash.Length / 2]; - for (int i = 0; i < this.ScriptHash.Length; i++) - this.ScriptHash[i] = byte.Parse(scriptHash.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier); - } - } -} diff --git a/src/Neo.SmartContract.Framework/ContractAttribute.cs b/src/Neo.SmartContract.Framework/ContractAttribute.cs new file mode 100644 index 000000000..1eb7fd21f --- /dev/null +++ b/src/Neo.SmartContract.Framework/ContractAttribute.cs @@ -0,0 +1,33 @@ +using System; +using System.Globalization; + +namespace Neo.SmartContract.Framework +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class ContractAttribute : Attribute + { + public byte[] Hash { get; } + + public ContractAttribute(byte[] hash) + { + if (hash == null) throw new ArgumentNullException(); + if (hash.Length != 20) throw new ArgumentException(); + Hash = hash; + } + + public ContractAttribute(string hash) + { + if (hash == null) throw new ArgumentNullException(); + + if (hash.StartsWith("0x")) + { + hash = hash.Remove(0, 2); + } + + if (hash.Length != 40) throw new ArgumentException(); + Hash = new byte[hash.Length / 2]; + for (int i = 0; i < Hash.Length; i++) + Hash[i] = byte.Parse(hash.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier); + } + } +} diff --git a/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs b/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs new file mode 100644 index 000000000..52a74e44f --- /dev/null +++ b/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs @@ -0,0 +1,16 @@ +#pragma warning disable CS0626 + +using System.Numerics; + +namespace Neo.SmartContract.Framework.Services.Neo +{ + [Contract("0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc")] + public class GAS + { + public static extern string Name(); + public static extern string Symbol(); + public static extern byte Decimals(); + public static extern BigInteger TotalSupply(); + public static extern BigInteger BalanceOf(byte[] account); + } +} diff --git a/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs b/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs new file mode 100644 index 000000000..6df9992b5 --- /dev/null +++ b/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs @@ -0,0 +1,27 @@ +#pragma warning disable CS0626 + +using System; +using System.Numerics; + +namespace Neo.SmartContract.Framework.Services.Neo +{ + [Contract("0xde5f57d430d3dece511cf975a8d37848cb9e0525")] + public class NEO + { + public static extern string Name(); + public static extern string Symbol(); + public static extern BigInteger Decimals(); + public static extern BigInteger TotalSupply(); + public static extern BigInteger BalanceOf(byte[] account); + + public static extern BigInteger UnclaimedGas(byte[] account, uint end); + + public static extern bool RegisterCandidate(byte[] pubkey); + public static extern bool UnRegisterCandidate(byte[] pubkey); + public static extern bool Vote(byte[] account, byte[] voteTo); + public static extern (string, BigInteger)[] GetCandidates(); + public static extern string[] GetValidators(); + public static extern string[] GetCommittee(); + public static extern string[] GetNextBlockValidators(); + } +} diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Native.cs b/src/Neo.SmartContract.Framework/Services/Neo/Native.cs deleted file mode 100644 index 96d573586..000000000 --- a/src/Neo.SmartContract.Framework/Services/Neo/Native.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Neo.SmartContract.Framework.Services.Neo -{ - public class Native - { - [Appcall("0xde5f57d430d3dece511cf975a8d37848cb9e0525")] - public static extern object NEO(string method, object[] arguments); - - [Appcall("0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc")] - public static extern object GAS(string method, object[] arguments); - - [Appcall("0xce06595079cd69583126dbfd1d2e25cca74cffe9")] - public static extern object Policy(string method, object[] arguments); - } -} diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs b/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs new file mode 100644 index 000000000..e6ba014fd --- /dev/null +++ b/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs @@ -0,0 +1,24 @@ +#pragma warning disable CS0626 + +using System; +using System.Numerics; + +namespace Neo.SmartContract.Framework.Services.Neo +{ + [Contract("0xce06595079cd69583126dbfd1d2e25cca74cffe9")] + public class Policy + { + public static extern string Name(); + public static extern uint GetMaxTransactionsPerBlock(); + public static extern uint GetMaxBlockSize(); + public static extern long GetMaxBlockSystemFee(); + public static extern BigInteger GetFeePerByte(); + public static extern string[] GetBlockedAccounts(); + public static extern bool SetMaxBlockSize(uint value); + public static extern bool SetMaxTransactionsPerBlock(uint value); + public static extern bool SetMaxBlockSystemFee(long value); + public static extern bool SetFeePerByte(long value); + public static extern bool BlockAccount(byte[] account); + public static extern bool UnblockAccount(byte[] account); + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract1.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract1.cs index 6b186879a..eb7b61337 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract1.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract1.cs @@ -8,5 +8,16 @@ public static byte[] unitTest_001() return nb; } + public static void testVoid() + { + var nb = new byte[] { 1, 2, 3, 4 }; + } + + public static byte[] testArgs(byte a) + { + var nb = new byte[] { 1, 2, 3, 3 }; + nb[3] = a; + return nb; + } } } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_ContractCall.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_ContractCall.cs new file mode 100644 index 000000000..c35ba2844 --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_ContractCall.cs @@ -0,0 +1,24 @@ +using Neo.SmartContract.Framework; + +namespace Neo.Compiler.MSIL.UnitTests.TestClasses +{ + [Contract("0102030405060708090A0102030405060708090A")] + public class Contract1 + { + public static extern byte[] testArgs(byte a); + public static extern void testVoid(); + } + + public class Contract_ContractCall : SmartContract.Framework.SmartContract + { + public static byte[] testContractCall() + { + return Contract1.testArgs((byte)4); + } + + public static void testContractCallVoid() + { + Contract1.testVoid(); + } + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_appcall.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_appcall.cs deleted file mode 100644 index ea9dd5487..000000000 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_appcall.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Neo.SmartContract.Framework; - -namespace Neo.Compiler.MSIL.UnitTests.TestClasses -{ - class Contract_syscall : SmartContract.Framework.SmartContract - { - //这个appcall的地址,在testcase中可以配置 - //[Appcall("0102030405060708090A0102030405060708090A")] - [Syscall("System.Contract.Call")] - static extern object unittest001(byte[] scriptHash, string method, object[] arguments); - - public static object testAppCall() - { - var scriptHash = new byte[] { 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - var methodName = "unitTest_001"; - object[] arguments = new object[0] { }; - return unittest001(scriptHash, methodName, arguments); - } - } -} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Appcall.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Appcall.cs deleted file mode 100644 index 1d7ebbaeb..000000000 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Appcall.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Compiler.MSIL.UnitTests.Utils; -using Neo.IO.Json; -using Neo.SmartContract.Manifest; -using Neo.VM.Types; - -namespace Neo.Compiler.MSIL.UnitTests -{ - [TestClass] - public class UnitTest_AppCall - { - [TestMethod] - public void Test_Appcall() - { - var hash = UInt160.Parse("0102030405060708090A0102030405060708090A"); - var testengine = new TestEngine(); - testengine.Snapshot.Contracts.Add(hash, new Ledger.ContractState() - { - //Manifest = new SmartContract.Manifest.ContractManifest(), - Script = testengine.Build("./TestClasses/Contract1.cs").finalNEF, - Manifest = ContractManifest.FromJson(JObject.Parse(testengine.Build("./TestClasses/Contract1.cs").finalManifest)), - }); - - //will appcall 0102030405060708090A0102030405060708090A - testengine.AddEntryScript("./TestClasses/Contract_appcall.cs"); - - var result = testengine.GetMethod("testAppCall").Run().ConvertTo(StackItemType.ByteString); - StackItem wantresult = new byte[] { 1, 2, 3, 4 }; - - var bequal = wantresult.Equals(result); - Assert.IsTrue(bequal); - } - } -} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ContractCall.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ContractCall.cs new file mode 100644 index 000000000..5c10863f9 --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ContractCall.cs @@ -0,0 +1,49 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Compiler.MSIL.UnitTests.Utils; +using Neo.IO.Json; +using Neo.SmartContract.Manifest; +using Neo.VM; +using Neo.VM.Types; + +namespace Neo.Compiler.MSIL.UnitTests +{ + [TestClass] + public class UnitTest_ContractCall + { + private TestEngine _engine; + + [TestInitialize] + public void Init() + { + var hash = UInt160.Parse("0102030405060708090A0102030405060708090A"); + _engine = new TestEngine(); + _engine.Snapshot.Contracts.Add(hash, new Ledger.ContractState() + { + Script = _engine.Build("./TestClasses/Contract1.cs").finalNEF, + Manifest = ContractManifest.FromJson(JObject.Parse(_engine.Build("./TestClasses/Contract1.cs").finalManifest)), + }); + + //will ContractCall 0102030405060708090A0102030405060708090A + _engine.AddEntryScript("./TestClasses/Contract_ContractCall.cs"); + } + + [TestMethod] + public void Test_ContractCall() + { + var result = _engine.GetMethod("testContractCall").Run().ConvertTo(StackItemType.ByteString); + Assert.AreEqual(VMState.HALT, _engine.State); + + StackItem wantresult = new byte[] { 1, 2, 3, 4 }; + var bequal = wantresult.Equals(result); + Assert.IsTrue(bequal); + } + + [TestMethod] + public void Test_ContractCall_Void() + { + var result = _engine.ExecuteTestCaseStandard("testContractCallVoid"); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(0, result.Count); + } + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs index 832b4b997..9260ceb74 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs @@ -1,9 +1,11 @@ using Neo.VM; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; +[assembly: InternalsVisibleTo("Neo.SmartContract.Framework.UnitTests")] namespace Neo.Compiler.MSIL.UnitTests.Utils { internal static class NeonTestTool diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/NativeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/NativeTest.cs index 0370c473f..12e0f414b 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/NativeTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/NativeTest.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; +using Neo.Cryptography.ECC; using Neo.VM; using Neo.VM.Types; @@ -9,15 +10,13 @@ namespace Neo.SmartContract.Framework.UnitTests.Services.Neo public class NativeTest { private TestEngine _engine; + private readonly byte[] pubKey = NeonTestTool.HexString2Bytes("03ea01cb94bdaf0cd1c01b159d474f9604f4af35a3e2196f6bdfdb33b2aa4961fa"); [TestInitialize] public void Init() { - _engine = new TestEngine(); - // Deploy native contracts - - ((TestSnapshot)_engine.Snapshot).SetPersistingBlock(new Network.P2P.Payloads.Block() + var block = new Network.P2P.Payloads.Block() { Index = 0, ConsensusData = new Network.P2P.Payloads.ConsensusData(), @@ -25,12 +24,15 @@ public void Init() Witness = new Network.P2P.Payloads.Witness() { InvocationScript = new byte[0], - VerificationScript = new byte[0] + VerificationScript = Contract.CreateSignatureRedeemScript(ECPoint.FromBytes(pubKey, ECCurve.Secp256k1)) }, NextConsensus = UInt160.Zero, MerkleRoot = UInt256.Zero, PrevHash = UInt256.Zero - }); + }; + + _engine = new TestEngine(TriggerType.Application, block); + ((TestSnapshot)_engine.Snapshot).SetPersistingBlock(block); using (var script = new ScriptBuilder()) { @@ -63,6 +65,54 @@ public void Test_NEO() item = result.Pop(); Assert.IsInstanceOfType(item, typeof(ByteString)); Assert.AreEqual("NEO", item.GetString()); + + _engine.Reset(); + var account = new byte[] { 0xf6, 0x64, 0x43, 0x49, 0x8d, 0x38, 0x78, 0xd3, 0x2b, 0x99, 0x4e, 0x4e, 0x12, 0x83, 0xc6, 0x93, 0x44, 0x21, 0xda, 0xfe }; + result = _engine.ExecuteTestCaseStandard("NEO_BalanceOf", account); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Integer)); + Assert.AreEqual(0, item.GetInteger()); + + // Before RegisterCandidate + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("NEO_GetCandidates"); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Array)); + Assert.AreEqual(21, ((Array)item).Count); + + // RegisterCandidate + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("NEO_RegisterCandidate", pubKey); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Boolean)); + Assert.AreEqual(true, item.GetBoolean()); + + // After RegisterCandidate + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("NEO_GetCandidates"); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Array)); + Assert.AreEqual(22, ((Array)item).Count); + var candidate = ((Array)item)[21]; + Assert.IsInstanceOfType(candidate, typeof(Struct)); + var candidatePubKey = ((Struct)candidate)[0]; + var candidateVotes = ((Struct)candidate)[1]; + Assert.IsInstanceOfType(candidatePubKey, typeof(ByteString)); + Assert.AreEqual(true, candidatePubKey.Equals((ByteString)pubKey)); + Assert.IsInstanceOfType(candidateVotes, typeof(Integer)); + Assert.AreEqual(0, candidateVotes.GetInteger()); } [TestMethod] @@ -98,6 +148,24 @@ public void Test_Policy() var item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(1000L, item.GetInteger()); + + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("policy_GetMaxTransactionsPerBlock"); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Integer)); + Assert.AreEqual(512, item.GetInteger()); + + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("policy_GetBlockedAccounts"); + Assert.AreEqual(VMState.HALT, _engine.State); + Assert.AreEqual(1, result.Count); + + item = result.Pop(); + Assert.IsInstanceOfType(item, typeof(Array)); + Assert.AreEqual(0, ((Array)item).Count); } } } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs index a3883513b..4608f9681 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs @@ -1,6 +1,7 @@ using Neo.SmartContract.Framework.Services.Neo; using System.ComponentModel; using System.Numerics; +using System; namespace Neo.Compiler.MSIL.TestClasses { @@ -9,30 +10,74 @@ public class Contract_Native : SmartContract.Framework.SmartContract [DisplayName("NEO_Decimals")] public static int NEO_Decimals() { - return (int)Native.NEO("decimals", new object[0]); + return (int)NEO.Decimals(); } [DisplayName("NEO_Name")] public static string NEO_Name() { - return (string)Native.NEO("name", new object[0]); + return NEO.Name(); + } + + [DisplayName("NEO_BalanceOf")] + public static BigInteger NEO_BalanceOf(byte[] account) + { + return NEO.BalanceOf(account); + } + + [DisplayName("NEO_GetValidators")] + public static string[] NEO_GetValidators() + { + return NEO.GetValidators(); + } + + [DisplayName("NEO_RegisterCandidate")] + public static bool NEO_RegisterCandidate(byte[] pubkey) + { + return NEO.RegisterCandidate(pubkey); + } + + [DisplayName("NEO_GetCandidates")] + public static (string, BigInteger)[] NEO_GetCandidates() + { + return NEO.GetCandidates(); } [DisplayName("GAS_Decimals")] public static int GAS_Decimals() { - return (int)Native.GAS("decimals", new object[0]); + return (int)GAS.Decimals(); } [DisplayName("GAS_Name")] public static string GAS_Name() { - return (string)Native.GAS("name", new object[0]); + return GAS.Name(); } public static BigInteger Policy_GetFeePerByte() { - return (BigInteger)Native.Policy("getFeePerByte", new object[0]); + return Policy.GetFeePerByte(); + } + + public static bool Policy_SetMaxTransactionsPerBlock(uint value) + { + return Policy.SetMaxTransactionsPerBlock(value); + } + + public static uint Policy_GetMaxTransactionsPerBlock() + { + return Policy.GetMaxTransactionsPerBlock(); + } + + public static bool Policy_BlockAccount(byte[] account) + { + return Policy.BlockAccount(account); + } + + public static object[] Policy_GetBlockedAccounts() + { + return Policy.GetBlockedAccounts(); } } }