diff --git a/.devcontainer/devcontainer.dockerfile b/.devcontainer/devcontainer.dockerfile
index 3b16107e9e..158bc6132a 100644
--- a/.devcontainer/devcontainer.dockerfile
+++ b/.devcontainer/devcontainer.dockerfile
@@ -1,3 +1,3 @@
-FROM mcr.microsoft.com/devcontainers/dotnet:8.0-jammy
+FROM mcr.microsoft.com/devcontainers/dotnet:9.0-jammy
# Install the libleveldb-dev package
RUN apt-get update && apt-get install -y libleveldb-dev
diff --git a/.editorconfig b/.editorconfig
index ccbd29fd03..af8e3350e9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -55,6 +55,11 @@ indent_size = 2
# Dotnet code style settings:
[*.{cs,vb}]
+# Use block-scoped namespace
+csharp_style_namespace_declarations = block_scoped:error
+dotnet_diagnostic.IDE0160.severity = error
+dotnet_diagnostic.IDE0161.severity = error
+
# Member can be made 'readonly'
csharp_style_prefer_readonly_struct_member = true
dotnet_diagnostic.IDE0251.severity = warning
diff --git a/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md
index 9b98d24f99..ddc181fabb 100644
--- a/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md
@@ -2,7 +2,7 @@
name: Feature or enhancement request
about: Suggest an idea for Neo
title: ''
-labels: discussion
+labels: Discussion
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/questions.md b/.github/ISSUE_TEMPLATE/questions.md
index 4d97925f89..4945492ae3 100644
--- a/.github/ISSUE_TEMPLATE/questions.md
+++ b/.github/ISSUE_TEMPLATE/questions.md
@@ -2,7 +2,7 @@
name: Questions
about: Questions about Neo Platform
title: ''
-labels: question
+labels: Question
assignees: ''
---
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 3d8e7d0d6c..4eb8ecb034 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -5,7 +5,7 @@ on:
types: [published]
env:
- DOTNET_VERSION: 8.0.x
+ DOTNET_VERSION: 9.0.x
DIST_DIR: ./dist
jobs:
@@ -29,7 +29,7 @@ jobs:
- name: Build (neo-cli)
run: |
dotnet publish ./src/Neo.CLI \
- --framework net8.0 \
+ --framework net9.0 \
--configuration Release \
--runtime linux-x64 \
--self-contained true \
@@ -49,7 +49,7 @@ jobs:
- name: Build (LevelDbStore)
run: |
dotnet build ./src/Plugins/LevelDBStore \
- --framework net8.0 \
+ --framework net9.0 \
--configuration Release \
--output ${{ env.DIST_DIR }}/Plugins/LevelDBStore \
--verbosity normal \
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 22cf4d08df..fd290a9111 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -6,7 +6,7 @@ on:
pull_request:
env:
- DOTNET_VERSION: 8.0.x
+ DOTNET_VERSION: 9.0.x
jobs:
@@ -63,9 +63,17 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
-
- - name: Test
- if: matrix.os != 'ubuntu-latest'
+
+ - name: Test (MacOS)
+ if: matrix.os == 'macos-latest'
+ run: |
+ brew install leveldb
+ dotnet build
+ cp -vp /opt/homebrew/Cellar/leveldb/1.23_1/lib/libleveldb.dylib ./tests/Neo.Plugins.Storage.Tests/bin/Debug/net9.0/
+ dotnet test --blame-hang --blame-crash --no-build
+
+ - name: Test (windows)
+ if: matrix.os == 'windows-latest'
run: |
dotnet sln neo.sln remove ./tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj
dotnet build
diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml
index 3fa6cc4f5e..cc0beff7df 100644
--- a/.github/workflows/nuget.yml
+++ b/.github/workflows/nuget.yml
@@ -7,7 +7,7 @@ on:
# Define environment variables
env:
- DOTNET_VERSION: 8.0.x
+ DOTNET_VERSION: 9.0.x
CONFIGURATION: Release
jobs:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bcfddc1185..b1d0107825 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -7,7 +7,7 @@ on:
# Define environment variables
env:
- DOTNET_VERSION: 8.0.x
+ DOTNET_VERSION: 9.0.x
CONFIGURATION: Release
DIST_PATH: /tmp/dist
OUTPUT_PATH: /tmp/out
@@ -106,7 +106,7 @@ jobs:
run: |
dotnet publish ./src/Neo.CLI \
--version-suffix ${{ matrix.runtime }} \
- --framework net8.0 \
+ --framework net9.0 \
--configuration ${{ env.CONFIGURATION }} \
--runtime ${{ matrix.runtime }} \
--self-contained true \
@@ -128,7 +128,7 @@ jobs:
run: |
dotnet build ./src/Plugins/LevelDBStore \
--version-suffix ${{ matrix.runtime }} \
- --framework net8.0 \
+ --framework net9.0 \
--configuration ${{ env.CONFIGURATION }} \
--output ${{ env.OUTPUT_PATH }}/${{ matrix.runtime }}/Plugins/LevelDBStore \
--verbosity normal \
diff --git a/.gitignore b/.gitignore
index 45ccb8c40a..16342efe06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -257,6 +257,8 @@ paket-files/
PublishProfiles
/.vscode
launchSettings.json
+/coverages
+**/.DS_Store
# Benchmarks
-**/BenchmarkDotNet.Artifacts/
\ No newline at end of file
+**/BenchmarkDotNet.Artifacts/
diff --git a/README.md b/README.md
index cc1c9b384a..e7f4e66eea 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
A modern distributed network for the Smart Economy.
- Documentation »
+ Documentation »
Neo
@@ -106,7 +106,7 @@
## Overview
This repository contain main classes of the
[Neo](https://neo.org) blockchain.
-Visit the [tutorials](https://developers.neo.org) to get started.
+Visit the [tutorials](https://docs.neo.org) to get started.
## Project structure
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs b/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs
index a63542bace..ce2fd99a83 100644
--- a/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs
@@ -16,41 +16,42 @@
using System.IO.Hashing;
using System.Text;
-namespace Neo.Benchmark;
-
-public class Benchmarks_Hash
+namespace Neo.Benchmark
{
- // 256 KiB
- static readonly byte[] data = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat("Hello, World!^_^", 16 * 1024)));
-
- static readonly byte[] hash = "9182abedfbb9b18d81a05d8bcb45489e7daa2858".HexToBytes();
-
- [Benchmark]
- public void RIPEMD160_ComputeHash()
- {
- using var ripemd160 = new RIPEMD160Managed();
- var result = ripemd160.ComputeHash(data);
- Debug.Assert(result.SequenceEqual(hash));
- }
-
- [Benchmark]
- public void XxHash32_HashToUInt32()
- {
- var result = XxHash32.HashToUInt32(data);
- Debug.Assert(result == 682967318u);
- }
-
- [Benchmark]
- public void XxHash3_HashToUInt64()
- {
- var result = (uint)XxHash3.HashToUInt64(data);
- Debug.Assert(result == 1389469485u);
- }
-
- [Benchmark]
- public void Murmur32_HashToUInt32()
+ public class Benchmarks_Hash
{
- var result = data.Murmur32(0);
- Debug.Assert(result == 3731881930u);
+ // 256 KiB
+ static readonly byte[] data = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat("Hello, World!^_^", 16 * 1024)));
+
+ static readonly byte[] hash = "9182abedfbb9b18d81a05d8bcb45489e7daa2858".HexToBytes();
+
+ [Benchmark]
+ public void RIPEMD160_ComputeHash()
+ {
+ using var ripemd160 = new RIPEMD160Managed();
+ var result = ripemd160.ComputeHash(data);
+ Debug.Assert(result.SequenceEqual(hash));
+ }
+
+ [Benchmark]
+ public void XxHash32_HashToUInt32()
+ {
+ var result = XxHash32.HashToUInt32(data);
+ Debug.Assert(result == 682967318u);
+ }
+
+ [Benchmark]
+ public void XxHash3_HashToUInt64()
+ {
+ var result = (uint)XxHash3.HashToUInt64(data);
+ Debug.Assert(result == 1389469485u);
+ }
+
+ [Benchmark]
+ public void Murmur32_HashToUInt32()
+ {
+ var result = data.Murmur32(0);
+ Debug.Assert(result == 3731881930u);
+ }
}
}
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs
index f073c543a9..00fbf8d1f0 100644
--- a/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs
@@ -15,64 +15,65 @@
using Neo.VM;
using System.Diagnostics;
-namespace Neo.Benchmark;
-
-public class Benchmarks_PoCs
+namespace Neo.Benchmark
{
- private static readonly ProtocolSettings protocol = ProtocolSettings.Load("config.json");
- private static readonly NeoSystem system = new(protocol, (string)null);
-
- [Benchmark]
- public void NeoIssue2725()
+ public class Benchmarks_PoCs
{
- // https://github.com/neo-project/neo/issues/2725
- // L00: INITSSLOT 1
- // L01: NEWARRAY0
- // L02: PUSHDATA1 6161616161 //"aaaaa"
- // L03: PUSHINT16 500
- // L04: STSFLD0
- // L05: OVER
- // L06: OVER
- // L07: SYSCALL 95016f61 //System.Runtime.Notify
- // L08: LDSFLD0
- // L09: DEC
- // L10: DUP
- // L11: STSFLD0
- // L12: JMPIF L05
- // L13: CLEAR
- // L14: SYSCALL dbfea874 //System.Runtime.GetExecutingScriptHash
- // L15: PUSHINT16 8000
- // L16: STSFLD0
- // L17: DUP
- // L18: SYSCALL 274335f1 //System.Runtime.GetNotifications
- // L19: DROP
- // L20: LDSFLD0
- // L21: DEC
- // L22: DUP
- // L23: STSFLD0
- // L24: JMPIF L17
- Run(nameof(NeoIssue2725), "VgHCDAVhYWFhYQH0AWBLS0GVAW9hWJ1KYCT1SUHb/qh0AUAfYEpBJ0M18UVYnUpgJPU=");
- }
+ private static readonly ProtocolSettings protocol = ProtocolSettings.Load("config.json");
+ private static readonly NeoSystem system = new(protocol, (string)null);
- private static void Run(string name, string poc)
- {
- Random random = new();
- Transaction tx = new()
+ [Benchmark]
+ public void NeoIssue2725()
+ {
+ // https://github.com/neo-project/neo/issues/2725
+ // L00: INITSSLOT 1
+ // L01: NEWARRAY0
+ // L02: PUSHDATA1 6161616161 //"aaaaa"
+ // L03: PUSHINT16 500
+ // L04: STSFLD0
+ // L05: OVER
+ // L06: OVER
+ // L07: SYSCALL 95016f61 //System.Runtime.Notify
+ // L08: LDSFLD0
+ // L09: DEC
+ // L10: DUP
+ // L11: STSFLD0
+ // L12: JMPIF L05
+ // L13: CLEAR
+ // L14: SYSCALL dbfea874 //System.Runtime.GetExecutingScriptHash
+ // L15: PUSHINT16 8000
+ // L16: STSFLD0
+ // L17: DUP
+ // L18: SYSCALL 274335f1 //System.Runtime.GetNotifications
+ // L19: DROP
+ // L20: LDSFLD0
+ // L21: DEC
+ // L22: DUP
+ // L23: STSFLD0
+ // L24: JMPIF L17
+ Run(nameof(NeoIssue2725), "VgHCDAVhYWFhYQH0AWBLS0GVAW9hWJ1KYCT1SUHb/qh0AUAfYEpBJ0M18UVYnUpgJPU=");
+ }
+
+ private static void Run(string name, string poc)
{
- Version = 0,
- Nonce = (uint)random.Next(),
- SystemFee = 20_00000000,
- NetworkFee = 1_00000000,
- ValidUntilBlock = ProtocolSettings.Default.MaxTraceableBlocks,
- Signers = Array.Empty(),
- Attributes = Array.Empty(),
- Script = Convert.FromBase64String(poc),
- Witnesses = Array.Empty()
- };
- using var snapshot = system.GetSnapshotCache();
- using var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, system.GenesisBlock, protocol, tx.SystemFee);
- engine.LoadScript(tx.Script);
- engine.Execute();
- Debug.Assert(engine.State == VMState.FAULT);
+ Random random = new();
+ Transaction tx = new()
+ {
+ Version = 0,
+ Nonce = (uint)random.Next(),
+ SystemFee = 20_00000000,
+ NetworkFee = 1_00000000,
+ ValidUntilBlock = ProtocolSettings.Default.MaxTraceableBlocks,
+ Signers = Array.Empty(),
+ Attributes = Array.Empty(),
+ Script = Convert.FromBase64String(poc),
+ Witnesses = Array.Empty()
+ };
+ using var snapshot = system.GetSnapshotCache();
+ using var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, system.GenesisBlock, protocol, tx.SystemFee);
+ engine.LoadScript(tx.Script);
+ engine.Execute();
+ Debug.Assert(engine.State == VMState.FAULT);
+ }
}
}
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs b/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs
index 37fa701ff9..3f46539d75 100644
--- a/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs
@@ -11,146 +11,147 @@
using BenchmarkDotNet.Attributes;
-namespace Neo.Benchmark;
-
-public class Benchmarks_UInt160
+namespace Neo.Benchmark
{
- static readonly OldUInt160 s_oldUInt160 = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
- static readonly UInt160 s_newUInt160 = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
-
- [Benchmark]
- public void TestOldUInt160Gernerator1()
- {
- _ = new OldUInt160();
- }
-
- [Benchmark]
- public void TestOldUInt160Gernerator2()
- {
- _ = new OldUInt160(new byte[20]);
- }
-
- [Benchmark]
- public void TestOldUInt160CompareTo()
- {
- OldUInt160.Zero.CompareTo(OldUInt160.Zero);
- OldUInt160.Zero.CompareTo(s_oldUInt160);
- s_oldUInt160.CompareTo(OldUInt160.Zero);
- }
-
- [Benchmark]
- public void TestOldUInt160Equals()
- {
- OldUInt160.Zero.Equals(OldUInt160.Zero);
- OldUInt160.Zero.Equals(s_oldUInt160);
- s_oldUInt160.Equals(null);
- }
-
- [Benchmark]
- public void TestOldUInt160Parse()
- {
- _ = OldUInt160.Parse("0x0000000000000000000000000000000000000000");
- _ = OldUInt160.Parse("0000000000000000000000000000000000000000");
- }
-
- [Benchmark]
- public void TestOldUInt160TryParse()
- {
- OldUInt160.TryParse(null, out _);
- OldUInt160.TryParse("0x0000000000000000000000000000000000000000", out var temp);
- OldUInt160.TryParse("0x1230000000000000000000000000000000000000", out temp);
- OldUInt160.TryParse("000000000000000000000000000000000000000", out _);
- }
-
- [Benchmark]
- public void TestOldUInt160OperatorLarger()
- {
- _ = s_oldUInt160 > OldUInt160.Zero;
- }
-
- [Benchmark]
- public void TestOldUInt160OperatorLargerAndEqual()
- {
- _ = s_oldUInt160 >= OldUInt160.Zero;
- }
-
- [Benchmark]
- public void TestOldUInt160OperatorSmaller()
- {
- _ = s_oldUInt160 < OldUInt160.Zero;
- }
-
- [Benchmark]
- public void TestOldUInt160OperatorSmallerAndEqual()
- {
- _ = s_oldUInt160 <= OldUInt160.Zero;
- }
-
- [Benchmark]
- public void TestGernerator1()
- {
- _ = new UInt160();
- }
-
- [Benchmark]
- public void TestGernerator2()
- {
- _ = new UInt160(new byte[20]);
- }
-
- [Benchmark]
- public void TestCompareTo()
- {
- UInt160.Zero.CompareTo(UInt160.Zero);
- UInt160.Zero.CompareTo(s_newUInt160);
- s_newUInt160.CompareTo(UInt160.Zero);
- }
-
- [Benchmark]
- public void TestEquals()
- {
- UInt160.Zero.Equals(UInt160.Zero);
- UInt160.Zero.Equals(s_newUInt160);
- s_newUInt160.Equals(null);
- }
-
- [Benchmark]
- public void TestParse()
- {
- _ = UInt160.Parse("0x0000000000000000000000000000000000000000");
- _ = UInt160.Parse("0000000000000000000000000000000000000000");
- }
-
- [Benchmark]
- public void TestTryParse()
- {
- UInt160.TryParse(null, out _);
- UInt160.TryParse("0x0000000000000000000000000000000000000000", out var temp);
- UInt160.TryParse("0x1230000000000000000000000000000000000000", out temp);
- UInt160.TryParse("000000000000000000000000000000000000000", out _);
- }
-
- [Benchmark]
- public void TestOperatorLarger()
- {
- _ = s_newUInt160 > UInt160.Zero;
- }
-
- [Benchmark]
- public void TestOperatorLargerAndEqual()
- {
- _ = s_newUInt160 >= UInt160.Zero;
- }
-
- [Benchmark]
- public void TestOperatorSmaller()
- {
- _ = s_newUInt160 < UInt160.Zero;
- }
-
- [Benchmark]
- public void TestOperatorSmallerAndEqual()
- {
- _ = s_newUInt160 <= UInt160.Zero;
+ public class Benchmarks_UInt160
+ {
+ static readonly OldUInt160 s_oldUInt160 = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
+ static readonly UInt160 s_newUInt160 = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
+
+ [Benchmark]
+ public void TestOldUInt160Gernerator1()
+ {
+ _ = new OldUInt160();
+ }
+
+ [Benchmark]
+ public void TestOldUInt160Gernerator2()
+ {
+ _ = new OldUInt160(new byte[20]);
+ }
+
+ [Benchmark]
+ public void TestOldUInt160CompareTo()
+ {
+ OldUInt160.Zero.CompareTo(OldUInt160.Zero);
+ OldUInt160.Zero.CompareTo(s_oldUInt160);
+ s_oldUInt160.CompareTo(OldUInt160.Zero);
+ }
+
+ [Benchmark]
+ public void TestOldUInt160Equals()
+ {
+ OldUInt160.Zero.Equals(OldUInt160.Zero);
+ OldUInt160.Zero.Equals(s_oldUInt160);
+ s_oldUInt160.Equals(null);
+ }
+
+ [Benchmark]
+ public void TestOldUInt160Parse()
+ {
+ _ = OldUInt160.Parse("0x0000000000000000000000000000000000000000");
+ _ = OldUInt160.Parse("0000000000000000000000000000000000000000");
+ }
+
+ [Benchmark]
+ public void TestOldUInt160TryParse()
+ {
+ OldUInt160.TryParse(null, out _);
+ OldUInt160.TryParse("0x0000000000000000000000000000000000000000", out var temp);
+ OldUInt160.TryParse("0x1230000000000000000000000000000000000000", out temp);
+ OldUInt160.TryParse("000000000000000000000000000000000000000", out _);
+ }
+
+ [Benchmark]
+ public void TestOldUInt160OperatorLarger()
+ {
+ _ = s_oldUInt160 > OldUInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOldUInt160OperatorLargerAndEqual()
+ {
+ _ = s_oldUInt160 >= OldUInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOldUInt160OperatorSmaller()
+ {
+ _ = s_oldUInt160 < OldUInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOldUInt160OperatorSmallerAndEqual()
+ {
+ _ = s_oldUInt160 <= OldUInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestGernerator1()
+ {
+ _ = new UInt160();
+ }
+
+ [Benchmark]
+ public void TestGernerator2()
+ {
+ _ = new UInt160(new byte[20]);
+ }
+
+ [Benchmark]
+ public void TestCompareTo()
+ {
+ UInt160.Zero.CompareTo(UInt160.Zero);
+ UInt160.Zero.CompareTo(s_newUInt160);
+ s_newUInt160.CompareTo(UInt160.Zero);
+ }
+
+ [Benchmark]
+ public void TestEquals()
+ {
+ UInt160.Zero.Equals(UInt160.Zero);
+ UInt160.Zero.Equals(s_newUInt160);
+ s_newUInt160.Equals(null);
+ }
+
+ [Benchmark]
+ public void TestParse()
+ {
+ _ = UInt160.Parse("0x0000000000000000000000000000000000000000");
+ _ = UInt160.Parse("0000000000000000000000000000000000000000");
+ }
+
+ [Benchmark]
+ public void TestTryParse()
+ {
+ UInt160.TryParse(null, out _);
+ UInt160.TryParse("0x0000000000000000000000000000000000000000", out var temp);
+ UInt160.TryParse("0x1230000000000000000000000000000000000000", out temp);
+ UInt160.TryParse("000000000000000000000000000000000000000", out _);
+ }
+
+ [Benchmark]
+ public void TestOperatorLarger()
+ {
+ _ = s_newUInt160 > UInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOperatorLargerAndEqual()
+ {
+ _ = s_newUInt160 >= UInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOperatorSmaller()
+ {
+ _ = s_newUInt160 < UInt160.Zero;
+ }
+
+ [Benchmark]
+ public void TestOperatorSmallerAndEqual()
+ {
+ _ = s_newUInt160 <= UInt160.Zero;
+ }
}
}
diff --git a/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj
index 6a4bd93264..4d5a494b00 100644
--- a/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj
+++ b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj
@@ -2,16 +2,16 @@
Exe
- net8.0
+ net9.0
Neo
enable
true
-
+
-
+
diff --git a/benchmarks/Neo.Benchmarks/Program.cs b/benchmarks/Neo.Benchmarks/Program.cs
index a64a1ca981..0bee186889 100644
--- a/benchmarks/Neo.Benchmarks/Program.cs
+++ b/benchmarks/Neo.Benchmarks/Program.cs
@@ -11,7 +11,9 @@
using BenchmarkDotNet.Running;
using Neo.Benchmark;
+using Neo.SmartContract.Benchmark;
// BenchmarkRunner.Run();
BenchmarkRunner.Run();
BenchmarkRunner.Run();
+BenchmarkRunner.Run();
diff --git a/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs b/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs
new file mode 100644
index 0000000000..5129a1dfaf
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs
@@ -0,0 +1,75 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// Benchmarks.StorageKey.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 BenchmarkDotNet.Attributes;
+using System.Text;
+
+namespace Neo.SmartContract.Benchmark
+{
+ public class Benchmarks_StorageKey
+ {
+ // for avoiding overhead of encoding
+ private static readonly byte[] testBytes = Encoding.ASCII.GetBytes("StorageKey");
+
+ private const int prefixSize = sizeof(int) + sizeof(byte);
+
+ [Benchmark]
+ public void KeyBuilder_AddInt()
+ {
+ var key = new KeyBuilder(1, 0)
+ .AddBigEndian(1)
+ .AddBigEndian(2)
+ .AddBigEndian(3);
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + 3 * sizeof(int))
+ throw new InvalidOperationException();
+ }
+
+ [Benchmark]
+ public void KeyBuilder_AddIntWithoutPrealloc()
+ {
+ var key = new KeyBuilder(1, 0, 0)
+ .AddBigEndian(1)
+ .AddBigEndian(2)
+ .AddBigEndian(3);
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + 3 * sizeof(int))
+ throw new InvalidOperationException();
+ }
+
+ [Benchmark]
+ public void KeyBuilder_AddBytes()
+ {
+ var key = new KeyBuilder(1, 0)
+ .Add(testBytes)
+ .Add(testBytes)
+ .Add(testBytes);
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + 3 * testBytes.Length)
+ throw new InvalidOperationException();
+ }
+
+ [Benchmark]
+ public void KeyBuilder_AddUInt160()
+ {
+ Span value = stackalloc byte[UInt160.Length];
+ var key = new KeyBuilder(1, 0)
+ .Add(new UInt160(value));
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + UInt160.Length)
+ throw new InvalidOperationException();
+ }
+ }
+}
diff --git a/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj b/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj
index d87bccaee5..5f7211e49a 100644
--- a/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj
+++ b/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj
@@ -2,16 +2,16 @@
Exe
- net8.0
+ net9.0
Neo.Extensions
enable
enable
-
+
-
+
diff --git a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Helper.cs b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Helper.cs
index f5ea579e6f..fb24fe7fa8 100644
--- a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Helper.cs
+++ b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Helper.cs
@@ -11,60 +11,61 @@
using System.Buffers.Binary;
-namespace Neo.VM.Benchmark;
-
-public static class Helper
+namespace Neo.VM.Benchmark
{
- public static void RebuildOffsets(this IReadOnlyList instructions)
+ public static class Helper
{
- var offset = 0;
- foreach (var instruction in instructions)
+ public static void RebuildOffsets(this IReadOnlyList instructions)
{
- instruction._offset = offset;
- offset += instruction.Size;
+ var offset = 0;
+ foreach (var instruction in instructions)
+ {
+ instruction._offset = offset;
+ offset += instruction.Size;
+ }
}
- }
- public static void RebuildOperands(this IReadOnlyList instructions)
- {
- foreach (var instruction in instructions)
+ public static void RebuildOperands(this IReadOnlyList instructions)
{
- if (instruction._target is null) continue;
- bool isLong;
- if (instruction._opCode >= VM.OpCode.JMP && instruction._opCode <= VM.OpCode.CALL_L)
- isLong = (instruction._opCode - VM.OpCode.JMP) % 2 != 0;
- else
- isLong = instruction._opCode == VM.OpCode.PUSHA || instruction._opCode == VM.OpCode.CALLA || instruction._opCode == VM.OpCode.TRY_L || instruction._opCode == VM.OpCode.ENDTRY_L;
- if (instruction._opCode == VM.OpCode.TRY || instruction._opCode == VM.OpCode.TRY_L)
+ foreach (var instruction in instructions)
{
- var offset1 = (instruction._target._instruction?._offset - instruction._offset) ?? 0;
- var offset2 = (instruction._target2!._instruction?._offset - instruction._offset) ?? 0;
- if (isLong)
- {
- instruction._operand = new byte[sizeof(int) + sizeof(int)];
- BinaryPrimitives.WriteInt32LittleEndian(instruction._operand, offset1);
- BinaryPrimitives.WriteInt32LittleEndian(instruction._operand.AsSpan(sizeof(int)), offset2);
- }
+ if (instruction._target is null) continue;
+ bool isLong;
+ if (instruction._opCode >= VM.OpCode.JMP && instruction._opCode <= VM.OpCode.CALL_L)
+ isLong = (instruction._opCode - VM.OpCode.JMP) % 2 != 0;
else
+ isLong = instruction._opCode == VM.OpCode.PUSHA || instruction._opCode == VM.OpCode.CALLA || instruction._opCode == VM.OpCode.TRY_L || instruction._opCode == VM.OpCode.ENDTRY_L;
+ if (instruction._opCode == VM.OpCode.TRY || instruction._opCode == VM.OpCode.TRY_L)
{
- instruction._operand = new byte[sizeof(sbyte) + sizeof(sbyte)];
- var sbyte1 = checked((sbyte)offset1);
- var sbyte2 = checked((sbyte)offset2);
- instruction._operand[0] = unchecked((byte)sbyte1);
- instruction._operand[1] = unchecked((byte)sbyte2);
- }
- }
- else
- {
- int offset = instruction._target._instruction!._offset - instruction._offset;
- if (isLong)
- {
- instruction._operand = BitConverter.GetBytes(offset);
+ var offset1 = (instruction._target._instruction?._offset - instruction._offset) ?? 0;
+ var offset2 = (instruction._target2!._instruction?._offset - instruction._offset) ?? 0;
+ if (isLong)
+ {
+ instruction._operand = new byte[sizeof(int) + sizeof(int)];
+ BinaryPrimitives.WriteInt32LittleEndian(instruction._operand, offset1);
+ BinaryPrimitives.WriteInt32LittleEndian(instruction._operand.AsSpan(sizeof(int)), offset2);
+ }
+ else
+ {
+ instruction._operand = new byte[sizeof(sbyte) + sizeof(sbyte)];
+ var sbyte1 = checked((sbyte)offset1);
+ var sbyte2 = checked((sbyte)offset2);
+ instruction._operand[0] = unchecked((byte)sbyte1);
+ instruction._operand[1] = unchecked((byte)sbyte2);
+ }
}
else
{
- var sbyte1 = checked((sbyte)offset);
- instruction._operand = [unchecked((byte)sbyte1)];
+ int offset = instruction._target._instruction!._offset - instruction._offset;
+ if (isLong)
+ {
+ instruction._operand = BitConverter.GetBytes(offset);
+ }
+ else
+ {
+ var sbyte1 = checked((sbyte)offset);
+ instruction._operand = [unchecked((byte)sbyte1)];
+ }
}
}
}
diff --git a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Instruction.cs b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Instruction.cs
index 5a30aeec10..54a0c3ee98 100644
--- a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Instruction.cs
+++ b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/Instruction.cs
@@ -13,46 +13,47 @@
using System.Diagnostics;
using System.Reflection;
-namespace Neo.VM.Benchmark;
-
-[DebuggerDisplay("{_opCode}")]
-public class Instruction
+namespace Neo.VM.Benchmark
{
- private static readonly int[] s_operandSizePrefixTable = new int[256];
- private static readonly int[] s_operandSizeTable = new int[256];
+ [DebuggerDisplay("{_opCode}")]
+ public class Instruction
+ {
+ private static readonly int[] s_operandSizePrefixTable = new int[256];
+ private static readonly int[] s_operandSizeTable = new int[256];
- public VM.OpCode _opCode;
- public byte[]? _operand;
- public JumpTarget? _target;
- public JumpTarget? _target2;
- public int _offset;
+ public VM.OpCode _opCode;
+ public byte[]? _operand;
+ public JumpTarget? _target;
+ public JumpTarget? _target2;
+ public int _offset;
- public int Size
- {
- get
+ public int Size
{
- int prefixSize = s_operandSizePrefixTable[(int)_opCode];
- return prefixSize > 0
- ? sizeof(VM.OpCode) + _operand!.Length
- : sizeof(VM.OpCode) + s_operandSizeTable[(int)_opCode];
+ get
+ {
+ int prefixSize = s_operandSizePrefixTable[(int)_opCode];
+ return prefixSize > 0
+ ? sizeof(VM.OpCode) + _operand!.Length
+ : sizeof(VM.OpCode) + s_operandSizeTable[(int)_opCode];
+ }
}
- }
- static Instruction()
- {
- foreach (var field in typeof(VM.OpCode).GetFields(BindingFlags.Public | BindingFlags.Static))
+ static Instruction()
{
- var attribute = field.GetCustomAttribute();
- if (attribute is null) continue;
- var index = (int)(VM.OpCode)field.GetValue(null)!;
- s_operandSizePrefixTable[index] = attribute.SizePrefix;
- s_operandSizeTable[index] = attribute.Size;
+ foreach (var field in typeof(VM.OpCode).GetFields(BindingFlags.Public | BindingFlags.Static))
+ {
+ var attribute = field.GetCustomAttribute();
+ if (attribute is null) continue;
+ var index = (int)(VM.OpCode)field.GetValue(null)!;
+ s_operandSizePrefixTable[index] = attribute.SizePrefix;
+ s_operandSizeTable[index] = attribute.Size;
+ }
}
- }
- public byte[] ToArray()
- {
- if (_operand is null) return [(byte)_opCode];
- return _operand.Prepend((byte)_opCode).ToArray();
+ public byte[] ToArray()
+ {
+ if (_operand is null) return [(byte)_opCode];
+ return _operand.Prepend((byte)_opCode).ToArray();
+ }
}
}
diff --git a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/InstructionBuilder.cs b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/InstructionBuilder.cs
index 21d1b77de2..8fb3469bce 100644
--- a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/InstructionBuilder.cs
+++ b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/InstructionBuilder.cs
@@ -12,231 +12,232 @@
using System.Buffers.Binary;
using System.Numerics;
-namespace Neo.VM.Benchmark;
-
-internal class InstructionBuilder
+namespace Neo.VM.Benchmark
{
- internal readonly List _instructions = new();
+ internal class InstructionBuilder
+ {
+ internal readonly List _instructions = new();
- public InstructionBuilder() { }
+ public InstructionBuilder() { }
- internal Instruction AddInstruction(Instruction instruction)
- {
- _instructions.Add(instruction);
- return instruction;
- }
+ internal Instruction AddInstruction(Instruction instruction)
+ {
+ _instructions.Add(instruction);
+ return instruction;
+ }
- internal Instruction AddInstruction(VM.OpCode opcode)
- {
- return AddInstruction(new Instruction
+ internal Instruction AddInstruction(VM.OpCode opcode)
{
- _opCode = opcode
- });
- }
+ return AddInstruction(new Instruction
+ {
+ _opCode = opcode
+ });
+ }
- internal Instruction Jump(VM.OpCode opcode, JumpTarget target)
- {
- return AddInstruction(new Instruction
+ internal Instruction Jump(VM.OpCode opcode, JumpTarget target)
{
- _opCode = opcode,
- _target = target
- });
- }
+ return AddInstruction(new Instruction
+ {
+ _opCode = opcode,
+ _target = target
+ });
+ }
- internal void Push(bool value)
- {
- AddInstruction(value ? VM.OpCode.PUSHT : VM.OpCode.PUSHF);
- }
+ internal void Push(bool value)
+ {
+ AddInstruction(value ? VM.OpCode.PUSHT : VM.OpCode.PUSHF);
+ }
- internal Instruction Ret() => AddInstruction(VM.OpCode.RET);
+ internal Instruction Ret() => AddInstruction(VM.OpCode.RET);
- internal Instruction Push(BigInteger number)
- {
- if (number >= -1 && number <= 16) return AddInstruction(number == -1 ? VM.OpCode.PUSHM1 : VM.OpCode.PUSH0 + (byte)(int)number);
- Span buffer = stackalloc byte[32];
- if (!number.TryWriteBytes(buffer, out var bytesWritten, isUnsigned: false, isBigEndian: false))
- throw new ArgumentOutOfRangeException(nameof(number));
- var instruction = bytesWritten switch
+ internal Instruction Push(BigInteger number)
{
- 1 => new Instruction
- {
- _opCode = VM.OpCode.PUSHINT8,
- _operand = PadRight(buffer, bytesWritten, 1, number.Sign < 0).ToArray()
- },
- 2 => new Instruction
- {
- _opCode = VM.OpCode.PUSHINT16,
- _operand = PadRight(buffer, bytesWritten, 2, number.Sign < 0).ToArray()
- },
- <= 4 => new Instruction
+ if (number >= -1 && number <= 16) return AddInstruction(number == -1 ? VM.OpCode.PUSHM1 : VM.OpCode.PUSH0 + (byte)(int)number);
+ Span buffer = stackalloc byte[32];
+ if (!number.TryWriteBytes(buffer, out var bytesWritten, isUnsigned: false, isBigEndian: false))
+ throw new ArgumentOutOfRangeException(nameof(number));
+ var instruction = bytesWritten switch
{
- _opCode = VM.OpCode.PUSHINT32,
- _operand = PadRight(buffer, bytesWritten, 4, number.Sign < 0).ToArray()
- },
- <= 8 => new Instruction
- {
- _opCode = VM.OpCode.PUSHINT64,
- _operand = PadRight(buffer, bytesWritten, 8, number.Sign < 0).ToArray()
- },
- <= 16 => new Instruction
- {
- _opCode = VM.OpCode.PUSHINT128,
- _operand = PadRight(buffer, bytesWritten, 16, number.Sign < 0).ToArray()
- },
- <= 32 => new Instruction
- {
- _opCode = VM.OpCode.PUSHINT256,
- _operand = PadRight(buffer, bytesWritten, 32, number.Sign < 0).ToArray()
- },
- _ => throw new ArgumentOutOfRangeException($"Number too large: {bytesWritten}")
- };
- AddInstruction(instruction);
- return instruction;
- }
-
- internal Instruction Push(string s)
- {
- return Push(Utility.StrictUTF8.GetBytes(s));
- }
+ 1 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT8,
+ _operand = PadRight(buffer, bytesWritten, 1, number.Sign < 0).ToArray()
+ },
+ 2 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT16,
+ _operand = PadRight(buffer, bytesWritten, 2, number.Sign < 0).ToArray()
+ },
+ <= 4 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT32,
+ _operand = PadRight(buffer, bytesWritten, 4, number.Sign < 0).ToArray()
+ },
+ <= 8 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT64,
+ _operand = PadRight(buffer, bytesWritten, 8, number.Sign < 0).ToArray()
+ },
+ <= 16 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT128,
+ _operand = PadRight(buffer, bytesWritten, 16, number.Sign < 0).ToArray()
+ },
+ <= 32 => new Instruction
+ {
+ _opCode = VM.OpCode.PUSHINT256,
+ _operand = PadRight(buffer, bytesWritten, 32, number.Sign < 0).ToArray()
+ },
+ _ => throw new ArgumentOutOfRangeException($"Number too large: {bytesWritten}")
+ };
+ AddInstruction(instruction);
+ return instruction;
+ }
- internal Instruction Push(byte[] data)
- {
- VM.OpCode opcode;
- byte[] buffer;
- switch (data.Length)
+ internal Instruction Push(string s)
{
- case <= byte.MaxValue:
- opcode = VM.OpCode.PUSHDATA1;
- buffer = new byte[sizeof(byte) + data.Length];
- buffer[0] = (byte)data.Length;
- Buffer.BlockCopy(data, 0, buffer, sizeof(byte), data.Length);
- break;
- case <= ushort.MaxValue:
- opcode = VM.OpCode.PUSHDATA2;
- buffer = new byte[sizeof(ushort) + data.Length];
- BinaryPrimitives.WriteUInt16LittleEndian(buffer, (ushort)data.Length);
- Buffer.BlockCopy(data, 0, buffer, sizeof(ushort), data.Length);
- break;
- default:
- opcode = VM.OpCode.PUSHDATA4;
- buffer = new byte[sizeof(uint) + data.Length];
- BinaryPrimitives.WriteUInt32LittleEndian(buffer, (uint)data.Length);
- Buffer.BlockCopy(data, 0, buffer, sizeof(uint), data.Length);
- break;
+ return Push(Utility.StrictUTF8.GetBytes(s));
}
- return AddInstruction(new Instruction
+
+ internal Instruction Push(byte[] data)
{
- _opCode = opcode,
- _operand = buffer
- });
- }
+ VM.OpCode opcode;
+ byte[] buffer;
+ switch (data.Length)
+ {
+ case <= byte.MaxValue:
+ opcode = VM.OpCode.PUSHDATA1;
+ buffer = new byte[sizeof(byte) + data.Length];
+ buffer[0] = (byte)data.Length;
+ Buffer.BlockCopy(data, 0, buffer, sizeof(byte), data.Length);
+ break;
+ case <= ushort.MaxValue:
+ opcode = VM.OpCode.PUSHDATA2;
+ buffer = new byte[sizeof(ushort) + data.Length];
+ BinaryPrimitives.WriteUInt16LittleEndian(buffer, (ushort)data.Length);
+ Buffer.BlockCopy(data, 0, buffer, sizeof(ushort), data.Length);
+ break;
+ default:
+ opcode = VM.OpCode.PUSHDATA4;
+ buffer = new byte[sizeof(uint) + data.Length];
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer, (uint)data.Length);
+ Buffer.BlockCopy(data, 0, buffer, sizeof(uint), data.Length);
+ break;
+ }
+ return AddInstruction(new Instruction
+ {
+ _opCode = opcode,
+ _operand = buffer
+ });
+ }
- internal void Push(object? obj)
- {
- switch (obj)
+ internal void Push(object? obj)
{
- case bool data:
- Push(data);
- break;
- case byte[] data:
- Push(data);
- break;
- case string data:
- Push(data);
- break;
- case BigInteger data:
- Push(data);
- break;
- case char data:
- Push((ushort)data);
- break;
- case sbyte data:
- Push(data);
- break;
- case byte data:
- Push(data);
- break;
- case short data:
- Push(data);
- break;
- case ushort data:
- Push(data);
- break;
- case int data:
- Push(data);
- break;
- case uint data:
- Push(data);
- break;
- case long data:
- Push(data);
- break;
- case ulong data:
- Push(data);
- break;
- case Enum data:
- Push(BigInteger.Parse(data.ToString("d")));
- break;
- case null:
- AddInstruction(VM.OpCode.PUSHNULL);
- break;
- default:
- throw new NotSupportedException($"Unsupported constant value: {obj}");
+ switch (obj)
+ {
+ case bool data:
+ Push(data);
+ break;
+ case byte[] data:
+ Push(data);
+ break;
+ case string data:
+ Push(data);
+ break;
+ case BigInteger data:
+ Push(data);
+ break;
+ case char data:
+ Push((ushort)data);
+ break;
+ case sbyte data:
+ Push(data);
+ break;
+ case byte data:
+ Push(data);
+ break;
+ case short data:
+ Push(data);
+ break;
+ case ushort data:
+ Push(data);
+ break;
+ case int data:
+ Push(data);
+ break;
+ case uint data:
+ Push(data);
+ break;
+ case long data:
+ Push(data);
+ break;
+ case ulong data:
+ Push(data);
+ break;
+ case Enum data:
+ Push(BigInteger.Parse(data.ToString("d")));
+ break;
+ case null:
+ AddInstruction(VM.OpCode.PUSHNULL);
+ break;
+ default:
+ throw new NotSupportedException($"Unsupported constant value: {obj}");
+ }
}
- }
- // Helper method to reverse stack items
- internal void ReverseStackItems(int count)
- {
- switch (count)
+ // Helper method to reverse stack items
+ internal void ReverseStackItems(int count)
{
- case 2:
- AddInstruction(VM.OpCode.SWAP);
- break;
- case 3:
- AddInstruction(VM.OpCode.REVERSE3);
- break;
- case 4:
- AddInstruction(VM.OpCode.REVERSE4);
- break;
- default:
- Push(count);
- AddInstruction(VM.OpCode.REVERSEN);
- break;
+ switch (count)
+ {
+ case 2:
+ AddInstruction(VM.OpCode.SWAP);
+ break;
+ case 3:
+ AddInstruction(VM.OpCode.REVERSE3);
+ break;
+ case 4:
+ AddInstruction(VM.OpCode.REVERSE4);
+ break;
+ default:
+ Push(count);
+ AddInstruction(VM.OpCode.REVERSEN);
+ break;
+ }
}
- }
- internal static ReadOnlySpan PadRight(Span buffer, int dataLength, int padLength, bool negative)
- {
- byte pad = negative ? (byte)0xff : (byte)0;
- for (int x = dataLength; x < padLength; x++)
- buffer[x] = pad;
- return buffer[..padLength];
- }
+ internal static ReadOnlySpan PadRight(Span buffer, int dataLength, int padLength, bool negative)
+ {
+ byte pad = negative ? (byte)0xff : (byte)0;
+ for (int x = dataLength; x < padLength; x++)
+ buffer[x] = pad;
+ return buffer[..padLength];
+ }
- internal Instruction IsType(VM.Types.StackItemType type)
- {
- return AddInstruction(new Instruction
+ internal Instruction IsType(VM.Types.StackItemType type)
{
- _opCode = VM.OpCode.ISTYPE,
- _operand = [(byte)type]
- });
- }
+ return AddInstruction(new Instruction
+ {
+ _opCode = VM.OpCode.ISTYPE,
+ _operand = [(byte)type]
+ });
+ }
- internal Instruction ChangeType(VM.Types.StackItemType type)
- {
- return AddInstruction(new Instruction
+ internal Instruction ChangeType(VM.Types.StackItemType type)
{
- _opCode = VM.OpCode.CONVERT,
- _operand = [(byte)type]
- });
- }
+ return AddInstruction(new Instruction
+ {
+ _opCode = VM.OpCode.CONVERT,
+ _operand = [(byte)type]
+ });
+ }
- internal byte[] ToArray()
- {
- var instructions = _instructions.ToArray();
- instructions.RebuildOffsets();
- instructions.RebuildOperands();
- return instructions.Select(p => p.ToArray()).SelectMany(p => p).ToArray();
+ internal byte[] ToArray()
+ {
+ var instructions = _instructions.ToArray();
+ instructions.RebuildOffsets();
+ instructions.RebuildOperands();
+ return instructions.Select(p => p.ToArray()).SelectMany(p => p).ToArray();
+ }
}
}
diff --git a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/JumpTarget.cs b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/JumpTarget.cs
index 246b0e5884..6fe4e24e00 100644
--- a/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/JumpTarget.cs
+++ b/benchmarks/Neo.VM.Benchmarks/InstructionBuilder/JumpTarget.cs
@@ -9,9 +9,10 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-namespace Neo.VM.Benchmark;
-
-public class JumpTarget
+namespace Neo.VM.Benchmark
{
- public Instruction? _instruction;
+ public class JumpTarget
+ {
+ public Instruction? _instruction;
+ }
}
diff --git a/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj b/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj
index d5a7909a4b..32b3ec9aa0 100644
--- a/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj
+++ b/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj
@@ -2,18 +2,18 @@
Exe
- net8.0
+ net9.0
Neo.VM
enable
enable
-
+
-
+
diff --git a/benchmarks/Neo.VM.Benchmarks/OpCode/Arrays/OpCode.ReverseN.cs b/benchmarks/Neo.VM.Benchmarks/OpCode/Arrays/OpCode.ReverseN.cs
index 515125ddc0..31faa5a770 100644
--- a/benchmarks/Neo.VM.Benchmarks/OpCode/Arrays/OpCode.ReverseN.cs
+++ b/benchmarks/Neo.VM.Benchmarks/OpCode/Arrays/OpCode.ReverseN.cs
@@ -9,40 +9,41 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-namespace Neo.VM.Benchmark.OpCode;
-
-public class OpCode_ReverseN : OpCodeBase
+namespace Neo.VM.Benchmark.OpCode
{
- protected override byte[] CreateScript(BenchmarkMode benchmarkMode)
+ public class OpCode_ReverseN : OpCodeBase
{
- var builder = new InstructionBuilder();
- var initBegin = new JumpTarget();
- builder.AddInstruction(new Instruction { _opCode = VM.OpCode.INITSLOT, _operand = [1, 0] });
- builder.Push(ItemCount);
- builder.AddInstruction(VM.OpCode.STLOC0);
- initBegin._instruction = builder.AddInstruction(VM.OpCode.NOP);
- builder.Push(0);
- builder.AddInstruction(VM.OpCode.LDLOC0);
- builder.AddInstruction(VM.OpCode.DEC);
- builder.AddInstruction(VM.OpCode.STLOC0);
- builder.AddInstruction(VM.OpCode.LDLOC0);
- builder.Jump(VM.OpCode.JMPIF, initBegin);
- if (benchmarkMode == BenchmarkMode.BaseLine)
- {
- return builder.ToArray();
- }
- builder.Push(ItemCount);
- builder.AddInstruction(VM.OpCode.REVERSEN);
- if (benchmarkMode == BenchmarkMode.OneGAS)
+ protected override byte[] CreateScript(BenchmarkMode benchmarkMode)
{
- // just keep running until GAS is exhausted
- var loopStart = new JumpTarget { _instruction = builder.AddInstruction(VM.OpCode.NOP) };
+ var builder = new InstructionBuilder();
+ var initBegin = new JumpTarget();
+ builder.AddInstruction(new Instruction { _opCode = VM.OpCode.INITSLOT, _operand = [1, 0] });
+ builder.Push(ItemCount);
+ builder.AddInstruction(VM.OpCode.STLOC0);
+ initBegin._instruction = builder.AddInstruction(VM.OpCode.NOP);
+ builder.Push(0);
+ builder.AddInstruction(VM.OpCode.LDLOC0);
+ builder.AddInstruction(VM.OpCode.DEC);
+ builder.AddInstruction(VM.OpCode.STLOC0);
+ builder.AddInstruction(VM.OpCode.LDLOC0);
+ builder.Jump(VM.OpCode.JMPIF, initBegin);
+ if (benchmarkMode == BenchmarkMode.BaseLine)
+ {
+ return builder.ToArray();
+ }
builder.Push(ItemCount);
builder.AddInstruction(VM.OpCode.REVERSEN);
- builder.Jump(VM.OpCode.JMP, loopStart);
- }
+ if (benchmarkMode == BenchmarkMode.OneGAS)
+ {
+ // just keep running until GAS is exhausted
+ var loopStart = new JumpTarget { _instruction = builder.AddInstruction(VM.OpCode.NOP) };
+ builder.Push(ItemCount);
+ builder.AddInstruction(VM.OpCode.REVERSEN);
+ builder.Jump(VM.OpCode.JMP, loopStart);
+ }
- return builder.ToArray();
+ return builder.ToArray();
+ }
}
}
diff --git a/benchmarks/Neo.VM.Benchmarks/OpCode/Benchmark.Opcode.cs b/benchmarks/Neo.VM.Benchmarks/OpCode/Benchmark.Opcode.cs
index f55abae7ee..7dae2c9074 100644
--- a/benchmarks/Neo.VM.Benchmarks/OpCode/Benchmark.Opcode.cs
+++ b/benchmarks/Neo.VM.Benchmarks/OpCode/Benchmark.Opcode.cs
@@ -9,226 +9,227 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.
-namespace Neo.VM.Benchmark.OpCode;
-
-public class Benchmark_Opcode
+namespace Neo.VM.Benchmark.OpCode
{
- internal static readonly long OneGasDatoshi = 1_0000_0000;
-
- public static readonly IReadOnlyDictionary OpCodePrices = new Dictionary
+ public class Benchmark_Opcode
{
- [VM.OpCode.PUSHINT8] = 1 << 0,
- [VM.OpCode.PUSHINT16] = 1 << 0,
- [VM.OpCode.PUSHINT32] = 1 << 0,
- [VM.OpCode.PUSHINT64] = 1 << 0,
- [VM.OpCode.PUSHINT128] = 1 << 2,
- [VM.OpCode.PUSHINT256] = 1 << 2,
- [VM.OpCode.PUSHT] = 1 << 0,
- [VM.OpCode.PUSHF] = 1 << 0,
- [VM.OpCode.PUSHA] = 1 << 2,
- [VM.OpCode.PUSHNULL] = 1 << 0,
- [VM.OpCode.PUSHDATA1] = 1 << 3,
- [VM.OpCode.PUSHDATA2] = 1 << 9,
- [VM.OpCode.PUSHDATA4] = 1 << 12,
- [VM.OpCode.PUSHM1] = 1 << 0,
- [VM.OpCode.PUSH0] = 1 << 0,
- [VM.OpCode.PUSH1] = 1 << 0,
- [VM.OpCode.PUSH2] = 1 << 0,
- [VM.OpCode.PUSH3] = 1 << 0,
- [VM.OpCode.PUSH4] = 1 << 0,
- [VM.OpCode.PUSH5] = 1 << 0,
- [VM.OpCode.PUSH6] = 1 << 0,
- [VM.OpCode.PUSH7] = 1 << 0,
- [VM.OpCode.PUSH8] = 1 << 0,
- [VM.OpCode.PUSH9] = 1 << 0,
- [VM.OpCode.PUSH10] = 1 << 0,
- [VM.OpCode.PUSH11] = 1 << 0,
- [VM.OpCode.PUSH12] = 1 << 0,
- [VM.OpCode.PUSH13] = 1 << 0,
- [VM.OpCode.PUSH14] = 1 << 0,
- [VM.OpCode.PUSH15] = 1 << 0,
- [VM.OpCode.PUSH16] = 1 << 0,
- [VM.OpCode.NOP] = 1 << 0,
- [VM.OpCode.JMP] = 1 << 1,
- [VM.OpCode.JMP_L] = 1 << 1,
- [VM.OpCode.JMPIF] = 1 << 1,
- [VM.OpCode.JMPIF_L] = 1 << 1,
- [VM.OpCode.JMPIFNOT] = 1 << 1,
- [VM.OpCode.JMPIFNOT_L] = 1 << 1,
- [VM.OpCode.JMPEQ] = 1 << 1,
- [VM.OpCode.JMPEQ_L] = 1 << 1,
- [VM.OpCode.JMPNE] = 1 << 1,
- [VM.OpCode.JMPNE_L] = 1 << 1,
- [VM.OpCode.JMPGT] = 1 << 1,
- [VM.OpCode.JMPGT_L] = 1 << 1,
- [VM.OpCode.JMPGE] = 1 << 1,
- [VM.OpCode.JMPGE_L] = 1 << 1,
- [VM.OpCode.JMPLT] = 1 << 1,
- [VM.OpCode.JMPLT_L] = 1 << 1,
- [VM.OpCode.JMPLE] = 1 << 1,
- [VM.OpCode.JMPLE_L] = 1 << 1,
- [VM.OpCode.CALL] = 1 << 9,
- [VM.OpCode.CALL_L] = 1 << 9,
- [VM.OpCode.CALLA] = 1 << 9,
- [VM.OpCode.CALLT] = 1 << 15,
- [VM.OpCode.ABORT] = 0,
- [VM.OpCode.ABORTMSG] = 0,
- [VM.OpCode.ASSERT] = 1 << 0,
- [VM.OpCode.ASSERTMSG] = 1 << 0,
- [VM.OpCode.THROW] = 1 << 9,
- [VM.OpCode.TRY] = 1 << 2,
- [VM.OpCode.TRY_L] = 1 << 2,
- [VM.OpCode.ENDTRY] = 1 << 2,
- [VM.OpCode.ENDTRY_L] = 1 << 2,
- [VM.OpCode.ENDFINALLY] = 1 << 2,
- [VM.OpCode.RET] = 0,
- [VM.OpCode.SYSCALL] = 0,
- [VM.OpCode.DEPTH] = 1 << 1,
- [VM.OpCode.DROP] = 1 << 1,
- [VM.OpCode.NIP] = 1 << 1,
- [VM.OpCode.XDROP] = 1 << 4,
- [VM.OpCode.CLEAR] = 1 << 4,
- [VM.OpCode.DUP] = 1 << 1,
- [VM.OpCode.OVER] = 1 << 1,
- [VM.OpCode.PICK] = 1 << 1,
- [VM.OpCode.TUCK] = 1 << 1,
- [VM.OpCode.SWAP] = 1 << 1,
- [VM.OpCode.ROT] = 1 << 1,
- [VM.OpCode.ROLL] = 1 << 4,
- [VM.OpCode.REVERSE3] = 1 << 1,
- [VM.OpCode.REVERSE4] = 1 << 1,
- [VM.OpCode.REVERSEN] = 1 << 4,
- [VM.OpCode.INITSSLOT] = 1 << 4,
- [VM.OpCode.INITSLOT] = 1 << 6,
- [VM.OpCode.LDSFLD0] = 1 << 1,
- [VM.OpCode.LDSFLD1] = 1 << 1,
- [VM.OpCode.LDSFLD2] = 1 << 1,
- [VM.OpCode.LDSFLD3] = 1 << 1,
- [VM.OpCode.LDSFLD4] = 1 << 1,
- [VM.OpCode.LDSFLD5] = 1 << 1,
- [VM.OpCode.LDSFLD6] = 1 << 1,
- [VM.OpCode.LDSFLD] = 1 << 1,
- [VM.OpCode.STSFLD0] = 1 << 1,
- [VM.OpCode.STSFLD1] = 1 << 1,
- [VM.OpCode.STSFLD2] = 1 << 1,
- [VM.OpCode.STSFLD3] = 1 << 1,
- [VM.OpCode.STSFLD4] = 1 << 1,
- [VM.OpCode.STSFLD5] = 1 << 1,
- [VM.OpCode.STSFLD6] = 1 << 1,
- [VM.OpCode.STSFLD] = 1 << 1,
- [VM.OpCode.LDLOC0] = 1 << 1,
- [VM.OpCode.LDLOC1] = 1 << 1,
- [VM.OpCode.LDLOC2] = 1 << 1,
- [VM.OpCode.LDLOC3] = 1 << 1,
- [VM.OpCode.LDLOC4] = 1 << 1,
- [VM.OpCode.LDLOC5] = 1 << 1,
- [VM.OpCode.LDLOC6] = 1 << 1,
- [VM.OpCode.LDLOC] = 1 << 1,
- [VM.OpCode.STLOC0] = 1 << 1,
- [VM.OpCode.STLOC1] = 1 << 1,
- [VM.OpCode.STLOC2] = 1 << 1,
- [VM.OpCode.STLOC3] = 1 << 1,
- [VM.OpCode.STLOC4] = 1 << 1,
- [VM.OpCode.STLOC5] = 1 << 1,
- [VM.OpCode.STLOC6] = 1 << 1,
- [VM.OpCode.STLOC] = 1 << 1,
- [VM.OpCode.LDARG0] = 1 << 1,
- [VM.OpCode.LDARG1] = 1 << 1,
- [VM.OpCode.LDARG2] = 1 << 1,
- [VM.OpCode.LDARG3] = 1 << 1,
- [VM.OpCode.LDARG4] = 1 << 1,
- [VM.OpCode.LDARG5] = 1 << 1,
- [VM.OpCode.LDARG6] = 1 << 1,
- [VM.OpCode.LDARG] = 1 << 1,
- [VM.OpCode.STARG0] = 1 << 1,
- [VM.OpCode.STARG1] = 1 << 1,
- [VM.OpCode.STARG2] = 1 << 1,
- [VM.OpCode.STARG3] = 1 << 1,
- [VM.OpCode.STARG4] = 1 << 1,
- [VM.OpCode.STARG5] = 1 << 1,
- [VM.OpCode.STARG6] = 1 << 1,
- [VM.OpCode.STARG] = 1 << 1,
- [VM.OpCode.NEWBUFFER] = 1 << 8,
- [VM.OpCode.MEMCPY] = 1 << 11,
- [VM.OpCode.CAT] = 1 << 11,
- [VM.OpCode.SUBSTR] = 1 << 11,
- [VM.OpCode.LEFT] = 1 << 11,
- [VM.OpCode.RIGHT] = 1 << 11,
- [VM.OpCode.INVERT] = 1 << 2,
- [VM.OpCode.AND] = 1 << 3,
- [VM.OpCode.OR] = 1 << 3,
- [VM.OpCode.XOR] = 1 << 3,
- [VM.OpCode.EQUAL] = 1 << 5,
- [VM.OpCode.NOTEQUAL] = 1 << 5,
- [VM.OpCode.SIGN] = 1 << 2,
- [VM.OpCode.ABS] = 1 << 2,
- [VM.OpCode.NEGATE] = 1 << 2,
- [VM.OpCode.INC] = 1 << 2,
- [VM.OpCode.DEC] = 1 << 2,
- [VM.OpCode.ADD] = 1 << 3,
- [VM.OpCode.SUB] = 1 << 3,
- [VM.OpCode.MUL] = 1 << 3,
- [VM.OpCode.DIV] = 1 << 3,
- [VM.OpCode.MOD] = 1 << 3,
- [VM.OpCode.POW] = 1 << 6,
- [VM.OpCode.SQRT] = 1 << 6,
- [VM.OpCode.MODMUL] = 1 << 5,
- [VM.OpCode.MODPOW] = 1 << 11,
- [VM.OpCode.SHL] = 1 << 3,
- [VM.OpCode.SHR] = 1 << 3,
- [VM.OpCode.NOT] = 1 << 2,
- [VM.OpCode.BOOLAND] = 1 << 3,
- [VM.OpCode.BOOLOR] = 1 << 3,
- [VM.OpCode.NZ] = 1 << 2,
- [VM.OpCode.NUMEQUAL] = 1 << 3,
- [VM.OpCode.NUMNOTEQUAL] = 1 << 3,
- [VM.OpCode.LT] = 1 << 3,
- [VM.OpCode.LE] = 1 << 3,
- [VM.OpCode.GT] = 1 << 3,
- [VM.OpCode.GE] = 1 << 3,
- [VM.OpCode.MIN] = 1 << 3,
- [VM.OpCode.MAX] = 1 << 3,
- [VM.OpCode.WITHIN] = 1 << 3,
- [VM.OpCode.PACKMAP] = 1 << 11,
- [VM.OpCode.PACKSTRUCT] = 1 << 11,
- [VM.OpCode.PACK] = 1 << 11,
- [VM.OpCode.UNPACK] = 1 << 11,
- [VM.OpCode.NEWARRAY0] = 1 << 4,
- [VM.OpCode.NEWARRAY] = 1 << 9,
- [VM.OpCode.NEWARRAY_T] = 1 << 9,
- [VM.OpCode.NEWSTRUCT0] = 1 << 4,
- [VM.OpCode.NEWSTRUCT] = 1 << 9,
- [VM.OpCode.NEWMAP] = 1 << 3,
- [VM.OpCode.SIZE] = 1 << 2,
- [VM.OpCode.HASKEY] = 1 << 6,
- [VM.OpCode.KEYS] = 1 << 4,
- [VM.OpCode.VALUES] = 1 << 13,
- [VM.OpCode.PICKITEM] = 1 << 6,
- [VM.OpCode.APPEND] = 1 << 13,
- [VM.OpCode.SETITEM] = 1 << 13,
- [VM.OpCode.REVERSEITEMS] = 1 << 13,
- [VM.OpCode.REMOVE] = 1 << 4,
- [VM.OpCode.CLEARITEMS] = 1 << 4,
- [VM.OpCode.POPITEM] = 1 << 4,
- [VM.OpCode.ISNULL] = 1 << 1,
- [VM.OpCode.ISTYPE] = 1 << 1,
- [VM.OpCode.CONVERT] = 1 << 13,
- };
+ internal static readonly long OneGasDatoshi = 1_0000_0000;
- internal static void RunScript(byte[] script)
- {
- LoadScript(script).ExecuteBenchmark();
- }
+ public static readonly IReadOnlyDictionary OpCodePrices = new Dictionary
+ {
+ [VM.OpCode.PUSHINT8] = 1 << 0,
+ [VM.OpCode.PUSHINT16] = 1 << 0,
+ [VM.OpCode.PUSHINT32] = 1 << 0,
+ [VM.OpCode.PUSHINT64] = 1 << 0,
+ [VM.OpCode.PUSHINT128] = 1 << 2,
+ [VM.OpCode.PUSHINT256] = 1 << 2,
+ [VM.OpCode.PUSHT] = 1 << 0,
+ [VM.OpCode.PUSHF] = 1 << 0,
+ [VM.OpCode.PUSHA] = 1 << 2,
+ [VM.OpCode.PUSHNULL] = 1 << 0,
+ [VM.OpCode.PUSHDATA1] = 1 << 3,
+ [VM.OpCode.PUSHDATA2] = 1 << 9,
+ [VM.OpCode.PUSHDATA4] = 1 << 12,
+ [VM.OpCode.PUSHM1] = 1 << 0,
+ [VM.OpCode.PUSH0] = 1 << 0,
+ [VM.OpCode.PUSH1] = 1 << 0,
+ [VM.OpCode.PUSH2] = 1 << 0,
+ [VM.OpCode.PUSH3] = 1 << 0,
+ [VM.OpCode.PUSH4] = 1 << 0,
+ [VM.OpCode.PUSH5] = 1 << 0,
+ [VM.OpCode.PUSH6] = 1 << 0,
+ [VM.OpCode.PUSH7] = 1 << 0,
+ [VM.OpCode.PUSH8] = 1 << 0,
+ [VM.OpCode.PUSH9] = 1 << 0,
+ [VM.OpCode.PUSH10] = 1 << 0,
+ [VM.OpCode.PUSH11] = 1 << 0,
+ [VM.OpCode.PUSH12] = 1 << 0,
+ [VM.OpCode.PUSH13] = 1 << 0,
+ [VM.OpCode.PUSH14] = 1 << 0,
+ [VM.OpCode.PUSH15] = 1 << 0,
+ [VM.OpCode.PUSH16] = 1 << 0,
+ [VM.OpCode.NOP] = 1 << 0,
+ [VM.OpCode.JMP] = 1 << 1,
+ [VM.OpCode.JMP_L] = 1 << 1,
+ [VM.OpCode.JMPIF] = 1 << 1,
+ [VM.OpCode.JMPIF_L] = 1 << 1,
+ [VM.OpCode.JMPIFNOT] = 1 << 1,
+ [VM.OpCode.JMPIFNOT_L] = 1 << 1,
+ [VM.OpCode.JMPEQ] = 1 << 1,
+ [VM.OpCode.JMPEQ_L] = 1 << 1,
+ [VM.OpCode.JMPNE] = 1 << 1,
+ [VM.OpCode.JMPNE_L] = 1 << 1,
+ [VM.OpCode.JMPGT] = 1 << 1,
+ [VM.OpCode.JMPGT_L] = 1 << 1,
+ [VM.OpCode.JMPGE] = 1 << 1,
+ [VM.OpCode.JMPGE_L] = 1 << 1,
+ [VM.OpCode.JMPLT] = 1 << 1,
+ [VM.OpCode.JMPLT_L] = 1 << 1,
+ [VM.OpCode.JMPLE] = 1 << 1,
+ [VM.OpCode.JMPLE_L] = 1 << 1,
+ [VM.OpCode.CALL] = 1 << 9,
+ [VM.OpCode.CALL_L] = 1 << 9,
+ [VM.OpCode.CALLA] = 1 << 9,
+ [VM.OpCode.CALLT] = 1 << 15,
+ [VM.OpCode.ABORT] = 0,
+ [VM.OpCode.ABORTMSG] = 0,
+ [VM.OpCode.ASSERT] = 1 << 0,
+ [VM.OpCode.ASSERTMSG] = 1 << 0,
+ [VM.OpCode.THROW] = 1 << 9,
+ [VM.OpCode.TRY] = 1 << 2,
+ [VM.OpCode.TRY_L] = 1 << 2,
+ [VM.OpCode.ENDTRY] = 1 << 2,
+ [VM.OpCode.ENDTRY_L] = 1 << 2,
+ [VM.OpCode.ENDFINALLY] = 1 << 2,
+ [VM.OpCode.RET] = 0,
+ [VM.OpCode.SYSCALL] = 0,
+ [VM.OpCode.DEPTH] = 1 << 1,
+ [VM.OpCode.DROP] = 1 << 1,
+ [VM.OpCode.NIP] = 1 << 1,
+ [VM.OpCode.XDROP] = 1 << 4,
+ [VM.OpCode.CLEAR] = 1 << 4,
+ [VM.OpCode.DUP] = 1 << 1,
+ [VM.OpCode.OVER] = 1 << 1,
+ [VM.OpCode.PICK] = 1 << 1,
+ [VM.OpCode.TUCK] = 1 << 1,
+ [VM.OpCode.SWAP] = 1 << 1,
+ [VM.OpCode.ROT] = 1 << 1,
+ [VM.OpCode.ROLL] = 1 << 4,
+ [VM.OpCode.REVERSE3] = 1 << 1,
+ [VM.OpCode.REVERSE4] = 1 << 1,
+ [VM.OpCode.REVERSEN] = 1 << 4,
+ [VM.OpCode.INITSSLOT] = 1 << 4,
+ [VM.OpCode.INITSLOT] = 1 << 6,
+ [VM.OpCode.LDSFLD0] = 1 << 1,
+ [VM.OpCode.LDSFLD1] = 1 << 1,
+ [VM.OpCode.LDSFLD2] = 1 << 1,
+ [VM.OpCode.LDSFLD3] = 1 << 1,
+ [VM.OpCode.LDSFLD4] = 1 << 1,
+ [VM.OpCode.LDSFLD5] = 1 << 1,
+ [VM.OpCode.LDSFLD6] = 1 << 1,
+ [VM.OpCode.LDSFLD] = 1 << 1,
+ [VM.OpCode.STSFLD0] = 1 << 1,
+ [VM.OpCode.STSFLD1] = 1 << 1,
+ [VM.OpCode.STSFLD2] = 1 << 1,
+ [VM.OpCode.STSFLD3] = 1 << 1,
+ [VM.OpCode.STSFLD4] = 1 << 1,
+ [VM.OpCode.STSFLD5] = 1 << 1,
+ [VM.OpCode.STSFLD6] = 1 << 1,
+ [VM.OpCode.STSFLD] = 1 << 1,
+ [VM.OpCode.LDLOC0] = 1 << 1,
+ [VM.OpCode.LDLOC1] = 1 << 1,
+ [VM.OpCode.LDLOC2] = 1 << 1,
+ [VM.OpCode.LDLOC3] = 1 << 1,
+ [VM.OpCode.LDLOC4] = 1 << 1,
+ [VM.OpCode.LDLOC5] = 1 << 1,
+ [VM.OpCode.LDLOC6] = 1 << 1,
+ [VM.OpCode.LDLOC] = 1 << 1,
+ [VM.OpCode.STLOC0] = 1 << 1,
+ [VM.OpCode.STLOC1] = 1 << 1,
+ [VM.OpCode.STLOC2] = 1 << 1,
+ [VM.OpCode.STLOC3] = 1 << 1,
+ [VM.OpCode.STLOC4] = 1 << 1,
+ [VM.OpCode.STLOC5] = 1 << 1,
+ [VM.OpCode.STLOC6] = 1 << 1,
+ [VM.OpCode.STLOC] = 1 << 1,
+ [VM.OpCode.LDARG0] = 1 << 1,
+ [VM.OpCode.LDARG1] = 1 << 1,
+ [VM.OpCode.LDARG2] = 1 << 1,
+ [VM.OpCode.LDARG3] = 1 << 1,
+ [VM.OpCode.LDARG4] = 1 << 1,
+ [VM.OpCode.LDARG5] = 1 << 1,
+ [VM.OpCode.LDARG6] = 1 << 1,
+ [VM.OpCode.LDARG] = 1 << 1,
+ [VM.OpCode.STARG0] = 1 << 1,
+ [VM.OpCode.STARG1] = 1 << 1,
+ [VM.OpCode.STARG2] = 1 << 1,
+ [VM.OpCode.STARG3] = 1 << 1,
+ [VM.OpCode.STARG4] = 1 << 1,
+ [VM.OpCode.STARG5] = 1 << 1,
+ [VM.OpCode.STARG6] = 1 << 1,
+ [VM.OpCode.STARG] = 1 << 1,
+ [VM.OpCode.NEWBUFFER] = 1 << 8,
+ [VM.OpCode.MEMCPY] = 1 << 11,
+ [VM.OpCode.CAT] = 1 << 11,
+ [VM.OpCode.SUBSTR] = 1 << 11,
+ [VM.OpCode.LEFT] = 1 << 11,
+ [VM.OpCode.RIGHT] = 1 << 11,
+ [VM.OpCode.INVERT] = 1 << 2,
+ [VM.OpCode.AND] = 1 << 3,
+ [VM.OpCode.OR] = 1 << 3,
+ [VM.OpCode.XOR] = 1 << 3,
+ [VM.OpCode.EQUAL] = 1 << 5,
+ [VM.OpCode.NOTEQUAL] = 1 << 5,
+ [VM.OpCode.SIGN] = 1 << 2,
+ [VM.OpCode.ABS] = 1 << 2,
+ [VM.OpCode.NEGATE] = 1 << 2,
+ [VM.OpCode.INC] = 1 << 2,
+ [VM.OpCode.DEC] = 1 << 2,
+ [VM.OpCode.ADD] = 1 << 3,
+ [VM.OpCode.SUB] = 1 << 3,
+ [VM.OpCode.MUL] = 1 << 3,
+ [VM.OpCode.DIV] = 1 << 3,
+ [VM.OpCode.MOD] = 1 << 3,
+ [VM.OpCode.POW] = 1 << 6,
+ [VM.OpCode.SQRT] = 1 << 6,
+ [VM.OpCode.MODMUL] = 1 << 5,
+ [VM.OpCode.MODPOW] = 1 << 11,
+ [VM.OpCode.SHL] = 1 << 3,
+ [VM.OpCode.SHR] = 1 << 3,
+ [VM.OpCode.NOT] = 1 << 2,
+ [VM.OpCode.BOOLAND] = 1 << 3,
+ [VM.OpCode.BOOLOR] = 1 << 3,
+ [VM.OpCode.NZ] = 1 << 2,
+ [VM.OpCode.NUMEQUAL] = 1 << 3,
+ [VM.OpCode.NUMNOTEQUAL] = 1 << 3,
+ [VM.OpCode.LT] = 1 << 3,
+ [VM.OpCode.LE] = 1 << 3,
+ [VM.OpCode.GT] = 1 << 3,
+ [VM.OpCode.GE] = 1 << 3,
+ [VM.OpCode.MIN] = 1 << 3,
+ [VM.OpCode.MAX] = 1 << 3,
+ [VM.OpCode.WITHIN] = 1 << 3,
+ [VM.OpCode.PACKMAP] = 1 << 11,
+ [VM.OpCode.PACKSTRUCT] = 1 << 11,
+ [VM.OpCode.PACK] = 1 << 11,
+ [VM.OpCode.UNPACK] = 1 << 11,
+ [VM.OpCode.NEWARRAY0] = 1 << 4,
+ [VM.OpCode.NEWARRAY] = 1 << 9,
+ [VM.OpCode.NEWARRAY_T] = 1 << 9,
+ [VM.OpCode.NEWSTRUCT0] = 1 << 4,
+ [VM.OpCode.NEWSTRUCT] = 1 << 9,
+ [VM.OpCode.NEWMAP] = 1 << 3,
+ [VM.OpCode.SIZE] = 1 << 2,
+ [VM.OpCode.HASKEY] = 1 << 6,
+ [VM.OpCode.KEYS] = 1 << 4,
+ [VM.OpCode.VALUES] = 1 << 13,
+ [VM.OpCode.PICKITEM] = 1 << 6,
+ [VM.OpCode.APPEND] = 1 << 13,
+ [VM.OpCode.SETITEM] = 1 << 13,
+ [VM.OpCode.REVERSEITEMS] = 1 << 13,
+ [VM.OpCode.REMOVE] = 1 << 4,
+ [VM.OpCode.CLEARITEMS] = 1 << 4,
+ [VM.OpCode.POPITEM] = 1 << 4,
+ [VM.OpCode.ISNULL] = 1 << 1,
+ [VM.OpCode.ISTYPE] = 1 << 1,
+ [VM.OpCode.CONVERT] = 1 << 13,
+ };
- internal static BenchmarkEngine RunScriptUntil(byte[] script, VM.OpCode opCode)
- {
- return LoadScript(script).ExecuteUntil(opCode);
- }
+ internal static void RunScript(byte[] script)
+ {
+ LoadScript(script).ExecuteBenchmark();
+ }
- internal static BenchmarkEngine LoadScript(byte[] script)
- {
- var engine = new BenchmarkEngine();
- engine.LoadScript(script);
- return engine;
+ internal static BenchmarkEngine RunScriptUntil(byte[] script, VM.OpCode opCode)
+ {
+ return LoadScript(script).ExecuteUntil(opCode);
+ }
+
+ internal static BenchmarkEngine LoadScript(byte[] script)
+ {
+ var engine = new BenchmarkEngine();
+ engine.LoadScript(script);
+ return engine;
+ }
}
}
diff --git a/benchmarks/Neo.VM.Benchmarks/OpCode/BenchmarkEngine.cs b/benchmarks/Neo.VM.Benchmarks/OpCode/BenchmarkEngine.cs
index 50f80c57e9..f1452f2e6c 100644
--- a/benchmarks/Neo.VM.Benchmarks/OpCode/BenchmarkEngine.cs
+++ b/benchmarks/Neo.VM.Benchmarks/OpCode/BenchmarkEngine.cs
@@ -13,178 +13,179 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
-namespace Neo.VM.Benchmark.OpCode;
-
-///
-/// A simple benchmark engine for .
-///
-public class BenchmarkEngine : TestEngine
+namespace Neo.VM.Benchmark.OpCode
{
- private readonly Dictionary _opcodeStats = new();
- private readonly Dictionary