diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index bce1dc7c79..aa935fd2d3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -38,6 +38,44 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coverage/lcov.net7.0.info
+ PublishGithub:
+ if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
+ needs: Test
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+
+ - name: Set Version
+ run: git rev-list --count HEAD | xargs printf 'CI%05d' | xargs -I{} echo 'VERSION_SUFFIX={}' >> $GITHUB_ENV
+
+ - name : Pack (Neo)
+ run: |
+ dotnet pack \
+ --configuration Release \
+ --output ./out \
+ --version-suffix ${{ env.VERSION_SUFFIX }}
+
+ - name: Remove Unwanted Files
+ working-directory: ./out
+ run: |
+ rm -v Neo.CLI*
+ rm -v Neo.GUI*
+
+ - name: Publish to Github Packages
+ working-directory: ./out
+ run: |
+ dotnet nuget push * \
+ --source https://nuget.pkg.github.com/neo-project/index.json \
+ --api-key "${{ secrets.GITHUB_TOKEN }}" \
+ --disable-buffering \
+ --no-service-endpoint;
+
# MyGet isn't working
# PublishMyGet:
# if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
@@ -113,6 +151,18 @@ jobs:
dotnet pack ./src/Neo \
--configuration Release \
--output ./out
+ - name : Pack (Neo.IO)
+ if: steps.check_tag.outputs.statusCode == '404'
+ run: |
+ dotnet pack ./src/Neo.IO \
+ --configuration Release \
+ --output ./out
+ - name : Pack (Neo.Extensions)
+ if: steps.check_tag.outputs.statusCode == '404'
+ run: |
+ dotnet pack ./src/Neo.Extensions \
+ --configuration Release \
+ --output ./out
- name : Pack (Neo.Json)
if: steps.check_tag.outputs.statusCode == '404'
run: |
diff --git a/.github/workflows/pkgs-delete.yml b/.github/workflows/pkgs-delete.yml
new file mode 100644
index 0000000000..16855f1070
--- /dev/null
+++ b/.github/workflows/pkgs-delete.yml
@@ -0,0 +1,51 @@
+name: Nuget Package Cleanup (github)
+
+on:
+ schedule:
+ - cron: '0 0 * * *' # Run every day at 24:00
+
+jobs:
+ delete-pkgs:
+ name: Delete Old Nuget Packages
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Delete Neo Package
+ uses: actions/delete-package-versions@v4
+ with:
+ package-name: Neo
+ package-type: nuget
+ min-versions-to-keep: 3
+ token: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Delete Neo.ConsoleService Package
+ uses: actions/delete-package-versions@v4
+ with:
+ package-name: Neo.ConsoleService
+ package-type: nuget
+ min-versions-to-keep: 3
+ token: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Delete Neo.ConsoleService Package
+ uses: actions/delete-package-versions@v4
+ with:
+ package-name: Neo.ConsoleService
+ package-type: nuget
+ min-versions-to-keep: 3
+ token: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Delete Neo.Json Package
+ uses: actions/delete-package-versions@v4
+ with:
+ package-name: Neo.Json
+ package-type: nuget
+ min-versions-to-keep: 3
+ token: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Delete Neo.VM Package
+ uses: actions/delete-package-versions@v4
+ with:
+ package-name: Neo.VM
+ package-type: nuget
+ min-versions-to-keep: 3
+ token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/NuGet.Config b/NuGet.Config
index 5922e754af..f7ce69db29 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -2,6 +2,7 @@
+
diff --git a/neo.sln b/neo.sln
index dc50d0f4d7..b62de06a6e 100644
--- a/neo.sln
+++ b/neo.sln
@@ -24,18 +24,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.VM", "src\Neo.VM\Neo.VM
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.VM.Tests", "tests\Neo.VM.Tests\Neo.VM.Tests.csproj", "{005F84EB-EA2E-449F-930A-7B4173DDC7EC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.ConsoleService", "src\Neo.ConsoleService\Neo.ConsoleService.csproj", "{9E886812-7243-48D8-BEAF-47AADC11C054}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.ConsoleService", "src\Neo.ConsoleService\Neo.ConsoleService.csproj", "{9E886812-7243-48D8-BEAF-47AADC11C054}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.GUI", "src\Neo.GUI\Neo.GUI.csproj", "{02ABDE42-9880-43B4-B6F7-8D618602A277}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.GUI", "src\Neo.GUI\Neo.GUI.csproj", "{02ABDE42-9880-43B4-B6F7-8D618602A277}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.CLI", "src\Neo.CLI\Neo.CLI.csproj", "{BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.CLI", "src\Neo.CLI\Neo.CLI.csproj", "{BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.ConsoleService.Tests", "tests\Neo.ConsoleService.Tests\Neo.ConsoleService.Tests.csproj", "{B40F8584-5AFB-452C-AEFA-009C80CC23A9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.ConsoleService.Tests", "tests\Neo.ConsoleService.Tests\Neo.ConsoleService.Tests.csproj", "{B40F8584-5AFB-452C-AEFA-009C80CC23A9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Cryptography.BLS12_381", "src\Neo.Cryptography.BLS12_381\Neo.Cryptography.BLS12_381.csproj", "{D48C1FAB-3471-4CA0-8688-25E6F43F2C25}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Cryptography.BLS12_381.Tests", "tests\Neo.Cryptography.BLS12_381.Tests\Neo.Cryptography.BLS12_381.Tests.csproj", "{387CCF6C-9A26-43F6-A639-0A82E91E10D8}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.IO", "src\Neo.IO\Neo.IO.csproj", "{4CDAC1AA-45C6-4157-8D8E-199050433048}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Extensions", "src\Neo.Extensions\Neo.Extensions.csproj", "{9C5213D6-3833-4570-8AE2-47E9F9017A8F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -98,6 +102,14 @@ Global
{387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -117,6 +129,8 @@ Global
{B40F8584-5AFB-452C-AEFA-009C80CC23A9} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
{D48C1FAB-3471-4CA0-8688-25E6F43F2C25} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
{387CCF6C-9A26-43F6-A639-0A82E91E10D8} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
+ {4CDAC1AA-45C6-4157-8D8E-199050433048} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}
diff --git a/src/Neo/LogLevel.cs b/src/Neo.Extensions/LogLevel.cs
similarity index 100%
rename from src/Neo/LogLevel.cs
rename to src/Neo.Extensions/LogLevel.cs
diff --git a/src/Neo.Extensions/Neo.Extensions.csproj b/src/Neo.Extensions/Neo.Extensions.csproj
new file mode 100644
index 0000000000..7552a56311
--- /dev/null
+++ b/src/Neo.Extensions/Neo.Extensions.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netstandard2.1;net7.0
+ enable
+ NEO;Blockchain;Extensions
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Neo/Utility.cs b/src/Neo.Extensions/Utility.cs
similarity index 97%
rename from src/Neo/Utility.cs
rename to src/Neo.Extensions/Utility.cs
index 6883c69a26..fca164a4f2 100644
--- a/src/Neo/Utility.cs
+++ b/src/Neo.Extensions/Utility.cs
@@ -31,7 +31,7 @@ public Logger()
}
}
- public static event LogEventHandler Logging;
+ public static event LogEventHandler? Logging;
///
/// A strict UTF8 encoding used in NEO system.
diff --git a/src/Neo/IO/ByteArrayComparer.cs b/src/Neo.IO/ByteArrayComparer.cs
similarity index 62%
rename from src/Neo/IO/ByteArrayComparer.cs
rename to src/Neo.IO/ByteArrayComparer.cs
index 872052095c..f9d44e24d6 100644
--- a/src/Neo/IO/ByteArrayComparer.cs
+++ b/src/Neo.IO/ByteArrayComparer.cs
@@ -20,27 +20,32 @@ internal class ByteArrayComparer : IComparer
public static readonly ByteArrayComparer Default = new(1);
public static readonly ByteArrayComparer Reverse = new(-1);
- private readonly int direction;
+ private readonly int _direction;
private ByteArrayComparer(int direction)
{
- this.direction = direction;
+ _direction = direction;
}
- public int Compare(byte[] x, byte[] y)
+ public int Compare(byte[]? x, byte[]? y)
{
- return direction > 0
- ? CompareInternal(x, y)
- : -CompareInternal(x, y);
+ if (x == y) return 0;
+ if (x is null && y is not null)
+ return _direction > 0 ? -y.Length : y.Length;
+ if (y is null && x is not null)
+ return _direction > 0 ? x.Length : -x.Length;
+ return _direction > 0 ?
+ CompareInternal(x!, y!) :
+ -CompareInternal(x!, y!);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int CompareInternal(byte[] x, byte[] y)
{
- int length = Math.Min(x.Length, y.Length);
- for (int i = 0; i < length; i++)
+ var length = Math.Min(x.Length, y.Length);
+ for (var i = 0; i < length; i++)
{
- int r = x[i].CompareTo(y[i]);
+ var r = x[i].CompareTo(y[i]);
if (r != 0) return r;
}
return x.Length.CompareTo(y.Length);
diff --git a/src/Neo/IO/ByteArrayEqualityComparer.cs b/src/Neo.IO/ByteArrayEqualityComparer.cs
similarity index 90%
rename from src/Neo/IO/ByteArrayEqualityComparer.cs
rename to src/Neo.IO/ByteArrayEqualityComparer.cs
index ffb5ad0e63..2b6f01491c 100644
--- a/src/Neo/IO/ByteArrayEqualityComparer.cs
+++ b/src/Neo.IO/ByteArrayEqualityComparer.cs
@@ -17,11 +17,11 @@ internal class ByteArrayEqualityComparer : IEqualityComparer
{
public static readonly ByteArrayEqualityComparer Default = new();
- public unsafe bool Equals(byte[] x, byte[] y)
+ public unsafe bool Equals(byte[]? x, byte[]? y)
{
if (ReferenceEquals(x, y)) return true;
if (x is null || y is null) return false;
- int len = x.Length;
+ var len = x.Length;
if (len != y.Length) return false;
if (len == 0) return true;
fixed (byte* xp = x, yp = y)
@@ -48,8 +48,8 @@ public int GetHashCode(byte[] obj)
{
unchecked
{
- int hash = 17;
- foreach (byte element in obj)
+ var hash = 17;
+ foreach (var element in obj)
hash = hash * 31 + element;
return hash;
}
diff --git a/src/Neo/IO/ISerializable.cs b/src/Neo.IO/ISerializable.cs
similarity index 100%
rename from src/Neo/IO/ISerializable.cs
rename to src/Neo.IO/ISerializable.cs
diff --git a/src/Neo/IO/MemoryReader.cs b/src/Neo.IO/MemoryReader.cs
similarity index 73%
rename from src/Neo/IO/MemoryReader.cs
rename to src/Neo.IO/MemoryReader.cs
index ece7cb56be..df8afbb3d3 100644
--- a/src/Neo/IO/MemoryReader.cs
+++ b/src/Neo.IO/MemoryReader.cs
@@ -17,29 +17,29 @@ namespace Neo.IO
{
public ref struct MemoryReader
{
- private readonly ReadOnlyMemory memory;
- private readonly ReadOnlySpan span;
- private int pos = 0;
+ private readonly ReadOnlyMemory _memory;
+ private readonly ReadOnlySpan _span;
+ private int _pos = 0;
- public readonly int Position => pos;
+ public readonly int Position => _pos;
public MemoryReader(ReadOnlyMemory memory)
{
- this.memory = memory;
- this.span = memory.Span;
+ _memory = memory;
+ _span = memory.Span;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private readonly void EnsurePosition(int move)
{
- if (pos + move > span.Length) throw new FormatException();
+ if (_pos + move > _span.Length) throw new FormatException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly byte Peek()
{
EnsurePosition(1);
- return span[pos];
+ return _span[_pos];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -57,7 +57,7 @@ public bool ReadBoolean()
public sbyte ReadSByte()
{
EnsurePosition(1);
- byte b = span[pos++];
+ var b = _span[_pos++];
return unchecked((sbyte)b);
}
@@ -65,15 +65,15 @@ public sbyte ReadSByte()
public byte ReadByte()
{
EnsurePosition(1);
- return span[pos++];
+ return _span[_pos++];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short ReadInt16()
{
EnsurePosition(sizeof(short));
- var result = BinaryPrimitives.ReadInt16LittleEndian(span[pos..]);
- pos += sizeof(short);
+ var result = BinaryPrimitives.ReadInt16LittleEndian(_span[_pos..]);
+ _pos += sizeof(short);
return result;
}
@@ -81,8 +81,8 @@ public short ReadInt16()
public short ReadInt16BigEndian()
{
EnsurePosition(sizeof(short));
- var result = BinaryPrimitives.ReadInt16BigEndian(span[pos..]);
- pos += sizeof(short);
+ var result = BinaryPrimitives.ReadInt16BigEndian(_span[_pos..]);
+ _pos += sizeof(short);
return result;
}
@@ -90,8 +90,8 @@ public short ReadInt16BigEndian()
public ushort ReadUInt16()
{
EnsurePosition(sizeof(ushort));
- var result = BinaryPrimitives.ReadUInt16LittleEndian(span[pos..]);
- pos += sizeof(ushort);
+ var result = BinaryPrimitives.ReadUInt16LittleEndian(_span[_pos..]);
+ _pos += sizeof(ushort);
return result;
}
@@ -99,8 +99,8 @@ public ushort ReadUInt16()
public ushort ReadUInt16BigEndian()
{
EnsurePosition(sizeof(ushort));
- var result = BinaryPrimitives.ReadUInt16BigEndian(span[pos..]);
- pos += sizeof(ushort);
+ var result = BinaryPrimitives.ReadUInt16BigEndian(_span[_pos..]);
+ _pos += sizeof(ushort);
return result;
}
@@ -108,8 +108,8 @@ public ushort ReadUInt16BigEndian()
public int ReadInt32()
{
EnsurePosition(sizeof(int));
- var result = BinaryPrimitives.ReadInt32LittleEndian(span[pos..]);
- pos += sizeof(int);
+ var result = BinaryPrimitives.ReadInt32LittleEndian(_span[_pos..]);
+ _pos += sizeof(int);
return result;
}
@@ -117,8 +117,8 @@ public int ReadInt32()
public int ReadInt32BigEndian()
{
EnsurePosition(sizeof(int));
- var result = BinaryPrimitives.ReadInt32BigEndian(span[pos..]);
- pos += sizeof(int);
+ var result = BinaryPrimitives.ReadInt32BigEndian(_span[_pos..]);
+ _pos += sizeof(int);
return result;
}
@@ -126,8 +126,8 @@ public int ReadInt32BigEndian()
public uint ReadUInt32()
{
EnsurePosition(sizeof(uint));
- var result = BinaryPrimitives.ReadUInt32LittleEndian(span[pos..]);
- pos += sizeof(uint);
+ var result = BinaryPrimitives.ReadUInt32LittleEndian(_span[_pos..]);
+ _pos += sizeof(uint);
return result;
}
@@ -135,8 +135,8 @@ public uint ReadUInt32()
public uint ReadUInt32BigEndian()
{
EnsurePosition(sizeof(uint));
- var result = BinaryPrimitives.ReadUInt32BigEndian(span[pos..]);
- pos += sizeof(uint);
+ var result = BinaryPrimitives.ReadUInt32BigEndian(_span[_pos..]);
+ _pos += sizeof(uint);
return result;
}
@@ -144,8 +144,8 @@ public uint ReadUInt32BigEndian()
public long ReadInt64()
{
EnsurePosition(sizeof(long));
- var result = BinaryPrimitives.ReadInt64LittleEndian(span[pos..]);
- pos += sizeof(long);
+ var result = BinaryPrimitives.ReadInt64LittleEndian(_span[_pos..]);
+ _pos += sizeof(long);
return result;
}
@@ -153,8 +153,8 @@ public long ReadInt64()
public long ReadInt64BigEndian()
{
EnsurePosition(sizeof(long));
- var result = BinaryPrimitives.ReadInt64BigEndian(span[pos..]);
- pos += sizeof(long);
+ var result = BinaryPrimitives.ReadInt64BigEndian(_span[_pos..]);
+ _pos += sizeof(long);
return result;
}
@@ -162,8 +162,8 @@ public long ReadInt64BigEndian()
public ulong ReadUInt64()
{
EnsurePosition(sizeof(ulong));
- var result = BinaryPrimitives.ReadUInt64LittleEndian(span[pos..]);
- pos += sizeof(ulong);
+ var result = BinaryPrimitives.ReadUInt64LittleEndian(_span[_pos..]);
+ _pos += sizeof(ulong);
return result;
}
@@ -171,16 +171,16 @@ public ulong ReadUInt64()
public ulong ReadUInt64BigEndian()
{
EnsurePosition(sizeof(ulong));
- var result = BinaryPrimitives.ReadUInt64BigEndian(span[pos..]);
- pos += sizeof(ulong);
+ var result = BinaryPrimitives.ReadUInt64BigEndian(_span[_pos..]);
+ _pos += sizeof(ulong);
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadVarInt(ulong max = ulong.MaxValue)
{
- byte b = ReadByte();
- ulong value = b switch
+ var b = ReadByte();
+ var value = b switch
{
0xfd => ReadUInt16(),
0xfe => ReadUInt32(),
@@ -195,24 +195,24 @@ public ulong ReadVarInt(ulong max = ulong.MaxValue)
public string ReadFixedString(int length)
{
EnsurePosition(length);
- int end = pos + length;
- int i = pos;
- while (i < end && span[i] != 0) i++;
- ReadOnlySpan data = span[pos..i];
+ var end = _pos + length;
+ var i = _pos;
+ while (i < end && _span[i] != 0) i++;
+ var data = _span[_pos..i];
for (; i < end; i++)
- if (span[i] != 0)
+ if (_span[i] != 0)
throw new FormatException();
- pos = end;
+ _pos = end;
return Utility.StrictUTF8.GetString(data);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadVarString(int max = 0x1000000)
{
- int length = (int)ReadVarInt((ulong)max);
+ var length = (int)ReadVarInt((ulong)max);
EnsurePosition(length);
- ReadOnlySpan data = span.Slice(pos, length);
- pos += length;
+ var data = _span.Slice(_pos, length);
+ _pos += length;
return Utility.StrictUTF8.GetString(data);
}
@@ -220,22 +220,20 @@ public string ReadVarString(int max = 0x1000000)
public ReadOnlyMemory ReadMemory(int count)
{
EnsurePosition(count);
- ReadOnlyMemory result = memory.Slice(pos, count);
- pos += count;
+ var result = _memory.Slice(_pos, count);
+ _pos += count;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ReadOnlyMemory ReadVarMemory(int max = 0x1000000)
- {
- return ReadMemory((int)ReadVarInt((ulong)max));
- }
+ public ReadOnlyMemory ReadVarMemory(int max = 0x1000000) =>
+ ReadMemory((int)ReadVarInt((ulong)max));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory ReadToEnd()
{
- ReadOnlyMemory result = memory[pos..];
- pos = memory.Length;
+ var result = _memory[_pos..];
+ _pos = _memory.Length;
return result;
}
}
diff --git a/src/Neo.IO/Neo.IO.csproj b/src/Neo.IO/Neo.IO.csproj
new file mode 100644
index 0000000000..05bc305a67
--- /dev/null
+++ b/src/Neo.IO/Neo.IO.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netstandard2.1;net7.0
+ true
+ enable
+ NEO;Blockchain;IO
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj
index 130ff2a570..75541f9091 100644
--- a/src/Neo/Neo.csproj
+++ b/src/Neo/Neo.csproj
@@ -18,6 +18,8 @@
+
+
diff --git a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
index fb3835e14d..16a0a95944 100644
--- a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs
@@ -10,6 +10,7 @@
// modifications are permitted.
using Neo.VM;
+using System;
using System.Collections.Generic;
namespace Neo.SmartContract
@@ -19,6 +20,7 @@ partial class ApplicationEngine
///
/// The prices of all the opcodes.
///
+ [Obsolete("You should use OpCodePriceTable")]
public static readonly IReadOnlyDictionary OpCodePrices = new Dictionary
{
[OpCode.PUSHINT8] = 1 << 0,
@@ -218,5 +220,20 @@ partial class ApplicationEngine
[OpCode.ISTYPE] = 1 << 1,
[OpCode.CONVERT] = 1 << 13,
};
+
+ public static readonly long[] OpCodePriceTable = new long[byte.MaxValue];
+
+ ///
+ /// Init OpCodePrices
+ ///
+ static ApplicationEngine()
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ foreach (var entry in OpCodePrices)
+#pragma warning restore CS0618 // Type or member is obsolete
+ {
+ OpCodePriceTable[(byte)entry.Key] = entry.Value;
+ }
+ }
}
}
diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs
index 8f30723d48..1331ff2608 100644
--- a/src/Neo/SmartContract/ApplicationEngine.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.cs
@@ -570,7 +570,7 @@ protected virtual void OnSysCall(InteropDescriptor descriptor)
protected override void PreExecuteInstruction(Instruction instruction)
{
Diagnostic?.PreExecuteInstruction(instruction);
- AddGas(ExecFeeFactor * OpCodePrices[instruction.OpCode]);
+ AddGas(ExecFeeFactor * OpCodePriceTable[(byte)instruction.OpCode]);
}
protected override void PostExecuteInstruction(Instruction instruction)
diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs
index 5045c74717..333ef77d7b 100644
--- a/src/Neo/SmartContract/Helper.cs
+++ b/src/Neo/SmartContract/Helper.cs
@@ -39,8 +39,8 @@ public static class Helper
///
/// The calculated cost.
public static long SignatureContractCost() =>
- ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * 2 +
- ApplicationEngine.OpCodePrices[OpCode.SYSCALL] +
+ ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * 2 +
+ ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] +
ApplicationEngine.CheckSigPrice;
///
@@ -51,12 +51,12 @@ public static long SignatureContractCost() =>
/// The calculated cost.
public static long MultiSignatureContractCost(int m, int n)
{
- long fee = ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * (m + n);
+ long fee = ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * (m + n);
using (ScriptBuilder sb = new())
- fee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(m).ToArray()[0]];
+ fee += ApplicationEngine.OpCodePriceTable[(byte)(OpCode)sb.EmitPush(m).ToArray()[0]];
using (ScriptBuilder sb = new())
- fee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(n).ToArray()[0]];
- fee += ApplicationEngine.OpCodePrices[OpCode.SYSCALL];
+ fee += ApplicationEngine.OpCodePriceTable[(byte)(OpCode)sb.EmitPush(n).ToArray()[0]];
+ fee += ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL];
fee += ApplicationEngine.CheckSigPrice * n;
return fee;
}
diff --git a/tests/Neo.UnitTests/IO/UT_ByteArrayComparer.cs b/tests/Neo.UnitTests/IO/UT_ByteArrayComparer.cs
index 5efba80cb3..19c3fafcd6 100644
--- a/tests/Neo.UnitTests/IO/UT_ByteArrayComparer.cs
+++ b/tests/Neo.UnitTests/IO/UT_ByteArrayComparer.cs
@@ -12,6 +12,7 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
+using System;
namespace Neo.UnitTests.IO
{
@@ -22,10 +23,23 @@ public class UT_ByteArrayComparer
public void TestCompare()
{
ByteArrayComparer comparer = ByteArrayComparer.Default;
- byte[] x = new byte[0], y = new byte[0];
+ byte[] x = null, y = null;
comparer.Compare(x, y).Should().Be(0);
+ x = new byte[] { 1, 2, 3, 4, 5 };
+ y = x;
+ comparer.Compare(x, y).Should().Be(0);
+ comparer.Compare(x, x).Should().Be(0);
+
+ y = null;
+ comparer.Compare(x, y).Should().Be(5);
+
+ y = x;
+ x = null;
+ comparer.Compare(x, y).Should().Be(-5);
+
x = new byte[] { 1 };
+ y = Array.Empty();
comparer.Compare(x, y).Should().Be(1);
y = x;
comparer.Compare(x, y).Should().Be(0);
diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
index faf3c1fde4..a263779282 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs
@@ -164,7 +164,7 @@ public void TestSignatureRedeemScriptFee()
byte[] verification = Contract.CreateSignatureRedeemScript(key.PublicKey);
byte[] invocation = new ScriptBuilder().EmitPush(UInt160.Zero).ToArray();
- var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePrices[OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice);
+ var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice);
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, null, settings: TestBlockchain.TheNeoSystem.Settings))
{
@@ -192,7 +192,7 @@ public void TestCreateMultiSigRedeemScriptFee()
byte[] verification = Contract.CreateMultiSigRedeemScript(2, publicKeys);
byte[] invocation = new ScriptBuilder().EmitPush(UInt160.Zero).EmitPush(UInt160.Zero).ToArray();
- long fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * (2 + 2) + ApplicationEngine.OpCodePrices[OpCode.PUSHINT8] * 2 + ApplicationEngine.OpCodePrices[OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice * 2);
+ long fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * (2 + 2) + ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHINT8] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice * 2);
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, null, settings: TestBlockchain.TheNeoSystem.Settings))
{
diff --git a/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs b/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs
index 13209618e3..c373930c6e 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_OpCodePrices.cs
@@ -23,7 +23,20 @@ public class UT_OpCodePrices
public void AllOpcodePriceAreSet()
{
foreach (OpCode opcode in Enum.GetValues(typeof(OpCode)))
- Assert.IsTrue(ApplicationEngine.OpCodePrices.ContainsKey(opcode), opcode.ToString());
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ Assert.IsTrue(ApplicationEngine.OpCodePrices.ContainsKey(opcode), opcode.ToString(), $"{opcode} without price");
+ Assert.AreEqual(ApplicationEngine.OpCodePrices[opcode], ApplicationEngine.OpCodePriceTable[(byte)opcode], $"{opcode} price mismatch");
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ if (opcode == OpCode.RET ||
+ opcode == OpCode.SYSCALL ||
+ opcode == OpCode.ABORT ||
+ opcode == OpCode.ABORTMSG)
+ continue;
+
+ Assert.AreNotEqual(0, ApplicationEngine.OpCodePriceTable[(byte)opcode], $"{opcode} without price");
+ }
}
}
}