diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3dae25a1df..dca46dbbd6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,12 +7,30 @@ on:
env:
DOTNET_VERSION: 8.0.x
- COVERALL_COLLECT_OUTPUT: "/p:CollectCoverage=true /p:CoverletOutput='${{ github.workspace }}/TestResults/coverage/'"
- COVERALL_MERGE_PATH: "/p:MergeWith='${{ github.workspace }}/TestResults/coverage/coverage.json'"
jobs:
+ Format:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+
+ - name: Check Format (*.cs)
+ run: dotnet format --verify-no-changes --verbosity diagnostic
+
+ - name: Build (Neo.CLI)
+ run: |
+ dotnet build ./src/Neo.CLI \
+ --output ./out/Neo.CLI
+
Test:
+ needs: [Format]
timeout-minutes: 15
strategy:
matrix:
@@ -25,14 +43,6 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- - name: Check format
- if: matrix.os == 'ubuntu-latest'
- run: |
- dotnet format --verify-no-changes --verbosity diagnostic
- - name: Build CLI
- if: matrix.os == 'ubuntu-latest'
- run: |
- dotnet publish ./src/Neo.CLI
- name: Test
if: matrix.os != 'ubuntu-latest'
run: |
@@ -42,31 +52,40 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get --assume-yes install libleveldb-dev librocksdb-dev
-
- dotnet test ./tests/Neo.Cryptography.BLS12_381.Tests ${{ env.COVERALL_COLLECT_OUTPUT }}
- dotnet test ./tests/Neo.ConsoleService.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.UnitTests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.VM.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.Json.UnitTests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
+
+ dotnet test ./tests/Neo.Cryptography.BLS12_381.Tests --output ./bin/tests/Neo.Cryptography.BLS12_381.Tests
+ dotnet test ./tests/Neo.ConsoleService.Tests --output ./bin/tests/Neo.ConsoleService.Tests
+ dotnet test ./tests/Neo.UnitTests --output ./bin/tests/Neo.UnitTests
+ dotnet test ./tests/Neo.VM.Tests --output ./bin/tests/Neo.VM.Tests
+ dotnet test ./tests/Neo.Json.UnitTests --output ./bin/tests/Neo.Json.UnitTests
# Plugins
- dotnet test ./tests/Neo.Cryptography.MPTTrie.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.Network.RPC.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.Plugins.OracleService.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.Plugins.RpcServer.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }}
- dotnet test ./tests/Neo.Plugins.Storage.Tests ${{ env.COVERALL_COLLECT_OUTPUT }} ${{ env.COVERALL_MERGE_PATH }} /p:CoverletOutputFormat='cobertura'
+ dotnet test ./tests/Neo.Cryptography.MPTTrie.Tests --output ./bin/tests/Neo.Cryptography.MPTTrie.Tests
+ dotnet test ./tests/Neo.Network.RPC.Tests --output ./bin/tests/Neo.Network.RPC.Tests
+ dotnet test ./tests/Neo.Plugins.OracleService.Tests --output ./bin/tests/Neo.Plugins.OracleService.Tests
+ dotnet test ./tests/Neo.Plugins.RpcServer.Tests --output ./bin/tests/Neo.Plugins.RpcServer.Tests
+ dotnet test ./tests/Neo.Plugins.Storage.Tests --output ./bin/tests/Neo.Plugins.Storage.Tests
- name: Coveralls
if: matrix.os == 'ubuntu-latest'
uses: coverallsapp/github-action@v2.3.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- format: cobertura
- file: ${{ github.workspace }}/TestResults/coverage/coverage.cobertura.xml
+ files:
+ ${{ github.workspace }}/tests/Neo.Cryptography.BLS12_381.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.ConsoleService.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.UnitTests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.VM.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Json.UnitTests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Cryptography.MPTTrie.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Network.RPC.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Plugins.OracleService.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Plugins.RpcServer.Tests/TestResults/coverage.info
+ ${{ github.workspace }}/tests/Neo.Plugins.Storage.Tests/TestResults/coverage.info
PublishPackage:
if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
- needs: Test
+ needs: [Test]
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -115,7 +134,7 @@ jobs:
Release:
if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
- needs: Test
+ needs: [Test]
runs-on: ubuntu-latest
steps:
- name: Checkout
diff --git a/neo.sln b/neo.sln
index 46ff7c64e8..b0de1c27b1 100644
--- a/neo.sln
+++ b/neo.sln
@@ -70,8 +70,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcServer", "src\Plugins\Rp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SQLiteWallet", "src\Plugins\SQLiteWallet\SQLiteWallet.csproj", "{F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatesDumper", "src\Plugins\StatesDumper\StatesDumper.csproj", "{90CCA7D4-C277-4112-A036-BBB90C3FE3BE}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StateService", "src\Plugins\StateService\StateService.csproj", "{88975A8D-4797-45A4-BC3E-15962A425A54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StorageDumper", "src\Plugins\StorageDumper\StorageDumper.csproj", "{FF76D8A4-356B-461A-8471-BC1B83E57BBC}"
@@ -202,10 +200,6 @@ Global
{F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|Any CPU.Build.0 = Release|Any CPU
- {90CCA7D4-C277-4112-A036-BBB90C3FE3BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {90CCA7D4-C277-4112-A036-BBB90C3FE3BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {90CCA7D4-C277-4112-A036-BBB90C3FE3BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {90CCA7D4-C277-4112-A036-BBB90C3FE3BE}.Release|Any CPU.Build.0 = Release|Any CPU
{88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88975A8D-4797-45A4-BC3E-15962A425A54}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -257,7 +251,6 @@ Global
{3DE59148-59D6-4CD3-8086-0BC74E3D4E0B} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{A3941551-E72C-42D7-8C4D-5122CB60D73D} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1} = {C2DC830A-327A-42A7-807D-295216D30DBB}
- {90CCA7D4-C277-4112-A036-BBB90C3FE3BE} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{88975A8D-4797-45A4-BC3E-15962A425A54} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{FF76D8A4-356B-461A-8471-BC1B83E57BBC} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{5E4947F3-05D3-4806-B0F3-30DAC71B5986} = {C2DC830A-327A-42A7-807D-295216D30DBB}
diff --git a/src/Neo.CLI/CLI/MainService.Blockchain.cs b/src/Neo.CLI/CLI/MainService.Blockchain.cs
index 9f5d40daa7..8a32eb8023 100644
--- a/src/Neo.CLI/CLI/MainService.Blockchain.cs
+++ b/src/Neo.CLI/CLI/MainService.Blockchain.cs
@@ -137,9 +137,9 @@ public void OnShowTransactionCommand(UInt256 hash)
ConsoleHelper.Info("", " Nonce: ", $"{tx.Transaction.Nonce}");
ConsoleHelper.Info("", " Sender: ", $"{tx.Transaction.Sender}");
ConsoleHelper.Info("", " ValidUntilBlock: ", $"{tx.Transaction.ValidUntilBlock}");
- ConsoleHelper.Info("", " FeePerByte: ", $"{tx.Transaction.FeePerByte}");
- ConsoleHelper.Info("", " NetworkFee: ", $"{tx.Transaction.NetworkFee}");
- ConsoleHelper.Info("", " SystemFee: ", $"{tx.Transaction.SystemFee}");
+ ConsoleHelper.Info("", " FeePerByte: ", $"{tx.Transaction.FeePerByte} datoshi");
+ ConsoleHelper.Info("", " NetworkFee: ", $"{tx.Transaction.NetworkFee} datoshi");
+ ConsoleHelper.Info("", " SystemFee: ", $"{tx.Transaction.SystemFee} datoshi");
ConsoleHelper.Info("", " Script: ", $"{Convert.ToBase64String(tx.Transaction.Script.Span)}");
ConsoleHelper.Info("", " Version: ", $"{tx.Transaction.Version}");
ConsoleHelper.Info("", " BlockIndex: ", $"{block.Index}");
diff --git a/src/Neo.CLI/CLI/MainService.Contracts.cs b/src/Neo.CLI/CLI/MainService.Contracts.cs
index 94fbe32f89..684b3330bc 100644
--- a/src/Neo.CLI/CLI/MainService.Contracts.cs
+++ b/src/Neo.CLI/CLI/MainService.Contracts.cs
@@ -46,8 +46,8 @@ private void OnDeployCommand(string filePath, string? manifestPath = null, JObje
UInt160 hash = SmartContract.Helper.GetContractHash(tx.Sender, nef.CheckSum, manifest.Name);
ConsoleHelper.Info("Contract hash: ", $"{hash}");
- ConsoleHelper.Info("Gas consumed: ", $"{new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)}");
- ConsoleHelper.Info("Network fee: ", $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)}");
+ ConsoleHelper.Info("Gas consumed: ", $"{new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)} GAS");
+ ConsoleHelper.Info("Network fee: ", $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)} GAS");
ConsoleHelper.Info("Total fee: ", $"{new BigDecimal((BigInteger)(tx.SystemFee + tx.NetworkFee), NativeContract.GAS.Decimals)} GAS");
if (!ConsoleHelper.ReadUserInput("Relay tx? (no|yes)").IsYes()) // Add this in case just want to get hash but not relay
{
@@ -108,8 +108,8 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes
{
ConsoleHelper.Info("Contract hash: ", $"{scriptHash}");
ConsoleHelper.Info("Updated times: ", $"{contract.UpdateCounter}");
- ConsoleHelper.Info("Gas consumed: ", $"{new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)}");
- ConsoleHelper.Info("Network fee: ", $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)}");
+ ConsoleHelper.Info("Gas consumed: ", $"{new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)} GAS");
+ ConsoleHelper.Info("Network fee: ", $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)} GAS");
ConsoleHelper.Info("Total fee: ", $"{new BigDecimal((BigInteger)(tx.SystemFee + tx.NetworkFee), NativeContract.GAS.Decimals)} GAS");
if (!ConsoleHelper.ReadUserInput("Relay tx? (no|yes)").IsYes()) // Add this in case just want to get hash but not relay
{
@@ -127,11 +127,12 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes
/// Contract parameters
/// Transaction's sender
/// Signer's accounts
- /// Max fee for running the script
+ /// Max fee for running the script, in the unit of GAS
[ConsoleCommand("invoke", Category = "Contract Commands")]
private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray? contractParameters = null, UInt160? sender = null, UInt160[]? signerAccounts = null, decimal maxGas = 20)
{
- var gas = new BigDecimal(maxGas, NativeContract.GAS.Decimals);
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
+ var datoshi = new BigDecimal(maxGas, NativeContract.GAS.Decimals);
Signer[] signers = Array.Empty();
if (!NoWallet())
{
@@ -163,12 +164,12 @@ private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray? contr
Witnesses = Array.Empty(),
};
- if (!OnInvokeWithResult(scriptHash, operation, out _, tx, contractParameters, gas: (long)gas.Value)) return;
+ if (!OnInvokeWithResult(scriptHash, operation, out _, tx, contractParameters, datoshi: (long)datoshi.Value)) return;
if (NoWallet()) return;
try
{
- tx = CurrentWallet!.MakeTransaction(NeoSystem.StoreView, tx.Script, sender, signers, maxGas: (long)gas.Value);
+ tx = CurrentWallet!.MakeTransaction(NeoSystem.StoreView, tx.Script, sender, signers, maxGas: (long)datoshi.Value);
}
catch (InvalidOperationException e)
{
@@ -176,7 +177,7 @@ private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray? contr
return;
}
ConsoleHelper.Info("Network fee: ",
- $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)}\t",
+ $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)} GAS\t",
"Total fee: ",
$"{new BigDecimal((BigInteger)(tx.SystemFee + tx.NetworkFee), NativeContract.GAS.Decimals)} GAS");
if (!ConsoleHelper.ReadUserInput("Relay tx? (no|yes)").IsYes())
diff --git a/src/Neo.CLI/CLI/MainService.Plugins.cs b/src/Neo.CLI/CLI/MainService.Plugins.cs
index 5b346fc33c..a73cdcb31e 100644
--- a/src/Neo.CLI/CLI/MainService.Plugins.cs
+++ b/src/Neo.CLI/CLI/MainService.Plugins.cs
@@ -228,24 +228,28 @@ private void OnPluginsCommand()
{
try
{
- var plugins = GetPluginListAsync().GetAwaiter().GetResult();
- if (plugins == null) return;
- plugins
- .Order()
- .ForEach(f =>
+ var plugins = GetPluginListAsync().GetAwaiter().GetResult()?.ToArray() ?? [];
+ var installedPlugins = Plugin.Plugins.ToList();
+
+ var maxLength = installedPlugins.Count == 0 ? 0 : installedPlugins.Max(s => s.Name.Length);
+ if (plugins.Length > 0)
{
- var installedPlugin = Plugin.Plugins.SingleOrDefault(pp => string.Equals(pp.Name, f, StringComparison.CurrentCultureIgnoreCase));
- if (installedPlugin != null)
+ maxLength = Math.Max(maxLength, plugins.Max(s => s.Length));
+ }
+
+ plugins.Select(s => (name: s, installedPlugin: Plugin.Plugins.SingleOrDefault(pp => string.Equals(pp.Name, s, StringComparison.InvariantCultureIgnoreCase))))
+ .Concat(installedPlugins.Select(u => (name: u.Name, installedPlugin: (Plugin?)u)).Where(u => !plugins.Contains(u.name, StringComparer.InvariantCultureIgnoreCase)))
+ .OrderBy(u => u.name)
+ .ForEach((f) =>
{
- var maxLength = plugins.Select(s => s.Length).OrderDescending().First();
- string tabs = string.Empty;
- if (f.Length < maxLength)
- tabs = "\t";
- ConsoleHelper.Info("", $"[Installed]\t {f,6}{tabs}", " @", $"{installedPlugin.Version.ToString(3)} {installedPlugin.Description}");
- }
- else
- ConsoleHelper.Info($"[Not Installed]\t {f}");
- });
+ if (f.installedPlugin != null)
+ {
+ var tabs = f.name.Length < maxLength ? "\t" : string.Empty;
+ ConsoleHelper.Info("", $"[Installed]\t {f.name,6}{tabs}", " @", $"{f.installedPlugin.Version.ToString(3)} {f.installedPlugin.Description}");
+ }
+ else
+ ConsoleHelper.Info($"[Not Installed]\t {f.name}");
+ });
}
catch (Exception ex)
{
diff --git a/src/Neo.CLI/CLI/MainService.Wallet.cs b/src/Neo.CLI/CLI/MainService.Wallet.cs
index 4f65390f85..db33e89564 100644
--- a/src/Neo.CLI/CLI/MainService.Wallet.cs
+++ b/src/Neo.CLI/CLI/MainService.Wallet.cs
@@ -626,7 +626,7 @@ private void OnCancelCommand(UInt256 txid, UInt160? sender = null, UInt160[]? si
{
var snapshot = NeoSystem.StoreView;
AssetDescriptor descriptor = new(snapshot, NeoSystem.Settings, NativeContract.GAS.Hash);
- string extracFee = ConsoleHelper.ReadUserInput("This tx is not in mempool, please input extra fee manually");
+ string extracFee = ConsoleHelper.ReadUserInput("This tx is not in mempool, please input extra fee (datoshi) manually");
if (!BigDecimal.TryParse(extracFee, descriptor.Decimals, out BigDecimal decimalExtraFee) || decimalExtraFee.Sign <= 0)
{
ConsoleHelper.Error("Incorrect Amount Format");
@@ -636,7 +636,7 @@ private void OnCancelCommand(UInt256 txid, UInt160? sender = null, UInt160[]? si
};
ConsoleHelper.Info("Network fee: ",
- $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)}\t",
+ $"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)} GAS\t",
"Total fee: ",
$"{new BigDecimal((BigInteger)(tx.SystemFee + tx.NetworkFee), NativeContract.GAS.Decimals)} GAS");
if (!ConsoleHelper.ReadUserInput("Relay tx? (no|yes)").IsYes())
diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs
index efe48b0165..7e96af9e85 100644
--- a/src/Neo.CLI/CLI/MainService.cs
+++ b/src/Neo.CLI/CLI/MainService.cs
@@ -375,7 +375,18 @@ public async void Start(CommandLineOptions options)
ProtocolSettings protocol = ProtocolSettings.Load("config.json");
CustomProtocolSettings(options, protocol);
CustomApplicationSettings(options, Settings.Default);
- NeoSystem = new NeoSystem(protocol, Settings.Default.Storage.Engine, string.Format(Settings.Default.Storage.Path, protocol.Network.ToString("X8")));
+ try
+ {
+ NeoSystem = new NeoSystem(protocol, Settings.Default.Storage.Engine, string.Format(Settings.Default.Storage.Path, protocol.Network.ToString("X8")));
+ }
+ catch (DllNotFoundException)
+ {
+ ConsoleHelper.Error("DLL not found, please install Microsoft Visual C++ Redistributable." + Environment.NewLine +
+ "See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist" + Environment.NewLine +
+ "Press any key to exit.");
+ Console.ReadKey();
+ Environment.Exit(-1);
+ }
NeoSystem.AddService(this);
LocalNode = NeoSystem.LocalNode.Ask(new LocalNode.GetInstance()).Result;
@@ -515,8 +526,8 @@ private static void WriteLineWithoutFlicker(string message = "", int maxWidth =
///
/// script
/// sender
- /// Max fee for running the script
- private void SendTransaction(byte[] script, UInt160? account = null, long gas = TestModeGas)
+ /// Max fee for running the script, in the unit of datoshi, 1 datoshi = 1e-8 GAS
+ private void SendTransaction(byte[] script, UInt160? account = null, long datoshi = TestModeGas)
{
if (NoWallet()) return;
@@ -533,10 +544,10 @@ private void SendTransaction(byte[] script, UInt160? account = null, long gas =
try
{
- Transaction tx = CurrentWallet!.MakeTransaction(snapshot, script, account, signers, maxGas: gas);
+ Transaction tx = CurrentWallet!.MakeTransaction(snapshot, script, account, signers, maxGas: datoshi);
ConsoleHelper.Info("Invoking script with: ", $"'{Convert.ToBase64String(tx.Script.Span)}'");
- using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, snapshot, container: tx, settings: NeoSystem.Settings, gas: gas))
+ using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, snapshot, container: tx, settings: NeoSystem.Settings, gas: datoshi))
{
PrintExecutionOutput(engine, true);
if (engine.State == VMState.FAULT) return;
@@ -564,9 +575,9 @@ private void SendTransaction(byte[] script, UInt160? account = null, long gas =
/// Transaction
/// Contract parameters
/// Show result stack if it is true
- /// Max fee for running the script
+ /// Max fee for running the script, in the unit of datoshi, 1 datoshi = 1e-8 GAS
/// Return true if it was successful
- private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackItem result, IVerifiable? verifiable = null, JArray? contractParameters = null, bool showStack = true, long gas = TestModeGas)
+ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackItem result, IVerifiable? verifiable = null, JArray? contractParameters = null, bool showStack = true, long datoshi = TestModeGas)
{
List parameters = new();
@@ -612,7 +623,7 @@ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackI
tx.Script = script;
}
- using ApplicationEngine engine = ApplicationEngine.Run(script, NeoSystem.StoreView, container: verifiable, settings: NeoSystem.Settings, gas: gas);
+ using ApplicationEngine engine = ApplicationEngine.Run(script, NeoSystem.StoreView, container: verifiable, settings: NeoSystem.Settings, gas: datoshi);
PrintExecutionOutput(engine, showStack);
result = engine.State == VMState.FAULT ? StackItem.Null : engine.ResultStack.Peek();
return engine.State != VMState.FAULT;
@@ -621,7 +632,7 @@ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackI
private void PrintExecutionOutput(ApplicationEngine engine, bool showStack = true)
{
ConsoleHelper.Info("VM State: ", engine.State.ToString());
- ConsoleHelper.Info("Gas Consumed: ", new BigDecimal((BigInteger)engine.GasConsumed, NativeContract.GAS.Decimals).ToString());
+ ConsoleHelper.Info("Gas Consumed: ", new BigDecimal((BigInteger)engine.FeeConsumed, NativeContract.GAS.Decimals).ToString());
if (showStack)
ConsoleHelper.Info("Result Stack: ", new JArray(engine.ResultStack.Select(p => p.ToJson())).ToString());
diff --git a/src/Neo.CLI/Neo.CLI.csproj b/src/Neo.CLI/Neo.CLI.csproj
index bb52675ec4..a9d4c9919e 100644
--- a/src/Neo.CLI/Neo.CLI.csproj
+++ b/src/Neo.CLI/Neo.CLI.csproj
@@ -10,6 +10,7 @@
Neo.CLI
neo.ico
enable
+ $(SolutionDir)/bin/$(AssemblyTitle)
diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json
index e79a31c312..6adb47eb03 100644
--- a/src/Neo.CLI/config.fs.mainnet.json
+++ b/src/Neo.CLI/config.fs.mainnet.json
@@ -6,8 +6,8 @@
"Active": false
},
"Storage": {
- "Engine": "LevelDBStore", // Candidates [MemoryStore, LevelDBStore, RocksDBStore]
- "Path": "Data_LevelDB_{0}" // {0} is a placeholder for the network id
+ "Engine": "LevelDBStore",
+ "Path": "Data_LevelDB_{0}"
},
"P2P": {
"Port": 40333,
diff --git a/src/Neo.CLI/config.fs.testnet.json b/src/Neo.CLI/config.fs.testnet.json
index b167f35b81..ca0f0225e6 100644
--- a/src/Neo.CLI/config.fs.testnet.json
+++ b/src/Neo.CLI/config.fs.testnet.json
@@ -6,8 +6,8 @@
"Active": false
},
"Storage": {
- "Engine": "LevelDBStore", // Candidates [MemoryStore, LevelDBStore, RocksDBStore]
- "Path": "Data_LevelDB_{0}" // {0} is a placeholder for the network id
+ "Engine": "LevelDBStore",
+ "Path": "Data_LevelDB_{0}"
},
"P2P": {
"Port": 50333,
diff --git a/src/Neo.CLI/config.json.md b/src/Neo.CLI/config.json.md
new file mode 100644
index 0000000000..da3bbaec6e
--- /dev/null
+++ b/src/Neo.CLI/config.json.md
@@ -0,0 +1,85 @@
+# README for Application and Protocol Configuration JSON File
+
+This README provides an explanation for each field in the JSON configuration file for a NEO node.
+
+## ApplicationConfiguration
+
+### Logger
+- **Path**: Directory where log files are stored. Default is "Logs".
+- **ConsoleOutput**: Boolean flag to enable or disable console output for logging. Default is `false`.
+- **Active**: Boolean flag to activate or deactivate the logger. Default is `false`.
+
+### Storage
+- **Engine**: Specifies the storage engine used by the node. Possible values are:
+ - `MemoryStore`
+ - `LevelDBStore`
+ - `RocksDBStore`
+- **Path**: Path to the data storage directory. `{0}` is a placeholder for the network ID.
+
+### P2P
+- **Port**: Port number for the P2P network. MainNet is `10333`, TestNet is `20333`.
+- **MinDesiredConnections**: Minimum number of desired P2P connections. Default is `10`.
+- **MaxConnections**: Maximum number of P2P connections. Default is `40`.
+- **MaxConnectionsPerAddress**: Maximum number of connections allowed per address. Default is `3`.
+
+### UnlockWallet
+- **Path**: Path to the wallet file.
+- **Password**: Password for the wallet.
+- **IsActive**: Boolean flag to activate or deactivate the wallet. Default is `false`.
+
+### Contracts
+- **NeoNameService**: Script hash of the Neo Name Service contract. MainNet is `0x50ac1c37690cc2cfc594472833cf57505d5f46de`, TestNet is `0x50ac1c37690cc2cfc594472833cf57505d5f46de`.
+
+### Plugins
+- **DownloadUrl**: URL to download plugins, typically from the NEO project's GitHub releases. Default is `https://api.github.com/repos/neo-project/neo/releases`.
+
+## ProtocolConfiguration
+
+### Network
+- **Network**: Network ID for the NEO network. MainNet is `860833102`, TestNet is `894710606`
+
+### AddressVersion
+- **AddressVersion**: Version byte used in NEO address generation. Default is `53`.
+
+### MillisecondsPerBlock
+- **MillisecondsPerBlock**: Time interval between blocks in milliseconds. Default is `15000` (15 seconds).
+
+### MaxTransactionsPerBlock
+- **MaxTransactionsPerBlock**: Maximum number of transactions allowed per block. Default is `512`.
+
+### MemoryPoolMaxTransactions
+- **MemoryPoolMaxTransactions**: Maximum number of transactions that can be held in the memory pool. Default is `50000`.
+
+### MaxTraceableBlocks
+- **MaxTraceableBlocks**: Maximum number of blocks that can be traced back. Default is `2102400`.
+
+### Hardforks
+- **HF_Aspidochelone**: Block height for the Aspidochelone hard fork. MainNet is `1730000`, TestNet is `210000`.
+- **HF_Basilisk**: Block height for the Basilisk hard fork. MainNet is `4120000`, TestNet is `2680000`.
+- **HF_Cockatrice**: Block height for the Cockatrice hard fork. MainNet is `5450000`, TestNet is `3967000`.
+
+### InitialGasDistribution
+- **InitialGasDistribution**: Total amount of GAS distributed initially. Default is `5,200,000,000,000,000 Datoshi` (`52,000,000 GAS`).
+
+### ValidatorsCount
+- **ValidatorsCount**: Number of consensus validators. Default is `7`.
+
+### StandbyCommittee
+- **StandbyCommittee**: List of public keys for the standby committee members.
+
+### SeedList
+- **SeedList**: List of seed nodes with their addresses and ports.
+ - MainNet addresses are:
+ - `seed1.neo.org:10333`
+ - `seed2.neo.org:10333`
+ - `seed3.neo.org:10333`
+ - `seed4.neo.org:10333`
+ - `seed5.neo.org:10333`
+ - TestNet addresses are:
+ - `seed1t5.neo.org:20333`
+ - `seed2t5.neo.org:20333`
+ - `seed3t5.neo.org:20333`
+ - `seed4t5.neo.org:20333`
+ - `seed5t5.neo.org:20333`
+
+This configuration file is essential for setting up and running a NEO node, ensuring proper logging, storage, network connectivity, and consensus protocol parameters.
diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json
index c9544a337f..a32cad5ad5 100644
--- a/src/Neo.CLI/config.mainnet.json
+++ b/src/Neo.CLI/config.mainnet.json
@@ -6,8 +6,8 @@
"Active": false
},
"Storage": {
- "Engine": "LevelDBStore", // Candidates [MemoryStore, LevelDBStore, RocksDBStore]
- "Path": "Data_LevelDB_{0}" // {0} is a placeholder for the network id
+ "Engine": "LevelDBStore",
+ "Path": "Data_LevelDB_{0}"
},
"P2P": {
"Port": 10333,
diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json
index 6e566c7ce1..4350fc62f2 100644
--- a/src/Neo.CLI/config.testnet.json
+++ b/src/Neo.CLI/config.testnet.json
@@ -6,8 +6,8 @@
"Active": false
},
"Storage": {
- "Engine": "LevelDBStore", // Candidates [MemoryStore, LevelDBStore, RocksDBStore]
- "Path": "Data_LevelDB_{0}" // {0} is a placeholder for the network id
+ "Engine": "LevelDBStore",
+ "Path": "Data_LevelDB_{0}"
},
"P2P": {
"Port": 20333,
diff --git a/src/Neo.ConsoleService/Neo.ConsoleService.csproj b/src/Neo.ConsoleService/Neo.ConsoleService.csproj
index 206e18235e..9b3ad32dfe 100644
--- a/src/Neo.ConsoleService/Neo.ConsoleService.csproj
+++ b/src/Neo.ConsoleService/Neo.ConsoleService.csproj
@@ -4,6 +4,7 @@
netstandard2.1;net8.0
Neo.ConsoleService
enable
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj b/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj
index 800699719f..d5313d9eab 100644
--- a/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj
+++ b/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj
@@ -5,6 +5,8 @@
netstandard2.1;net8.0
enable
enable
+ Neo.Cryptography.BLS12_381
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo.Extensions/Neo.Extensions.csproj b/src/Neo.Extensions/Neo.Extensions.csproj
index 71330a05a3..c6d549be6a 100644
--- a/src/Neo.Extensions/Neo.Extensions.csproj
+++ b/src/Neo.Extensions/Neo.Extensions.csproj
@@ -3,7 +3,9 @@
netstandard2.1;net8.0
enable
+ Neo.Extensions
NEO;Blockchain;Extensions
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo.GUI/GUI/InvokeContractDialog.cs b/src/Neo.GUI/GUI/InvokeContractDialog.cs
index 4e46799f5c..d8a8a6b66f 100644
--- a/src/Neo.GUI/GUI/InvokeContractDialog.cs
+++ b/src/Neo.GUI/GUI/InvokeContractDialog.cs
@@ -90,12 +90,12 @@ private void button5_Click(object sender, EventArgs e)
using ApplicationEngine engine = ApplicationEngine.Run(tx_test.Script, Service.NeoSystem.StoreView, container: tx_test);
StringBuilder sb = new StringBuilder();
sb.AppendLine($"VM State: {engine.State}");
- sb.AppendLine($"Gas Consumed: {engine.GasConsumed}");
+ sb.AppendLine($"Gas Consumed: {engine.FeeConsumed}");
sb.AppendLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson()))}");
textBox7.Text = sb.ToString();
if (engine.State != VMState.FAULT)
{
- label7.Text = engine.GasConsumed + " gas";
+ label7.Text = engine.FeeConsumed + " gas";
button3.Enabled = true;
}
else
diff --git a/src/Neo.GUI/Neo.GUI.csproj b/src/Neo.GUI/Neo.GUI.csproj
index 34e515b159..014459be4c 100644
--- a/src/Neo.GUI/Neo.GUI.csproj
+++ b/src/Neo.GUI/Neo.GUI.csproj
@@ -10,6 +10,8 @@
true
Neo.GUI
neo.ico
+ false
+ $(SolutionDir)/bin/$(AssemblyTitle)
@@ -61,4 +63,4 @@
-
\ No newline at end of file
+
diff --git a/src/Neo.IO/Neo.IO.csproj b/src/Neo.IO/Neo.IO.csproj
index f920a40fd5..a1a0a9ea2e 100644
--- a/src/Neo.IO/Neo.IO.csproj
+++ b/src/Neo.IO/Neo.IO.csproj
@@ -4,7 +4,9 @@
netstandard2.1;net8.0
true
enable
+ Neo.IO
NEO;Blockchain;IO
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo.Json/Neo.Json.csproj b/src/Neo.Json/Neo.Json.csproj
index cc3ea45278..3d75276dec 100644
--- a/src/Neo.Json/Neo.Json.csproj
+++ b/src/Neo.Json/Neo.Json.csproj
@@ -4,7 +4,9 @@
netstandard2.1;net8.0
enable
enable
+ Neo.Json
NEO;JSON
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo.VM/Neo.VM.csproj b/src/Neo.VM/Neo.VM.csproj
index a9157f5bcf..9315a850df 100644
--- a/src/Neo.VM/Neo.VM.csproj
+++ b/src/Neo.VM/Neo.VM.csproj
@@ -4,6 +4,8 @@
netstandard2.1;net8.0
true
enable
+ Neo.VM
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Neo/Hardfork.cs b/src/Neo/Hardfork.cs
index 9ef6a63c1c..7bd3cc0aef 100644
--- a/src/Neo/Hardfork.cs
+++ b/src/Neo/Hardfork.cs
@@ -15,6 +15,7 @@ public enum Hardfork : byte
{
HF_Aspidochelone,
HF_Basilisk,
- HF_Cockatrice
+ HF_Cockatrice,
+ HF_Domovoi
}
}
diff --git a/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs b/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs
index 211ac14117..e1fa5fae62 100644
--- a/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs
+++ b/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs
@@ -62,7 +62,7 @@ internal ApplicationExecuted(ApplicationEngine engine)
Transaction = engine.ScriptContainer as Transaction;
Trigger = engine.Trigger;
VMState = engine.State;
- GasConsumed = engine.GasConsumed;
+ GasConsumed = engine.FeeConsumed;
Exception = engine.FaultException;
Stack = engine.ResultStack.ToArray();
Notifications = engine.Notifications.ToArray();
diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj
index 6a1ba44504..707b94fa4c 100644
--- a/src/Neo/Neo.csproj
+++ b/src/Neo/Neo.csproj
@@ -3,7 +3,9 @@
netstandard2.1;net8.0
true
+ Neo
NEO;AntShares;Blockchain;Smart Contract
+ $(SolutionDir)/bin/$(PackageId)
@@ -27,6 +29,7 @@
+
diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs
index 16417beb43..b922674d91 100644
--- a/src/Neo/Network/P2P/Payloads/Transaction.cs
+++ b/src/Neo/Network/P2P/Payloads/Transaction.cs
@@ -46,7 +46,9 @@ public class Transaction : IEquatable, IInventory, IInteroperable
private byte version;
private uint nonce;
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
private long sysfee;
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
private long netfee;
private uint validUntilBlock;
private Signer[] _signers;
@@ -372,26 +374,26 @@ public virtual VerifyResult VerifyStateDependent(ProtocolSettings settings, Data
return VerifyResult.InvalidAttribute;
else
attributesFee += attribute.CalculateNetworkFee(snapshot, this);
- long net_fee = NetworkFee - (Size * NativeContract.Policy.GetFeePerByte(snapshot)) - attributesFee;
- if (net_fee < 0) return VerifyResult.InsufficientFunds;
+ long netFeeDatoshi = NetworkFee - (Size * NativeContract.Policy.GetFeePerByte(snapshot)) - attributesFee;
+ if (netFeeDatoshi < 0) return VerifyResult.InsufficientFunds;
- if (net_fee > MaxVerificationGas) net_fee = MaxVerificationGas;
+ if (netFeeDatoshi > MaxVerificationGas) netFeeDatoshi = MaxVerificationGas;
uint execFeeFactor = NativeContract.Policy.GetExecFeeFactor(snapshot);
for (int i = 0; i < hashes.Length; i++)
{
if (IsSignatureContract(witnesses[i].VerificationScript.Span))
- net_fee -= execFeeFactor * SignatureContractCost();
+ netFeeDatoshi -= execFeeFactor * SignatureContractCost();
else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out int m, out int n))
{
- net_fee -= execFeeFactor * MultiSignatureContractCost(m, n);
+ netFeeDatoshi -= execFeeFactor * MultiSignatureContractCost(m, n);
}
else
{
- if (!this.VerifyWitness(settings, snapshot, hashes[i], witnesses[i], net_fee, out long fee))
+ if (!this.VerifyWitness(settings, snapshot, hashes[i], witnesses[i], netFeeDatoshi, out long fee))
return VerifyResult.Invalid;
- net_fee -= fee;
+ netFeeDatoshi -= fee;
}
- if (net_fee < 0) return VerifyResult.InsufficientFunds;
+ if (netFeeDatoshi < 0) return VerifyResult.InsufficientFunds;
}
return VerifyResult.Succeed;
}
diff --git a/src/Neo/Persistence/SnapshotCache.cs b/src/Neo/Persistence/SnapshotCache.cs
index 24036b41dc..6731e5342f 100644
--- a/src/Neo/Persistence/SnapshotCache.cs
+++ b/src/Neo/Persistence/SnapshotCache.cs
@@ -48,7 +48,7 @@ protected override void DeleteInternal(StorageKey key)
public override void Commit()
{
base.Commit();
- snapshot.Commit();
+ snapshot?.Commit();
}
protected override bool ContainsInternal(StorageKey key)
diff --git a/src/Neo/ProtocolSettings.cs b/src/Neo/ProtocolSettings.cs
index f03e5ffaf9..19011dc24c 100644
--- a/src/Neo/ProtocolSettings.cs
+++ b/src/Neo/ProtocolSettings.cs
@@ -93,6 +93,7 @@ public record ProtocolSettings
///
/// Indicates the amount of gas to distribute during initialization.
+ /// In the unit of datoshi, 1 GAS = 1e8 datoshi
///
public ulong InitialGasDistribution { get; init; }
diff --git a/src/Neo/SmartContract/ApplicationEngine.Contract.cs b/src/Neo/SmartContract/ApplicationEngine.Contract.cs
index 6f4b257016..e5c1c762a7 100644
--- a/src/Neo/SmartContract/ApplicationEngine.Contract.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.Contract.cs
@@ -120,10 +120,11 @@ protected internal CallFlags GetCallFlags()
/// The hash of the account.
internal protected UInt160 CreateStandardAccount(ECPoint pubKey)
{
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
long fee = IsHardforkEnabled(Hardfork.HF_Aspidochelone)
? CheckSigPrice
: 1 << 8;
- AddGas(fee * ExecFeeFactor);
+ AddFee(fee * ExecFeeFactor);
return Contract.CreateSignatureRedeemScript(pubKey).ToScriptHash();
}
@@ -136,10 +137,11 @@ internal protected UInt160 CreateStandardAccount(ECPoint pubKey)
/// The hash of the account.
internal protected UInt160 CreateMultisigAccount(int m, ECPoint[] pubKeys)
{
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
long fee = IsHardforkEnabled(Hardfork.HF_Aspidochelone)
? CheckSigPrice * pubKeys.Length
: 1 << 8;
- AddGas(fee * ExecFeeFactor);
+ AddFee(fee * ExecFeeFactor);
return Contract.CreateMultiSigRedeemScript(m, pubKeys).ToScriptHash();
}
diff --git a/src/Neo/SmartContract/ApplicationEngine.Crypto.cs b/src/Neo/SmartContract/ApplicationEngine.Crypto.cs
index 1a8b2c7d6d..b63f1287f0 100644
--- a/src/Neo/SmartContract/ApplicationEngine.Crypto.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.Crypto.cs
@@ -20,6 +20,7 @@ partial class ApplicationEngine
{
///
/// The price of System.Crypto.CheckSig.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
public const long CheckSigPrice = 1 << 15;
@@ -66,7 +67,7 @@ protected internal bool CheckMultisig(byte[][] pubkeys, byte[][] signatures)
byte[] message = ScriptContainer.GetSignData(ProtocolSettings.Network);
int m = signatures.Length, n = pubkeys.Length;
if (n == 0 || m == 0 || m > n) throw new ArgumentException();
- AddGas(CheckSigPrice * n * ExecFeeFactor);
+ AddFee(CheckSigPrice * n * ExecFeeFactor);
try
{
for (int i = 0, j = 0; i < m && j < n;)
diff --git a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
index 16a0a95944..17e4bd6bfb 100644
--- a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
@@ -221,6 +221,10 @@ partial class ApplicationEngine
[OpCode.CONVERT] = 1 << 13,
};
+ ///
+ /// The prices of all the opcodes.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
+ ///
public static readonly long[] OpCodePriceTable = new long[byte.MaxValue];
///
diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
index 293b245bd7..e54529f6d1 100644
--- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
@@ -305,6 +305,7 @@ protected internal int GetInvocationCounter()
protected internal BigInteger GetRandom()
{
byte[] buffer;
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
long price;
if (IsHardforkEnabled(Hardfork.HF_Aspidochelone))
{
@@ -316,7 +317,7 @@ protected internal BigInteger GetRandom()
buffer = nonceData = Cryptography.Helper.Murmur128(nonceData, ProtocolSettings.Network);
price = 1 << 4;
}
- AddGas(price * ExecFeeFactor);
+ AddFee(price * ExecFeeFactor);
return new BigInteger(buffer, isUnsigned: true);
}
@@ -406,26 +407,31 @@ protected internal void SendNotification(UInt160 hash, string eventName, Array s
///
/// The hash of the specified contract. It can be set to to get all notifications.
/// The notifications sent during the execution.
- protected internal NotifyEventArgs[] GetNotifications(UInt160 hash)
+ protected internal Array GetNotifications(UInt160 hash)
{
IEnumerable notifications = Notifications;
if (hash != null) // must filter by scriptHash
notifications = notifications.Where(p => p.ScriptHash == hash);
- NotifyEventArgs[] array = notifications.ToArray();
+ var array = notifications.ToArray();
if (array.Length > Limits.MaxStackSize) throw new InvalidOperationException();
- return array;
+ Array notifyArray = new(ReferenceCounter);
+ foreach (var notify in array)
+ {
+ notifyArray.Add(notify.ToStackItem(ReferenceCounter, this));
+ }
+ return notifyArray;
}
///
/// The implementation of System.Runtime.BurnGas.
/// Burning GAS to benefit the NEO ecosystem.
///
- /// The amount of GAS to burn.
- protected internal void BurnGas(long gas)
+ /// The amount of GAS to burn, in the unit of datoshi, 1 datoshi = 1e-8 GAS
+ protected internal void BurnGas(long datoshi)
{
- if (gas <= 0)
+ if (datoshi <= 0)
throw new InvalidOperationException("GAS must be positive.");
- AddGas(gas);
+ AddFee(datoshi);
}
///
diff --git a/src/Neo/SmartContract/ApplicationEngine.Storage.cs b/src/Neo/SmartContract/ApplicationEngine.Storage.cs
index 3a8bb9d122..fbd452d6cc 100644
--- a/src/Neo/SmartContract/ApplicationEngine.Storage.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.Storage.cs
@@ -194,7 +194,7 @@ protected internal void Put(StorageContext context, byte[] key, byte[] value)
else
newDataSize = (item.Value.Length - 1) / 4 + 1 + value.Length - item.Value.Length;
}
- AddGas(newDataSize * StoragePrice);
+ AddFee(newDataSize * StoragePrice);
item.Value = value;
}
diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs
index 14dedf8e7c..fab17a2bb1 100644
--- a/src/Neo/SmartContract/ApplicationEngine.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.cs
@@ -36,6 +36,7 @@ public partial class ApplicationEngine : ExecutionEngine
///
/// The maximum cost that can be spent when a contract is executed in test mode.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
public const long TestModeGas = 20_00000000;
@@ -50,7 +51,9 @@ public partial class ApplicationEngine : ExecutionEngine
public static event EventHandler Log;
private static Dictionary services;
- private readonly long gas_amount;
+ // Total amount of GAS spent to execute.
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi
+ private readonly long _feeAmount;
private Dictionary states;
private readonly DataCache originalSnapshot;
private List notifications;
@@ -58,6 +61,7 @@ public partial class ApplicationEngine : ExecutionEngine
private readonly Dictionary invocationCounter = new();
private readonly Dictionary contractTasks = new();
internal readonly uint ExecFeeFactor;
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
internal readonly uint StoragePrice;
private byte[] nonceData;
@@ -105,13 +109,22 @@ public partial class ApplicationEngine : ExecutionEngine
///
/// GAS spent to execute.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi
///
+ [Obsolete("This property is deprecated. Use FeeConsumed instead.")]
public long GasConsumed { get; private set; } = 0;
+ ///
+ /// GAS spent to execute.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi
+ ///
+ public long FeeConsumed { get; private set; } = 0;
+
///
/// The remaining GAS that can be spent in order to complete the execution.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi
///
- public long GasLeft => gas_amount - GasConsumed;
+ public long GasLeft => _feeAmount - FeeConsumed;
///
/// The exception that caused the execution to terminate abnormally. This field could be if no exception is thrown.
@@ -154,7 +167,7 @@ public virtual UInt160 CallingScriptHash
/// The snapshot used by the engine during execution.
/// The block being persisted. It should be if the is .
/// The used by the engine.
- /// The maximum gas used in this execution. The execution will fail when the gas is exhausted.
+ /// The maximum gas, in the unit of datoshi, used in this execution. The execution will fail when the gas is exhausted.
/// The diagnostic to be used by the .
/// The jump table to be used by the .
protected unsafe ApplicationEngine(
@@ -167,7 +180,7 @@ protected unsafe ApplicationEngine(
originalSnapshot = snapshot;
PersistingBlock = persistingBlock;
ProtocolSettings = settings;
- gas_amount = gas;
+ _feeAmount = gas;
Diagnostic = diagnostic;
ExecFeeFactor = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(snapshot);
StoragePrice = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(snapshot);
@@ -235,13 +248,15 @@ protected static void OnSysCall(ExecutionEngine engine, Instruction instruction)
#endregion
///
- /// Adds GAS to and checks if it has exceeded the maximum limit.
+ /// Adds GAS to and checks if it has exceeded the maximum limit.
///
- /// The amount of GAS to be added.
- protected internal void AddGas(long gas)
+ /// The amount of GAS, in the unit of datoshi, 1 datoshi = 1e-8 GAS, to be added.
+ protected internal void AddFee(long datoshi)
{
- GasConsumed = checked(GasConsumed + gas);
- if (GasConsumed > gas_amount)
+#pragma warning disable CS0618 // Type or member is obsolete
+ FeeConsumed = GasConsumed = checked(FeeConsumed + datoshi);
+#pragma warning restore CS0618 // Type or member is obsolete
+ if (FeeConsumed > _feeAmount)
throw new InvalidOperationException("Insufficient GAS.");
}
@@ -271,14 +286,18 @@ private ExecutionContext CallContractInternal(ContractState contract, ContractMe
if (NativeContract.Policy.IsBlocked(Snapshot, contract.Hash))
throw new InvalidOperationException($"The contract {contract.Hash} has been blocked.");
+ ExecutionContext currentContext = CurrentContext;
+ ExecutionContextState state = currentContext.GetState();
if (method.Safe)
{
flags &= ~(CallFlags.WriteStates | CallFlags.AllowNotify);
}
else
{
- ContractState currentContract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash);
- if (currentContract?.CanCall(contract, method.Name) == false)
+ var executingContract = IsHardforkEnabled(Hardfork.HF_Domovoi)
+ ? state.Contract // use executing contract state to avoid possible contract update/destroy side-effects, ref. https://github.com/neo-project/neo/pull/3290.
+ : NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash);
+ if (executingContract?.CanCall(contract, method.Name) == false)
throw new InvalidOperationException($"Cannot Call Method {method.Name} Of Contract {contract.Hash} From Contract {CurrentScriptHash}");
}
@@ -291,8 +310,6 @@ private ExecutionContext CallContractInternal(ContractState contract, ContractMe
invocationCounter[contract.Hash] = 1;
}
- ExecutionContext currentContext = CurrentContext;
- ExecutionContextState state = currentContext.GetState();
CallFlags callingFlags = state.CallFlags;
if (args.Count != method.Parameters.Length) throw new InvalidOperationException($"Method {method} Expects {method.Parameters.Length} Arguments But Receives {args.Count} Arguments");
@@ -372,7 +389,7 @@ internal override void UnloadContext(ExecutionContext context)
/// The snapshot used by the engine during execution.
/// The block being persisted. It should be if the is .
/// The used by the engine.
- /// The maximum gas used in this execution. The execution will fail when the gas is exhausted.
+ /// The maximum gas used in this execution, in the unit of datoshi. The execution will fail when the gas is exhausted.
/// The diagnostic to be used by the .
/// The engine instance created.
public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock = null, ProtocolSettings settings = null, long gas = TestModeGas, IDiagnostic diagnostic = null)
@@ -421,7 +438,7 @@ public ExecutionContext LoadContract(ContractState contract, ContractMethodDescr
});
// Call initialization
- var init = contract.Manifest.Abi.GetMethod("_initialize", 0);
+ var init = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Initialize, ContractBasicMethod.InitializePCount);
if (init != null)
{
LoadContext(context.Clone(init.Offset));
@@ -555,7 +572,7 @@ internal protected void ValidateCallFlags(CallFlags requiredCallFlags)
protected virtual void OnSysCall(InteropDescriptor descriptor)
{
ValidateCallFlags(descriptor.RequiredCallFlags);
- AddGas(descriptor.FixedPrice * ExecFeeFactor);
+ AddFee(descriptor.FixedPrice * ExecFeeFactor);
object[] parameters = new object[descriptor.Parameters.Count];
for (int i = 0; i < parameters.Length; i++)
@@ -569,7 +586,7 @@ protected virtual void OnSysCall(InteropDescriptor descriptor)
protected override void PreExecuteInstruction(Instruction instruction)
{
Diagnostic?.PreExecuteInstruction(instruction);
- AddGas(ExecFeeFactor * OpCodePriceTable[(byte)instruction.OpCode]);
+ AddFee(ExecFeeFactor * OpCodePriceTable[(byte)instruction.OpCode]);
}
protected override void PostExecuteInstruction(Instruction instruction)
@@ -627,7 +644,7 @@ private static InteropDescriptor Register(string name, string handler, long fixe
/// The block being persisted.
/// The used by the engine.
/// The initial position of the instruction pointer.
- /// The maximum gas used in this execution. The execution will fail when the gas is exhausted.
+ /// The maximum gas, in the unit of datoshi, used in this execution. The execution will fail when the gas is exhausted.
/// The diagnostic to be used by the .
/// The engine instance created.
public static ApplicationEngine Run(ReadOnlyMemory script, DataCache snapshot, IVerifiable container = null, Block persistingBlock = null, ProtocolSettings settings = null, int offset = 0, long gas = TestModeGas, IDiagnostic diagnostic = null)
diff --git a/src/Neo/SmartContract/ContractBasicMethod.cs b/src/Neo/SmartContract/ContractBasicMethod.cs
new file mode 100644
index 0000000000..7897f50c0a
--- /dev/null
+++ b/src/Neo/SmartContract/ContractBasicMethod.cs
@@ -0,0 +1,122 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// ContractBasicMethod.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+namespace Neo.SmartContract
+{
+ ///
+ /// This class provides a guideline for basic methods used in the Neo blockchain, offering
+ /// a generalized interaction mechanism for smart contract deployment, verification, updates, and destruction.
+ ///
+ public record ContractBasicMethod
+ {
+ ///
+ /// The verification method. This must be called when withdrawing tokens from the contract.
+ /// If the contract address is included in the transaction signature, this method verifies the signature.
+ /// Example:
+ ///
+ /// public static bool Verify() => Runtime.CheckWitness(Owner);
+ ///
+ ///
+ /// {
+ /// "name": "verify",
+ /// "safe": false,
+ /// "parameters": [],
+ /// "returntype": "bool"
+ /// }
+ ///
+ ///
+ public static string Verify { get; } = "verify";
+
+ ///
+ /// The initialization method. Compiled into the file if any function uses the initialize statement.
+ /// These functions are executed first when loading the contract.
+ /// Example:
+ ///
+ /// private static readonly UInt160 owner = "NdUL5oDPD159KeFpD5A9zw5xNF1xLX6nLT";
+ ///
+ ///
+ public static string Initialize { get; } = "_initialize";
+
+ ///
+ /// The deployment method. Automatically executed by the ContractManagement contract when a contract is first deployed or updated.
+ ///
+ /// {
+ /// "name": "_deploy",
+ /// "safe": false,
+ /// "parameters": [
+ /// {
+ /// "name": "data",
+ /// "type": "Any"
+ /// },
+ /// {
+ /// "name": "update",
+ /// "type": "Boolean"
+ /// }
+ /// ],
+ /// "returntype": "Void"
+ /// }
+ ///
+ ///
+ public static string Deploy { get; } = "_deploy";
+
+ ///
+ /// The update method. Requires or , or both, and is passed to _deploy.
+ /// Should verify the signer's address using SYSCALL Neo.Runtime.CheckWitness
.
+ ///
+ /// {
+ /// "name": "update",
+ /// "safe": false,
+ /// "parameters": [
+ /// {
+ /// "name": "nefFile",
+ /// "type": "ByteArray"
+ /// },
+ /// {
+ /// "name": "manifest",
+ /// "type": "ByteArray"
+ /// },
+ /// {
+ /// "name": "data",
+ /// "type": "Any"
+ /// }
+ /// ],
+ /// "returntype": "Void"
+ /// }
+ ///
+ ///
+ public static string Update { get; } = "update";
+
+ ///
+ /// The destruction method. Deletes all the storage of the contract.
+ /// Should verify the signer's address using SYSCALL Neo.Runtime.CheckWitness
.
+ /// Any tokens in the contract must be transferred before destruction.
+ ///
+ /// {
+ /// "name": "destroy",
+ /// "safe": false,
+ /// "parameters": [],
+ /// "returntype": "Void"
+ /// }
+ ///
+ ///
+ public static string Destroy { get; } = "destroy";
+
+ ///
+ /// Parameter counts for the methods.
+ /// -1 represents the method can take arbitrary parameters.
+ ///
+ public static int VerifyPCount { get; } = -1;
+ public static int InitializePCount { get; } = 0;
+ public static int DeployPCount { get; } = 2;
+ public static int UpdatePCount { get; } = 3;
+ public static int DestroyPCount { get; } = 0;
+ }
+}
diff --git a/src/Neo/SmartContract/DeployedContract.cs b/src/Neo/SmartContract/DeployedContract.cs
index 0587a029e5..a3f9cfd9fb 100644
--- a/src/Neo/SmartContract/DeployedContract.cs
+++ b/src/Neo/SmartContract/DeployedContract.cs
@@ -32,7 +32,7 @@ public DeployedContract(ContractState contract)
Script = null;
ScriptHash = contract.Hash;
- ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod("verify", -1);
+ ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (descriptor is null) throw new NotSupportedException("The smart contract haven't got verify method.");
ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray();
diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs
index c0c694fc4e..ae31d66a50 100644
--- a/src/Neo/SmartContract/Helper.cs
+++ b/src/Neo/SmartContract/Helper.cs
@@ -31,11 +31,13 @@ public static class Helper
{
///
/// The maximum GAS that can be consumed when is called.
+ /// The unit is datoshi, 1 datoshi = 1e-8 GAS
///
public const long MaxVerificationGas = 1_50000000;
///
/// Calculates the verification fee for a signature address.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
/// The calculated cost.
public static long SignatureContractCost() =>
@@ -45,6 +47,7 @@ public static long SignatureContractCost() =>
///
/// Calculates the verification fee for a multi-signature address.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
/// The minimum number of correct signatures that need to be provided in order for the verification to pass.
/// The number of public keys in the account.
@@ -285,12 +288,12 @@ public static UInt160 ToScriptHash(this ReadOnlySpan script)
/// The to be verified.
/// The to be used for the verification.
/// The snapshot used to read data.
- /// The maximum GAS that can be used.
+ /// The maximum GAS that can be used, in the unit of datoshi, 1 datoshi = 1e-8 GAS.
/// if the is verified as valid; otherwise, .
- public static bool VerifyWitnesses(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, long gas)
+ public static bool VerifyWitnesses(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, long datoshi)
{
- if (gas < 0) return false;
- if (gas > MaxVerificationGas) gas = MaxVerificationGas;
+ if (datoshi < 0) return false;
+ if (datoshi > MaxVerificationGas) datoshi = MaxVerificationGas;
UInt160[] hashes;
try
@@ -304,14 +307,14 @@ public static bool VerifyWitnesses(this IVerifiable verifiable, ProtocolSettings
if (hashes.Length != verifiable.Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
- if (!verifiable.VerifyWitness(settings, snapshot, hashes[i], verifiable.Witnesses[i], gas, out long fee))
+ if (!verifiable.VerifyWitness(settings, snapshot, hashes[i], verifiable.Witnesses[i], datoshi, out long fee))
return false;
- gas -= fee;
+ datoshi -= fee;
}
return true;
}
- internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, UInt160 hash, Witness witness, long gas, out long fee)
+ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, UInt160 hash, Witness witness, long datoshi, out long fee)
{
fee = 0;
Script invocationScript;
@@ -323,13 +326,13 @@ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings
{
return false;
}
- using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.CreateSnapshot(), null, settings, gas))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.CreateSnapshot(), null, settings, datoshi))
{
if (witness.VerificationScript.Length == 0)
{
ContractState cs = NativeContract.ContractManagement.GetContract(snapshot, hash);
if (cs is null) return false;
- ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify", -1);
+ ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (md?.ReturnType != ContractParameterType.Boolean) return false;
engine.LoadContract(cs, md, CallFlags.ReadOnly);
}
@@ -357,7 +360,7 @@ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings
if (engine.Execute() == VMState.FAULT) return false;
if (!engine.ResultStack.Peek().GetBoolean()) return false;
- fee = engine.GasConsumed;
+ fee = engine.FeeConsumed;
}
return true;
}
diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs
index e7a7e122f2..c533f029a6 100644
--- a/src/Neo/SmartContract/Native/ContractManagement.cs
+++ b/src/Neo/SmartContract/Native/ContractManagement.cs
@@ -60,7 +60,7 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor
private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState contract, StackItem data, bool update)
{
- ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy", 2);
+ ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount);
if (md is not null)
await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update);
engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() });
@@ -118,11 +118,12 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine)
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
private long GetMinimumDeploymentFee(DataCache snapshot)
{
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
return (long)(BigInteger)snapshot[CreateStorageKey(Prefix_MinimumDeploymentFee)];
}
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)]
- private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value)
+ private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value/* In the unit of datoshi, 1 datoshi = 1e-8 GAS*/)
{
if (value < 0) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
@@ -218,7 +219,7 @@ private async ContractTask Deploy(ApplicationEngine engine, byte[
if (manifest.Length == 0)
throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
- engine.AddGas(Math.Max(
+ engine.AddFee(Math.Max(
engine.StoragePrice * (nefFile.Length + manifest.Length),
GetMinimumDeploymentFee(engine.Snapshot)
));
@@ -264,7 +265,7 @@ private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] man
{
if (nefFile is null && manifest is null) throw new ArgumentException();
- engine.AddGas(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0)));
+ engine.AddFee(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0)));
var contract = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Contract).Add(engine.CallingScriptHash))?.GetInteroperable(false);
if (contract is null) throw new InvalidOperationException($"Updating Contract Does Not Exist: {engine.CallingScriptHash}");
diff --git a/src/Neo/SmartContract/Native/CryptoLib.cs b/src/Neo/SmartContract/Native/CryptoLib.cs
index 452dd31faa..9027298752 100644
--- a/src/Neo/SmartContract/Native/CryptoLib.cs
+++ b/src/Neo/SmartContract/Native/CryptoLib.cs
@@ -21,12 +21,6 @@ namespace Neo.SmartContract.Native
///
public sealed partial class CryptoLib : NativeContract
{
- private static readonly Dictionary curves = new()
- {
- [NamedCurve.secp256k1] = ECCurve.Secp256k1,
- [NamedCurve.secp256r1] = ECCurve.Secp256r1,
- };
-
private static readonly Dictionary s_curves = new()
{
[NamedCurveHash.secp256k1SHA256] = (ECCurve.Secp256k1, Hasher.SHA256),
@@ -106,12 +100,15 @@ public static bool VerifyWithECDsa(byte[] message, byte[] pubkey, byte[] signatu
}
// This is for solving the hardfork issue in https://github.com/neo-project/neo/pull/3209
- [ContractMethod(true, Hardfork.HF_Cockatrice, CpuFee = 1 << 15)]
- public static bool VerifyWithECDsa(byte[] message, byte[] pubkey, byte[] signature, NamedCurve curve)
+ [ContractMethod(true, Hardfork.HF_Cockatrice, CpuFee = 1 << 15, Name = "verifyWithECDsa")]
+ public static bool VerifyWithECDsaV0(byte[] message, byte[] pubkey, byte[] signature, NamedCurveHash curve)
{
+ if (curve != NamedCurveHash.secp256k1SHA256 && curve != NamedCurveHash.secp256r1SHA256)
+ throw new ArgumentOutOfRangeException(nameof(curve));
+
try
{
- return Crypto.VerifySignature(message, signature, pubkey, curves[curve]);
+ return Crypto.VerifySignature(message, signature, pubkey, s_curves[curve].Curve);
}
catch (ArgumentException)
{
diff --git a/src/Neo/SmartContract/Native/NamedCurve.cs b/src/Neo/SmartContract/Native/NamedCurve.cs
deleted file mode 100644
index 8c7a9107e9..0000000000
--- a/src/Neo/SmartContract/Native/NamedCurve.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2015-2024 The Neo Project.
-//
-// NamedCurve.cs file belongs to the neo project and is free
-// software distributed under the MIT software license, see the
-// accompanying file LICENSE in the main directory of the
-// repository or http://www.opensource.org/licenses/mit-license.php
-// for more details.
-//
-// Redistribution and use in source and binary forms with or without
-// modifications are permitted.
-
-using System;
-
-namespace Neo.SmartContract.Native
-{
- ///
- /// Represents the named curve used in ECDSA. This enum is obsolete
- /// and will be removed in future versions. Please, use an extended instead.
- ///
- ///
- /// https://tools.ietf.org/html/rfc4492#section-5.1.1
- ///
- [Obsolete("NamedCurve enum is obsolete and will be removed in future versions. Please, use an extended NamedCurveHash instead.")]
- public enum NamedCurve : byte
- {
- ///
- /// The secp256k1 curve.
- ///
- [Obsolete("secp256k1 value is obsolete and will be removed in future versions. Please, use NamedCurveHash.secp256k1SHA256 for compatible behaviour.")]
- secp256k1 = 22,
-
- ///
- /// The secp256r1 curve, which known as prime256v1 or nistP-256.
- ///
- [Obsolete("secp256r1 value is obsolete and will be removed in future versions. Please, use NamedCurveHash.secp256r1SHA256 for compatible behaviour.")]
- secp256r1 = 23
- }
-}
diff --git a/src/Neo/SmartContract/Native/NamedCurveHash.cs b/src/Neo/SmartContract/Native/NamedCurveHash.cs
index 8bd63bf874..653ed3aa88 100644
--- a/src/Neo/SmartContract/Native/NamedCurveHash.cs
+++ b/src/Neo/SmartContract/Native/NamedCurveHash.cs
@@ -13,7 +13,6 @@ namespace Neo.SmartContract.Native
{
///
/// Represents a pair of the named curve used in ECDSA and a hash algorithm used to hash message.
- /// This is a compatible extension of an obsolete enum.
///
public enum NamedCurveHash : byte
{
diff --git a/src/Neo/SmartContract/Native/NativeContract.cs b/src/Neo/SmartContract/Native/NativeContract.cs
index 03815b3fae..1cc244408d 100644
--- a/src/Neo/SmartContract/Native/NativeContract.cs
+++ b/src/Neo/SmartContract/Native/NativeContract.cs
@@ -35,7 +35,7 @@ public class CacheEntry
public byte[] Script { get; set; }
}
- internal Dictionary NativeContracts { get; set; } = new Dictionary();
+ internal Dictionary NativeContracts { get; set; } = new();
public CacheEntry GetAllowedMethods(NativeContract native, ApplicationEngine engine)
{
@@ -48,12 +48,12 @@ public CacheEntry GetAllowedMethods(NativeContract native, ApplicationEngine eng
}
}
- public delegate bool IsHardforkEnabledDelegate(Hardfork hf, uint index);
- private static readonly List contractsList = new();
- private static readonly Dictionary contractsDictionary = new();
- private readonly ImmutableHashSet usedHardforks;
- private readonly ReadOnlyCollection methodDescriptors;
- private readonly ReadOnlyCollection eventsDescriptors;
+ public delegate bool IsHardforkEnabledDelegate(Hardfork hf, uint blockHeight);
+ private static readonly List s_contractsList = [];
+ private static readonly Dictionary s_contractsDictionary = new();
+ private readonly ImmutableHashSet _usedHardforks;
+ private readonly ReadOnlyCollection _methodDescriptors;
+ private readonly ReadOnlyCollection _eventsDescriptors;
private static int id_counter = 0;
#region Named Native Contracts
@@ -108,7 +108,7 @@ public CacheEntry GetAllowedMethods(NativeContract native, ApplicationEngine eng
///
/// Gets all native contracts.
///
- public static IReadOnlyCollection Contracts { get; } = contractsList;
+ public static IReadOnlyCollection Contracts { get; } = s_contractsList;
///
/// The name of the native contract.
@@ -139,17 +139,17 @@ protected NativeContract()
// Reflection to get the methods
- List listMethods = new();
+ List listMethods = [];
foreach (MemberInfo member in GetType().GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
{
ContractMethodAttribute attribute = member.GetCustomAttribute();
if (attribute is null) continue;
listMethods.Add(new ContractMethodMetadata(member, attribute));
}
- methodDescriptors = listMethods.OrderBy(p => p.Name, StringComparer.Ordinal).ThenBy(p => p.Parameters.Length).ToList().AsReadOnly();
+ _methodDescriptors = listMethods.OrderBy(p => p.Name, StringComparer.Ordinal).ThenBy(p => p.Parameters.Length).ToList().AsReadOnly();
// Reflection to get the events
- eventsDescriptors =
+ _eventsDescriptors =
GetType().GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty(), null)?.
GetCustomAttributes().
// Take into account not only the contract constructor, but also the base type constructor for proper FungibleToken events handling.
@@ -158,26 +158,25 @@ protected NativeContract()
OrderBy(p => p.Order).ToList().AsReadOnly();
// Calculate the initializations forks
- usedHardforks =
- methodDescriptors.Select(u => u.ActiveIn)
- .Concat(methodDescriptors.Select(u => u.DeprecatedIn))
- .Concat(eventsDescriptors.Select(u => u.ActiveIn))
- .Concat(new Hardfork?[] { ActiveIn })
- .Where(u => u is not null)
- .OrderBy(u => (byte)u)
- .Cast().ToImmutableHashSet();
-
- contractsList.Add(this);
- contractsDictionary.Add(Hash, this);
+ _usedHardforks =
+ _methodDescriptors.Select(u => u.ActiveIn)
+ .Concat(_methodDescriptors.Select(u => u.DeprecatedIn))
+ .Concat(_eventsDescriptors.Select(u => u.ActiveIn))
+ .Concat([ActiveIn])
+ .Where(u => u is not null)
+ .OrderBy(u => (byte)u)
+ .Cast().ToImmutableHashSet();
+ s_contractsList.Add(this);
+ s_contractsDictionary.Add(Hash, this);
}
///
/// The allowed methods and his offsets.
///
/// Hardfork checker
- /// Block index
+ /// Block height. Used to check the hardforks and active methods.
/// The .
- private NativeContractsCache.CacheEntry GetAllowedMethods(IsHardforkEnabledDelegate hfChecker, uint index)
+ private NativeContractsCache.CacheEntry GetAllowedMethods(IsHardforkEnabledDelegate hfChecker, uint blockHeight)
{
Dictionary methods = new();
@@ -185,14 +184,14 @@ private NativeContractsCache.CacheEntry GetAllowedMethods(IsHardforkEnabledDeleg
byte[] script;
using (ScriptBuilder sb = new())
{
- foreach (ContractMethodMetadata method in methodDescriptors.Where(u
+ foreach (ContractMethodMetadata method in _methodDescriptors.Where(u
=>
// no hardfork is involved
u.ActiveIn is null && u.DeprecatedIn is null ||
// deprecated method hardfork is involved
- u.DeprecatedIn is not null && hfChecker(u.DeprecatedIn.Value, index) == false ||
+ u.DeprecatedIn is not null && hfChecker(u.DeprecatedIn.Value, blockHeight) == false ||
// active method hardfork is involved
- u.ActiveIn is not null && hfChecker(u.ActiveIn.Value, index))
+ u.ActiveIn is not null && hfChecker(u.ActiveIn.Value, blockHeight))
)
{
method.Descriptor.Offset = sb.Length;
@@ -204,35 +203,35 @@ u.ActiveIn is null && u.DeprecatedIn is null ||
script = sb.ToArray();
}
- return new NativeContractsCache.CacheEntry() { Methods = methods, Script = script };
+ return new NativeContractsCache.CacheEntry { Methods = methods, Script = script };
}
///
/// The of the native contract.
///
/// The where the HardForks are configured.
- /// Block index
+ /// Block index
/// The .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ContractState GetContractState(ProtocolSettings settings, uint index) => GetContractState(settings.IsHardforkEnabled, index);
+ public ContractState GetContractState(ProtocolSettings settings, uint blockHeight) => GetContractState(settings.IsHardforkEnabled, blockHeight);
///
/// The of the native contract.
///
/// Hardfork checker
- /// Block index
+ /// Block height. Used to check hardforks and active methods.
/// The .
- public ContractState GetContractState(IsHardforkEnabledDelegate hfChecker, uint index)
+ public ContractState GetContractState(IsHardforkEnabledDelegate hfChecker, uint blockHeight)
{
// Get allowed methods and nef script
- var allowedMethods = GetAllowedMethods(hfChecker, index);
+ var allowedMethods = GetAllowedMethods(hfChecker, blockHeight);
// Compose nef file
var nef = new NefFile()
{
Compiler = "neo-core-v3.0",
Source = string.Empty,
- Tokens = Array.Empty(),
+ Tokens = [],
Script = allowedMethods.Script
};
nef.CheckSum = NefFile.ComputeChecksum(nef);
@@ -241,17 +240,17 @@ public ContractState GetContractState(IsHardforkEnabledDelegate hfChecker, uint
var manifest = new ContractManifest()
{
Name = Name,
- Groups = Array.Empty(),
- SupportedStandards = Array.Empty(),
- Abi = new ContractAbi()
+ Groups = [],
+ SupportedStandards = [],
+ Abi = new ContractAbi
{
- Events = eventsDescriptors
- .Where(u => u.ActiveIn is null || hfChecker(u.ActiveIn.Value, index))
+ Events = _eventsDescriptors
+ .Where(u => u.ActiveIn is null || hfChecker(u.ActiveIn.Value, blockHeight))
.Select(p => p.Descriptor).ToArray(),
Methods = allowedMethods.Methods.Values
.Select(p => p.Descriptor).ToArray()
},
- Permissions = new[] { ContractPermission.DefaultPermission },
+ Permissions = [ContractPermission.DefaultPermission],
Trusts = WildcardContainer.Create(),
Extra = null
};
@@ -282,7 +281,7 @@ internal bool IsInitializeBlock(ProtocolSettings settings, uint index, out Hardf
var hfs = new List();
// If is in the hardfork height, add them to return array
- foreach (var hf in usedHardforks)
+ foreach (var hf in _usedHardforks)
{
if (!settings.Hardforks.TryGetValue(hf, out var activeIn))
{
@@ -319,9 +318,9 @@ internal bool IsInitializeBlock(ProtocolSettings settings, uint index, out Hardf
/// Is the native contract active
///
/// The where the HardForks are configured.
- /// Block index
+ /// Block height
/// True if the native contract is active
- internal bool IsActive(ProtocolSettings settings, uint index)
+ internal bool IsActive(ProtocolSettings settings, uint blockHeight)
{
if (ActiveIn is null) return true;
@@ -331,7 +330,7 @@ internal bool IsActive(ProtocolSettings settings, uint index)
activeIn = 0;
}
- return activeIn <= index;
+ return activeIn <= blockHeight;
}
///
@@ -357,7 +356,7 @@ private protected KeyBuilder CreateStorageKey(byte prefix)
/// The native contract with the specified hash.
public static NativeContract GetContract(UInt160 hash)
{
- contractsDictionary.TryGetValue(hash, out var contract);
+ s_contractsDictionary.TryGetValue(hash, out var contract);
return contract;
}
@@ -380,7 +379,8 @@ internal async void Invoke(ApplicationEngine engine, byte version)
ExecutionContextState state = context.GetState();
if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
- engine.AddGas(method.CpuFee * engine.ExecFeeFactor + method.StorageFee * engine.StoragePrice);
+ // In the unit of datoshi, 1 datoshi = 1e-8 GAS
+ engine.AddFee(method.CpuFee * engine.ExecFeeFactor + method.StorageFee * engine.StoragePrice);
List
/// The snapshot used to read data.
- /// The price for an Oracle request.
+ /// The price for an Oracle request, in the unit of datoshi, 1 datoshi = 1e-8 GAS.
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public long GetPrice(DataCache snapshot)
{
@@ -184,7 +184,7 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine)
}
[ContractMethod(RequiredCallFlags = CallFlags.States | CallFlags.AllowNotify)]
- private async ContractTask Request(ApplicationEngine engine, string url, string filter, string callback, StackItem userData, long gasForResponse)
+ private async ContractTask Request(ApplicationEngine engine, string url, string filter, string callback, StackItem userData, long gasForResponse /* In the unit of datoshi, 1 datoshi = 1e-8 GAS */)
{
//Check the arguments
if (Utility.StrictUTF8.GetByteCount(url) > MaxUrlLength
@@ -193,10 +193,10 @@ private async ContractTask Request(ApplicationEngine engine, string url, string
|| gasForResponse < 0_10000000)
throw new ArgumentException();
- engine.AddGas(GetPrice(engine.Snapshot));
+ engine.AddFee(GetPrice(engine.Snapshot));
//Mint gas for the response
- engine.AddGas(gasForResponse);
+ engine.AddFee(gasForResponse);
await GAS.Mint(engine, Hash, gasForResponse, false);
//Increase the request id
diff --git a/src/Neo/SmartContract/Native/PolicyContract.cs b/src/Neo/SmartContract/Native/PolicyContract.cs
index aea3a3ab06..adeb2f1c19 100644
--- a/src/Neo/SmartContract/Native/PolicyContract.cs
+++ b/src/Neo/SmartContract/Native/PolicyContract.cs
@@ -35,6 +35,7 @@ public sealed class PolicyContract : NativeContract
///
/// The default network fee per byte of transactions.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
public const uint DefaultFeePerByte = 1000;
diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs
index 93c124ea88..257efb3a66 100644
--- a/src/Neo/SmartContract/NotifyEventArgs.cs
+++ b/src/Neo/SmartContract/NotifyEventArgs.cs
@@ -66,11 +66,31 @@ public void FromStackItem(StackItem stackItem)
public StackItem ToStackItem(ReferenceCounter referenceCounter)
{
return new Array(referenceCounter)
+ {
+ ScriptHash.ToArray(),
+ EventName,
+ State
+ };
+ }
+
+ public StackItem ToStackItem(ReferenceCounter referenceCounter, ApplicationEngine engine)
+ {
+ if (engine.IsHardforkEnabled(Hardfork.HF_Domovoi))
{
- ScriptHash.ToArray(),
- EventName,
- State
- };
+ return new Array(referenceCounter)
+ {
+ ScriptHash.ToArray(),
+ EventName,
+ State.OnStack ? State : State.DeepCopy(true)
+ };
+ }
+
+ return new Array(referenceCounter)
+ {
+ ScriptHash.ToArray(),
+ EventName,
+ State
+ };
}
}
}
diff --git a/src/Neo/Wallets/Helper.cs b/src/Neo/Wallets/Helper.cs
index 7589ae949a..1273bafc50 100644
--- a/src/Neo/Wallets/Helper.cs
+++ b/src/Neo/Wallets/Helper.cs
@@ -80,6 +80,7 @@ internal static byte[] XOR(byte[] x, byte[] y)
///
/// Calculates the network fee for the specified transaction.
+ /// In the unit of datoshi, 1 datoshi = 1e-8 GAS
///
/// The transaction to calculate.
/// The snapshot used to read data.
@@ -119,7 +120,7 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot,
var contract = NativeContract.ContractManagement.GetContract(snapshot, hash);
if (contract is null)
throw new ArgumentException($"The smart contract or address {hash} is not found");
- var md = contract.Manifest.Abi.GetMethod("verify", -1);
+ var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (md is null)
throw new ArgumentException($"The smart contract {contract.Hash} haven't got verify method");
if (md.ReturnType != ContractParameterType.Boolean)
@@ -138,9 +139,9 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot,
if (engine.Execute() == VMState.FAULT) throw new ArgumentException($"Smart contract {contract.Hash} verification fault.");
if (!engine.ResultStack.Pop().GetBoolean()) throw new ArgumentException($"Smart contract {contract.Hash} returns false.");
- maxExecutionCost -= engine.GasConsumed;
+ maxExecutionCost -= engine.FeeConsumed;
if (maxExecutionCost <= 0) throw new InvalidOperationException("Insufficient GAS.");
- networkFee += engine.GasConsumed;
+ networkFee += engine.FeeConsumed;
}
else if (IsSignatureContract(witnessScript))
{
diff --git a/src/Neo/Wallets/NEP6/NEP6Wallet.cs b/src/Neo/Wallets/NEP6/NEP6Wallet.cs
index cede8e0efa..17a59fc830 100644
--- a/src/Neo/Wallets/NEP6/NEP6Wallet.cs
+++ b/src/Neo/Wallets/NEP6/NEP6Wallet.cs
@@ -15,6 +15,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
@@ -223,6 +224,10 @@ public override IEnumerable GetAccounts()
public override WalletAccount Import(X509Certificate2 cert)
{
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ throw new PlatformNotSupportedException("Importing certificates is not supported on macOS.");
+ }
KeyPair key;
using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
{
diff --git a/src/Neo/Wallets/Wallet.cs b/src/Neo/Wallets/Wallet.cs
index 761b0b1999..aca30b008f 100644
--- a/src/Neo/Wallets/Wallet.cs
+++ b/src/Neo/Wallets/Wallet.cs
@@ -22,6 +22,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
@@ -412,6 +413,10 @@ private static Signer[] GetSigners(UInt160 sender, Signer[] cosigners)
/// The imported account.
public virtual WalletAccount Import(X509Certificate2 cert)
{
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ throw new PlatformNotSupportedException("Importing certificates is not supported on macOS.");
+ }
byte[] privateKey;
using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
{
@@ -535,7 +540,7 @@ public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs,
/// The sender of the transaction.
/// The cosigners to be added to the transaction.
/// The attributes to be added to the transaction.
- /// The maximum gas that can be spent to execute the script.
+ /// The maximum gas that can be spent to execute the script, in the unit of datoshi, 1 datoshi = 1e-8 GAS.
/// The block environment to execute the transaction. If null, will be used.
/// The created transaction.
public Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory script, UInt160 sender = null, Signer[] cosigners = null, TransactionAttribute[] attributes = null, long maxGas = ApplicationEngine.TestModeGas, Block persistingBlock = null)
@@ -575,7 +580,7 @@ private Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory scr
{
throw new InvalidOperationException($"Failed execution for '{Convert.ToBase64String(script.Span)}'", engine.FaultException);
}
- tx.SystemFee = engine.GasConsumed;
+ tx.SystemFee = engine.FeeConsumed;
}
tx.NetworkFee = tx.CalculateNetworkFee(snapshot, ProtocolSettings, (a) => GetAccount(a)?.Contract?.Script, maxGas);
diff --git a/src/Plugins/ApplicationLogs/ApplicationLogs.csproj b/src/Plugins/ApplicationLogs/ApplicationLogs.csproj
index 89eea3b1bb..4529b946af 100644
--- a/src/Plugins/ApplicationLogs/ApplicationLogs.csproj
+++ b/src/Plugins/ApplicationLogs/ApplicationLogs.csproj
@@ -4,6 +4,7 @@
Neo.Plugins.ApplicationLogs
Neo.Plugins
enable
+ $(SolutionDir)/bin/$(PackageId)
@@ -18,4 +19,4 @@
PreserveNewest
-
\ No newline at end of file
+
diff --git a/src/Plugins/ApplicationLogs/LogReader.cs b/src/Plugins/ApplicationLogs/LogReader.cs
index 4de4237acb..6a8682ab5e 100644
--- a/src/Plugins/ApplicationLogs/LogReader.cs
+++ b/src/Plugins/ApplicationLogs/LogReader.cs
@@ -9,21 +9,21 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using ApplicationLogs.Store;
-using ApplicationLogs.Store.Models;
using Neo.ConsoleService;
-using Neo.IO;
using Neo.Json;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.ApplicationLogs.Store;
+using Neo.Plugins.ApplicationLogs.Store.Models;
+using Neo.Plugins.RpcServer;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using System.Numerics;
using static System.IO.Path;
-namespace Neo.Plugins
+namespace Neo.Plugins.ApplicationLogs
{
public class LogReader : Plugin
{
diff --git a/src/Plugins/ApplicationLogs/Settings.cs b/src/Plugins/ApplicationLogs/Settings.cs
index 1e425f664b..8f2a0da1e1 100644
--- a/src/Plugins/ApplicationLogs/Settings.cs
+++ b/src/Plugins/ApplicationLogs/Settings.cs
@@ -11,7 +11,7 @@
using Microsoft.Extensions.Configuration;
-namespace Neo.Plugins
+namespace Neo.Plugins.ApplicationLogs
{
internal class Settings
{
diff --git a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs
index aa0357ffb2..147a80034b 100644
--- a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs
+++ b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs
@@ -9,17 +9,14 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using ApplicationLogs.Store.States;
-using Neo;
using Neo.IO;
using Neo.Persistence;
-using Neo.Plugins;
-using Neo.Plugins.Store.States;
+using Neo.Plugins.ApplicationLogs.Store.States;
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
-namespace ApplicationLogs.Store
+namespace Neo.Plugins.ApplicationLogs.Store
{
public sealed class LogStorageStore : IDisposable
{
@@ -162,7 +159,7 @@ public Guid PutStackItemState(StackItem stackItem)
{
_snapshot.Put(key, BinarySerializer.Serialize(stackItem, ExecutionEngineLimits.Default with { MaxItemSize = (uint)Settings.Default.MaxStackSize }));
}
- catch (NotSupportedException)
+ catch
{
_snapshot.Put(key, BinarySerializer.Serialize(StackItem.Null, ExecutionEngineLimits.Default with { MaxItemSize = (uint)Settings.Default.MaxStackSize }));
}
diff --git a/src/Plugins/ApplicationLogs/Store/Models/ApplicationEngineLogModel.cs b/src/Plugins/ApplicationLogs/Store/Models/ApplicationEngineLogModel.cs
index 9836db7146..edc85b1da6 100644
--- a/src/Plugins/ApplicationLogs/Store/Models/ApplicationEngineLogModel.cs
+++ b/src/Plugins/ApplicationLogs/Store/Models/ApplicationEngineLogModel.cs
@@ -9,9 +9,9 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using Neo.Plugins.Store.States;
+using Neo.Plugins.ApplicationLogs.Store.States;
-namespace Neo.Plugins.Store.Models
+namespace Neo.Plugins.ApplicationLogs.Store.Models
{
public class ApplicationEngineLogModel
{
diff --git a/src/Plugins/ApplicationLogs/Store/Models/BlockchainEventModel.cs b/src/Plugins/ApplicationLogs/Store/Models/BlockchainEventModel.cs
index a882ff1a8c..b067d02f9d 100644
--- a/src/Plugins/ApplicationLogs/Store/Models/BlockchainEventModel.cs
+++ b/src/Plugins/ApplicationLogs/Store/Models/BlockchainEventModel.cs
@@ -9,11 +9,10 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using ApplicationLogs.Store.States;
-using Neo;
+using Neo.Plugins.ApplicationLogs.Store.States;
using Neo.VM.Types;
-namespace ApplicationLogs.Store.Models
+namespace Neo.Plugins.ApplicationLogs.Store.Models
{
public class BlockchainEventModel
{
diff --git a/src/Plugins/ApplicationLogs/Store/Models/BlockchainExecutionModel.cs b/src/Plugins/ApplicationLogs/Store/Models/BlockchainExecutionModel.cs
index 19a3de5749..e8ee0fc180 100644
--- a/src/Plugins/ApplicationLogs/Store/Models/BlockchainExecutionModel.cs
+++ b/src/Plugins/ApplicationLogs/Store/Models/BlockchainExecutionModel.cs
@@ -9,13 +9,12 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using ApplicationLogs.Store.States;
-using Neo.Plugins.Store.Models;
+using Neo.Plugins.ApplicationLogs.Store.States;
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
-namespace ApplicationLogs.Store.Models
+namespace Neo.Plugins.ApplicationLogs.Store.Models
{
public class BlockchainExecutionModel
{
diff --git a/src/Plugins/ApplicationLogs/Store/NeoStore.cs b/src/Plugins/ApplicationLogs/Store/NeoStore.cs
index 496502869b..bc61a9b03c 100644
--- a/src/Plugins/ApplicationLogs/Store/NeoStore.cs
+++ b/src/Plugins/ApplicationLogs/Store/NeoStore.cs
@@ -9,18 +9,15 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using ApplicationLogs.Store.Models;
-using ApplicationLogs.Store.States;
-using Neo;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
-using Neo.Plugins.Store.Models;
-using Neo.Plugins.Store.States;
+using Neo.Plugins.ApplicationLogs.Store.Models;
+using Neo.Plugins.ApplicationLogs.Store.States;
using Neo.SmartContract;
using Neo.VM.Types;
-namespace ApplicationLogs.Store
+namespace Neo.Plugins.ApplicationLogs.Store
{
public sealed class NeoStore : IDisposable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs b/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs
index dcbb58b6e6..54369a672a 100644
--- a/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs
@@ -12,7 +12,7 @@
using Neo;
using Neo.IO;
-namespace ApplicationLogs.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class BlockLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs b/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs
index 0987e86e67..011886f67c 100644
--- a/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs
@@ -14,7 +14,7 @@
using Neo.Ledger;
using Neo.SmartContract;
-namespace ApplicationLogs.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class ContractLogState : NotifyLogState, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs
index 8b07855253..96f9041aaf 100644
--- a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs
@@ -11,7 +11,7 @@
using Neo.IO;
-namespace Neo.Plugins.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class EngineLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs b/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs
index 44f8a74b49..210ac36283 100644
--- a/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs
@@ -13,7 +13,7 @@
using Neo.Ledger;
using Neo.VM;
-namespace ApplicationLogs.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class ExecutionLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs
index 20fbd9e456..70b53268e5 100644
--- a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs
@@ -13,7 +13,7 @@
using Neo.IO;
using Neo.SmartContract;
-namespace ApplicationLogs.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class NotifyLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs b/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs
index 8b32867b66..9417f984e2 100644
--- a/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs
@@ -11,7 +11,7 @@
using Neo.IO;
-namespace Neo.Plugins.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class TransactionEngineLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs b/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs
index b40d3244d0..1667478509 100644
--- a/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs
+++ b/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs
@@ -9,10 +9,9 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-using Neo;
using Neo.IO;
-namespace ApplicationLogs.Store.States
+namespace Neo.Plugins.ApplicationLogs.Store.States
{
public class TransactionLogState : ISerializable, IEquatable
{
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs
index b54b6eca1e..edffc1cb09 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs
@@ -10,13 +10,12 @@
// modifications are permitted.
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Messages;
using Neo.SmartContract;
-using Neo.Wallets;
using System.Linq;
using System.Runtime.CompilerServices;
-using static Neo.Consensus.RecoveryMessage;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
partial class ConsensusContext
{
@@ -33,10 +32,10 @@ public T GetMessage(ExtensiblePayload payload) where T : ConsensusMessage
return (T)GetMessage(payload);
}
- private ChangeViewPayloadCompact GetChangeViewPayloadCompact(ExtensiblePayload payload)
+ private RecoveryMessage.ChangeViewPayloadCompact GetChangeViewPayloadCompact(ExtensiblePayload payload)
{
ChangeView message = GetMessage(payload);
- return new ChangeViewPayloadCompact
+ return new RecoveryMessage.ChangeViewPayloadCompact
{
ValidatorIndex = message.ValidatorIndex,
OriginalViewNumber = message.ViewNumber,
@@ -45,10 +44,10 @@ private ChangeViewPayloadCompact GetChangeViewPayloadCompact(ExtensiblePayload p
};
}
- private CommitPayloadCompact GetCommitPayloadCompact(ExtensiblePayload payload)
+ private RecoveryMessage.CommitPayloadCompact GetCommitPayloadCompact(ExtensiblePayload payload)
{
Commit message = GetMessage(payload);
- return new CommitPayloadCompact
+ return new RecoveryMessage.CommitPayloadCompact
{
ViewNumber = message.ViewNumber,
ValidatorIndex = message.ValidatorIndex,
@@ -57,9 +56,9 @@ private CommitPayloadCompact GetCommitPayloadCompact(ExtensiblePayload payload)
};
}
- private PreparationPayloadCompact GetPreparationPayloadCompact(ExtensiblePayload payload)
+ private RecoveryMessage.PreparationPayloadCompact GetPreparationPayloadCompact(ExtensiblePayload payload)
{
- return new PreparationPayloadCompact
+ return new RecoveryMessage.PreparationPayloadCompact
{
ValidatorIndex = GetMessage(payload).ValidatorIndex,
InvocationScript = payload.Witness.InvocationScript
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs
index a761cbafb0..ee3b8a7747 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs
@@ -11,15 +11,16 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Messages;
+using Neo.Plugins.DBFTPlugin.Types;
using Neo.SmartContract;
using Neo.Wallets;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
-using static Neo.Consensus.RecoveryMessage;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
partial class ConsensusContext
{
@@ -153,7 +154,7 @@ public ExtensiblePayload MakeRecoveryMessage()
PreparationMessages = PreparationPayloads.Where(p => p != null).Select(p => GetPreparationPayloadCompact(p)).ToDictionary(p => p.ValidatorIndex),
CommitMessages = CommitSent
? CommitPayloads.Where(p => p != null).Select(p => GetCommitPayloadCompact(p)).ToDictionary(p => p.ValidatorIndex)
- : new Dictionary()
+ : new Dictionary()
});
}
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs
index 35044e4fb8..abd0309783 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs
@@ -15,6 +15,7 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.DBFTPlugin.Messages;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
@@ -24,7 +25,7 @@
using System.IO;
using System.Linq;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
public partial class ConsensusContext : IDisposable, ISerializable
{
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs
index 3b15bcd8fc..c6ba86ee86 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs
@@ -13,10 +13,12 @@
using Neo.IO;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Messages;
+using Neo.Plugins.DBFTPlugin.Types;
using System;
using System.Linq;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
partial class ConsensusService
{
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs
index ecc31f7ba3..3c6ab8e243 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs
@@ -11,18 +11,17 @@
using Akka.Actor;
using Neo.Cryptography;
-using Neo.IO;
using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Messages;
using Neo.SmartContract;
using Neo.SmartContract.Native;
-using Neo.Wallets;
using System;
using System.Collections.Generic;
using System.Linq;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
partial class ConsensusService
{
diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs
index 8a6d75e8b9..eb97e7024b 100644
--- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs
+++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs
@@ -14,13 +14,15 @@
using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Messages;
+using Neo.Plugins.DBFTPlugin.Types;
using Neo.Wallets;
using System;
using System.Collections.Generic;
using System.Linq;
using static Neo.Ledger.Blockchain;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Consensus
{
partial class ConsensusService : UntypedActor
{
diff --git a/src/Plugins/DBFTPlugin/DBFTPlugin.cs b/src/Plugins/DBFTPlugin/DBFTPlugin.cs
index 59191d2881..9ca44adc74 100644
--- a/src/Plugins/DBFTPlugin/DBFTPlugin.cs
+++ b/src/Plugins/DBFTPlugin/DBFTPlugin.cs
@@ -14,9 +14,10 @@
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
using Neo.Plugins;
+using Neo.Plugins.DBFTPlugin.Consensus;
using Neo.Wallets;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin
{
public class DBFTPlugin : Plugin
{
diff --git a/src/Plugins/DBFTPlugin/DBFTPlugin.csproj b/src/Plugins/DBFTPlugin/DBFTPlugin.csproj
index b04e2e5c4f..68595be53a 100644
--- a/src/Plugins/DBFTPlugin/DBFTPlugin.csproj
+++ b/src/Plugins/DBFTPlugin/DBFTPlugin.csproj
@@ -4,6 +4,7 @@
net8.0
Neo.Consensus.DBFT
Neo.Consensus
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/DBFTPlugin/Messages/ChangeView.cs b/src/Plugins/DBFTPlugin/Messages/ChangeView.cs
index e7be40075f..84f681f499 100644
--- a/src/Plugins/DBFTPlugin/Messages/ChangeView.cs
+++ b/src/Plugins/DBFTPlugin/Messages/ChangeView.cs
@@ -10,9 +10,10 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public class ChangeView : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/Commit.cs b/src/Plugins/DBFTPlugin/Messages/Commit.cs
index 6e8fe93d87..8f276bb6fe 100644
--- a/src/Plugins/DBFTPlugin/Messages/Commit.cs
+++ b/src/Plugins/DBFTPlugin/Messages/Commit.cs
@@ -10,10 +10,11 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public class Commit : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs b/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs
index 4e136a99e5..de030d166d 100644
--- a/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs
+++ b/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs
@@ -10,10 +10,11 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public abstract class ConsensusMessage : ISerializable
{
diff --git a/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs b/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs
index 2bce609f79..495ccbd726 100644
--- a/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs
+++ b/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs
@@ -10,11 +10,12 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System;
using System.IO;
using System.Linq;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public class PrepareRequest : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs
index 7510ff99bb..b4608ff9af 100644
--- a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs
+++ b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs
@@ -10,9 +10,10 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public class PrepareResponse : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs
index 6a7734e569..2d7283cd22 100644
--- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs
+++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs
@@ -13,7 +13,7 @@
using System;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
partial class RecoveryMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs
index 2dfa16597a..6d3880f3c0 100644
--- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs
+++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs
@@ -13,7 +13,7 @@
using System;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
partial class RecoveryMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs
index 80b2a48b6f..8fae1596ef 100644
--- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs
+++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs
@@ -13,7 +13,7 @@
using System;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
partial class RecoveryMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs
index fc688d6a1f..2de33470ea 100644
--- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs
+++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs
@@ -11,12 +11,14 @@
using Neo.IO;
using Neo.Network.P2P.Payloads;
+using Neo.Plugins.DBFTPlugin.Consensus;
+using Neo.Plugins.DBFTPlugin.Types;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public partial class RecoveryMessage : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryRequest.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryRequest.cs
index 84cd381add..2872d28e26 100644
--- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryRequest.cs
+++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryRequest.cs
@@ -10,9 +10,10 @@
// modifications are permitted.
using Neo.IO;
+using Neo.Plugins.DBFTPlugin.Types;
using System.IO;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Messages
{
public class RecoveryRequest : ConsensusMessage
{
diff --git a/src/Plugins/DBFTPlugin/Settings.cs b/src/Plugins/DBFTPlugin/Settings.cs
index d0ecbb63fd..28ad21f37a 100644
--- a/src/Plugins/DBFTPlugin/Settings.cs
+++ b/src/Plugins/DBFTPlugin/Settings.cs
@@ -11,7 +11,7 @@
using Microsoft.Extensions.Configuration;
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin
{
public class Settings
{
diff --git a/src/Plugins/DBFTPlugin/Types/ChangeViewReason.cs b/src/Plugins/DBFTPlugin/Types/ChangeViewReason.cs
index 4c0a3c1100..5d9e55ffeb 100644
--- a/src/Plugins/DBFTPlugin/Types/ChangeViewReason.cs
+++ b/src/Plugins/DBFTPlugin/Types/ChangeViewReason.cs
@@ -9,7 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Types
{
public enum ChangeViewReason : byte
{
diff --git a/src/Plugins/DBFTPlugin/Types/ConsensusMessageType.cs b/src/Plugins/DBFTPlugin/Types/ConsensusMessageType.cs
index f325133f08..81636e94c1 100644
--- a/src/Plugins/DBFTPlugin/Types/ConsensusMessageType.cs
+++ b/src/Plugins/DBFTPlugin/Types/ConsensusMessageType.cs
@@ -9,7 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-namespace Neo.Consensus
+namespace Neo.Plugins.DBFTPlugin.Types
{
public enum ConsensusMessageType : byte
{
diff --git a/src/Plugins/Directory.Build.props b/src/Plugins/Directory.Build.props
index f7bcef093b..72e96f0300 100644
--- a/src/Plugins/Directory.Build.props
+++ b/src/Plugins/Directory.Build.props
@@ -9,7 +9,7 @@
-
+
diff --git a/src/Plugins/LevelDBStore/LevelDBStore.csproj b/src/Plugins/LevelDBStore/LevelDBStore.csproj
index ba82156b18..ef605a7afe 100644
--- a/src/Plugins/LevelDBStore/LevelDBStore.csproj
+++ b/src/Plugins/LevelDBStore/LevelDBStore.csproj
@@ -5,6 +5,7 @@
Neo.Plugins.Storage.LevelDBStore
Neo.Plugins.Storage
true
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/MPTTrie/MPTTrie.csproj b/src/Plugins/MPTTrie/MPTTrie.csproj
index a2c3377a16..ef9e45cc51 100644
--- a/src/Plugins/MPTTrie/MPTTrie.csproj
+++ b/src/Plugins/MPTTrie/MPTTrie.csproj
@@ -5,6 +5,7 @@
Neo.Cryptography.MPT
Neo.Cryptography
true
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/OracleService/Helper.cs b/src/Plugins/OracleService/Helper.cs
index 35611e8698..a4711b848e 100644
--- a/src/Plugins/OracleService/Helper.cs
+++ b/src/Plugins/OracleService/Helper.cs
@@ -12,7 +12,7 @@
using System.Linq;
using System.Net;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
static class Helper
{
diff --git a/src/Plugins/OracleService/OracleService.cs b/src/Plugins/OracleService/OracleService.cs
index 637c06712f..e9787b3d4c 100644
--- a/src/Plugins/OracleService/OracleService.cs
+++ b/src/Plugins/OracleService/OracleService.cs
@@ -20,6 +20,7 @@
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.RpcServer;
using Neo.SmartContract;
using Neo.SmartContract.Manifest;
using Neo.SmartContract.Native;
@@ -34,7 +35,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
public class OracleService : Plugin
{
@@ -427,10 +428,10 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req
var oracleContract = NativeContract.ContractManagement.GetContract(snapshot, NativeContract.Oracle.Hash);
var engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: settings);
- ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod("verify", -1);
+ ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
engine.LoadContract(oracleContract, md, CallFlags.None);
if (engine.Execute() != VMState.HALT) return null;
- tx.NetworkFee += engine.GasConsumed;
+ tx.NetworkFee += engine.FeeConsumed;
var executionFactor = NativeContract.Policy.GetExecFeeFactor(snapshot);
var networkFee = executionFactor * SmartContract.Helper.MultiSignatureContractCost(m, n);
diff --git a/src/Plugins/OracleService/OracleService.csproj b/src/Plugins/OracleService/OracleService.csproj
index 48ca5f3808..1fa5c5602f 100644
--- a/src/Plugins/OracleService/OracleService.csproj
+++ b/src/Plugins/OracleService/OracleService.csproj
@@ -3,6 +3,7 @@
net8.0
Neo.Plugins.OracleService
+ $(SolutionDir)/bin/$(PackageId)
@@ -23,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/src/Plugins/OracleService/Protocols/IOracleProtocol.cs b/src/Plugins/OracleService/Protocols/IOracleProtocol.cs
index 3532a69454..d8b84660ee 100644
--- a/src/Plugins/OracleService/Protocols/IOracleProtocol.cs
+++ b/src/Plugins/OracleService/Protocols/IOracleProtocol.cs
@@ -14,7 +14,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
interface IOracleProtocol : IDisposable
{
diff --git a/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs b/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs
index 29d3eedc43..a825f5e60f 100644
--- a/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs
+++ b/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs
@@ -20,7 +20,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
class OracleHttpsProtocol : IOracleProtocol
{
diff --git a/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs
index 2bf92fa8f4..de0cbd8044 100644
--- a/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs
+++ b/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs
@@ -24,7 +24,7 @@
using Object = Neo.FileStorage.API.Object.Object;
using Range = Neo.FileStorage.API.Object.Range;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
class OracleNeoFSProtocol : IOracleProtocol
{
diff --git a/src/Plugins/OracleService/Settings.cs b/src/Plugins/OracleService/Settings.cs
index c66010cb5f..952ea0c27b 100644
--- a/src/Plugins/OracleService/Settings.cs
+++ b/src/Plugins/OracleService/Settings.cs
@@ -13,7 +13,7 @@
using System;
using System.Linq;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService
{
class HttpsSettings
{
diff --git a/src/Plugins/RocksDBStore/RocksDBStore.csproj b/src/Plugins/RocksDBStore/RocksDBStore.csproj
index 57037c68cf..441b17306e 100644
--- a/src/Plugins/RocksDBStore/RocksDBStore.csproj
+++ b/src/Plugins/RocksDBStore/RocksDBStore.csproj
@@ -4,6 +4,7 @@
net8.0
Neo.Plugins.Storage.RocksDBStore
Neo.Plugins.Storage
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/RpcClient/RpcClient.csproj b/src/Plugins/RpcClient/RpcClient.csproj
index cc634337d5..c43c71ef8a 100644
--- a/src/Plugins/RpcClient/RpcClient.csproj
+++ b/src/Plugins/RpcClient/RpcClient.csproj
@@ -4,6 +4,7 @@
net8.0
Neo.Network.RPC.RpcClient
Neo.Network.RPC
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/RpcServer/Diagnostic.cs b/src/Plugins/RpcServer/Diagnostic.cs
index a8cba4af9a..7363bc852c 100644
--- a/src/Plugins/RpcServer/Diagnostic.cs
+++ b/src/Plugins/RpcServer/Diagnostic.cs
@@ -12,7 +12,7 @@
using Neo.SmartContract;
using Neo.VM;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
class Diagnostic : IDiagnostic
{
diff --git a/src/Plugins/RpcServer/Result.cs b/src/Plugins/RpcServer/Result.cs
index 0ead2482cd..9c7ace227c 100644
--- a/src/Plugins/RpcServer/Result.cs
+++ b/src/Plugins/RpcServer/Result.cs
@@ -10,7 +10,7 @@
// modifications are permitted.
using System;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public static class Result
{
diff --git a/src/Plugins/RpcServer/RpcError.cs b/src/Plugins/RpcServer/RpcError.cs
index 7130540183..667a3906d4 100644
--- a/src/Plugins/RpcServer/RpcError.cs
+++ b/src/Plugins/RpcServer/RpcError.cs
@@ -11,7 +11,7 @@
using Neo.Json;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public class RpcError
{
diff --git a/src/Plugins/RpcServer/RpcErrorFactory.cs b/src/Plugins/RpcServer/RpcErrorFactory.cs
index 328ba02f61..3d2ac7c9a5 100644
--- a/src/Plugins/RpcServer/RpcErrorFactory.cs
+++ b/src/Plugins/RpcServer/RpcErrorFactory.cs
@@ -11,7 +11,7 @@
using Neo.Cryptography.ECC;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public static class RpcErrorFactory
{
diff --git a/src/Plugins/RpcServer/RpcException.cs b/src/Plugins/RpcServer/RpcException.cs
index 5c7b5675a1..ab47901b6d 100644
--- a/src/Plugins/RpcServer/RpcException.cs
+++ b/src/Plugins/RpcServer/RpcException.cs
@@ -11,7 +11,7 @@
using System;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public class RpcException : Exception
{
diff --git a/src/Plugins/RpcServer/RpcMethodAttribute.cs b/src/Plugins/RpcServer/RpcMethodAttribute.cs
index 89edccdd5a..743530ca83 100644
--- a/src/Plugins/RpcServer/RpcMethodAttribute.cs
+++ b/src/Plugins/RpcServer/RpcMethodAttribute.cs
@@ -11,7 +11,7 @@
using System;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RpcMethodAttribute : Attribute
diff --git a/src/Plugins/RpcServer/RpcServer.Blockchain.cs b/src/Plugins/RpcServer/RpcServer.Blockchain.cs
index a4fda6e738..1c8eecb99f 100644
--- a/src/Plugins/RpcServer/RpcServer.Blockchain.cs
+++ b/src/Plugins/RpcServer/RpcServer.Blockchain.cs
@@ -20,7 +20,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
@@ -61,7 +61,7 @@ protected virtual JToken GetBlock(JArray _params)
}
[RpcMethod]
- protected virtual JToken GetBlockHeaderCount(JArray _params)
+ internal virtual JToken GetBlockHeaderCount(JArray _params)
{
return (system.HeaderCache.Last?.Index ?? NativeContract.Ledger.CurrentIndex(system.StoreView)) + 1;
}
@@ -119,15 +119,13 @@ protected virtual JToken GetContractState(JArray _params)
{
if (int.TryParse(_params[0].AsString(), out int contractId))
{
- var contracts = NativeContract.ContractManagement.GetContractById(system.StoreView, contractId);
- return contracts?.ToJson().NotNull_Or(RpcError.UnknownContract);
- }
- else
- {
- UInt160 script_hash = ToScriptHash(_params[0].AsString());
- ContractState contract = NativeContract.ContractManagement.GetContract(system.StoreView, script_hash);
- return contract?.ToJson().NotNull_Or(RpcError.UnknownContract);
+ var contractState = NativeContract.ContractManagement.GetContractById(system.StoreView, contractId);
+ return contractState.NotNull_Or(RpcError.UnknownContract).ToJson();
}
+
+ var scriptHash = ToScriptHash(_params[0].AsString());
+ var contract = NativeContract.ContractManagement.GetContract(system.StoreView, scriptHash);
+ return contract.NotNull_Or(RpcError.UnknownContract).ToJson();
}
private static UInt160 ToScriptHash(string keyword)
diff --git a/src/Plugins/RpcServer/RpcServer.Node.cs b/src/Plugins/RpcServer/RpcServer.Node.cs
index c455100802..79a8884a0f 100644
--- a/src/Plugins/RpcServer/RpcServer.Node.cs
+++ b/src/Plugins/RpcServer/RpcServer.Node.cs
@@ -19,7 +19,7 @@
using System.Linq;
using static Neo.Ledger.Blockchain;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs
index 92ea7ff62c..2fe49d4965 100644
--- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs
+++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs
@@ -26,7 +26,7 @@
using System.Threading;
using Array = System.Array;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
@@ -75,7 +75,8 @@ private JObject GetInvokeResult(byte[] script, Signer[] signers = null, Witness[
{
json["script"] = Convert.ToBase64String(script);
json["state"] = session.Engine.State;
- json["gasconsumed"] = session.Engine.GasConsumed.ToString();
+ // Gas consumed in the unit of datoshi, 1 GAS = 10^8 datoshi
+ json["gasconsumed"] = session.Engine.FeeConsumed.ToString();
json["exception"] = GetExceptionMessage(session.Engine.FaultException);
json["notifications"] = new JArray(session.Engine.Notifications.Select(n =>
{
diff --git a/src/Plugins/RpcServer/RpcServer.Utilities.cs b/src/Plugins/RpcServer/RpcServer.Utilities.cs
index f410e01b73..f9b874c824 100644
--- a/src/Plugins/RpcServer/RpcServer.Utilities.cs
+++ b/src/Plugins/RpcServer/RpcServer.Utilities.cs
@@ -13,7 +13,7 @@
using Neo.Wallets;
using System.Linq;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs
index 36825b3f82..f1adb277ce 100644
--- a/src/Plugins/RpcServer/RpcServer.Wallet.cs
+++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs
@@ -25,7 +25,7 @@
using System.Linq;
using System.Numerics;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
@@ -95,14 +95,15 @@ protected virtual JToken GetWalletBalance(JArray _params)
protected virtual JToken GetWalletUnclaimedGas(JArray _params)
{
CheckWallet();
- BigInteger gas = BigInteger.Zero;
+ // Datoshi is the smallest unit of GAS, 1 GAS = 10^8 Datoshi
+ BigInteger datoshi = BigInteger.Zero;
using (var snapshot = system.GetSnapshot())
{
uint height = NativeContract.Ledger.CurrentIndex(snapshot) + 1;
foreach (UInt160 account in wallet.GetAccounts().Select(p => p.ScriptHash))
- gas += NativeContract.NEO.UnclaimedGas(snapshot, account, height);
+ datoshi += NativeContract.NEO.UnclaimedGas(snapshot, account, height);
}
- return gas.ToString();
+ return datoshi.ToString();
}
[RpcMethod]
@@ -355,7 +356,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar
{
using var snapshot = system.GetSnapshot();
var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash).NotNull_Or(RpcError.UnknownContract);
- var md = contract.Manifest.Abi.GetMethod("verify", -1).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
+ var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
(md.ReturnType == ContractParameterType.Boolean).True_Or(RpcErrorFactory.InvalidContractVerification("The verify method doesn't return boolean value."));
Transaction tx = new()
{
@@ -381,7 +382,8 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar
JObject json = new();
json["script"] = Convert.ToBase64String(invocationScript);
json["state"] = engine.Execute();
- json["gasconsumed"] = engine.GasConsumed.ToString();
+ // Gas consumed in the unit of datoshi, 1 GAS = 1e8 datoshi
+ json["gasconsumed"] = engine.FeeConsumed.ToString();
json["exception"] = GetExceptionMessage(engine.FaultException);
try
{
diff --git a/src/Plugins/RpcServer/RpcServer.cs b/src/Plugins/RpcServer/RpcServer.cs
index f77c2d1e33..c53f17b860 100644
--- a/src/Plugins/RpcServer/RpcServer.cs
+++ b/src/Plugins/RpcServer/RpcServer.cs
@@ -29,7 +29,7 @@
using System.Text;
using System.Threading.Tasks;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public partial class RpcServer : IDisposable
{
@@ -51,7 +51,7 @@ public RpcServer(NeoSystem system, RpcServerSettings settings)
Initialize_SmartContract();
}
- private bool CheckAuth(HttpContext context)
+ internal bool CheckAuth(HttpContext context)
{
if (string.IsNullOrEmpty(settings.RpcUser)) return true;
diff --git a/src/Plugins/RpcServer/RpcServer.csproj b/src/Plugins/RpcServer/RpcServer.csproj
index ab2d7e6783..3fb7a7bb9a 100644
--- a/src/Plugins/RpcServer/RpcServer.csproj
+++ b/src/Plugins/RpcServer/RpcServer.csproj
@@ -1,8 +1,9 @@
-
+
- net8.0
+ net8.0
Neo.Plugins.RpcServer
+ $(SolutionDir)/bin/$(PackageId)
@@ -15,4 +16,8 @@
+
+
+
+
diff --git a/src/Plugins/RpcServer/RpcServerPlugin.cs b/src/Plugins/RpcServer/RpcServerPlugin.cs
index 61d9da4397..c22462d139 100644
--- a/src/Plugins/RpcServer/RpcServerPlugin.cs
+++ b/src/Plugins/RpcServer/RpcServerPlugin.cs
@@ -12,7 +12,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
public class RpcServerPlugin : Plugin
{
@@ -55,18 +55,18 @@ protected override void OnSystemLoaded(NeoSystem system)
$"Example: \"AllowOrigins\": [\"http://{s.BindAddress}:{s.Port}\"]", LogLevel.Info);
}
- RpcServer server = new(system, s);
+ RpcServer rpcRpcServer = new(system, s);
if (handlers.Remove(s.Network, out var list))
{
foreach (var handler in list)
{
- server.RegisterMethods(handler);
+ rpcRpcServer.RegisterMethods(handler);
}
}
- server.StartRpcServer();
- servers.TryAdd(s.Network, server);
+ rpcRpcServer.StartRpcServer();
+ servers.TryAdd(s.Network, rpcRpcServer);
}
public static void RegisterMethods(object handler, uint network)
diff --git a/src/Plugins/RpcServer/Session.cs b/src/Plugins/RpcServer/Session.cs
index 2b4213c28e..1dd8808dde 100644
--- a/src/Plugins/RpcServer/Session.cs
+++ b/src/Plugins/RpcServer/Session.cs
@@ -17,7 +17,7 @@
using System;
using System.Collections.Generic;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
class Session : IDisposable
{
@@ -26,7 +26,7 @@ class Session : IDisposable
public readonly Dictionary Iterators = new();
public DateTime StartTime;
- public Session(NeoSystem system, byte[] script, Signer[] signers, Witness[] witnesses, long gas, Diagnostic diagnostic)
+ public Session(NeoSystem system, byte[] script, Signer[] signers, Witness[] witnesses, long datoshi, Diagnostic diagnostic)
{
Random random = new();
Snapshot = system.GetSnapshot();
@@ -40,7 +40,7 @@ public Session(NeoSystem system, byte[] script, Signer[] signers, Witness[] witn
Script = script,
Witnesses = witnesses
};
- Engine = ApplicationEngine.Run(script, Snapshot, container: tx, settings: system.Settings, gas: gas, diagnostic: diagnostic);
+ Engine = ApplicationEngine.Run(script, Snapshot, container: tx, settings: system.Settings, gas: datoshi, diagnostic: diagnostic);
ResetExpiration();
}
diff --git a/src/Plugins/RpcServer/Settings.cs b/src/Plugins/RpcServer/Settings.cs
index f4aef116c6..ad624d9082 100644
--- a/src/Plugins/RpcServer/Settings.cs
+++ b/src/Plugins/RpcServer/Settings.cs
@@ -16,7 +16,7 @@
using System.Linq;
using System.Net;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
class Settings
{
@@ -44,7 +44,9 @@ public record RpcServerSettings
public string[] AllowOrigins { get; init; }
public int KeepAliveTimeout { get; init; }
public uint RequestHeadersTimeout { get; init; }
+ // In the unit of datoshi, 1 GAS = 10^8 datoshi
public long MaxGasInvoke { get; init; }
+ // In the unit of datoshi, 1 GAS = 10^8 datoshi
public long MaxFee { get; init; }
public int MaxIteratorResultItems { get; init; }
public int MaxStackSize { get; init; }
diff --git a/src/Plugins/RpcServer/Tree.cs b/src/Plugins/RpcServer/Tree.cs
index 77ca1fc2a5..b2d1afc11a 100644
--- a/src/Plugins/RpcServer/Tree.cs
+++ b/src/Plugins/RpcServer/Tree.cs
@@ -12,7 +12,7 @@
using System;
using System.Collections.Generic;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
class Tree
{
diff --git a/src/Plugins/RpcServer/TreeNode.cs b/src/Plugins/RpcServer/TreeNode.cs
index 82785277b6..0ba06a689f 100644
--- a/src/Plugins/RpcServer/TreeNode.cs
+++ b/src/Plugins/RpcServer/TreeNode.cs
@@ -11,7 +11,7 @@
using System.Collections.Generic;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
class TreeNode
{
diff --git a/src/Plugins/RpcServer/Utility.cs b/src/Plugins/RpcServer/Utility.cs
index 24ccc9248d..1dda8c131c 100644
--- a/src/Plugins/RpcServer/Utility.cs
+++ b/src/Plugins/RpcServer/Utility.cs
@@ -14,7 +14,7 @@
using Neo.SmartContract.Native;
using System.Linq;
-namespace Neo.Plugins
+namespace Neo.Plugins.RpcServer
{
static class Utility
{
diff --git a/src/Plugins/SQLiteWallet/SQLiteWallet.csproj b/src/Plugins/SQLiteWallet/SQLiteWallet.csproj
index fb2d3e71b8..4c9029040f 100644
--- a/src/Plugins/SQLiteWallet/SQLiteWallet.csproj
+++ b/src/Plugins/SQLiteWallet/SQLiteWallet.csproj
@@ -5,6 +5,7 @@
Neo.Wallets.SQLite
Neo.Wallets.SQLite
enable
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/StateService/StatePlugin.cs b/src/Plugins/StateService/StatePlugin.cs
index 36d2c01050..1c28e92193 100644
--- a/src/Plugins/StateService/StatePlugin.cs
+++ b/src/Plugins/StateService/StatePlugin.cs
@@ -17,6 +17,7 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.RpcServer;
using Neo.Plugins.StateService.Network;
using Neo.Plugins.StateService.Storage;
using Neo.Plugins.StateService.Verification;
diff --git a/src/Plugins/StateService/StateService.csproj b/src/Plugins/StateService/StateService.csproj
index b8e395c990..2bf85f1465 100644
--- a/src/Plugins/StateService/StateService.csproj
+++ b/src/Plugins/StateService/StateService.csproj
@@ -4,6 +4,7 @@
net8.0
Neo.Plugins.StateService
true
+ $(SolutionDir)/bin/$(PackageId)
@@ -18,4 +19,4 @@
-
\ No newline at end of file
+
diff --git a/src/Plugins/StatesDumper/PersistActions.cs b/src/Plugins/StatesDumper/PersistActions.cs
deleted file mode 100644
index 9c1aa2210c..0000000000
--- a/src/Plugins/StatesDumper/PersistActions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2015-2024 The Neo Project.
-//
-// PersistActions.cs file belongs to the neo project and is free
-// software distributed under the MIT software license, see the
-// accompanying file LICENSE in the main directory of the
-// repository or http://www.opensource.org/licenses/mit-license.php
-// for more details.
-//
-// Redistribution and use in source and binary forms with or without
-// modifications are permitted.
-
-using System;
-
-namespace Neo.Plugins
-{
- [Flags]
- internal enum PersistActions : byte
- {
- StorageChanges = 0b00000001
- }
-}
diff --git a/src/Plugins/StatesDumper/Settings.cs b/src/Plugins/StatesDumper/Settings.cs
deleted file mode 100644
index 8fd3b9e163..0000000000
--- a/src/Plugins/StatesDumper/Settings.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2015-2024 The Neo Project.
-//
-// Settings.cs file belongs to the neo project and is free
-// software distributed under the MIT software license, see the
-// accompanying file LICENSE in the main directory of the
-// repository or http://www.opensource.org/licenses/mit-license.php
-// for more details.
-//
-// Redistribution and use in source and binary forms with or without
-// modifications are permitted.
-
-using Microsoft.Extensions.Configuration;
-using Neo.SmartContract.Native;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Neo.Plugins
-{
- internal class Settings
- {
- ///
- /// Amount of storages states (heights) to be dump in a given json file
- ///
- public uint BlockCacheSize { get; }
- ///
- /// Height to begin storage dump
- ///
- public uint HeightToBegin { get; }
- ///
- /// Height to begin real-time syncing and dumping on, consequently, dumping every block into a single files
- ///
- public int HeightToStartRealTimeSyncing { get; }
- ///
- /// Persisting actions
- ///
- public PersistActions PersistAction { get; }
- public IReadOnlyList Exclude { get; }
-
- public static Settings Default { get; private set; }
-
- private Settings(IConfigurationSection section)
- {
- /// Geting settings for storage changes state dumper
- BlockCacheSize = section.GetValue("BlockCacheSize", 1000u);
- HeightToBegin = section.GetValue("HeightToBegin", 0u);
- HeightToStartRealTimeSyncing = section.GetValue("HeightToStartRealTimeSyncing", -1);
- PersistAction = section.GetValue("PersistAction", PersistActions.StorageChanges);
- Exclude = section.GetSection("Exclude").Exists()
- ? section.GetSection("Exclude").GetChildren().Select(p => int.Parse(p.Value)).ToArray()
- : new[] { NativeContract.Ledger.Id };
- }
-
- public static void Load(IConfigurationSection section)
- {
- Default = new Settings(section);
- }
- }
-}
diff --git a/src/Plugins/StatesDumper/StatesDumper.cs b/src/Plugins/StatesDumper/StatesDumper.cs
deleted file mode 100644
index da1bbd3f69..0000000000
--- a/src/Plugins/StatesDumper/StatesDumper.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (C) 2015-2024 The Neo Project.
-//
-// StatesDumper.cs file belongs to the neo project and is free
-// software distributed under the MIT software license, see the
-// accompanying file LICENSE in the main directory of the
-// repository or http://www.opensource.org/licenses/mit-license.php
-// for more details.
-//
-// Redistribution and use in source and binary forms with or without
-// modifications are permitted.
-
-using Neo.ConsoleService;
-using Neo.IO;
-using Neo.Json;
-using Neo.Ledger;
-using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
-using Neo.SmartContract.Native;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Plugins
-{
- public class StatesDumper : Plugin
- {
- private readonly Dictionary bs_cache = new Dictionary();
- private readonly Dictionary systems = new Dictionary();
-
- public override string Description => "Exports Neo-CLI status data";
-
- public override string ConfigFile => System.IO.Path.Combine(RootPath, "StatesDumper.json");
-
- public StatesDumper()
- {
- Blockchain.Committing += OnCommitting;
- Blockchain.Committed += OnCommitted;
- }
-
- public override void Dispose()
- {
- Blockchain.Committing -= OnCommitting;
- Blockchain.Committed -= OnCommitted;
- }
-
- protected override void Configure()
- {
- Settings.Load(GetConfiguration());
- }
-
- protected override void OnSystemLoaded(NeoSystem system)
- {
- systems.Add(system.Settings.Network, system);
- }
-
- ///
- /// Process "dump storage" command
- ///
- [ConsoleCommand("dump storage", Category = "Storage", Description = "You can specify the contract script hash or use null to get the corresponding information from the storage")]
- private void OnDumpStorage(uint network, UInt160 contractHash = null)
- {
- if (!systems.ContainsKey(network)) throw new InvalidOperationException("invalid network");
- string path = $"dump_{network:x8}.json";
- byte[] prefix = null;
- if (contractHash is not null)
- {
- var contract = NativeContract.ContractManagement.GetContract(systems[network].StoreView, contractHash);
- if (contract is null) throw new InvalidOperationException("contract not found");
- prefix = BitConverter.GetBytes(contract.Id);
- }
- var states = systems[network].StoreView.Find(prefix);
- JArray array = new JArray(states.Where(p => !Settings.Default.Exclude.Contains(p.Key.Id)).Select(p => new JObject
- {
- ["key"] = Convert.ToBase64String(p.Key.ToArray()),
- ["value"] = Convert.ToBase64String(p.Value.ToArray())
- }));
- File.WriteAllText(path, array.ToString());
- ConsoleHelper.Info("States",
- $"({array.Count})",
- " have been dumped into file ",
- $"{path}");
- }
-
- private void OnCommitting(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList)
- {
- if (Settings.Default.PersistAction.HasFlag(PersistActions.StorageChanges))
- OnPersistStorage(system.Settings.Network, snapshot);
- }
-
- private void OnPersistStorage(uint network, DataCache snapshot)
- {
- uint blockIndex = NativeContract.Ledger.CurrentIndex(snapshot);
- if (blockIndex >= Settings.Default.HeightToBegin)
- {
- JArray array = new JArray();
-
- foreach (var trackable in snapshot.GetChangeSet())
- {
- if (Settings.Default.Exclude.Contains(trackable.Key.Id))
- continue;
- JObject state = new JObject();
- switch (trackable.State)
- {
- case TrackState.Added:
- state["state"] = "Added";
- state["key"] = Convert.ToBase64String(trackable.Key.ToArray());
- state["value"] = Convert.ToBase64String(trackable.Item.ToArray());
- // Here we have a new trackable.Key and trackable.Item
- break;
- case TrackState.Changed:
- state["state"] = "Changed";
- state["key"] = Convert.ToBase64String(trackable.Key.ToArray());
- state["value"] = Convert.ToBase64String(trackable.Item.ToArray());
- break;
- case TrackState.Deleted:
- state["state"] = "Deleted";
- state["key"] = Convert.ToBase64String(trackable.Key.ToArray());
- break;
- }
- array.Add(state);
- }
-
- JObject bs_item = new JObject();
- bs_item["block"] = blockIndex;
- bs_item["size"] = array.Count;
- bs_item["storage"] = array;
- if (!bs_cache.TryGetValue(network, out JArray cache))
- {
- cache = new JArray();
- }
- cache.Add(bs_item);
- bs_cache[network] = cache;
- }
- }
-
- private void OnCommitted(NeoSystem system, Block block)
- {
- if (Settings.Default.PersistAction.HasFlag(PersistActions.StorageChanges))
- OnCommitStorage(system.Settings.Network, system.StoreView);
- }
-
- void OnCommitStorage(uint network, DataCache snapshot)
- {
- if (!bs_cache.TryGetValue(network, out JArray cache)) return;
- if (cache.Count == 0) return;
- uint blockIndex = NativeContract.Ledger.CurrentIndex(snapshot);
- if ((blockIndex % Settings.Default.BlockCacheSize == 0) || (Settings.Default.HeightToStartRealTimeSyncing != -1 && blockIndex >= Settings.Default.HeightToStartRealTimeSyncing))
- {
- string path = HandlePaths(network, blockIndex);
- path = $"{path}/dump-block-{blockIndex}.json";
- File.WriteAllText(path, cache.ToString());
- cache.Clear();
- }
- }
-
- private static string HandlePaths(uint network, uint blockIndex)
- {
- //Default Parameter
- uint storagePerFolder = 100000;
- uint folder = (((blockIndex - 1) / storagePerFolder) + 1) * storagePerFolder;
- if (blockIndex == 0)
- folder = 0;
- string dirPathWithBlock = $"./Storage_{network:x8}/BlockStorage_{folder}";
- Directory.CreateDirectory(dirPathWithBlock);
- return dirPathWithBlock;
- }
- }
-}
diff --git a/src/Plugins/StatesDumper/StatesDumper.csproj b/src/Plugins/StatesDumper/StatesDumper.csproj
deleted file mode 100644
index 4ebf25f2c1..0000000000
--- a/src/Plugins/StatesDumper/StatesDumper.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- net8.0
- Neo.Plugins.StatesDumper
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
diff --git a/src/Plugins/StatesDumper/StatesDumper.json b/src/Plugins/StatesDumper/StatesDumper.json
deleted file mode 100644
index c3b73767dd..0000000000
--- a/src/Plugins/StatesDumper/StatesDumper.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "PluginConfiguration": {
- "PersistAction": "StorageChanges",
- "BlockCacheSize": 1000,
- "HeightToBegin": 0,
- "HeightToStartRealTimeSyncing": -1,
- "Exclude": [ -4 ]
- }
-}
diff --git a/src/Plugins/StorageDumper/Settings.cs b/src/Plugins/StorageDumper/Settings.cs
index 84fe2b2231..c2761ce6b9 100644
--- a/src/Plugins/StorageDumper/Settings.cs
+++ b/src/Plugins/StorageDumper/Settings.cs
@@ -12,7 +12,7 @@
using Microsoft.Extensions.Configuration;
using Neo.SmartContract.Native;
-namespace Neo.Plugins
+namespace Neo.Plugins.StorageDumper
{
internal class Settings
{
@@ -24,18 +24,22 @@ internal class Settings
/// Height to begin storage dump
///
public uint HeightToBegin { get; }
-
+ ///
+ /// Default number of items per folder
+ ///
+ public uint StoragePerFolder { get; }
public IReadOnlyList Exclude { get; }
public static Settings? Default { get; private set; }
private Settings(IConfigurationSection section)
{
- /// Geting settings for storage changes state dumper
+ // Geting settings for storage changes state dumper
BlockCacheSize = section.GetValue("BlockCacheSize", 1000u);
HeightToBegin = section.GetValue("HeightToBegin", 0u);
+ StoragePerFolder = section.GetValue("StoragePerFolder", 100000u);
Exclude = section.GetSection("Exclude").Exists()
- ? section.GetSection("Exclude").GetChildren().Select(p => int.Parse(p.Value)).ToArray()
+ ? section.GetSection("Exclude").GetChildren().Select(p => int.Parse(p.Value!)).ToArray()
: new[] { NativeContract.Ledger.Id };
}
diff --git a/src/Plugins/StorageDumper/StorageDumper.cs b/src/Plugins/StorageDumper/StorageDumper.cs
index 696f5014ac..d8987cdcaa 100644
--- a/src/Plugins/StorageDumper/StorageDumper.cs
+++ b/src/Plugins/StorageDumper/StorageDumper.cs
@@ -17,15 +17,18 @@
using Neo.Persistence;
using Neo.SmartContract.Native;
-namespace Neo.Plugins
+namespace Neo.Plugins.StorageDumper
{
public class StorageDumper : Plugin
{
private readonly Dictionary systems = new Dictionary();
- private StreamWriter _writer;
- private JObject _currentBlock;
- private string _lastCreateDirectory;
+ private StreamWriter? _writer;
+ ///
+ /// _currentBlock stores the last cached item
+ ///
+ private JObject? _currentBlock;
+ private string? _lastCreateDirectory;
public override string Description => "Exports Neo-CLI status data";
@@ -70,7 +73,7 @@ private void OnDumpStorage(uint network, UInt160? contractHash = null)
prefix = BitConverter.GetBytes(contract.Id);
}
var states = systems[network].StoreView.Find(prefix);
- JArray array = new JArray(states.Where(p => !Settings.Default.Exclude.Contains(p.Key.Id)).Select(p => new JObject
+ JArray array = new JArray(states.Where(p => !Settings.Default!.Exclude.Contains(p.Key.Id)).Select(p => new JObject
{
["key"] = Convert.ToBase64String(p.Key.ToArray()),
["value"] = Convert.ToBase64String(p.Value.ToArray())
@@ -91,9 +94,9 @@ private void OnCommitting(NeoSystem system, Block block, DataCache snapshot, IRe
private void OnPersistStorage(uint network, DataCache snapshot)
{
uint blockIndex = NativeContract.Ledger.CurrentIndex(snapshot);
- if (blockIndex >= Settings.Default.HeightToBegin)
+ if (blockIndex >= Settings.Default!.HeightToBegin)
{
- JArray array = new JArray();
+ JArray stateChangeArray = new JArray();
foreach (var trackable in snapshot.GetChangeSet())
{
@@ -106,7 +109,6 @@ private void OnPersistStorage(uint network, DataCache snapshot)
state["state"] = "Added";
state["key"] = Convert.ToBase64String(trackable.Key.ToArray());
state["value"] = Convert.ToBase64String(trackable.Item.ToArray());
- // Here we have a new trackable.Key and trackable.Item
break;
case TrackState.Changed:
state["state"] = "Changed";
@@ -118,13 +120,13 @@ private void OnPersistStorage(uint network, DataCache snapshot)
state["key"] = Convert.ToBase64String(trackable.Key.ToArray());
break;
}
- array.Add(state);
+ stateChangeArray.Add(state);
}
JObject bs_item = new JObject();
bs_item["block"] = blockIndex;
- bs_item["size"] = array.Count;
- bs_item["storage"] = array;
+ bs_item["size"] = stateChangeArray.Count;
+ bs_item["storage"] = stateChangeArray;
_currentBlock = bs_item;
}
}
@@ -137,7 +139,7 @@ private void OnCommitted(NeoSystem system, Block block)
void OnCommitStorage(uint network, DataCache snapshot)
{
- if (_currentBlock != null)
+ if (_currentBlock != null && _writer != null)
{
_writer.WriteLine(_currentBlock.ToString());
_writer.Flush();
@@ -148,10 +150,10 @@ private void InitFileWriter(uint network, DataCache snapshot)
{
uint blockIndex = NativeContract.Ledger.CurrentIndex(snapshot);
if (_writer == null
- || blockIndex % Settings.Default.BlockCacheSize == 0)
+ || blockIndex % Settings.Default!.BlockCacheSize == 0)
{
string path = GetOrCreateDirectory(network, blockIndex);
- var filepart = (blockIndex / Settings.Default.BlockCacheSize) * Settings.Default.BlockCacheSize;
+ var filepart = (blockIndex / Settings.Default!.BlockCacheSize) * Settings.Default.BlockCacheSize;
path = $"{path}/dump-block-{filepart}.dump";
if (_writer != null)
{
@@ -174,9 +176,7 @@ private string GetOrCreateDirectory(uint network, uint blockIndex)
private string GetDirectoryPath(uint network, uint blockIndex)
{
- //Default Parameter
- uint storagePerFolder = 100000;
- uint folder = (blockIndex / storagePerFolder) * storagePerFolder;
+ uint folder = (blockIndex / Settings.Default!.StoragePerFolder) * Settings.Default.StoragePerFolder;
return $"./StorageDumper_{network}/BlockStorage_{folder}";
}
diff --git a/src/Plugins/StorageDumper/StorageDumper.csproj b/src/Plugins/StorageDumper/StorageDumper.csproj
index 49d5362538..7805140f3e 100644
--- a/src/Plugins/StorageDumper/StorageDumper.csproj
+++ b/src/Plugins/StorageDumper/StorageDumper.csproj
@@ -5,6 +5,7 @@
Neo.Plugins.StorageDumper
enable
enable
+ $(SolutionDir)/bin/$(PackageId)
diff --git a/src/Plugins/StorageDumper/StorageDumper.json b/src/Plugins/StorageDumper/StorageDumper.json
index 3f5c0537f0..b327c37e0c 100644
--- a/src/Plugins/StorageDumper/StorageDumper.json
+++ b/src/Plugins/StorageDumper/StorageDumper.json
@@ -2,6 +2,7 @@
"PluginConfiguration": {
"BlockCacheSize": 1000,
"HeightToBegin": 0,
+ "StoragePerFolder": 100000,
"Exclude": [ -4 ]
}
}
diff --git a/src/Plugins/TokensTracker/TokensTracker.cs b/src/Plugins/TokensTracker/TokensTracker.cs
index 0d8863a767..eacd0de6e4 100644
--- a/src/Plugins/TokensTracker/TokensTracker.cs
+++ b/src/Plugins/TokensTracker/TokensTracker.cs
@@ -10,12 +10,11 @@
// modifications are permitted.
using Microsoft.Extensions.Configuration;
-using Neo.IO;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.RpcServer;
using Neo.Plugins.Trackers;
-using System;
using System.Collections.Generic;
using System.Linq;
using static System.IO.Path;
diff --git a/src/Plugins/TokensTracker/TokensTracker.csproj b/src/Plugins/TokensTracker/TokensTracker.csproj
index 7c3df5c0c6..bdacd3839c 100644
--- a/src/Plugins/TokensTracker/TokensTracker.csproj
+++ b/src/Plugins/TokensTracker/TokensTracker.csproj
@@ -1,8 +1,9 @@
-
+
net8.0
Neo.Plugins.TokensTracker
+ $(SolutionDir)/bin/$(PackageId)
@@ -15,4 +16,4 @@
-
\ No newline at end of file
+
diff --git a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs
index 35a579eb77..12d3c208bc 100644
--- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs
+++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs
@@ -13,6 +13,7 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.RpcServer;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
diff --git a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs
index 8ea2efa6a6..d4698cba1e 100644
--- a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs
+++ b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs
@@ -13,6 +13,7 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins.RpcServer;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index 7ba3905160..a2fc251365 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -7,6 +7,9 @@
false
true
0
+ true
+ TestResults/
+ lcov
diff --git a/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs b/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs
index 88c08575fa..d689578e22 100644
--- a/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs
+++ b/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs
@@ -12,7 +12,7 @@
using Neo.Persistence;
using System;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService.Tests
{
public static class TestBlockchain
{
diff --git a/tests/Neo.Plugins.OracleService.Tests/TestUtils.cs b/tests/Neo.Plugins.OracleService.Tests/TestUtils.cs
index 5700b83769..7f1c3a58d5 100644
--- a/tests/Neo.Plugins.OracleService.Tests/TestUtils.cs
+++ b/tests/Neo.Plugins.OracleService.Tests/TestUtils.cs
@@ -13,7 +13,7 @@
using Neo.SmartContract;
using Neo.SmartContract.Native;
-namespace Neo.Plugins
+namespace Neo.Plugins.OracleService.Tests
{
public static class TestUtils
{
diff --git a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs
index 08f96c95d7..9622ceb9e2 100644
--- a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs
+++ b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs
@@ -16,7 +16,7 @@
using Neo.SmartContract;
using Neo.SmartContract.Native;
-namespace Neo.Plugins.Tests
+namespace Neo.Plugins.OracleService.Tests
{
[TestClass]
public class UT_OracleService : TestKit
diff --git a/tests/Neo.Plugins.RpcServer.Tests/MockNeoSystem.cs b/tests/Neo.Plugins.RpcServer.Tests/MockNeoSystem.cs
new file mode 100644
index 0000000000..0f45a63d98
--- /dev/null
+++ b/tests/Neo.Plugins.RpcServer.Tests/MockNeoSystem.cs
@@ -0,0 +1,34 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// MockNeoSystem.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using Neo.Ledger;
+using Neo.Persistence;
+
+namespace Neo.Plugins.RpcServer.Tests
+{
+ public class MockNeoSystem : NeoSystem
+ {
+ public SnapshotCache SnapshotCache { get; }
+ public MemoryPool MemoryPool { get; }
+
+ public MockNeoSystem(SnapshotCache snapshotCache, MemoryPool memoryPool)
+ : base(TestProtocolSettings.Default, new TestBlockchain.StoreProvider())
+ {
+ SnapshotCache = snapshotCache;
+ MemoryPool = memoryPool;
+ }
+
+ public SnapshotCache GetSnapshot()
+ {
+ return SnapshotCache;
+ }
+ }
+}
diff --git a/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj b/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj
index 2459b1cb5f..5b693c96b8 100644
--- a/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj
+++ b/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj
@@ -8,11 +8,13 @@
+
+
diff --git a/tests/Neo.Plugins.RpcServer.Tests/TestBlockchain.cs b/tests/Neo.Plugins.RpcServer.Tests/TestBlockchain.cs
new file mode 100644
index 0000000000..f6e35cf695
--- /dev/null
+++ b/tests/Neo.Plugins.RpcServer.Tests/TestBlockchain.cs
@@ -0,0 +1,49 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// TestBlockchain.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using Akka.Actor;
+using Neo.Ledger;
+using Neo.Persistence;
+using System;
+
+namespace Neo.Plugins.RpcServer.Tests
+{
+ public static class TestBlockchain
+ {
+ public static readonly NeoSystem TheNeoSystem;
+ public static readonly UInt160[] DefaultExtensibleWitnessWhiteList;
+ private static readonly MemoryStore Store = new();
+
+ internal class StoreProvider : IStoreProvider
+ {
+ public string Name => "TestProvider";
+
+ public IStore GetStore(string path) => Store;
+ }
+
+ static TestBlockchain()
+ {
+ Console.WriteLine("initialize NeoSystem");
+ TheNeoSystem = new NeoSystem(TestProtocolSettings.Default, new StoreProvider());
+ }
+
+ internal static void ResetStore()
+ {
+ Store.Reset();
+ TheNeoSystem.Blockchain.Ask(new Blockchain.Initialize()).Wait();
+ }
+
+ internal static DataCache GetTestSnapshot()
+ {
+ return TheNeoSystem.GetSnapshot().CreateSnapshot();
+ }
+ }
+}
diff --git a/tests/Neo.Plugins.RpcServer.Tests/TestProtocolSettings.cs b/tests/Neo.Plugins.RpcServer.Tests/TestProtocolSettings.cs
new file mode 100644
index 0000000000..edf2df39fb
--- /dev/null
+++ b/tests/Neo.Plugins.RpcServer.Tests/TestProtocolSettings.cs
@@ -0,0 +1,65 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// TestProtocolSettings.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using Neo.Cryptography.ECC;
+
+namespace Neo.Plugins.RpcServer.Tests
+{
+ public static class TestProtocolSettings
+ {
+ public static readonly ProtocolSettings Default = new()
+ {
+ Network = 0x334F454Eu,
+ AddressVersion = ProtocolSettings.Default.AddressVersion,
+ StandbyCommittee = new[]
+ {
+ //Validators
+ ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", ECCurve.Secp256r1),
+ ECPoint.Parse("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093", ECCurve.Secp256r1),
+ ECPoint.Parse("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a", ECCurve.Secp256r1),
+ ECPoint.Parse("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554", ECCurve.Secp256r1),
+ ECPoint.Parse("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d", ECCurve.Secp256r1),
+ ECPoint.Parse("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e", ECCurve.Secp256r1),
+ ECPoint.Parse("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70", ECCurve.Secp256r1),
+ //Other Members
+ ECPoint.Parse("023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe", ECCurve.Secp256r1),
+ ECPoint.Parse("03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379", ECCurve.Secp256r1),
+ ECPoint.Parse("03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050", ECCurve.Secp256r1),
+ ECPoint.Parse("03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0", ECCurve.Secp256r1),
+ ECPoint.Parse("02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62", ECCurve.Secp256r1),
+ ECPoint.Parse("03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0", ECCurve.Secp256r1),
+ ECPoint.Parse("0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654", ECCurve.Secp256r1),
+ ECPoint.Parse("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639", ECCurve.Secp256r1),
+ ECPoint.Parse("0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30", ECCurve.Secp256r1),
+ ECPoint.Parse("03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde", ECCurve.Secp256r1),
+ ECPoint.Parse("02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad", ECCurve.Secp256r1),
+ ECPoint.Parse("0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d", ECCurve.Secp256r1),
+ ECPoint.Parse("03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc", ECCurve.Secp256r1),
+ ECPoint.Parse("02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a", ECCurve.Secp256r1)
+ },
+ ValidatorsCount = 7,
+ SeedList = new[]
+ {
+ "seed1.neo.org:10333",
+ "seed2.neo.org:10333",
+ "seed3.neo.org:10333",
+ "seed4.neo.org:10333",
+ "seed5.neo.org:10333"
+ },
+ MillisecondsPerBlock = ProtocolSettings.Default.MillisecondsPerBlock,
+ MaxTransactionsPerBlock = ProtocolSettings.Default.MaxTransactionsPerBlock,
+ MemoryPoolMaxTransactions = ProtocolSettings.Default.MemoryPoolMaxTransactions,
+ MaxTraceableBlocks = ProtocolSettings.Default.MaxTraceableBlocks,
+ InitialGasDistribution = ProtocolSettings.Default.InitialGasDistribution,
+ Hardforks = ProtocolSettings.Default.Hardforks
+ };
+ }
+}
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_Result.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_Result.cs
new file mode 100644
index 0000000000..aa6a8fe308
--- /dev/null
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_Result.cs
@@ -0,0 +1,26 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// UT_Result.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Neo.SmartContract;
+
+namespace Neo.Plugins.RpcServer.Tests;
+
+[TestClass]
+public class UT_Result
+{
+ [TestMethod]
+ public void TestNotNull_Or()
+ {
+ ContractState? contracts = null;
+ Assert.ThrowsException(() => contracts.NotNull_Or(RpcError.UnknownContract).ToJson());
+ }
+}
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.cs
index 803980eb8f..7bca550b83 100644
--- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.cs
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.cs
@@ -9,12 +9,53 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
+using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Neo.Ledger;
+using Neo.Persistence;
+using System;
+using System.Text;
namespace Neo.Plugins.RpcServer.Tests
{
[TestClass]
- public class UT_RpcServer
+ public partial class UT_RpcServer
{
+ private Mock _systemMock;
+ private SnapshotCache _snapshotCache;
+ private MemoryPool _memoryPool;
+ private RpcServerSettings _settings;
+ private RpcServer _rpcServer;
+
+ [TestInitialize]
+ public void TestSetup()
+ {
+ // Mock IReadOnlyStore
+ var mockStore = new Mock();
+
+ // Initialize SnapshotCache with the mock IReadOnlyStore
+ _snapshotCache = new SnapshotCache(mockStore.Object);
+
+ // Initialize NeoSystem
+ var neoSystem = new NeoSystem(TestProtocolSettings.Default, new TestBlockchain.StoreProvider());
+
+ // Initialize MemoryPool with the NeoSystem
+ _memoryPool = new MemoryPool(neoSystem);
+
+ // Set up the mock system with the correct constructor arguments
+ _systemMock = new Mock(_snapshotCache, _memoryPool);
+
+ _rpcServer = new RpcServer(_systemMock.Object, RpcServerSettings.Default);
+ }
+
+ [TestMethod]
+ public void TestCheckAuth_ValidCredentials_ReturnsTrue()
+ {
+ var context = new DefaultHttpContext();
+ context.Request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes("testuser:testpass"));
+ var result = _rpcServer.CheckAuth(context);
+ Assert.IsTrue(result);
+ }
}
}
diff --git a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
index 9e72fc7ec3..9a282759a9 100644
--- a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
+++ b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs
@@ -21,13 +21,23 @@ namespace Neo.UnitTests.Extensions
{
public static class NativeContractExtensions
{
- public static ContractState DeployContract(this DataCache snapshot, UInt160 sender, byte[] nefFile, byte[] manifest, long gas = 200_00000000)
+ ///
+ /// Deploy a contract to the blockchain.
+ ///
+ /// The snapshot used for deploying the contract.
+ /// The address of the contract deployer.
+ /// The file of the contract to be deployed.
+ /// The manifest of the contract to be deployed.
+ /// The gas fee to spend for deploying the contract in the unit of datoshi, 1 datoshi = 1e-8 GAS.
+ ///
+ ///
+ public static ContractState DeployContract(this DataCache snapshot, UInt160 sender, byte[] nefFile, byte[] manifest, long datoshi = 200_00000000)
{
var script = new ScriptBuilder();
script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest, null);
var engine = ApplicationEngine.Create(TriggerType.Application,
- sender != null ? new Transaction() { Signers = new Signer[] { new Signer() { Account = sender } }, Attributes = System.Array.Empty() } : null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: gas);
+ sender != null ? new Transaction() { Signers = new Signer[] { new Signer() { Account = sender } }, Attributes = System.Array.Empty() } : null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: datoshi);
engine.LoadScript(script.ToArray());
if (engine.Execute() != VMState.HALT)
diff --git a/tests/Neo.UnitTests/Ledger/UT_PoolItem.cs b/tests/Neo.UnitTests/Ledger/UT_PoolItem.cs
index 683291eda9..2b8e54b919 100644
--- a/tests/Neo.UnitTests/Ledger/UT_PoolItem.cs
+++ b/tests/Neo.UnitTests/Ledger/UT_PoolItem.cs
@@ -47,11 +47,11 @@ public void TestCleanup()
public void PoolItem_CompareTo_Fee()
{
int size1 = 51;
- int netFeeSatoshi1 = 1;
- var tx1 = GenerateTx(netFeeSatoshi1, size1);
+ int netFeeDatoshi1 = 1;
+ var tx1 = GenerateTx(netFeeDatoshi1, size1);
int size2 = 51;
- int netFeeSatoshi2 = 2;
- var tx2 = GenerateTx(netFeeSatoshi2, size2);
+ int netFeeDatoshi2 = 2;
+ var tx2 = GenerateTx(netFeeDatoshi2, size2);
PoolItem pitem1 = new PoolItem(tx1);
PoolItem pitem2 = new PoolItem(tx2);
@@ -67,10 +67,10 @@ public void PoolItem_CompareTo_Fee()
public void PoolItem_CompareTo_Hash()
{
int sizeFixed = 51;
- int netFeeSatoshiFixed = 1;
+ int netFeeDatoshiFixed = 1;
- var tx1 = GenerateTxWithFirstByteOfHashGreaterThanOrEqualTo(0x80, netFeeSatoshiFixed, sizeFixed);
- var tx2 = GenerateTxWithFirstByteOfHashLessThanOrEqualTo(0x79, netFeeSatoshiFixed, sizeFixed);
+ var tx1 = GenerateTxWithFirstByteOfHashGreaterThanOrEqualTo(0x80, netFeeDatoshiFixed, sizeFixed);
+ var tx2 = GenerateTxWithFirstByteOfHashLessThanOrEqualTo(0x79, netFeeDatoshiFixed, sizeFixed);
tx1.Attributes = new TransactionAttribute[] { new HighPriorityAttribute() };
@@ -83,8 +83,8 @@ public void PoolItem_CompareTo_Hash()
// Bulk test
for (int testRuns = 0; testRuns < 30; testRuns++)
{
- tx1 = GenerateTxWithFirstByteOfHashGreaterThanOrEqualTo(0x80, netFeeSatoshiFixed, sizeFixed);
- tx2 = GenerateTxWithFirstByteOfHashLessThanOrEqualTo(0x79, netFeeSatoshiFixed, sizeFixed);
+ tx1 = GenerateTxWithFirstByteOfHashGreaterThanOrEqualTo(0x80, netFeeDatoshiFixed, sizeFixed);
+ tx2 = GenerateTxWithFirstByteOfHashLessThanOrEqualTo(0x79, netFeeDatoshiFixed, sizeFixed);
pitem1 = new PoolItem(tx1);
pitem2 = new PoolItem(tx2);
@@ -103,8 +103,8 @@ public void PoolItem_CompareTo_Hash()
public void PoolItem_CompareTo_Equals()
{
int sizeFixed = 500;
- int netFeeSatoshiFixed = 10;
- var tx = GenerateTx(netFeeSatoshiFixed, sizeFixed, new byte[] { 0x13, 0x37 });
+ int netFeeDatoshiFixed = 10;
+ var tx = GenerateTx(netFeeDatoshiFixed, sizeFixed, new byte[] { 0x13, 0x37 });
PoolItem pitem1 = new PoolItem(tx);
PoolItem pitem2 = new PoolItem(tx);
diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
index 43755374d3..56d9a66bec 100644
--- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
+++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
@@ -187,7 +187,7 @@ public void FeeIsMultiSigContract()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
@@ -263,7 +263,7 @@ public void FeeIsSignatureContractDetailed()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// ------------------
@@ -368,7 +368,7 @@ public void FeeIsSignatureContract_TestScope_Global()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
@@ -448,7 +448,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
@@ -531,7 +531,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
@@ -661,7 +661,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
@@ -818,7 +818,7 @@ public void Transaction_Serialize_Deserialize_Simple()
"00" + // version
"04030201" + // nonce
"00e1f50500000000" + // system fee (1 GAS)
- "0100000000000000" + // network fee (1 satoshi)
+ "0100000000000000" + // network fee (1 datoshi)
"04030201" + // timelimit
"01000000000000000000000000000000000000000000" + // empty signer
"00" + // no attributes
@@ -1050,7 +1050,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.AreEqual(1, engine.ResultStack.Count);
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- verificationGas += engine.GasConsumed;
+ verificationGas += engine.FeeConsumed;
}
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
diff --git a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs
index 88d48ba548..b0f61791f6 100644
--- a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs
+++ b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs
@@ -11,8 +11,10 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Persistence;
+using Neo.SmartContract;
using System;
using System.Linq;
+using System.Text;
namespace Neo.UnitTests.Persistence
{
@@ -30,27 +32,42 @@ public void StoreTest()
{
using var store = new MemoryStore();
- store.Delete(new byte[] { 1 });
- Assert.AreEqual(null, store.TryGet(new byte[] { 1 }));
- store.Put(new byte[] { 1 }, new byte[] { 1, 2, 3 });
- CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, store.TryGet(new byte[] { 1 }));
+ store.Delete([1]);
+ Assert.AreEqual(null, store.TryGet([1]));
+ store.Put([1], [1, 2, 3]);
+ CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, store.TryGet([1]));
- store.Put(new byte[] { 2 }, new byte[] { 4, 5, 6 });
- CollectionAssert.AreEqual(new byte[] { 1 }, store.Seek(Array.Empty(), SeekDirection.Forward).Select(u => u.Key).First());
- CollectionAssert.AreEqual(new byte[] { 2 }, store.Seek(new byte[] { 2 }, SeekDirection.Backward).Select(u => u.Key).First());
- CollectionAssert.AreEqual(new byte[] { 1 }, store.Seek(new byte[] { 1 }, SeekDirection.Backward).Select(u => u.Key).First());
+ store.Put([2], [4, 5, 6]);
+ CollectionAssert.AreEqual(new byte[] { 1 }, store.Seek(Array.Empty()).Select(u => u.Key).First());
+ CollectionAssert.AreEqual(new byte[] { 2 }, store.Seek([2], SeekDirection.Backward).Select(u => u.Key).First());
+ CollectionAssert.AreEqual(new byte[] { 1 }, store.Seek([1], SeekDirection.Backward).Select(u => u.Key).First());
- store.Delete(new byte[] { 1 });
- store.Delete(new byte[] { 2 });
+ store.Delete([1]);
+ store.Delete([2]);
- store.Put(new byte[] { 0x00, 0x00, 0x00 }, new byte[] { 0x00 });
- store.Put(new byte[] { 0x00, 0x00, 0x01 }, new byte[] { 0x01 });
- store.Put(new byte[] { 0x00, 0x00, 0x02 }, new byte[] { 0x02 });
- store.Put(new byte[] { 0x00, 0x00, 0x03 }, new byte[] { 0x03 });
- store.Put(new byte[] { 0x00, 0x00, 0x04 }, new byte[] { 0x04 });
+ store.Put([0x00, 0x00, 0x00], [0x00]);
+ store.Put([0x00, 0x00, 0x01], [0x01]);
+ store.Put([0x00, 0x00, 0x02], [0x02]);
+ store.Put([0x00, 0x00, 0x03], [0x03]);
+ store.Put([0x00, 0x00, 0x04], [0x04]);
var entries = store.Seek(Array.Empty(), SeekDirection.Backward).ToArray();
- Assert.AreEqual(entries.Count(), 0);
+ Assert.AreEqual(entries.Length, 0);
}
+
+ [TestMethod]
+ public void NeoSystemStoreViewTest()
+ {
+ var neoSystem = new NeoSystem(TestProtocolSettings.Default, new MemoryStoreProvider());
+ Assert.IsNotNull(neoSystem.StoreView);
+ var store = neoSystem.StoreView;
+ var key = new StorageKey(Encoding.UTF8.GetBytes("testKey"));
+ var value = new StorageItem(Encoding.UTF8.GetBytes("testValue"));
+ store.Add(key, value);
+ store.Commit();
+ var result = store.TryGet(key);
+ Assert.AreEqual("testValue", Encoding.UTF8.GetString(result.Value.ToArray()));
+ }
+
}
}
diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
index 7639377fe1..0969e12776 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
@@ -12,6 +12,9 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.SmartContract;
+using Neo.SmartContract.Manifest;
+using Neo.UnitTests.Extensions;
+using Neo.VM;
using System;
using System.Collections.Immutable;
using System.Linq;
@@ -103,5 +106,103 @@ public void TestCheckingHardfork()
(setting[sortedHardforks[i]] > setting[sortedHardforks[i + 1]]).Should().Be(false);
}
}
+
+ [TestMethod]
+ public void TestSystem_Contract_Call_Permissions()
+ {
+ UInt160 scriptHash;
+ var snapshot = TestBlockchain.GetTestSnapshot();
+
+ // Setup: put a simple contract to the storage.
+ using (var script = new ScriptBuilder())
+ {
+ // Push True on stack and return.
+ script.EmitPush(true);
+ script.Emit(OpCode.RET);
+
+ // Mock contract and put it to the Managemant's storage.
+ scriptHash = script.ToArray().ToScriptHash();
+
+ snapshot.DeleteContract(scriptHash);
+ var contract = TestUtils.GetContract(script.ToArray(), TestUtils.CreateManifest("test", ContractParameterType.Any));
+ contract.Manifest.Abi.Methods = new[]
+ {
+ new ContractMethodDescriptor
+ {
+ Name = "disallowed",
+ Parameters = new ContractParameterDefinition[]{}
+ },
+ new ContractMethodDescriptor
+ {
+ Name = "test",
+ Parameters = new ContractParameterDefinition[]{}
+ }
+ };
+ snapshot.AddContract(scriptHash, contract);
+ }
+
+ // Disallowed method call.
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default))
+ using (var script = new ScriptBuilder())
+ {
+ // Build call script calling disallowed method.
+ script.EmitDynamicCall(scriptHash, "disallowed");
+
+ // Mock executing state to be a contract-based.
+ engine.LoadScript(script.ToArray());
+ engine.CurrentContext.GetState().Contract = new()
+ {
+ Manifest = new()
+ {
+ Abi = new() { },
+ Permissions = new ContractPermission[]
+ {
+ new ContractPermission
+ {
+ Contract = ContractPermissionDescriptor.Create(scriptHash),
+ Methods = WildcardContainer.Create(new string[]{"test"}) // allowed to call only "test" method of the target contract.
+ }
+ }
+ }
+ };
+ var currentScriptHash = engine.EntryScriptHash;
+
+ Assert.AreEqual(VMState.FAULT, engine.Execute());
+ Assert.IsTrue(engine.FaultException.ToString().Contains($"Cannot Call Method disallowed Of Contract {scriptHash.ToString()}"));
+ }
+
+ // Allowed method call.
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default))
+ using (var script = new ScriptBuilder())
+ {
+ // Build call script.
+ script.EmitDynamicCall(scriptHash, "test");
+
+ // Mock executing state to be a contract-based.
+ engine.LoadScript(script.ToArray());
+ engine.CurrentContext.GetState().Contract = new()
+ {
+ Manifest = new()
+ {
+ Abi = new() { },
+ Permissions = new ContractPermission[]
+ {
+ new ContractPermission
+ {
+ Contract = ContractPermissionDescriptor.Create(scriptHash),
+ Methods = WildcardContainer.Create(new string[]{"test"}) // allowed to call only "test" method of the target contract.
+ }
+ }
+ }
+ };
+ var currentScriptHash = engine.EntryScriptHash;
+
+ Assert.AreEqual(VMState.HALT, engine.Execute());
+ Assert.AreEqual(1, engine.ResultStack.Count);
+ Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(VM.Types.Boolean));
+ var res = (VM.Types.Boolean)engine.ResultStack.Pop();
+ Assert.IsTrue(res.GetBoolean());
+ }
+ }
}
}
diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
index a263779282..07ae320a0f 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
@@ -170,7 +170,7 @@ public void TestSignatureRedeemScriptFee()
{
engine.LoadScript(invocation.Concat(verification).ToArray(), configureState: p => p.CallFlags = CallFlags.None);
engine.Execute();
- engine.GasConsumed.Should().Be(fee);
+ engine.FeeConsumed.Should().Be(fee);
}
}
@@ -198,7 +198,7 @@ public void TestCreateMultiSigRedeemScriptFee()
{
engine.LoadScript(invocation.Concat(verification).ToArray(), configureState: p => p.CallFlags = CallFlags.None);
engine.Execute();
- engine.GasConsumed.Should().Be(fee);
+ engine.FeeConsumed.Should().Be(fee);
}
}
}
diff --git a/tests/Neo.UnitTests/SmartContract/UT_Helper.cs b/tests/Neo.UnitTests/SmartContract/UT_Helper.cs
index ffffc70728..e629a5908f 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_Helper.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_Helper.cs
@@ -133,7 +133,7 @@ public void TestSignatureContractCost()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- Assert.AreEqual(Neo.SmartContract.Helper.SignatureContractCost() * PolicyContract.DefaultExecFeeFactor, engine.GasConsumed);
+ Assert.AreEqual(Neo.SmartContract.Helper.SignatureContractCost() * PolicyContract.DefaultExecFeeFactor, engine.FeeConsumed);
}
[TestMethod]
@@ -153,7 +153,7 @@ public void TestMultiSignatureContractCost()
Assert.AreEqual(VMState.HALT, engine.Execute());
Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());
- Assert.AreEqual(Neo.SmartContract.Helper.MultiSignatureContractCost(1, 1) * PolicyContract.DefaultExecFeeFactor, engine.GasConsumed);
+ Assert.AreEqual(Neo.SmartContract.Helper.MultiSignatureContractCost(1, 1) * PolicyContract.DefaultExecFeeFactor, engine.FeeConsumed);
}
}
}
diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs
index a55db382df..581bf42751 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_InteropPrices.cs
@@ -74,9 +74,9 @@ public void ApplicationEngineRegularPut()
debugger.StepInto();
debugger.StepInto();
debugger.StepInto();
- var setupPrice = ae.GasConsumed;
+ var setupPrice = ae.FeeConsumed;
debugger.Execute();
- (ae.GasConsumed - setupPrice).Should().Be(ae.StoragePrice * value.Length + (1 << 15) * 30);
+ (ae.FeeConsumed - setupPrice).Should().Be(ae.StoragePrice * value.Length + (1 << 15) * 30);
}
///
@@ -105,9 +105,9 @@ public void ApplicationEngineReusedStorage_FullReuse()
debugger.StepInto();
debugger.StepInto();
debugger.StepInto();
- var setupPrice = applicationEngine.GasConsumed;
+ var setupPrice = applicationEngine.FeeConsumed;
debugger.Execute();
- (applicationEngine.GasConsumed - setupPrice).Should().Be(1 * applicationEngine.StoragePrice + (1 << 15) * 30);
+ (applicationEngine.FeeConsumed - setupPrice).Should().Be(1 * applicationEngine.StoragePrice + (1 << 15) * 30);
}
///
@@ -138,10 +138,10 @@ public void ApplicationEngineReusedStorage_PartialReuse()
debugger.StepInto();
debugger.StepInto();
debugger.StepInto();
- var setupPrice = ae.GasConsumed;
+ var setupPrice = ae.FeeConsumed;
debugger.StepInto();
debugger.StepInto();
- (ae.GasConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ae.StoragePrice + (1 << 15) * 30);
+ (ae.FeeConsumed - setupPrice).Should().Be((1 + (oldValue.Length / 4) + value.Length - oldValue.Length) * ae.StoragePrice + (1 << 15) * 30);
}
///
@@ -176,9 +176,9 @@ public void ApplicationEngineReusedStorage_PartialReuseTwice()
debugger.StepInto(); //push value
debugger.StepInto(); //push key
debugger.StepInto(); //syscall Storage.GetContext
- var setupPrice = ae.GasConsumed;
+ var setupPrice = ae.FeeConsumed;
debugger.StepInto(); //syscall Storage.Put
- (ae.GasConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ae.StoragePrice + (1 << 15) * 30); // = PUT basic fee
+ (ae.FeeConsumed - setupPrice).Should().Be((sItem.Value.Length / 4 + 1) * ae.StoragePrice + (1 << 15) * 30); // = PUT basic fee
}
private static byte[] CreateMultiplePutScript(byte[] key, byte[] value, int times = 2)
diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs
index 0e9916b7d5..51f26d22eb 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs
@@ -71,6 +71,14 @@ public void Runtime_GetNotifications_Test()
}
}
};
+ contract.Manifest.Permissions = new ContractPermission[]
+ {
+ new ContractPermission
+ {
+ Contract = ContractPermissionDescriptor.Create(scriptHash2),
+ Methods = WildcardContainer.Create(new string[]{"test"})
+ }
+ };
snapshot.AddContract(scriptHash2, contract);
}
@@ -133,6 +141,14 @@ public void Runtime_GetNotifications_Test()
Parameters = System.Array.Empty()
}
}
+ },
+ Permissions = new ContractPermission[]
+ {
+ new ContractPermission
+ {
+ Contract = ContractPermissionDescriptor.Create(scriptHash2),
+ Methods = WildcardContainer.Create(new string[]{"test"})
+ }
}
}
};
@@ -202,6 +218,14 @@ public void Runtime_GetNotifications_Test()
Parameters = System.Array.Empty()
}
}
+ },
+ Permissions = new ContractPermission[]
+ {
+ new ContractPermission
+ {
+ Contract = ContractPermissionDescriptor.Create(scriptHash2),
+ Methods = WildcardContainer.Create(new string[]{"test"})
+ }
}
}
};
@@ -642,7 +666,7 @@ public void TestContract_Call()
var args = new VM.Types.Array { 0, 1 };
var state = TestUtils.GetContract(method, args.Count);
- var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default);
engine.LoadScript(new byte[] { 0x01 });
engine.Snapshot.AddContract(state.Hash, state);
diff --git a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs
index fdaeb9106e..59afbbb760 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs
@@ -13,6 +13,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
namespace Neo.UnitTests.SmartContract
{
@@ -27,5 +29,37 @@ public void TestGetScriptContainer()
NotifyEventArgs args = new NotifyEventArgs(container, script_hash, "Test", null);
args.ScriptContainer.Should().Be(container);
}
+
+
+ [TestMethod]
+ public void TestIssue3300() // https://github.com/neo-project/neo/issues/3300
+ {
+ using var engine = ApplicationEngine.Create(TriggerType.Application, null, null, settings: TestProtocolSettings.Default, gas: 1100_00000000);
+ using (var script = new ScriptBuilder())
+ {
+ // Build call script calling disallowed method.
+ script.Emit(OpCode.NOP);
+ // Mock executing state to be a contract-based.
+ engine.LoadScript(script.ToArray());
+ }
+
+ var ns = new Array(engine.ReferenceCounter);
+ for (var i = 0; i < 500; i++)
+ {
+ ns.Add("");
+ };
+
+ var hash = UInt160.Parse("0x179ab5d297fd34ecd48643894242fc3527f42853");
+ engine.SendNotification(hash, "Test", ns);
+ // This should have being 0, but we have optimized the vm to not clean the reference counter
+ // unless it is necessary, so the reference counter will be 1000.
+ // Same reason why its 1504 instead of 504.
+ Assert.AreEqual(1000, engine.ReferenceCounter.Count);
+ // This will make a deepcopy for the notification, along with the 500 state items.
+ engine.GetNotifications(hash);
+ // With the fix of issue 3300, the reference counter calculates not only
+ // the notifaction items, but also the subitems of the notification state.
+ Assert.AreEqual(1504, engine.ReferenceCounter.Count);
+ }
}
}
diff --git a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs
index 0a98b5fd66..7791b8acef 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs
@@ -257,7 +257,7 @@ public void System_Runtime_GetInvocationCounter()
// Execute
- var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, ProtocolSettings.Default);
engine.LoadScript(script.ToArray());
Assert.AreEqual(VMState.HALT, engine.Execute());
diff --git a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs
index aff3561a75..71914c86f0 100644
--- a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs
+++ b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Contract = Neo.SmartContract.Contract;
@@ -302,6 +303,11 @@ public void TestImportCert()
X509Certificate2 cert = NewCertificate();
Assert.IsNotNull(cert);
Assert.AreEqual(true, cert.HasPrivateKey);
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ Assert.ThrowsException(() => uut.Import(cert));
+ return;
+ }
WalletAccount account = uut.Import(cert);
Assert.IsNotNull(account);
}