From c7997a93e0b878c75bddf24dd41e57efb003c337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Wed, 21 Oct 2020 14:59:01 +0800 Subject: [PATCH 01/24] fixed-bug-1021 --- src/RpcServer/RpcServer.SmartContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index f5cf6cbfc..3de9c924f 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -79,7 +79,7 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) } if (engine.State != VMState.FAULT) { - ProcessInvokeWithWallet(json, signers); + ProcessInvokeWithWallet(json, null, signers); } return json; } From 7c9f02bb4bb73841a3cc2cd85dc67b59d643edc9 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 21 Oct 2020 09:22:58 +0200 Subject: [PATCH 02/24] Update src/RpcServer/RpcServer.SmartContract.cs --- src/RpcServer/RpcServer.SmartContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 3de9c924f..8203bd7c6 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -79,7 +79,7 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) } if (engine.State != VMState.FAULT) { - ProcessInvokeWithWallet(json, null, signers); + ProcessInvokeWithWallet(json, signers: signers); } return json; } From 1079aa36eb031f2d2672033ecd3cdb2e689672ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Wed, 21 Oct 2020 17:48:21 +0800 Subject: [PATCH 03/24] =?UTF-8?q?=F0=9F=98=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RpcServer/RpcServer.SmartContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 8203bd7c6..f5cf6cbfc 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -79,7 +79,7 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) } if (engine.State != VMState.FAULT) { - ProcessInvokeWithWallet(json, signers: signers); + ProcessInvokeWithWallet(json, signers); } return json; } From 68280621509eeb6b0f44836a9c2701a765c00234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 16 Nov 2020 10:43:50 +0800 Subject: [PATCH 04/24] Object reference not set to an instance of an object. --- src/RpcServer/RpcServer.SmartContract.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 9146c91d1..165fb0318 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -65,9 +65,9 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) { Transaction tx = new Transaction { - Signers = signers.GetSigners(), + Signers = signers?.GetSigners(), Attributes = Array.Empty(), - Witnesses = signers.Witnesses, + Witnesses = signers?.Witnesses, }; using ApplicationEngine engine = ApplicationEngine.Run(script, container: tx, gas: settings.MaxGasInvoke); JObject json = new JObject(); From 938312ac44e2e66a052a16405f12966aac288008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 15:41:26 +0800 Subject: [PATCH 05/24] a --- src/RpcServer/RpcServer.SmartContract.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index f3a5c340a..4fed465ad 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -65,9 +65,9 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) { Transaction tx = signers == null ? null : new Transaction { - Signers = signers?.GetSigners(), + Signers = signers.GetSigners(), Attributes = Array.Empty(), - Witnesses = signers?.Witnesses, + Witnesses = signers.Witnesses, }; using ApplicationEngine engine = ApplicationEngine.Run(script, container: tx, gas: settings.MaxGasInvoke); JObject json = new JObject(); From eab56dd959e32e9bc9ffdef408839b880846f3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 15:56:05 +0800 Subject: [PATCH 06/24] Upgrade target framework. --- src/ApplicationLogs/ApplicationLogs.csproj | 2 +- src/LevelDBStore/LevelDBStore.csproj | 2 +- src/RocksDBStore/RocksDBStore.csproj | 2 +- src/RpcClient/RpcClient.csproj | 2 +- src/RpcNep5Tracker/RpcNep5Tracker.csproj | 2 +- src/RpcServer/RpcServer.csproj | 2 +- src/StatesDumper/StatesDumper.csproj | 2 +- tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj | 2 +- .../Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ApplicationLogs/ApplicationLogs.csproj b/src/ApplicationLogs/ApplicationLogs.csproj index 5318c84ca..398325db4 100644 --- a/src/ApplicationLogs/ApplicationLogs.csproj +++ b/src/ApplicationLogs/ApplicationLogs.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Plugins diff --git a/src/LevelDBStore/LevelDBStore.csproj b/src/LevelDBStore/LevelDBStore.csproj index 2acba8102..38de12318 100644 --- a/src/LevelDBStore/LevelDBStore.csproj +++ b/src/LevelDBStore/LevelDBStore.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo true diff --git a/src/RocksDBStore/RocksDBStore.csproj b/src/RocksDBStore/RocksDBStore.csproj index 8cace3405..800bd992d 100644 --- a/src/RocksDBStore/RocksDBStore.csproj +++ b/src/RocksDBStore/RocksDBStore.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Plugins.Storage diff --git a/src/RpcClient/RpcClient.csproj b/src/RpcClient/RpcClient.csproj index d687d0cce..554f6bfab 100644 --- a/src/RpcClient/RpcClient.csproj +++ b/src/RpcClient/RpcClient.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Network.RPC The Neo Project Neo.Network.RPC.RpcClient diff --git a/src/RpcNep5Tracker/RpcNep5Tracker.csproj b/src/RpcNep5Tracker/RpcNep5Tracker.csproj index 7a9a6764e..85f7cd579 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker.csproj +++ b/src/RpcNep5Tracker/RpcNep5Tracker.csproj @@ -1,7 +1,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Plugins diff --git a/src/RpcServer/RpcServer.csproj b/src/RpcServer/RpcServer.csproj index eafe5d8d5..834215d0c 100644 --- a/src/RpcServer/RpcServer.csproj +++ b/src/RpcServer/RpcServer.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Plugins diff --git a/src/StatesDumper/StatesDumper.csproj b/src/StatesDumper/StatesDumper.csproj index ee9be372a..e65142458 100644 --- a/src/StatesDumper/StatesDumper.csproj +++ b/src/StatesDumper/StatesDumper.csproj @@ -2,7 +2,7 @@ 3.0.0-preview3 - netstandard2.1 + net5.0 Neo.Plugins diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index af5c7c416..c571eb8e3 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 Neo.Network.RPC.Tests false diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index ac7f99449..dc0ff604e 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + net5.0 Neo.Plugins.Storage.Tests false From b53daabad178aa5189507259af95de3a73b8a960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 16:07:46 +0800 Subject: [PATCH 07/24] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 989a033f7..545a686d7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ on: pull_request: env: - DOTNET_VERSION: 3.1.100 + DOTNET_VERSION: 5.0.100 jobs: From 80b92da1641abaa41e099f52ba977bc02fcb2b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 17:12:47 +0800 Subject: [PATCH 08/24] Update main.yml --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 545a686d7..205b9c616 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,8 +21,8 @@ jobs: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Check format run: | - dotnet tool install --version 3.2.111002 --tool-path ./ dotnet-format --add-source https://dotnet.myget.org/F/format/api/v3/index.json - ./dotnet-format --check --dry-run -v diagnostic + dotnet tool install --version 5.0.142902 --tool-path ./ dotnet-format --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + ./dotnet-format . --check -v diagnostic - name: Test run: | sudo apt-get --assume-yes install libleveldb-dev libsnappy-dev libc6-dev From 4a73e9208b072f42d299004f8e0604138b2a06a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 18:47:57 +0800 Subject: [PATCH 09/24] update --- src/ApplicationLogs/ApplicationLogs.csproj | 2 -- src/Directory.Build.props | 2 +- src/LevelDBStore/LevelDBStore.csproj | 3 --- src/RocksDBStore/RocksDBStore.csproj | 2 -- src/RpcClient/RpcClient.csproj | 4 ---- src/RpcNep5Tracker/RpcNep5Tracker.csproj | 2 -- src/RpcServer/RpcServer.csproj | 2 -- src/StatesDumper/StatesDumper.csproj | 3 --- tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj | 2 +- .../Neo.Plugins.Storage.Tests.csproj | 2 +- 10 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/ApplicationLogs/ApplicationLogs.csproj b/src/ApplicationLogs/ApplicationLogs.csproj index b9e9d8a9e..007129f40 100644 --- a/src/ApplicationLogs/ApplicationLogs.csproj +++ b/src/ApplicationLogs/ApplicationLogs.csproj @@ -1,8 +1,6 @@ - 3.0.0-preview3 - net5.0 Neo.Plugins.ApplicationLogs Neo.Plugins diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 44d252790..79cbc6cf9 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,7 +4,7 @@ 3.0.0 preview3 - netstandard2.1 + net5.0 Neo.Plugins The Neo Project NEO;Blockchain diff --git a/src/LevelDBStore/LevelDBStore.csproj b/src/LevelDBStore/LevelDBStore.csproj index 937b7b3b5..d49bce97d 100644 --- a/src/LevelDBStore/LevelDBStore.csproj +++ b/src/LevelDBStore/LevelDBStore.csproj @@ -1,9 +1,6 @@ - 3.0.0-preview3 - net5.0 - Neo Neo.Plugins.Storage.LevelDBStore Neo.Plugins.Storage true diff --git a/src/RocksDBStore/RocksDBStore.csproj b/src/RocksDBStore/RocksDBStore.csproj index fb66bdd79..e1f5bad60 100644 --- a/src/RocksDBStore/RocksDBStore.csproj +++ b/src/RocksDBStore/RocksDBStore.csproj @@ -1,8 +1,6 @@ - 3.0.0-preview3 - net5.0 Neo.Plugins.Storage.RocksDBStore Neo.Plugins.Storage diff --git a/src/RpcClient/RpcClient.csproj b/src/RpcClient/RpcClient.csproj index ba1db0abd..d2f535e5e 100644 --- a/src/RpcClient/RpcClient.csproj +++ b/src/RpcClient/RpcClient.csproj @@ -1,10 +1,6 @@ - 3.0.0-preview3 - net5.0 - Neo.Network.RPC - The Neo Project Neo.Network.RPC.RpcClient Neo.Network.RPC diff --git a/src/RpcNep5Tracker/RpcNep5Tracker.csproj b/src/RpcNep5Tracker/RpcNep5Tracker.csproj index 4547f0658..403f4a12a 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker.csproj +++ b/src/RpcNep5Tracker/RpcNep5Tracker.csproj @@ -1,7 +1,5 @@ - 3.0.0-preview3 - net5.0 Neo.Plugins.RpcNep5Tracker Neo.Plugins diff --git a/src/RpcServer/RpcServer.csproj b/src/RpcServer/RpcServer.csproj index 92d8024dd..9ce3d9e1c 100644 --- a/src/RpcServer/RpcServer.csproj +++ b/src/RpcServer/RpcServer.csproj @@ -1,8 +1,6 @@  - 3.0.0-preview3 - net5.0 Neo.Plugins.RpcServer Neo.Plugins diff --git a/src/StatesDumper/StatesDumper.csproj b/src/StatesDumper/StatesDumper.csproj index d496c956d..c361bbf96 100644 --- a/src/StatesDumper/StatesDumper.csproj +++ b/src/StatesDumper/StatesDumper.csproj @@ -1,9 +1,6 @@ - 3.0.0-preview3 - net5.0 - Neo.Plugins Neo.Plugins.StatesDumper diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index c571eb8e3..af5c7c416 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 Neo.Network.RPC.Tests false diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index dc0ff604e..ac7f99449 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.0 Neo.Plugins.Storage.Tests false From ab53cdedb88393d82576b3570c45ca8b54598249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 19:01:17 +0800 Subject: [PATCH 10/24] update --- tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj | 2 +- .../Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index af5c7c416..c571eb8e3 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 Neo.Network.RPC.Tests false diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index ac7f99449..dc0ff604e 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + net5.0 Neo.Plugins.Storage.Tests false From 4ca3610bba620944f48aa5ccacf916186cc3ff18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 23 Nov 2020 19:06:12 +0800 Subject: [PATCH 11/24] update --- src/Directory.Build.props => Directory.Build.props | 0 tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj | 1 - tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj | 1 - 3 files changed, 2 deletions(-) rename src/Directory.Build.props => Directory.Build.props (100%) diff --git a/src/Directory.Build.props b/Directory.Build.props similarity index 100% rename from src/Directory.Build.props rename to Directory.Build.props diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index c571eb8e3..b019b5b47 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -1,7 +1,6 @@ - net5.0 Neo.Network.RPC.Tests false diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index dc0ff604e..6a68865f3 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -1,7 +1,6 @@ - net5.0 Neo.Plugins.Storage.Tests false From 6dd0c37a1ab748a9cae0a52608535c4c4cdea188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 26 Nov 2020 04:02:49 -0600 Subject: [PATCH 12/24] [RpcServer] Querying contracts by ID/name (#378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan --- src/ApplicationLogs/LogReader.cs | 13 +++---- src/RpcClient/Models/RpcApplicationLog.cs | 6 ++-- src/RpcClient/Models/RpcBlock.cs | 2 +- src/RpcClient/Models/RpcInvokeResult.cs | 4 ++- src/RpcClient/Models/RpcTransaction.cs | 2 +- src/RpcClient/TransactionManagerFactory.cs | 3 +- src/RpcClient/Utility.cs | 19 ++++++++-- src/RpcServer/RpcServer.Blockchain.cs | 17 +++++++-- src/RpcServer/RpcServer.SmartContract.cs | 2 +- src/RpcServer/RpcServer.Wallet.cs | 2 +- src/RpcServer/RpcServer.cs | 2 +- src/RpcServer/Utility.cs | 28 +++++++++++++++ tests/Neo.Network.RPC.Tests/RpcTestCases.json | 36 +++++++++---------- .../UT_TransactionManager.cs | 2 +- 14 files changed, 99 insertions(+), 39 deletions(-) create mode 100644 src/RpcServer/Utility.cs diff --git a/src/ApplicationLogs/LogReader.cs b/src/ApplicationLogs/LogReader.cs index 90c772691..f68ebaede 100644 --- a/src/ApplicationLogs/LogReader.cs +++ b/src/ApplicationLogs/LogReader.cs @@ -4,6 +4,7 @@ using Neo.Ledger; using Neo.Persistence; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; using System; using System.Collections.Generic; @@ -40,7 +41,7 @@ public JObject GetApplicationLog(JArray _params) if (value is null) throw new RpcException(-100, "Unknown transaction/blockhash"); - var raw = JObject.Parse(Utility.StrictUTF8.GetString(value)); + var raw = JObject.Parse(Neo.Utility.StrictUTF8.GetString(value)); //Additional optional "trigger" parameter to getapplicationlog for clients to be able to get just one execution result for a block. if (_params.Count >= 2 && Enum.TryParse(_params[1].AsString(), true, out TriggerType trigger)) { @@ -66,7 +67,7 @@ public static JObject TxLogToJson(Blockchain.ApplicationExecuted appExec) trigger["trigger"] = appExec.Trigger; trigger["vmstate"] = appExec.VMState; trigger["exception"] = GetExceptionMessage(appExec.Exception); - trigger["gasconsumed"] = appExec.GasConsumed.ToString(); + trigger["gasconsumed"] = new BigDecimal(appExec.GasConsumed, NativeContract.GAS.Decimals).ToString(); try { trigger["stack"] = appExec.Stack.Select(q => q.ToJson()).ToArray(); @@ -109,7 +110,7 @@ public static JObject BlockLogToJson(StoreView snapshot, IReadOnlyList q.ToJson()).ToArray(); @@ -150,14 +151,14 @@ public void OnPersist(StoreView snapshot, IReadOnlyList p.Transaction != null)) { var txJson = TxLogToJson(appExec); - writeBatch.Put(appExec.Transaction.Hash.ToArray(), Utility.StrictUTF8.GetBytes(txJson.ToString())); + writeBatch.Put(appExec.Transaction.Hash.ToArray(), Neo.Utility.StrictUTF8.GetBytes(txJson.ToString())); } //processing log for block var blockJson = BlockLogToJson(snapshot, applicationExecutedList); if (blockJson != null) { - writeBatch.Put(snapshot.PersistingBlock.Hash.ToArray(), Utility.StrictUTF8.GetBytes(blockJson.ToString())); + writeBatch.Put(snapshot.PersistingBlock.Hash.ToArray(), Neo.Utility.StrictUTF8.GetBytes(blockJson.ToString())); } db.Write(WriteOptions.Default, writeBatch); } @@ -173,7 +174,7 @@ public bool ShouldThrowExceptionFromCommit(Exception ex) static string GetExceptionMessage(Exception exception) { - if (exception == null) return "Engine faulted."; + if (exception == null) return null; if (exception.InnerException != null) { diff --git a/src/RpcClient/Models/RpcApplicationLog.cs b/src/RpcClient/Models/RpcApplicationLog.cs index cfdfbcc7e..42fa20833 100644 --- a/src/RpcClient/Models/RpcApplicationLog.cs +++ b/src/RpcClient/Models/RpcApplicationLog.cs @@ -1,7 +1,9 @@ using Neo.IO.Json; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; +using System; using System.Collections.Generic; using System.Linq; @@ -54,7 +56,7 @@ public JObject ToJson() JObject json = new JObject(); json["trigger"] = Trigger; json["vmstate"] = VMState; - json["gasconsumed"] = GasConsumed.ToString(); + json["gasconsumed"] = new BigDecimal(GasConsumed, NativeContract.GAS.Decimals).ToString(); json["stack"] = Stack.Select(q => q.ToJson()).ToArray(); json["notifications"] = Notifications.Select(q => q.ToJson()).ToArray(); return json; @@ -66,7 +68,7 @@ public static Execution FromJson(JObject json) { Trigger = json["trigger"].TryGetEnum(), VMState = json["vmstate"].TryGetEnum(), - GasConsumed = long.Parse(json["gasconsumed"].AsString()), + GasConsumed = (long)BigDecimal.Parse(json["gasconsumed"].AsString(), NativeContract.GAS.Decimals).Value, Stack = ((JArray)json["stack"]).Select(p => Utility.StackItemFromJson(p)).ToList(), Notifications = ((JArray)json["notifications"]).Select(p => RpcNotifyEventArgs.FromJson(p)).ToList() }; diff --git a/src/RpcClient/Models/RpcBlock.cs b/src/RpcClient/Models/RpcBlock.cs index 24687812f..8d706ca74 100644 --- a/src/RpcClient/Models/RpcBlock.cs +++ b/src/RpcClient/Models/RpcBlock.cs @@ -13,7 +13,7 @@ public class RpcBlock public JObject ToJson() { - JObject json = Block.ToJson(); + JObject json = Utility.BlockToJson(Block); json["confirmations"] = Confirmations; json["nextblockhash"] = NextBlockHash?.ToString(); return json; diff --git a/src/RpcClient/Models/RpcInvokeResult.cs b/src/RpcClient/Models/RpcInvokeResult.cs index e57310894..8ef6e50a6 100644 --- a/src/RpcClient/Models/RpcInvokeResult.cs +++ b/src/RpcClient/Models/RpcInvokeResult.cs @@ -1,8 +1,10 @@ using Neo.IO.Json; +using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; using System; using System.Linq; +using System.Numerics; namespace Neo.Network.RPC.Models { @@ -25,7 +27,7 @@ public JObject ToJson() JObject json = new JObject(); json["script"] = Script; json["state"] = State; - json["gasconsumed"] = GasConsumed; + json["gasconsumed"] = GasConsumed.ToString(); if (!string.IsNullOrEmpty(Exception)) json["exception"] = Exception; try diff --git a/src/RpcClient/Models/RpcTransaction.cs b/src/RpcClient/Models/RpcTransaction.cs index 74aae5566..2ccd2687b 100644 --- a/src/RpcClient/Models/RpcTransaction.cs +++ b/src/RpcClient/Models/RpcTransaction.cs @@ -18,7 +18,7 @@ public class RpcTransaction public JObject ToJson() { - JObject json = Transaction.ToJson(); + JObject json = Utility.TransactionToJson(Transaction); if (Confirmations != null) { json["blockhash"] = BlockHash.ToString(); diff --git a/src/RpcClient/TransactionManagerFactory.cs b/src/RpcClient/TransactionManagerFactory.cs index 0f7277a2c..92e50b310 100644 --- a/src/RpcClient/TransactionManagerFactory.cs +++ b/src/RpcClient/TransactionManagerFactory.cs @@ -1,5 +1,6 @@ using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; +using Neo.SmartContract.Native; using System; using System.Threading.Tasks; @@ -47,7 +48,7 @@ public async Task MakeTransactionAsync(byte[] script, Signer Script = script, Signers = signers ?? Array.Empty(), ValidUntilBlock = blockCount - 1 + Transaction.MaxValidUntilBlockIncrement, - SystemFee = long.Parse(invokeResult.GasConsumed), + SystemFee = (long)BigDecimal.Parse(invokeResult.GasConsumed.ToString(), NativeContract.GAS.Decimals).Value, Attributes = attributes ?? Array.Empty(), }; diff --git a/src/RpcClient/Utility.cs b/src/RpcClient/Utility.cs index dae537f2b..2da05a1b4 100644 --- a/src/RpcClient/Utility.cs +++ b/src/RpcClient/Utility.cs @@ -129,6 +129,13 @@ public static Block BlockFromJson(JObject json) return block; } + public static JObject BlockToJson(Block block) + { + JObject json = block.ToJson(); + json["tx"] = block.Transactions.Select(p => TransactionToJson(p)).ToArray(); + return json; + } + public static void FromJson(this BlockBase block, JObject json) { block.Version = (uint)json["version"].AsNumber(); @@ -147,8 +154,8 @@ public static Transaction TransactionFromJson(JObject json) Version = byte.Parse(json["version"].AsString()), Nonce = uint.Parse(json["nonce"].AsString()), Signers = ((JArray)json["signers"]).Select(p => SignerFromJson(p)).ToArray(), - SystemFee = long.Parse(json["sysfee"].AsString()), - NetworkFee = long.Parse(json["netfee"].AsString()), + SystemFee = (long)BigDecimal.Parse(json["sysfee"].AsString(), NativeContract.GAS.Decimals).Value, + NetworkFee = (long)BigDecimal.Parse(json["netfee"].AsString(), NativeContract.GAS.Decimals).Value, ValidUntilBlock = uint.Parse(json["validuntilblock"].AsString()), Attributes = ((JArray)json["attributes"]).Select(p => TransactionAttributeFromJson(p)).ToArray(), Script = Convert.FromBase64String(json["script"].AsString()), @@ -156,6 +163,14 @@ public static Transaction TransactionFromJson(JObject json) }; } + public static JObject TransactionToJson(Transaction tx) + { + JObject json = tx.ToJson(); + json["sysfee"] = new BigDecimal(tx.SystemFee, NativeContract.GAS.Decimals).ToString(); + json["netfee"] = new BigDecimal(tx.NetworkFee, NativeContract.GAS.Decimals).ToString(); + return json; + } + public static Header HeaderFromJson(JObject json) { Header header = new Header(); diff --git a/src/RpcServer/RpcServer.Blockchain.cs b/src/RpcServer/RpcServer.Blockchain.cs index 4ef57fc18..137d484e4 100644 --- a/src/RpcServer/RpcServer.Blockchain.cs +++ b/src/RpcServer/RpcServer.Blockchain.cs @@ -41,7 +41,7 @@ protected virtual JObject GetBlock(JArray _params) throw new RpcException(-100, "Unknown block"); if (verbose) { - JObject json = block.ToJson(); + JObject json = Utility.BlockToJson(block); json["confirmations"] = Blockchain.Singleton.Height - block.Index + 1; UInt256 hash = Blockchain.Singleton.GetNextBlockHash(block.Hash); if (hash != null) @@ -103,11 +103,22 @@ protected virtual JObject GetBlockHeader(JArray _params) [RpcMethod] protected virtual JObject GetContractState(JArray _params) { - UInt160 script_hash = UInt160.Parse(_params[0].AsString()); + UInt160 script_hash = ToScriptHash(_params[0].AsString()); ContractState contract = Blockchain.Singleton.View.Contracts.TryGet(script_hash); return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"); } + private static UInt160 ToScriptHash(string keyword) + { + foreach (var native in NativeContract.Contracts) + { + if (keyword.Equals(native.Name, StringComparison.InvariantCultureIgnoreCase) || keyword == native.Id.ToString()) + return native.Hash; + } + + return UInt160.Parse(keyword); + } + [RpcMethod] protected virtual JObject GetRawMemPool(JArray _params) { @@ -135,7 +146,7 @@ protected virtual JObject GetRawTransaction(JArray _params) throw new RpcException(-100, "Unknown transaction"); if (verbose) { - JObject json = tx.ToJson(); + JObject json = Utility.TransactionToJson(tx); TransactionState txState = Blockchain.Singleton.View.Transactions.TryGet(hash); if (txState != null) { diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 4fed465ad..a48ede69a 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -73,7 +73,7 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) JObject json = new JObject(); json["script"] = Convert.ToBase64String(script); json["state"] = engine.State; - json["gasconsumed"] = engine.GasConsumed.ToString(); + json["gasconsumed"] = new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals).ToString(); json["exception"] = GetExceptionMessage(engine.FaultException); try { diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 2256c0a6d..214df1bee 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -332,7 +332,7 @@ private JObject SignAndRelay(Transaction tx) { tx.Witnesses = context.GetWitnesses(); system.Blockchain.Tell(tx); - return tx.ToJson(); + return Utility.TransactionToJson(tx); } else { diff --git a/src/RpcServer/RpcServer.cs b/src/RpcServer/RpcServer.cs index a17d51d22..b20a22caf 100644 --- a/src/RpcServer/RpcServer.cs +++ b/src/RpcServer/RpcServer.cs @@ -107,7 +107,7 @@ public void StartRpcServer() { if (err != SslPolicyErrors.None) return false; - X509Certificate2 authority = chain.ChainElements[chain.ChainElements.Count - 1].Certificate; + X509Certificate2 authority = chain.ChainElements[^1].Certificate; return settings.TrustedAuthorities.Contains(authority.Thumbprint); }; }); diff --git a/src/RpcServer/Utility.cs b/src/RpcServer/Utility.cs new file mode 100644 index 000000000..0ac336351 --- /dev/null +++ b/src/RpcServer/Utility.cs @@ -0,0 +1,28 @@ +using Neo.IO.Json; +using Neo.Network.P2P.Payloads; +using Neo.SmartContract.Native; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Neo.Plugins +{ + public static class Utility + { + public static JObject BlockToJson(Block block) + { + JObject json = block.ToJson(); + json["tx"] = block.Transactions.Select(p => TransactionToJson(p)).ToArray(); + return json; + } + + public static JObject TransactionToJson(Transaction tx) + { + JObject json = tx.ToJson(); + json["sysfee"] = new BigDecimal(tx.SystemFee, NativeContract.GAS.Decimals).ToString(); + json["netfee"] = new BigDecimal(tx.NetworkFee, NativeContract.GAS.Decimals).ToString(); + return json; + } + } +} diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 5de1433b6..8833fed6b 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -96,8 +96,8 @@ "version": 0, "nonce": 631973574, "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2", - "sysfee": "9007990", - "netfee": "1248450", + "sysfee": "0.0900799", + "netfee": "0.0124845", "validuntilblock": 2102405, "signers": [ { @@ -157,8 +157,8 @@ "version": 0, "nonce": 631973574, "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2", - "sysfee": "9007990", - "netfee": "1248450", + "sysfee": "0.0900799", + "netfee": "0.0124845", "validuntilblock": 2102405, "signers": [ { @@ -520,8 +520,8 @@ "version": 0, "nonce": 969006668, "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2", - "sysfee": "100000000", - "netfee": "1272390", + "sysfee": "1", + "netfee": "0.0127239", "validuntilblock": 2104625, "signers": [ { @@ -731,7 +731,7 @@ "result": { "script": "0c1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89111c00c0962616c616e63654f660c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b52", "state": "HALT", - "gasconsumed": "2007570", + "gasconsumed": "0.0200757", "stack": [ { "type": "Integer", @@ -756,7 +756,7 @@ "result": { "script": "EMMMBG5hbWUMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1IQwwwGc3ltYm9sDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMC3RvdGFsU3VwcGx5DBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS", "state": "HALT", - "gasconsumed": "5061560", + "gasconsumed": "0.0506156", "stack": [ { "type": "Array", @@ -942,7 +942,7 @@ "result": { "script": "EMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS", "state": "HALT", - "gasconsumed": "5061560", + "gasconsumed": "0.0506156", "stack": [ { "type": "Integer", @@ -1074,8 +1074,8 @@ "version": 0, "nonce": 1553700339, "sender": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", - "sysfee": "100000000", - "netfee": "1272390", + "sysfee": "1", + "netfee": "0.0127239", "validuntilblock": 2105487, "attributes": [], "cosigners": [ @@ -1125,8 +1125,8 @@ "version": 0, "nonce": 34429660, "sender": "NUMK37TV9yYKbJr1Gufh74nZiM623eBLqX", - "sysfee": "100000000", - "netfee": "2483780", + "sysfee": "1", + "netfee": "0.0248378", "validuntilblock": 2105494, "attributes": [], "cosigners": [ @@ -1170,8 +1170,8 @@ "version": 0, "nonce": 330056065, "sender": "NUMK37TV9yYKbJr1Gufh74nZiM623eBLqX", - "sysfee": "100000000", - "netfee": "2381780", + "sysfee": "1", + "netfee": "0.0238178", "validuntilblock": 2105500, "attributes": [], "cosigners": [ @@ -1213,7 +1213,7 @@ { "trigger": "OnPersist", "vmstate": "HALT", - "gasconsumed": "2031260", + "gasconsumed": "0.0203126", "stack": [], "notifications": [ { @@ -1261,7 +1261,7 @@ { "trigger": "PostPersist", "vmstate": "HALT", - "gasconsumed": "2031260", + "gasconsumed": "0.0203126", "stack": [], "notifications": [ { @@ -1307,7 +1307,7 @@ { "trigger": "OnPersist", "vmstate": "HALT", - "gasconsumed": "2031260", + "gasconsumed": "0.0203126", "stack": [], "notifications": [ { diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index 32744c2e2..bc740fd1c 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -164,7 +164,7 @@ await txManager Assert.IsTrue(Crypto.VerifySignature(tx.GetHashData(), signature, keyPair1.PublicKey)); // verify network fee and system fee Assert.AreEqual(100000000/*Mock*/, tx.NetworkFee); - Assert.AreEqual(100, tx.SystemFee); + Assert.AreEqual(10000000000, tx.SystemFee); // duplicate sign should not add new witness await txManager.AddSignature(keyPair1).SignAsync(); From c7d19614491ffc0953ddf247fae0514c3dbbee53 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Fri, 27 Nov 2020 15:26:35 +0800 Subject: [PATCH 13/24] MPT in StateService from core (#410) --- neo-modules.sln | 16 +- src/StateService/MPT/BranchNode.cs | 35 ++ src/StateService/MPT/ExtensionNode.cs | 30 ++ src/StateService/MPT/HashNode.cs | 41 +++ src/StateService/MPT/LeafNode.cs | 36 ++ src/StateService/MPT/MPTNode.cs | 62 ++++ src/StateService/MPT/MPTNodeType.cs | 16 + src/StateService/MPT/MPTTrie.Delete.cs | 120 +++++++ src/StateService/MPT/MPTTrie.Find.cs | 110 ++++++ src/StateService/MPT/MPTTrie.Get.cs | 61 ++++ src/StateService/MPT/MPTTrie.Proof.cs | 73 ++++ src/StateService/MPT/MPTTrie.Put.cs | 158 +++++++++ src/StateService/MPT/MPTTrie.cs | 58 ++++ src/StateService/StateService.csproj | 9 + .../MPT/UT_MPTNode.cs | 30 ++ .../MPT/UT_MPTTrie.cs | 320 ++++++++++++++++++ .../Neo.Plugins.StateService.Tests.csproj | 16 + 17 files changed, 1190 insertions(+), 1 deletion(-) create mode 100644 src/StateService/MPT/BranchNode.cs create mode 100644 src/StateService/MPT/ExtensionNode.cs create mode 100644 src/StateService/MPT/HashNode.cs create mode 100644 src/StateService/MPT/LeafNode.cs create mode 100644 src/StateService/MPT/MPTNode.cs create mode 100644 src/StateService/MPT/MPTNodeType.cs create mode 100644 src/StateService/MPT/MPTTrie.Delete.cs create mode 100644 src/StateService/MPT/MPTTrie.Find.cs create mode 100644 src/StateService/MPT/MPTTrie.Get.cs create mode 100644 src/StateService/MPT/MPTTrie.Proof.cs create mode 100644 src/StateService/MPT/MPTTrie.Put.cs create mode 100644 src/StateService/MPT/MPTTrie.cs create mode 100644 src/StateService/StateService.csproj create mode 100644 tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTNode.cs create mode 100644 tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs create mode 100644 tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj diff --git a/neo-modules.sln b/neo-modules.sln index 763a89627..24f303eb4 100644 --- a/neo-modules.sln +++ b/neo-modules.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28729.10 MinimumVisualStudioVersion = 10.0.40219.1 @@ -24,6 +24,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Network.RPC.Tests", "te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Plugins.Storage.Tests", "tests\Neo.Plugins.Storage.Tests\Neo.Plugins.Storage.Tests.csproj", "{9E7EA895-302A-4C0C-BA9B-54F9A67AD75C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StateService", "src\StateService\StateService.csproj", "{A0F4A66F-6F87-4B99-B8BE-A779BC002F47}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.StateService.Tests", "tests\Neo.Plugins.StateService.Tests\Neo.Plugins.StateService.Tests.csproj", "{149822EC-4E0C-425F-A032-4196B615BFEB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -66,6 +70,14 @@ Global {9E7EA895-302A-4C0C-BA9B-54F9A67AD75C}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E7EA895-302A-4C0C-BA9B-54F9A67AD75C}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E7EA895-302A-4C0C-BA9B-54F9A67AD75C}.Release|Any CPU.Build.0 = Release|Any CPU + {A0F4A66F-6F87-4B99-B8BE-A779BC002F47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A0F4A66F-6F87-4B99-B8BE-A779BC002F47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A0F4A66F-6F87-4B99-B8BE-A779BC002F47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A0F4A66F-6F87-4B99-B8BE-A779BC002F47}.Release|Any CPU.Build.0 = Release|Any CPU + {149822EC-4E0C-425F-A032-4196B615BFEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {149822EC-4E0C-425F-A032-4196B615BFEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {149822EC-4E0C-425F-A032-4196B615BFEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {149822EC-4E0C-425F-A032-4196B615BFEB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -80,6 +92,8 @@ Global {1403FFE9-4265-4269-8E3D-5A79EFD108CA} = {97E81C78-1637-481F-9485-DA1225E94C23} {D52460B3-AB5C-4D07-B400-9E7ADCB01FF5} = {59D802AB-C552-422A-B9C3-64D329FBCDCC} {9E7EA895-302A-4C0C-BA9B-54F9A67AD75C} = {59D802AB-C552-422A-B9C3-64D329FBCDCC} + {A0F4A66F-6F87-4B99-B8BE-A779BC002F47} = {97E81C78-1637-481F-9485-DA1225E94C23} + {149822EC-4E0C-425F-A032-4196B615BFEB} = {59D802AB-C552-422A-B9C3-64D329FBCDCC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {61D3ADE6-BBFC-402D-AB42-1C71C9F9EDE3} diff --git a/src/StateService/MPT/BranchNode.cs b/src/StateService/MPT/BranchNode.cs new file mode 100644 index 000000000..f729412b5 --- /dev/null +++ b/src/StateService/MPT/BranchNode.cs @@ -0,0 +1,35 @@ +using System.IO; + +namespace Neo.Plugins.MPT +{ + public class BranchNode : MPTNode + { + public const int ChildCount = 17; + public readonly MPTNode[] Children = new MPTNode[ChildCount]; + + protected override NodeType Type => NodeType.BranchNode; + + public BranchNode() + { + for (int i = 0; i < ChildCount; i++) + { + Children[i] = HashNode.EmptyNode; + } + } + + internal override void EncodeSpecific(BinaryWriter writer) + { + for (int i = 0; i < ChildCount; i++) + WriteHash(writer, Children[i].Hash); + } + + internal override void DecodeSpecific(BinaryReader reader) + { + for (int i = 0; i < ChildCount; i++) + { + Children[i] = new HashNode(); + Children[i].DecodeSpecific(reader); + } + } + } +} diff --git a/src/StateService/MPT/ExtensionNode.cs b/src/StateService/MPT/ExtensionNode.cs new file mode 100644 index 000000000..00f107240 --- /dev/null +++ b/src/StateService/MPT/ExtensionNode.cs @@ -0,0 +1,30 @@ +using Neo.IO; +using Neo.SmartContract; +using System.IO; + +namespace Neo.Plugins.MPT +{ + public class ExtensionNode : MPTNode + { + //max lenght when store StorageKey + public const int MaxKeyLength = (ApplicationEngine.MaxStorageValueSize + sizeof(int)) * 2; + + public byte[] Key; + public MPTNode Next; + + protected override NodeType Type => NodeType.ExtensionNode; + + internal override void EncodeSpecific(BinaryWriter writer) + { + writer.WriteVarBytes(Key); + WriteHash(writer, Next.Hash); + } + + internal override void DecodeSpecific(BinaryReader reader) + { + Key = reader.ReadVarBytes(MaxKeyLength); + Next = new HashNode(); + Next.DecodeSpecific(reader); + } + } +} diff --git a/src/StateService/MPT/HashNode.cs b/src/StateService/MPT/HashNode.cs new file mode 100644 index 000000000..7053f0a3b --- /dev/null +++ b/src/StateService/MPT/HashNode.cs @@ -0,0 +1,41 @@ +using Neo.IO; +using System; +using System.IO; + +namespace Neo.Plugins.MPT +{ + public class HashNode : MPTNode + { + private UInt256 hash; + + public override UInt256 Hash => hash; + protected override NodeType Type => NodeType.HashNode; + public bool IsEmpty => Hash is null; + public static HashNode EmptyNode { get; } = new HashNode(); + + public HashNode() + { + } + + public HashNode(UInt256 hash) + { + this.hash = hash; + } + + internal override void EncodeSpecific(BinaryWriter writer) + { + WriteHash(writer, hash); + } + + internal override void DecodeSpecific(BinaryReader reader) + { + byte[] buffer = reader.ReadVarBytes(UInt256.Length); + hash = buffer.Length switch + { + 0 => null, + UInt256.Length => new UInt256(buffer), + _ => throw new FormatException() + }; + } + } +} diff --git a/src/StateService/MPT/LeafNode.cs b/src/StateService/MPT/LeafNode.cs new file mode 100644 index 000000000..2a17ef4e2 --- /dev/null +++ b/src/StateService/MPT/LeafNode.cs @@ -0,0 +1,36 @@ +using Neo.IO; +using Neo.SmartContract; +using System; +using System.IO; + +namespace Neo.Plugins.MPT +{ + public class LeafNode : MPTNode + { + //the max size when store StorageItem + public const int MaxValueLength = 3 + ApplicationEngine.MaxStorageValueSize + sizeof(bool); + + public byte[] Value; + + protected override NodeType Type => NodeType.LeafNode; + + public LeafNode() + { + } + + public LeafNode(ReadOnlySpan value) + { + Value = value.ToArray(); + } + + internal override void EncodeSpecific(BinaryWriter writer) + { + writer.WriteVarBytes(Value); + } + + internal override void DecodeSpecific(BinaryReader reader) + { + Value = reader.ReadVarBytes(MaxValueLength); + } + } +} diff --git a/src/StateService/MPT/MPTNode.cs b/src/StateService/MPT/MPTNode.cs new file mode 100644 index 000000000..197031cdf --- /dev/null +++ b/src/StateService/MPT/MPTNode.cs @@ -0,0 +1,62 @@ +using Neo.Cryptography; +using Neo.IO; +using Neo.IO.Caching; +using System; +using System.IO; + +namespace Neo.Plugins.MPT +{ + public abstract class MPTNode + { + private UInt256 hash; + + public virtual UInt256 Hash => hash ??= new UInt256(Crypto.Hash256(Encode())); + protected abstract NodeType Type { get; } + + public void SetDirty() + { + hash = null; + } + + public byte[] Encode() + { + using MemoryStream ms = new MemoryStream(); + using BinaryWriter writer = new BinaryWriter(ms); + + writer.Write((byte)Type); + EncodeSpecific(writer); + writer.Flush(); + + return ms.ToArray(); + } + + internal abstract void EncodeSpecific(BinaryWriter writer); + + public static unsafe MPTNode Decode(ReadOnlySpan data) + { + if (data.IsEmpty) return null; + + fixed (byte* pointer = data) + { + using UnmanagedMemoryStream stream = new UnmanagedMemoryStream(pointer, data.Length); + using BinaryReader reader = new BinaryReader(stream); + + MPTNode n = (MPTNode)ReflectionCache.CreateInstance((NodeType)reader.ReadByte()); + if (n is null) throw new InvalidOperationException(); + + n.DecodeSpecific(reader); + return n; + } + } + + internal abstract void DecodeSpecific(BinaryReader reader); + + protected void WriteHash(BinaryWriter writer, UInt256 hash) + { + if (hash is null) + writer.Write((byte)0); + else + writer.WriteVarBytes(hash.ToArray()); + } + } +} diff --git a/src/StateService/MPT/MPTNodeType.cs b/src/StateService/MPT/MPTNodeType.cs new file mode 100644 index 000000000..05370a645 --- /dev/null +++ b/src/StateService/MPT/MPTNodeType.cs @@ -0,0 +1,16 @@ +using Neo.IO.Caching; + +namespace Neo.Plugins.MPT +{ + public enum NodeType : byte + { + [ReflectionCache(typeof(BranchNode))] + BranchNode = 0x00, + [ReflectionCache(typeof(ExtensionNode))] + ExtensionNode = 0x01, + [ReflectionCache(typeof(HashNode))] + HashNode = 0x02, + [ReflectionCache(typeof(LeafNode))] + LeafNode = 0x03, + } +} diff --git a/src/StateService/MPT/MPTTrie.Delete.cs b/src/StateService/MPT/MPTTrie.Delete.cs new file mode 100644 index 000000000..0470c2393 --- /dev/null +++ b/src/StateService/MPT/MPTTrie.Delete.cs @@ -0,0 +1,120 @@ +using Neo.IO; +using System; +using System.Collections.Generic; +using static Neo.Helper; + +namespace Neo.Plugins.MPT +{ + partial class MPTTrie + { + public bool Delete(TKey key) + { + var path = ToNibbles(key.ToArray()); + if (path.Length == 0) return false; + return TryDelete(ref root, path); + } + + private bool TryDelete(ref MPTNode node, ReadOnlySpan path) + { + switch (node) + { + case LeafNode _: + { + if (path.IsEmpty) + { + node = HashNode.EmptyNode; + return true; + } + return false; + } + case ExtensionNode extensionNode: + { + if (path.StartsWith(extensionNode.Key)) + { + var result = TryDelete(ref extensionNode.Next, path[extensionNode.Key.Length..]); + if (!result) return false; + if (extensionNode.Next is HashNode hashNode && hashNode.IsEmpty) + { + node = extensionNode.Next; + return true; + } + if (extensionNode.Next is ExtensionNode sn) + { + extensionNode.Key = Concat(extensionNode.Key, sn.Key); + extensionNode.Next = sn.Next; + } + extensionNode.SetDirty(); + PutToStore(extensionNode); + return true; + } + return false; + } + case BranchNode branchNode: + { + bool result; + if (path.IsEmpty) + { + result = TryDelete(ref branchNode.Children[BranchNode.ChildCount - 1], path); + } + else + { + result = TryDelete(ref branchNode.Children[path[0]], path[1..]); + } + if (!result) return false; + List childrenIndexes = new List(BranchNode.ChildCount); + for (int i = 0; i < BranchNode.ChildCount; i++) + { + if (branchNode.Children[i] is HashNode hn && hn.IsEmpty) continue; + childrenIndexes.Add((byte)i); + } + if (childrenIndexes.Count > 1) + { + branchNode.SetDirty(); + PutToStore(branchNode); + return true; + } + var lastChildIndex = childrenIndexes[0]; + var lastChild = branchNode.Children[lastChildIndex]; + if (lastChildIndex == BranchNode.ChildCount - 1) + { + node = lastChild; + return true; + } + if (lastChild is HashNode hashNode) + { + lastChild = Resolve(hashNode); + if (lastChild is null) return false; + } + if (lastChild is ExtensionNode exNode) + { + exNode.Key = Concat(childrenIndexes.ToArray(), exNode.Key); + exNode.SetDirty(); + PutToStore(exNode); + node = exNode; + return true; + } + node = new ExtensionNode() + { + Key = childrenIndexes.ToArray(), + Next = lastChild, + }; + PutToStore(node); + return true; + } + case HashNode hashNode: + { + if (hashNode.IsEmpty) + { + return true; + } + var newNode = Resolve(hashNode); + if (newNode is null) return false; + node = newNode; + return TryDelete(ref node, path); + } + default: + return false; + } + } + } +} diff --git a/src/StateService/MPT/MPTTrie.Find.cs b/src/StateService/MPT/MPTTrie.Find.cs new file mode 100644 index 000000000..6d072fd60 --- /dev/null +++ b/src/StateService/MPT/MPTTrie.Find.cs @@ -0,0 +1,110 @@ +using Neo.IO; +using System; +using System.Collections.Generic; +using System.Linq; +using static Neo.Helper; + +namespace Neo.Plugins.MPT +{ + partial class MPTTrie + { + private ReadOnlySpan Seek(ref MPTNode node, ReadOnlySpan path, out MPTNode start) + { + switch (node) + { + case LeafNode leafNode: + { + if (path.IsEmpty) + { + start = leafNode; + return ReadOnlySpan.Empty; + } + break; + } + case HashNode hashNode: + { + if (hashNode.IsEmpty) break; + var newNode = Resolve(hashNode); + if (newNode is null) break; + node = newNode; + return Seek(ref node, path, out start); + } + case BranchNode branchNode: + { + if (path.IsEmpty) + { + start = branchNode; + return ReadOnlySpan.Empty; + } + return Concat(path[..1], Seek(ref branchNode.Children[path[0]], path[1..], out start)); + } + case ExtensionNode extensionNode: + { + if (path.IsEmpty) + { + start = extensionNode.Next; + return extensionNode.Key; + } + if (path.StartsWith(extensionNode.Key)) + { + return Concat(extensionNode.Key, Seek(ref extensionNode.Next, path[extensionNode.Key.Length..], out start)); + } + if (extensionNode.Key.AsSpan().StartsWith(path)) + { + start = extensionNode.Next; + return extensionNode.Key; + } + break; + } + } + start = null; + return ReadOnlySpan.Empty; + } + + public IEnumerable<(TKey Key, TValue Value)> Find(ReadOnlySpan prefix) + { + var path = ToNibbles(prefix); + path = Seek(ref root, path, out MPTNode start).ToArray(); + return Travers(start, path) + .Select(p => (FromNibbles(p.Key).AsSerializable(), p.Value.AsSerializable())); + } + + private IEnumerable<(byte[] Key, byte[] Value)> Travers(MPTNode node, byte[] path) + { + if (node is null) yield break; + switch (node) + { + case LeafNode leafNode: + { + yield return (path, (byte[])leafNode.Value.Clone()); + break; + } + case HashNode hashNode: + { + if (hashNode.IsEmpty) break; + var newNode = Resolve(hashNode); + if (newNode is null) break; + node = newNode; + foreach (var item in Travers(node, path)) + yield return item; + break; + } + case BranchNode branchNode: + { + for (int i = 0; i < BranchNode.ChildCount; i++) + { + foreach (var item in Travers(branchNode.Children[i], i == BranchNode.ChildCount - 1 ? path : Concat(path, new byte[] { (byte)i }))) + yield return item; + } + break; + } + case ExtensionNode extensionNode: + { + foreach (var item in Travers(extensionNode.Next, Concat(path, extensionNode.Key))) + yield return item; + break; + } + } + } + } +} diff --git a/src/StateService/MPT/MPTTrie.Get.cs b/src/StateService/MPT/MPTTrie.Get.cs new file mode 100644 index 000000000..49dc6ed5d --- /dev/null +++ b/src/StateService/MPT/MPTTrie.Get.cs @@ -0,0 +1,61 @@ +using Neo.IO; +using System; + +namespace Neo.Plugins.MPT +{ + partial class MPTTrie + { + public TValue this[TKey key] + { + get + { + var path = ToNibbles(key.ToArray()); + if (path.Length == 0) return null; + var result = TryGet(ref root, path, out var value); + return result ? value.AsSerializable() : null; + } + } + + private bool TryGet(ref MPTNode node, ReadOnlySpan path, out ReadOnlySpan value) + { + switch (node) + { + case LeafNode leafNode: + { + if (path.IsEmpty) + { + value = leafNode.Value; + return true; + } + break; + } + case HashNode hashNode: + { + if (hashNode.IsEmpty) break; + var newNode = Resolve(hashNode); + if (newNode is null) break; + node = newNode; + return TryGet(ref node, path, out value); + } + case BranchNode branchNode: + { + if (path.IsEmpty) + { + return TryGet(ref branchNode.Children[BranchNode.ChildCount - 1], path, out value); + } + return TryGet(ref branchNode.Children[path[0]], path[1..], out value); + } + case ExtensionNode extensionNode: + { + if (path.StartsWith(extensionNode.Key)) + { + return TryGet(ref extensionNode.Next, path[extensionNode.Key.Length..], out value); + } + break; + } + } + value = default; + return false; + } + } +} diff --git a/src/StateService/MPT/MPTTrie.Proof.cs b/src/StateService/MPT/MPTTrie.Proof.cs new file mode 100644 index 000000000..f6e194bf8 --- /dev/null +++ b/src/StateService/MPT/MPTTrie.Proof.cs @@ -0,0 +1,73 @@ +using Neo.Cryptography; +using Neo.IO; +using Neo.Persistence; +using System; +using System.Collections.Generic; + +namespace Neo.Plugins.MPT +{ + partial class MPTTrie + { + public HashSet GetProof(TKey key) + { + var path = ToNibbles(key.ToArray()); + if (path.Length == 0) return null; + HashSet set = new HashSet(ByteArrayEqualityComparer.Default); + if (!GetProof(ref root, path, set)) return null; + return set; + } + + private bool GetProof(ref MPTNode node, ReadOnlySpan path, HashSet set) + { + switch (node) + { + case LeafNode leafNode: + { + if (path.IsEmpty) + { + set.Add(leafNode.Encode()); + return true; + } + break; + } + case HashNode hashNode: + { + if (hashNode.IsEmpty) break; + var newNode = Resolve(hashNode); + if (newNode is null) break; + node = newNode; + return GetProof(ref node, path, set); + } + case BranchNode branchNode: + { + set.Add(branchNode.Encode()); + if (path.IsEmpty) + { + return GetProof(ref branchNode.Children[BranchNode.ChildCount - 1], path, set); + } + return GetProof(ref branchNode.Children[path[0]], path[1..], set); + } + case ExtensionNode extensionNode: + { + if (path.StartsWith(extensionNode.Key)) + { + set.Add(extensionNode.Encode()); + return GetProof(ref extensionNode.Next, path[extensionNode.Key.Length..], set); + } + break; + } + } + return false; + } + + public static TValue VerifyProof(UInt256 root, TKey key, HashSet proof) + { + using var memoryStore = new MemoryStore(); + foreach (byte[] data in proof) + memoryStore.Put(Prefix, Crypto.Hash256(data), data); + using ISnapshot snapshot = memoryStore.GetSnapshot(); + var trie = new MPTTrie(snapshot, root); + return trie[key]; + } + } +} diff --git a/src/StateService/MPT/MPTTrie.Put.cs b/src/StateService/MPT/MPTTrie.Put.cs new file mode 100644 index 000000000..9ddaed16a --- /dev/null +++ b/src/StateService/MPT/MPTTrie.Put.cs @@ -0,0 +1,158 @@ +using Neo.IO; +using System; + +namespace Neo.Plugins.MPT +{ + partial class MPTTrie + { + private static ReadOnlySpan CommonPrefix(ReadOnlySpan a, ReadOnlySpan b) + { + var minLen = a.Length <= b.Length ? a.Length : b.Length; + int i = 0; + if (a.Length != 0 && b.Length != 0) + { + for (i = 0; i < minLen; i++) + { + if (a[i] != b[i]) break; + } + } + return a[..i]; + } + + public bool Put(TKey key, TValue value) + { + var path = ToNibbles(key.ToArray()); + var val = value.ToArray(); + if (path.Length == 0 || path.Length > ExtensionNode.MaxKeyLength) + return false; + if (val.Length > LeafNode.MaxValueLength) + return false; + if (val.Length == 0) + return TryDelete(ref root, path); + var n = new LeafNode(val); + return Put(ref root, path, n); + } + + private bool Put(ref MPTNode node, ReadOnlySpan path, MPTNode val) + { + switch (node) + { + case LeafNode leafNode: + { + if (val is LeafNode v) + { + if (path.IsEmpty) + { + node = v; + PutToStore(node); + return true; + } + var branch = new BranchNode(); + branch.Children[BranchNode.ChildCount - 1] = leafNode; + Put(ref branch.Children[path[0]], path[1..], v); + PutToStore(branch); + node = branch; + return true; + } + return false; + } + case ExtensionNode extensionNode: + { + if (path.StartsWith(extensionNode.Key)) + { + var result = Put(ref extensionNode.Next, path[extensionNode.Key.Length..], val); + if (result) + { + extensionNode.SetDirty(); + PutToStore(extensionNode); + } + return result; + } + var prefix = CommonPrefix(extensionNode.Key, path); + var pathRemain = path[prefix.Length..]; + var keyRemain = extensionNode.Key.AsSpan(prefix.Length); + var son = new BranchNode(); + MPTNode grandSon1 = HashNode.EmptyNode; + MPTNode grandSon2 = HashNode.EmptyNode; + + Put(ref grandSon1, keyRemain[1..], extensionNode.Next); + son.Children[keyRemain[0]] = grandSon1; + + if (pathRemain.IsEmpty) + { + Put(ref grandSon2, pathRemain, val); + son.Children[BranchNode.ChildCount - 1] = grandSon2; + } + else + { + Put(ref grandSon2, pathRemain[1..], val); + son.Children[pathRemain[0]] = grandSon2; + } + PutToStore(son); + if (prefix.Length > 0) + { + var exNode = new ExtensionNode() + { + Key = prefix.ToArray(), + Next = son, + }; + PutToStore(exNode); + node = exNode; + } + else + { + node = son; + } + return true; + } + case BranchNode branchNode: + { + bool result; + if (path.IsEmpty) + { + result = Put(ref branchNode.Children[BranchNode.ChildCount - 1], path, val); + } + else + { + result = Put(ref branchNode.Children[path[0]], path[1..], val); + } + if (result) + { + branchNode.SetDirty(); + PutToStore(branchNode); + } + return result; + } + case HashNode hashNode: + { + MPTNode newNode; + if (hashNode.IsEmpty) + { + if (path.IsEmpty) + { + newNode = val; + } + else + { + newNode = new ExtensionNode() + { + Key = path.ToArray(), + Next = val, + }; + PutToStore(newNode); + } + node = newNode; + if (val is LeafNode) PutToStore(val); + return true; + } + newNode = Resolve(hashNode); + if (newNode is null) return false; + node = newNode; + return Put(ref node, path, val); + } + default: + return false; + } + } + } +} diff --git a/src/StateService/MPT/MPTTrie.cs b/src/StateService/MPT/MPTTrie.cs new file mode 100644 index 000000000..c77bc746e --- /dev/null +++ b/src/StateService/MPT/MPTTrie.cs @@ -0,0 +1,58 @@ +using Neo.IO; +using Neo.Persistence; +using System; + +namespace Neo.Plugins.MPT +{ + public partial class MPTTrie + where TKey : notnull, ISerializable, new() + where TValue : class, ISerializable, new() + { + private const byte Prefix = 0xf0; + + private readonly ISnapshot store; + private MPTNode root; + + public MPTNode Root => root; + + public MPTTrie(ISnapshot store, UInt256 root) + { + this.store = store ?? throw new ArgumentNullException(); + this.root = root is null ? HashNode.EmptyNode : new HashNode(root); + } + + private MPTNode Resolve(HashNode n) + { + var data = store.TryGet(Prefix, n.Hash.ToArray()); + return MPTNode.Decode(data); + } + + private static byte[] ToNibbles(ReadOnlySpan path) + { + var result = new byte[path.Length * 2]; + for (int i = 0; i < path.Length; i++) + { + result[i * 2] = (byte)(path[i] >> 4); + result[i * 2 + 1] = (byte)(path[i] & 0x0F); + } + return result; + } + + private static byte[] FromNibbles(ReadOnlySpan path) + { + if (path.Length % 2 != 0) throw new FormatException($"MPTTrie.FromNibbles invalid path."); + var key = new byte[path.Length / 2]; + for (int i = 0; i < key.Length; i++) + { + key[i] = (byte)(path[i * 2] << 4); + key[i] |= path[i * 2 + 1]; + } + return key; + } + + private void PutToStore(MPTNode node) + { + store.Put(Prefix, node.Hash.ToArray(), node.Encode()); + } + } +} diff --git a/src/StateService/StateService.csproj b/src/StateService/StateService.csproj new file mode 100644 index 000000000..24ea71663 --- /dev/null +++ b/src/StateService/StateService.csproj @@ -0,0 +1,9 @@ + + + + Neo.Plugins.StateService + Neo.Plugins + true + + + diff --git a/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTNode.cs b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTNode.cs new file mode 100644 index 000000000..a26325470 --- /dev/null +++ b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTNode.cs @@ -0,0 +1,30 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Cryptography.MPT; +using System.Text; + +namespace Neo.Plugins.StateService.Tests.MPT +{ + [TestClass] + public class UT_MPTNode + { + [TestMethod] + public void TestDecode() + { + var n = new LeafNode + { + Value = Encoding.ASCII.GetBytes("hello") + }; + var code = n.Encode(); + var m = MPTNode.Decode(code); + Assert.IsInstanceOfType(m, n.GetType()); + } + + [TestMethod] + public void TestHashNode() + { + var hn = new HashNode(null); + var data = hn.Encode(); + Assert.AreEqual("0200", data.ToHexString()); + } + } +} diff --git a/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs new file mode 100644 index 000000000..31ec30b5d --- /dev/null +++ b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs @@ -0,0 +1,320 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Cryptography.MPT; +using Neo.IO; +using Neo.Persistence; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Neo.Plugins.StateService.Tests.MPT +{ + public class TestKey : ISerializable + { + private byte[] key; + + public int Size => key.Length; + + public TestKey() + { + this.key = Array.Empty(); + } + + public TestKey(byte[] key) + { + this.key = key; + } + public void Serialize(BinaryWriter writer) + { + writer.Write(key); + } + + public void Deserialize(BinaryReader reader) + { + key = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); + } + + public override string ToString() + { + return key.ToHexString(); + } + + public static implicit operator TestKey(byte[] key) + { + return new TestKey(key); + } + } + + public class TestValue : ISerializable + { + private byte[] value; + + public int Size => value.Length; + + public TestValue() + { + this.value = Array.Empty(); + } + + public TestValue(byte[] value) + { + this.value = value; + } + + public void Serialize(BinaryWriter writer) + { + writer.Write(value); + } + + public void Deserialize(BinaryReader reader) + { + value = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); + } + + public override string ToString() + { + return value.ToHexString(); + } + + public static implicit operator TestValue(byte[] value) + { + return new TestValue(value); + } + } + + [TestClass] + public class UT_MPTTrie + { + private MPTNode root; + private IStore mptdb; + + private void PutToStore(MPTNode node) + { + mptdb.Put(0xf0, node.Hash.ToArray(), node.Encode()); + } + + [TestInitialize] + public void TestInit() + { + var b = new BranchNode(); + var r = new ExtensionNode { Key = "0a0c".HexToBytes(), Next = b }; + var v1 = new LeafNode { Value = "abcd".HexToBytes() }; + var v2 = new LeafNode { Value = "2222".HexToBytes() }; + var v3 = new LeafNode { Value = Encoding.ASCII.GetBytes("hello") }; + var h1 = new HashNode(v3.Hash); + var l1 = new ExtensionNode { Key = new byte[] { 0x01 }, Next = v1 }; + var l2 = new ExtensionNode { Key = new byte[] { 0x09 }, Next = v2 }; + var l3 = new ExtensionNode { Key = "0e".HexToBytes(), Next = h1 }; + b.Children[0] = l1; + b.Children[9] = l2; + b.Children[10] = l3; + this.root = r; + this.mptdb = new MemoryStore(); + PutToStore(r); + PutToStore(b); + PutToStore(l1); + PutToStore(l2); + PutToStore(l3); + PutToStore(v1); + PutToStore(v2); + PutToStore(v3); + } + + [TestMethod] + public void TestTryGet() + { + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + Assert.AreEqual("abcd", mpt["ac01".HexToBytes()].ToString()); + Assert.AreEqual("2222", mpt["ac99".HexToBytes()].ToString()); + Assert.IsNull(mpt["ab99".HexToBytes()]); + Assert.IsNull(mpt["ac39".HexToBytes()]); + Assert.IsNull(mpt["ac02".HexToBytes()]); + Assert.IsNull(mpt["ac9910".HexToBytes()]); + } + + [TestMethod] + public void TestTryGetResolve() + { + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + Assert.AreEqual(Encoding.ASCII.GetBytes("hello").ToHexString(), mpt["acae".HexToBytes()].ToString()); + } + + [TestMethod] + public void TestTryPut() + { + var store = new MemoryStore(); + var mpt = new MPTTrie(store.GetSnapshot(), null); + var result = mpt.Put("ac01".HexToBytes(), "abcd".HexToBytes()); + Assert.IsTrue(result); + result = mpt.Put("ac99".HexToBytes(), "2222".HexToBytes()); + Assert.IsTrue(result); + result = mpt.Put("acae".HexToBytes(), Encoding.ASCII.GetBytes("hello")); + Assert.IsTrue(result); + Assert.AreEqual(root.Hash.ToString(), mpt.Root.Hash.ToString()); + } + + [TestMethod] + public void TestTryDelete() + { + var b = new BranchNode(); + var r = new ExtensionNode { Key = "0a0c".HexToBytes(), Next = b }; + var v1 = new LeafNode { Value = "abcd".HexToBytes() }; + var v2 = new LeafNode { Value = "2222".HexToBytes() }; + var r1 = new ExtensionNode { Key = "0a0c0001".HexToBytes(), Next = v1 }; + var l1 = new ExtensionNode { Key = new byte[] { 0x01 }, Next = v1 }; + var l2 = new ExtensionNode { Key = new byte[] { 0x09 }, Next = v2 }; + b.Children[0] = l1; + b.Children[9] = l2; + + Assert.AreEqual("0xdea3ab46e9461e885ed7091c1e533e0a8030b248d39cbc638962394eaca0fbb3", r1.Hash.ToString()); + Assert.AreEqual("0x93e8e1ffe2f83dd92fca67330e273bcc811bf64b8f8d9d1b25d5e7366b47d60d", r.Hash.ToString()); + + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + Assert.IsNotNull(mpt["ac99".HexToBytes()]); + bool result = mpt.Delete("ac99".HexToBytes()); + Assert.IsTrue(result); + result = mpt.Delete("acae".HexToBytes()); + Assert.IsTrue(result); + Assert.AreEqual("0xdea3ab46e9461e885ed7091c1e533e0a8030b248d39cbc638962394eaca0fbb3", mpt.Root.Hash.ToString()); + } + + [TestMethod] + public void TestDeleteSameValue() + { + var store = new MemoryStore(); + var snapshot = store.GetSnapshot(); + var mpt = new MPTTrie(snapshot, null); + Assert.IsTrue(mpt.Put("ac01".HexToBytes(), "abcd".HexToBytes())); + Assert.IsTrue(mpt.Put("ac02".HexToBytes(), "abcd".HexToBytes())); + Assert.IsNotNull(mpt["ac01".HexToBytes()]); + Assert.IsNotNull(mpt["ac02".HexToBytes()]); + mpt.Delete("ac01".HexToBytes()); + Assert.IsNotNull(mpt["ac02".HexToBytes()]); + snapshot.Commit(); + + var mpt0 = new MPTTrie(store.GetSnapshot(), mpt.Root.Hash); + Assert.IsNotNull(mpt0["ac02".HexToBytes()]); + } + + [TestMethod] + public void TestBranchNodeRemainValue() + { + var store = new MemoryStore(); + var mpt = new MPTTrie(store.GetSnapshot(), null); + Assert.IsTrue(mpt.Put("ac11".HexToBytes(), "ac11".HexToBytes())); + Assert.IsTrue(mpt.Put("ac22".HexToBytes(), "ac22".HexToBytes())); + Assert.IsTrue(mpt.Put("ac".HexToBytes(), "ac".HexToBytes())); + Assert.IsTrue(mpt.Delete("ac11".HexToBytes())); + mpt.Delete("ac22".HexToBytes()); + Assert.IsNotNull(mpt["ac".HexToBytes()]); + } + + [TestMethod] + public void TestGetProof() + { + var b = new BranchNode(); + var r = new ExtensionNode { Key = "0a0c".HexToBytes(), Next = b }; + var v1 = new LeafNode { Value = "abcd".HexToBytes() }; + var v2 = new LeafNode { Value = "2222".HexToBytes() }; + var v3 = new LeafNode { Value = Encoding.ASCII.GetBytes("hello") }; + var h1 = new HashNode(v3.Hash); + var l1 = new ExtensionNode { Key = new byte[] { 0x01 }, Next = v1 }; + var l2 = new ExtensionNode { Key = new byte[] { 0x09 }, Next = v2 }; + var l3 = new ExtensionNode { Key = "0e".HexToBytes(), Next = h1 }; + b.Children[0] = l1; + b.Children[9] = l2; + b.Children[10] = l3; + + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + Assert.AreEqual(r.Hash.ToString(), mpt.Root.Hash.ToString()); + HashSet proof = mpt.GetProof("ac01".HexToBytes()); + Assert.AreEqual(4, proof.Count); + Assert.IsTrue(proof.Contains(b.Encode())); + Assert.IsTrue(proof.Contains(r.Encode())); + Assert.IsTrue(proof.Contains(l1.Encode())); + Assert.IsTrue(proof.Contains(v1.Encode())); + + proof = mpt.GetProof(Array.Empty()); + Assert.IsNull(proof); + } + + [TestMethod] + public void TestVerifyProof() + { + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + HashSet proof = mpt.GetProof("ac01".HexToBytes()); + TestValue value = MPTTrie.VerifyProof(root.Hash, "ac01".HexToBytes(), proof); + Assert.IsNotNull(value); + Assert.AreEqual(value.ToString(), "abcd"); + } + + [TestMethod] + public void TestAddLongerKey() + { + var store = new MemoryStore(); + var snapshot = store.GetSnapshot(); + var mpt = new MPTTrie(snapshot, null); + var result = mpt.Put(new byte[] { 0xab }, new byte[] { 0x01 }); + Assert.IsTrue(result); + result = mpt.Put(new byte[] { 0xab, 0xcd }, new byte[] { 0x02 }); + Assert.IsTrue(result); + } + + [TestMethod] + public void TestSplitKey() + { + var store = new MemoryStore(); + var snapshot = store.GetSnapshot(); + var mpt1 = new MPTTrie(snapshot, null); + Assert.IsTrue(mpt1.Put(new byte[] { 0xab, 0xcd }, new byte[] { 0x01 })); + Assert.IsTrue(mpt1.Put(new byte[] { 0xab }, new byte[] { 0x02 })); + HashSet set1 = mpt1.GetProof(new byte[] { 0xab, 0xcd }); + Assert.AreEqual(4, set1.Count); + var mpt2 = new MPTTrie(snapshot, null); + Assert.IsTrue(mpt2.Put(new byte[] { 0xab }, new byte[] { 0x02 })); + Assert.IsTrue(mpt2.Put(new byte[] { 0xab, 0xcd }, new byte[] { 0x01 })); + HashSet set2 = mpt2.GetProof(new byte[] { 0xab, 0xcd }); + Assert.AreEqual(4, set2.Count); + Assert.AreEqual(mpt1.Root.Hash, mpt2.Root.Hash); + } + + [TestMethod] + public void TestFind() + { + var store = new MemoryStore(); + var snapshot = store.GetSnapshot(); + var mpt1 = new MPTTrie(snapshot, null); + var results = mpt1.Find(ReadOnlySpan.Empty).ToArray(); + Assert.AreEqual(0, results.Count()); + var mpt2 = new MPTTrie(snapshot, null); + Assert.IsTrue(mpt2.Put(new byte[] { 0xab, 0xcd, 0xef }, new byte[] { 0x01 })); + Assert.IsTrue(mpt2.Put(new byte[] { 0xab, 0xcd, 0xe1 }, new byte[] { 0x02 })); + Assert.IsTrue(mpt2.Put(new byte[] { 0xab }, new byte[] { 0x03 })); + results = mpt2.Find(ReadOnlySpan.Empty).ToArray(); + Assert.AreEqual(3, results.Count()); + results = mpt2.Find(new byte[] { 0xab }).ToArray(); + Assert.AreEqual(3, results.Count()); + results = mpt2.Find(new byte[] { 0xab, 0xcd }).ToArray(); + Assert.AreEqual(2, results.Count()); + results = mpt2.Find(new byte[] { 0xac }).ToArray(); + Assert.AreEqual(0, results.Count()); + } + + [TestMethod] + public void TestFindLeadNode() + { + // r.Key = 0x0a0c + // b.Key = 0x00 + // l1.Key = 0x01 + var mpt = new MPTTrie(mptdb.GetSnapshot(), root.Hash); + var prefix = new byte[] { 0xac, 0x01 }; // = FromNibbles(path = { 0x0a, 0x0c, 0x00, 0x01 }); + var results = mpt.Find(prefix).ToArray(); + Assert.AreEqual(1, results.Count()); + + prefix = new byte[] { 0xac }; // = FromNibbles(path = { 0x0a, 0x0c }); + results = mpt.Find(prefix).ToArray(); + Assert.AreEqual(3, results.Count()); + } + } +} diff --git a/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj new file mode 100644 index 000000000..8733ce647 --- /dev/null +++ b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.0 + Neo.Plugins.StateService.Tests + false + + + + + + + + + + From 0799d85e2433834ad44b11422aa0545a315d1d4e Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Fri, 27 Nov 2020 17:36:27 +0800 Subject: [PATCH 14/24] Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix --- src/RpcClient/Models/RpcUnclaimedGas.cs | 6 +++--- src/RpcClient/RpcClient.cs | 4 ++-- src/RpcServer/RpcServer.SmartContract.cs | 2 +- src/RpcServer/RpcServer.Wallet.cs | 2 +- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/RpcClient/Models/RpcUnclaimedGas.cs b/src/RpcClient/Models/RpcUnclaimedGas.cs index 93e2c72fc..4ec14f5d7 100644 --- a/src/RpcClient/Models/RpcUnclaimedGas.cs +++ b/src/RpcClient/Models/RpcUnclaimedGas.cs @@ -1,11 +1,11 @@ using Neo.IO.Json; -using System.Numerics; +using Neo.SmartContract.Native; namespace Neo.Network.RPC.Models { public class RpcUnclaimedGas { - public BigInteger Unclaimed { get; set; } + public BigDecimal Unclaimed { get; set; } public string Address { get; set; } @@ -21,7 +21,7 @@ public static RpcUnclaimedGas FromJson(JObject json) { return new RpcUnclaimedGas { - Unclaimed = BigInteger.Parse(json["unclaimed"].AsString()), + Unclaimed = BigDecimal.Parse(json["unclaimed"].AsString(), NativeContract.GAS.Decimals), Address = json["address"].AsString() }; } diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index b5d2cf430..431e08988 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -460,10 +460,10 @@ public async Task GetWalletBalanceAsync(string assetId) /// /// Gets the amount of unclaimed GAS in the wallet. /// - public async Task GetWalletUnclaimedGasAsync() + public async Task GetWalletUnclaimedGasAsync() { var result = await RpcSendAsync(GetRpcName()).ConfigureAwait(false); - return BigInteger.Parse(result.AsString()); + return BigDecimal.Parse(result.AsString(), SmartContract.Native.NativeContract.GAS.Decimals); } /// diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index a48ede69a..99dff93bf 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -148,7 +148,7 @@ protected virtual JObject GetUnclaimedGas(JArray _params) if (script_hash == null) throw new RpcException(-100, "Invalid address"); SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); - json["unclaimed"] = NativeContract.NEO.UnclaimedGas(snapshot, script_hash, snapshot.Height + 1).ToString(); + json["unclaimed"] = new BigDecimal(NativeContract.NEO.UnclaimedGas(snapshot, script_hash, snapshot.Height + 1), NativeContract.GAS.Decimals).ToString(); json["address"] = script_hash.ToAddress(); return json; } diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 214df1bee..6ec21fb56 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -94,7 +94,7 @@ protected virtual JObject GetWalletUnclaimedGas(JArray _params) { gas += NativeContract.NEO.UnclaimedGas(snapshot, account, snapshot.Height + 1); } - return gas.ToString(); + return new BigDecimal(gas, NativeContract.GAS.Decimals).ToString(); } [RpcMethod] diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 8833fed6b..7b4c1c33d 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -834,7 +834,7 @@ "jsonrpc": "2.0", "id": 1, "result": { - "unclaimed": "735870007400", + "unclaimed": "7358.700074", "address": "NPvKVTGZapmFWABLsyvfreuqn73jCjJtN1" } } @@ -994,7 +994,7 @@ "Response": { "jsonrpc": "2.0", "id": 1, - "result": "735870007400" + "result": "7358.700074" } }, { From b522dce0a9d4f5ee5bdac198c13fb34e07ee9af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Wed, 2 Dec 2020 02:40:09 -0600 Subject: [PATCH 15/24] Fixed UT (Neo CI01089) (#416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao --- src/Directory.Build.props | 2 +- src/RpcClient/Models/RpcContractState.cs | 2 + src/RpcClient/RpcClient.cs | 1 + tests/Neo.Network.RPC.Tests/RpcTestCases.json | 117 ++++++++---------- .../UT_ContractClient.cs | 2 - 5 files changed, 54 insertions(+), 70 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 44d252790..ab7337427 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/RpcClient/Models/RpcContractState.cs b/src/RpcClient/Models/RpcContractState.cs index 041cd97f8..802710d0d 100644 --- a/src/RpcClient/Models/RpcContractState.cs +++ b/src/RpcClient/Models/RpcContractState.cs @@ -1,3 +1,4 @@ +using Neo; using Neo.IO.Json; using Neo.Ledger; using Neo.SmartContract.Manifest; @@ -19,6 +20,7 @@ public static RpcContractState FromJson(JObject json) ContractState = new ContractState { Id = (int)json["id"].AsNumber(), + Hash = UInt160.Parse(json["hash"].AsString()), Script = Convert.FromBase64String(json["script"].AsString()), Manifest = ContractManifest.FromJson(json["manifest"]) } diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index 431e08988..b9c184137 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -201,6 +201,7 @@ public static ContractState ContractStateFromJson(JObject json) return new ContractState { Id = (int)json["id"].AsNumber(), + Hash = UInt160.Parse(json["hash"].AsString()), Script = Convert.FromBase64String(json["script"].AsString()), Manifest = ContractManifest.FromJson(json["manifest"]) }; diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 7b4c1c33d..eae9639f9 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -318,109 +318,87 @@ "Request": { "jsonrpc": "2.0", "method": "getcontractstate", - "params": [ "0x806b7fa0db3b46d6c42e1e1b0a7fd50db9d4a9b0" ], + "params": [ "0x36a019d836d964c438c573f78badf79b9e7eebdd" ], "id": 1 }, "Response": { "jsonrpc": "2.0", "id": 1, "result": { - "id": 0, - "hash": "0x806b7fa0db3b46d6c42e1e1b0a7fd50db9d4a9b0", - "script": "VgIMFGklqlVHEkOanGE7oRTvo/rCPdvKYAwDKiwKYVcDAiFB6X04oAwBINshmlCaULQlIwAAACEMFGklqlVHEkOanGE7oRTvo/rCPdvKIUH4J+yMQCFB6X04oAwBQNshmlCaULQlKQEAAHgMCWJhbGFuY2VPZpcnDwAAAHkQziE1WgEAAEB4DAhkZWNpbWFsc5cnDAAAACE1sQEAAEB4DAZkZXBsb3mXJwwAAAAhNbQBAABAeAwEbmFtZZcnDAAAACE1OQIAAEB4DAZzeW1ib2yXJwwAAAAhNTsCAABAeAwSc3VwcG9ydGVkU3RhbmRhcmRzlycMAAAAITUfAgAAQHgMC3RvdGFsU3VwcGx5lycMAAAAITUmAgAAQHgMCHRyYW5zZmVylyclAAAAecoTsyUHAAAAEEB5EM55Ec5weRLOcWhpIVM1EgIAAEB4DAdkZXN0cm95lycMAAAAITUzAAAAQHgMB21pZ3JhdGWXJyAAAAB5yhKzJQcAAAAQQHkQznkRznJqIVA1EAAAAEAQQCFBxp8d8BFAVwACIQwUaSWqVUcSQ5qcYTuhFO+j+sI928ohQfgn7IwlBwAAABBAeMonDAAAAHnKJQcAAAAQQHh5IVBBMcYzHRFAVwEBeMoMARTbIbMlPAAAAAwyVGhlIHBhcmFtZXRlciBhY2NvdW50IFNIT1VMRCBiZSAyMC1ieXRlIGFkZHJlc3Nlcy4hRTohQZv2Z854IVBBkl3oMRBwJQcAAABoQCFBm/ZnznghUEGSXegx2yFAGEBXAQF4IUGpxUtBcGgnCQAAAGgSzkARQCFBm/ZnzgwLdG90YWxTdXBwbHkhUEGSXegxRSFBm/ZnziEMFGklqlVHEkOanGE7oRTvo/rCPdvKIQwDKiwKIVNB5j8YhCFBm/ZnzgwLdG90YWxTdXBwbHkhDAMqLAohU0HmPxiEIQshDBRpJapVRxJDmpxhO6EU76P6wj3byiEMAyosCiFTDAhUcmFuc2ZlchTAQZUBb2ERQAwVTmVwNSBOZW8zIFRlbXBsYXRlIDEgQAwDTk5EQBPDShAMBU5FUC010EoRDAVORVAtN9BKEgwGTkVQLTEw0EAhQZv2Z84MC3RvdGFsU3VwcGx5IVBBkl3oMdshQFcCA3oQticHAAAAEEB4IUH4J+yMJQcAAAAQQHnKDAEU2yGzJQcAAAAQQCFBm/ZnznghUEGSXegx2yFwaHq1JwcAAAAQQHh5mlCaULQlBwAAABFAaHqzJxgAAAAhQZv2Z854IVBBL1jF7SMWAAAAIUGb9mfOeGh6nyFTQeY/GIQhQZv2Z855IVBBkl3oMXFpJ0QAAAAMB2lmIHBhc3MhQc/nR5YhQZv2Z855adshep4hU0HmPxiEDBBTdG9yYWdlLnB1dCBwYXNzIUHP50eWIzsAAAAMCWVsc2UgcGFzcyFBz+dHliFBm/Znznl6IVNB5j8YhAwOYW1vdW50IC0+IHBhc3MhQc/nR5YheHl6IVMMCFRyYW5zZmVyFMBBlQFvYRFA", + "id": -2, + "updatecounter": 0, + "hash": "0x36a019d836d964c438c573f78badf79b9e7eebdd", + "script": "DANHQVNBa2d4Cw==", "manifest": { + "name": "GAS", "groups": [], - "features": { - "storage": true, - "payable": true - }, "supportedstandards": [ - "NEP-5" + "NEP-17" ], "abi": { - "hash": "0x806b7fa0db3b46d6c42e1e1b0a7fd50db9d4a9b0", "methods": [ { - "name": "main", - "parameters": [ - { - "name": "method", - "type": "String" - }, - { - "name": "args", - "type": "Array" - } - ], + "name": "onPersist", + "parameters": [], "offset": 0, - "returntype": "ByteArray" + "returntype": "Void" }, { - "name": "Destroy", + "name": "totalSupply", "parameters": [], - "offset": 400, - "returntype": "Boolean" + "offset": 0, + "returntype": "Integer" }, { - "name": "Migrate", + "name": "balanceOf", "parameters": [ { - "name": "script", + "name": "account", "type": "ByteArray" - }, - { - "name": "manifest", - "type": "String" } ], - "offset": 408, - "returntype": "Boolean" + "offset": 0, + "returntype": "Integer" }, { - "name": "BalanceOf", + "name": "transfer", "parameters": [ { - "name": "account", + "name": "from", "type": "ByteArray" + }, + { + "name": "to", + "type": "ByteArray" + }, + { + "name": "amount", + "type": "Integer" + }, + { + "name": "data", + "type": "Any" } ], - "offset": 474, - "returntype": "Integer" - }, - { - "name": "Decimals", - "parameters": [], - "offset": 585, - "returntype": "Integer" - }, - { - "name": "Deploy", - "parameters": [], - "offset": 610, + "offset": 0, "returntype": "Boolean" }, { - "name": "Name", + "name": "postPersist", "parameters": [], - "offset": 763, - "returntype": "String" + "offset": 0, + "returntype": "Void" }, { - "name": "Symbol", + "name": "symbol", "parameters": [], - "offset": 787, + "offset": 0, "returntype": "String" }, { - "name": "SupportedStandards", + "name": "decimals", "parameters": [], - "offset": 793, - "returntype": "Array" - }, - { - "name": "TotalSupply", - "parameters": [], - "offset": 827, + "offset": 0, "returntype": "Integer" } ], @@ -429,15 +407,15 @@ "name": "Transfer", "parameters": [ { - "name": "arg1", - "type": "ByteArray" + "name": "from", + "type": "Hash160" }, { - "name": "arg2", - "type": "ByteArray" + "name": "to", + "type": "Hash160" }, { - "name": "arg3", + "name": "amount", "type": "Integer" } ] @@ -451,7 +429,12 @@ } ], "trusts": [], - "safemethods": [], + "safemethods": [ + "totalSupply", + "balanceOf", + "symbol", + "decimals" + ], "extra": null } } diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index 2a120fad4..a442fdd74 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -45,7 +45,6 @@ public async Task TestDeployContract() Permissions = new[] { ContractPermission.DefaultPermission }, Abi = new ContractAbi() { - Hash = new byte[1].ToScriptHash(), Events = new ContractEventDescriptor[0], Methods = new ContractMethodDescriptor[0] }, @@ -55,7 +54,6 @@ public async Task TestDeployContract() SupportedStandards = new string[] { "NEP-10" }, Extra = null, }; - manifest.Features = ContractFeatures.HasStorage | ContractFeatures.Payable; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitSysCall(ApplicationEngine.System_Contract_Create, new byte[1], manifest.ToString()); From bd80d9eff87cce9fd41b940b860015fe347761c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 7 Dec 2020 02:57:14 -0600 Subject: [PATCH 16/24] Nep17 (#412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * String Substitution * Modify filename and name methods * update * update * Update src/RpcClient/Models/RpcNep5TokenInfo.cs Co-authored-by: Vitor Nazário Coelho * Update src/RpcClient/Nep17API.cs Co-authored-by: Vitor Nazário Coelho * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) * Update Nep17API.cs * Update README.md Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> * update filename * Fix UT * Format * fix * update * update UT * Add Unit Tests * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao --- README.md | 6 +- neo-modules.sln | 2 +- src/Directory.Build.props | 2 +- ...RpcNep5Balances.cs => RpcNep17Balances.cs} | 18 ++--- ...cNep5TokenInfo.cs => RpcNep17TokenInfo.cs} | 2 +- ...cNep5Transfers.cs => RpcNep17Transfers.cs} | 20 ++--- src/RpcClient/{Nep5API.cs => Nep17API.cs} | 57 ++++++------- src/RpcClient/RpcClient.cs | 20 ++--- src/RpcClient/TransactionManager.cs | 2 +- src/RpcClient/WalletAPI.cs | 34 ++++---- .../DbCache.cs | 0 .../Helper.cs | 0 .../Nep17Balance.cs} | 8 +- .../Nep17BalanceKey.cs} | 12 +-- .../Nep17Transfer.cs} | 8 +- .../Nep17TransferKey.cs} | 12 +-- .../RpcNep17Tracker.cs} | 80 +++++++++---------- .../RpcNep17Tracker.csproj} | 4 +- .../RpcNep17Tracker}/config.json | 4 +- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 14 ++-- .../{UT_Nep5API.cs => UT_Nep17API.cs} | 56 ++++++------- tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 16 ++-- tests/Neo.Network.RPC.Tests/UT_RpcModels.cs | 12 +-- tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs | 16 ++++ 24 files changed, 208 insertions(+), 197 deletions(-) rename src/RpcClient/Models/{RpcNep5Balances.cs => RpcNep17Balances.cs} (75%) rename src/RpcClient/Models/{RpcNep5TokenInfo.cs => RpcNep17TokenInfo.cs} (87%) rename src/RpcClient/Models/{RpcNep5Transfers.cs => RpcNep17Transfers.cs} (81%) rename src/RpcClient/{Nep5API.cs => Nep17API.cs} (76%) rename src/{RpcNep5Tracker => RpcNep17Tracker}/DbCache.cs (100%) rename src/{RpcNep5Tracker => RpcNep17Tracker}/Helper.cs (100%) rename src/{RpcNep5Tracker/Nep5Balance.cs => RpcNep17Tracker/Nep17Balance.cs} (80%) rename src/{RpcNep5Tracker/Nep5BalanceKey.cs => RpcNep17Tracker/Nep17BalanceKey.cs} (80%) rename src/{RpcNep5Tracker/Nep5Transfer.cs => RpcNep17Tracker/Nep17Transfer.cs} (84%) rename src/{RpcNep5Tracker/Nep5TransferKey.cs => RpcNep17Tracker/Nep17TransferKey.cs} (87%) rename src/{RpcNep5Tracker/RpcNep5Tracker.cs => RpcNep17Tracker/RpcNep17Tracker.cs} (75%) rename src/{RpcNep5Tracker/RpcNep5Tracker.csproj => RpcNep17Tracker/RpcNep17Tracker.csproj} (82%) rename src/{RpcNep5Tracker/RpcNep5Tracker => RpcNep17Tracker/RpcNep17Tracker}/config.json (76%) rename tests/Neo.Network.RPC.Tests/{UT_Nep5API.cs => UT_Nep17API.cs} (67%) diff --git a/README.md b/README.md index 4712b5be2..95f0e3526 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,12 @@ You can also use `RocksDBStore` in the NEO system by modifying the default stora ### RpcServer Plugin for hosting a RpcServer on the neo-node, being able to disable specific calls. -### RpcNep5Tracker -Plugin that enables NEP5 tracking using LevelDB. +### RpcNep17Tracker +Plugin that enables NEP17 tracking using LevelDB. This module works in conjunction with RpcServer, otherwise, just local storage (on leveldb) would be created. ## C# SDK ### RpcClient The RpcClient Project is an individual SDK that is used to interact with NEO blockchain through NEO RPC methods for development using. The main functions include RPC calling, Transaction making, Contract deployment & calling, and Asset transfering. -It needs a NEO node with the `RpcServer` plugin as a provider. And the provider needs more plugins like `RpcNep5Tracker` and `ApplicationLogs` if you want to call RPC methods supplied by the plugins. +It needs a NEO node with the `RpcServer` plugin as a provider. And the provider needs more plugins like `RpcNep17Tracker` and `ApplicationLogs` if you want to call RPC methods supplied by the plugins. diff --git a/neo-modules.sln b/neo-modules.sln index 24f303eb4..18f557324 100644 --- a/neo-modules.sln +++ b/neo-modules.sln @@ -10,7 +10,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationLogs", "src\Appl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatesDumper", "src\StatesDumper\StatesDumper.csproj", "{86531DB1-A231-46C4-823F-BE60972F7523}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcNep5Tracker", "src\RpcNep5Tracker\RpcNep5Tracker.csproj", "{BBE8AC15-12DF-4AF0-ABC1-F1557EB5DC8E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcNep17Tracker", "src\RpcNep17Tracker\RpcNep17Tracker.csproj", "{BBE8AC15-12DF-4AF0-ABC1-F1557EB5DC8E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelDBStore", "src\LevelDBStore\LevelDBStore.csproj", "{C66214CD-0B97-4EA5-B7A2-164F54346F19}" EndProject diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ab7337427..b7a7f73f8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/RpcClient/Models/RpcNep5Balances.cs b/src/RpcClient/Models/RpcNep17Balances.cs similarity index 75% rename from src/RpcClient/Models/RpcNep5Balances.cs rename to src/RpcClient/Models/RpcNep17Balances.cs index 4cdc1ecc7..dfd35b939 100644 --- a/src/RpcClient/Models/RpcNep5Balances.cs +++ b/src/RpcClient/Models/RpcNep17Balances.cs @@ -6,11 +6,11 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5Balances + public class RpcNep17Balances { public UInt160 UserScriptHash { get; set; } - public List Balances { get; set; } + public List Balances { get; set; } public JObject ToJson() { @@ -20,18 +20,18 @@ public JObject ToJson() return json; } - public static RpcNep5Balances FromJson(JObject json) + public static RpcNep17Balances FromJson(JObject json) { - RpcNep5Balances nep5Balance = new RpcNep5Balances + RpcNep17Balances nep17Balance = new RpcNep17Balances { - Balances = ((JArray)json["balance"]).Select(p => RpcNep5Balance.FromJson(p)).ToList(), + Balances = ((JArray)json["balance"]).Select(p => RpcNep17Balance.FromJson(p)).ToList(), UserScriptHash = json["address"].ToScriptHash() }; - return nep5Balance; + return nep17Balance; } } - public class RpcNep5Balance + public class RpcNep17Balance { public UInt160 AssetHash { get; set; } @@ -48,9 +48,9 @@ public JObject ToJson() return json; } - public static RpcNep5Balance FromJson(JObject json) + public static RpcNep17Balance FromJson(JObject json) { - RpcNep5Balance balance = new RpcNep5Balance + RpcNep17Balance balance = new RpcNep17Balance { AssetHash = json["assethash"].ToScriptHash(), Amount = BigInteger.Parse(json["amount"].AsString()), diff --git a/src/RpcClient/Models/RpcNep5TokenInfo.cs b/src/RpcClient/Models/RpcNep17TokenInfo.cs similarity index 87% rename from src/RpcClient/Models/RpcNep5TokenInfo.cs rename to src/RpcClient/Models/RpcNep17TokenInfo.cs index cb609b8a9..d28873943 100644 --- a/src/RpcClient/Models/RpcNep5TokenInfo.cs +++ b/src/RpcClient/Models/RpcNep17TokenInfo.cs @@ -2,7 +2,7 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5TokenInfo + public class RpcNep17TokenInfo { public string Name { get; set; } diff --git a/src/RpcClient/Models/RpcNep5Transfers.cs b/src/RpcClient/Models/RpcNep17Transfers.cs similarity index 81% rename from src/RpcClient/Models/RpcNep5Transfers.cs rename to src/RpcClient/Models/RpcNep17Transfers.cs index d23ca7a41..bc433ede0 100644 --- a/src/RpcClient/Models/RpcNep5Transfers.cs +++ b/src/RpcClient/Models/RpcNep17Transfers.cs @@ -7,13 +7,13 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5Transfers + public class RpcNep17Transfers { public UInt160 UserScriptHash { get; set; } - public List Sent { get; set; } + public List Sent { get; set; } - public List Received { get; set; } + public List Received { get; set; } public JObject ToJson() { @@ -24,19 +24,19 @@ public JObject ToJson() return json; } - public static RpcNep5Transfers FromJson(JObject json) + public static RpcNep17Transfers FromJson(JObject json) { - RpcNep5Transfers transfers = new RpcNep5Transfers + RpcNep17Transfers transfers = new RpcNep17Transfers { - Sent = ((JArray)json["sent"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), - Received = ((JArray)json["received"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), + Sent = ((JArray)json["sent"]).Select(p => RpcNep17Transfer.FromJson(p)).ToList(), + Received = ((JArray)json["received"]).Select(p => RpcNep17Transfer.FromJson(p)).ToList(), UserScriptHash = json["address"].ToScriptHash() }; return transfers; } } - public class RpcNep5Transfer + public class RpcNep17Transfer { public ulong TimestampMS { get; set; } @@ -65,9 +65,9 @@ public JObject ToJson() return json; } - public static RpcNep5Transfer FromJson(JObject json) + public static RpcNep17Transfer FromJson(JObject json) { - return new RpcNep5Transfer + return new RpcNep17Transfer { TimestampMS = (ulong)json["timestamp"].AsNumber(), AssetHash = json["assethash"].ToScriptHash(), diff --git a/src/RpcClient/Nep5API.cs b/src/RpcClient/Nep17API.cs similarity index 76% rename from src/RpcClient/Nep5API.cs rename to src/RpcClient/Nep17API.cs index 59cadd67e..50650ade6 100644 --- a/src/RpcClient/Nep5API.cs +++ b/src/RpcClient/Nep17API.cs @@ -13,18 +13,18 @@ namespace Neo.Network.RPC { /// - /// Call NEP5 methods with RPC API + /// Call NEP17 methods with RPC API /// - public class Nep5API : ContractClient + public class Nep17API : ContractClient { /// - /// Nep5API Constructor + /// Nep17API Constructor /// /// the RPC client to call NEO RPC methods - public Nep5API(RpcClient rpcClient) : base(rpcClient) { } + public Nep17API(RpcClient rpcClient) : base(rpcClient) { } /// - /// Get balance of NEP5 token + /// Get balance of NEP17 token /// /// contract script hash /// account script hash @@ -37,18 +37,7 @@ public async Task BalanceOfAsync(UInt160 scriptHash, UInt160 account } /// - /// Get name of NEP5 token - /// - /// contract script hash - /// - public async Task NameAsync(UInt160 scriptHash) - { - var result = await TestInvokeAsync(scriptHash, "name").ConfigureAwait(false); - return result.Stack.Single().GetString(); - } - - /// - /// Get symbol of NEP5 token + /// Get symbol of NEP17 token /// /// contract script hash /// @@ -59,7 +48,7 @@ public async Task SymbolAsync(UInt160 scriptHash) } /// - /// Get decimals of NEP5 token + /// Get decimals of NEP17 token /// /// contract script hash /// @@ -70,7 +59,7 @@ public async Task DecimalsAsync(UInt160 scriptHash) } /// - /// Get total supply of NEP5 token + /// Get total supply of NEP17 token /// /// contract script hash /// @@ -85,40 +74,43 @@ public async Task TotalSupplyAsync(UInt160 scriptHash) /// /// contract script hash /// - public async Task GetTokenInfoAsync(UInt160 scriptHash) + public async Task GetTokenInfoAsync(UInt160 scriptHash) { byte[] script = Concat( - scriptHash.MakeScript("name"), scriptHash.MakeScript("symbol"), scriptHash.MakeScript("decimals"), scriptHash.MakeScript("totalSupply")); + var contractState = await rpcClient.GetContractStateAsync(scriptHash.ToString()).ConfigureAwait(false); + var name = contractState.Manifest.Name; + var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false); var stack = result.Stack; - return new RpcNep5TokenInfo + return new RpcNep17TokenInfo { - Name = stack[0].GetString(), - Symbol = stack[1].GetString(), - Decimals = (byte)stack[2].GetInteger(), - TotalSupply = stack[3].GetInteger() + Name = name, + Symbol = stack[0].GetString(), + Decimals = (byte)stack[1].GetInteger(), + TotalSupply = stack[2].GetInteger() }; } /// - /// Create NEP5 token transfer transaction + /// Create NEP17 token transfer transaction /// /// contract script hash /// from KeyPair /// to account script hash /// transfer amount + /// onPayment data /// - public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount, object data = null) { var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); + byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); @@ -128,7 +120,7 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair } /// - /// Create NEP5 token transfer transaction from multi-sig account + /// Create NEP17 token transfer transaction from multi-sig account /// /// contract script hash /// multi-sig min signature count @@ -136,15 +128,16 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair /// sign keys /// to account /// transfer amount + /// onPayment data /// - public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount, object data = null) { if (m > fromKeys.Length) throw new ArgumentException($"Need at least {m} KeyPairs for signing!"); var sender = Contract.CreateMultiSigContract(m, pubKeys).ScriptHash; Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); + byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index b9c184137..8c0ea27c1 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -447,14 +447,14 @@ public async Task GetNewAddressAsync() /// /// Returns the balance of the corresponding asset in the wallet, based on the specified asset Id. - /// This method applies to assets that conform to NEP-5 standards. + /// This method applies to assets that conform to NEP-17 standards. /// /// new address as string public async Task GetWalletBalanceAsync(string assetId) { var result = await RpcSendAsync(GetRpcName(), assetId).ConfigureAwait(false); BigInteger balance = BigInteger.Parse(result["balance"].AsString()); - byte decimals = await new Nep5API(this).DecimalsAsync(UInt160.Parse(assetId.AsScriptHash())).ConfigureAwait(false); + byte decimals = await new Nep17API(this).DecimalsAsync(UInt160.Parse(assetId.AsScriptHash())).ConfigureAwait(false); return new BigDecimal(balance, decimals); } @@ -556,30 +556,30 @@ public async Task GetApplicationLogAsync(string txHash, Trigg } /// - /// Returns all the NEP-5 transaction information occurred in the specified address. - /// This method is provided by the plugin RpcNep5Tracker. + /// Returns all the NEP-17 transaction information occurred in the specified address. + /// This method is provided by the plugin RpcNep17Tracker. /// /// The address to query the transaction information. /// The start block Timestamp, default to seven days before UtcNow /// The end block Timestamp, default to UtcNow - public async Task GetNep5TransfersAsync(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) + public async Task GetNep17TransfersAsync(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) { startTimestamp ??= 0; endTimestamp ??= DateTime.UtcNow.ToTimestampMS(); var result = await RpcSendAsync(GetRpcName(), address.AsScriptHash(), startTimestamp, endTimestamp) .ConfigureAwait(false); - return RpcNep5Transfers.FromJson(result); + return RpcNep17Transfers.FromJson(result); } /// - /// Returns the balance of all NEP-5 assets in the specified address. - /// This method is provided by the plugin RpcNep5Tracker. + /// Returns the balance of all NEP-17 assets in the specified address. + /// This method is provided by the plugin RpcNep17Tracker. /// - public async Task GetNep5BalancesAsync(string address) + public async Task GetNep17BalancesAsync(string address) { var result = await RpcSendAsync(GetRpcName(), address.AsScriptHash()) .ConfigureAwait(false); - return RpcNep5Balances.FromJson(result); + return RpcNep17Balances.FromJson(result); } #endregion Plugins diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index 067fc2ff6..c301fea59 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -166,7 +166,7 @@ public async Task SignAsync() Tx.NetworkFee = await rpcClient.CalculateNetworkFeeAsync(Tx).ConfigureAwait(false); Tx.Witnesses = null; - var gasBalance = await new Nep5API(rpcClient).BalanceOfAsync(NativeContract.GAS.Hash, Tx.Sender).ConfigureAwait(false); + var gasBalance = await new Nep17API(rpcClient).BalanceOfAsync(NativeContract.GAS.Hash, Tx.Sender).ConfigureAwait(false); if (gasBalance < Tx.SystemFee + Tx.NetworkFee) throw new InvalidOperationException($"Insufficient GAS in address: {Tx.Sender.ToAddress()}"); diff --git a/src/RpcClient/WalletAPI.cs b/src/RpcClient/WalletAPI.cs index b4cef3c55..aba15cf91 100644 --- a/src/RpcClient/WalletAPI.cs +++ b/src/RpcClient/WalletAPI.cs @@ -19,7 +19,7 @@ namespace Neo.Network.RPC public class WalletAPI { private readonly RpcClient rpcClient; - private readonly Nep5API nep5API; + private readonly Nep17API nep17API; /// /// WalletAPI Constructor @@ -28,7 +28,7 @@ public class WalletAPI public WalletAPI(RpcClient rpc) { rpcClient = rpc; - nep5API = new Nep5API(rpc); + nep17API = new Nep17API(rpc); } /// @@ -52,7 +52,7 @@ public async Task GetUnclaimedGasAsync(UInt160 account) { UInt160 scriptHash = NativeContract.NEO.Hash; var blockCount = await rpcClient.GetBlockCountAsync().ConfigureAwait(false); - var result = await nep5API.TestInvokeAsync(scriptHash, "unclaimedGas", account, blockCount - 1).ConfigureAwait(false); + var result = await nep17API.TestInvokeAsync(scriptHash, "unclaimedGas", account, blockCount - 1).ConfigureAwait(false); BigInteger balance = result.Stack.Single().GetInteger(); return ((decimal)balance) / (long)NativeContract.GAS.Factor; } @@ -92,7 +92,7 @@ public Task GetTokenBalanceAsync(string tokenHash, string account) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); UInt160 accountHash = Utility.GetScriptHash(account); - return nep5API.BalanceOfAsync(scriptHash, accountHash); + return nep17API.BalanceOfAsync(scriptHash, accountHash); } /// @@ -117,49 +117,49 @@ public Task ClaimGasAsync(string key) public async Task ClaimGasAsync(KeyPair keyPair) { UInt160 toHash = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(); - BigInteger balance = await nep5API.BalanceOfAsync(NativeContract.NEO.Hash, toHash).ConfigureAwait(false); - Transaction transaction = await nep5API.CreateTransferTxAsync(NativeContract.NEO.Hash, keyPair, toHash, balance).ConfigureAwait(false); + BigInteger balance = await nep17API.BalanceOfAsync(NativeContract.NEO.Hash, toHash).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(NativeContract.NEO.Hash, keyPair, toHash, balance).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } /// - /// Transfer NEP5 token balance, with common data types + /// Transfer NEP17 token balance, with common data types /// - /// nep5 token script hash, Example: scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8") + /// nep17 token script hash, Example: scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8") /// wif or private key /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") /// address or account script hash /// token amount /// - public async Task TransferAsync(string tokenHash, string fromKey, string toAddress, decimal amount) + public async Task TransferAsync(string tokenHash, string fromKey, string toAddress, decimal amount, object data = null) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); - var decimals = await nep5API.DecimalsAsync(scriptHash).ConfigureAwait(false); + var decimals = await nep17API.DecimalsAsync(scriptHash).ConfigureAwait(false); KeyPair from = Utility.GetKeyPair(fromKey); UInt160 to = Utility.GetScriptHash(toAddress); BigInteger amountInteger = amount.ToBigInteger(decimals); - return await TransferAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); + return await TransferAsync(scriptHash, from, to, amountInteger, data).ConfigureAwait(false); } /// - /// Transfer NEP5 token from single-sig account + /// Transfer NEP17 token from single-sig account /// /// contract script hash /// from KeyPair /// to account script hash /// transfer amount /// - public async Task TransferAsync(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger, object data = null) { - Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(scriptHash, from, to, amountInteger, data).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } /// - /// Transfer NEP5 token from multi-sig account + /// Transfer NEP17 token from multi-sig account /// /// contract script hash /// multi-sig min signature count @@ -168,9 +168,9 @@ public async Task TransferAsync(UInt160 scriptHash, KeyPair from, U /// to account /// transfer amount /// - public async Task TransferAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger, object data = null) { - Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, m, pubKeys, keys, to, amountInteger).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(scriptHash, m, pubKeys, keys, to, amountInteger, data).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } diff --git a/src/RpcNep5Tracker/DbCache.cs b/src/RpcNep17Tracker/DbCache.cs similarity index 100% rename from src/RpcNep5Tracker/DbCache.cs rename to src/RpcNep17Tracker/DbCache.cs diff --git a/src/RpcNep5Tracker/Helper.cs b/src/RpcNep17Tracker/Helper.cs similarity index 100% rename from src/RpcNep5Tracker/Helper.cs rename to src/RpcNep17Tracker/Helper.cs diff --git a/src/RpcNep5Tracker/Nep5Balance.cs b/src/RpcNep17Tracker/Nep17Balance.cs similarity index 80% rename from src/RpcNep5Tracker/Nep5Balance.cs rename to src/RpcNep17Tracker/Nep17Balance.cs index c848879f5..9dc5e3d67 100644 --- a/src/RpcNep5Tracker/Nep5Balance.cs +++ b/src/RpcNep17Tracker/Nep17Balance.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5Balance : ICloneable, ISerializable + public class Nep17Balance : ICloneable, ISerializable { public BigInteger Balance; public uint LastUpdatedBlock; @@ -23,16 +23,16 @@ void ISerializable.Deserialize(BinaryReader reader) LastUpdatedBlock = reader.ReadUInt32(); } - Nep5Balance ICloneable.Clone() + Nep17Balance ICloneable.Clone() { - return new Nep5Balance + return new Nep17Balance { Balance = Balance, LastUpdatedBlock = LastUpdatedBlock }; } - public void FromReplica(Nep5Balance replica) + public void FromReplica(Nep17Balance replica) { Balance = replica.Balance; LastUpdatedBlock = replica.LastUpdatedBlock; diff --git a/src/RpcNep5Tracker/Nep5BalanceKey.cs b/src/RpcNep17Tracker/Nep17BalanceKey.cs similarity index 80% rename from src/RpcNep5Tracker/Nep5BalanceKey.cs rename to src/RpcNep17Tracker/Nep17BalanceKey.cs index ec1fc218d..0d5e5267a 100644 --- a/src/RpcNep5Tracker/Nep5BalanceKey.cs +++ b/src/RpcNep17Tracker/Nep17BalanceKey.cs @@ -4,18 +4,18 @@ namespace Neo.Plugins { - public class Nep5BalanceKey : IComparable, IEquatable, ISerializable + public class Nep17BalanceKey : IComparable, IEquatable, ISerializable { public readonly UInt160 UserScriptHash; public readonly UInt160 AssetScriptHash; public int Size => 20 + 20; - public Nep5BalanceKey() : this(new UInt160(), new UInt160()) + public Nep17BalanceKey() : this(new UInt160(), new UInt160()) { } - public Nep5BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) + public Nep17BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) { if (userScriptHash == null || assetScriptHash == null) throw new ArgumentNullException(); @@ -23,7 +23,7 @@ public Nep5BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) AssetScriptHash = assetScriptHash; } - public int CompareTo(Nep5BalanceKey other) + public int CompareTo(Nep17BalanceKey other) { if (other is null) return 1; if (ReferenceEquals(this, other)) return 0; @@ -32,7 +32,7 @@ public int CompareTo(Nep5BalanceKey other) return AssetScriptHash.CompareTo(other.AssetScriptHash); } - public bool Equals(Nep5BalanceKey other) + public bool Equals(Nep17BalanceKey other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; @@ -41,7 +41,7 @@ public bool Equals(Nep5BalanceKey other) public override bool Equals(Object other) { - return other is Nep5BalanceKey otherKey && Equals(otherKey); + return other is Nep17BalanceKey otherKey && Equals(otherKey); } public override int GetHashCode() diff --git a/src/RpcNep5Tracker/Nep5Transfer.cs b/src/RpcNep17Tracker/Nep17Transfer.cs similarity index 84% rename from src/RpcNep5Tracker/Nep5Transfer.cs rename to src/RpcNep17Tracker/Nep17Transfer.cs index 84c71f1d7..8a2f33561 100644 --- a/src/RpcNep5Tracker/Nep5Transfer.cs +++ b/src/RpcNep17Tracker/Nep17Transfer.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5Transfer : ICloneable, ISerializable + public class Nep17Transfer : ICloneable, ISerializable { public UInt160 UserScriptHash; public uint BlockIndex; @@ -29,9 +29,9 @@ void ISerializable.Deserialize(BinaryReader reader) Amount = new BigInteger(reader.ReadVarBytes(512)); } - Nep5Transfer ICloneable.Clone() + Nep17Transfer ICloneable.Clone() { - return new Nep5Transfer + return new Nep17Transfer { UserScriptHash = UserScriptHash, BlockIndex = BlockIndex, @@ -40,7 +40,7 @@ Nep5Transfer ICloneable.Clone() }; } - void ICloneable.FromReplica(Nep5Transfer replica) + void ICloneable.FromReplica(Nep17Transfer replica) { UserScriptHash = replica.UserScriptHash; BlockIndex = replica.BlockIndex; diff --git a/src/RpcNep5Tracker/Nep5TransferKey.cs b/src/RpcNep17Tracker/Nep17TransferKey.cs similarity index 87% rename from src/RpcNep5Tracker/Nep5TransferKey.cs rename to src/RpcNep17Tracker/Nep17TransferKey.cs index 69e7fc735..128a7bef1 100644 --- a/src/RpcNep5Tracker/Nep5TransferKey.cs +++ b/src/RpcNep17Tracker/Nep17TransferKey.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5TransferKey : IComparable, IEquatable, ISerializable + public class Nep17TransferKey : IComparable, IEquatable, ISerializable { public readonly UInt160 UserScriptHash; public ulong TimestampMS { get; private set; } @@ -17,11 +17,11 @@ public class Nep5TransferKey : IComparable, IEquatable _balances; - private DataCache _transfersSent; - private DataCache _transfersReceived; + private DataCache _balances; + private DataCache _transfersSent; + private DataCache _transfersReceived; private WriteBatch _writeBatch; private bool _shouldTrackHistory; private bool _recordNullAddressHistory; private uint _maxResults; private Snapshot _levelDbSnapshot; - public override string Description => "Enquiries NEP-5 balances and transaction history of accounts through RPC"; + public override string Description => "Enquiries NEP-17 balances and transaction history of accounts through RPC"; - public RpcNep5Tracker() + public RpcNep17Tracker() { RpcServerPlugin.RegisterMethods(this); } @@ -44,7 +44,7 @@ protected override void Configure() { if (_db == null) { - var dbPath = GetConfiguration().GetSection("DBPath").Value ?? "Nep5BalanceData"; + var dbPath = GetConfiguration().GetSection("DBPath").Value ?? "Nep17BalanceData"; _db = DB.Open(GetFullPath(dbPath), new Options { CreateIfMissing = true }); } _shouldTrackHistory = (GetConfiguration().GetSection("TrackHistory").Value ?? true.ToString()) != false.ToString(); @@ -58,13 +58,13 @@ private void ResetBatch() _levelDbSnapshot?.Dispose(); _levelDbSnapshot = _db.GetSnapshot(); ReadOptions dbOptions = new ReadOptions { FillCache = false, Snapshot = _levelDbSnapshot }; - _balances = new DbCache(_db, dbOptions, _writeBatch, Nep5BalancePrefix); + _balances = new DbCache(_db, dbOptions, _writeBatch, Nep17BalancePrefix); if (_shouldTrackHistory) { _transfersSent = - new DbCache(_db, dbOptions, _writeBatch, Nep5TransferSentPrefix); + new DbCache(_db, dbOptions, _writeBatch, Nep17TransferSentPrefix); _transfersReceived = - new DbCache(_db, dbOptions, _writeBatch, Nep5TransferReceivedPrefix); + new DbCache(_db, dbOptions, _writeBatch, Nep17TransferReceivedPrefix); } } @@ -76,8 +76,8 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 if (_recordNullAddressHistory || from != UInt160.Zero) { - _transfersSent.Add(new Nep5TransferKey(from, header.Timestamp, scriptHash, transferIndex), - new Nep5Transfer + _transfersSent.Add(new Nep17TransferKey(from, header.Timestamp, scriptHash, transferIndex), + new Nep17Transfer { Amount = amount, UserScriptHash = to, @@ -88,8 +88,8 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 if (_recordNullAddressHistory || to != UInt160.Zero) { - _transfersReceived.Add(new Nep5TransferKey(to, header.Timestamp, scriptHash, transferIndex), - new Nep5Transfer + _transfersReceived.Add(new Nep17TransferKey(to, header.Timestamp, scriptHash, transferIndex), + new Nep17Transfer { Amount = amount, UserScriptHash = from, @@ -102,7 +102,7 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 private void HandleNotification(StoreView snapshot, IVerifiable scriptContainer, UInt160 scriptHash, string eventName, VM.Types.Array stateItems, - Dictionary nep5BalancesChanged, ref ushort transferIndex) + Dictionary nep17BalancesChanged, ref ushort transferIndex) { if (stateItems.Count == 0) return; if (eventName != "Transfer") return; @@ -129,15 +129,15 @@ private void HandleNotification(StoreView snapshot, IVerifiable scriptContainer, if (fromBytes != null) { from = new UInt160(fromBytes); - var fromKey = new Nep5BalanceKey(from, scriptHash); - if (!nep5BalancesChanged.ContainsKey(fromKey)) nep5BalancesChanged.Add(fromKey, new Nep5Balance()); + var fromKey = new Nep17BalanceKey(from, scriptHash); + if (!nep17BalancesChanged.ContainsKey(fromKey)) nep17BalancesChanged.Add(fromKey, new Nep17Balance()); } if (toBytes != null) { to = new UInt160(toBytes); - var toKey = new Nep5BalanceKey(to, scriptHash); - if (!nep5BalancesChanged.ContainsKey(toKey)) nep5BalancesChanged.Add(toKey, new Nep5Balance()); + var toKey = new Nep17BalanceKey(to, scriptHash); + if (!nep17BalancesChanged.ContainsKey(toKey)) nep17BalancesChanged.Add(toKey, new Nep17Balance()); } if (scriptContainer is Transaction transaction) { @@ -149,7 +149,7 @@ public void OnPersist(StoreView snapshot, IReadOnlyList nep5BalancesChanged = new Dictionary(); + Dictionary nep17BalancesChanged = new Dictionary(); ushort transferIndex = 0; foreach (Blockchain.ApplicationExecuted appExecuted in applicationExecutedList) @@ -161,18 +161,18 @@ public void OnPersist(StoreView snapshot, IReadOnlyList nep5BalancePair.Value); - if (itemToChange != nep5BalancePair.Value) - itemToChange.FromReplica(nep5BalancePair.Value); + var itemToChange = _balances.GetAndChange(nep17BalancePair.Key, () => nep17BalancePair.Value); + if (itemToChange != nep17BalancePair.Value) + itemToChange.FromReplica(nep17BalancePair.Value); } } @@ -223,7 +223,7 @@ private void AddTransfers(byte dbPrefix, UInt160 userScriptHash, ulong startTime Array.Reverse(endTimeBytes); } - var transferPairs = _db.FindRange( + var transferPairs = _db.FindRange( prefix.Concat(startTimeBytes).ToArray(), prefix.Concat(endTimeBytes).ToArray()); @@ -250,7 +250,7 @@ private UInt160 GetScriptHashFromParam(string addressOrScriptHash) } [RpcMethod] - public JObject GetNep5Transfers(JArray _params) + public JObject GetNep17Transfers(JArray _params) { if (!_shouldTrackHistory) throw new RpcException(-32601, "Method not found"); UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); @@ -267,13 +267,13 @@ public JObject GetNep5Transfers(JArray _params) JArray transfersReceived = new JArray(); json["received"] = transfersReceived; json["address"] = userScriptHash.ToAddress(); - AddTransfers(Nep5TransferSentPrefix, userScriptHash, startTime, endTime, transfersSent); - AddTransfers(Nep5TransferReceivedPrefix, userScriptHash, startTime, endTime, transfersReceived); + AddTransfers(Nep17TransferSentPrefix, userScriptHash, startTime, endTime, transfersSent); + AddTransfers(Nep17TransferReceivedPrefix, userScriptHash, startTime, endTime, transfersReceived); return json; } [RpcMethod] - public JObject GetNep5Balances(JArray _params) + public JObject GetNep17Balances(JArray _params) { UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); @@ -281,7 +281,7 @@ public JObject GetNep5Balances(JArray _params) JArray balances = new JArray(); json["balance"] = balances; json["address"] = userScriptHash.ToAddress(); - var dbCache = new DbCache(_db, null, null, Nep5BalancePrefix); + var dbCache = new DbCache(_db, null, null, Nep17BalancePrefix); byte[] prefix = userScriptHash.ToArray(); foreach (var (key, value) in dbCache.Find(prefix)) { diff --git a/src/RpcNep5Tracker/RpcNep5Tracker.csproj b/src/RpcNep17Tracker/RpcNep17Tracker.csproj similarity index 82% rename from src/RpcNep5Tracker/RpcNep5Tracker.csproj rename to src/RpcNep17Tracker/RpcNep17Tracker.csproj index 403f4a12a..bb3b93e44 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker.csproj +++ b/src/RpcNep17Tracker/RpcNep17Tracker.csproj @@ -1,10 +1,10 @@ - Neo.Plugins.RpcNep5Tracker + Neo.Plugins.RpcNep17Tracker Neo.Plugins - + PreserveNewest PreserveNewest diff --git a/src/RpcNep5Tracker/RpcNep5Tracker/config.json b/src/RpcNep17Tracker/RpcNep17Tracker/config.json similarity index 76% rename from src/RpcNep5Tracker/RpcNep5Tracker/config.json rename to src/RpcNep17Tracker/RpcNep17Tracker/config.json index 13e79b805..af5e20247 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker/config.json +++ b/src/RpcNep17Tracker/RpcNep17Tracker/config.json @@ -1,6 +1,6 @@ -{ +{ "PluginConfiguration": { - "DBPath": "Nep5BalanceData", + "DBPath": "Nep17BalanceData", "TrackHistory" : true, "RecordNullAddressHistory": false, "MaxResults" : 1000 diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index eae9639f9..42ac24a45 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -850,7 +850,7 @@ ] }, { - "name": "RpcNep5Tracker", + "name": "RpcNep17Tracker", "version": "3.0.0.0", "interfaces": [ "IPersistencePlugin" @@ -1340,10 +1340,10 @@ } }, { - "Name": "getnep5transfersasync", + "Name": "getnep17transfersasync", "Request": { "jsonrpc": "2.0", - "method": "getnep5transfers", + "method": "getnep17transfers", "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", 0, 1868595301000 ], "id": 1 }, @@ -1387,10 +1387,10 @@ } }, { - "Name": "getnep5transfersasync_with_null_transferaddress", + "Name": "getnep17transfersasync_with_null_transferaddress", "Request": { "jsonrpc": "2.0", - "method": "getnep5transfers", + "method": "getnep17transfers", "params": [ "Ncb7jVsYWBt1q5T5k3ZTP8bn5eK4DuanLd", 0, 1868595301000 ], "id": 1 }, @@ -1434,10 +1434,10 @@ } }, { - "Name": "getnep5balancesasync", + "Name": "getnep17balancesasync", "Request": { "jsonrpc": "2.0", - "method": "getnep5balances", + "method": "getnep17balances", "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ" ], "id": 1 }, diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs similarity index 67% rename from tests/Neo.Network.RPC.Tests/UT_Nep5API.cs rename to tests/Neo.Network.RPC.Tests/UT_Nep17API.cs index 12f0142c9..b35a2bfc9 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.IO.Json; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; @@ -11,12 +12,12 @@ namespace Neo.Network.RPC.Tests { [TestClass] - public class UT_Nep5API + public class UT_Nep17API { Mock rpcClientMock; KeyPair keyPair1; UInt160 sender; - Nep5API nep5API; + Nep17API nep17API; [TestInitialize] public void TestSetup() @@ -24,7 +25,7 @@ public void TestSetup() keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p")); sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash(); rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]); - nep5API = new Nep5API(rpcClientMock.Object); + nep17API = new Nep17API(rpcClientMock.Object); } [TestMethod] @@ -33,27 +34,17 @@ public async Task TestBalanceOf() byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(10000) }); - var balance = await nep5API.BalanceOfAsync(NativeContract.GAS.Hash, UInt160.Zero); + var balance = await nep17API.BalanceOfAsync(NativeContract.GAS.Hash, UInt160.Zero); Assert.AreEqual(10000, (int)balance); } - [TestMethod] - public async Task TestGetName() - { - byte[] testScript = NativeContract.GAS.Hash.MakeScript("name"); - UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }); - - var result = await nep5API.NameAsync(NativeContract.GAS.Hash); - Assert.AreEqual(NativeContract.GAS.Name, result); - } - [TestMethod] public async Task TestGetSymbol() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("symbol"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }); - var result = await nep5API.SymbolAsync(NativeContract.GAS.Hash); + var result = await nep17API.SymbolAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Symbol, result); } @@ -63,7 +54,7 @@ public async Task TestGetDecimals() byte[] testScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }); - var result = await nep5API.DecimalsAsync(NativeContract.GAS.Hash); + var result = await nep17API.DecimalsAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Decimals, result); } @@ -73,7 +64,7 @@ public async Task TestGetTotalSupply() byte[] testScript = NativeContract.GAS.Hash.MakeScript("totalSupply"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = await nep5API.TotalSupplyAsync(NativeContract.GAS.Hash); + var result = await nep17API.TotalSupplyAsync(NativeContract.GAS.Hash); Assert.AreEqual(1_00000000, (int)result); } @@ -81,22 +72,28 @@ public async Task TestGetTotalSupply() public async Task TestGetTokenInfo() { UInt160 scriptHash = NativeContract.GAS.Hash; - byte[] testScript = scriptHash.MakeScript("name") - .Concat(scriptHash.MakeScript("symbol")) + byte[] testScript = scriptHash.MakeScript("symbol") .Concat(scriptHash.MakeScript("decimals")) .Concat(scriptHash.MakeScript("totalSupply")) - .ToArray(); ; + .ToArray(); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, - new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = await nep5API.GetTokenInfoAsync(NativeContract.GAS.Hash); - Assert.AreEqual(NativeContract.GAS.Name, result.Name); - Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); - Assert.AreEqual(8, (int)result.Decimals); - Assert.AreEqual(1_00000000, (int)result.TotalSupply); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == "getcontractstateasync"); + foreach (var test in tests) + { + rpcClientMock.Setup(p => p.RpcSendAsync("getcontractstate", It.Is(u => true))) + .ReturnsAsync(test.Response.Result) + .Verifiable(); + + var result = await nep17API.GetTokenInfoAsync(NativeContract.GAS.Hash); + Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); + Assert.AreEqual(8, (int)result.Decimals); + Assert.AreEqual(1_00000000, (int)result.TotalSupply); + Assert.AreEqual("GAS", result.Name); + } } [TestMethod] @@ -105,7 +102,12 @@ public async Task TestTransfer() byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000)); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); - var result = await nep5API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + var result = await nep17API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + + testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000), string.Empty); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); + + result = await nep17API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000), string.Empty); Assert.IsNotNull(result); } } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index b558ef201..69ba8caaf 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -431,21 +431,21 @@ public async Task GetApplicationLogTest_TriggerType() } [TestMethod()] - public async Task GetNep5TransfersTest() + public async Task GetNep17TransfersTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5TransfersAsync).ToLower()); - var result = await rpc.GetNep5TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep17TransfersAsync).ToLower()); + var result = await rpc.GetNep17TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); - test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.GetNep5TransfersAsync).ToLower() + "_with_null_transferaddress")); - result = await rpc.GetNep5TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); + test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.GetNep17TransfersAsync).ToLower() + "_with_null_transferaddress")); + result = await rpc.GetNep17TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod()] - public async Task GetNep5BalancesTest() + public async Task GetNep17BalancesTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5BalancesAsync).ToLower()); - var result = await rpc.GetNep5BalancesAsync(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep17BalancesAsync).ToLower()); + var result = await rpc.GetNep17BalancesAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs index 04613dbc1..18b55c603 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs @@ -57,18 +57,18 @@ public void TestRpcInvokeResult() } [TestMethod()] - public void TestRpcNep5Balances() + public void TestRpcNep17Balances() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5BalancesAsync).ToLower()).Response.Result; - var item = RpcNep5Balances.FromJson(json); + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep17BalancesAsync).ToLower()).Response.Result; + var item = RpcNep17Balances.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } [TestMethod()] - public void TestRpcNep5Transfers() + public void TestRpcNep17Transfers() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5TransfersAsync).ToLower()).Response.Result; - var item = RpcNep5Transfers.FromJson(json); + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep17TransfersAsync).ToLower()).Response.Result; + var item = RpcNep17Transfers.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs index ebfbcb51b..721b53fef 100644 --- a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs @@ -127,6 +127,22 @@ public async Task TestTransferfromMultiSigAccount() var tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); + + try + { + tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 2, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); + Assert.Fail(); + } + catch (System.Exception e) + { + Assert.AreEqual(e.Message, $"Need at least 2 KeyPairs for signing!"); + } + + testScript = NativeContract.GAS.Hash.MakeScript("transfer", multiSender, UInt160.Zero, NativeContract.GAS.Factor * 100, string.Empty); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100, string.Empty); + Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); } [TestMethod] From 0cb8a830ec12cd9a963479a9dbed5bfe206397e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 17 Dec 2020 13:47:22 +0800 Subject: [PATCH 17/24] merge --- src/StateService/MPT/MPTNode.cs | 1 - src/StateService/MPT/MPTNodeType.cs | 3 --- src/StateService/MPT/MPTTrie.Put.cs | 2 -- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 2 +- tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs | 1 - 5 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/StateService/MPT/MPTNode.cs b/src/StateService/MPT/MPTNode.cs index b37c9602b..2cd3a29d6 100644 --- a/src/StateService/MPT/MPTNode.cs +++ b/src/StateService/MPT/MPTNode.cs @@ -1,6 +1,5 @@ using Neo.Cryptography; using Neo.IO; -using Neo.IO.Caching; using System; using System.IO; diff --git a/src/StateService/MPT/MPTNodeType.cs b/src/StateService/MPT/MPTNodeType.cs index a17ce1a7e..83c2b558a 100644 --- a/src/StateService/MPT/MPTNodeType.cs +++ b/src/StateService/MPT/MPTNodeType.cs @@ -1,12 +1,9 @@ -using Neo.IO.Caching; namespace Neo.Plugins.MPT { public enum NodeType : byte { - [ReflectionCache(typeof(BranchNode))] BranchNode = 0x00, - [ReflectionCache(typeof(ExtensionNode))] ExtensionNode = 0x01, LeafNode = 0x02, HashNode = 0x03, diff --git a/src/StateService/MPT/MPTTrie.Put.cs b/src/StateService/MPT/MPTTrie.Put.cs index 5fecbc33f..5ff4f9933 100644 --- a/src/StateService/MPT/MPTTrie.Put.cs +++ b/src/StateService/MPT/MPTTrie.Put.cs @@ -133,8 +133,6 @@ private bool Put(ref MPTNode node, ReadOnlySpan path, MPTNode val) case NodeType.Empty: { MPTNode newNode; - if (hashNode.IsEmpty) - { if (path.IsEmpty) { newNode = val; diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 39e068840..c6c2228b2 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -521,7 +521,7 @@ "name": "vote", "parameters": [ { - "name": "from", + "name": "account", "type": "ByteArray" }, { diff --git a/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs index 3747a73a9..9affc5f1a 100644 --- a/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs +++ b/tests/Neo.Plugins.StateService.Tests/MPT/UT_MPTTrie.cs @@ -278,7 +278,6 @@ public void TestDeleteSameValue() Assert.IsNotNull(mpt["ac02".HexToBytes()]); mpt.Commit(); snapshot.Commit(); - var mpt0 = new MPTTrie(store.GetSnapshot(), mpt.Root.Hash); Assert.IsNotNull(mpt0["ac02".HexToBytes()]); } From f05644f5887fe7fb9b3513e54594246c25206e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 17 Dec 2020 13:58:38 +0800 Subject: [PATCH 18/24] clear --- src/StateService/MPT/BranchNode.cs | 35 ----------------------- src/StateService/MPT/ExtensionNode.cs | 30 -------------------- src/StateService/MPT/HashNode.cs | 41 --------------------------- src/StateService/MPT/LeafNode.cs | 36 ----------------------- 4 files changed, 142 deletions(-) delete mode 100644 src/StateService/MPT/BranchNode.cs delete mode 100644 src/StateService/MPT/ExtensionNode.cs delete mode 100644 src/StateService/MPT/HashNode.cs delete mode 100644 src/StateService/MPT/LeafNode.cs diff --git a/src/StateService/MPT/BranchNode.cs b/src/StateService/MPT/BranchNode.cs deleted file mode 100644 index f729412b5..000000000 --- a/src/StateService/MPT/BranchNode.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.IO; - -namespace Neo.Plugins.MPT -{ - public class BranchNode : MPTNode - { - public const int ChildCount = 17; - public readonly MPTNode[] Children = new MPTNode[ChildCount]; - - protected override NodeType Type => NodeType.BranchNode; - - public BranchNode() - { - for (int i = 0; i < ChildCount; i++) - { - Children[i] = HashNode.EmptyNode; - } - } - - internal override void EncodeSpecific(BinaryWriter writer) - { - for (int i = 0; i < ChildCount; i++) - WriteHash(writer, Children[i].Hash); - } - - internal override void DecodeSpecific(BinaryReader reader) - { - for (int i = 0; i < ChildCount; i++) - { - Children[i] = new HashNode(); - Children[i].DecodeSpecific(reader); - } - } - } -} diff --git a/src/StateService/MPT/ExtensionNode.cs b/src/StateService/MPT/ExtensionNode.cs deleted file mode 100644 index 00f107240..000000000 --- a/src/StateService/MPT/ExtensionNode.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Neo.IO; -using Neo.SmartContract; -using System.IO; - -namespace Neo.Plugins.MPT -{ - public class ExtensionNode : MPTNode - { - //max lenght when store StorageKey - public const int MaxKeyLength = (ApplicationEngine.MaxStorageValueSize + sizeof(int)) * 2; - - public byte[] Key; - public MPTNode Next; - - protected override NodeType Type => NodeType.ExtensionNode; - - internal override void EncodeSpecific(BinaryWriter writer) - { - writer.WriteVarBytes(Key); - WriteHash(writer, Next.Hash); - } - - internal override void DecodeSpecific(BinaryReader reader) - { - Key = reader.ReadVarBytes(MaxKeyLength); - Next = new HashNode(); - Next.DecodeSpecific(reader); - } - } -} diff --git a/src/StateService/MPT/HashNode.cs b/src/StateService/MPT/HashNode.cs deleted file mode 100644 index 7053f0a3b..000000000 --- a/src/StateService/MPT/HashNode.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Neo.IO; -using System; -using System.IO; - -namespace Neo.Plugins.MPT -{ - public class HashNode : MPTNode - { - private UInt256 hash; - - public override UInt256 Hash => hash; - protected override NodeType Type => NodeType.HashNode; - public bool IsEmpty => Hash is null; - public static HashNode EmptyNode { get; } = new HashNode(); - - public HashNode() - { - } - - public HashNode(UInt256 hash) - { - this.hash = hash; - } - - internal override void EncodeSpecific(BinaryWriter writer) - { - WriteHash(writer, hash); - } - - internal override void DecodeSpecific(BinaryReader reader) - { - byte[] buffer = reader.ReadVarBytes(UInt256.Length); - hash = buffer.Length switch - { - 0 => null, - UInt256.Length => new UInt256(buffer), - _ => throw new FormatException() - }; - } - } -} diff --git a/src/StateService/MPT/LeafNode.cs b/src/StateService/MPT/LeafNode.cs deleted file mode 100644 index 2a17ef4e2..000000000 --- a/src/StateService/MPT/LeafNode.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Neo.IO; -using Neo.SmartContract; -using System; -using System.IO; - -namespace Neo.Plugins.MPT -{ - public class LeafNode : MPTNode - { - //the max size when store StorageItem - public const int MaxValueLength = 3 + ApplicationEngine.MaxStorageValueSize + sizeof(bool); - - public byte[] Value; - - protected override NodeType Type => NodeType.LeafNode; - - public LeafNode() - { - } - - public LeafNode(ReadOnlySpan value) - { - Value = value.ToArray(); - } - - internal override void EncodeSpecific(BinaryWriter writer) - { - writer.WriteVarBytes(Value); - } - - internal override void DecodeSpecific(BinaryReader reader) - { - Value = reader.ReadVarBytes(MaxValueLength); - } - } -} From 615b9743b19d52330138adada0dc067691054658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 17 Dec 2020 14:36:18 -0600 Subject: [PATCH 19/24] Transfer bug fix (#429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) (#416) * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao * Nep17 (#412) * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * String Substitution * Modify filename and name methods * update * update * Update src/RpcClient/Models/RpcNep5TokenInfo.cs Co-authored-by: Vitor Nazário Coelho * Update src/RpcClient/Nep17API.cs Co-authored-by: Vitor Nazário Coelho * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) * Update Nep17API.cs * Update README.md Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> * update filename * Fix UT * Format * fix * update * update UT * Add Unit Tests * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao * merge * fixed bug * clear * UT * Add a little code coverage Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao --- src/Directory.Build.props | 2 +- src/RpcClient/Nep17API.cs | 4 ++-- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 8 ++++---- tests/Neo.Network.RPC.Tests/UT_Nep17API.cs | 10 +++++----- tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 1 + tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs | 6 +++--- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7668491fb..ae97d5e4a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/RpcClient/Nep17API.cs b/src/RpcClient/Nep17API.cs index 50650ade6..69a3b7d53 100644 --- a/src/RpcClient/Nep17API.cs +++ b/src/RpcClient/Nep17API.cs @@ -110,7 +110,7 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); + byte[] script = scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); @@ -137,7 +137,7 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, var sender = Contract.CreateMultiSigContract(m, pubKeys).ScriptHash; Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); + byte[] script = scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index c6c2228b2..1e97c3832 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -433,7 +433,7 @@ "jsonrpc": "2.0", "id": 1, "method": "getcontractstate", - "params": [ "0x74c21a1ca66b7a190bf2a65db83ba6fe550cea64" ] + "params": [ "0x0a46e2e37c9987f570b4af253fb77e7eef0f72b6" ] }, "Response": { "jsonrpc": "2.0", @@ -441,10 +441,10 @@ "result": { "id": -1, "updatecounter": 0, - "hash": "0x74c21a1ca66b7a190bf2a65db83ba6fe550cea64", - "script": "DANORU9BGvd7Zw==", + "hash": "0x0a46e2e37c9987f570b4af253fb77e7eef0f72b6", + "script": "DAhOZW9Ub2tlbkEa93tn", "manifest": { - "name": "NEO", + "name": "NeoToken", "groups": [], "supportedstandards": [ "NEP-17" diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs index f48a6eea4..a4f2d93f8 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs @@ -98,21 +98,21 @@ public async Task TestGetTokenInfo() .ReturnsAsync(test.Response.Result) .Verifiable(); - if (test.Request.Params[0].AsString() == "0xb399c051778cf37a1e4ef88509b2e054d0420a32") + if (test.Request.Params[0].AsString() == "0xa6a6c15dcdc9b997dac448b6926522d22efeedfb") { var result = await nep17API.GetTokenInfoAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); Assert.AreEqual(8, (int)result.Decimals); Assert.AreEqual(1_00000000, (int)result.TotalSupply); - Assert.AreEqual("GAS", result.Name); + Assert.AreEqual("GasToken", result.Name); } - else if (test.Request.Params[0].AsString() == "0x74c21a1ca66b7a190bf2a65db83ba6fe550cea64") + else if (test.Request.Params[0].AsString() == "0x0a46e2e37c9987f570b4af253fb77e7eef0f72b6") { var result = await nep17API.GetTokenInfoAsync(NativeContract.NEO.Hash); Assert.AreEqual(NativeContract.NEO.Symbol, result.Symbol); Assert.AreEqual(0, (int)result.Decimals); Assert.AreEqual(1_00000000, (int)result.TotalSupply); - Assert.AreEqual("NEO", result.Name); + Assert.AreEqual("NeoToken", result.Name); } } } @@ -120,7 +120,7 @@ public async Task TestGetTokenInfo() [TestMethod] public async Task TestTransfer() { - byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000)); + byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000), null); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); var result = await nep17API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index 69ba8caaf..f4f2f5c12 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -294,6 +294,7 @@ public async Task TestGetUnclaimedGas() { var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetUnclaimedGasAsync).ToLower()); var result = await rpc.GetUnclaimedGasAsync(test.Request.Params[0].AsString()); + Assert.AreEqual(result.ToJson().AsString(), RpcUnclaimedGas.FromJson(result.ToJson()).ToJson().AsString()); Assert.AreEqual(test.Response.Result["unclaimed"].AsString(), result.Unclaimed.ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs index 721b53fef..7ec348ebe 100644 --- a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs @@ -79,7 +79,7 @@ public async Task TestClaimGas() byte[] balanceScript = NativeContract.NEO.Hash.MakeScript("balanceOf", sender); UT_TransactionManager.MockInvokeScript(rpcClientMock, balanceScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - byte[] testScript = NativeContract.NEO.Hash.MakeScript("transfer", sender, sender, new BigInteger(1_00000000)); + byte[] testScript = NativeContract.NEO.Hash.MakeScript("transfer", sender, sender, new BigInteger(1_00000000), null); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); var json = new JObject(); @@ -96,7 +96,7 @@ public async Task TestTransfer() byte[] decimalsScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, decimalsScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(8) }); - byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, NativeContract.GAS.Factor * 100); + byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, NativeContract.GAS.Factor * 100, null); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); var json = new JObject(); @@ -118,7 +118,7 @@ public async Task TestTransferfromMultiSigAccount() byte[] decimalsScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, decimalsScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(8) }); - byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", multiSender, UInt160.Zero, NativeContract.GAS.Factor * 100); + byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", multiSender, UInt160.Zero, NativeContract.GAS.Factor * 100, null); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); var json = new JObject(); From 33141c1658e6b4f2e0d2d3a9370f559c175724d3 Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:37:07 +0800 Subject: [PATCH 20/24] Preview4 (#430) * Preview4 * Remove syslog in README.md --- README.md | 3 --- src/Directory.Build.props | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 95f0e3526..0919ba2fd 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,6 @@ The resulting folder structure is going to be like this: ### ApplicationLogs Add this plugin to your application if need to access the log files. This can be useful to handle notifications, but remember that this also largely increases the space used by the application. `LevelDBStore` and `RpcServer` are also needed for this plugin. You can find more details [here](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getapplicationlog.html). -### SystemLog -Enable neo-cli Logging with timestamps by showing messages with different levels (shown with different colors) \(useful for debugging\). - ### StatesDumper Exports neo-cli status data \(useful for debugging\), such as storage modifications block by block. diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ae97d5e4a..28635c471 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ 3.0.0 - preview3 + preview4 netstandard2.1 Neo.Plugins The Neo Project @@ -15,7 +15,7 @@ - + \ No newline at end of file From ae42b948a2037cd2c7c6246a191f29126c3722bb Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 22 Dec 2020 11:36:27 +0800 Subject: [PATCH 21/24] CI01122 --- Directory.Build.props | 6 ++-- src/RpcClient/ContractClient.cs | 4 +-- src/RpcNep17Tracker/RpcNep17Tracker.cs | 3 +- src/RpcServer/RpcServer.Blockchain.cs | 4 +-- src/RpcServer/RpcServer.SmartContract.cs | 2 +- .../UT_ContractClient.cs | 4 +-- .../Neo.Plugins.StateService.Tests.csproj | 35 +++++++++---------- 7 files changed, 28 insertions(+), 30 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 0d11eede8..d2c7dfa9c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,4 +1,4 @@ - + @@ -15,7 +15,7 @@ - + - \ No newline at end of file + diff --git a/src/RpcClient/ContractClient.cs b/src/RpcClient/ContractClient.cs index bc664c82f..296c2e12b 100644 --- a/src/RpcClient/ContractClient.cs +++ b/src/RpcClient/ContractClient.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; @@ -6,6 +5,7 @@ using Neo.SmartContract.Native; using Neo.VM; using Neo.Wallets; +using System.Threading.Tasks; namespace Neo.Network.RPC { @@ -57,7 +57,7 @@ public async Task CreateDeployContractTxAsync(byte[] nefFile, Contr byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(NativeContract.Management.Hash, "deploy", nefFile, manifest.ToString()); + sb.EmitAppCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest.ToString()); script = sb.ToArray(); } UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.cs b/src/RpcNep17Tracker/RpcNep17Tracker.cs index 9dcef2318..79fbafa7c 100644 --- a/src/RpcNep17Tracker/RpcNep17Tracker.cs +++ b/src/RpcNep17Tracker/RpcNep17Tracker.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Http; using Neo.IO; using Neo.IO.Caching; using Neo.IO.Data.LevelDB; @@ -287,7 +286,7 @@ public JObject GetNep17Balances(JArray _params) foreach (var (key, value) in dbCache.Find(prefix)) { JObject balance = new JObject(); - if (NativeContract.Management.GetContract(snapshot, key.AssetScriptHash) is null) + if (NativeContract.ContractManagement.GetContract(snapshot, key.AssetScriptHash) is null) continue; balance["assethash"] = key.AssetScriptHash.ToString(); balance["amount"] = value.Balance.ToString(); diff --git a/src/RpcServer/RpcServer.Blockchain.cs b/src/RpcServer/RpcServer.Blockchain.cs index adccfbf38..16eb2a990 100644 --- a/src/RpcServer/RpcServer.Blockchain.cs +++ b/src/RpcServer/RpcServer.Blockchain.cs @@ -106,7 +106,7 @@ protected virtual JObject GetContractState(JArray _params) { using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = ToScriptHash(_params[0].AsString()); - ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); + ContractState contract = NativeContract.ContractManagement.GetContract(snapshot, script_hash); return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"); } @@ -170,7 +170,7 @@ protected virtual JObject GetStorage(JArray _params) { using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = UInt160.Parse(_params[0].AsString()); - ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); + ContractState contract = NativeContract.ContractManagement.GetContract(snapshot, script_hash); if (contract == null) return null; id = contract.Id; } diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index ca635f896..475a12bf6 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -110,7 +110,7 @@ private static Signers SignersFromJson(JArray _params) private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signers signers = null) { var snapshot = Blockchain.Singleton.GetSnapshot(); - var contract = NativeContract.Management.GetContract(snapshot, scriptHash); + var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash); if (contract is null) { throw new RpcException(-100, "Unknown contract"); diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index 0de9a0958..06b331595 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Neo.SmartContract; @@ -6,6 +5,7 @@ using Neo.SmartContract.Native; using Neo.VM; using Neo.Wallets; +using System.Threading.Tasks; namespace Neo.Network.RPC.Tests { @@ -55,7 +55,7 @@ public async Task TestDeployContract() }; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(NativeContract.Management.Hash, "deploy", new byte[1], manifest.ToString()); + sb.EmitAppCall(NativeContract.ContractManagement.Hash, "deploy", new byte[1], manifest.ToString()); script = sb.ToArray(); } diff --git a/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj index 4f0dfa232..e5481279c 100644 --- a/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj +++ b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj @@ -1,18 +1,17 @@ - - - - netcoreapp3.0 - Neo.Plugins.StateService.Tests - false - - - - - - - - - - - - + + + + Neo.Plugins.StateService.Tests + false + + + + + + + + + + + + From c777eba6d73af99ba30d04be6000f7a1cf508eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Tue, 22 Dec 2020 11:42:04 +0800 Subject: [PATCH 22/24] Keep up to date with neo --- Directory.Build.props | 2 +- src/RpcClient/ContractClient.cs | 2 +- src/RpcServer/RpcServer.Blockchain.cs | 4 ++-- src/RpcServer/RpcServer.SmartContract.cs | 2 +- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 16 +++++++++------- tests/Neo.Network.RPC.Tests/UT_ContractClient.cs | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 0d11eede8..72db189b5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/RpcClient/ContractClient.cs b/src/RpcClient/ContractClient.cs index bc664c82f..d103ec191 100644 --- a/src/RpcClient/ContractClient.cs +++ b/src/RpcClient/ContractClient.cs @@ -57,7 +57,7 @@ public async Task CreateDeployContractTxAsync(byte[] nefFile, Contr byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(NativeContract.Management.Hash, "deploy", nefFile, manifest.ToString()); + sb.EmitAppCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest.ToString()); script = sb.ToArray(); } UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); diff --git a/src/RpcServer/RpcServer.Blockchain.cs b/src/RpcServer/RpcServer.Blockchain.cs index adccfbf38..16eb2a990 100644 --- a/src/RpcServer/RpcServer.Blockchain.cs +++ b/src/RpcServer/RpcServer.Blockchain.cs @@ -106,7 +106,7 @@ protected virtual JObject GetContractState(JArray _params) { using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = ToScriptHash(_params[0].AsString()); - ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); + ContractState contract = NativeContract.ContractManagement.GetContract(snapshot, script_hash); return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"); } @@ -170,7 +170,7 @@ protected virtual JObject GetStorage(JArray _params) { using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = UInt160.Parse(_params[0].AsString()); - ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); + ContractState contract = NativeContract.ContractManagement.GetContract(snapshot, script_hash); if (contract == null) return null; id = contract.Id; } diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index ca635f896..475a12bf6 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -110,7 +110,7 @@ private static Signers SignersFromJson(JArray _params) private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signers signers = null) { var snapshot = Blockchain.Singleton.GetSnapshot(); - var contract = NativeContract.Management.GetContract(snapshot, scriptHash); + var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash); if (contract is null) { throw new RpcException(-100, "Unknown contract"); diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 1e97c3832..c62c64d5e 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -1112,24 +1112,26 @@ "Name": "invokescriptasync", "Request": { "jsonrpc": "2.0", + "id": 1, "method": "invokescript", - "params": [ "EMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS" ], - "id": 1 + "params": [ + "HxDDDAhkZWNpbWFscwwU\u002B\u002B3\u002BLtIiZZK2SMTal7nJzV3BpqZB7vQM2w==" + ] }, "Response": { "jsonrpc": "2.0", "id": 1, "result": { - "script": "EMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS", + "script": "HxDDDAhkZWNpbWFscwwU++3+LtIiZZK2SMTal7nJzV3BpqZB7vQM2w==", "state": "HALT", - "gasconsumed": "0.0506156", + "gasconsumed": "0.0099918", + "exception": null, "stack": [ { "type": "Integer", "value": "8" } - ], - "tx": "00769d16556925aa554712439a9c613ba114efa3fac23ddbca00e1f505000000009e021400000000005620200000009910c30c046e616d650c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0673796d626f6c0c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c08646563696d616c730c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0b746f74616c537570706c790c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5201420c40c848d0fcbf5e6a820508242ea8b7ccbeed3caefeed5db570537279c2154f7cfd8b0d8f477f37f4e6ca912935b732684d57c455dff7aa525ad4ab000931f22208290c2103aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a0b410a906ad4" + ] } } }, @@ -1152,7 +1154,7 @@ "Request": { "jsonrpc": "2.0", "method": "getwalletbalance", - "params": [ "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b" ], + "params": [ "0xa6a6c15dcdc9b997dac448b6926522d22efeedfb" ], "id": 1 }, "Response": { diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index 0de9a0958..f29b09f08 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -55,7 +55,7 @@ public async Task TestDeployContract() }; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(NativeContract.Management.Hash, "deploy", new byte[1], manifest.ToString()); + sb.EmitAppCall(NativeContract.ContractManagement.Hash, "deploy", new byte[1], manifest.ToString()); script = sb.ToArray(); } From 350ae199477782603fb24b014c1abe28b104a81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Tue, 22 Dec 2020 11:46:23 +0800 Subject: [PATCH 23/24] 1122 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index c8dcf12f9..d2c7dfa9c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,7 +15,7 @@ - + From 550d38e3eab8a98fc20d743cd8c09c72ffa24f7c Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 22 Dec 2020 11:53:24 +0800 Subject: [PATCH 24/24] Update Directory.Build.props --- .../Directory.Build.props | 0 tests/Directory.Build.props | 15 +++++++++++++++ .../Neo.Network.RPC.Tests.csproj | 4 ---- .../Neo.Plugins.StateService.Tests.csproj | 7 ------- .../Neo.Plugins.Storage.Tests.csproj | 7 ------- 5 files changed, 15 insertions(+), 18 deletions(-) rename Directory.Build.props => src/Directory.Build.props (100%) create mode 100644 tests/Directory.Build.props diff --git a/Directory.Build.props b/src/Directory.Build.props similarity index 100% rename from Directory.Build.props rename to src/Directory.Build.props diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props new file mode 100644 index 000000000..3a7fa1350 --- /dev/null +++ b/tests/Directory.Build.props @@ -0,0 +1,15 @@ + + + + + net5.0 + false + + + + + + + + + diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index b019b5b47..3209d575a 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -2,14 +2,10 @@ Neo.Network.RPC.Tests - false - - - diff --git a/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj index e5481279c..94b2e2355 100644 --- a/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj +++ b/tests/Neo.Plugins.StateService.Tests/Neo.Plugins.StateService.Tests.csproj @@ -2,15 +2,8 @@ Neo.Plugins.StateService.Tests - false - - - - - - diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index 6a68865f3..c6798b71a 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -2,15 +2,8 @@ Neo.Plugins.Storage.Tests - false - - - - - -