diff --git a/src/neo/Consensus/ConsensusService.cs b/src/neo/Consensus/ConsensusService.cs index 3c5c334e11..ae901611b3 100644 --- a/src/neo/Consensus/ConsensusService.cs +++ b/src/neo/Consensus/ConsensusService.cs @@ -573,7 +573,7 @@ private void OnTimer(Timer timer) { var reason = ChangeViewReason.Timeout; - if (context.Block != null && context.TransactionHashes?.Count() > context.Transactions?.Count) + if (context.Block != null && context.TransactionHashes?.Length > context.Transactions?.Count) { reason = ChangeViewReason.TxNotFound; } diff --git a/src/neo/Cryptography/Base58.cs b/src/neo/Cryptography/Base58.cs index 1920bed10d..4a39acfbef 100644 --- a/src/neo/Cryptography/Base58.cs +++ b/src/neo/Cryptography/Base58.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Numerics; using System.Text; +using static Neo.Helper; namespace Neo.Cryptography { @@ -27,7 +28,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 leadingZeros.Concat(bytesWithoutLeadingZeros).ToArray(); + return Concat(leadingZeros, bytesWithoutLeadingZeros); } public static string Encode(byte[] input) diff --git a/src/neo/Cryptography/Crypto.cs b/src/neo/Cryptography/Crypto.cs index c835e3eebb..5bf90a6c97 100644 --- a/src/neo/Cryptography/Crypto.cs +++ b/src/neo/Cryptography/Crypto.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Security.Cryptography; namespace Neo.Cryptography @@ -26,8 +25,8 @@ public byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey) D = prikey, Q = new ECPoint { - X = pubkey.Take(32).ToArray(), - Y = pubkey.Skip(32).ToArray() + X = pubkey[..32], + Y = pubkey[32..] } })) { @@ -41,7 +40,7 @@ public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey) { try { - pubkey = Cryptography.ECC.ECPoint.DecodePoint(pubkey, Cryptography.ECC.ECCurve.Secp256r1).EncodePoint(false).Skip(1).ToArray(); + pubkey = ECC.ECPoint.DecodePoint(pubkey, ECC.ECCurve.Secp256r1).EncodePoint(false)[1..]; } catch { @@ -50,7 +49,7 @@ public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey) } else if (pubkey.Length == 65 && pubkey[0] == 0x04) { - pubkey = pubkey.Skip(1).ToArray(); + pubkey = pubkey[1..]; } else if (pubkey.Length != 64) { @@ -61,8 +60,8 @@ public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey) Curve = ECCurve.NamedCurves.nistP256, Q = new ECPoint { - X = pubkey.Take(32).ToArray(), - Y = pubkey.Skip(32).ToArray() + X = pubkey[..32], + Y = pubkey[32..] } })) { diff --git a/src/neo/Cryptography/ECC/ECCurve.cs b/src/neo/Cryptography/ECC/ECCurve.cs index 45d70d31f4..6fc476ff84 100644 --- a/src/neo/Cryptography/ECC/ECCurve.cs +++ b/src/neo/Cryptography/ECC/ECCurve.cs @@ -12,9 +12,12 @@ public class ECCurve public readonly ECPoint Infinity; public readonly ECPoint G; + public readonly int ExpectedECPointLength; + private ECCurve(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, byte[] G) { this.Q = Q; + this.ExpectedECPointLength = (Q.GetBitLength() + 7) / 8; this.A = new ECFieldElement(A, this); this.B = new ECFieldElement(B, this); this.N = N; diff --git a/src/neo/Cryptography/ECC/ECFieldElement.cs b/src/neo/Cryptography/ECC/ECFieldElement.cs index 33d593b4cf..948afc263d 100644 --- a/src/neo/Cryptography/ECC/ECFieldElement.cs +++ b/src/neo/Cryptography/ECC/ECFieldElement.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Numerics; namespace Neo.Cryptography.ECC @@ -28,9 +27,7 @@ public override bool Equals(object obj) if (obj == this) return true; - ECFieldElement other = obj as ECFieldElement; - - if (other == null) + if (!(obj is ECFieldElement other)) return false; return Equals(other); @@ -145,7 +142,9 @@ public byte[] ToByteArray() byte[] data = Value.ToByteArray(isUnsigned: true, isBigEndian: true); if (data.Length == 32) return data; - return Enumerable.Repeat(0, 32 - data.Length).Concat(data).ToArray(); + byte[] buffer = new byte[32]; + Buffer.BlockCopy(data, 0, buffer, buffer.Length - data.Length, data.Length); + return buffer; } public static ECFieldElement operator -(ECFieldElement x) diff --git a/src/neo/Cryptography/ECC/ECPoint.cs b/src/neo/Cryptography/ECC/ECPoint.cs index d597c4a8c5..7eef7362e2 100644 --- a/src/neo/Cryptography/ECC/ECPoint.cs +++ b/src/neo/Cryptography/ECC/ECPoint.cs @@ -1,8 +1,8 @@ using Neo.IO; using System; using System.IO; -using System.Linq; using System.Numerics; +using static Neo.Helper; namespace Neo.Cryptography.ECC { @@ -18,10 +18,7 @@ public bool IsInfinity public int Size => IsInfinity ? 1 : 33; - public ECPoint() - : this(null, null, ECCurve.Secp256r1) - { - } + public ECPoint() : this(null, null, ECCurve.Secp256r1) { } internal ECPoint(ECFieldElement x, ECFieldElement y, ECCurve curve) { @@ -43,13 +40,12 @@ public int CompareTo(ECPoint other) public static ECPoint DecodePoint(byte[] encoded, ECCurve curve) { ECPoint p = null; - int expectedLength = (curve.Q.GetBitLength() + 7) / 8; switch (encoded[0]) { case 0x02: // compressed case 0x03: // compressed { - if (encoded.Length != (expectedLength + 1)) + if (encoded.Length != (curve.ExpectedECPointLength + 1)) throw new FormatException("Incorrect length for compressed encoding"); int yTilde = encoded[0] & 1; BigInteger X1 = new BigInteger(encoded.AsSpan(1), isUnsigned: true, isBigEndian: true); @@ -58,10 +54,10 @@ public static ECPoint DecodePoint(byte[] encoded, ECCurve curve) } case 0x04: // uncompressed { - if (encoded.Length != (2 * expectedLength + 1)) + if (encoded.Length != (2 * curve.ExpectedECPointLength + 1)) throw new FormatException("Incorrect length for uncompressed/hybrid encoding"); - BigInteger X1 = new BigInteger(encoded.AsSpan(1, expectedLength), isUnsigned: true, isBigEndian: true); - BigInteger Y1 = new BigInteger(encoded.AsSpan(1 + expectedLength), isUnsigned: true, isBigEndian: true); + BigInteger X1 = new BigInteger(encoded.AsSpan(1, curve.ExpectedECPointLength), isUnsigned: true, isBigEndian: true); + BigInteger Y1 = new BigInteger(encoded.AsSpan(1 + curve.ExpectedECPointLength), isUnsigned: true, isBigEndian: true); p = new ECPoint(new ECFieldElement(X1, curve), new ECFieldElement(Y1, curve), curve); break; } @@ -105,23 +101,22 @@ void ISerializable.Deserialize(BinaryReader reader) public static ECPoint DeserializeFrom(BinaryReader reader, ECCurve curve) { - int expectedLength = (curve.Q.GetBitLength() + 7) / 8; - byte[] buffer = new byte[1 + expectedLength * 2]; + byte[] buffer = new byte[1 + curve.ExpectedECPointLength * 2]; buffer[0] = reader.ReadByte(); switch (buffer[0]) { case 0x02: case 0x03: { - if (reader.Read(buffer, 1, expectedLength) != expectedLength) + if (reader.Read(buffer, 1, curve.ExpectedECPointLength) != curve.ExpectedECPointLength) { throw new FormatException(); } - return DecodePoint(buffer.Take(1 + expectedLength).ToArray(), curve); + return DecodePoint(buffer[..(1 + curve.ExpectedECPointLength)], curve); } case 0x04: { - if (reader.Read(buffer, 1, expectedLength * 2) != expectedLength * 2) + if (reader.Read(buffer, 1, curve.ExpectedECPointLength * 2) != curve.ExpectedECPointLength * 2) { throw new FormatException(); } @@ -175,10 +170,10 @@ public static ECPoint FromBytes(byte[] pubkey, ECCurve curve) return DecodePoint(pubkey, curve); case 64: case 72: - return DecodePoint(new byte[] { 0x04 }.Concat(pubkey.Skip(pubkey.Length - 64)).ToArray(), curve); + return DecodePoint(Concat(new byte[] { 0x04 }, pubkey[^64..]), curve); case 96: case 104: - return DecodePoint(new byte[] { 0x04 }.Concat(pubkey.Skip(pubkey.Length - 96).Take(64)).ToArray(), curve); + return DecodePoint(Concat(new byte[] { 0x04 }, pubkey[^96..^32]), curve); default: throw new FormatException(); } @@ -241,7 +236,7 @@ internal static ECPoint Multiply(ECPoint p, BigInteger k) // The length of the precomputation array int preCompLen = 1; - ECPoint[] preComp = preComp = new ECPoint[] { p }; + ECPoint[] preComp = new ECPoint[] { p }; ECPoint twiceP = p.Twice(); if (preCompLen < reqPreCompLen) diff --git a/src/neo/Cryptography/Helper.cs b/src/neo/Cryptography/Helper.cs index 07c9ce74e9..83e0d7afa1 100644 --- a/src/neo/Cryptography/Helper.cs +++ b/src/neo/Cryptography/Helper.cs @@ -77,9 +77,9 @@ public static byte[] Base58CheckDecode(this string input) byte[] buffer = Base58.Decode(input); if (buffer.Length < 4) throw new FormatException(); byte[] checksum = buffer.Sha256(0, buffer.Length - 4).Sha256(); - if (!buffer.Skip(buffer.Length - 4).SequenceEqual(checksum.Take(4))) + if (!buffer.AsSpan(^4).SequenceEqual(checksum.AsSpan(..4))) throw new FormatException(); - var ret = buffer.Take(buffer.Length - 4).ToArray(); + var ret = buffer[..^4]; Array.Clear(buffer, 0, buffer.Length); return ret; } diff --git a/src/neo/Helper.cs b/src/neo/Helper.cs index 8fa7005f5e..6706355574 100644 --- a/src/neo/Helper.cs +++ b/src/neo/Helper.cs @@ -17,6 +17,7 @@ public static class Helper { private static readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int BitLen(int w) { return (w < 1 << 15 ? (w < 1 << 7 @@ -34,6 +35,23 @@ private static int BitLen(int w) : (w < 1 << 29 ? (w < 1 << 28 ? 28 : 29) : (w < 1 << 30 ? 30 : 31))))); } + [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; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int GetBitLength(this BigInteger i) { byte[] b = i.ToByteArray(); @@ -110,6 +128,7 @@ public static byte[] HexToBytes(this string value) return result; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static BigInteger Mod(this BigInteger x, BigInteger y) { x %= y; @@ -172,13 +191,13 @@ public static BigInteger Sum(this IEnumerable source) return sum; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TestBit(this BigInteger i, int index) { return (i & (BigInteger.One << index)) > BigInteger.Zero; } - - public static string ToHexString(this IEnumerable value) + public static string ToHexString(this byte[] value) { StringBuilder sb = new StringBuilder(); foreach (byte b in value) @@ -186,6 +205,14 @@ public static string ToHexString(this IEnumerable value) return sb.ToString(); } + public static string ToHexString(this byte[] value, bool reverse = false) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.Length; i++) + sb.AppendFormat("{0:x2}", value[reverse ? value.Length - i - 1 : i]); + return sb.ToString(); + } + public static string ToHexString(this ReadOnlySpan value) { StringBuilder sb = new StringBuilder(); diff --git a/src/neo/IO/Caching/DataCache.cs b/src/neo/IO/Caching/DataCache.cs index 373c4f2757..df6b6775a8 100644 --- a/src/neo/IO/Caching/DataCache.cs +++ b/src/neo/IO/Caching/DataCache.cs @@ -129,7 +129,7 @@ public void DeleteWhere(Func predicate) lock (dictionary) { cached = dictionary - .Where(p => p.Value.State != TrackState.Deleted && (key_prefix == null || p.Key.ToArray().Take(key_prefix.Length).SequenceEqual(key_prefix))) + .Where(p => p.Value.State != TrackState.Deleted && (key_prefix == null || p.Key.ToArray().AsSpan().StartsWith(key_prefix))) .Select(p => ( KeyBytes: p.Key.ToArray(), diff --git a/src/neo/IO/Data/LevelDB/Helper.cs b/src/neo/IO/Data/LevelDB/Helper.cs index d4c451f574..585d282414 100644 --- a/src/neo/IO/Data/LevelDB/Helper.cs +++ b/src/neo/IO/Data/LevelDB/Helper.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; namespace Neo.IO.Data.LevelDB { @@ -26,7 +25,7 @@ public static IEnumerable Find(this DB db, ReadOptions options, Slice pref byte[] x = key.ToArray(); byte[] y = prefix.ToArray(); if (x.Length < y.Length) break; - if (!x.Take(y.Length).SequenceEqual(y)) break; + if (!x.AsSpan().StartsWith(y)) break; yield return resultSelector(key, it.Value()); } } diff --git a/src/neo/IO/Data/LevelDB/Slice.cs b/src/neo/IO/Data/LevelDB/Slice.cs index 1f9d927783..fc52e6eb08 100644 --- a/src/neo/IO/Data/LevelDB/Slice.cs +++ b/src/neo/IO/Data/LevelDB/Slice.cs @@ -1,6 +1,5 @@ using Neo.Cryptography; using System; -using System.Linq; using System.Runtime.InteropServices; using System.Text; @@ -29,7 +28,7 @@ public int CompareTo(Slice other) public bool Equals(Slice other) { if (buffer.Length != other.buffer.Length) return false; - return buffer.SequenceEqual(other.buffer); + return MemoryExtensions.SequenceEqual(buffer, other.buffer); } public override bool Equals(object obj) diff --git a/src/neo/Ledger/StorageKey.cs b/src/neo/Ledger/StorageKey.cs index c214260c21..70e045560e 100644 --- a/src/neo/Ledger/StorageKey.cs +++ b/src/neo/Ledger/StorageKey.cs @@ -2,7 +2,6 @@ using Neo.IO; using System; using System.IO; -using System.Linq; namespace Neo.Ledger { @@ -28,7 +27,7 @@ internal static byte[] CreateSearchPrefix(UInt160 hash, byte[] prefix) } if (remain > 0) ms.Write(prefix, index, remain); - return hash.ToArray().Concat(ms.ToArray()).ToArray(); + return Helper.Concat(hash.ToArray(), ms.ToArray()); } } @@ -44,7 +43,7 @@ public bool Equals(StorageKey other) return false; if (ReferenceEquals(this, other)) return true; - return ScriptHash.Equals(other.ScriptHash) && Key.SequenceEqual(other.Key); + return ScriptHash.Equals(other.ScriptHash) && MemoryExtensions.SequenceEqual(Key, other.Key); } public override bool Equals(object obj) diff --git a/src/neo/Network/P2P/Payloads/Block.cs b/src/neo/Network/P2P/Payloads/Block.cs index 305536c38d..0533e0f373 100644 --- a/src/neo/Network/P2P/Payloads/Block.cs +++ b/src/neo/Network/P2P/Payloads/Block.cs @@ -3,7 +3,6 @@ using Neo.IO.Json; using Neo.Ledger; using Neo.SmartContract; -using Neo.VM; using Neo.VM.Types; using System; using System.Collections.Generic; @@ -130,7 +129,7 @@ public TrimmedBlock Trim() Index = Index, NextConsensus = NextConsensus, Witness = Witness, - Hashes = new[] { ConsensusData.Hash }.Concat(Transactions.Select(p => p.Hash)).ToArray(), + Hashes = Transactions.Select(p => p.Hash).Prepend(ConsensusData.Hash).ToArray(), ConsensusData = ConsensusData }; } diff --git a/src/neo/Network/P2P/Payloads/InvPayload.cs b/src/neo/Network/P2P/Payloads/InvPayload.cs index 613d280234..662398e6a4 100644 --- a/src/neo/Network/P2P/Payloads/InvPayload.cs +++ b/src/neo/Network/P2P/Payloads/InvPayload.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; namespace Neo.Network.P2P.Payloads { @@ -30,7 +29,7 @@ public static IEnumerable CreateGroup(InventoryType type, UInt256[] yield return new InvPayload { Type = type, - Hashes = hashes.Skip(i).Take(MaxHashesCount).ToArray() + Hashes = hashes[i..(i + MaxHashesCount)] }; } diff --git a/src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs b/src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs index 0d00434cd4..cf2dcba2d9 100644 --- a/src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs +++ b/src/neo/Network/P2P/Payloads/MerkleBlockPayload.cs @@ -16,7 +16,7 @@ public class MerkleBlockPayload : BlockBase public static MerkleBlockPayload Create(Block block, BitArray flags) { - MerkleTree tree = new MerkleTree(new[] { block.ConsensusData.Hash }.Concat(block.Transactions.Select(p => p.Hash)).ToArray()); + MerkleTree tree = new MerkleTree(block.Transactions.Select(p => p.Hash).Prepend(block.ConsensusData.Hash).ToArray()); byte[] buffer = new byte[(flags.Length + 7) / 8]; flags.CopyTo(buffer, 0); return new MerkleBlockPayload diff --git a/src/neo/Network/RPC/Nep5API.cs b/src/neo/Network/RPC/Nep5API.cs index 26ae041ae0..619c755280 100644 --- a/src/neo/Network/RPC/Nep5API.cs +++ b/src/neo/Network/RPC/Nep5API.cs @@ -5,6 +5,7 @@ using Neo.Wallets; using System.Linq; using System.Numerics; +using static Neo.Helper; namespace Neo.Network.RPC { @@ -78,11 +79,10 @@ public BigInteger TotalSupply(UInt160 scriptHash) /// public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash) { - byte[] script = scriptHash.MakeScript("name") - .Concat(scriptHash.MakeScript("symbol")) - .Concat(scriptHash.MakeScript("decimals")) - .Concat(scriptHash.MakeScript("totalSupply")) - .ToArray(); + byte[] script = Concat(scriptHash.MakeScript("name"), + scriptHash.MakeScript("symbol"), + scriptHash.MakeScript("decimals"), + scriptHash.MakeScript("totalSupply")); var result = rpcClient.InvokeScript(script).Stack; diff --git a/src/neo/Network/RPC/RpcServer.cs b/src/neo/Network/RPC/RpcServer.cs index 953783b5ed..4bdaf91caf 100644 --- a/src/neo/Network/RPC/RpcServer.cs +++ b/src/neo/Network/RPC/RpcServer.cs @@ -411,7 +411,7 @@ public void Start(IPAddress bindAddress, int port, string sslCert = null, string { // options.EnableForHttps = false; options.Providers.Add(); - options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/json-rpc" }); + options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Append("application/json-rpc"); }); services.Configure(options => diff --git a/src/neo/Persistence/LevelDB/Snapshot.cs b/src/neo/Persistence/LevelDB/Snapshot.cs index dbf5cbe278..712268924c 100644 --- a/src/neo/Persistence/LevelDB/Snapshot.cs +++ b/src/neo/Persistence/LevelDB/Snapshot.cs @@ -1,6 +1,5 @@ using Neo.IO.Data.LevelDB; using System.Collections.Generic; -using System.Linq; using LSnapshot = Neo.IO.Data.LevelDB.Snapshot; namespace Neo.Persistence.LevelDB @@ -37,7 +36,7 @@ public void Dispose() public IEnumerable<(byte[] Key, byte[] Value)> Find(byte table, byte[] prefix) { - return db.Find(options, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray().Skip(1).ToArray(), v.ToArray())); + return db.Find(options, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray()[1..], v.ToArray())); } public void Put(byte table, byte[] key, byte[] value) diff --git a/src/neo/Persistence/LevelDB/Store.cs b/src/neo/Persistence/LevelDB/Store.cs index fbded76391..6758744281 100644 --- a/src/neo/Persistence/LevelDB/Store.cs +++ b/src/neo/Persistence/LevelDB/Store.cs @@ -1,7 +1,6 @@ using Neo.IO.Data.LevelDB; using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; namespace Neo.Persistence.LevelDB @@ -41,7 +40,7 @@ public void Dispose() public IEnumerable<(byte[], byte[])> Find(byte table, byte[] prefix) { - return db.Find(ReadOptions.Default, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray().Skip(1).ToArray(), v.ToArray())); + return db.Find(ReadOptions.Default, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray()[1..], v.ToArray())); } public ISnapshot GetSnapshot() diff --git a/src/neo/Persistence/Memory/Snapshot.cs b/src/neo/Persistence/Memory/Snapshot.cs index 82455ddea8..a8edf8cf05 100644 --- a/src/neo/Persistence/Memory/Snapshot.cs +++ b/src/neo/Persistence/Memory/Snapshot.cs @@ -1,4 +1,5 @@ using Neo.IO; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; @@ -44,7 +45,7 @@ public void Dispose() { IEnumerable> records = immutableData[table]; if (prefix?.Length > 0) - records = records.Where(p => p.Key.Length >= prefix.Length && p.Key.Take(prefix.Length).SequenceEqual(prefix)); + records = records.Where(p => p.Key.AsSpan().StartsWith(prefix)); records = records.OrderBy(p => p.Key, ByteArrayComparer.Default); return records.Select(p => (p.Key, p.Value)); } diff --git a/src/neo/Persistence/Memory/Store.cs b/src/neo/Persistence/Memory/Store.cs index 5e2d11eeb9..067cf073d9 100644 --- a/src/neo/Persistence/Memory/Store.cs +++ b/src/neo/Persistence/Memory/Store.cs @@ -30,7 +30,7 @@ public void Dispose() { IEnumerable> records = innerData[table]; if (prefix?.Length > 0) - records = records.Where(p => p.Key.Length >= prefix.Length && p.Key.Take(prefix.Length).SequenceEqual(prefix)); + records = records.Where(p => p.Key.AsSpan().StartsWith(prefix)); records = records.OrderBy(p => p.Key, ByteArrayComparer.Default); foreach (var pair in records) yield return (pair.Key, pair.Value); diff --git a/src/neo/SmartContract/ContractParametersContext.cs b/src/neo/SmartContract/ContractParametersContext.cs index 4465e7831e..1ddc703830 100644 --- a/src/neo/SmartContract/ContractParametersContext.cs +++ b/src/neo/SmartContract/ContractParametersContext.cs @@ -153,7 +153,7 @@ public bool AddSignature(Contract contract, ECPoint pubkey, byte[] signature) } while (contract.Script[i++] == 33) { - points.Add(ECPoint.DecodePoint(contract.Script.Skip(i).Take(33).ToArray(), ECCurve.Secp256r1)); + points.Add(ECPoint.DecodePoint(contract.Script[i..(i + 33)], ECCurve.Secp256r1)); i += 33; } } @@ -256,9 +256,9 @@ public Witness[] GetWitnesses() ContextItem item = ContextItems[ScriptHashes[i]]; using (ScriptBuilder sb = new ScriptBuilder()) { - foreach (ContractParameter parameter in item.Parameters.Reverse()) + for (int j = item.Parameters.Length - 1; j >= 0; j--) { - sb.EmitPush(parameter); + sb.EmitPush(item.Parameters[j]); } witnesses[i] = new Witness { diff --git a/src/neo/SmartContract/InteropService.NEO.cs b/src/neo/SmartContract/InteropService.NEO.cs index a133e882fa..07fac8e2b7 100644 --- a/src/neo/SmartContract/InteropService.NEO.cs +++ b/src/neo/SmartContract/InteropService.NEO.cs @@ -250,7 +250,7 @@ private static bool Storage_Find(ApplicationEngine engine) if (!CheckStorageContext(engine, context)) return false; byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray(); byte[] prefix_key = StorageKey.CreateSearchPrefix(context.ScriptHash, prefix); - StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.Take(prefix.Length).SequenceEqual(prefix)).GetEnumerator())); + StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.AsSpan().StartsWith(prefix)).GetEnumerator())); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator)); return true; } diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index e0023b3841..e3bfb34c11 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -204,7 +204,7 @@ private StackItem GetRegisteredValidators(ApplicationEngine engine, VMArray args byte[] prefix_key = StorageKey.CreateSearchPrefix(Hash, new[] { Prefix_Validator }); return snapshot.Storages.Find(prefix_key).Select(p => ( - p.Key.Key.Skip(1).ToArray().AsSerializable(), + p.Key.Key.AsSerializable(1), ValidatorState.FromByteArray(p.Value.Value).Votes )); } diff --git a/src/neo/UInt160.cs b/src/neo/UInt160.cs index 0052d45569..8eaf0ffc23 100644 --- a/src/neo/UInt160.cs +++ b/src/neo/UInt160.cs @@ -1,6 +1,5 @@ using System; using System.Globalization; -using System.Linq; namespace Neo { @@ -82,7 +81,9 @@ public unsafe bool Equals(UInt160 other) value = value.Substring(2); if (value.Length != Length * 2) throw new FormatException(); - return new UInt160(value.HexToBytes().Reverse().ToArray()); + byte[] data = value.HexToBytes(); + Array.Reverse(data); + return new UInt160(data); } /// @@ -110,7 +111,8 @@ public static bool TryParse(string s, out UInt160 result) result = null; return false; } - result = new UInt160(data.Reverse().ToArray()); + Array.Reverse(data); + result = new UInt160(data); return true; } diff --git a/src/neo/UInt256.cs b/src/neo/UInt256.cs index 72719f0e90..57e91fadd7 100644 --- a/src/neo/UInt256.cs +++ b/src/neo/UInt256.cs @@ -1,6 +1,5 @@ using System; using System.Globalization; -using System.Linq; namespace Neo { @@ -83,7 +82,9 @@ public unsafe bool Equals(UInt256 other) s = s.Substring(2); if (s.Length != Length * 2) throw new FormatException(); - return new UInt256(s.HexToBytes().Reverse().ToArray()); + byte[] data = s.HexToBytes(); + Array.Reverse(data); + return new UInt256(data); } /// @@ -111,7 +112,8 @@ public static bool TryParse(string s, out UInt256 result) result = null; return false; } - result = new UInt256(data.Reverse().ToArray()); + Array.Reverse(data); + result = new UInt256(data); return true; } diff --git a/src/neo/UIntBase.cs b/src/neo/UIntBase.cs index 6b5f6d6acd..ab07670660 100644 --- a/src/neo/UIntBase.cs +++ b/src/neo/UIntBase.cs @@ -1,7 +1,6 @@ using Neo.IO; using System; using System.IO; -using System.Linq; using System.Runtime.CompilerServices; namespace Neo @@ -62,7 +61,7 @@ public bool Equals(UIntBase other) return true; if (data_bytes.Length != other.data_bytes.Length) return false; - return data_bytes.SequenceEqual(other.data_bytes); + return MemoryExtensions.SequenceEqual(data_bytes, other.data_bytes); } /// @@ -123,7 +122,7 @@ public byte[] ToArray() /// public override string ToString() { - return "0x" + data_bytes.Reverse().ToHexString(); + return "0x" + data_bytes.ToHexString(reverse: true); } /// diff --git a/src/neo/Wallets/Helper.cs b/src/neo/Wallets/Helper.cs index 5960876fe2..9de3dde7f3 100644 --- a/src/neo/Wallets/Helper.cs +++ b/src/neo/Wallets/Helper.cs @@ -2,7 +2,6 @@ using Neo.Network.P2P; using Neo.Network.P2P.Payloads; using System; -using System.Linq; namespace Neo.Wallets { @@ -10,7 +9,7 @@ public static class Helper { public static byte[] Sign(this IVerifiable verifiable, KeyPair key) { - return Crypto.Default.Sign(verifiable.GetHashData(), key.PrivateKey, key.PublicKey.EncodePoint(false).Skip(1).ToArray()); + return Crypto.Default.Sign(verifiable.GetHashData(), key.PrivateKey, key.PublicKey.EncodePoint(false)[1..]); } public static string ToAddress(this UInt160 scriptHash) @@ -28,7 +27,7 @@ public static UInt160 ToScriptHash(this string address) throw new FormatException(); if (data[0] != ProtocolSettings.Default.AddressVersion) throw new FormatException(); - return new UInt160(data.Skip(1).ToArray()); + return new UInt160(data[1..]); } } } diff --git a/src/neo/Wallets/KeyPair.cs b/src/neo/Wallets/KeyPair.cs index afea8e822a..55d720634b 100644 --- a/src/neo/Wallets/KeyPair.cs +++ b/src/neo/Wallets/KeyPair.cs @@ -56,10 +56,10 @@ public string Export(string passphrase, int N = 16384, int r = 8, int p = 8) { UInt160 script_hash = Contract.CreateSignatureRedeemScript(PublicKey).ToScriptHash(); string address = script_hash.ToAddress(); - byte[] addresshash = Encoding.ASCII.GetBytes(address).Sha256().Sha256().Take(4).ToArray(); + byte[] addresshash = Encoding.ASCII.GetBytes(address).Sha256().Sha256()[..4]; byte[] derivedkey = SCrypt.DeriveKey(Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64); - byte[] derivedhalf1 = derivedkey.Take(32).ToArray(); - byte[] derivedhalf2 = derivedkey.Skip(32).ToArray(); + byte[] derivedhalf1 = derivedkey[..32]; + byte[] derivedhalf2 = derivedkey[32..]; byte[] encryptedkey = XOR(PrivateKey, derivedhalf1).AES256Encrypt(derivedhalf2); byte[] buffer = new byte[39]; buffer[0] = 0x01; diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index f2cf92e7b2..ebc1e6b58f 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -151,8 +151,8 @@ public static byte[] GetPrivateKeyFromNEP2(string nep2, string passphrase, int N byte[] datapassphrase = Encoding.UTF8.GetBytes(passphrase); byte[] derivedkey = SCrypt.DeriveKey(datapassphrase, addresshash, N, r, p, 64); Array.Clear(datapassphrase, 0, datapassphrase.Length); - byte[] derivedhalf1 = derivedkey.Take(32).ToArray(); - byte[] derivedhalf2 = derivedkey.Skip(32).ToArray(); + byte[] derivedhalf1 = derivedkey[..32]; + byte[] derivedhalf2 = derivedkey[32..]; Array.Clear(derivedkey, 0, derivedkey.Length); byte[] encryptedkey = new byte[32]; Buffer.BlockCopy(data, 7, encryptedkey, 0, 32); @@ -163,7 +163,7 @@ public static byte[] GetPrivateKeyFromNEP2(string nep2, string passphrase, int N ECPoint pubkey = Cryptography.ECC.ECCurve.Secp256r1.G * prikey; UInt160 script_hash = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash(); string address = script_hash.ToAddress(); - if (!Encoding.ASCII.GetBytes(address).Sha256().Sha256().Take(4).SequenceEqual(addresshash)) + if (!Encoding.ASCII.GetBytes(address).Sha256().Sha256().AsSpan(0, 4).SequenceEqual(addresshash)) throw new FormatException(); return prikey; }