From 1c3fe4564ae316b7d7ad75328bc7b0726d69bc97 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 30 Jul 2024 01:46:47 -0400 Subject: [PATCH 1/6] `[Move]` Part-3 Classes into Different Library - `Neo.Extensions` (#3400) * Part-1 `Neo.IO` - move * Part-2 * Added `BigInteger` to `Neo.Extensions` * Found more `BigInteger` * Added `ByteArray` to `Neo.Extensions` * Added Tests * Added `tests` from `Part-2` --------- Co-authored-by: Shargon Co-authored-by: Jimmy --- .../{Extensions.cs => AssemblyExtensions.cs} | 4 +- src/Neo.CLI/CLI/MainService.Tools.cs | 1 + src/Neo.CLI/CLI/MainService.Vote.cs | 1 + src/Neo.CLI/CLI/MainService.Wallet.cs | 1 + src/Neo.CLI/CLI/MainService.cs | 1 + src/Neo.CLI/Neo.CLI.csproj | 1 + src/Neo.Extensions/ByteExtensions.cs | 59 ++++++++++++ src/Neo.GUI/GUI/DeployContractDialog.cs | 1 + src/Neo.GUI/GUI/InvokeContractDialog.cs | 1 + src/Neo.GUI/GUI/SigningDialog.cs | 1 + src/Neo.GUI/GUI/ViewContractDialog.cs | 1 + src/Neo.GUI/GUI/ViewPrivateKeyDialog.cs | 1 + src/Neo.GUI/GUI/Wrappers/HexConverter.cs | 1 + src/Neo/Cryptography/Base58.cs | 3 +- src/Neo/Cryptography/ECC/ECPoint.cs | 5 +- src/Neo/Cryptography/Helper.cs | 3 +- src/Neo/Helper.cs | 95 ------------------- src/Neo/SmartContract/ContractParameter.cs | 1 + src/Neo/UInt160.cs | 1 + src/Neo/UInt256.cs | 1 + .../DBFTPlugin/Consensus/ConsensusService.cs | 1 + .../Cryptography/MPTTrie/Trie.Delete.cs | 5 +- .../MPTTrie/Cryptography/MPTTrie/Trie.Find.cs | 15 ++- .../Cryptography/MPTTrie/Trie.Proof.cs | 3 +- src/Plugins/OracleService/OracleService.cs | 5 +- src/Plugins/RpcClient/Nep17API.cs | 17 ++-- src/Plugins/RpcServer/RpcServer.Blockchain.cs | 1 + .../Trackers/NEP-11/Nep11Tracker.cs | 1 + .../Cryptography/MPTTrie/UT_Cache.cs | 1 + .../Cryptography/MPTTrie/UT_Node.cs | 1 + .../Cryptography/MPTTrie/UT_Trie.cs | 5 +- .../Neo.Extensions.Tests/UT_ByteExtensions.cs | 37 ++++++++ tests/Neo.Network.RPC.Tests/UT_Nep17API.cs | 16 ++-- tests/Neo.Network.RPC.Tests/UT_Utility.cs | 1 + tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs | 1 + .../Cryptography/UT_Cryptography_Helper.cs | 1 + .../Cryptography/UT_Murmur128.cs | 1 + tests/Neo.UnitTests/Cryptography/UT_SCrypt.cs | 1 + .../Neo.UnitTests/IO/Caching/UT_CloneCache.cs | 1 + tests/Neo.UnitTests/IO/UT_IOHelper.cs | 1 + tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs | 1 + .../Network/P2P/Payloads/UT_Block.cs | 1 + .../Network/P2P/Payloads/UT_Header.cs | 1 + .../Network/P2P/Payloads/UT_Signers.cs | 1 + .../Network/P2P/Payloads/UT_Transaction.cs | 2 + .../Network/P2P/Payloads/UT_Witness.cs | 1 + .../SmartContract/Native/UT_CryptoLib.cs | 1 + .../SmartContract/Native/UT_NeoToken.cs | 1 + .../SmartContract/Native/UT_RoleManagement.cs | 1 + .../SmartContract/Native/UT_StdLib.cs | 1 + .../SmartContract/UT_ContractParameter.cs | 1 + .../UT_ContractParameterContext.cs | 1 + .../SmartContract/UT_InteropService.NEO.cs | 1 + .../SmartContract/UT_InteropService.cs | 1 + .../SmartContract/UT_KeyBuilder.cs | 1 + tests/Neo.UnitTests/UT_Helper.cs | 32 ------- tests/Neo.UnitTests/VM/UT_Helper.cs | 1 + 57 files changed, 177 insertions(+), 170 deletions(-) rename src/Neo.CLI/{Extensions.cs => AssemblyExtensions.cs} (88%) create mode 100644 src/Neo.Extensions/ByteExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/UT_ByteExtensions.cs diff --git a/src/Neo.CLI/Extensions.cs b/src/Neo.CLI/AssemblyExtensions.cs similarity index 88% rename from src/Neo.CLI/Extensions.cs rename to src/Neo.CLI/AssemblyExtensions.cs index b8331201be..42e49e13fc 100644 --- a/src/Neo.CLI/Extensions.cs +++ b/src/Neo.CLI/AssemblyExtensions.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// Extensions.cs file belongs to the neo project and is free +// AssemblyExtensions.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 @@ -17,7 +17,7 @@ namespace Neo /// /// Extension methods /// - internal static class Extensions + internal static class AssemblyExtensions { public static string GetVersion(this Assembly assembly) { diff --git a/src/Neo.CLI/CLI/MainService.Tools.cs b/src/Neo.CLI/CLI/MainService.Tools.cs index 66723d7df9..a8eab7893c 100644 --- a/src/Neo.CLI/CLI/MainService.Tools.cs +++ b/src/Neo.CLI/CLI/MainService.Tools.cs @@ -11,6 +11,7 @@ using Neo.ConsoleService; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using Neo.VM; diff --git a/src/Neo.CLI/CLI/MainService.Vote.cs b/src/Neo.CLI/CLI/MainService.Vote.cs index 12cd48b3a9..bec0bab91d 100644 --- a/src/Neo.CLI/CLI/MainService.Vote.cs +++ b/src/Neo.CLI/CLI/MainService.Vote.cs @@ -11,6 +11,7 @@ using Neo.ConsoleService; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/src/Neo.CLI/CLI/MainService.Wallet.cs b/src/Neo.CLI/CLI/MainService.Wallet.cs index f1390612bc..54bd8dccab 100644 --- a/src/Neo.CLI/CLI/MainService.Wallet.cs +++ b/src/Neo.CLI/CLI/MainService.Wallet.cs @@ -12,6 +12,7 @@ using Akka.Actor; using Neo.ConsoleService; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs index de667bc63d..96db57a19d 100644 --- a/src/Neo.CLI/CLI/MainService.cs +++ b/src/Neo.CLI/CLI/MainService.cs @@ -12,6 +12,7 @@ using Akka.Actor; using Neo.ConsoleService; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/src/Neo.CLI/Neo.CLI.csproj b/src/Neo.CLI/Neo.CLI.csproj index eaa2cb3067..f2e1359194 100644 --- a/src/Neo.CLI/Neo.CLI.csproj +++ b/src/Neo.CLI/Neo.CLI.csproj @@ -31,6 +31,7 @@ + diff --git a/src/Neo.Extensions/ByteExtensions.cs b/src/Neo.Extensions/ByteExtensions.cs new file mode 100644 index 0000000000..013a8ef1cc --- /dev/null +++ b/src/Neo.Extensions/ByteExtensions.cs @@ -0,0 +1,59 @@ +// 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 System; +using System.Text; + +namespace Neo.Extensions +{ + public static class ByteExtensions + { + /// + /// Converts a byte array to hex . + /// + /// The byte array to convert. + /// The converted hex . + public static string ToHexString(this byte[] value) + { + StringBuilder sb = new(); + foreach (var b in value) + sb.AppendFormat("{0:x2}", b); + return sb.ToString(); + } + + /// + /// Converts a byte array to hex . + /// + /// The byte array to convert. + /// Indicates whether it should be converted in the reversed byte order. + /// The converted hex . + public static string ToHexString(this byte[] value, bool reverse = false) + { + StringBuilder sb = new(); + for (var i = 0; i < value.Length; i++) + sb.AppendFormat("{0:x2}", value[reverse ? value.Length - i - 1 : i]); + return sb.ToString(); + } + + /// + /// Converts a byte array to hex . + /// + /// The byte array to convert. + /// The converted hex . + public static string ToHexString(this ReadOnlySpan value) + { + StringBuilder sb = new(); + foreach (var b in value) + sb.AppendFormat("{0:x2}", b); + return sb.ToString(); + } + } +} diff --git a/src/Neo.GUI/GUI/DeployContractDialog.cs b/src/Neo.GUI/GUI/DeployContractDialog.cs index 31ca5e6636..0eaf9c1ae1 100644 --- a/src/Neo.GUI/GUI/DeployContractDialog.cs +++ b/src/Neo.GUI/GUI/DeployContractDialog.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/src/Neo.GUI/GUI/InvokeContractDialog.cs b/src/Neo.GUI/GUI/InvokeContractDialog.cs index d8a8a6b66f..e24b3c24ee 100644 --- a/src/Neo.GUI/GUI/InvokeContractDialog.cs +++ b/src/Neo.GUI/GUI/InvokeContractDialog.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Properties; diff --git a/src/Neo.GUI/GUI/SigningDialog.cs b/src/Neo.GUI/GUI/SigningDialog.cs index 5b515a4365..e7e5b6bb2b 100644 --- a/src/Neo.GUI/GUI/SigningDialog.cs +++ b/src/Neo.GUI/GUI/SigningDialog.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.Properties; using Neo.Wallets; using System; diff --git a/src/Neo.GUI/GUI/ViewContractDialog.cs b/src/Neo.GUI/GUI/ViewContractDialog.cs index 00ea963328..a97aa648e9 100644 --- a/src/Neo.GUI/GUI/ViewContractDialog.cs +++ b/src/Neo.GUI/GUI/ViewContractDialog.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.SmartContract; using Neo.Wallets; using System.Linq; diff --git a/src/Neo.GUI/GUI/ViewPrivateKeyDialog.cs b/src/Neo.GUI/GUI/ViewPrivateKeyDialog.cs index 7beaa56271..4233814df9 100644 --- a/src/Neo.GUI/GUI/ViewPrivateKeyDialog.cs +++ b/src/Neo.GUI/GUI/ViewPrivateKeyDialog.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Wallets; using System.Windows.Forms; diff --git a/src/Neo.GUI/GUI/Wrappers/HexConverter.cs b/src/Neo.GUI/GUI/Wrappers/HexConverter.cs index 757bfd3b97..ecd1fd1e4a 100644 --- a/src/Neo.GUI/GUI/Wrappers/HexConverter.cs +++ b/src/Neo.GUI/GUI/Wrappers/HexConverter.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using System; using System.ComponentModel; using System.Globalization; diff --git a/src/Neo/Cryptography/Base58.cs b/src/Neo/Cryptography/Base58.cs index adecc8b631..a2f562b06b 100644 --- a/src/Neo/Cryptography/Base58.cs +++ b/src/Neo/Cryptography/Base58.cs @@ -13,7 +13,6 @@ using System.Linq; using System.Numerics; using System.Text; -using static Neo.Helper; namespace Neo.Cryptography { @@ -86,7 +85,7 @@ public static byte[] Decode(string input) var leadingZeros = new byte[leadingZeroCount]; if (bi.IsZero) return leadingZeros; var bytesWithoutLeadingZeros = bi.ToByteArray(isUnsigned: true, isBigEndian: true); - return Concat(leadingZeros, bytesWithoutLeadingZeros); + return [.. leadingZeros, .. bytesWithoutLeadingZeros]; } /// diff --git a/src/Neo/Cryptography/ECC/ECPoint.cs b/src/Neo/Cryptography/ECC/ECPoint.cs index 77d01b90ea..ce6b3ac588 100644 --- a/src/Neo/Cryptography/ECC/ECPoint.cs +++ b/src/Neo/Cryptography/ECC/ECPoint.cs @@ -15,7 +15,6 @@ using System; using System.IO; using System.Numerics; -using static Neo.Helper; namespace Neo.Cryptography.ECC { @@ -225,8 +224,8 @@ public static ECPoint FromBytes(byte[] bytes, ECCurve curve) return bytes.Length switch { 33 or 65 => DecodePoint(bytes, curve), - 64 or 72 => DecodePoint(Concat(new byte[] { 0x04 }, bytes[^64..]), curve), - 96 or 104 => DecodePoint(Concat(new byte[] { 0x04 }, bytes[^96..^32]), curve), + 64 or 72 => DecodePoint([.. new byte[] { 0x04 }, .. bytes[^64..]], curve), + 96 or 104 => DecodePoint([.. new byte[] { 0x04 }, .. bytes[^96..^32]], curve), _ => throw new FormatException(), }; } diff --git a/src/Neo/Cryptography/Helper.cs b/src/Neo/Cryptography/Helper.cs index f13fa08118..41e89f5a49 100644 --- a/src/Neo/Cryptography/Helper.cs +++ b/src/Neo/Cryptography/Helper.cs @@ -22,7 +22,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; -using static Neo.Helper; using ECPoint = Neo.Cryptography.ECC.ECPoint; namespace Neo.Cryptography @@ -213,7 +212,7 @@ public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] non var length = cipher.ProcessBytes(plainData, 0, plainData.Length, cipherBytes, 0); cipher.DoFinal(cipherBytes, length); } - return Concat(nonce, cipherBytes, tag); + return [.. nonce, .. cipherBytes, .. tag]; } public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[] associatedData = null) diff --git a/src/Neo/Helper.cs b/src/Neo/Helper.cs index 7acf69b0e9..4458d04f42 100644 --- a/src/Neo/Helper.cs +++ b/src/Neo/Helper.cs @@ -17,8 +17,6 @@ using System.Net; using System.Numerics; using System.Reflection; -using System.Runtime.CompilerServices; -using System.Text; namespace Neo { @@ -29,59 +27,6 @@ public static class Helper { private static readonly DateTime unixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int BitLen(int w) - { - return (w < 1 << 15 ? (w < 1 << 7 - ? (w < 1 << 3 ? (w < 1 << 1 - ? (w < 1 << 0 ? (w < 0 ? 32 : 0) : 1) - : (w < 1 << 2 ? 2 : 3)) : (w < 1 << 5 - ? (w < 1 << 4 ? 4 : 5) - : (w < 1 << 6 ? 6 : 7))) - : (w < 1 << 11 - ? (w < 1 << 9 ? (w < 1 << 8 ? 8 : 9) : (w < 1 << 10 ? 10 : 11)) - : (w < 1 << 13 ? (w < 1 << 12 ? 12 : 13) : (w < 1 << 14 ? 14 : 15)))) : (w < 1 << 23 ? (w < 1 << 19 - ? (w < 1 << 17 ? (w < 1 << 16 ? 16 : 17) : (w < 1 << 18 ? 18 : 19)) - : (w < 1 << 21 ? (w < 1 << 20 ? 20 : 21) : (w < 1 << 22 ? 22 : 23))) : (w < 1 << 27 - ? (w < 1 << 25 ? (w < 1 << 24 ? 24 : 25) : (w < 1 << 26 ? 26 : 27)) - : (w < 1 << 29 ? (w < 1 << 28 ? 28 : 29) : (w < 1 << 30 ? 30 : 31))))); - } - - /// - /// Concatenates the specified byte arrays. - /// - /// The byte arrays to concatenate. - /// The concatenated byte array. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Concat(params byte[][] buffers) - { - int length = 0; - for (int i = 0; i < buffers.Length; i++) - length += buffers[i].Length; - byte[] dst = new byte[length]; - int p = 0; - foreach (byte[] src in buffers) - { - Buffer.BlockCopy(src, 0, dst, p, src.Length); - p += src.Length; - } - return dst; - } - - /// - /// Concatenates two byte arrays. - /// - /// The first byte array to concatenate. - /// The second byte array to concatenate. - /// The concatenated byte array. - public static byte[] Concat(ReadOnlySpan a, ReadOnlySpan b) - { - byte[] buffer = new byte[a.Length + b.Length]; - a.CopyTo(buffer); - b.CopyTo(buffer.AsSpan(a.Length)); - return buffer; - } - internal static void Remove(this HashSet set, ISet other) { if (set.Count > other.Count) @@ -158,46 +103,6 @@ internal static BigInteger NextBigInteger(this Random rand, int sizeInBits) return new BigInteger(b); } - /// - /// Converts a byte array to hex . - /// - /// The byte array to convert. - /// The converted hex . - public static string ToHexString(this byte[] value) - { - StringBuilder sb = new(); - foreach (byte b in value) - sb.AppendFormat("{0:x2}", b); - return sb.ToString(); - } - - /// - /// Converts a byte array to hex . - /// - /// The byte array to convert. - /// Indicates whether it should be converted in the reversed byte order. - /// The converted hex . - public static string ToHexString(this byte[] value, bool reverse = false) - { - StringBuilder sb = new(); - for (int i = 0; i < value.Length; i++) - sb.AppendFormat("{0:x2}", value[reverse ? value.Length - i - 1 : i]); - return sb.ToString(); - } - - /// - /// Converts a byte array to hex . - /// - /// The byte array to convert. - /// The converted hex . - public static string ToHexString(this ReadOnlySpan value) - { - StringBuilder sb = new(); - foreach (byte b in value) - sb.AppendFormat("{0:x2}", b); - return sb.ToString(); - } - /// /// Converts a to timestamp. /// diff --git a/src/Neo/SmartContract/ContractParameter.cs b/src/Neo/SmartContract/ContractParameter.cs index 4abc7aa985..f1b12c6c0a 100644 --- a/src/Neo/SmartContract/ContractParameter.cs +++ b/src/Neo/SmartContract/ContractParameter.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using System; using System.Collections.Generic; diff --git a/src/Neo/UInt160.cs b/src/Neo/UInt160.cs index 8dfd6bf70c..db317ef7e5 100644 --- a/src/Neo/UInt160.cs +++ b/src/Neo/UInt160.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.Globalization; diff --git a/src/Neo/UInt256.cs b/src/Neo/UInt256.cs index 7c4d996339..95324ef6ac 100644 --- a/src/Neo/UInt256.cs +++ b/src/Neo/UInt256.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.Globalization; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs index eb97e7024b..ad1b88feb1 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.Actor; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs index 2041100a14..cb1a09bae7 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs @@ -11,7 +11,6 @@ using System; using System.Collections.Generic; -using static Neo.Helper; namespace Neo.Cryptography.MPTTrie { @@ -57,7 +56,7 @@ private bool TryDelete(ref Node node, ReadOnlySpan path) if (node.Next.Type == NodeType.ExtensionNode) { if (!full) cache.DeleteNode(node.Next.Hash); - node.Key = Concat(node.Key.Span, node.Next.Key.Span); + node.Key = new([.. node.Key.Span, .. node.Next.Key.Span]); node.Next = node.Next.Next; } node.SetDirty(); @@ -107,7 +106,7 @@ private bool TryDelete(ref Node node, ReadOnlySpan path) if (lastChild.Type == NodeType.ExtensionNode) { if (!full) cache.DeleteNode(lastChild.Hash); - lastChild.Key = Concat(childrenIndexes.ToArray(), lastChild.Key.Span); + lastChild.Key = new([.. childrenIndexes.ToArray(), .. lastChild.Key.Span]); lastChild.SetDirty(); cache.PutNode(lastChild); node = lastChild; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Find.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Find.cs index b3922e8ce8..aeb3a1ec5e 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Find.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Find.cs @@ -12,7 +12,6 @@ using System; using System.Collections.Generic; using System.Linq; -using static Neo.Helper; namespace Neo.Cryptography.MPTTrie { @@ -47,7 +46,7 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node start = node; return ReadOnlySpan.Empty; } - return Concat(path[..1], Seek(ref node.Children[path[0]], path[1..], out start)); + return new([.. path[..1], .. Seek(ref node.Children[path[0]], path[1..], out start)]); } case NodeType.ExtensionNode: { @@ -58,7 +57,7 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node } if (path.StartsWith(node.Key.Span)) { - return Concat(node.Key.Span, Seek(ref node.Next, path[node.Key.Length..], out start)); + return new([.. node.Key.Span, .. Seek(ref node.Next, path[node.Key.Length..], out start)]); } if (node.Key.Span.StartsWith(path)) { @@ -135,10 +134,10 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node for (int i = 0; i < Node.BranchChildCount - 1; i++) { if (from[offset] < i) - foreach (var item in Travers(node.Children[i], Concat(path, new byte[] { (byte)i }), from, from.Length)) + foreach (var item in Travers(node.Children[i], [.. path, .. new byte[] { (byte)i }], from, from.Length)) yield return item; else if (i == from[offset]) - foreach (var item in Travers(node.Children[i], Concat(path, new byte[] { (byte)i }), from, offset + 1)) + foreach (var item in Travers(node.Children[i], [.. path, .. new byte[] { (byte)i }], from, offset + 1)) yield return item; } } @@ -148,7 +147,7 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node yield return item; for (int i = 0; i < Node.BranchChildCount - 1; i++) { - foreach (var item in Travers(node.Children[i], Concat(path, new byte[] { (byte)i }), from, offset)) + foreach (var item in Travers(node.Children[i], [.. path, .. new byte[] { (byte)i }], from, offset)) yield return item; } } @@ -157,10 +156,10 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node case NodeType.ExtensionNode: { if (offset < from.Length && from.AsSpan()[offset..].StartsWith(node.Key.Span)) - foreach (var item in Travers(node.Next, Concat(path, node.Key.Span), from, offset + node.Key.Length)) + foreach (var item in Travers(node.Next, [.. path, .. node.Key.Span], from, offset + node.Key.Length)) yield return item; else if (from.Length <= offset || 0 < node.Key.Span.CompareTo(from.AsSpan(offset))) - foreach (var item in Travers(node.Next, Concat(path, node.Key.Span), from, from.Length)) + foreach (var item in Travers(node.Next, [.. path, .. node.Key.Span], from, from.Length)) yield return item; break; } diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Proof.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Proof.cs index e0925452e3..d3c04053b9 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Proof.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Trie.Proof.cs @@ -13,7 +13,6 @@ using Neo.Persistence; using System; using System.Collections.Generic; -using static Neo.Helper; namespace Neo.Cryptography.MPTTrie { @@ -86,7 +85,7 @@ public static byte[] VerifyProof(UInt256 root, byte[] key, HashSet proof { using var memoryStore = new MemoryStore(); foreach (byte[] data in proof) - memoryStore.Put(Key(Crypto.Hash256(data)), Concat(data, new byte[] { 1 })); + memoryStore.Put(Key(Crypto.Hash256(data)), [.. data, .. new byte[] { 1 }]); using ISnapshot snapshot = memoryStore.GetSnapshot(); var trie = new Trie(snapshot, root, false); return trie[key]; diff --git a/src/Plugins/OracleService/OracleService.cs b/src/Plugins/OracleService/OracleService.cs index 3f14c8eab8..a6d91892a3 100644 --- a/src/Plugins/OracleService/OracleService.cs +++ b/src/Plugins/OracleService/OracleService.cs @@ -14,6 +14,7 @@ using Neo.ConsoleService; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IEventHandlers; using Neo.IO; using Neo.Json; @@ -240,7 +241,7 @@ public JObject SubmitOracleResponse(JArray _params) var oracles = NativeContract.RoleManagement.GetDesignatedByRole(snapshot, Role.Oracle, height); oracles.Any(p => p.Equals(oraclePub)).True_Or(RpcErrorFactory.OracleNotDesignatedNode(oraclePub)); NativeContract.Oracle.GetRequest(snapshot, requestId).NotNull_Or(RpcError.OracleRequestNotFound); - var data = Neo.Helper.Concat(oraclePub.ToArray(), BitConverter.GetBytes(requestId), txSign); + byte[] data = [.. oraclePub.ToArray(), .. BitConverter.GetBytes(requestId), .. txSign]; Crypto.VerifySignature(data, msgSign, oraclePub).True_Or(RpcErrorFactory.InvalidSignature($"Invalid oracle response transaction signature from '{oraclePub}'.")); AddResponseTxSign(snapshot, requestId, oraclePub, txSign); } @@ -262,7 +263,7 @@ private static async Task SendContentAsync(Uri url, string content) private async Task SendResponseSignatureAsync(ulong requestId, byte[] txSign, KeyPair keyPair) { - var message = Neo.Helper.Concat(keyPair.PublicKey.ToArray(), BitConverter.GetBytes(requestId), txSign); + byte[] message = [.. keyPair.PublicKey.ToArray(), .. BitConverter.GetBytes(requestId), .. txSign]; var sign = Crypto.Sign(message, keyPair.PrivateKey); var param = "\"" + Convert.ToBase64String(keyPair.PublicKey.ToArray()) + "\", " + requestId + ", \"" + Convert.ToBase64String(txSign) + "\",\"" + Convert.ToBase64String(sign) + "\""; var content = "{\"id\":" + Interlocked.Increment(ref counter) + ",\"jsonrpc\":\"2.0\",\"method\":\"submitoracleresponse\",\"params\":[" + param + "]}"; diff --git a/src/Plugins/RpcClient/Nep17API.cs b/src/Plugins/RpcClient/Nep17API.cs index 518f470924..0870670231 100644 --- a/src/Plugins/RpcClient/Nep17API.cs +++ b/src/Plugins/RpcClient/Nep17API.cs @@ -19,7 +19,6 @@ using System.Linq; using System.Numerics; using System.Threading.Tasks; -using static Neo.Helper; namespace Neo.Network.RPC { @@ -88,10 +87,10 @@ public async Task TotalSupplyAsync(UInt160 scriptHash) public async Task GetTokenInfoAsync(UInt160 scriptHash) { var contractState = await rpcClient.GetContractStateAsync(scriptHash.ToString()).ConfigureAwait(false); - byte[] script = Concat( - scriptHash.MakeScript("symbol"), - scriptHash.MakeScript("decimals"), - scriptHash.MakeScript("totalSupply")); + byte[] script = [ + .. scriptHash.MakeScript("symbol"), + .. scriptHash.MakeScript("decimals"), + .. scriptHash.MakeScript("totalSupply")]; var name = contractState.Manifest.Name; var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false); var stack = result.Stack; @@ -108,10 +107,10 @@ public async Task GetTokenInfoAsync(UInt160 scriptHash) public async Task GetTokenInfoAsync(string contractHash) { var contractState = await rpcClient.GetContractStateAsync(contractHash).ConfigureAwait(false); - byte[] script = Concat( - contractState.Hash.MakeScript("symbol"), - contractState.Hash.MakeScript("decimals"), - contractState.Hash.MakeScript("totalSupply")); + byte[] script = [ + .. contractState.Hash.MakeScript("symbol"), + .. contractState.Hash.MakeScript("decimals"), + .. contractState.Hash.MakeScript("totalSupply")]; var name = contractState.Manifest.Name; var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false); var stack = result.Stack; diff --git a/src/Plugins/RpcServer/RpcServer.Blockchain.cs b/src/Plugins/RpcServer/RpcServer.Blockchain.cs index 7bc4711f1c..8f73fa3c78 100644 --- a/src/Plugins/RpcServer/RpcServer.Blockchain.cs +++ b/src/Plugins/RpcServer/RpcServer.Blockchain.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/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs index a799e79a7a..e859394e91 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11Tracker.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs index 3a34962059..0b5c0faace 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using System.Text; diff --git a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Node.cs b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Node.cs index 8f46fbec27..ba77dcd15e 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Node.cs +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Node.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using System; using System.Collections.Generic; diff --git a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs index 372de6a738..05592d366b 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using System; @@ -26,7 +27,7 @@ class TestSnapshot : ISnapshot private byte[] StoreKey(byte[] key) { - return Concat(key); + return [.. key]; } public void Put(byte[] key, byte[] value) @@ -65,7 +66,7 @@ public class UT_Trie private void PutToStore(IStore store, Node node) { - store.Put(Concat(new byte[] { 0xf0 }, node.Hash.ToArray()), node.ToArray()); + store.Put([.. new byte[] { 0xf0 }, .. node.Hash.ToArray()], node.ToArray()); } [TestInitialize] diff --git a/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs new file mode 100644 index 0000000000..a66d462694 --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_ByteExtensions.cs @@ -0,0 +1,37 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_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 FluentAssertions; +using System; + +namespace Neo.Extensions.Tests +{ + [TestClass] + public class UT_ByteExtensions + { + [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"); + } + } +} diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs index 3bfb4e87ff..863d424405 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs @@ -84,20 +84,20 @@ public async Task TestGetTotalSupply() public async Task TestGetTokenInfo() { UInt160 scriptHash = NativeContract.GAS.Hash; - byte[] testScript = Concat( - scriptHash.MakeScript("symbol"), - scriptHash.MakeScript("decimals"), - scriptHash.MakeScript("totalSupply")); + byte[] testScript = [ + .. scriptHash.MakeScript("symbol"), + .. scriptHash.MakeScript("decimals"), + .. scriptHash.MakeScript("totalSupply")]; UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); scriptHash = NativeContract.NEO.Hash; - testScript = Concat( - scriptHash.MakeScript("symbol"), - scriptHash.MakeScript("decimals"), - scriptHash.MakeScript("totalSupply")); + testScript = [ + .. scriptHash.MakeScript("symbol"), + .. scriptHash.MakeScript("decimals"), + .. scriptHash.MakeScript("totalSupply")]; UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.NEO.Symbol }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.NEO.Decimals) }, diff --git a/tests/Neo.Network.RPC.Tests/UT_Utility.cs b/tests/Neo.Network.RPC.Tests/UT_Utility.cs index fa410c5437..53e381b836 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Utility.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Utility.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.Wallets; using System; diff --git a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs index 10a35fd064..76851bbe99 100644 --- a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs @@ -12,6 +12,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; diff --git a/tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs b/tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs index 4bfde89ba2..8cddc26d16 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Cryptography/UT_Murmur128.cs b/tests/Neo.UnitTests/Cryptography/UT_Murmur128.cs index f33dd7110a..167caf6d3e 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_Murmur128.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_Murmur128.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using System.Text; namespace Neo.UnitTests.Cryptography diff --git a/tests/Neo.UnitTests/Cryptography/UT_SCrypt.cs b/tests/Neo.UnitTests/Cryptography/UT_SCrypt.cs index c3a3127ff0..ee41f8149a 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_SCrypt.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_SCrypt.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Org.BouncyCastle.Crypto.Generators; namespace Neo.UnitTests.Cryptography diff --git a/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs b/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs index e5fea8130a..fd0694f413 100644 --- a/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.cs +++ b/tests/Neo.UnitTests/IO/Caching/UT_CloneCache.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 4b74a495b5..48453c992a 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using System; using System.Collections.Generic; diff --git a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs index e65bfba843..ae3bc2570b 100644 --- a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs +++ b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.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_Block.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs index 1c31e3483c..c91811c3e2 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs index 0291b6f7c6..7604db6db0 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.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_Signers.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs index 44d337fd1c..d2358e947c 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Network.P2P.Payloads.Conditions; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index a483ecf0d6..dc910c5142 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -11,6 +11,8 @@ 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.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index cf765365c9..107eb5858c 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.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/SmartContract/Native/UT_CryptoLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs index cdca35a69e..daf1922644 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs @@ -14,6 +14,7 @@ using Neo.Cryptography; using Neo.Cryptography.BLS12_381; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs index cff1eb12b0..2ff07d5a69 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs index ad3cb4b6c8..c8d5a176f2 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs index a13d2659ce..1dffb3d384 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ContractParameter.cs b/tests/Neo.UnitTests/SmartContract/UT_ContractParameter.cs index 6618a918e7..4068837f6f 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ContractParameter.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ContractParameter.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract; using System; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs index 9523c41be4..9452cc6ebc 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.VM; diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs index 657206ab57..e0ccdd7dcc 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.NEO.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs index 972f8dc0d1..35dd3dbe37 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs @@ -15,6 +15,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs index 3ff52c1324..a3514c7f5a 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; namespace Neo.UnitTests.SmartContract diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 7fa3902cba..413c9dcf31 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -51,22 +51,6 @@ public void ToScriptHash() res.Should().Be(UInt160.Parse("2d3b96ae1bcc5a585e075e3b81920210dec16302")); } - [TestMethod] - public void TestGetLowestSetBit() - { - var big1 = new BigInteger(0); - big1.GetLowestSetBit().Should().Be(-1); - - var big2 = new BigInteger(512); - big2.GetLowestSetBit().Should().Be(9); - - var big3 = new BigInteger(int.MinValue); - big3.GetLowestSetBit().Should().Be(31); - - var big4 = new BigInteger(long.MinValue); - big4.GetLowestSetBit().Should().Be(63); - } - [TestMethod] public void TestHexToBytes() { @@ -163,22 +147,6 @@ 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() { diff --git a/tests/Neo.UnitTests/VM/UT_Helper.cs b/tests/Neo.UnitTests/VM/UT_Helper.cs index c5bf61d152..4178ed58d3 100644 --- a/tests/Neo.UnitTests/VM/UT_Helper.cs +++ b/tests/Neo.UnitTests/VM/UT_Helper.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using Neo.SmartContract.Native; From ffb3100034a90baa6af11d52644bf60b04a83861 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 30 Jul 2024 01:53:40 -0400 Subject: [PATCH 2/6] [`Optimization`] Parsing Smart Contract Script Analysis (#3420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed Parsing Smart Contract Script Analysis * Add more opcode outputs * Bug fixes * Move to ToString * Reorder using * Change ToString --------- Co-authored-by: Jimmy Co-authored-by: Vitor Nazário Coelho Co-authored-by: Fernando Diaz Toledano Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- src/Neo.CLI/CLI/MainService.Tools.cs | 67 +++------- src/Neo.CLI/Tools/VMInstruction.cs | 178 +++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 51 deletions(-) create mode 100644 src/Neo.CLI/Tools/VMInstruction.cs diff --git a/src/Neo.CLI/CLI/MainService.Tools.cs b/src/Neo.CLI/CLI/MainService.Tools.cs index a8eab7893c..60de31493a 100644 --- a/src/Neo.CLI/CLI/MainService.Tools.cs +++ b/src/Neo.CLI/CLI/MainService.Tools.cs @@ -14,7 +14,6 @@ using Neo.Extensions; using Neo.IO; using Neo.SmartContract; -using Neo.VM; using Neo.Wallets; using System; using System.Collections.Generic; @@ -57,7 +56,8 @@ private void OnParseCommand(string value) if (result != null) { - Console.WriteLine($"{pair.Key,-30}\t{result}"); + ConsoleHelper.Info("", "-----", pair.Key, "-----"); + ConsoleHelper.Info("", result, Environment.NewLine); any = true; } } @@ -418,62 +418,27 @@ private static string Base64Fixed(string str) [ParseFunction("Base64 Smart Contract Script Analysis")] private string? ScriptsToOpCode(string base64) { - Script script; try { - var scriptData = Convert.FromBase64String(base64); - script = new Script(scriptData.ToArray(), true); - } - catch (Exception) - { - return null; - } - return ScriptsToOpCode(script); - } + var bytes = Convert.FromBase64String(base64); + var sb = new StringBuilder(); + var line = 0; - private string ScriptsToOpCode(Script script) - { - //Initialize all InteropService - var dic = new Dictionary(); - ApplicationEngine.Services.ToList().ForEach(p => dic.Add(p.Value.Hash, p.Value.Name)); - - //Analyzing Scripts - var ip = 0; - Instruction instruction; - var result = new List(); - while (ip < script.Length && (instruction = script.GetInstruction(ip)) != null) - { - ip += instruction.Size; - - var op = instruction.OpCode; - - if (op.ToString().StartsWith("PUSHINT")) - { - var operand = instruction.Operand.ToArray(); - result.Add($"{op} {new BigInteger(operand)}"); - } - else if (op == OpCode.SYSCALL) + foreach (var instruct in new VMInstruction(bytes)) { - var operand = instruction.Operand.ToArray(); - result.Add($"{op} {dic[BitConverter.ToUInt32(operand)]}"); - } - else - { - if (!instruction.Operand.IsEmpty && instruction.Operand.Length > 0) - { - var operand = instruction.Operand.ToArray(); - var ascii = Encoding.Default.GetString(operand); - ascii = ascii.Any(p => p < '0' || p > 'z') ? operand.ToHexString() : ascii; - - result.Add($"{op} {(operand.Length == 20 ? new UInt160(operand).ToString() : ascii)}"); - } + if (instruct.OperandSize == 0) + sb.AppendFormat("L{0:D04}:{1:X04} {2}{3}", line, instruct.Position, instruct.OpCode, Environment.NewLine); else - { - result.Add($"{op}"); - } + sb.AppendFormat("L{0:D04}:{1:X04} {2,-10}{3}{4}", line, instruct.Position, instruct.OpCode, instruct.DecodeOperand(), Environment.NewLine); + line++; } + + return sb.ToString(); + } + catch + { + return null; } - return Environment.NewLine + string.Join("\r\n", result.ToArray()); } /// diff --git a/src/Neo.CLI/Tools/VMInstruction.cs b/src/Neo.CLI/Tools/VMInstruction.cs new file mode 100644 index 0000000000..9a4ba6a3d4 --- /dev/null +++ b/src/Neo.CLI/Tools/VMInstruction.cs @@ -0,0 +1,178 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// VMInstruction.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.SmartContract; +using Neo.VM; +using System; +using System.Buffers.Binary; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Neo.CLI +{ + [DebuggerDisplay("OpCode={OpCode}, OperandSize={OperandSize}")] + internal sealed class VMInstruction : IEnumerable + { + private const int OpCodeSize = 1; + + public int Position { get; private init; } + public OpCode OpCode { get; private init; } + public ReadOnlyMemory Operand { get; private init; } + public int OperandSize { get; private init; } + public int OperandPrefixSize { get; private init; } + + private static readonly int[] s_operandSizeTable = new int[256]; + private static readonly int[] s_operandSizePrefixTable = new int[256]; + + private readonly ReadOnlyMemory _script; + + public VMInstruction(ReadOnlyMemory script, int start = 0) + { + if (script.IsEmpty) + throw new Exception("Bad Script."); + + var opcode = (OpCode)script.Span[start]; + + if (Enum.IsDefined(opcode) == false) + throw new InvalidDataException($"Invalid opcode at Position: {start}."); + + OperandPrefixSize = s_operandSizePrefixTable[(int)opcode]; + OperandSize = OperandPrefixSize switch + { + 0 => s_operandSizeTable[(int)opcode], + 1 => script.Span[start + 1], + 2 => BinaryPrimitives.ReadUInt16LittleEndian(script.Span[(start + 1)..]), + 4 => unchecked((int)BinaryPrimitives.ReadUInt32LittleEndian(script.Span[(start + 1)..])), + _ => throw new InvalidDataException($"Invalid opcode prefix at Position: {start}."), + }; + + OperandSize += OperandPrefixSize; + + if (start + OperandSize + OpCodeSize > script.Length) + throw new IndexOutOfRangeException("Operand size exceeds end of script."); + + Operand = script.Slice(start + OpCodeSize, OperandSize); + + _script = script; + OpCode = opcode; + Position = start; + } + + static VMInstruction() + { + foreach (var field in typeof(OpCode).GetFields(BindingFlags.Public | BindingFlags.Static)) + { + var attr = field.GetCustomAttribute(); + if (attr == null) continue; + + var index = (uint)(OpCode)field.GetValue(null)!; + s_operandSizeTable[index] = attr.Size; + s_operandSizePrefixTable[index] = attr.SizePrefix; + } + } + + public IEnumerator GetEnumerator() + { + var nip = Position + OperandSize + OpCodeSize; + yield return this; + + VMInstruction? instruct; + for (var ip = nip; ip < _script.Length; ip += instruct.OperandSize + OpCodeSize) + yield return instruct = new VMInstruction(_script, ip); + } + + IEnumerator IEnumerable.GetEnumerator() => + GetEnumerator(); + + public override string ToString() + { + var sb = new StringBuilder(); + sb.AppendFormat("{1:X04} {2,-10}{3}{4}", Position, OpCode, DecodeOperand()); + return sb.ToString(); + } + + public T AsToken(uint index = 0) + where T : unmanaged + { + var size = Unsafe.SizeOf(); + + if (size > OperandSize) + throw new ArgumentOutOfRangeException(nameof(T), $"SizeOf {typeof(T).FullName} is too big for operand. OpCode: {OpCode}."); + if (size + index > OperandSize) + throw new ArgumentOutOfRangeException(nameof(index), $"SizeOf {typeof(T).FullName} + {index} is too big for operand. OpCode: {OpCode}."); + + var bytes = Operand[..OperandSize].ToArray(); + return Unsafe.As(ref bytes[index]); + } + + public string DecodeOperand() + { + var operand = Operand[OperandPrefixSize..].ToArray(); + var asStr = Encoding.UTF8.GetString(operand); + var readable = asStr.All(char.IsAsciiLetterOrDigit); + + return OpCode switch + { + OpCode.JMP or + OpCode.JMPIF or + OpCode.JMPIFNOT or + OpCode.JMPEQ or + OpCode.JMPNE or + OpCode.JMPGT or + OpCode.JMPLT or + OpCode.CALL or + OpCode.ENDTRY => $"[{checked(Position + AsToken()):X08}]", + OpCode.JMP_L or + OpCode.JMPIF_L or + OpCode.PUSHA or + OpCode.JMPIFNOT_L or + OpCode.JMPEQ_L or + OpCode.JMPNE_L or + OpCode.JMPGT_L or + OpCode.JMPLT_L or + OpCode.CALL_L or + OpCode.ENDTRY_L => $"[{checked(Position + AsToken()):X08}]", + OpCode.TRY => $"[{AsToken():X02}, {AsToken(1):X02}]", + OpCode.INITSLOT => $"{AsToken()}, {AsToken(1)}", + OpCode.TRY_L => $"[{checked(Position + AsToken()):X08}, {checked(Position + AsToken()):X08}]", + OpCode.CALLT => $"[{checked(Position + AsToken()):X08}]", + OpCode.NEWARRAY_T or + OpCode.ISTYPE or + OpCode.CONVERT => $"{AsToken():X02}", + OpCode.STLOC or + OpCode.LDLOC or + OpCode.LDSFLD or + OpCode.STSFLD or + OpCode.LDARG or + OpCode.STARG or + OpCode.INITSSLOT => $"{AsToken()}", + OpCode.PUSHINT8 => $"{AsToken()}", + OpCode.PUSHINT16 => $"{AsToken()}", + OpCode.PUSHINT32 => $"{AsToken()}", + OpCode.PUSHINT64 => $"{AsToken()}", + OpCode.PUSHINT128 or + OpCode.PUSHINT256 => $"{new BigInteger(operand)}", + OpCode.SYSCALL => $"[{ApplicationEngine.Services[Unsafe.As(ref operand[0])].Name}]", + OpCode.PUSHDATA1 or + OpCode.PUSHDATA2 or + OpCode.PUSHDATA4 => readable ? $"{Convert.ToHexString(operand)} // {asStr}" : Convert.ToHexString(operand), + _ => readable ? $"\"{asStr}\"" : $"{Convert.ToHexString(operand)}", + }; + } + } +} From 3c7d2492fd6e77e5001c44c4dea4c7c91b345217 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Tue, 30 Jul 2024 14:02:06 +0800 Subject: [PATCH 3/6] update benchmark system (#3442) Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- .../{Benchmarks.cs => Benchmarks.POC.cs} | 13 ++++++------- .../Neo.Benchmarks/Neo.Benchmarks.csproj | 1 + benchmarks/Neo.Benchmarks/Program.cs | 9 +++------ .../{Benchmarks.cs => Benchmarks.POC.cs} | 19 ++++++++++--------- .../Neo.VM.Benchmarks.csproj | 1 + benchmarks/Neo.VM.Benchmarks/Program.cs | 9 +++------ 6 files changed, 24 insertions(+), 28 deletions(-) rename benchmarks/Neo.Benchmarks/{Benchmarks.cs => Benchmarks.POC.cs} (89%) rename benchmarks/Neo.VM.Benchmarks/{Benchmarks.cs => Benchmarks.POC.cs} (87%) diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.cs b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs similarity index 89% rename from benchmarks/Neo.Benchmarks/Benchmarks.cs rename to benchmarks/Neo.Benchmarks/Benchmarks.POC.cs index 52eec04d44..f073c543a9 100644 --- a/benchmarks/Neo.Benchmarks/Benchmarks.cs +++ b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// Benchmarks.cs file belongs to the neo project and is free +// Benchmarks.POC.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 @@ -9,19 +9,21 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using BenchmarkDotNet.Attributes; using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.VM; using System.Diagnostics; -namespace Neo; +namespace Neo.Benchmark; -static class Benchmarks +public class Benchmarks_PoCs { private static readonly ProtocolSettings protocol = ProtocolSettings.Load("config.json"); private static readonly NeoSystem system = new(protocol, (string)null); - public static void NeoIssue2725() + [Benchmark] + public void NeoIssue2725() { // https://github.com/neo-project/neo/issues/2725 // L00: INITSSLOT 1 @@ -70,10 +72,7 @@ private static void Run(string name, string poc) using var snapshot = system.GetSnapshotCache(); using var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, system.GenesisBlock, protocol, tx.SystemFee); engine.LoadScript(tx.Script); - Stopwatch stopwatch = Stopwatch.StartNew(); engine.Execute(); - stopwatch.Stop(); Debug.Assert(engine.State == VMState.FAULT); - Console.WriteLine($"Benchmark: {name},\tTime: {stopwatch.Elapsed}"); } } diff --git a/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj index 22b90aeb03..c4b1a35da9 100644 --- a/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj +++ b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj @@ -9,6 +9,7 @@ + diff --git a/benchmarks/Neo.Benchmarks/Program.cs b/benchmarks/Neo.Benchmarks/Program.cs index 9d4125bb9f..e39ef23ff7 100644 --- a/benchmarks/Neo.Benchmarks/Program.cs +++ b/benchmarks/Neo.Benchmarks/Program.cs @@ -9,10 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo; -using System.Reflection; +using BenchmarkDotNet.Running; +using Neo.Benchmark; -foreach (var method in typeof(Benchmarks).GetMethods(BindingFlags.Public | BindingFlags.Static)) -{ - method.CreateDelegate().Invoke(); -} +BenchmarkRunner.Run(); diff --git a/benchmarks/Neo.VM.Benchmarks/Benchmarks.cs b/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs similarity index 87% rename from benchmarks/Neo.VM.Benchmarks/Benchmarks.cs rename to benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs index 6eab691a7d..1a5dac4b97 100644 --- a/benchmarks/Neo.VM.Benchmarks/Benchmarks.cs +++ b/benchmarks/Neo.VM.Benchmarks/Benchmarks.POC.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// Benchmarks.cs file belongs to the neo project and is free +// Benchmarks.POC.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 @@ -9,13 +9,15 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using BenchmarkDotNet.Attributes; using System.Diagnostics; -namespace Neo.VM +namespace Neo.VM.Benchmark { - public static class Benchmarks + public class Benchmarks_PoCs { - public static void NeoIssue2528() + [Benchmark] + public void NeoIssue2528() { // https://github.com/neo-project/neo/issues/2528 // L01: INITSLOT 1, 0 @@ -47,7 +49,8 @@ public static void NeoIssue2528() Run(nameof(NeoIssue2528), "VwEAwkpKAfsHdwARwG8AnXcAbwAl9////xHAzwJwlAAAdwAQzm8AnXcAbwAl9////0U="); } - public static void NeoVMIssue418() + [Benchmark] + public void NeoVMIssue418() { // https://github.com/neo-project/neo-vm/issues/418 // L00: NEWARRAY0 @@ -81,7 +84,8 @@ public static void NeoVMIssue418() Run(nameof(NeoVMIssue418), "whBNEcARTRHAVgEB/gGdYBFNEU0SwFMSwFhKJPNFUUU="); } - public static void NeoIssue2723() + [Benchmark] + public void NeoIssue2723() { // L00: INITSSLOT 1 // L01: PUSHINT32 130000 @@ -102,11 +106,8 @@ private static void Run(string name, string poc) byte[] script = Convert.FromBase64String(poc); using ExecutionEngine engine = new(); engine.LoadScript(script); - Stopwatch stopwatch = Stopwatch.StartNew(); engine.Execute(); - stopwatch.Stop(); Debug.Assert(engine.State == VMState.HALT); - Console.WriteLine($"Benchmark: {name},\tTime: {stopwatch.Elapsed}"); } } } diff --git a/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj b/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj index 4c3c3d6057..ae717e8254 100644 --- a/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj +++ b/benchmarks/Neo.VM.Benchmarks/Neo.VM.Benchmarks.csproj @@ -10,6 +10,7 @@ + diff --git a/benchmarks/Neo.VM.Benchmarks/Program.cs b/benchmarks/Neo.VM.Benchmarks/Program.cs index a9c86f405d..028dff9460 100644 --- a/benchmarks/Neo.VM.Benchmarks/Program.cs +++ b/benchmarks/Neo.VM.Benchmarks/Program.cs @@ -9,10 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.VM; -using System.Reflection; +using BenchmarkDotNet.Running; +using Neo.VM.Benchmark; -foreach (var method in typeof(Benchmarks).GetMethods(BindingFlags.Public | BindingFlags.Static)) -{ - method.CreateDelegate().Invoke(); -} +BenchmarkRunner.Run(); From 450cb6164e3b5ab2fec8965c3a8bb246adec062a Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 30 Jul 2024 10:29:33 -0700 Subject: [PATCH 4/6] [rpc] Extend `getversion` RPC response with additional protocol settings (#3443) * getversion * Extend client --------- Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com> --- src/Plugins/RpcClient/Models/RpcVersion.cs | 13 ++++++++ src/Plugins/RpcServer/RpcServer.Node.cs | 2 ++ tests/Neo.Network.RPC.Tests/RpcTestCases.json | 30 +++++++++++++++++++ .../UT_RpcServer.Node.cs | 2 ++ 4 files changed, 47 insertions(+) diff --git a/src/Plugins/RpcClient/Models/RpcVersion.cs b/src/Plugins/RpcClient/Models/RpcVersion.cs index 430d659f7c..369c206e93 100644 --- a/src/Plugins/RpcClient/Models/RpcVersion.cs +++ b/src/Plugins/RpcClient/Models/RpcVersion.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Cryptography.ECC; using Neo.Json; using System; using System.Collections.Generic; @@ -30,6 +31,8 @@ public class RpcProtocol public int MemoryPoolMaxTransactions { get; set; } public ulong InitialGasDistribution { get; set; } public IReadOnlyDictionary Hardforks { get; set; } + public IReadOnlyList SeedList { get; set; } + public IReadOnlyList StandbyCommittee { get; set; } public JObject ToJson() { @@ -49,6 +52,8 @@ public JObject ToJson() ["name"] = StripPrefix(s.Key.ToString(), "HF_"), ["blockheight"] = s.Value, })); + json["standbycommittee"] = new JArray(StandbyCommittee.Select(u => new JString(u.ToString()))); + json["seedlist"] = new JArray(SeedList.Select(u => new JString(u))); return json; } @@ -71,6 +76,14 @@ public static RpcProtocol FromJson(JObject json) // Add HF_ prefix to the hardfork response for proper Hardfork enum parsing. return new KeyValuePair(Enum.Parse(name.StartsWith("HF_") ? name : $"HF_{name}"), (uint)s["blockheight"].AsNumber()); })), + SeedList = new List(((JArray)json["seedlist"]).Select(s => + { + return s.AsString(); + })), + StandbyCommittee = new List(((JArray)json["standbycommittee"]).Select(s => + { + return ECPoint.Parse(s.AsString(), ECCurve.Secp256r1); + })) }; } diff --git a/src/Plugins/RpcServer/RpcServer.Node.cs b/src/Plugins/RpcServer/RpcServer.Node.cs index 21ca583090..716125e2cf 100644 --- a/src/Plugins/RpcServer/RpcServer.Node.cs +++ b/src/Plugins/RpcServer/RpcServer.Node.cs @@ -139,6 +139,8 @@ protected internal virtual JToken GetVersion(JArray _params) forkJson["blockheight"] = hf.Value; return forkJson; })); + protocol["standbycommittee"] = new JArray(system.Settings.StandbyCommittee.Select(u => new JString(u.ToString()))); + protocol["seedlist"] = new JArray(system.Settings.SeedList.Select(u => new JString(u))); json["rpc"] = rpc; json["protocol"] = protocol; return json; diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index cfbffb3ede..c2e4f4b5a2 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -2496,6 +2496,36 @@ "name": "Aspidochelone", "blockheight": 0 } + ], + "standbycommittee": [ + "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", + "02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093", + "03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a", + "02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554", + "024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d", + "02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e", + "02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70", + "023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe", + "03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379", + "03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050", + "03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0", + "02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62", + "03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0", + "0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654", + "020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639", + "0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30", + "03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde", + "02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad", + "0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d", + "03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc", + "02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a" + ], + "seedlist": [ + "seed1.neo.org:10333", + "seed2.neo.org:10333", + "seed3.neo.org:10333", + "seed4.neo.org:10333", + "seed5.neo.org:10333" ] } } diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs index 413df59441..c8b655024c 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs @@ -42,6 +42,8 @@ public void TestGetVersion() Assert.IsTrue(protocol.ContainsProperty("maxvaliduntilblockincrement")); Assert.IsTrue(protocol.ContainsProperty("maxtransactionsperblock")); Assert.IsTrue(protocol.ContainsProperty("memorypoolmaxtransactions")); + Assert.IsTrue(protocol.ContainsProperty("standbycommittee")); + Assert.IsTrue(protocol.ContainsProperty("seedlist")); } #region SendRawTransaction Tests From 62789616d2249dc1202db2e91b0e955c28235a5f Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 1 Aug 2024 15:06:07 +0800 Subject: [PATCH 5/6] [Neo Core Add] add char support (#3441) * add char support * Update src/Neo/VM/Helper.cs * add char unit test --------- Co-authored-by: Shargon --- src/Neo/VM/Helper.cs | 3 +++ tests/Neo.UnitTests/VM/UT_Helper.cs | 37 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 4a82041ea5..c6423ac1f1 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -217,6 +217,9 @@ public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) case short data: builder.EmitPush(data); break; + case char data: + builder.EmitPush((ushort)data); + break; case ushort data: builder.EmitPush(data); break; diff --git a/tests/Neo.UnitTests/VM/UT_Helper.cs b/tests/Neo.UnitTests/VM/UT_Helper.cs index 4178ed58d3..3e83256669 100644 --- a/tests/Neo.UnitTests/VM/UT_Helper.cs +++ b/tests/Neo.UnitTests/VM/UT_Helper.cs @@ -18,6 +18,7 @@ using Neo.SmartContract.Native; using Neo.VM; using Neo.VM.Types; +using Org.BouncyCastle.Asn1.Tsp; using System; using System.Collections.Generic; using System.Linq; @@ -152,7 +153,7 @@ public void TestEmitAppCall3() sb.EmitDynamicCall(UInt160.Zero, "AAAAA", true); byte[] tempArray = new byte[38]; tempArray[0] = (byte)OpCode.PUSHT; - tempArray[1] = (byte)OpCode.PUSH1;//arg.Length + tempArray[1] = (byte)OpCode.PUSH1;//arg.Length tempArray[2] = (byte)OpCode.PACK; tempArray[3] = (byte)OpCode.PUSH15;//(byte)CallFlags.All; tempArray[4] = (byte)OpCode.PUSHDATA1; @@ -401,6 +402,7 @@ public void TestEmitPush3() TestEmitPush3Byte(); TestEmitPush3Short(); TestEmitPush3Ushort(); + TestEmitPush3Char(); TestEmitPush3Int(); TestEmitPush3Uint(); TestEmitPush3Long(); @@ -472,6 +474,16 @@ private void TestEmitPush3Ushort() CollectionAssert.AreEqual(tempArray, sb.ToArray()); } + private void TestEmitPush3Char() + { + ScriptBuilder sb = new ScriptBuilder(); + char temp = char.MinValue; + VM.Helper.EmitPush(sb, temp); + byte[] tempArray = new byte[1]; + tempArray[0] = (byte)OpCode.PUSH0; + CollectionAssert.AreEqual(tempArray, sb.ToArray()); + } + private void TestEmitPush3Short() { ScriptBuilder sb = new ScriptBuilder(); @@ -630,5 +642,28 @@ private void TestToParaMeter2VMArray() Assert.AreEqual(ContractParameterType.Array, parameter.Type); Assert.AreEqual(0, ((List)parameter.Value).Count); } + + [TestMethod] + public void TestCharAsUInt16() + { + Assert.AreEqual(ushort.MaxValue, char.MaxValue); + Assert.AreEqual(ushort.MinValue, char.MinValue); + + // test every char in a loop + for (int i = ushort.MinValue; i < char.MinValue; i++) + { + var c = Convert.ToChar(i); + Assert.AreEqual(i, c); + } + + for (int i = ushort.MinValue; i < ushort.MaxValue; i++) + { + using var sbUInt16 = new ScriptBuilder(); + using var sbChar = new ScriptBuilder(); + sbUInt16.EmitPush((ushort)i); + sbChar.EmitPush(Convert.ToChar(i)); + CollectionAssert.AreEqual(sbUInt16.ToArray(), sbChar.ToArray()); + } + } } } From 7bded56c50fc84abbceb7ee242d4826a026984e1 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 1 Aug 2024 10:55:54 +0200 Subject: [PATCH 6/6] Clean using --- src/Neo/Wallets/Helper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Neo/Wallets/Helper.cs b/src/Neo/Wallets/Helper.cs index 5f24baa134..46e455d7a9 100644 --- a/src/Neo/Wallets/Helper.cs +++ b/src/Neo/Wallets/Helper.cs @@ -9,7 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Akka.Routing; using Neo.Cryptography; using Neo.IO; using Neo.Network.P2P;