From b2cbfc05aa2f8a517f029ec5cec51efbafbb4548 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Mon, 25 Nov 2024 04:55:08 -0500 Subject: [PATCH 01/13] `[Move]` Part-6 Classes into Different Library - `Neo.Extensions` (#3410) * Part-1 `Neo.IO` - move * Part-2 * Added `BigInteger` to `Neo.Extensions` * Found more `BigInteger` * Added `ByteArray` to `Neo.Extensions` * Added `DateTime` Extensions to `Neo.Extensions` * Added `HashSetExtensions`, `HashSetExtensions2`, `IpAddressExtensions`, `AssemblyExtensions`, `StringExtensdions` Deleted `Helper.cs` file * Added `ICollection`, `Memory`, `String`, `Unsafe` extensions * Adding `using` * dotnet format * Added more Extensions * Move some methods * Added Tests * Added `tests` from `Part-2` * Added `tests` for `PART-4` * Added `tests` for `PART-5` * Dotnet format * dotnet format * Renamed ByteExtensions2 to ByteExtensions * Apply suggestions from code review --------- Co-authored-by: Shargon Co-authored-by: Jimmy Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- src/Neo/Cryptography/Helper.cs | 2 +- src/Neo/Cryptography/MerkleTree.cs | 2 +- src/Neo/Extensions/ByteExtensions.cs | 66 ++++ .../Extensions/IO/BinaryReaderExtensions.cs | 79 +++++ .../Extensions/IO/BinaryWriterExtensions.cs | 137 ++++++++ .../Extensions/IO/ISerializableExtensions.cs | 33 ++ .../Extensions/IO/MemoryReaderExtensions.cs | 70 ++++ src/Neo/Extensions/MemoryExtensions.cs | 14 + src/Neo/Extensions/SpanExtensions.cs | 80 +++++ src/Neo/IO/Helper.cs | 329 ------------------ src/Neo/Network/P2P/Helper.cs | 2 +- .../Conditions/CalledByContractCondition.cs | 1 + .../Conditions/CalledByGroupCondition.cs | 1 + .../P2P/Payloads/Conditions/GroupCondition.cs | 1 + .../P2P/Payloads/Conditions/NotCondition.cs | 1 + .../Conditions/ScriptHashCondition.cs | 1 + src/Neo/Network/P2P/Payloads/Conflicts.cs | 1 + .../Network/P2P/Payloads/GetBlocksPayload.cs | 1 + src/Neo/Network/P2P/Payloads/Header.cs | 1 + src/Neo/Network/P2P/Payloads/WitnessRule.cs | 1 + src/Neo/Network/P2P/RemoteNode.cs | 1 + src/Neo/Persistence/SnapshotCache.cs | 2 +- src/Neo/SmartContract/ApplicationEngine.cs | 1 + src/Neo/SmartContract/BinarySerializer.cs | 1 + src/Neo/SmartContract/ContractState.cs | 2 +- .../SmartContract/Manifest/ContractGroup.cs | 2 +- .../Manifest/ContractPermission.cs | 2 +- .../Manifest/ContractPermissionDescriptor.cs | 2 +- .../Native/ContractManagement.cs | 2 +- src/Neo/SmartContract/Native/FungibleToken.cs | 2 +- .../SmartContract/Native/HashIndexState.cs | 2 +- .../SmartContract/Native/OracleContract.cs | 2 +- src/Neo/SmartContract/Native/OracleRequest.cs | 2 +- .../SmartContract/Native/RoleManagement.cs | 2 +- src/Neo/SmartContract/NotifyEventArgs.cs | 2 +- src/Neo/VM/Helper.cs | 1 + .../ApplicationLogs/Store/LogStorageStore.cs | 2 +- .../DBFTPlugin/Consensus/ConsensusContext.cs | 1 + .../DBFTPlugin/Messages/PrepareResponse.cs | 1 + .../MPTTrie/Cryptography/MPTTrie/Cache.cs | 2 +- .../MPTTrie/Cryptography/MPTTrie/Node.Hash.cs | 1 + src/Plugins/RpcServer/RpcServer.Node.cs | 2 +- src/Plugins/RpcServer/RpcServer.Wallet.cs | 2 +- src/Plugins/SQLiteWallet/SQLiteWallet.cs | 2 +- src/Plugins/StateService/Network/StateRoot.cs | 1 + src/Plugins/StateService/StatePlugin.cs | 2 +- .../StateService/Storage/StateSnapshot.cs | 2 +- src/Plugins/StorageDumper/StorageDumper.cs | 2 +- .../Trackers/NEP-11/Nep11BalanceKey.cs | 1 + .../Trackers/NEP-11/Nep11TransferKey.cs | 1 + .../Trackers/NEP-17/Nep17BalanceKey.cs | 1 + .../TokensTracker/Trackers/TokenBalance.cs | 1 + .../TokensTracker/Trackers/TokenTransfer.cs | 1 + .../Trackers/TokenTransferKey.cs | 1 + .../TokensTracker/Trackers/TrackerBase.cs | 1 + .../UT_StringExtensions.cs | 151 ++++++++ tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 1 + .../UT_LogReader.cs | 1 + .../UT_RpcServer.Blockchain.cs | 1 + .../UT_RpcServer.Node.cs | 1 + .../UT_RpcServer.SmartContract.cs | 1 + .../UT_RpcServer.Wallet.cs | 1 + .../Cryptography/UT_MerkleTree.cs | 1 + .../Extensions/NativeContractExtensions.cs | 1 + .../Neo.UnitTests/IO/Caching/UT_DataCache.cs | 1 + tests/Neo.UnitTests/IO/UT_IOHelper.cs | 101 +++--- .../P2P/Capabilities/UT_FullNodeCapability.cs | 1 + .../P2P/Capabilities/UT_ServerCapability.cs | 1 + .../Network/P2P/Payloads/UT_AddrPayload.cs | 1 + .../Network/P2P/Payloads/UT_Conflicts.cs | 1 + .../P2P/Payloads/UT_ExtensiblePayload.cs | 1 + .../P2P/Payloads/UT_FilterAddPayload.cs | 1 + .../P2P/Payloads/UT_FilterLoadPayload.cs | 1 + .../P2P/Payloads/UT_GetBlockByIndexPayload.cs | 1 + .../P2P/Payloads/UT_GetBlocksPayload.cs | 1 + .../Network/P2P/Payloads/UT_HeadersPayload.cs | 1 + .../P2P/Payloads/UT_HighPriorityAttribute.cs | 1 + .../Network/P2P/Payloads/UT_InvPayload.cs | 1 + .../P2P/Payloads/UT_MerkleBlockPayload.cs | 1 + .../Network/P2P/Payloads/UT_NotValidBefore.cs | 1 + .../Network/P2P/Payloads/UT_Transaction.cs | 4 +- tests/Neo.UnitTests/Network/P2P/UT_Message.cs | 1 + .../Network/P2P/UT_RemoteNode.cs | 1 + .../Persistence/UT_MemoryStore.cs | 1 + .../SmartContract/Native/UT_GasToken.cs | 1 + .../SmartContract/Native/UT_PolicyContract.cs | 1 + .../SmartContract/UT_MethodToken.cs | 1 + .../Neo.UnitTests/SmartContract/UT_NefFile.cs | 1 + .../SmartContract/UT_Syscalls.cs | 1 + tests/Neo.UnitTests/TestUtils.cs | 1 + tests/Neo.UnitTests/UT_Helper.cs | 72 ++++ .../Wallets/UT_Wallets_Helper.cs | 1 + 92 files changed, 844 insertions(+), 395 deletions(-) create mode 100644 src/Neo/Extensions/ByteExtensions.cs create mode 100644 src/Neo/Extensions/IO/BinaryReaderExtensions.cs create mode 100644 src/Neo/Extensions/IO/BinaryWriterExtensions.cs create mode 100644 src/Neo/Extensions/IO/ISerializableExtensions.cs create mode 100644 src/Neo/Extensions/IO/MemoryReaderExtensions.cs create mode 100644 src/Neo/Extensions/SpanExtensions.cs delete mode 100644 src/Neo/IO/Helper.cs diff --git a/src/Neo/Cryptography/Helper.cs b/src/Neo/Cryptography/Helper.cs index f398612e61..3a89ecba75 100644 --- a/src/Neo/Cryptography/Helper.cs +++ b/src/Neo/Cryptography/Helper.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Wallets; using Org.BouncyCastle.Crypto.Digests; diff --git a/src/Neo/Cryptography/MerkleTree.cs b/src/Neo/Cryptography/MerkleTree.cs index ed25171ef8..09afa29277 100644 --- a/src/Neo/Cryptography/MerkleTree.cs +++ b/src/Neo/Cryptography/MerkleTree.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using System; using System.Collections; using System.Collections.Generic; diff --git a/src/Neo/Extensions/ByteExtensions.cs b/src/Neo/Extensions/ByteExtensions.cs new file mode 100644 index 0000000000..7bacd33f42 --- /dev/null +++ b/src/Neo/Extensions/ByteExtensions.cs @@ -0,0 +1,66 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ByteExtensions.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.IO; +using System; + +namespace Neo.Extensions +{ + public static class ByteExtensions + { + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this byte[] data) + { + return data.AsSpan().CompressLz4(); + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this byte[] data, int maxOutput) + { + return data.AsSpan().DecompressLz4(maxOutput); + } + + /// + /// Converts a byte array to an object. + /// + /// The type to convert to. + /// The byte array to be converted. + /// The offset into the byte array from which to begin using data. + /// The converted object. + public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable, new() + { + MemoryReader reader = new(value.AsMemory(start)); + return reader.ReadSerializable(); + } + + /// + /// Converts a byte array to an array. + /// + /// The type of the array element. + /// The byte array to be converted. + /// The maximum number of elements contained in the converted array. + /// The converted array. + public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable, new() + { + MemoryReader reader = new(value); + return reader.ReadSerializableArray(max); + } + } +} diff --git a/src/Neo/Extensions/IO/BinaryReaderExtensions.cs b/src/Neo/Extensions/IO/BinaryReaderExtensions.cs new file mode 100644 index 0000000000..f3448d96e1 --- /dev/null +++ b/src/Neo/Extensions/IO/BinaryReaderExtensions.cs @@ -0,0 +1,79 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// BinaryReaderExtensions.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; +using System.IO; + +namespace Neo.Extensions +{ + public static class BinaryReaderExtensions + { + /// + /// Reads a byte array of the specified size from a . + /// + /// The for reading data. + /// The size of the byte array. + /// The byte array read from the . + public static byte[] ReadFixedBytes(this BinaryReader reader, int size) + { + var index = 0; + var data = new byte[size]; + + while (size > 0) + { + var bytesRead = reader.Read(data, index, size); + + if (bytesRead <= 0) + { + throw new FormatException(); + } + + size -= bytesRead; + index += bytesRead; + } + + return data; + } + + /// + /// Reads a byte array from a . + /// + /// The for reading data. + /// The maximum size of the byte array. + /// The byte array read from the . + public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x1000000) + { + return reader.ReadFixedBytes((int)reader.ReadVarInt((ulong)max)); + } + + /// + /// Reads an integer from a . + /// + /// The for reading data. + /// The maximum value of the integer. + /// The integer read from the . + public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) + { + var fb = reader.ReadByte(); + ulong value; + if (fb == 0xFD) + value = reader.ReadUInt16(); + else if (fb == 0xFE) + value = reader.ReadUInt32(); + else if (fb == 0xFF) + value = reader.ReadUInt64(); + else + value = fb; + if (value > max) throw new FormatException(); + return value; + } + } +} diff --git a/src/Neo/Extensions/IO/BinaryWriterExtensions.cs b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs new file mode 100644 index 0000000000..665eae1a69 --- /dev/null +++ b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs @@ -0,0 +1,137 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// BinaryWriterExtensions.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.IO; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Neo.Extensions +{ + public static class BinaryWriterExtensions + { + /// + /// Writes an object into a . + /// + /// The for writing data. + /// The object to be written. + public static void Write(this BinaryWriter writer, ISerializable value) + { + value.Serialize(writer); + } + + /// + /// Writes an array into a . + /// + /// The type of the array element. + /// The for writing data. + /// The array to be written. + public static void Write(this BinaryWriter writer, IReadOnlyCollection value) + where T : ISerializable + { + writer.WriteVarInt(value.Count); + foreach (T item in value) + { + item.Serialize(writer); + } + } + + /// + /// Writes a into a . + /// + /// The for writing data. + /// The to be written. + /// The fixed size of the . + public static void WriteFixedString(this BinaryWriter writer, string value, int length) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + if (value.Length > length) + throw new ArgumentException(null, nameof(value)); + var bytes = Utility.StrictUTF8.GetBytes(value); + if (bytes.Length > length) + throw new ArgumentException(null, nameof(value)); + writer.Write(bytes); + if (bytes.Length < length) + writer.Write(stackalloc byte[length - bytes.Length]); + } + + /// + /// Writes an array into a . + /// + /// The type of the array element. + /// The for writing data. + /// The array to be written. + public static void WriteNullableArray(this BinaryWriter writer, T[] value) + where T : class, ISerializable + { + writer.WriteVarInt(value.Length); + foreach (var item in value) + { + var isNull = item is null; + writer.Write(!isNull); + if (isNull) continue; + item.Serialize(writer); + } + } + + /// + /// Writes a byte array into a . + /// + /// The for writing data. + /// The byte array to be written. + public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan value) + { + writer.WriteVarInt(value.Length); + writer.Write(value); + } + + /// + /// Writes an integer into a . + /// + /// The for writing data. + /// The integer to be written. + public static void WriteVarInt(this BinaryWriter writer, long value) + { + if (value < 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (value < 0xFD) + { + writer.Write((byte)value); + } + else if (value <= 0xFFFF) + { + writer.Write((byte)0xFD); + writer.Write((ushort)value); + } + else if (value <= 0xFFFFFFFF) + { + writer.Write((byte)0xFE); + writer.Write((uint)value); + } + else + { + writer.Write((byte)0xFF); + writer.Write(value); + } + } + + /// + /// Writes a into a . + /// + /// The for writing data. + /// The to be written. + public static void WriteVarString(this BinaryWriter writer, string value) + { + writer.WriteVarBytes(Utility.StrictUTF8.GetBytes(value)); + } + } +} diff --git a/src/Neo/Extensions/IO/ISerializableExtensions.cs b/src/Neo/Extensions/IO/ISerializableExtensions.cs new file mode 100644 index 0000000000..67b4f39519 --- /dev/null +++ b/src/Neo/Extensions/IO/ISerializableExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ISerializableExtensions.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.IO; +using System.IO; + +namespace Neo.Extensions +{ + public static class ISerializableExtensions + { + /// + /// Converts an object to a byte array. + /// + /// The object to be converted. + /// The converted byte array. + public static byte[] ToArray(this ISerializable value) + { + using MemoryStream ms = new(); + using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); + value.Serialize(writer); + writer.Flush(); + return ms.ToArray(); + } + } +} diff --git a/src/Neo/Extensions/IO/MemoryReaderExtensions.cs b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs new file mode 100644 index 0000000000..5591724b80 --- /dev/null +++ b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs @@ -0,0 +1,70 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// MemoryReaderExtensions.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.IO; + +namespace Neo.Extensions +{ + /// + /// A helper class for serialization of NEO objects. + /// + public static class MemoryReaderExtensions + { + /// + /// Reads an array from a . + /// + /// The type of the array element. + /// The for reading data. + /// The maximum number of elements in the array. + /// The array read from the . + public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) + where T : class, ISerializable, new() + { + var array = new T[reader.ReadVarInt((ulong)max)]; + for (var i = 0; i < array.Length; i++) + array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null; + return array; + } + + /// + /// Reads an object from a . + /// + /// The type of the object. + /// The for reading data. + /// The object read from the . + public static T ReadSerializable(this ref MemoryReader reader) + where T : ISerializable, new() + { + T obj = new(); + obj.Deserialize(ref reader); + return obj; + } + + /// + /// Reads an array from a . + /// + /// The type of the array element. + /// The for reading data. + /// The maximum number of elements in the array. + /// The array read from the . + public static T[] ReadSerializableArray(this ref MemoryReader reader, int max = 0x1000000) + where T : ISerializable, new() + { + var array = new T[reader.ReadVarInt((ulong)max)]; + for (var i = 0; i < array.Length; i++) + { + array[i] = new T(); + array[i].Deserialize(ref reader); + } + return array; + } + } +} diff --git a/src/Neo/Extensions/MemoryExtensions.cs b/src/Neo/Extensions/MemoryExtensions.cs index f6576387de..c1331a5998 100644 --- a/src/Neo/Extensions/MemoryExtensions.cs +++ b/src/Neo/Extensions/MemoryExtensions.cs @@ -17,6 +17,20 @@ namespace Neo.Extensions { public static class MemoryExtensions { + /// + /// Converts a byte array to an array. + /// + /// The type of the array element. + /// The byte array to be converted. + /// The maximum number of elements contained in the converted array. + /// The converted array. + public static T[] AsSerializableArray(this ReadOnlyMemory value, int max = 0x1000000) where T : ISerializable, new() + { + if (value.IsEmpty) throw new FormatException(); + MemoryReader reader = new(value); + return reader.ReadSerializableArray(max); + } + /// /// Converts a byte array to an object. /// diff --git a/src/Neo/Extensions/SpanExtensions.cs b/src/Neo/Extensions/SpanExtensions.cs new file mode 100644 index 0000000000..3bc650cbb8 --- /dev/null +++ b/src/Neo/Extensions/SpanExtensions.cs @@ -0,0 +1,80 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// SpanExtensions.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 K4os.Compression.LZ4; +using System; +using System.Buffers.Binary; + +namespace Neo.Extensions +{ + public static class SpanExtensions + { + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) + { + var maxLength = LZ4Codec.MaximumOutputSize(data.Length); + var buffer = new byte[sizeof(uint) + maxLength]; + BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); + var length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); + return buffer.AsMemory(0, sizeof(uint) + length); + } + + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this Span data) + { + var maxLength = LZ4Codec.MaximumOutputSize(data.Length); + var buffer = new byte[sizeof(uint) + maxLength]; + BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); + var length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); + return buffer.AsMemory(0, sizeof(uint) + length); + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) + { + var length = BinaryPrimitives.ReadInt32LittleEndian(data); + if (length < 0 || length > maxOutput) throw new FormatException(); + var result = new byte[length]; + if (LZ4Codec.Decode(data[4..], result) != length) + throw new FormatException(); + return result; + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this Span data, int maxOutput) + { + var length = BinaryPrimitives.ReadInt32LittleEndian(data); + if (length < 0 || length > maxOutput) throw new FormatException(); + var result = new byte[length]; + if (LZ4Codec.Decode(data[4..], result) != length) + throw new FormatException(); + return result; + } + } +} diff --git a/src/Neo/IO/Helper.cs b/src/Neo/IO/Helper.cs deleted file mode 100644 index d0e5a00ec9..0000000000 --- a/src/Neo/IO/Helper.cs +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (C) 2015-2024 The Neo Project. -// -// Helper.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 K4os.Compression.LZ4; -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; - -namespace Neo.IO -{ - /// - /// A helper class for serialization of NEO objects. - /// - public static class Helper - { - /// - /// Converts a byte array to an object. - /// - /// The type to convert to. - /// The byte array to be converted. - /// The offset into the byte array from which to begin using data. - /// The converted object. - public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable, new() - { - MemoryReader reader = new(value.AsMemory(start)); - return reader.ReadSerializable(); - } - - /// - /// Converts a byte array to an array. - /// - /// The type of the array element. - /// The byte array to be converted. - /// The maximum number of elements contained in the converted array. - /// The converted array. - public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable, new() - { - MemoryReader reader = new(value); - return reader.ReadSerializableArray(max); - } - - /// - /// Converts a byte array to an array. - /// - /// The type of the array element. - /// The byte array to be converted. - /// The maximum number of elements contained in the converted array. - /// The converted array. - public static T[] AsSerializableArray(this ReadOnlyMemory value, int max = 0x1000000) where T : ISerializable, new() - { - if (value.IsEmpty) throw new FormatException(); - MemoryReader reader = new(value); - return reader.ReadSerializableArray(max); - } - - /// - /// Compresses the specified data using the LZ4 algorithm. - /// - /// The data to be compressed. - /// The compressed data. - public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) - { - int maxLength = LZ4Codec.MaximumOutputSize(data.Length); - byte[] buffer = new byte[sizeof(uint) + maxLength]; - BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); - int length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); - return buffer.AsMemory(0, sizeof(uint) + length); - } - - /// - /// Decompresses the specified data using the LZ4 algorithm. - /// - /// The compressed data. - /// The maximum data size after decompression. - /// The original data. - public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) - { - int length = BinaryPrimitives.ReadInt32LittleEndian(data); - if (length < 0 || length > maxOutput) throw new FormatException(); - byte[] result = new byte[length]; - if (LZ4Codec.Decode(data[4..], result) != length) - throw new FormatException(); - return result; - } - - /// - /// Reads a byte array of the specified size from a . - /// - /// The for reading data. - /// The size of the byte array. - /// The byte array read from the . - public static byte[] ReadFixedBytes(this BinaryReader reader, int size) - { - var index = 0; - var data = new byte[size]; - - while (size > 0) - { - var bytesRead = reader.Read(data, index, size); - - if (bytesRead <= 0) - { - throw new FormatException(); - } - - size -= bytesRead; - index += bytesRead; - } - - return data; - } - - /// - /// Reads an array from a . - /// - /// The type of the array element. - /// The for reading data. - /// The maximum number of elements in the array. - /// The array read from the . - public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) where T : class, ISerializable, new() - { - T[] array = new T[reader.ReadVarInt((ulong)max)]; - for (int i = 0; i < array.Length; i++) - array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null; - return array; - } - - /// - /// Reads an object from a . - /// - /// The type of the object. - /// The for reading data. - /// The object read from the . - public static T ReadSerializable(this ref MemoryReader reader) where T : ISerializable, new() - { - T obj = new(); - obj.Deserialize(ref reader); - return obj; - } - - /// - /// Reads an array from a . - /// - /// The type of the array element. - /// The for reading data. - /// The maximum number of elements in the array. - /// The array read from the . - public static T[] ReadSerializableArray(this ref MemoryReader reader, int max = 0x1000000) where T : ISerializable, new() - { - T[] array = new T[reader.ReadVarInt((ulong)max)]; - for (int i = 0; i < array.Length; i++) - { - array[i] = new T(); - array[i].Deserialize(ref reader); - } - return array; - } - - /// - /// Reads a byte array from a . - /// - /// The for reading data. - /// The maximum size of the byte array. - /// The byte array read from the . - public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x1000000) - { - return reader.ReadFixedBytes((int)reader.ReadVarInt((ulong)max)); - } - - /// - /// Reads an integer from a . - /// - /// The for reading data. - /// The maximum value of the integer. - /// The integer read from the . - public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) - { - byte fb = reader.ReadByte(); - ulong value; - if (fb == 0xFD) - value = reader.ReadUInt16(); - else if (fb == 0xFE) - value = reader.ReadUInt32(); - else if (fb == 0xFF) - value = reader.ReadUInt64(); - else - value = fb; - if (value > max) throw new FormatException(); - return value; - } - - /// - /// Converts an object to a byte array. - /// - /// The object to be converted. - /// The converted byte array. - public static byte[] ToArray(this ISerializable value) - { - using MemoryStream ms = new(); - using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); - value.Serialize(writer); - writer.Flush(); - return ms.ToArray(); - } - - /// - /// Writes an object into a . - /// - /// The for writing data. - /// The object to be written. - public static void Write(this BinaryWriter writer, ISerializable value) - { - value.Serialize(writer); - } - - /// - /// Writes an array into a . - /// - /// The type of the array element. - /// The for writing data. - /// The array to be written. - public static void Write(this BinaryWriter writer, IReadOnlyCollection value) where T : ISerializable - { - writer.WriteVarInt(value.Count); - foreach (T item in value) - { - item.Serialize(writer); - } - } - - /// - /// Writes a into a . - /// - /// The for writing data. - /// The to be written. - /// The fixed size of the . - public static void WriteFixedString(this BinaryWriter writer, string value, int length) - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - if (value.Length > length) - throw new ArgumentException(null, nameof(value)); - byte[] bytes = Utility.StrictUTF8.GetBytes(value); - if (bytes.Length > length) - throw new ArgumentException(null, nameof(value)); - writer.Write(bytes); - if (bytes.Length < length) - writer.Write(stackalloc byte[length - bytes.Length]); - } - - /// - /// Writes an array into a . - /// - /// The type of the array element. - /// The for writing data. - /// The array to be written. - public static void WriteNullableArray(this BinaryWriter writer, T[] value) where T : class, ISerializable - { - writer.WriteVarInt(value.Length); - foreach (var item in value) - { - bool isNull = item is null; - writer.Write(!isNull); - if (isNull) continue; - item.Serialize(writer); - } - } - - /// - /// Writes a byte array into a . - /// - /// The for writing data. - /// The byte array to be written. - public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan value) - { - writer.WriteVarInt(value.Length); - writer.Write(value); - } - - /// - /// Writes an integer into a . - /// - /// The for writing data. - /// The integer to be written. - public static void WriteVarInt(this BinaryWriter writer, long value) - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (value < 0xFD) - { - writer.Write((byte)value); - } - else if (value <= 0xFFFF) - { - writer.Write((byte)0xFD); - writer.Write((ushort)value); - } - else if (value <= 0xFFFFFFFF) - { - writer.Write((byte)0xFE); - writer.Write((uint)value); - } - else - { - writer.Write((byte)0xFF); - writer.Write(value); - } - } - - /// - /// Writes a into a . - /// - /// The for writing data. - /// The to be written. - public static void WriteVarString(this BinaryWriter writer, string value) - { - writer.WriteVarBytes(Utility.StrictUTF8.GetBytes(value)); - } - } -} diff --git a/src/Neo/Network/P2P/Helper.cs b/src/Neo/Network/P2P/Helper.cs index f171a7b0a3..ffbbc6a702 100644 --- a/src/Neo/Network/P2P/Helper.cs +++ b/src/Neo/Network/P2P/Helper.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs index 4ce1e2dc1f..9cccec95cc 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index ac233a156a..d4a3b74800 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index 18e94fbc40..6e76309432 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs index fd813c7230..c8fd2baf69 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs index a9cf1de0e9..cde011c116 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conflicts.cs b/src/Neo/Network/P2P/Payloads/Conflicts.cs index 082de2014d..a876468828 100644 --- a/src/Neo/Network/P2P/Payloads/Conflicts.cs +++ b/src/Neo/Network/P2P/Payloads/Conflicts.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Persistence; diff --git a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs index 254287135f..aeb6212f23 100644 --- a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs +++ b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/Header.cs b/src/Neo/Network/P2P/Payloads/Header.cs index 9e1d77fb8a..8b3eda0e28 100644 --- a/src/Neo/Network/P2P/Payloads/Header.cs +++ b/src/Neo/Network/P2P/Payloads/Header.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index 515d234666..ddc1d108cf 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads.Conditions; diff --git a/src/Neo/Network/P2P/RemoteNode.cs b/src/Neo/Network/P2P/RemoteNode.cs index a4bf0cc089..e570afeb13 100644 --- a/src/Neo/Network/P2P/RemoteNode.cs +++ b/src/Neo/Network/P2P/RemoteNode.cs @@ -13,6 +13,7 @@ using Akka.Configuration; using Akka.IO; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.IO.Actors; using Neo.IO.Caching; diff --git a/src/Neo/Persistence/SnapshotCache.cs b/src/Neo/Persistence/SnapshotCache.cs index 6731e5342f..07afdccfab 100644 --- a/src/Neo/Persistence/SnapshotCache.cs +++ b/src/Neo/Persistence/SnapshotCache.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using System; using System.Collections.Generic; diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index 7808baae5e..f8f2332b4e 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/src/Neo/SmartContract/BinarySerializer.cs b/src/Neo/SmartContract/BinarySerializer.cs index b77a998d6e..46b2a644a1 100644 --- a/src/Neo/SmartContract/BinarySerializer.cs +++ b/src/Neo/SmartContract/BinarySerializer.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index cd065cb8c3..8acb6504a8 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract.Manifest; using Neo.VM; diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index 8796c0f07a..3b8dc8ef20 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -11,7 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index cf4d5078c5..1888963672 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs index d950d25c62..6cebaa99ee 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM.Types; using System; diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index 6fefd2d05f..9fb66a063c 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -11,7 +11,7 @@ #pragma warning disable IDE0051 -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract.Iterators; diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index 21de0a5644..ab6ed8f9c0 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.SmartContract.Manifest; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index 4ab7a991cf..16c051e4aa 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 54156a0029..c142b98ce1 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -12,7 +12,7 @@ #pragma warning disable IDE0051 using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.VM; diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index cd4962b1cb..746fada4e5 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.VM; using Neo.VM.Types; using Array = Neo.VM.Types.Array; diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index e57f3f3e83..b11eeaf0dd 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 8d8542bca9..2fe37affb3 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index fd95467da1..0a9a106e1f 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs index 147a80034b..433359e261 100644 --- a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs +++ b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.Plugins.ApplicationLogs.Store.States; using Neo.SmartContract; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs index d6a4340544..ef26fc4130 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs @@ -11,6 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs index b4608ff9af..3c49693c69 100644 --- a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs +++ b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Plugins.DBFTPlugin.Types; using System.IO; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs index d8baef8529..e832e8994b 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using System.Collections.Generic; using System.IO; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs index e0190dd146..dc58535fb3 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/RpcServer/RpcServer.Node.cs b/src/Plugins/RpcServer/RpcServer.Node.cs index 23c731d01e..cfc66e932a 100644 --- a/src/Plugins/RpcServer/RpcServer.Node.cs +++ b/src/Plugins/RpcServer/RpcServer.Node.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Akka.Actor; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P; diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs index 25a7333aac..61dd03675b 100644 --- a/src/Plugins/RpcServer/RpcServer.Wallet.cs +++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Akka.Actor; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/src/Plugins/SQLiteWallet/SQLiteWallet.cs b/src/Plugins/SQLiteWallet/SQLiteWallet.cs index 7b270ec81b..d7d4fab9d6 100644 --- a/src/Plugins/SQLiteWallet/SQLiteWallet.cs +++ b/src/Plugins/SQLiteWallet/SQLiteWallet.cs @@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore; using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using Neo.Wallets.NEP6; using System.Buffers.Binary; diff --git a/src/Plugins/StateService/Network/StateRoot.cs b/src/Plugins/StateService/Network/StateRoot.cs index 5b4e8610f2..7b3b7e9706 100644 --- a/src/Plugins/StateService/Network/StateRoot.cs +++ b/src/Plugins/StateService/Network/StateRoot.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P; diff --git a/src/Plugins/StateService/StatePlugin.cs b/src/Plugins/StateService/StatePlugin.cs index 03dcc55aac..a514f22ce7 100644 --- a/src/Plugins/StateService/StatePlugin.cs +++ b/src/Plugins/StateService/StatePlugin.cs @@ -12,8 +12,8 @@ using Akka.Actor; using Neo.ConsoleService; using Neo.Cryptography.MPTTrie; +using Neo.Extensions; using Neo.IEventHandlers; -using Neo.IO; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/StateService/Storage/StateSnapshot.cs b/src/Plugins/StateService/Storage/StateSnapshot.cs index 70ec006227..6dc1b323fd 100644 --- a/src/Plugins/StateService/Storage/StateSnapshot.cs +++ b/src/Plugins/StateService/Storage/StateSnapshot.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.MPTTrie; -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.Plugins.StateService.Network; using System; diff --git a/src/Plugins/StorageDumper/StorageDumper.cs b/src/Plugins/StorageDumper/StorageDumper.cs index 6f5498b3a2..184b6f61ac 100644 --- a/src/Plugins/StorageDumper/StorageDumper.cs +++ b/src/Plugins/StorageDumper/StorageDumper.cs @@ -10,8 +10,8 @@ // modifications are permitted. using Neo.ConsoleService; +using Neo.Extensions; using Neo.IEventHandlers; -using Neo.IO; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs index 1f375f33d9..2965985653 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM.Types; using System; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs index 5c999e8e00..9248267785 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM.Types; using System; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs index bbceabec2b..817d789e5c 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/TokensTracker/Trackers/TokenBalance.cs b/src/Plugins/TokensTracker/Trackers/TokenBalance.cs index f54a7c9856..a171fa40d7 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenBalance.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenBalance.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.IO; using System.Numerics; diff --git a/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs b/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs index 0a221850fc..9bb389b516 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.IO; using System.Numerics; diff --git a/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs b/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs index 252eb20af0..3c59131749 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.Buffers.Binary; diff --git a/src/Plugins/TokensTracker/Trackers/TrackerBase.cs b/src/Plugins/TokensTracker/Trackers/TrackerBase.cs index 471362b019..40009e6d85 100644 --- a/src/Plugins/TokensTracker/Trackers/TrackerBase.cs +++ b/src/Plugins/TokensTracker/Trackers/TrackerBase.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.Extensions.Tests/UT_StringExtensions.cs b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs index 6e823d2493..05e5388dfa 100644 --- a/tests/Neo.Extensions.Tests/UT_StringExtensions.cs +++ b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs @@ -42,5 +42,156 @@ public void TestGetVarSizeString() int result = "AA".GetVarSize(); Assert.AreEqual(3, result); } + + [TestMethod] + public void TestGetVarSizeInt() + { + for (int i = 0; i < 3; i++) + { + if (i == 0) + { + int result = UnsafeData.GetVarSize(1); + Assert.AreEqual(1, result); + } + else if (i == 1) + { + int result = UnsafeData.GetVarSize(0xFFFF); + Assert.AreEqual(3, result); + } + else + { + int result = UnsafeData.GetVarSize(0xFFFFFF); + Assert.AreEqual(5, result); + } + } + } + + [TestMethod] + public void TestGetVarSizeGeneric() + { + for (int i = 0; i < 9; i++) + { + if (i == 0) + { + int result = new UInt160[] { UInt160.Zero }.GetVarSize(); + Assert.AreEqual(21, result); + } + else if (i == 1)//sbyte + { + List initList = new() + { + TestEnum0.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(2, result); + } + else if (i == 2)//byte + { + List initList = new() + { + TestEnum1.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(2, result); + } + else if (i == 3)//short + { + List initList = new() + { + TestEnum2.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(3, result); + } + else if (i == 4)//ushort + { + List initList = new() + { + TestEnum3.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(3, result); + } + else if (i == 5)//int + { + List initList = new() + { + TestEnum4.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + else if (i == 6)//uint + { + List initList = new() + { + TestEnum5.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + else if (i == 7)//long + { + List initList = new() + { + TestEnum6.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(9, result); + } + else if (i == 8) + { + List initList = new() + { + 1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + } + } + + enum TestEnum0 : sbyte + { + case1 = 1, case2 = 2 + } + + enum TestEnum1 : byte + { + case1 = 1, case2 = 2 + } + + enum TestEnum2 : short + { + case1 = 1, case2 = 2 + } + + enum TestEnum3 : ushort + { + case1 = 1, case2 = 2 + } + + enum TestEnum4 : int + { + case1 = 1, case2 = 2 + } + + enum TestEnum5 : uint + { + case1 = 1, case2 = 2 + } + + enum TestEnum6 : long + { + case1 = 1, case2 = 2 + } } } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index b87960e76d..e0c4751bac 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Moq.Protected; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs b/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs index f7e2e2bdad..59671cd43b 100644 --- a/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs +++ b/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs @@ -13,6 +13,7 @@ using Akka.Util; using Microsoft.AspNetCore.Authorization; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs index b04b5e33d4..4a42d084d1 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs @@ -14,6 +14,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs index 042bde0d30..c4ab013021 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs @@ -12,6 +12,7 @@ using Akka.Actor; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P; diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.SmartContract.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.SmartContract.cs index 5f2ad3c18f..3b204cc53f 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.SmartContract.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.SmartContract.cs @@ -14,6 +14,7 @@ using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs index 801938903a..ad35975352 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs b/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs index f8a6b19b34..edcea4dd75 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using System; using System.Collections; diff --git a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs index c205a7e4bd..10c0f64019 100644 --- a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs @@ -10,6 +10,7 @@ // modifications are permitted. using FluentAssertions; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs b/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs index 224b1cc3f6..3c5e8e6e7d 100644 --- a/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs +++ b/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index d9d753e292..514a8daaf5 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -31,7 +31,7 @@ public void TestAsSerializableGeneric() 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00 }; - UInt160 result = Neo.IO.Helper.AsSerializable(caseArray); + UInt160 result = caseArray.AsSerializable(); Assert.AreEqual(UInt160.Zero, result); } @@ -44,7 +44,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - byte[] result = Neo.IO.Helper.ReadFixedBytes(reader, 3); + byte[] result = reader.ReadFixedBytes(3); Assert.AreEqual("010203", result.ToHexString()); Assert.AreEqual(3, reader.BaseStream.Position); @@ -54,7 +54,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - byte[] result = Neo.IO.Helper.ReadFixedBytes(reader, 4); + byte[] result = reader.ReadFixedBytes(4); Assert.AreEqual("01020304", result.ToHexString()); Assert.AreEqual(4, reader.BaseStream.Position); @@ -64,7 +64,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - Assert.ThrowsException(() => Neo.IO.Helper.ReadFixedBytes(reader, 5)); + Assert.ThrowsException(() => reader.ReadFixedBytes(5)); Assert.AreEqual(4, reader.BaseStream.Position); } } @@ -87,7 +87,7 @@ public void TestNullableArray() using (MemoryStream stream = new()) using (BinaryWriter writter = new(stream)) { - Neo.IO.Helper.WriteNullableArray(writter, caseArray); + writter.WriteNullableArray(caseArray); data = stream.ToArray(); } @@ -103,14 +103,33 @@ public void TestNullableArray() // Read 100% MemoryReader reader = new(data); - var read = Neo.IO.Helper.ReadNullableArray(ref reader); + var read = reader.ReadNullableArray(); CollectionAssert.AreEqual(caseArray, read); } [TestMethod] public void TestAsSerializable() { - byte[] caseArray = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + byte[] caseArray = [0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00]; ISerializable result = caseArray.AsSerializable(); Assert.AreEqual(UInt160.Zero, result); } @@ -119,8 +138,8 @@ public void TestAsSerializable() public void TestCompression() { var data = new byte[] { 1, 2, 3, 4 }; - var byteArray = Neo.IO.Helper.CompressLz4(data); - var result = Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue); + var byteArray = data.CompressLz4(); + var result = byteArray.Span.DecompressLz4(byte.MaxValue); CollectionAssert.AreEqual(result, data); @@ -129,29 +148,29 @@ public void TestCompression() data = new byte[255]; for (int x = 0; x < data.Length; x++) data[x] = 1; - byteArray = Neo.IO.Helper.CompressLz4(data); - result = Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue); + byteArray = data.CompressLz4(); + result = byteArray.Span.DecompressLz4(byte.MaxValue); Assert.IsTrue(byteArray.Length < result.Length); CollectionAssert.AreEqual(result, data); // Error max length - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue - 1)); - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray.Span, -1)); + Assert.ThrowsException(() => byteArray.Span.DecompressLz4(byte.MaxValue - 1)); + Assert.ThrowsException(() => byteArray.Span.DecompressLz4(-1)); // Error length byte[] data_wrong = byteArray.ToArray(); data_wrong[0]++; - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(data_wrong, byte.MaxValue)); + Assert.ThrowsException(() => data_wrong.DecompressLz4(byte.MaxValue)); } [TestMethod] public void TestAsSerializableArray() { byte[] byteArray = new UInt160[] { UInt160.Zero }.ToByteArray(); - UInt160[] result = Neo.IO.Helper.AsSerializableArray(byteArray); + UInt160[] result = byteArray.AsSerializableArray(); Assert.AreEqual(1, result.Length); Assert.AreEqual(UInt160.Zero, result[0]); } @@ -161,9 +180,9 @@ public void TestReadSerializable() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, UInt160.Zero); + writer.Write(UInt160.Zero); MemoryReader reader = new(stream.ToArray()); - UInt160 result = Neo.IO.Helper.ReadSerializable(ref reader); + UInt160 result = reader.ReadSerializable(); Assert.AreEqual(UInt160.Zero, result); } @@ -172,9 +191,9 @@ public void TestReadSerializableArray() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, new UInt160[] { UInt160.Zero }); + writer.Write(new UInt160[] { UInt160.Zero }); MemoryReader reader = new(stream.ToArray()); - UInt160[] resultArray = Neo.IO.Helper.ReadSerializableArray(ref reader); + UInt160[] resultArray = reader.ReadSerializableArray(); Assert.AreEqual(1, resultArray.Length); Assert.AreEqual(UInt160.Zero, resultArray[0]); } @@ -184,10 +203,10 @@ public void TestReadVarBytes() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarBytes(writer, new byte[] { 0xAA, 0xAA }); + writer.WriteVarBytes(new byte[] { 0xAA, 0xAA }); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - byte[] byteArray = Neo.IO.Helper.ReadVarBytes(reader, 10); + byte[] byteArray = reader.ReadVarBytes(10); Assert.AreEqual(Encoding.Default.GetString(new byte[] { 0xAA, 0xAA }), Encoding.Default.GetString(byteArray)); } @@ -200,30 +219,30 @@ public void TestReadVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFF); + writer.WriteVarInt(0xFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - ulong result = Neo.IO.Helper.ReadVarInt(reader, 0xFFFF); + ulong result = reader.ReadVarInt(0xFFFF); Assert.AreEqual((ulong)0xFFFF, result); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - ulong result = Neo.IO.Helper.ReadVarInt(reader, 0xFFFFFFFF); + ulong result = reader.ReadVarInt(0xFFFFFFFF); Assert.AreEqual(0xFFFFFFFF, result); } else { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - Action action = () => Neo.IO.Helper.ReadVarInt(reader, 0xFFFFFFFF); + Action action = () => reader.ReadVarInt(0xFFFFFFFF); action.Should().Throw(); } } @@ -232,7 +251,7 @@ public void TestReadVarInt() [TestMethod] public void TestToArray() { - byte[] byteArray = Neo.IO.Helper.ToArray(UInt160.Zero); + byte[] byteArray = UInt160.Zero.ToArray(); Assert.AreEqual(Encoding.Default.GetString(new byte[] { 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, @@ -254,7 +273,7 @@ public void TestWrite() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, UInt160.Zero); + writer.Write(UInt160.Zero); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -269,7 +288,7 @@ public void TestWriteGeneric() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, new UInt160[] { UInt160.Zero }); + writer.Write(new UInt160[] { UInt160.Zero }); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -288,28 +307,28 @@ public void TestWriteFixedString() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, null, 0); + Action action = () => writer.WriteFixedString(null, 0); action.Should().Throw(); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, "AA", Encoding.UTF8.GetBytes("AA").Length - 1); + Action action = () => writer.WriteFixedString("AA", Encoding.UTF8.GetBytes("AA").Length - 1); action.Should().Throw(); } else if (i == 2) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, "拉拉", Encoding.UTF8.GetBytes("拉拉").Length - 1); + Action action = () => writer.WriteFixedString("拉拉", Encoding.UTF8.GetBytes("拉拉").Length - 1); action.Should().Throw(); } else if (i == 3) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteFixedString(writer, "AA", Encoding.UTF8.GetBytes("AA").Length + 1); + writer.WriteFixedString("AA", Encoding.UTF8.GetBytes("AA").Length + 1); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -325,7 +344,7 @@ public void TestWriteVarBytes() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarBytes(writer, new byte[] { 0xAA }); + writer.WriteVarBytes(new byte[] { 0xAA }); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -341,14 +360,14 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteVarInt(writer, -1); + Action action = () => writer.WriteVarInt(-1); action.Should().Throw(); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFC); + writer.WriteVarInt(0xFC); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -358,7 +377,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFF); + writer.WriteVarInt(0xFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -369,7 +388,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -380,7 +399,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xAEFFFFFFFF); + writer.WriteVarInt(0xAEFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -395,7 +414,7 @@ public void TestWriteVarString() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarString(writer, "a"); + writer.WriteVarString("a"); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); diff --git a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs index c3c5c2c86f..fbb2ca5106 100644 --- a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs +++ b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; diff --git a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs index 5551daae65..b35d92f4e3 100644 --- a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs +++ b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs index 6e189ad3ec..1308909d73 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs index a0dac53fbe..219c8cc684 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index 1a0ad19a9a..28fdcaf068 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs index 76eff8e198..ae5a0e7758 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs index f73e9b5595..0661649215 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs index 3aa4049d87..5859d974ce 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs index 6752525ac0..ccd4e7aaed 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs index 9ecdd7f5e4..1c11871225 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs index 09454d298f..0bdb4982c8 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs index 4735fddfe1..c799ff8289 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs index f491d46749..b1849f1332 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs index bff21a4e5e..193f14902d 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index dc910c5142..97bb61a98a 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -825,7 +825,7 @@ public void Transaction_Serialize_Deserialize_Simple() "010000"); // empty witnesses // try to deserialize - var tx2 = sTx.AsSerializable(); + Transaction tx2 = sTx.AsSerializable(); tx2.Version.Should().Be(0x00); tx2.Nonce.Should().Be(0x01020304); @@ -887,7 +887,7 @@ public void Transaction_Serialize_Deserialize_DistinctCosigners() // back to transaction (should fail, due to non-distinct cosigners) Transaction tx2 = null; Assert.ThrowsException(() => - tx2 = Neo.IO.Helper.AsSerializable(sTx) + tx2 = sTx.AsSerializable() ); Assert.IsNull(tx2); } diff --git a/tests/Neo.UnitTests/Network/P2P/UT_Message.cs b/tests/Neo.UnitTests/Network/P2P/UT_Message.cs index 35f99fc44f..7a43cf89a4 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_Message.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_Message.cs @@ -12,6 +12,7 @@ using Akka.IO; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs b/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs index 9f114e2708..cfa94a3113 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs @@ -13,6 +13,7 @@ using Akka.TestKit.Xunit2; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Capabilities; diff --git a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs index 4473ae63a8..07f8740776 100644 --- a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs +++ b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs index a7d087fa86..b6e41c559f 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 745670977e..d5e6f22800 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs b/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs index 9d687e1053..b6be60cdab 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using System; diff --git a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs index 40142e93be..b5fb90fe22 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using System; diff --git a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs index a864c5d427..e2f89751c1 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -12,6 +12,7 @@ using Akka.TestKit.Xunit2; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/TestUtils.cs b/tests/Neo.UnitTests/TestUtils.cs index a9ad4d8ff7..3b768940e8 100644 --- a/tests/Neo.UnitTests/TestUtils.cs +++ b/tests/Neo.UnitTests/TestUtils.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 6cf1605a24..ae446503e6 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -77,5 +77,77 @@ public void TestRemoveHashsetHashSetCache() CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); } + + [TestMethod] + public void TestToHexString() + { + byte[] nullStr = null; + Assert.ThrowsException(() => nullStr.ToHexString()); + byte[] empty = Array.Empty(); + empty.ToHexString().Should().Be(""); + empty.ToHexString(false).Should().Be(""); + empty.ToHexString(true).Should().Be(""); + + byte[] str1 = new byte[] { (byte)'n', (byte)'e', (byte)'o' }; + str1.ToHexString().Should().Be("6e656f"); + str1.ToHexString(false).Should().Be("6e656f"); + str1.ToHexString(true).Should().Be("6f656e"); + } + + [TestMethod] + public void TestGetVersion() + { + // assembly without version + + var asm = AppDomain.CurrentDomain.GetAssemblies() + .Where(u => u.FullName == "Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null") + .FirstOrDefault(); + string version = asm?.GetVersion() ?? ""; + version.Should().Be("0.0.0"); + } + + [TestMethod] + public void TestToByteArrayStandard() + { + BigInteger number = BigInteger.Zero; + Assert.AreEqual("", number.ToByteArrayStandard().ToHexString()); + + number = BigInteger.One; + Assert.AreEqual("01", number.ToByteArrayStandard().ToHexString()); + } + + [TestMethod] + public void TestNextBigIntegerForRandom() + { + Random ran = new(); + Action action1 = () => ran.NextBigInteger(-1); + action1.Should().Throw(); + + ran.NextBigInteger(0).Should().Be(0); + ran.NextBigInteger(8).Should().NotBeNull(); + ran.NextBigInteger(9).Should().NotBeNull(); + } + + [TestMethod] + public void TestUnmapForIPAddress() + { + var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); + addr.UnMap().Should().Be(addr); + + var addr2 = addr.MapToIPv6(); + addr2.UnMap().Should().Be(addr); + } + + [TestMethod] + public void TestUnmapForIPEndPoin() + { + var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); + var endPoint = new IPEndPoint(addr, 8888); + endPoint.UnMap().Should().Be(endPoint); + + var addr2 = addr.MapToIPv6(); + var endPoint2 = new IPEndPoint(addr2, 8888); + endPoint2.UnMap().Should().Be(endPoint); + } } } diff --git a/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs b/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs index 843eeae192..055ea193f7 100644 --- a/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs +++ b/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Wallets; using System; From 6e000529d7efb0a7fd589e162a03a88cef799415 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Mon, 25 Nov 2024 22:08:22 -0500 Subject: [PATCH 02/13] Fixed `GetVarSize` (#3594) * Fixed `GetVarSize` * Added unit tests * revert `global.json` * Fixed test for `old` method * revert `global.json` * Update src/Neo.Extensions/UnsafeData.cs --------- Co-authored-by: Shargon --- src/Neo.Extensions/UnsafeData.cs | 8 +++--- tests/Neo.Extensions.Tests/UT_UnsafeData.cs | 29 ++++++++++++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Neo.Extensions/UnsafeData.cs b/src/Neo.Extensions/UnsafeData.cs index 6d4c9a6f8e..50126c25f4 100644 --- a/src/Neo.Extensions/UnsafeData.cs +++ b/src/Neo.Extensions/UnsafeData.cs @@ -18,14 +18,16 @@ public static class UnsafeData /// /// The length of the data. /// The size of variable-length of the data. - public static int GetVarSize(int value) + public static byte GetVarSize(long value) { if (value < 0xFD) return sizeof(byte); - else if (value <= 0xFFFF) + else if (value <= ushort.MaxValue) return sizeof(byte) + sizeof(ushort); - else + else if (value <= uint.MaxValue) return sizeof(byte) + sizeof(uint); + else + return sizeof(byte) + sizeof(ulong); } } } diff --git a/tests/Neo.Extensions.Tests/UT_UnsafeData.cs b/tests/Neo.Extensions.Tests/UT_UnsafeData.cs index 5c8bb310c3..98562fdfa2 100644 --- a/tests/Neo.Extensions.Tests/UT_UnsafeData.cs +++ b/tests/Neo.Extensions.Tests/UT_UnsafeData.cs @@ -12,22 +12,33 @@ public class UT_UnsafeData [TestMethod] public void TestGetVarSizeInt() { - for (int i = 0; i < 3; i++) + for (int i = 0; i < 4; i++) { if (i == 0) { int result = UnsafeData.GetVarSize(1); + int old = OldGetVarSize(1); Assert.AreEqual(1, result); + Assert.AreEqual(1, old); } else if (i == 1) { - int result = UnsafeData.GetVarSize(0xFFFF); + int result = UnsafeData.GetVarSize(ushort.MaxValue); + int old = OldGetVarSize(ushort.MaxValue); Assert.AreEqual(3, result); + Assert.AreEqual(3, old); } - else + else if (i == 2) { - int result = UnsafeData.GetVarSize(0xFFFFFF); + int result = UnsafeData.GetVarSize(uint.MaxValue); + int old = OldGetVarSize(int.MaxValue); Assert.AreEqual(5, result); + Assert.AreEqual(5, old); + } + else + { + int result = UnsafeData.GetVarSize(long.MaxValue); + Assert.AreEqual(9, result); } } } @@ -159,5 +170,15 @@ enum TestEnum6 : long { case1 = 1, case2 = 2 } + + public static int OldGetVarSize(int value) + { + if (value < 0xFD) + return sizeof(byte); + else if (value <= ushort.MaxValue) + return sizeof(byte) + sizeof(ushort); + else + return sizeof(byte) + sizeof(uint); + } } } From b3a78469c9e94c0b304181f302962b659e6011a2 Mon Sep 17 00:00:00 2001 From: nan01ab Date: Wed, 27 Nov 2024 14:23:32 +0800 Subject: [PATCH 03/13] Optimizations for `KeyBuilder` (#3598) * Optimize KeyBuilder and Add some UTs for not-covered methods * optimization for adding UInt160 and UInt256 to KeyBuilder * fix stream capacity calculation * Update src/Neo/SmartContract/KeyBuilder.cs Co-authored-by: Shargon * Update src/Neo/SmartContract/KeyBuilder.cs Co-authored-by: Shargon * add more benchmark * check IsLittleEndian or not * add UTs for UInt160 and UInt256 * fix code format --------- Co-authored-by: Shargon Co-authored-by: Jimmy --- benchmarks/Neo.Benchmarks/Program.cs | 2 + .../SmartContract/Benchmarks.StorageKey.cs | 75 +++++++++++++++++++ src/Neo/SmartContract/KeyBuilder.cs | 47 ++++++++++-- src/Neo/UInt160.cs | 12 +++ src/Neo/UInt256.cs | 13 ++++ .../SmartContract/UT_KeyBuilder.cs | 67 +++++++++++++++++ tests/Neo.UnitTests/UT_UInt160.cs | 14 ++++ tests/Neo.UnitTests/UT_UInt256.cs | 13 ++++ 8 files changed, 236 insertions(+), 7 deletions(-) create mode 100644 benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs 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/src/Neo/SmartContract/KeyBuilder.cs b/src/Neo/SmartContract/KeyBuilder.cs index cfd27cc6f8..9e6371ff31 100644 --- a/src/Neo/SmartContract/KeyBuilder.cs +++ b/src/Neo/SmartContract/KeyBuilder.cs @@ -13,6 +13,7 @@ using System; using System.Buffers.Binary; using System.IO; +using System.Runtime.CompilerServices; namespace Neo.SmartContract { @@ -21,18 +22,20 @@ namespace Neo.SmartContract /// public class KeyBuilder { - private readonly MemoryStream stream = new(); + private readonly MemoryStream stream; /// /// Initializes a new instance of the class. /// /// The id of the contract. /// The prefix of the key. - public KeyBuilder(int id, byte prefix) + /// The hint of the storage key size(including the id and prefix). + public KeyBuilder(int id, byte prefix, int keySizeHint = ApplicationEngine.MaxStorageKeySize) { - var data = new byte[sizeof(int)]; + Span data = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(data, id); + stream = new(keySizeHint); stream.Write(data); stream.WriteByte(prefix); } @@ -42,6 +45,7 @@ public KeyBuilder(int id, byte prefix) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder Add(byte key) { stream.WriteByte(key); @@ -53,12 +57,37 @@ public KeyBuilder Add(byte key) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder Add(ReadOnlySpan key) { stream.Write(key); return this; } + /// + /// Adds part of the key to the builder. + /// + /// Part of the key represented by a byte array. + /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public KeyBuilder Add(byte[] key) => Add(key.AsSpan()); + + /// + /// Adds part of the key to the builder. + /// + /// Part of the key represented by a . + /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public KeyBuilder Add(UInt160 key) => Add(key.GetSpan()); + + /// + /// Adds part of the key to the builder. + /// + /// Part of the key represented by a . + /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public KeyBuilder Add(UInt256 key) => Add(key.GetSpan()); + /// /// Adds part of the key to the builder. /// @@ -79,9 +108,10 @@ public KeyBuilder Add(ISerializable key) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder AddBigEndian(int key) { - var data = new byte[sizeof(int)]; + Span data = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32BigEndian(data, key); return Add(data); @@ -92,9 +122,10 @@ public KeyBuilder AddBigEndian(int key) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder AddBigEndian(uint key) { - var data = new byte[sizeof(uint)]; + Span data = stackalloc byte[sizeof(uint)]; BinaryPrimitives.WriteUInt32BigEndian(data, key); return Add(data); @@ -105,9 +136,10 @@ public KeyBuilder AddBigEndian(uint key) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder AddBigEndian(long key) { - var data = new byte[sizeof(long)]; + Span data = stackalloc byte[sizeof(long)]; BinaryPrimitives.WriteInt64BigEndian(data, key); return Add(data); @@ -118,9 +150,10 @@ public KeyBuilder AddBigEndian(long key) /// /// Part of the key. /// A reference to this instance after the add operation has completed. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public KeyBuilder AddBigEndian(ulong key) { - var data = new byte[sizeof(ulong)]; + Span data = stackalloc byte[sizeof(ulong)]; BinaryPrimitives.WriteUInt64BigEndian(data, key); return Add(data); diff --git a/src/Neo/UInt160.cs b/src/Neo/UInt160.cs index da4c920cbe..6aa4a9eaa9 100644 --- a/src/Neo/UInt160.cs +++ b/src/Neo/UInt160.cs @@ -101,6 +101,18 @@ public override int GetHashCode() return HashCode.Combine(_value1, _value2, _value3); } + /// + /// Gets a ReadOnlySpan that represents the current value in little-endian. + /// + /// A ReadOnlySpan that represents the current value in little-endian. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan GetSpan() + { + if (BitConverter.IsLittleEndian) + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref _value1), Length); + return this.ToArray().AsSpan(); // Keep the same output as Serialize when BigEndian + } + /// /// Parses an from the specified . /// diff --git a/src/Neo/UInt256.cs b/src/Neo/UInt256.cs index 95324ef6ac..74f72d5cd3 100644 --- a/src/Neo/UInt256.cs +++ b/src/Neo/UInt256.cs @@ -14,6 +14,7 @@ using System; using System.Globalization; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Neo @@ -101,6 +102,18 @@ public override int GetHashCode() return (int)value1; } + /// + /// Gets a ReadOnlySpan that represents the current value in little-endian. + /// + /// A ReadOnlySpan that represents the current value in little-endian. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan GetSpan() + { + if (BitConverter.IsLittleEndian) + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref value1), Length); + return this.ToArray().AsSpan(); // Keep the same output as Serialize when BigEndian + } + /// /// Parses an from the specified . /// diff --git a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs index a3514c7f5a..029514c103 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Extensions; +using Neo.IO; using Neo.SmartContract; namespace Neo.UnitTests.SmartContract @@ -42,5 +43,71 @@ public void Test() key = key.AddBigEndian(1); Assert.AreEqual("010000000000000001", key.ToArray().ToHexString()); } + + [TestMethod] + public void TestAddInt() + { + var key = new KeyBuilder(1, 2); + Assert.AreEqual("0100000002", key.ToArray().ToHexString()); + + // add int + key = new KeyBuilder(1, 2); + key = key.AddBigEndian(-1); + key = key.AddBigEndian(2); + key = key.AddBigEndian(3); + Assert.AreEqual("0100000002ffffffff0000000200000003", key.ToArray().ToHexString()); + + // add ulong + key = new KeyBuilder(1, 2); + key = key.AddBigEndian(1ul); + key = key.AddBigEndian(2ul); + key = key.AddBigEndian(ulong.MaxValue); + Assert.AreEqual("010000000200000000000000010000000000000002ffffffffffffffff", key.ToArray().ToHexString()); + + // add uint + key = new KeyBuilder(1, 2); + key = key.AddBigEndian(1u); + key = key.AddBigEndian(2u); + key = key.AddBigEndian(uint.MaxValue); + Assert.AreEqual("01000000020000000100000002ffffffff", key.ToArray().ToHexString()); + + // add byte + key = new KeyBuilder(1, 2); + key = key.Add((byte)1); + key = key.Add((byte)2); + key = key.Add((byte)3); + Assert.AreEqual("0100000002010203", key.ToArray().ToHexString()); + } + + [TestMethod] + public void TestAddUInt() + { + var key = new KeyBuilder(1, 2); + var value = new byte[UInt160.Length]; + for (int i = 0; i < value.Length; i++) + value[i] = (byte)i; + + key = key.Add(new UInt160(value)); + Assert.AreEqual("0100000002000102030405060708090a0b0c0d0e0f10111213", key.ToArray().ToHexString()); + + var key2 = new KeyBuilder(1, 2); + key2 = key2.Add((ISerializable)(new UInt160(value))); + + // It must be same before and after optimization. + Assert.AreEqual(key.ToArray().ToHexString(), key2.ToArray().ToHexString()); + + key = new KeyBuilder(1, 2); + value = new byte[UInt256.Length]; + for (int i = 0; i < value.Length; i++) + value[i] = (byte)i; + key = key.Add(new UInt256(value)); + Assert.AreEqual("0100000002000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", key.ToArray().ToHexString()); + + key2 = new KeyBuilder(1, 2); + key2 = key2.Add((ISerializable)(new UInt256(value))); + + // It must be same before and after optimization. + Assert.AreEqual(key.ToArray().ToHexString(), key2.ToArray().ToHexString()); + } } } diff --git a/tests/Neo.UnitTests/UT_UInt160.cs b/tests/Neo.UnitTests/UT_UInt160.cs index 3502c7cf90..3fb9dd89a0 100644 --- a/tests/Neo.UnitTests/UT_UInt160.cs +++ b/tests/Neo.UnitTests/UT_UInt160.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using System; using System.Security.Cryptography; @@ -126,5 +127,18 @@ public void TestOperatorSmallerAndEqual() Assert.AreEqual(true, UInt160.Zero <= UInt160.Zero); Assert.IsTrue(UInt160.Zero >= "0x0000000000000000000000000000000000000000"); } + + [TestMethod] + public void TestSpanAndSerialize() + { + // random data + var random = new Random(); + var data = new byte[UInt160.Length]; + random.NextBytes(data); + + var value = new UInt160(data); + var span = value.GetSpan(); + Assert.IsTrue(span.SequenceEqual(value.ToArray())); + } } } diff --git a/tests/Neo.UnitTests/UT_UInt256.cs b/tests/Neo.UnitTests/UT_UInt256.cs index b2bd02dac3..40006b4b67 100644 --- a/tests/Neo.UnitTests/UT_UInt256.cs +++ b/tests/Neo.UnitTests/UT_UInt256.cs @@ -13,6 +13,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using System; using System.IO; @@ -155,5 +156,17 @@ public void TestOperatorSmallerAndEqual() { Assert.AreEqual(true, UInt256.Zero <= UInt256.Zero); } + + [TestMethod] + public void TestSpanAndSerialize() + { + var random = new Random(); + var data = new byte[UInt256.Length]; + random.NextBytes(data); + + var value = new UInt256(data); + var span = value.GetSpan(); + Assert.IsTrue(span.SequenceEqual(value.ToArray())); + } } } From 38780458ac5c3ecaf1cfd5fff5e1f9132556e106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 28 Nov 2024 10:28:17 +0800 Subject: [PATCH 04/13] Update README.md (#3601) * Update README.md * Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 1703774f29ea334e8bd7f6af3eaae2e92b75ba39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 28 Nov 2024 14:25:48 +0800 Subject: [PATCH 05/13] .NET 9 (#3576) * .NET 9 * format * update * update * update * Update .editorconfig * Update Directory.Build.props * UT seems it changed * Update tests/Neo.VM.Tests/UT_ScriptBuilder.cs * fixes * resolve a conflict * fixed bug * Fixes * Update packages * fix ut --------- Co-authored-by: Jimmy Co-authored-by: Christopher Schuchardt Co-authored-by: Shargon Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- .devcontainer/devcontainer.dockerfile | 2 +- .github/workflows/docker.yml | 6 +++--- .github/workflows/main.yml | 4 ++-- .github/workflows/nuget.yml | 2 +- .github/workflows/release.yml | 6 +++--- .../Neo.Benchmarks/Neo.Benchmarks.csproj | 6 +++--- .../Neo.Extensions.Benchmarks.csproj | 6 +++--- .../Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj | 6 +++--- global.json | 2 +- scripts/Neo.CLI/test-neo-cli.exp | 2 +- src/Neo.CLI/CLI/MainService.cs | 4 ++-- src/Neo.CLI/Dockerfile | 6 +++--- src/Neo.CLI/Neo.CLI.csproj | 2 +- .../Neo.ConsoleService.csproj | 4 ++-- .../Neo.Cryptography.BLS12_381.csproj | 4 ++-- src/Neo.Extensions/Neo.Extensions.csproj | 6 +++--- src/Neo.GUI/GUI/ChangePasswordDialog.cs | 3 +++ src/Neo.GUI/GUI/CreateWalletDialog.cs | 3 +++ src/Neo.GUI/GUI/ImportPrivateKeyDialog.cs | 2 ++ src/Neo.GUI/GUI/OpenWalletDialog.cs | 3 +++ src/Neo.GUI/GUI/TxOutListBox.cs | 3 +++ src/Neo.GUI/Neo.GUI.csproj | 2 +- src/Neo.IO/Neo.IO.csproj | 2 +- src/Neo.Json/Neo.Json.csproj | 4 ++-- src/Neo.VM/Neo.VM.csproj | 4 ++-- src/Neo.VM/ScriptBuilder.cs | 2 -- src/Neo.VM/Types/Map.cs | 3 +-- src/Neo/Neo.csproj | 12 ++++++------ .../ApplicationLogs/ApplicationLogs.csproj | 2 +- src/Plugins/DBFTPlugin/DBFTPlugin.csproj | 2 +- src/Plugins/LevelDBStore/LevelDBStore.csproj | 2 +- src/Plugins/MPTTrie/MPTTrie.csproj | 2 +- src/Plugins/OracleService/OracleService.csproj | 2 +- src/Plugins/RocksDBStore/RocksDBStore.csproj | 2 +- src/Plugins/RpcClient/RpcClient.csproj | 2 +- src/Plugins/RpcServer/RpcServer.csproj | 2 +- src/Plugins/SQLiteWallet/SQLiteWallet.csproj | 4 ++-- src/Plugins/StateService/StateService.csproj | 2 +- src/Plugins/StorageDumper/StorageDumper.csproj | 2 +- src/Plugins/TokensTracker/Extensions.cs | 2 +- src/Plugins/TokensTracker/TokensTracker.csproj | 2 +- tests/Directory.Build.props | 2 +- .../Neo.ConsoleService.Tests.csproj | 8 ++++---- .../Neo.Cryptography.BLS12_381.Tests.csproj | 8 ++++---- .../Neo.Cryptography.MPTTrie.Tests.csproj | 8 ++++---- .../Neo.Extensions.Tests.csproj | 8 ++++---- .../Neo.Extensions.Tests/UT_ByteExtensions.cs | 2 +- .../Neo.Json.UnitTests.csproj | 8 ++++---- .../Neo.Network.RPC.Tests.csproj | 10 +++++----- .../Neo.Plugins.ApplicationLogs.Tests.csproj | 11 +++++++---- .../Neo.Plugins.OracleService.Tests.csproj | 12 ++++++------ .../Neo.Plugins.RpcServer.Tests.csproj | 11 +++++------ .../Neo.Plugins.Storage.Tests.csproj | 8 ++++---- tests/Neo.UnitTests/Neo.UnitTests.csproj | 14 +++++++------- tests/Neo.UnitTests/UT_Helper.cs | 2 +- tests/Neo.VM.Tests/Neo.VM.Tests.csproj | 8 ++++---- tests/Neo.VM.Tests/UT_ScriptBuilder.cs | 18 +++++++++++++++++- tests/Neo.VM.Tests/UT_Utility.cs | 2 +- 58 files changed, 154 insertions(+), 125 deletions(-) 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/.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 e70c6e4cd3..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: @@ -69,7 +69,7 @@ jobs: 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/net8.0/ + 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) 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/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.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/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/global.json b/global.json index beefe210a1..41c9ad2ed8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.202", + "version": "9.0.100", "rollForward": "latestFeature", "allowPrerelease": false } diff --git a/scripts/Neo.CLI/test-neo-cli.exp b/scripts/Neo.CLI/test-neo-cli.exp index e7124402c3..73705c8a15 100644 --- a/scripts/Neo.CLI/test-neo-cli.exp +++ b/scripts/Neo.CLI/test-neo-cli.exp @@ -6,7 +6,7 @@ set timeout 10 exp_internal true # Start neo-cli -spawn dotnet ./bin/Neo.CLI/net8.0/neo-cli.dll +spawn dotnet ./bin/Neo.CLI/net9.0/neo-cli.dll # Expect the main input prompt expect { diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs index 96db57a19d..266549f3cf 100644 --- a/src/Neo.CLI/CLI/MainService.cs +++ b/src/Neo.CLI/CLI/MainService.cs @@ -521,13 +521,13 @@ private void WriteBlocks(uint start, uint count, string path, bool writeStart) if (writeStart) { fs.Seek(sizeof(uint), SeekOrigin.Begin); - fs.Read(buffer, 0, buffer.Length); + fs.ReadExactly(buffer); start += BitConverter.ToUInt32(buffer, 0); fs.Seek(sizeof(uint), SeekOrigin.Begin); } else { - fs.Read(buffer, 0, buffer.Length); + fs.ReadExactly(buffer); start = BitConverter.ToUInt32(buffer, 0); fs.Seek(0, SeekOrigin.Begin); } diff --git a/src/Neo.CLI/Dockerfile b/src/Neo.CLI/Dockerfile index 5863e9a74d..100056b6f7 100644 --- a/src/Neo.CLI/Dockerfile +++ b/src/Neo.CLI/Dockerfile @@ -1,13 +1,13 @@ -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS Build +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0 AS Build # Run this from the repository root folder COPY src . COPY NuGet.Config /Neo.CLI WORKDIR /Neo.CLI -RUN dotnet restore && dotnet publish -f net8.0 -c Release -o /app +RUN dotnet restore && dotnet publish -f net9.0 -c Release -o /app -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/aspnet:8.0 AS Final +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/aspnet:9.0 AS Final RUN apt-get update && apt-get install -y \ screen \ libleveldb-dev \ diff --git a/src/Neo.CLI/Neo.CLI.csproj b/src/Neo.CLI/Neo.CLI.csproj index f2e1359194..ff71de843f 100644 --- a/src/Neo.CLI/Neo.CLI.csproj +++ b/src/Neo.CLI/Neo.CLI.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.CLI neo-cli Exe diff --git a/src/Neo.ConsoleService/Neo.ConsoleService.csproj b/src/Neo.ConsoleService/Neo.ConsoleService.csproj index b4254a4cad..51c90d9520 100644 --- a/src/Neo.ConsoleService/Neo.ConsoleService.csproj +++ b/src/Neo.ConsoleService/Neo.ConsoleService.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 Neo.ConsoleService enable ../../bin/$(PackageId) @@ -9,7 +9,7 @@ - + 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 cbed7d23b8..83cb016cbc 100644 --- a/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj +++ b/src/Neo.Cryptography.BLS12_381/Neo.Cryptography.BLS12_381.csproj @@ -2,7 +2,7 @@ 0.3.0 - netstandard2.1;net8.0 + netstandard2.1;net9.0 enable enable Neo.Cryptography.BLS12_381 @@ -10,7 +10,7 @@ - + diff --git a/src/Neo.Extensions/Neo.Extensions.csproj b/src/Neo.Extensions/Neo.Extensions.csproj index 38cbf346fb..5d66927611 100644 --- a/src/Neo.Extensions/Neo.Extensions.csproj +++ b/src/Neo.Extensions/Neo.Extensions.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 enable true Neo.Extensions @@ -10,8 +10,8 @@ - - + + diff --git a/src/Neo.GUI/GUI/ChangePasswordDialog.cs b/src/Neo.GUI/GUI/ChangePasswordDialog.cs index f6ea079e41..30f77aa546 100644 --- a/src/Neo.GUI/GUI/ChangePasswordDialog.cs +++ b/src/Neo.GUI/GUI/ChangePasswordDialog.cs @@ -10,12 +10,14 @@ // modifications are permitted. using System; +using System.ComponentModel; using System.Windows.Forms; namespace Neo.GUI { internal partial class ChangePasswordDialog : Form { + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string OldPassword { get @@ -28,6 +30,7 @@ public string OldPassword } } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string NewPassword { get diff --git a/src/Neo.GUI/GUI/CreateWalletDialog.cs b/src/Neo.GUI/GUI/CreateWalletDialog.cs index 770cd07cac..08deaf3345 100644 --- a/src/Neo.GUI/GUI/CreateWalletDialog.cs +++ b/src/Neo.GUI/GUI/CreateWalletDialog.cs @@ -10,6 +10,7 @@ // modifications are permitted. using System; +using System.ComponentModel; using System.Windows.Forms; namespace Neo.GUI @@ -21,6 +22,7 @@ public CreateWalletDialog() InitializeComponent(); } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string Password { get @@ -34,6 +36,7 @@ public string Password } } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string WalletPath { get diff --git a/src/Neo.GUI/GUI/ImportPrivateKeyDialog.cs b/src/Neo.GUI/GUI/ImportPrivateKeyDialog.cs index 9379f45900..e4105001da 100644 --- a/src/Neo.GUI/GUI/ImportPrivateKeyDialog.cs +++ b/src/Neo.GUI/GUI/ImportPrivateKeyDialog.cs @@ -10,6 +10,7 @@ // modifications are permitted. using System; +using System.ComponentModel; using System.Windows.Forms; namespace Neo.GUI @@ -21,6 +22,7 @@ public ImportPrivateKeyDialog() InitializeComponent(); } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string[] WifStrings { get diff --git a/src/Neo.GUI/GUI/OpenWalletDialog.cs b/src/Neo.GUI/GUI/OpenWalletDialog.cs index a43352a9ed..c34495af9f 100644 --- a/src/Neo.GUI/GUI/OpenWalletDialog.cs +++ b/src/Neo.GUI/GUI/OpenWalletDialog.cs @@ -10,6 +10,7 @@ // modifications are permitted. using System; +using System.ComponentModel; using System.Windows.Forms; namespace Neo.GUI @@ -21,6 +22,7 @@ public OpenWalletDialog() InitializeComponent(); } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string Password { get @@ -33,6 +35,7 @@ public string Password } } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string WalletPath { get diff --git a/src/Neo.GUI/GUI/TxOutListBox.cs b/src/Neo.GUI/GUI/TxOutListBox.cs index d2e314ecaf..ae6db6c3cf 100644 --- a/src/Neo.GUI/GUI/TxOutListBox.cs +++ b/src/Neo.GUI/GUI/TxOutListBox.cs @@ -23,12 +23,14 @@ internal partial class TxOutListBox : UserControl { public event EventHandler ItemsChanged; + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public AssetDescriptor Asset { get; set; } public int ItemCount => listBox1.Items.Count; public IEnumerable Items => listBox1.Items.OfType(); + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool ReadOnly { get @@ -42,6 +44,7 @@ public bool ReadOnly } private UInt160 _script_hash = null; + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public UInt160 ScriptHash { get diff --git a/src/Neo.GUI/Neo.GUI.csproj b/src/Neo.GUI/Neo.GUI.csproj index 28c7d841a5..51997403e8 100644 --- a/src/Neo.GUI/Neo.GUI.csproj +++ b/src/Neo.GUI/Neo.GUI.csproj @@ -4,7 +4,7 @@ 2016-2024 The Neo Project Neo.GUI WinExe - net8.0-windows + net9.0-windows true Neo true diff --git a/src/Neo.IO/Neo.IO.csproj b/src/Neo.IO/Neo.IO.csproj index deb98b053b..0b2b858049 100644 --- a/src/Neo.IO/Neo.IO.csproj +++ b/src/Neo.IO/Neo.IO.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 true enable Neo.IO diff --git a/src/Neo.Json/Neo.Json.csproj b/src/Neo.Json/Neo.Json.csproj index 0a490a1934..3f0a78b02e 100644 --- a/src/Neo.Json/Neo.Json.csproj +++ b/src/Neo.Json/Neo.Json.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 enable enable Neo.Json @@ -10,7 +10,7 @@ - + diff --git a/src/Neo.VM/Neo.VM.csproj b/src/Neo.VM/Neo.VM.csproj index eb7f9e7407..e860e29113 100644 --- a/src/Neo.VM/Neo.VM.csproj +++ b/src/Neo.VM/Neo.VM.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 true enable Neo.VM @@ -15,7 +15,7 @@ - + diff --git a/src/Neo.VM/ScriptBuilder.cs b/src/Neo.VM/ScriptBuilder.cs index 5615f6b918..5c56c660b1 100644 --- a/src/Neo.VM/ScriptBuilder.cs +++ b/src/Neo.VM/ScriptBuilder.cs @@ -126,8 +126,6 @@ public ScriptBuilder EmitPush(bool value) /// A reference to this instance after the emit operation has completed. public ScriptBuilder EmitPush(ReadOnlySpan data) { - if (data == null) - throw new ArgumentNullException(nameof(data)); if (data.Length < 0x100) { Emit(OpCode.PUSHDATA1); diff --git a/src/Neo.VM/Types/Map.cs b/src/Neo.VM/Types/Map.cs index 9ea88ba4a9..6e786adbce 100644 --- a/src/Neo.VM/Types/Map.cs +++ b/src/Neo.VM/Types/Map.cs @@ -9,7 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.VM.Collections; using System; using System.Collections; using System.Collections.Generic; @@ -29,7 +28,7 @@ public class Map : CompoundType, IReadOnlyDictionary /// public const int MaxKeySize = 64; - private readonly OrderedDictionary dictionary = new(); + private readonly Collections.OrderedDictionary dictionary = new(); ///

/// Gets or sets the element that has the specified key in the map. diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 7c6478c33e..5092f442fc 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -1,7 +1,7 @@ - netstandard2.1;net8.0 + netstandard2.1;net9.0 true Neo NEO;AntShares;Blockchain;Smart Contract @@ -9,13 +9,13 @@ - + - - - - + + + + diff --git a/src/Plugins/ApplicationLogs/ApplicationLogs.csproj b/src/Plugins/ApplicationLogs/ApplicationLogs.csproj index b0c31a7180..a878df9961 100644 --- a/src/Plugins/ApplicationLogs/ApplicationLogs.csproj +++ b/src/Plugins/ApplicationLogs/ApplicationLogs.csproj @@ -1,6 +1,6 @@ - net8.0 + net9.0 Neo.Plugins.ApplicationLogs Neo.Plugins enable diff --git a/src/Plugins/DBFTPlugin/DBFTPlugin.csproj b/src/Plugins/DBFTPlugin/DBFTPlugin.csproj index 93c77ad1f8..84198f62e8 100644 --- a/src/Plugins/DBFTPlugin/DBFTPlugin.csproj +++ b/src/Plugins/DBFTPlugin/DBFTPlugin.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Consensus.DBFT Neo.Consensus ../../../bin/$(PackageId) diff --git a/src/Plugins/LevelDBStore/LevelDBStore.csproj b/src/Plugins/LevelDBStore/LevelDBStore.csproj index 23cf469640..09e4abb7bd 100644 --- a/src/Plugins/LevelDBStore/LevelDBStore.csproj +++ b/src/Plugins/LevelDBStore/LevelDBStore.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.Storage.LevelDBStore Neo.Plugins.Storage true diff --git a/src/Plugins/MPTTrie/MPTTrie.csproj b/src/Plugins/MPTTrie/MPTTrie.csproj index 3134f7ae5b..430f9328e6 100644 --- a/src/Plugins/MPTTrie/MPTTrie.csproj +++ b/src/Plugins/MPTTrie/MPTTrie.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Cryptography.MPT Neo.Cryptography true diff --git a/src/Plugins/OracleService/OracleService.csproj b/src/Plugins/OracleService/OracleService.csproj index c77ddb75d8..6b6dbebb98 100644 --- a/src/Plugins/OracleService/OracleService.csproj +++ b/src/Plugins/OracleService/OracleService.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.OracleService ../../../bin/$(PackageId) diff --git a/src/Plugins/RocksDBStore/RocksDBStore.csproj b/src/Plugins/RocksDBStore/RocksDBStore.csproj index 90ed2e841a..7a827d382e 100644 --- a/src/Plugins/RocksDBStore/RocksDBStore.csproj +++ b/src/Plugins/RocksDBStore/RocksDBStore.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.Storage.RocksDBStore Neo.Plugins.Storage ../../../bin/$(PackageId) diff --git a/src/Plugins/RpcClient/RpcClient.csproj b/src/Plugins/RpcClient/RpcClient.csproj index bc6161e3cb..a8a4b84d6d 100644 --- a/src/Plugins/RpcClient/RpcClient.csproj +++ b/src/Plugins/RpcClient/RpcClient.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Network.RPC.RpcClient Neo.Network.RPC ../../../bin/$(PackageId) diff --git a/src/Plugins/RpcServer/RpcServer.csproj b/src/Plugins/RpcServer/RpcServer.csproj index c5b72e7a61..80618b13e3 100644 --- a/src/Plugins/RpcServer/RpcServer.csproj +++ b/src/Plugins/RpcServer/RpcServer.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.RpcServer ../../../bin/$(PackageId) diff --git a/src/Plugins/SQLiteWallet/SQLiteWallet.csproj b/src/Plugins/SQLiteWallet/SQLiteWallet.csproj index b8a1646e65..f623a8c8cf 100644 --- a/src/Plugins/SQLiteWallet/SQLiteWallet.csproj +++ b/src/Plugins/SQLiteWallet/SQLiteWallet.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Wallets.SQLite Neo.Wallets.SQLite enable @@ -9,7 +9,7 @@ - + diff --git a/src/Plugins/StateService/StateService.csproj b/src/Plugins/StateService/StateService.csproj index 58c18ac498..d2475c4cb2 100644 --- a/src/Plugins/StateService/StateService.csproj +++ b/src/Plugins/StateService/StateService.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.StateService true ../../../bin/$(PackageId) diff --git a/src/Plugins/StorageDumper/StorageDumper.csproj b/src/Plugins/StorageDumper/StorageDumper.csproj index ebadda6136..abf6469ade 100644 --- a/src/Plugins/StorageDumper/StorageDumper.csproj +++ b/src/Plugins/StorageDumper/StorageDumper.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.StorageDumper enable enable diff --git a/src/Plugins/TokensTracker/Extensions.cs b/src/Plugins/TokensTracker/Extensions.cs index 83b4371435..2eaea3bfd6 100644 --- a/src/Plugins/TokensTracker/Extensions.cs +++ b/src/Plugins/TokensTracker/Extensions.cs @@ -28,7 +28,7 @@ public static bool NotNull(this StackItem item) public static string ToBase64(this ReadOnlySpan item) { - return item == null ? String.Empty : Convert.ToBase64String(item); + return item.IsEmpty ? String.Empty : Convert.ToBase64String(item); } public static int GetVarSize(this ByteString item) diff --git a/src/Plugins/TokensTracker/TokensTracker.csproj b/src/Plugins/TokensTracker/TokensTracker.csproj index 5f17120159..802f71f1ae 100644 --- a/src/Plugins/TokensTracker/TokensTracker.csproj +++ b/src/Plugins/TokensTracker/TokensTracker.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Plugins.TokensTracker ../../../bin/$(PackageId) diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index a2fc251365..e4089c9a68 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -13,7 +13,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj b/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj index 469a49e548..3e25625ce3 100644 --- a/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj +++ b/tests/Neo.ConsoleService.Tests/Neo.ConsoleService.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 neo_cli.Tests @@ -10,9 +10,9 @@ - - - + + + diff --git a/tests/Neo.Cryptography.BLS12_381.Tests/Neo.Cryptography.BLS12_381.Tests.csproj b/tests/Neo.Cryptography.BLS12_381.Tests/Neo.Cryptography.BLS12_381.Tests.csproj index 827c547041..57167ed73b 100644 --- a/tests/Neo.Cryptography.BLS12_381.Tests/Neo.Cryptography.BLS12_381.Tests.csproj +++ b/tests/Neo.Cryptography.BLS12_381.Tests/Neo.Cryptography.BLS12_381.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable @@ -11,9 +11,9 @@ - - - + + + diff --git a/tests/Neo.Cryptography.MPTTrie.Tests/Neo.Cryptography.MPTTrie.Tests.csproj b/tests/Neo.Cryptography.MPTTrie.Tests/Neo.Cryptography.MPTTrie.Tests.csproj index ed23c8a909..84d6a34755 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Neo.Cryptography.MPTTrie.Tests.csproj +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Neo.Cryptography.MPTTrie.Tests.csproj @@ -1,14 +1,14 @@ - net8.0 + net9.0 Neo.Cryptography.MPT.Tests - - - + + + diff --git a/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj index 03809a4fe3..f15a1eb422 100644 --- a/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj +++ b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj @@ -1,14 +1,14 @@ - net8.0 + net9.0 enable - - - + + + diff --git a/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs index 7f4a58bc0d..bb12d00eed 100644 --- a/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs +++ b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs @@ -25,7 +25,7 @@ public class UT_ByteExtensions public void TestToHexString() { byte[] nullStr = null; - Assert.ThrowsException(() => nullStr.ToHexString()); + Assert.ThrowsException(() => nullStr.ToHexString()); byte[] empty = Array.Empty(); empty.ToHexString().Should().Be(""); empty.ToHexString(false).Should().Be(""); diff --git a/tests/Neo.Json.UnitTests/Neo.Json.UnitTests.csproj b/tests/Neo.Json.UnitTests/Neo.Json.UnitTests.csproj index c931c287a4..9646f59fde 100644 --- a/tests/Neo.Json.UnitTests/Neo.Json.UnitTests.csproj +++ b/tests/Neo.Json.UnitTests/Neo.Json.UnitTests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable @@ -10,9 +10,9 @@ - - - + + + diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index fc632685b4..acabd9cbd7 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -1,15 +1,15 @@ - net8.0 + net9.0 Neo.Network.RPC.Tests - - - - + + + + diff --git a/tests/Neo.Plugins.ApplicationLogs.Tests/Neo.Plugins.ApplicationLogs.Tests.csproj b/tests/Neo.Plugins.ApplicationLogs.Tests/Neo.Plugins.ApplicationLogs.Tests.csproj index 92951a59dd..7543c8487d 100644 --- a/tests/Neo.Plugins.ApplicationLogs.Tests/Neo.Plugins.ApplicationLogs.Tests.csproj +++ b/tests/Neo.Plugins.ApplicationLogs.Tests/Neo.Plugins.ApplicationLogs.Tests.csproj @@ -1,14 +1,17 @@ - net8.0 + net9.0 Neo.Plugins.ApplicationsLogs.Tests - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj b/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj index d192f37ea7..a1f18331b8 100644 --- a/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj +++ b/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj @@ -1,17 +1,17 @@ - net8.0 + net9.0 OracleService.Tests Neo.Plugins - - - - - + + + + + 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 b7e2ec91ac..0dc03fea55 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj +++ b/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj @@ -1,17 +1,17 @@ - net8.0 + net9.0 Neo.Plugins.RpcServer.Tests Neo.Plugins.RpcServer.Tests true - - - - + + + + @@ -19,5 +19,4 @@ - \ No newline at end of file diff --git a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj index 3d2031e4d5..1b2d235fd1 100644 --- a/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj +++ b/tests/Neo.Plugins.Storage.Tests/Neo.Plugins.Storage.Tests.csproj @@ -1,14 +1,14 @@ - net8.0 + net9.0 Neo.Plugins.Storage.Tests - - - + + + diff --git a/tests/Neo.UnitTests/Neo.UnitTests.csproj b/tests/Neo.UnitTests/Neo.UnitTests.csproj index 54320cd223..1345a0434e 100644 --- a/tests/Neo.UnitTests/Neo.UnitTests.csproj +++ b/tests/Neo.UnitTests/Neo.UnitTests.csproj @@ -1,14 +1,14 @@ - net8.0 + net9.0 true - - - + + + @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index ae446503e6..2447d5e251 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -82,7 +82,7 @@ public void TestRemoveHashsetHashSetCache() public void TestToHexString() { byte[] nullStr = null; - Assert.ThrowsException(() => nullStr.ToHexString()); + Assert.ThrowsException(() => nullStr.ToHexString()); byte[] empty = Array.Empty(); empty.ToHexString().Should().Be(""); empty.ToHexString(false).Should().Be(""); diff --git a/tests/Neo.VM.Tests/Neo.VM.Tests.csproj b/tests/Neo.VM.Tests/Neo.VM.Tests.csproj index 2766ce05d2..b1de7bc3cc 100644 --- a/tests/Neo.VM.Tests/Neo.VM.Tests.csproj +++ b/tests/Neo.VM.Tests/Neo.VM.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Neo.Test true @@ -17,9 +17,9 @@ - - - + + + diff --git a/tests/Neo.VM.Tests/UT_ScriptBuilder.cs b/tests/Neo.VM.Tests/UT_ScriptBuilder.cs index 6d5b4e6f2d..5903cecba8 100644 --- a/tests/Neo.VM.Tests/UT_ScriptBuilder.cs +++ b/tests/Neo.VM.Tests/UT_ScriptBuilder.cs @@ -42,6 +42,21 @@ public void TestEmit() } } + [TestMethod] + public void TestNullAndEmpty() + { + using (ScriptBuilder script = new()) + { + ReadOnlySpan span = null; + script.EmitPush(span); + + span = []; + script.EmitPush(span); + + CollectionAssert.AreEqual(new byte[] { (byte)OpCode.PUSHDATA1, 0, (byte)OpCode.PUSHDATA1, 0 }, script.ToArray()); + } + } + [TestMethod] public void TestBigInteger() { @@ -233,7 +248,8 @@ public void TestEmitPushByteArray() { using (ScriptBuilder script = new()) { - Assert.ThrowsException(() => script.EmitPush((byte[])null)); + script.EmitPush((byte[])null); + CollectionAssert.AreEqual(new byte[] { (byte)OpCode.PUSHDATA1, 0 }, script.ToArray()); } using (ScriptBuilder script = new()) diff --git a/tests/Neo.VM.Tests/UT_Utility.cs b/tests/Neo.VM.Tests/UT_Utility.cs index e87bcbcda7..8806050900 100644 --- a/tests/Neo.VM.Tests/UT_Utility.cs +++ b/tests/Neo.VM.Tests/UT_Utility.cs @@ -54,7 +54,7 @@ public void TestGetBitLength() var random = new Random(); // Big Number (net standard didn't work) - VerifyGetBitLength(BigInteger.One << 32 << int.MaxValue, 2147483680); + Assert.ThrowsException(() => VerifyGetBitLength(BigInteger.One << 32 << int.MaxValue, 2147483680)); // Trivial cases // sign bit|shortest two's complement From d862ce8e559fcf377432e8600c1dbd50d610cead Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Thu, 28 Nov 2024 04:09:28 -0500 Subject: [PATCH 06/13] Added better error handling to `Native.Ledger` (#3593) * Added better error handling to `Native.Ledger` * revert some logic --------- Co-authored-by: Shargon Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- .../SmartContract/Native/LedgerContract.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Neo/SmartContract/Native/LedgerContract.cs b/src/Neo/SmartContract/Native/LedgerContract.cs index 3d2d16e023..b10b7b7f0d 100644 --- a/src/Neo/SmartContract/Native/LedgerContract.cs +++ b/src/Neo/SmartContract/Native/LedgerContract.cs @@ -76,6 +76,9 @@ internal override ContractTask PostPersistAsync(ApplicationEngine engine) internal bool Initialized(DataCache snapshot) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + return snapshot.Find(CreateStorageKey(Prefix_Block).ToArray()).Any(); } @@ -94,6 +97,9 @@ private bool IsTraceableBlock(DataCache snapshot, uint index, uint maxTraceableB /// The hash of the block. public UInt256 GetBlockHash(DataCache snapshot, uint index) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_BlockHash).AddBigEndian(index)); if (item is null) return null; return new UInt256(item.Value.Span); @@ -107,6 +113,9 @@ public UInt256 GetBlockHash(DataCache snapshot, uint index) [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] public UInt256 CurrentHash(DataCache snapshot) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + return snapshot[CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable().Hash; } @@ -118,6 +127,9 @@ public UInt256 CurrentHash(DataCache snapshot) [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] public uint CurrentIndex(DataCache snapshot) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + return snapshot[CreateStorageKey(Prefix_CurrentBlock)].GetInteroperable().Index; } @@ -129,6 +141,9 @@ public uint CurrentIndex(DataCache snapshot) /// if the blockchain contains the block; otherwise, . public bool ContainsBlock(DataCache snapshot, UInt256 hash) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + return snapshot.Contains(CreateStorageKey(Prefix_Block).Add(hash)); } @@ -155,6 +170,12 @@ public bool ContainsTransaction(DataCache snapshot, UInt256 hash) /// if the blockchain contains the hash of the conflicting transaction; otherwise, . public bool ContainsConflictHash(DataCache snapshot, UInt256 hash, IEnumerable signers, uint maxTraceableBlocks) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + + if (signers is null) + throw new ArgumentNullException(nameof(signers)); + // Check the dummy stub firstly to define whether there's exist at least one conflict record. var stub = snapshot.TryGet(CreateStorageKey(Prefix_Transaction).Add(hash))?.GetInteroperable(); if (stub is null || stub.Transaction is not null || !IsTraceableBlock(snapshot, stub.BlockIndex, maxTraceableBlocks)) @@ -179,6 +200,9 @@ public bool ContainsConflictHash(DataCache snapshot, UInt256 hash, IEnumerableThe trimmed block. public TrimmedBlock GetTrimmedBlock(DataCache snapshot, UInt256 hash) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_Block).Add(hash)); if (item is null) return null; return item.Value.AsSerializable(); @@ -262,6 +286,9 @@ public Header GetHeader(DataCache snapshot, uint index) /// The with the specified hash. public TransactionState GetTransactionState(DataCache snapshot, UInt256 hash) { + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + var state = snapshot.TryGet(CreateStorageKey(Prefix_Transaction).Add(hash))?.GetInteroperable(); if (state?.Transaction is null) return null; return state; From 43ae8dbf16fad177c07f04b51612fb2f85308e90 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Fri, 29 Nov 2024 02:26:54 -0500 Subject: [PATCH 07/13] `[Move]` Part-7 Classes into Different Library - `Neo.Extensions` (#3446) * Part-1 `Neo.IO` - move * Part-2 * Added `BigInteger` to `Neo.Extensions` * Found more `BigInteger` * Added `ByteArray` to `Neo.Extensions` * Added `DateTime` Extensions to `Neo.Extensions` * Added `HashSetExtensions`, `HashSetExtensions2`, `IpAddressExtensions`, `AssemblyExtensions`, `StringExtensdions` Deleted `Helper.cs` file * Added `ICollection`, `Memory`, `String`, `Unsafe` extensions * Adding `using` * dotnet format * Added more Extensions * Move some methods * Added Tests * Added `tests` from `Part-2` * Added `tests` for `PART-4` * Added `tests` for `PART-5` * Added the `Part` 7 * revert `OrCondition.cs` * revert `OrCondition.cs` * Update tests/Neo.Extensions.Tests/UT_BigIntegerExtensions.cs --------- Co-authored-by: Shargon Co-authored-by: Jimmy --- src/Neo.GUI/GUI/ElectionDialog.cs | 2 +- src/Neo.GUI/GUI/VotingDialog.cs | 2 +- .../Collections/ICollectionExtensions.cs | 1 + .../Extensions/VM/ScriptBuilderExtensions.cs | 306 ++++++++++++++++++ .../ContractParametersContext.cs | 1 + src/Neo/SmartContract/Helper.cs | 1 + src/Neo/VM/Helper.cs | 282 ---------------- src/Neo/Wallets/AssetDescriptor.cs | 1 + src/Plugins/RpcClient/ContractClient.cs | 1 + .../E2E_Https.cs | 1 + .../TestBlockchain.cs | 1 + .../Nep17NativeContractExtensions.cs | 1 + .../SmartContract/Native/UT_NativeContract.cs | 1 + .../UT_ApplicationEngine.Contract.cs | 1 + .../SmartContract/UT_ApplicationEngine.cs | 1 + .../SmartContract/UT_Contract.cs | 1 + tests/Neo.UnitTests/VM/UT_Helper.cs | 18 +- 17 files changed, 329 insertions(+), 293 deletions(-) create mode 100644 src/Neo/Extensions/VM/ScriptBuilderExtensions.cs diff --git a/src/Neo.GUI/GUI/ElectionDialog.cs b/src/Neo.GUI/GUI/ElectionDialog.cs index ddc730589e..ef644074d9 100644 --- a/src/Neo.GUI/GUI/ElectionDialog.cs +++ b/src/Neo.GUI/GUI/ElectionDialog.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract.Native; using Neo.VM; using System; diff --git a/src/Neo.GUI/GUI/VotingDialog.cs b/src/Neo.GUI/GUI/VotingDialog.cs index d289cc48ca..ff5749e181 100644 --- a/src/Neo.GUI/GUI/VotingDialog.cs +++ b/src/Neo.GUI/GUI/VotingDialog.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/src/Neo/Extensions/Collections/ICollectionExtensions.cs b/src/Neo/Extensions/Collections/ICollectionExtensions.cs index 724def6d80..742446a4e8 100644 --- a/src/Neo/Extensions/Collections/ICollectionExtensions.cs +++ b/src/Neo/Extensions/Collections/ICollectionExtensions.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.Collections.Generic; using System.IO; diff --git a/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs new file mode 100644 index 0000000000..ee64bb5736 --- /dev/null +++ b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs @@ -0,0 +1,306 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ScriptBuilderExtensions.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; +using Neo.IO; +using Neo.SmartContract; +using Neo.VM; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +namespace Neo.Extensions +{ + public static class ScriptBuilderExtensions + { + /// + /// Emits the opcodes for creating an array. + /// + /// The type of the elements of the array. + /// The to be used. + /// The elements of the array. + /// The same instance as . + public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList list = null) + { + if (list is null || list.Count == 0) + return builder.Emit(OpCode.NEWARRAY0); + for (var i = list.Count - 1; i >= 0; i--) + builder.EmitPush(list[i]); + builder.EmitPush(list.Count); + return builder.Emit(OpCode.PACK); + } + + /// + /// Emits the opcodes for creating a map. + /// + /// The type of the key of the map. + /// The type of the value of the map. + /// The to be used. + /// The key/value pairs of the map. + /// The same instance as . + public static ScriptBuilder CreateMap(this ScriptBuilder builder, IEnumerable> map) + where TKey : notnull + where TValue : notnull + { + var count = map.Count(); + + if (count == 0) + return builder.Emit(OpCode.NEWMAP); + + foreach (var (key, value) in map.Reverse()) + { + builder.EmitPush(value); + builder.EmitPush(key); + } + builder.EmitPush(count); + return builder.Emit(OpCode.PACKMAP); + } + + /// + /// Emits the opcodes for creating a map. + /// + /// The type of the key of the map. + /// The type of the value of the map. + /// The to be used. + /// The key/value pairs of the map. + /// The same instance as . + public static ScriptBuilder CreateMap(this ScriptBuilder builder, IReadOnlyDictionary map) + where TKey : notnull + where TValue : notnull + { + if (map.Count == 0) + return builder.Emit(OpCode.NEWMAP); + + foreach (var (key, value) in map.Reverse()) + { + builder.EmitPush(value); + builder.EmitPush(key); + } + builder.EmitPush(map.Count); + return builder.Emit(OpCode.PACKMAP); + } + + /// + /// Emits the opcodes for creating a struct. + /// + /// The type of the property. + /// The to be used. + /// The list of properties. + /// The same instance as . + public static ScriptBuilder CreateStruct(this ScriptBuilder builder, IReadOnlyList array) + where T : notnull + { + if (array.Count == 0) + return builder.Emit(OpCode.NEWSTRUCT0); + for (var i = array.Count - 1; i >= 0; i--) + builder.EmitPush(array[i]); + builder.EmitPush(array.Count); + return builder.Emit(OpCode.PACKSTRUCT); + } + + /// + /// Emits the specified opcodes. + /// + /// The to be used. + /// The opcodes to emit. + /// The same instance as . + public static ScriptBuilder Emit(this ScriptBuilder builder, params OpCode[] ops) + { + foreach (var op in ops) + builder.Emit(op); + return builder; + } + + /// + /// Emits the opcodes for calling a contract dynamically. + /// + /// The to be used. + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The arguments for calling the contract. + /// The same instance as . + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object[] args) + { + return EmitDynamicCall(builder, scriptHash, method, CallFlags.All, args); + } + + /// + /// Emits the opcodes for calling a contract dynamically. + /// + /// The to be used. + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The for calling the contract. + /// The arguments for calling the contract. + /// The same instance as . + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object[] args) + { + builder.CreateArray(args); + builder.EmitPush(flags); + builder.EmitPush(method); + builder.EmitPush(scriptHash); + builder.EmitSysCall(ApplicationEngine.System_Contract_Call); + return builder; + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, ISerializable data) + { + return builder.EmitPush(data.ToArray()); + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParameter parameter) + { + if (parameter.Value is null) + builder.Emit(OpCode.PUSHNULL); + else + switch (parameter.Type) + { + case ContractParameterType.Signature: + case ContractParameterType.ByteArray: + builder.EmitPush((byte[])parameter.Value); + break; + case ContractParameterType.Boolean: + builder.EmitPush((bool)parameter.Value); + break; + case ContractParameterType.Integer: + if (parameter.Value is BigInteger bi) + builder.EmitPush(bi); + else + builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor([parameter.Value.GetType()]).Invoke([parameter.Value])); + break; + case ContractParameterType.Hash160: + builder.EmitPush((UInt160)parameter.Value); + break; + case ContractParameterType.Hash256: + builder.EmitPush((UInt256)parameter.Value); + break; + case ContractParameterType.PublicKey: + builder.EmitPush((ECPoint)parameter.Value); + break; + case ContractParameterType.String: + builder.EmitPush((string)parameter.Value); + break; + case ContractParameterType.Array: + { + var parameters = (IList)parameter.Value; + for (var i = parameters.Count - 1; i >= 0; i--) + builder.EmitPush(parameters[i]); + builder.EmitPush(parameters.Count); + builder.Emit(OpCode.PACK); + } + break; + case ContractParameterType.Map: + { + var pairs = (IList>)parameter.Value; + builder.CreateMap(pairs); + } + break; + default: + throw new ArgumentException(null, nameof(parameter)); + } + return builder; + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) + { + switch (obj) + { + case bool data: + builder.EmitPush(data); + break; + case byte[] data: + builder.EmitPush(data); + break; + case string data: + builder.EmitPush(data); + break; + case BigInteger data: + builder.EmitPush(data); + break; + case ISerializable data: + builder.EmitPush(data); + break; + case sbyte data: + builder.EmitPush(data); + break; + case byte data: + builder.EmitPush(data); + break; + case short data: + builder.EmitPush(data); + break; + case char data: + builder.EmitPush(data); + break; + case ushort data: + builder.EmitPush(data); + break; + case int data: + builder.EmitPush(data); + break; + case uint data: + builder.EmitPush(data); + break; + case long data: + builder.EmitPush(data); + break; + case ulong data: + builder.EmitPush(data); + break; + case Enum data: + builder.EmitPush(BigInteger.Parse(data.ToString("d"))); + break; + case ContractParameter data: + builder.EmitPush(data); + break; + case null: + builder.Emit(OpCode.PUSHNULL); + break; + default: + throw new ArgumentException(null, nameof(obj)); + } + return builder; + } + + /// + /// Emits the opcodes for invoking an interoperable service. + /// + /// The to be used. + /// The hash of the interoperable service. + /// The arguments for calling the interoperable service. + /// The same instance as . + public static ScriptBuilder EmitSysCall(this ScriptBuilder builder, uint method, params object[] args) + { + for (var i = args.Length - 1; i >= 0; i--) + EmitPush(builder, args[i]); + return builder.EmitSysCall(method); + } + } +} diff --git a/src/Neo/SmartContract/ContractParametersContext.cs b/src/Neo/SmartContract/ContractParametersContext.cs index c4129f0ad1..ea5ea35ab8 100644 --- a/src/Neo/SmartContract/ContractParametersContext.cs +++ b/src/Neo/SmartContract/ContractParametersContext.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs index d0bc3c939b..96ec2af03c 100644 --- a/src/Neo/SmartContract/Helper.cs +++ b/src/Neo/SmartContract/Helper.cs @@ -11,6 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract.Manifest; diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 0a9a106e1f..3ac202a818 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -11,7 +11,6 @@ using Neo.Cryptography.ECC; using Neo.Extensions; -using Neo.IO; using Neo.Json; using Neo.SmartContract; using Neo.VM.Types; @@ -30,287 +29,6 @@ namespace Neo.VM /// public static class Helper { - /// - /// Emits the opcodes for creating an array. - /// - /// The type of the elements of the array. - /// The to be used. - /// The elements of the array. - /// The same instance as . - public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList list = null) - { - if (list is null || list.Count == 0) - return builder.Emit(OpCode.NEWARRAY0); - for (int i = list.Count - 1; i >= 0; i--) - builder.EmitPush(list[i]); - builder.EmitPush(list.Count); - return builder.Emit(OpCode.PACK); - } - - /// - /// Emits the opcodes for creating a map. - /// - /// The type of the key of the map. - /// The type of the value of the map. - /// The to be used. - /// The key/value pairs of the map. - /// The same instance as . - public static ScriptBuilder CreateMap(this ScriptBuilder builder, IEnumerable> map) - where TKey : notnull - where TValue : notnull - { - var count = map.Count(); - - if (count == 0) - return builder.Emit(OpCode.NEWMAP); - - foreach (var (key, value) in map.Reverse()) - { - builder.EmitPush(value); - builder.EmitPush(key); - } - builder.EmitPush(count); - return builder.Emit(OpCode.PACKMAP); - } - - /// - /// Emits the opcodes for creating a map. - /// - /// The type of the key of the map. - /// The type of the value of the map. - /// The to be used. - /// The key/value pairs of the map. - /// The same instance as . - public static ScriptBuilder CreateMap(this ScriptBuilder builder, IReadOnlyDictionary map) - where TKey : notnull - where TValue : notnull - { - if (map.Count == 0) - return builder.Emit(OpCode.NEWMAP); - - foreach (var (key, value) in map.Reverse()) - { - builder.EmitPush(value); - builder.EmitPush(key); - } - builder.EmitPush(map.Count); - return builder.Emit(OpCode.PACKMAP); - } - - /// - /// Emits the opcodes for creating a struct. - /// - /// The type of the property. - /// The to be used. - /// The list of properties. - /// The same instance as . - public static ScriptBuilder CreateStruct(this ScriptBuilder builder, IReadOnlyList array) - where T : notnull - { - if (array.Count == 0) - return builder.Emit(OpCode.NEWSTRUCT0); - for (var i = array.Count - 1; i >= 0; i--) - builder.EmitPush(array[i]); - builder.EmitPush(array.Count); - return builder.Emit(OpCode.PACKSTRUCT); - } - - /// - /// Emits the specified opcodes. - /// - /// The to be used. - /// The opcodes to emit. - /// The same instance as . - public static ScriptBuilder Emit(this ScriptBuilder builder, params OpCode[] ops) - { - foreach (OpCode op in ops) - builder.Emit(op); - return builder; - } - - /// - /// Emits the opcodes for calling a contract dynamically. - /// - /// The to be used. - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The arguments for calling the contract. - /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object[] args) - { - return EmitDynamicCall(builder, scriptHash, method, CallFlags.All, args); - } - - /// - /// Emits the opcodes for calling a contract dynamically. - /// - /// The to be used. - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The for calling the contract. - /// The arguments for calling the contract. - /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object[] args) - { - builder.CreateArray(args); - builder.EmitPush(flags); - builder.EmitPush(method); - builder.EmitPush(scriptHash); - builder.EmitSysCall(ApplicationEngine.System_Contract_Call); - return builder; - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, ISerializable data) - { - return builder.EmitPush(data.ToArray()); - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParameter parameter) - { - if (parameter.Value is null) - builder.Emit(OpCode.PUSHNULL); - else - switch (parameter.Type) - { - case ContractParameterType.Signature: - case ContractParameterType.ByteArray: - builder.EmitPush((byte[])parameter.Value); - break; - case ContractParameterType.Boolean: - builder.EmitPush((bool)parameter.Value); - break; - case ContractParameterType.Integer: - if (parameter.Value is BigInteger bi) - builder.EmitPush(bi); - else - builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor(new[] { parameter.Value.GetType() }).Invoke(new[] { parameter.Value })); - break; - case ContractParameterType.Hash160: - builder.EmitPush((UInt160)parameter.Value); - break; - case ContractParameterType.Hash256: - builder.EmitPush((UInt256)parameter.Value); - break; - case ContractParameterType.PublicKey: - builder.EmitPush((ECPoint)parameter.Value); - break; - case ContractParameterType.String: - builder.EmitPush((string)parameter.Value); - break; - case ContractParameterType.Array: - { - IList parameters = (IList)parameter.Value; - for (int i = parameters.Count - 1; i >= 0; i--) - builder.EmitPush(parameters[i]); - builder.EmitPush(parameters.Count); - builder.Emit(OpCode.PACK); - } - break; - case ContractParameterType.Map: - { - var pairs = (IList>)parameter.Value; - builder.CreateMap(pairs); - } - break; - default: - throw new ArgumentException(null, nameof(parameter)); - } - return builder; - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) - { - switch (obj) - { - case bool data: - builder.EmitPush(data); - break; - case byte[] data: - builder.EmitPush(data); - break; - case string data: - builder.EmitPush(data); - break; - case BigInteger data: - builder.EmitPush(data); - break; - case ISerializable data: - builder.EmitPush(data); - break; - case sbyte data: - builder.EmitPush(data); - break; - case byte data: - builder.EmitPush(data); - break; - case short data: - builder.EmitPush(data); - break; - case char data: - builder.EmitPush(data); - break; - case ushort data: - builder.EmitPush(data); - break; - case int data: - builder.EmitPush(data); - break; - case uint data: - builder.EmitPush(data); - break; - case long data: - builder.EmitPush(data); - break; - case ulong data: - builder.EmitPush(data); - break; - case Enum data: - builder.EmitPush(BigInteger.Parse(data.ToString("d"))); - break; - case ContractParameter data: - builder.EmitPush(data); - break; - case null: - builder.Emit(OpCode.PUSHNULL); - break; - default: - throw new ArgumentException(null, nameof(obj)); - } - return builder; - } - - /// - /// Emits the opcodes for invoking an interoperable service. - /// - /// The to be used. - /// The hash of the interoperable service. - /// The arguments for calling the interoperable service. - /// The same instance as . - public static ScriptBuilder EmitSysCall(this ScriptBuilder builder, uint method, params object[] args) - { - for (int i = args.Length - 1; i >= 0; i--) - EmitPush(builder, args[i]); - return builder.EmitSysCall(method); - } - /// /// Generates the script for calling a contract dynamically. /// diff --git a/src/Neo/Wallets/AssetDescriptor.cs b/src/Neo/Wallets/AssetDescriptor.cs index 7b9be7b16b..e8ba27b4e4 100644 --- a/src/Neo/Wallets/AssetDescriptor.cs +++ b/src/Neo/Wallets/AssetDescriptor.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/src/Plugins/RpcClient/ContractClient.cs b/src/Plugins/RpcClient/ContractClient.cs index f4ec020abc..02b8edc5ef 100644 --- a/src/Plugins/RpcClient/ContractClient.cs +++ b/src/Plugins/RpcClient/ContractClient.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; diff --git a/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs b/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs index c404f3f982..b9e2d407f8 100644 --- a/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs +++ b/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs @@ -14,6 +14,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs b/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs index 160ac0407e..229a5f361d 100644 --- a/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs +++ b/tests/Neo.Plugins.OracleService.Tests/TestBlockchain.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.Actor; +using Neo.Extensions; using Neo.Ledger; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs index a3f33f26a7..d32e16d0c6 100644 --- a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs @@ -10,6 +10,7 @@ // modifications are permitted. using FluentAssertions; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index f9a3089f9d..64d6338f0c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs index f9dc5e7b46..2d71b97e25 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.VM; using System.Linq; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index def978596e..26df1a1639 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Manifest; using Neo.UnitTests.Extensions; diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs index 07ae320a0f..ecd8532faa 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/VM/UT_Helper.cs b/tests/Neo.UnitTests/VM/UT_Helper.cs index cabe0c7a02..cd7b8f01bb 100644 --- a/tests/Neo.UnitTests/VM/UT_Helper.cs +++ b/tests/Neo.UnitTests/VM/UT_Helper.cs @@ -452,7 +452,7 @@ private void TestEmitPush3Ulong() { ScriptBuilder sb = new ScriptBuilder(); ulong temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -462,7 +462,7 @@ private void TestEmitPush3Long() { ScriptBuilder sb = new ScriptBuilder(); long temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -472,7 +472,7 @@ private void TestEmitPush3Uint() { ScriptBuilder sb = new ScriptBuilder(); uint temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -482,7 +482,7 @@ private void TestEmitPush3Int() { ScriptBuilder sb = new ScriptBuilder(); int temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -492,7 +492,7 @@ private void TestEmitPush3Ushort() { ScriptBuilder sb = new ScriptBuilder(); ushort temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -502,7 +502,7 @@ private void TestEmitPush3Char() { ScriptBuilder sb = new ScriptBuilder(); char temp = char.MinValue; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -512,7 +512,7 @@ private void TestEmitPush3Short() { ScriptBuilder sb = new ScriptBuilder(); short temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -522,7 +522,7 @@ private void TestEmitPush3Byte() { ScriptBuilder sb = new ScriptBuilder(); byte temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -532,7 +532,7 @@ private void TestEmitPush3Sbyte() { ScriptBuilder sb = new ScriptBuilder(); sbyte temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); From 116c219a41e6650feeea7d0d73757081aabac3ab Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sat, 30 Nov 2024 16:12:42 +0800 Subject: [PATCH 08/13] [Core Plugin] adopt more change from pr 3414 (#3591) * adapt more change from pr 3414 * Update src/Plugins/LevelDBStore/Plugins/Storage/Store.cs * Remove two memory leaks and avoid iterate without specify the snapshot --------- Co-authored-by: Shargon --- .../LevelDBStore/IO/Data/LevelDB/DB.cs | 23 ++- .../LevelDBStore/IO/Data/LevelDB/Helper.cs | 19 +-- .../LevelDBStore/IO/Data/LevelDB/Iterator.cs | 2 +- .../IO/Data/LevelDB/LevelDBException.cs | 2 +- .../IO/Data/LevelDB/LevelDBHandle.cs | 2 +- .../LevelDBStore/IO/Data/LevelDB/Native.cs | 142 +++++++++--------- .../LevelDBStore/IO/Data/LevelDB/Options.cs | 2 +- .../IO/Data/LevelDB/ReadOptions.cs | 2 +- .../LevelDBStore/IO/Data/LevelDB/Snapshot.cs | 2 +- .../IO/Data/LevelDB/WriteBatch.cs | 2 +- .../IO/Data/LevelDB/WriteOptions.cs | 2 +- .../Plugins/Storage/LevelDBStore.cs | 2 +- .../LevelDBStore/Plugins/Storage/Snapshot.cs | 7 +- .../LevelDBStore/Plugins/Storage/Store.cs | 14 +- 14 files changed, 118 insertions(+), 105 deletions(-) diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs index ecb79344cc..583385d34a 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs @@ -9,10 +9,13 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +#nullable enable + using System; +using System.Collections.Generic; using System.IO; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// A DB is a persistent ordered map from keys to values. @@ -90,9 +93,9 @@ public static DB Open(string name) public static DB Open(string name, Options options) { - var Handle = Native.leveldb_open(options.Handle, Path.GetFullPath(name), out var error); + var handle = Native.leveldb_open(options.Handle, Path.GetFullPath(name), out var error); NativeHelper.CheckError(error); - return new DB(Handle); + return new DB(handle); } /// @@ -122,5 +125,19 @@ public void Write(WriteOptions options, WriteBatch write_batch) Native.leveldb_write(Handle, options.Handle, write_batch.Handle, out var error); NativeHelper.CheckError(error); } + + public IEnumerable> GetAll(Snapshot? snapshot = null) + { + using var options = new ReadOptions(); + if (snapshot != null) options.Snapshot = snapshot; + + using var iterator = NewIterator(options); + iterator.SeekToFirst(); + while (iterator.Valid()) + { + yield return new KeyValuePair(iterator.Key(), iterator.Value()); + iterator.Next(); + } + } } } diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs index 2ac3a0005f..907452353a 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs @@ -14,17 +14,17 @@ using System.Collections.Generic; using System.Runtime.InteropServices; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { public static class Helper { - public static IEnumerable Seek(this DB db, ReadOptions options, byte[] prefix, SeekDirection direction, Func resultSelector) + public static IEnumerable<(byte[], byte[])> Seek(this DB db, ReadOptions options, byte[] prefix, SeekDirection direction) { using Iterator it = db.NewIterator(options); if (direction == SeekDirection.Forward) { for (it.Seek(prefix); it.Valid(); it.Next()) - yield return resultSelector(it.Key(), it.Value()); + yield return new(it.Key(), it.Value()); } else { @@ -37,18 +37,7 @@ public static IEnumerable Seek(this DB db, ReadOptions options, byte[] pre it.Prev(); for (; it.Valid(); it.Prev()) - yield return resultSelector(it.Key(), it.Value()); - } - } - - public static IEnumerable FindRange(this DB db, ReadOptions options, byte[] startKey, byte[] endKey, Func resultSelector) - { - using Iterator it = db.NewIterator(options); - for (it.Seek(startKey); it.Valid(); it.Next()) - { - byte[] key = it.Key(); - if (key.AsSpan().SequenceCompareTo(endKey) > 0) break; - yield return resultSelector(key, it.Value()); + yield return new(it.Key(), it.Value()); } } diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs index d3e36a3a9c..2fa007af7c 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs @@ -11,7 +11,7 @@ using System; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// An iterator yields a sequence of key/value pairs from a database. diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBException.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBException.cs index c9cca42070..ba900a655e 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBException.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBException.cs @@ -11,7 +11,7 @@ using System.Data.Common; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { public class LevelDBException : DbException { diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBHandle.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBHandle.cs index 2f8aa9e4db..6868eae884 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBHandle.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/LevelDBHandle.cs @@ -11,7 +11,7 @@ using System; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// Base class for all LevelDB objects diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs index acf8fa82b9..bf91524fae 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs @@ -13,7 +13,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { public enum CompressionType : byte { @@ -25,56 +25,56 @@ public static class Native { #region Logger [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_logger_create(IntPtr /* Action */ logger); + public static extern nint leveldb_logger_create(nint /* Action */ logger); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_logger_destroy(IntPtr /* logger*/ option); + public static extern void leveldb_logger_destroy(nint /* logger*/ option); #endregion #region DB [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_open(IntPtr /* Options*/ options, string name, out IntPtr error); + public static extern nint leveldb_open(nint /* Options*/ options, string name, out nint error); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_close(IntPtr /*DB */ db); + public static extern void leveldb_close(nint /*DB */ db); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_put(IntPtr /* DB */ db, IntPtr /* WriteOptions*/ options, byte[] key, UIntPtr keylen, byte[] val, UIntPtr vallen, out IntPtr errptr); + public static extern void leveldb_put(nint /* DB */ db, nint /* WriteOptions*/ options, byte[] key, UIntPtr keylen, byte[] val, UIntPtr vallen, out nint errptr); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_delete(IntPtr /* DB */ db, IntPtr /* WriteOptions*/ options, byte[] key, UIntPtr keylen, out IntPtr errptr); + public static extern void leveldb_delete(nint /* DB */ db, nint /* WriteOptions*/ options, byte[] key, UIntPtr keylen, out nint errptr); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_write(IntPtr /* DB */ db, IntPtr /* WriteOptions*/ options, IntPtr /* WriteBatch */ batch, out IntPtr errptr); + public static extern void leveldb_write(nint /* DB */ db, nint /* WriteOptions*/ options, nint /* WriteBatch */ batch, out nint errptr); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_get(IntPtr /* DB */ db, IntPtr /* ReadOptions*/ options, byte[] key, UIntPtr keylen, out UIntPtr vallen, out IntPtr errptr); + public static extern nint leveldb_get(nint /* DB */ db, nint /* ReadOptions*/ options, byte[] key, UIntPtr keylen, out UIntPtr vallen, out nint errptr); //[DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - //static extern void leveldb_approximate_sizes(IntPtr /* DB */ db, int num_ranges, byte[] range_start_key, long range_start_key_len, byte[] range_limit_key, long range_limit_key_len, out long sizes); + //static extern void leveldb_approximate_sizes(nint /* DB */ db, int num_ranges, byte[] range_start_key, long range_start_key_len, byte[] range_limit_key, long range_limit_key_len, out long sizes); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_create_iterator(IntPtr /* DB */ db, IntPtr /* ReadOption */ options); + public static extern nint leveldb_create_iterator(nint /* DB */ db, nint /* ReadOption */ options); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_create_snapshot(IntPtr /* DB */ db); + public static extern nint leveldb_create_snapshot(nint /* DB */ db); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_release_snapshot(IntPtr /* DB */ db, IntPtr /* SnapShot*/ snapshot); + public static extern void leveldb_release_snapshot(nint /* DB */ db, nint /* SnapShot*/ snapshot); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_property_value(IntPtr /* DB */ db, string propname); + public static extern nint leveldb_property_value(nint /* DB */ db, string propname); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_repair_db(IntPtr /* Options*/ options, string name, out IntPtr error); + public static extern void leveldb_repair_db(nint /* Options*/ options, string name, out nint error); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_destroy_db(IntPtr /* Options*/ options, string name, out IntPtr error); + public static extern void leveldb_destroy_db(nint /* Options*/ options, string name, out nint error); - #region extensions + #region extensions [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_free(IntPtr /* void */ ptr); + public static extern void leveldb_free(nint /* void */ ptr); #endregion @@ -83,167 +83,167 @@ public static class Native #region Env [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_create_default_env(); + public static extern nint leveldb_create_default_env(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_env_destroy(IntPtr /*Env*/ cache); + public static extern void leveldb_env_destroy(nint /*Env*/ cache); #endregion #region Iterator [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_destroy(IntPtr /*Iterator*/ iterator); + public static extern void leveldb_iter_destroy(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool leveldb_iter_valid(IntPtr /*Iterator*/ iterator); + public static extern bool leveldb_iter_valid(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_seek_to_first(IntPtr /*Iterator*/ iterator); + public static extern void leveldb_iter_seek_to_first(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_seek_to_last(IntPtr /*Iterator*/ iterator); + public static extern void leveldb_iter_seek_to_last(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_seek(IntPtr /*Iterator*/ iterator, byte[] key, UIntPtr length); + public static extern void leveldb_iter_seek(nint /*Iterator*/ iterator, byte[] key, UIntPtr length); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_next(IntPtr /*Iterator*/ iterator); + public static extern void leveldb_iter_next(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_prev(IntPtr /*Iterator*/ iterator); + public static extern void leveldb_iter_prev(nint /*Iterator*/ iterator); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_iter_key(IntPtr /*Iterator*/ iterator, out UIntPtr length); + public static extern nint leveldb_iter_key(nint /*Iterator*/ iterator, out UIntPtr length); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_iter_value(IntPtr /*Iterator*/ iterator, out UIntPtr length); + public static extern nint leveldb_iter_value(nint /*Iterator*/ iterator, out UIntPtr length); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_iter_get_error(IntPtr /*Iterator*/ iterator, out IntPtr error); + public static extern void leveldb_iter_get_error(nint /*Iterator*/ iterator, out nint error); #endregion #region Options [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_options_create(); + public static extern nint leveldb_options_create(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_destroy(IntPtr /*Options*/ options); + public static extern void leveldb_options_destroy(nint /*Options*/ options); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_create_if_missing(IntPtr /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_options_set_create_if_missing(nint /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_error_if_exists(IntPtr /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_options_set_error_if_exists(nint /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_info_log(IntPtr /*Options*/ options, IntPtr /* Logger */ logger); + public static extern void leveldb_options_set_info_log(nint /*Options*/ options, nint /* Logger */ logger); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_paranoid_checks(IntPtr /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_options_set_paranoid_checks(nint /*Options*/ options, [MarshalAs(UnmanagedType.U1)] bool o); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_env(IntPtr /*Options*/ options, IntPtr /*Env*/ env); + public static extern void leveldb_options_set_env(nint /*Options*/ options, nint /*Env*/ env); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_write_buffer_size(IntPtr /*Options*/ options, UIntPtr size); + public static extern void leveldb_options_set_write_buffer_size(nint /*Options*/ options, UIntPtr size); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_max_open_files(IntPtr /*Options*/ options, int max); + public static extern void leveldb_options_set_max_open_files(nint /*Options*/ options, int max); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_cache(IntPtr /*Options*/ options, IntPtr /*Cache*/ cache); + public static extern void leveldb_options_set_cache(nint /*Options*/ options, nint /*Cache*/ cache); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_block_size(IntPtr /*Options*/ options, UIntPtr size); + public static extern void leveldb_options_set_block_size(nint /*Options*/ options, UIntPtr size); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_block_restart_interval(IntPtr /*Options*/ options, int interval); + public static extern void leveldb_options_set_block_restart_interval(nint /*Options*/ options, int interval); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_compression(IntPtr /*Options*/ options, CompressionType level); + public static extern void leveldb_options_set_compression(nint /*Options*/ options, CompressionType level); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_comparator(IntPtr /*Options*/ options, IntPtr /*Comparator*/ comparer); + public static extern void leveldb_options_set_comparator(nint /*Options*/ options, nint /*Comparator*/ comparer); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_options_set_filter_policy(IntPtr /*Options*/ options, IntPtr /*FilterPolicy*/ policy); + public static extern void leveldb_options_set_filter_policy(nint /*Options*/ options, nint /*FilterPolicy*/ policy); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_filterpolicy_create_bloom(int bits_per_key); + public static extern nint leveldb_filterpolicy_create_bloom(int bits_per_key); #endregion #region ReadOptions [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_readoptions_create(); + public static extern nint leveldb_readoptions_create(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_readoptions_destroy(IntPtr /*ReadOptions*/ options); + public static extern void leveldb_readoptions_destroy(nint /*ReadOptions*/ options); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_readoptions_set_verify_checksums(IntPtr /*ReadOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_readoptions_set_verify_checksums(nint /*ReadOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_readoptions_set_fill_cache(IntPtr /*ReadOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_readoptions_set_fill_cache(nint /*ReadOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_readoptions_set_snapshot(IntPtr /*ReadOptions*/ options, IntPtr /*SnapShot*/ snapshot); + public static extern void leveldb_readoptions_set_snapshot(nint /*ReadOptions*/ options, nint /*SnapShot*/ snapshot); #endregion #region WriteBatch [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_writebatch_create(); + public static extern nint leveldb_writebatch_create(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writebatch_destroy(IntPtr /* WriteBatch */ batch); + public static extern void leveldb_writebatch_destroy(nint /* WriteBatch */ batch); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writebatch_clear(IntPtr /* WriteBatch */ batch); + public static extern void leveldb_writebatch_clear(nint /* WriteBatch */ batch); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writebatch_put(IntPtr /* WriteBatch */ batch, byte[] key, UIntPtr keylen, byte[] val, UIntPtr vallen); + public static extern void leveldb_writebatch_put(nint /* WriteBatch */ batch, byte[] key, UIntPtr keylen, byte[] val, UIntPtr vallen); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writebatch_delete(IntPtr /* WriteBatch */ batch, byte[] key, UIntPtr keylen); + public static extern void leveldb_writebatch_delete(nint /* WriteBatch */ batch, byte[] key, UIntPtr keylen); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writebatch_iterate(IntPtr /* WriteBatch */ batch, object state, Action put, Action deleted); + public static extern void leveldb_writebatch_iterate(nint /* WriteBatch */ batch, object state, Action put, Action deleted); #endregion #region WriteOptions [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_writeoptions_create(); + public static extern nint leveldb_writeoptions_create(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writeoptions_destroy(IntPtr /*WriteOptions*/ options); + public static extern void leveldb_writeoptions_destroy(nint /*WriteOptions*/ options); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_writeoptions_set_sync(IntPtr /*WriteOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + public static extern void leveldb_writeoptions_set_sync(nint /*WriteOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); #endregion - #region Cache + #region Cache [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr leveldb_cache_create_lru(int capacity); + public static extern nint leveldb_cache_create_lru(int capacity); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_cache_destroy(IntPtr /*Cache*/ cache); + public static extern void leveldb_cache_destroy(nint /*Cache*/ cache); #endregion #region Comparator [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr /* leveldb_comparator_t* */ + public static extern nint /* leveldb_comparator_t* */ leveldb_comparator_create( - IntPtr /* void* */ state, - IntPtr /* void (*)(void*) */ destructor, - IntPtr + nint /* void* */ state, + nint /* void (*)(void*) */ destructor, + nint /* int (*compare)(void*, const char* a, size_t alen, const char* b, size_t blen) */ compare, - IntPtr /* const char* (*)(void*) */ name); + nint /* const char* (*)(void*) */ name); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] - public static extern void leveldb_comparator_destroy(IntPtr /* leveldb_comparator_t* */ cmp); + public static extern void leveldb_comparator_destroy(nint /* leveldb_comparator_t* */ cmp); #endregion } @@ -251,9 +251,9 @@ public static extern IntPtr /* leveldb_comparator_t* */ internal static class NativeHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CheckError(IntPtr error) + public static void CheckError(nint error) { - if (error != IntPtr.Zero) + if (error != nint.Zero) { string message = Marshal.PtrToStringAnsi(error); Native.leveldb_free(error); diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Options.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Options.cs index 99c7fb2739..2c91d2f9b8 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Options.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Options.cs @@ -11,7 +11,7 @@ using System; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// Options to control the behavior of a database (passed to Open) diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/ReadOptions.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/ReadOptions.cs index 9a1d48f76e..2a219fa1df 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/ReadOptions.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/ReadOptions.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// Options that control read operations. diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Snapshot.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Snapshot.cs index e9ca8d1ff6..668f06718b 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Snapshot.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Snapshot.cs @@ -11,7 +11,7 @@ using System; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// A Snapshot is an immutable object and can therefore be safely diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteBatch.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteBatch.cs index 7e9c04305b..300476a5f1 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteBatch.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteBatch.cs @@ -11,7 +11,7 @@ using System; -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// WriteBatch holds a collection of updates to apply atomically to a DB. diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteOptions.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteOptions.cs index 994a97d8a2..a4a304ad33 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteOptions.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/WriteOptions.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -namespace Neo.IO.Data.LevelDB +namespace Neo.IO.Storage.LevelDB { /// /// Options that control write operations. diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs b/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs index 9c676e8a7f..6f39abd6af 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO.Data.LevelDB; +using Neo.IO.Storage.LevelDB; using Neo.Persistence; using System; using System.Linq; diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs index 4f7c73d820..fd7febd451 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs @@ -9,10 +9,10 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO.Data.LevelDB; +using Neo.IO.Storage.LevelDB; using Neo.Persistence; using System.Collections.Generic; -using LSnapshot = Neo.IO.Data.LevelDB.Snapshot; +using LSnapshot = Neo.IO.Storage.LevelDB.Snapshot; namespace Neo.Plugins.Storage { @@ -44,11 +44,12 @@ public void Delete(byte[] key) public void Dispose() { _snapshot.Dispose(); + _options.Dispose(); } public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] prefix, SeekDirection direction = SeekDirection.Forward) { - return _db.Seek(_options, prefix, direction, (k, v) => (k, v)); + return _db.Seek(_options, prefix, direction); } public void Put(byte[] key, byte[] value) diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs index 337a598a61..c77a6beeb1 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO.Data.LevelDB; +using Neo.IO.Storage.LevelDB; using Neo.Persistence; using System.Collections.Generic; @@ -18,10 +18,12 @@ namespace Neo.Plugins.Storage internal class Store : IStore { private readonly DB _db; + private readonly Options _options; public Store(string path) { - _db = DB.Open(path, new Options { CreateIfMissing = true, FilterPolicy = Native.leveldb_filterpolicy_create_bloom(15) }); + _options = new Options { CreateIfMissing = true, FilterPolicy = Native.leveldb_filterpolicy_create_bloom(15) }; + _db = DB.Open(path, _options); } public void Delete(byte[] key) @@ -29,7 +31,11 @@ public void Delete(byte[] key) _db.Delete(WriteOptions.Default, key); } - public void Dispose() => _db.Dispose(); + public void Dispose() + { + _db.Dispose(); + _options.Dispose(); + } public ISnapshot GetSnapshot() => new Snapshot(_db); @@ -53,6 +59,6 @@ public bool TryGet(byte[] key, out byte[] value) } public IEnumerable<(byte[], byte[])> Seek(byte[] prefix, SeekDirection direction = SeekDirection.Forward) => - _db.Seek(ReadOptions.Default, prefix, direction, (k, v) => (k, v)); + _db.Seek(ReadOptions.Default, prefix, direction); } } From 6cafc3be851919d642637ec7214fcb992a976f3d Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sat, 30 Nov 2024 03:43:19 -0500 Subject: [PATCH 09/13] Revert "[Remove] obsolete `WsServer` (#3582)" (#3603) This reverts commit 849b2c8d63e53a1311b529e3764067f55d285404. Co-authored-by: Shargon --- .../Network/P2P/Capabilities/NodeCapability.cs | 4 +++- .../P2P/Capabilities/NodeCapabilityType.cs | 8 ++++++++ .../P2P/Capabilities/ServerCapability.cs | 6 ++++-- .../P2P/Capabilities/UT_ServerCapability.cs | 18 ++++++++++++++++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/Neo/Network/P2P/Capabilities/NodeCapability.cs b/src/Neo/Network/P2P/Capabilities/NodeCapability.cs index 737f2873be..c47f238a4f 100644 --- a/src/Neo/Network/P2P/Capabilities/NodeCapability.cs +++ b/src/Neo/Network/P2P/Capabilities/NodeCapability.cs @@ -56,7 +56,9 @@ public static NodeCapability DeserializeFrom(ref MemoryReader reader) NodeCapabilityType type = (NodeCapabilityType)reader.ReadByte(); NodeCapability capability = type switch { - NodeCapabilityType.TcpServer => new ServerCapability(type), +#pragma warning disable CS0612 // Type or member is obsolete + NodeCapabilityType.TcpServer or NodeCapabilityType.WsServer => new ServerCapability(type), +#pragma warning restore CS0612 // Type or member is obsolete NodeCapabilityType.FullNode => new FullNodeCapability(), _ => throw new FormatException(), }; diff --git a/src/Neo/Network/P2P/Capabilities/NodeCapabilityType.cs b/src/Neo/Network/P2P/Capabilities/NodeCapabilityType.cs index 68305380e9..419d086fa9 100644 --- a/src/Neo/Network/P2P/Capabilities/NodeCapabilityType.cs +++ b/src/Neo/Network/P2P/Capabilities/NodeCapabilityType.cs @@ -9,6 +9,8 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using System; + namespace Neo.Network.P2P.Capabilities { /// @@ -23,6 +25,12 @@ public enum NodeCapabilityType : byte /// TcpServer = 0x01, + /// + /// Indicates that the node is listening on a WebSocket port. + /// + [Obsolete] + WsServer = 0x02, + #endregion #region Others diff --git a/src/Neo/Network/P2P/Capabilities/ServerCapability.cs b/src/Neo/Network/P2P/Capabilities/ServerCapability.cs index 820c4eff6d..e8c2d110df 100644 --- a/src/Neo/Network/P2P/Capabilities/ServerCapability.cs +++ b/src/Neo/Network/P2P/Capabilities/ServerCapability.cs @@ -32,11 +32,13 @@ public class ServerCapability : NodeCapability /// /// Initializes a new instance of the class. /// - /// The type of the . It must be + /// The type of the . It must be or /// The port that the node is listening on. public ServerCapability(NodeCapabilityType type, ushort port = 0) : base(type) { - if (type != NodeCapabilityType.TcpServer) +#pragma warning disable CS0612 // Type or member is obsolete + if (type != NodeCapabilityType.TcpServer && type != NodeCapabilityType.WsServer) +#pragma warning restore CS0612 // Type or member is obsolete { throw new ArgumentException(nameof(type)); } diff --git a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs index b35d92f4e3..cb538771dc 100644 --- a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs +++ b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs @@ -26,12 +26,18 @@ public void Size_Get() { var test = new ServerCapability(NodeCapabilityType.TcpServer) { Port = 1 }; test.Size.Should().Be(3); + +#pragma warning disable CS0612 // Type or member is obsolete + test = new ServerCapability(NodeCapabilityType.WsServer) { Port = 2 }; +#pragma warning restore CS0612 // Type or member is obsolete + test.Size.Should().Be(3); } [TestMethod] public void DeserializeAndSerialize() { - var test = new ServerCapability(NodeCapabilityType.TcpServer) { Port = 2 }; +#pragma warning disable CS0612 // Type or member is obsolete + var test = new ServerCapability(NodeCapabilityType.WsServer) { Port = 2 }; var buffer = test.ToArray(); var br = new MemoryReader(buffer); @@ -40,13 +46,21 @@ public void DeserializeAndSerialize() Assert.AreEqual(test.Port, clone.Port); Assert.AreEqual(test.Type, clone.Type); - clone = new ServerCapability(NodeCapabilityType.TcpServer, 123); + clone = new ServerCapability(NodeCapabilityType.WsServer, 123); +#pragma warning restore CS0612 // Type or member is obsolete br = new MemoryReader(buffer); ((ISerializable)clone).Deserialize(ref br); Assert.AreEqual(test.Port, clone.Port); Assert.AreEqual(test.Type, clone.Type); + clone = new ServerCapability(NodeCapabilityType.TcpServer, 123); + + Assert.ThrowsException(() => + { + var br2 = new MemoryReader(buffer); + ((ISerializable)clone).Deserialize(ref br2); + }); Assert.ThrowsException(() => { _ = new ServerCapability(NodeCapabilityType.FullNode); From b8073d429bde36579bb736abfff1d661b918ab0a Mon Sep 17 00:00:00 2001 From: nan01ab Date: Sun, 1 Dec 2024 07:13:38 +0800 Subject: [PATCH 10/13] Add argument null check for ToHexString to keep same behavior between net9 and older version (#3605) Co-authored-by: Jimmy --- src/Neo.Extensions/ByteExtensions.cs | 8 ++++++++ tests/Neo.Extensions.Tests/UT_ByteExtensions.cs | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/Neo.Extensions/ByteExtensions.cs b/src/Neo.Extensions/ByteExtensions.cs index 61cb5bde2e..702b71f109 100644 --- a/src/Neo.Extensions/ByteExtensions.cs +++ b/src/Neo.Extensions/ByteExtensions.cs @@ -50,12 +50,16 @@ public static int XxHash3_32(this byte[] value, long seed = DefaultXxHash3Seed) /// /// The byte array to convert. /// The converted hex . + /// Thrown when is null. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToHexString(this byte[] value) { #if NET9_0_OR_GREATER return Convert.ToHexStringLower(value); #else + if (value is null) + throw new ArgumentNullException(nameof(value)); + return string.Create(value.Length * 2, value, (span, bytes) => { for (var i = 0; i < bytes.Length; i++) @@ -74,12 +78,16 @@ public static string ToHexString(this byte[] value) /// The byte array to convert. /// Indicates whether it should be converted in the reversed byte order. /// The converted hex . + /// Thrown when is null. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToHexString(this byte[] value, bool reverse = false) { if (!reverse) return ToHexString(value); + if (value is null) + throw new ArgumentNullException(nameof(value)); + return string.Create(value.Length * 2, value, (span, bytes) => { for (var i = 0; i < bytes.Length; i++) diff --git a/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs index bb12d00eed..87c4ad9bd8 100644 --- a/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs +++ b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs @@ -26,6 +26,9 @@ public void TestToHexString() { byte[] nullStr = null; Assert.ThrowsException(() => nullStr.ToHexString()); + Assert.ThrowsException(() => nullStr.ToHexString(false)); + Assert.ThrowsException(() => nullStr.ToHexString(true)); + byte[] empty = Array.Empty(); empty.ToHexString().Should().Be(""); empty.ToHexString(false).Should().Be(""); From 1adc6e89071e85bfadd42725bb8496f52bf70058 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 1 Dec 2024 18:06:49 +0800 Subject: [PATCH 11/13] thread safe (#3606) --- .../LevelDBStore/Plugins/Storage/Snapshot.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs index fd7febd451..c4a2709b6d 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs @@ -20,56 +20,60 @@ internal class Snapshot : ISnapshot { private readonly DB _db; private readonly LSnapshot _snapshot; - private readonly ReadOptions _options; + private readonly ReadOptions _readOptions; private readonly WriteBatch _batch; + private readonly object _lock = new(); public Snapshot(DB db) { _db = db; _snapshot = db.GetSnapshot(); - _options = new ReadOptions { FillCache = false, Snapshot = _snapshot }; + _readOptions = new ReadOptions { FillCache = false, Snapshot = _snapshot }; _batch = new WriteBatch(); } public void Commit() { - _db.Write(WriteOptions.Default, _batch); + lock (_lock) + _db.Write(WriteOptions.Default, _batch); } public void Delete(byte[] key) { - _batch.Delete(key); + lock (_lock) + _batch.Delete(key); } public void Dispose() { _snapshot.Dispose(); - _options.Dispose(); + _readOptions.Dispose(); } public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] prefix, SeekDirection direction = SeekDirection.Forward) { - return _db.Seek(_options, prefix, direction); + return _db.Seek(_readOptions, prefix, direction); } public void Put(byte[] key, byte[] value) { - _batch.Put(key, value); + lock (_lock) + _batch.Put(key, value); } public bool Contains(byte[] key) { - return _db.Contains(_options, key); + return _db.Contains(_readOptions, key); } public byte[] TryGet(byte[] key) { - return _db.Get(_options, key); + return _db.Get(_readOptions, key); } public bool TryGet(byte[] key, out byte[] value) { - value = _db.Get(_options, key); + value = _db.Get(_readOptions, key); return value != null; } } From 7afdf2474c12cc821b944e4ad1bae2cf62cacf6d Mon Sep 17 00:00:00 2001 From: nan01ab Date: Mon, 2 Dec 2024 13:58:08 +0800 Subject: [PATCH 12/13] upgrade System.Text.RegularExpressions to fix vulnerability (#3604) Co-authored-by: Shargon Co-authored-by: Jimmy Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- src/Plugins/OracleService/OracleService.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugins/OracleService/OracleService.csproj b/src/Plugins/OracleService/OracleService.csproj index 6b6dbebb98..4f2b25cb07 100644 --- a/src/Plugins/OracleService/OracleService.csproj +++ b/src/Plugins/OracleService/OracleService.csproj @@ -8,6 +8,7 @@ + From 79554f236cb87e497326727358b00845d73fdd3e Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Mon, 2 Dec 2024 07:07:50 -0500 Subject: [PATCH 13/13] `[Move]` Part-8 Classes into Different Library - `Neo.Extensions` (#3447) * Part-1 `Neo.IO` - move * Part-2 * Added `BigInteger` to `Neo.Extensions` * Found more `BigInteger` * Added `ByteArray` to `Neo.Extensions` * Added `DateTime` Extensions to `Neo.Extensions` * Added `HashSetExtensions`, `HashSetExtensions2`, `IpAddressExtensions`, `AssemblyExtensions`, `StringExtensdions` Deleted `Helper.cs` file * Added `ICollection`, `Memory`, `String`, `Unsafe` extensions * Adding `using` * dotnet format * Added more Extensions * Move some methods * Added Tests * Added `tests` from `Part-2` * Added `tests` for `PART-4` * Added `tests` for `PART-5` * Added the `Part` 7 * `PART-8` * Fixed some stuff --------- Co-authored-by: Shargon --- src/Neo/Extensions/UInt160Extensions.cs | 32 ++++++++++++++++ .../VM/EvaluationStackExtensions.cs | 37 +++++++++++++++++++ src/Neo/VM/Helper.cs | 33 +---------------- src/Plugins/RpcClient/Nep17API.cs | 1 + tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs | 1 + .../UT_TransactionManager.cs | 1 + 6 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 src/Neo/Extensions/UInt160Extensions.cs create mode 100644 src/Neo/Extensions/VM/EvaluationStackExtensions.cs diff --git a/src/Neo/Extensions/UInt160Extensions.cs b/src/Neo/Extensions/UInt160Extensions.cs new file mode 100644 index 0000000000..988d7e5d83 --- /dev/null +++ b/src/Neo/Extensions/UInt160Extensions.cs @@ -0,0 +1,32 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UInt160Extensions.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.VM; + +namespace Neo.Extensions +{ + public static class UInt160Extensions + { + /// + /// Generates the script for calling a contract dynamically. + /// + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The arguments for calling the contract. + /// The generated script. + public static byte[] MakeScript(this UInt160 scriptHash, string method, params object[] args) + { + using ScriptBuilder sb = new(); + sb.EmitDynamicCall(scriptHash, method, args); + return sb.ToArray(); + } + } +} diff --git a/src/Neo/Extensions/VM/EvaluationStackExtensions.cs b/src/Neo/Extensions/VM/EvaluationStackExtensions.cs new file mode 100644 index 0000000000..30684c01b2 --- /dev/null +++ b/src/Neo/Extensions/VM/EvaluationStackExtensions.cs @@ -0,0 +1,37 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// EvaluationStackExtensions.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.Json; +using Neo.VM; +using System; + +namespace Neo.Extensions +{ + public static class EvaluationStackExtensions + { + /// + /// Converts the to a JSON object. + /// + /// The to convert. + /// The maximum size in bytes of the result. + /// The represented by a JSON object. + public static JArray ToJson(this EvaluationStack stack, int maxSize = int.MaxValue) + { + if (maxSize <= 0) throw new ArgumentOutOfRangeException(nameof(maxSize)); + maxSize -= 2/*[]*/+ Math.Max(0, (stack.Count - 1))/*,*/; + JArray result = []; + foreach (var item in stack) + result.Add(item.ToJson(null, ref maxSize)); + if (maxSize < 0) throw new InvalidOperationException("Max size reached."); + return result; + } + } +} diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 3ac202a818..2321d014b2 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -29,20 +29,6 @@ namespace Neo.VM /// public static class Helper { - /// - /// Generates the script for calling a contract dynamically. - /// - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The arguments for calling the contract. - /// The generated script. - public static byte[] MakeScript(this UInt160 scriptHash, string method, params object[] args) - { - using ScriptBuilder sb = new(); - sb.EmitDynamicCall(scriptHash, method, args); - return sb.ToArray(); - } - /// /// Converts the to a JSON object. /// @@ -54,24 +40,7 @@ public static JObject ToJson(this StackItem item, int maxSize = int.MaxValue) return ToJson(item, null, ref maxSize); } - /// - /// Converts the to a JSON object. - /// - /// The to convert. - /// The maximum size in bytes of the result. - /// The represented by a JSON object. - public static JArray ToJson(this EvaluationStack stack, int maxSize = int.MaxValue) - { - if (maxSize <= 0) throw new ArgumentOutOfRangeException(nameof(maxSize)); - maxSize -= 2/*[]*/+ Math.Max(0, (stack.Count - 1))/*,*/; - JArray result = new(); - foreach (var item in stack) - result.Add(ToJson(item, null, ref maxSize)); - if (maxSize < 0) throw new InvalidOperationException("Max size reached."); - return result; - } - - private static JObject ToJson(StackItem item, HashSet context, ref int maxSize) + public static JObject ToJson(this StackItem item, HashSet context, ref int maxSize) { JObject json = new() { diff --git a/src/Plugins/RpcClient/Nep17API.cs b/src/Plugins/RpcClient/Nep17API.cs index 0870670231..c1f7324c4c 100644 --- a/src/Plugins/RpcClient/Nep17API.cs +++ b/src/Plugins/RpcClient/Nep17API.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; diff --git a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs index 7defa163ad..a05918c83f 100644 --- a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index ae025cf65a..b7eecf2298 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -13,6 +13,7 @@ using Moq; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P;