From bf9341222e04b7f38d4e4e606412435b4c4acc0a Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 2 Jul 2024 04:46:11 -0400 Subject: [PATCH 01/18] Part-1 `Neo.IO` - move --- src/{Neo/IO => Neo.IO}/Caching/Cache.cs | 56 ++++++++----------- src/{Neo/IO => Neo.IO}/Caching/FIFOCache.cs | 9 +-- .../IO => Neo.IO}/Caching/HashSetCache.cs | 36 ++++++------ .../IO => Neo.IO}/Caching/IndexedQueue.cs | 16 +++--- .../Caching/KeyedCollectionSlim.cs | 23 ++++---- src/Neo/Cryptography/Crypto.cs | 2 +- src/Neo/IO/Caching/ECDsaCache.cs | 5 +- .../Network/P2P/RemoteNode.ProtocolHandler.cs | 6 +- 8 files changed, 72 insertions(+), 81 deletions(-) rename src/{Neo/IO => Neo.IO}/Caching/Cache.cs (80%) rename src/{Neo/IO => Neo.IO}/Caching/FIFOCache.cs (72%) rename src/{Neo/IO => Neo.IO}/Caching/HashSetCache.cs (76%) rename src/{Neo/IO => Neo.IO}/Caching/IndexedQueue.cs (95%) rename src/{Neo/IO => Neo.IO}/Caching/KeyedCollectionSlim.cs (61%) diff --git a/src/Neo/IO/Caching/Cache.cs b/src/Neo.IO/Caching/Cache.cs similarity index 80% rename from src/Neo/IO/Caching/Cache.cs rename to src/Neo.IO/Caching/Cache.cs index 7895a8ca2d..1a66e6dca5 100644 --- a/src/Neo/IO/Caching/Cache.cs +++ b/src/Neo.IO/Caching/Cache.cs @@ -17,25 +17,21 @@ namespace Neo.IO.Caching { - internal abstract class Cache : ICollection, IDisposable + internal abstract class Cache + (int max_capacity, IEqualityComparer? comparer = null) : ICollection, IDisposable + where TKey : notnull { protected class CacheItem + (TKey key, TValue value) { - public readonly TKey Key; - public readonly TValue Value; - public readonly DateTime Time; - - public CacheItem(TKey key, TValue value) - { - Key = key; - Value = value; - Time = TimeProvider.Current.UtcNow; - } + public readonly TKey Key = key; + public readonly TValue Value = value; + public readonly DateTime Time = DateTime.UtcNow; } protected readonly ReaderWriterLockSlim RwSyncRootLock = new(LockRecursionPolicy.SupportsRecursion); - protected readonly Dictionary InnerDictionary; - private readonly int max_capacity; + protected readonly Dictionary InnerDictionary = new Dictionary(comparer); + private readonly int _max_capacity = max_capacity; public TValue this[TKey key] { @@ -44,7 +40,7 @@ public TValue this[TKey key] RwSyncRootLock.EnterReadLock(); try { - if (!InnerDictionary.TryGetValue(key, out CacheItem item)) throw new KeyNotFoundException(); + if (!InnerDictionary.TryGetValue(key, out CacheItem? item)) throw new KeyNotFoundException(); OnAccess(item); return item.Value; } @@ -73,15 +69,9 @@ public int Count public bool IsReadOnly => false; - public Cache(int max_capacity, IEqualityComparer comparer = null) - { - this.max_capacity = max_capacity; - InnerDictionary = new Dictionary(comparer); - } - public void Add(TValue item) { - TKey key = GetKeyForItem(item); + var key = GetKeyForItem(item); RwSyncRootLock.EnterWriteLock(); try { @@ -95,16 +85,16 @@ public void Add(TValue item) private void AddInternal(TKey key, TValue item) { - if (InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) + if (InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) { OnAccess(cacheItem); } else { - if (InnerDictionary.Count >= max_capacity) + if (InnerDictionary.Count >= _max_capacity) { //TODO: Perform a performance test on the PLINQ query to determine which algorithm is better here (parallel or not) - foreach (CacheItem item_del in InnerDictionary.Values.AsParallel().OrderBy(p => p.Time).Take(InnerDictionary.Count - max_capacity + 1)) + foreach (var item_del in InnerDictionary.Values.AsParallel().OrderBy(p => p.Time).Take(InnerDictionary.Count - _max_capacity + 1)) { RemoveInternal(item_del); } @@ -118,9 +108,9 @@ public void AddRange(IEnumerable items) RwSyncRootLock.EnterWriteLock(); try { - foreach (TValue item in items) + foreach (var item in items) { - TKey key = GetKeyForItem(item); + var key = GetKeyForItem(item); AddInternal(key, item); } } @@ -135,7 +125,7 @@ public void Clear() RwSyncRootLock.EnterWriteLock(); try { - foreach (CacheItem item_del in InnerDictionary.Values.ToArray()) + foreach (var item_del in InnerDictionary.Values.ToArray()) { RemoveInternal(item_del); } @@ -151,7 +141,7 @@ public bool Contains(TKey key) RwSyncRootLock.EnterReadLock(); try { - if (!InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) return false; + if (!InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) return false; OnAccess(cacheItem); return true; } @@ -171,7 +161,7 @@ public void CopyTo(TValue[] array, int arrayIndex) if (array == null) throw new ArgumentNullException(); if (arrayIndex < 0) throw new ArgumentOutOfRangeException(); if (arrayIndex + InnerDictionary.Count > array.Length) throw new ArgumentException(); - foreach (TValue item in this) + foreach (var item in this) { array[arrayIndex++] = item; } @@ -188,7 +178,7 @@ public IEnumerator GetEnumerator() RwSyncRootLock.EnterReadLock(); try { - foreach (TValue item in InnerDictionary.Values.Select(p => p.Value)) + foreach (var item in InnerDictionary.Values.Select(p => p.Value)) { yield return item; } @@ -211,7 +201,7 @@ public bool Remove(TKey key) RwSyncRootLock.EnterWriteLock(); try { - if (!InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) return false; + if (!InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) return false; RemoveInternal(cacheItem); return true; } @@ -242,7 +232,7 @@ public bool TryGet(TKey key, out TValue item) RwSyncRootLock.EnterReadLock(); try { - if (InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) + if (InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) { OnAccess(cacheItem); item = cacheItem.Value; @@ -253,7 +243,7 @@ public bool TryGet(TKey key, out TValue item) { RwSyncRootLock.ExitReadLock(); } - item = default; + item = default!; return false; } } diff --git a/src/Neo/IO/Caching/FIFOCache.cs b/src/Neo.IO/Caching/FIFOCache.cs similarity index 72% rename from src/Neo/IO/Caching/FIFOCache.cs rename to src/Neo.IO/Caching/FIFOCache.cs index af3e5e469d..b7e9f39e98 100644 --- a/src/Neo/IO/Caching/FIFOCache.cs +++ b/src/Neo.IO/Caching/FIFOCache.cs @@ -13,13 +13,10 @@ namespace Neo.IO.Caching { - internal abstract class FIFOCache : Cache + internal abstract class FIFOCache + (int max_capacity, IEqualityComparer? comparer = null) : Cache(max_capacity, comparer) + where TKey : notnull { - public FIFOCache(int max_capacity, IEqualityComparer comparer = null) - : base(max_capacity, comparer) - { - } - protected override void OnAccess(CacheItem item) { } diff --git a/src/Neo/IO/Caching/HashSetCache.cs b/src/Neo.IO/Caching/HashSetCache.cs similarity index 76% rename from src/Neo/IO/Caching/HashSetCache.cs rename to src/Neo.IO/Caching/HashSetCache.cs index bdef1c5e3a..577893e924 100644 --- a/src/Neo/IO/Caching/HashSetCache.cs +++ b/src/Neo.IO/Caching/HashSetCache.cs @@ -20,17 +20,17 @@ class HashSetCache : IReadOnlyCollection where T : IEquatable /// /// Sets where the Hashes are stored /// - private readonly LinkedList> sets = new(); + private readonly LinkedList> _sets = new(); /// - /// Maximum capacity of each bucket inside each HashSet of . + /// Maximum capacity of each bucket inside each HashSet of . /// - private readonly int bucketCapacity; + private readonly int _bucketCapacity; /// /// Maximum number of buckets for the LinkedList, meaning its maximum cardinality. /// - private readonly int maxBucketCount; + private readonly int _maxBucketCount; /// /// Entry count @@ -43,32 +43,32 @@ public HashSetCache(int bucketCapacity, int maxBucketCount = 10) if (maxBucketCount <= 0) throw new ArgumentOutOfRangeException($"{nameof(maxBucketCount)} should be greater than 0"); Count = 0; - this.bucketCapacity = bucketCapacity; - this.maxBucketCount = maxBucketCount; - sets.AddFirst(new HashSet()); + _bucketCapacity = bucketCapacity; + _maxBucketCount = maxBucketCount; + _sets.AddFirst([]); } public bool Add(T item) { if (Contains(item)) return false; Count++; - if (sets.First.Value.Count < bucketCapacity) return sets.First.Value.Add(item); + if (_sets.First?.Value.Count < _bucketCapacity) return _sets.First.Value.Add(item); var newSet = new HashSet { item }; - sets.AddFirst(newSet); - if (sets.Count > maxBucketCount) + _sets.AddFirst(newSet); + if (_sets.Count > _maxBucketCount) { - Count -= sets.Last.Value.Count; - sets.RemoveLast(); + Count -= _sets.Last?.Value.Count ?? 0; + _sets.RemoveLast(); } return true; } public bool Contains(T item) { - foreach (var set in sets) + foreach (var set in _sets) { if (set.Contains(item)) return true; } @@ -77,17 +77,17 @@ public bool Contains(T item) public void ExceptWith(IEnumerable items) { - List> removeList = null; + List> removeList = default!; foreach (var item in items) { - foreach (var set in sets) + foreach (var set in _sets) { if (set.Remove(item)) { Count--; if (set.Count == 0) { - removeList ??= new List>(); + removeList ??= []; removeList.Add(set); } break; @@ -97,13 +97,13 @@ public void ExceptWith(IEnumerable items) if (removeList == null) return; foreach (var set in removeList) { - sets.Remove(set); + _sets.Remove(set); } } public IEnumerator GetEnumerator() { - foreach (var set in sets) + foreach (var set in _sets) { foreach (var item in set) { diff --git a/src/Neo/IO/Caching/IndexedQueue.cs b/src/Neo.IO/Caching/IndexedQueue.cs similarity index 95% rename from src/Neo/IO/Caching/IndexedQueue.cs rename to src/Neo.IO/Caching/IndexedQueue.cs index 54440a871b..29b39a4947 100644 --- a/src/Neo/IO/Caching/IndexedQueue.cs +++ b/src/Neo.IO/Caching/IndexedQueue.cs @@ -89,14 +89,14 @@ public void Enqueue(T item) { if (_array.Length == _count) { - int newSize = _array.Length * GrowthFactor; + var newSize = _array.Length * GrowthFactor; if (_head == 0) { Array.Resize(ref _array, newSize); } else { - T[] buffer = new T[newSize]; + var buffer = new T[newSize]; Array.Copy(_array, _head, buffer, 0, _array.Length - _head); Array.Copy(_array, 0, buffer, _array.Length - _head, _head); _array = buffer; @@ -127,7 +127,7 @@ public bool TryPeek(out T item) { if (_count == 0) { - item = default; + item = default!; return false; } else @@ -145,7 +145,7 @@ public T Dequeue() { if (_count == 0) throw new InvalidOperationException("The queue is empty"); - T result = _array[_head]; + var result = _array[_head]; ++_head; _head %= _array.Length; --_count; @@ -161,7 +161,7 @@ public bool TryDequeue(out T item) { if (_count == 0) { - item = default; + item = default!; return false; } else @@ -194,7 +194,7 @@ public void TrimExcess() } else if (_array.Length * TrimThreshold >= _count) { - T[] arr = new T[_count]; + var arr = new T[_count]; CopyTo(arr, 0); _array = arr; _head = 0; @@ -228,14 +228,14 @@ public void CopyTo(T[] array, int arrayIndex) /// An array containing the queue's items public T[] ToArray() { - T[] result = new T[_count]; + var result = new T[_count]; CopyTo(result, 0); return result; } public IEnumerator GetEnumerator() { - for (int i = 0; i < _count; i++) + for (var i = 0; i < _count; i++) yield return _array[(_head + i) % _array.Length]; } diff --git a/src/Neo/IO/Caching/KeyedCollectionSlim.cs b/src/Neo.IO/Caching/KeyedCollectionSlim.cs similarity index 61% rename from src/Neo/IO/Caching/KeyedCollectionSlim.cs rename to src/Neo.IO/Caching/KeyedCollectionSlim.cs index a24dd87e4c..f632dc0927 100644 --- a/src/Neo/IO/Caching/KeyedCollectionSlim.cs +++ b/src/Neo.IO/Caching/KeyedCollectionSlim.cs @@ -10,43 +10,46 @@ // modifications are permitted. using System; +using System.Collections; using System.Collections.Generic; namespace Neo.IO.Caching; -abstract class KeyedCollectionSlim where TKey : notnull +abstract class KeyedCollectionSlim + where TKey : notnull + where TItem : class, IStructuralEquatable, IStructuralComparable, IComparable { private readonly LinkedList _items = new(); - private readonly Dictionary> dict = new(); + private readonly Dictionary> _dict = []; - public int Count => dict.Count; - public TItem First => _items.First.Value; + public int Count => _dict.Count; + public TItem? First => _items.First?.Value; - protected abstract TKey GetKeyForItem(TItem item); + protected abstract TKey GetKeyForItem(TItem? item); public void Add(TItem item) { var key = GetKeyForItem(item); var node = _items.AddLast(item); - if (!dict.TryAdd(key, node)) + if (!_dict.TryAdd(key, node)) { _items.RemoveLast(); throw new ArgumentException("An element with the same key already exists in the collection."); } } - public bool Contains(TKey key) => dict.ContainsKey(key); + public bool Contains(TKey key) => _dict.ContainsKey(key); public void Remove(TKey key) { - if (dict.Remove(key, out var node)) + if (_dict.Remove(key, out var node)) _items.Remove(node); } public void RemoveFirst() { - var key = GetKeyForItem(_items.First.Value); - dict.Remove(key); + var key = GetKeyForItem(_items.First?.Value); + _dict.Remove(key); _items.RemoveFirst(); } } diff --git a/src/Neo/Cryptography/Crypto.cs b/src/Neo/Cryptography/Crypto.cs index 85ed0411a8..a2e89dc787 100644 --- a/src/Neo/Cryptography/Crypto.cs +++ b/src/Neo/Cryptography/Crypto.cs @@ -170,7 +170,7 @@ public static ECDsa CreateECDsa(ECC.ECPoint pubkey) { if (CacheECDsa.TryGet(pubkey, out var cache)) { - return cache.value; + return cache.Value; } var curve = pubkey.Curve == ECC.ECCurve.Secp256r1 ? ECCurve.NamedCurves.nistP256 : diff --git a/src/Neo/IO/Caching/ECDsaCache.cs b/src/Neo/IO/Caching/ECDsaCache.cs index b25f29da8e..b41a058b61 100644 --- a/src/Neo/IO/Caching/ECDsaCache.cs +++ b/src/Neo/IO/Caching/ECDsaCache.cs @@ -14,7 +14,8 @@ namespace Neo.IO.Caching { - record ECDsaCacheItem(Cryptography.ECC.ECPoint key, ECDsa value); + record ECDsaCacheItem(Cryptography.ECC.ECPoint Key, ECDsa Value); + internal class ECDsaCache : FIFOCache { public ECDsaCache(int max_capacity = 20000) : base(max_capacity, EqualityComparer.Default) @@ -23,7 +24,7 @@ public ECDsaCache(int max_capacity = 20000) : base(max_capacity, EqualityCompare protected override Cryptography.ECC.ECPoint GetKeyForItem(ECDsaCacheItem item) { - return item.key; + return item.Key; } } } diff --git a/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs index 4606723cd0..4e7861a562 100644 --- a/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -30,9 +30,9 @@ namespace Neo.Network.P2P partial class RemoteNode { private class Timer { } - private class PendingKnownHashesCollection : KeyedCollectionSlim + private class PendingKnownHashesCollection : KeyedCollectionSlim> { - protected override UInt256 GetKeyForItem((UInt256, DateTime) item) + protected override UInt256 GetKeyForItem(Tuple item) { return item.Item1; } @@ -354,7 +354,7 @@ private void OnInvMessageReceived(InvPayload payload) } if (hashes.Length == 0) return; foreach (UInt256 hash in hashes) - pendingKnownHashes.Add((hash, TimeProvider.Current.UtcNow)); + pendingKnownHashes.Add(Tuple.Create(hash, TimeProvider.Current.UtcNow)); system.TaskManager.Tell(new TaskManager.NewTasks { Payload = InvPayload.Create(payload.Type, hashes) }); } From 4d08154ccb0832c0a4e8ad5f04d56d4c8ccabe3b Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 2 Jul 2024 05:22:54 -0400 Subject: [PATCH 02/18] Part-2 --- src/{Neo/IO => Neo.IO}/Actors/Idle.cs | 2 +- .../Caching/ReflectionCacheAttribute.cs | 18 ++++------ src/Neo/IO/Actors/PriorityMailbox.cs | 14 +++----- src/Neo/IO/Actors/PriorityMessageQueue.cs | 35 ++++++++----------- src/Neo/IO/Caching/ReflectionCache.cs | 17 ++++----- src/Neo/IO/Caching/RelayCache.cs | 8 ++--- 6 files changed, 38 insertions(+), 56 deletions(-) rename src/{Neo/IO => Neo.IO}/Actors/Idle.cs (89%) rename src/{Neo/IO => Neo.IO}/Caching/ReflectionCacheAttribute.cs (67%) diff --git a/src/Neo/IO/Actors/Idle.cs b/src/Neo.IO/Actors/Idle.cs similarity index 89% rename from src/Neo/IO/Actors/Idle.cs rename to src/Neo.IO/Actors/Idle.cs index e722d057ee..c372062783 100644 --- a/src/Neo/IO/Actors/Idle.cs +++ b/src/Neo.IO/Actors/Idle.cs @@ -13,6 +13,6 @@ namespace Neo.IO.Actors { internal sealed class Idle { - public static Idle Instance { get; } = new Idle(); + public static Idle Instance { get; } = new(); } } diff --git a/src/Neo/IO/Caching/ReflectionCacheAttribute.cs b/src/Neo.IO/Caching/ReflectionCacheAttribute.cs similarity index 67% rename from src/Neo/IO/Caching/ReflectionCacheAttribute.cs rename to src/Neo.IO/Caching/ReflectionCacheAttribute.cs index 20aeb91320..7071e879e4 100644 --- a/src/Neo/IO/Caching/ReflectionCacheAttribute.cs +++ b/src/Neo.IO/Caching/ReflectionCacheAttribute.cs @@ -13,21 +13,17 @@ namespace Neo.IO.Caching { + /// + /// Constructor + /// + /// Type [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - internal class ReflectionCacheAttribute : Attribute + internal class ReflectionCacheAttribute + (Type type) : Attribute { /// /// Type /// - public Type Type { get; } - - /// - /// Constructor - /// - /// Type - public ReflectionCacheAttribute(Type type) - { - Type = type; - } + public Type Type { get; } = type; } } diff --git a/src/Neo/IO/Actors/PriorityMailbox.cs b/src/Neo/IO/Actors/PriorityMailbox.cs index 0b08c04d70..b51d5ee861 100644 --- a/src/Neo/IO/Actors/PriorityMailbox.cs +++ b/src/Neo/IO/Actors/PriorityMailbox.cs @@ -17,17 +17,11 @@ namespace Neo.IO.Actors { - internal abstract class PriorityMailbox : MailboxType, IProducesMessageQueue + internal abstract class PriorityMailbox + (Settings settings, Config config) : MailboxType(settings, config), IProducesMessageQueue { - public PriorityMailbox(Akka.Actor.Settings settings, Config config) - : base(settings, config) - { - } - - public override IMessageQueue Create(IActorRef owner, ActorSystem system) - { - return new PriorityMessageQueue(ShallDrop, IsHighPriority); - } + public override IMessageQueue Create(IActorRef owner, ActorSystem system) => + new PriorityMessageQueue(ShallDrop, IsHighPriority); internal protected virtual bool IsHighPriority(object message) => false; internal protected virtual bool ShallDrop(object message, IEnumerable queue) => false; diff --git a/src/Neo/IO/Actors/PriorityMessageQueue.cs b/src/Neo/IO/Actors/PriorityMessageQueue.cs index 225720ec97..8723416adf 100644 --- a/src/Neo/IO/Actors/PriorityMessageQueue.cs +++ b/src/Neo/IO/Actors/PriorityMessageQueue.cs @@ -20,22 +20,17 @@ namespace Neo.IO.Actors { - internal class PriorityMessageQueue : IMessageQueue, IUnboundedMessageQueueSemantics + internal class PriorityMessageQueue + (Func dropper, Func priority_generator) : IMessageQueue, IUnboundedMessageQueueSemantics { - private readonly ConcurrentQueue high = new(); - private readonly ConcurrentQueue low = new(); - private readonly Func dropper; - private readonly Func priority_generator; - private int idle = 1; + private readonly ConcurrentQueue _high = new(); + private readonly ConcurrentQueue _low = new(); + private readonly Func _dropper = dropper; + private readonly Func _priority_generator = priority_generator; + private int _idle = 1; - public bool HasMessages => !high.IsEmpty || !low.IsEmpty; - public int Count => high.Count + low.Count; - - public PriorityMessageQueue(Func dropper, Func priority_generator) - { - this.dropper = dropper; - this.priority_generator = priority_generator; - } + public bool HasMessages => !_high.IsEmpty || !_low.IsEmpty; + public int Count => _high.Count + _low.Count; public void CleanUp(IActorRef owner, IMessageQueue deadletters) { @@ -43,19 +38,19 @@ public void CleanUp(IActorRef owner, IMessageQueue deadletters) public void Enqueue(IActorRef receiver, Envelope envelope) { - Interlocked.Increment(ref idle); + Interlocked.Increment(ref _idle); if (envelope.Message is Idle) return; - if (dropper(envelope.Message, high.Concat(low).Select(p => p.Message))) + if (_dropper(envelope.Message, _high.Concat(_low).Select(p => p.Message))) return; - ConcurrentQueue queue = priority_generator(envelope.Message) ? high : low; + var queue = _priority_generator(envelope.Message) ? _high : _low; queue.Enqueue(envelope); } public bool TryDequeue(out Envelope envelope) { - if (high.TryDequeue(out envelope)) return true; - if (low.TryDequeue(out envelope)) return true; - if (Interlocked.Exchange(ref idle, 0) > 0) + if (_high.TryDequeue(out envelope)) return true; + if (_low.TryDequeue(out envelope)) return true; + if (Interlocked.Exchange(ref _idle, 0) > 0) { envelope = new Envelope(Idle.Instance, ActorRefs.NoSender); return true; diff --git a/src/Neo/IO/Caching/ReflectionCache.cs b/src/Neo/IO/Caching/ReflectionCache.cs index 2fd8f5fceb..5007b67740 100644 --- a/src/Neo/IO/Caching/ReflectionCache.cs +++ b/src/Neo/IO/Caching/ReflectionCache.cs @@ -15,29 +15,30 @@ namespace Neo.IO.Caching { - internal static class ReflectionCache where T : Enum + internal static class ReflectionCache + where T : Enum { - private static readonly Dictionary dictionary = new(); + private static readonly Dictionary s_dictionary = []; - public static int Count => dictionary.Count; + public static int Count => s_dictionary.Count; static ReflectionCache() { - foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)) + foreach (var field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)) { // Get attribute - ReflectionCacheAttribute attribute = field.GetCustomAttribute(); + var attribute = field.GetCustomAttribute(); if (attribute == null) continue; // Append to cache - dictionary.Add((T)field.GetValue(null), attribute.Type); + s_dictionary.Add((T)field.GetValue(null), attribute.Type); } } public static object CreateInstance(T key, object def = null) { // Get Type from cache - if (dictionary.TryGetValue(key, out Type t)) + if (s_dictionary.TryGetValue(key, out var t)) return Activator.CreateInstance(t); // return null @@ -46,7 +47,7 @@ public static object CreateInstance(T key, object def = null) public static ISerializable CreateSerializable(T key, ReadOnlyMemory data) { - if (dictionary.TryGetValue(key, out Type t)) + if (s_dictionary.TryGetValue(key, out var t)) return data.AsSerializable(t); return null; } diff --git a/src/Neo/IO/Caching/RelayCache.cs b/src/Neo/IO/Caching/RelayCache.cs index 0f617f4d24..56466d9a7f 100644 --- a/src/Neo/IO/Caching/RelayCache.cs +++ b/src/Neo/IO/Caching/RelayCache.cs @@ -13,13 +13,9 @@ namespace Neo.IO.Caching { - internal class RelayCache : FIFOCache + internal class RelayCache + (int max_capacity) : FIFOCache(max_capacity) { - public RelayCache(int max_capacity) - : base(max_capacity) - { - } - protected override UInt256 GetKeyForItem(IInventory item) { return item.Hash; From 988157973228e73fa7bc30984eb7cd0d9559ffa6 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Fri, 5 Jul 2024 04:55:22 -0400 Subject: [PATCH 03/18] Added `BigInteger` to `Neo.Extensions` --- src/Neo.Extensions/BigIntegerExtensions.cs | 66 ++++++++++++++++++++++ src/Neo.Extensions/Neo.Extensions.csproj | 2 +- src/Neo/Cryptography/ECC/ECFieldElement.cs | 1 + src/Neo/Cryptography/ECC/ECPoint.cs | 1 + src/Neo/Helper.cs | 46 --------------- tests/Neo.UnitTests/Neo.UnitTests.csproj | 1 + tests/Neo.UnitTests/UT_Helper.cs | 1 + 7 files changed, 71 insertions(+), 47 deletions(-) create mode 100644 src/Neo.Extensions/BigIntegerExtensions.cs diff --git a/src/Neo.Extensions/BigIntegerExtensions.cs b/src/Neo.Extensions/BigIntegerExtensions.cs new file mode 100644 index 0000000000..9bdcafe15b --- /dev/null +++ b/src/Neo.Extensions/BigIntegerExtensions.cs @@ -0,0 +1,66 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// BigIntegerExtensions.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.Numerics; +using System.Runtime.CompilerServices; + +namespace Neo.Extensions +{ + internal static class BigIntegerExtensions + { + internal static int GetLowestSetBit(this BigInteger i) + { + if (i.Sign == 0) + return -1; + var b = i.ToByteArray(); + var w = 0; + while (b[w] == 0) + w++; + for (var x = 0; x < 8; x++) + if ((b[w] & 1 << x) > 0) + return x + w * 8; + throw new Exception(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static BigInteger Mod(this BigInteger x, BigInteger y) + { + x %= y; + if (x.Sign < 0) + x += y; + return x; + } + + internal static BigInteger ModInverse(this BigInteger a, BigInteger n) + { + BigInteger i = n, v = 0, d = 1; + while (a > 0) + { + BigInteger t = i / a, x = a; + a = i % x; + i = x; + x = d; + d = v - t * x; + v = x; + } + v %= n; + if (v < 0) v = (v + n) % n; + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool TestBit(this BigInteger i, int index) + { + return (i & (BigInteger.One << index)) > BigInteger.Zero; + } + } +} diff --git a/src/Neo.Extensions/Neo.Extensions.csproj b/src/Neo.Extensions/Neo.Extensions.csproj index a7f4870568..aa79170ddb 100644 --- a/src/Neo.Extensions/Neo.Extensions.csproj +++ b/src/Neo.Extensions/Neo.Extensions.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/Neo/Cryptography/ECC/ECFieldElement.cs b/src/Neo/Cryptography/ECC/ECFieldElement.cs index 47d8bfa274..d77a8b0451 100644 --- a/src/Neo/Cryptography/ECC/ECFieldElement.cs +++ b/src/Neo/Cryptography/ECC/ECFieldElement.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.Numerics; diff --git a/src/Neo/Cryptography/ECC/ECPoint.cs b/src/Neo/Cryptography/ECC/ECPoint.cs index 3b7bdcc885..77d01b90ea 100644 --- a/src/Neo/Cryptography/ECC/ECPoint.cs +++ b/src/Neo/Cryptography/ECC/ECPoint.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.IO.Caching; using System; diff --git a/src/Neo/Helper.cs b/src/Neo/Helper.cs index 00099bc148..a5f28cab2a 100644 --- a/src/Neo/Helper.cs +++ b/src/Neo/Helper.cs @@ -82,20 +82,6 @@ public static byte[] Concat(ReadOnlySpan a, ReadOnlySpan b) return buffer; } - internal static int GetLowestSetBit(this BigInteger i) - { - if (i.Sign == 0) - return -1; - byte[] b = i.ToByteArray(); - int w = 0; - while (b[w] == 0) - w++; - for (int x = 0; x < 8; x++) - if ((b[w] & 1 << x) > 0) - return x + w * 8; - throw new Exception(); - } - internal static void Remove(this HashSet set, ISet other) { if (set.Count > other.Count) @@ -157,32 +143,6 @@ public static byte[] HexToBytes(this string value) return result; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static BigInteger Mod(this BigInteger x, BigInteger y) - { - x %= y; - if (x.Sign < 0) - x += y; - return x; - } - - internal static BigInteger ModInverse(this BigInteger a, BigInteger n) - { - BigInteger i = n, v = 0, d = 1; - while (a > 0) - { - BigInteger t = i / a, x = a; - a = i % x; - i = x; - x = d; - d = v - t * x; - v = x; - } - v %= n; - if (v < 0) v = (v + n) % n; - return v; - } - internal static BigInteger NextBigInteger(this Random rand, int sizeInBits) { if (sizeInBits < 0) @@ -210,12 +170,6 @@ 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; - } - /// /// Converts a to byte array and eliminates all the leading zeros. /// diff --git a/tests/Neo.UnitTests/Neo.UnitTests.csproj b/tests/Neo.UnitTests/Neo.UnitTests.csproj index fb246cbdc3..b2e0e03b59 100644 --- a/tests/Neo.UnitTests/Neo.UnitTests.csproj +++ b/tests/Neo.UnitTests/Neo.UnitTests.csproj @@ -19,6 +19,7 @@ + diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index b7dc4f1681..3f5ca78c98 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO.Caching; using Neo.Network.P2P; using Neo.SmartContract; From 8779151cf799c542eec9b6a21bafa4c5a0816765 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Fri, 5 Jul 2024 05:06:28 -0400 Subject: [PATCH 04/18] Found more `BigInteger` --- src/Neo.Extensions/BigIntegerExtensions.cs | 27 +++++++++++++++++++++- src/Neo.GUI/GUI/MainForm.cs | 1 + src/Neo/Helper.cs | 24 ------------------- src/Neo/SmartContract/StorageItem.cs | 1 + src/Neo/Wallets/Wallet.cs | 1 + 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Neo.Extensions/BigIntegerExtensions.cs b/src/Neo.Extensions/BigIntegerExtensions.cs index 9bdcafe15b..6856a2a426 100644 --- a/src/Neo.Extensions/BigIntegerExtensions.cs +++ b/src/Neo.Extensions/BigIntegerExtensions.cs @@ -10,12 +10,13 @@ // modifications are permitted. using System; +using System.Collections.Generic; using System.Numerics; using System.Runtime.CompilerServices; namespace Neo.Extensions { - internal static class BigIntegerExtensions + public static class BigIntegerExtensions { internal static int GetLowestSetBit(this BigInteger i) { @@ -62,5 +63,29 @@ internal static bool TestBit(this BigInteger i, int index) { return (i & (BigInteger.One << index)) > BigInteger.Zero; } + + /// + /// Finds the sum of the specified integers. + /// + /// The specified integers. + /// The sum of the integers. + public static BigInteger Sum(this IEnumerable source) + { + var sum = BigInteger.Zero; + foreach (var bi in source) sum += bi; + return sum; + } + + /// + /// Converts a to byte array and eliminates all the leading zeros. + /// + /// The to convert. + /// The converted byte array. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte[] ToByteArrayStandard(this BigInteger i) + { + if (i.IsZero) return Array.Empty(); + return i.ToByteArray(); + } } } diff --git a/src/Neo.GUI/GUI/MainForm.cs b/src/Neo.GUI/GUI/MainForm.cs index 3114e542b6..66d5cc8c0e 100644 --- a/src/Neo.GUI/GUI/MainForm.cs +++ b/src/Neo.GUI/GUI/MainForm.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.Actor; +using Neo.Extensions; using Neo.IO.Actors; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Neo/Helper.cs b/src/Neo/Helper.cs index a5f28cab2a..7acf69b0e9 100644 --- a/src/Neo/Helper.cs +++ b/src/Neo/Helper.cs @@ -158,30 +158,6 @@ internal static BigInteger NextBigInteger(this Random rand, int sizeInBits) return new BigInteger(b); } - /// - /// Finds the sum of the specified integers. - /// - /// The specified integers. - /// The sum of the integers. - public static BigInteger Sum(this IEnumerable source) - { - var sum = BigInteger.Zero; - foreach (var bi in source) sum += bi; - return sum; - } - - /// - /// Converts a to byte array and eliminates all the leading zeros. - /// - /// The to convert. - /// The converted byte array. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] ToByteArrayStandard(this BigInteger i) - { - if (i.IsZero) return Array.Empty(); - return i.ToByteArray(); - } - /// /// Converts a byte array to hex . /// diff --git a/src/Neo/SmartContract/StorageItem.cs b/src/Neo/SmartContract/StorageItem.cs index 133a8fa1dd..61fa62e3c4 100644 --- a/src/Neo/SmartContract/StorageItem.cs +++ b/src/Neo/SmartContract/StorageItem.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM; using System; diff --git a/src/Neo/Wallets/Wallet.cs b/src/Neo/Wallets/Wallet.cs index aca30b008f..43cfadb9b7 100644 --- a/src/Neo/Wallets/Wallet.cs +++ b/src/Neo/Wallets/Wallet.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; From ed3470741c9c361dc515fbac47fbd0173358ca68 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Fri, 5 Jul 2024 05:59:42 -0400 Subject: [PATCH 05/18] Added `ByteArray` to `Neo.Extensions` --- .../{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 +- 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 | 1 + .../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/VM/UT_Helper.cs | 1 + 55 files changed, 139 insertions(+), 138 deletions(-) rename src/Neo.CLI/{Extensions.cs => AssemblyExtensions.cs} (88%) create mode 100644 src/Neo.Extensions/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 db33e89564..1fa0c5ef72 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 6f291e763d..890e1c3b03 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; @@ -242,7 +243,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); } @@ -264,7 +265,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 4abddbc183..f887dc60d4 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 12d3c208bc..12ebf8f18e 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.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 01022baab9..78fbdc2e77 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 4d57da62b9..4204af48a6 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 ea797f8be3..0674689f43 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 2021e5a187..7a526ab1dc 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.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs index a597c88cb6..0b9025a2a3 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 56d9a66bec..ffd70e354e 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 74898eb4fb..dba0e77802 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 f65e061093..09742b6a37 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 0a19314153..f7209abd9c 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 25ca7ee0d6..4b0694386a 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 f36fa2cfa4..da61df7299 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -10,6 +10,7 @@ // modifications are permitted. 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 aba90cc6f0..6fd53527b0 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 4f0767bf2c..b39c1f0e37 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 06290922da..c5b38f5cf8 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs @@ -14,6 +14,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/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 5b1230464554d538bbd84bd6f2043047a6b3766a Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 07:50:43 -0400 Subject: [PATCH 06/18] Added `DateTime` Extensions to `Neo.Extensions` --- src/Neo.CLI/CLI/MainService.Network.cs | 1 + src/Neo.Extensions/DateTimeExtensions.cs | 38 +++++++++++++++++++ src/Neo/Helper.cs | 22 ----------- src/Neo/NeoSystem.cs | 1 + src/Neo/Network/P2P/Payloads/PingPayload.cs | 1 + .../Network/P2P/Payloads/VersionPayload.cs | 1 + .../Consensus/ConsensusContext.MakePayload.cs | 1 + .../Consensus/ConsensusService.OnMessage.cs | 1 + src/Plugins/RpcClient/RpcClient.cs | 1 + .../Trackers/NEP-17/Nep17Tracker.cs | 1 + tests/Neo.UnitTests/TestUtils.Block.cs | 1 + 11 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 src/Neo.Extensions/DateTimeExtensions.cs diff --git a/src/Neo.CLI/CLI/MainService.Network.cs b/src/Neo.CLI/CLI/MainService.Network.cs index 38d6fd1d28..efe4d18ce3 100644 --- a/src/Neo.CLI/CLI/MainService.Network.cs +++ b/src/Neo.CLI/CLI/MainService.Network.cs @@ -11,6 +11,7 @@ using Akka.Actor; using Neo.ConsoleService; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P; diff --git a/src/Neo.Extensions/DateTimeExtensions.cs b/src/Neo.Extensions/DateTimeExtensions.cs new file mode 100644 index 0000000000..130d09e78d --- /dev/null +++ b/src/Neo.Extensions/DateTimeExtensions.cs @@ -0,0 +1,38 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// DateTimeExtensions.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; + +namespace Neo.Extensions +{ + public static class DateTimeExtensions + { + /// + /// Converts a to timestamp. + /// + /// The to convert. + /// The converted timestamp. + public static uint ToTimestamp(this DateTime time) + { + return (uint)new DateTimeOffset(time.ToUniversalTime()).ToUnixTimeSeconds(); + } + + /// + /// Converts a to timestamp in milliseconds. + /// + /// The to convert. + /// The converted timestamp. + public static ulong ToTimestampMS(this DateTime time) + { + return (ulong)new DateTimeOffset(time.ToUniversalTime()).ToUnixTimeMilliseconds(); + } + } +} diff --git a/src/Neo/Helper.cs b/src/Neo/Helper.cs index 4458d04f42..292be29cbb 100644 --- a/src/Neo/Helper.cs +++ b/src/Neo/Helper.cs @@ -25,8 +25,6 @@ namespace Neo /// public static class Helper { - private static readonly DateTime unixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - internal static void Remove(this HashSet set, ISet other) { if (set.Count > other.Count) @@ -103,26 +101,6 @@ internal static BigInteger NextBigInteger(this Random rand, int sizeInBits) return new BigInteger(b); } - /// - /// Converts a to timestamp. - /// - /// The to convert. - /// The converted timestamp. - public static uint ToTimestamp(this DateTime time) - { - return (uint)(time.ToUniversalTime() - unixEpoch).TotalSeconds; - } - - /// - /// Converts a to timestamp in milliseconds. - /// - /// The to convert. - /// The converted timestamp. - public static ulong ToTimestampMS(this DateTime time) - { - return (ulong)(time.ToUniversalTime() - unixEpoch).TotalMilliseconds; - } - /// /// Checks if address is IPv4 Mapped to IPv6 format, if so, Map to IPv4. /// Otherwise, return current address. diff --git a/src/Neo/NeoSystem.cs b/src/Neo/NeoSystem.cs index b752f16712..ad65741aec 100644 --- a/src/Neo/NeoSystem.cs +++ b/src/Neo/NeoSystem.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.Actor; +using Neo.Extensions; using Neo.IO.Caching; using Neo.Ledger; using Neo.Network.P2P; diff --git a/src/Neo/Network/P2P/Payloads/PingPayload.cs b/src/Neo/Network/P2P/Payloads/PingPayload.cs index f6296a7713..6ac3d2d94e 100644 --- a/src/Neo/Network/P2P/Payloads/PingPayload.cs +++ b/src/Neo/Network/P2P/Payloads/PingPayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/VersionPayload.cs b/src/Neo/Network/P2P/Payloads/VersionPayload.cs index 8cec6278e7..f8fe74a856 100644 --- a/src/Neo/Network/P2P/Payloads/VersionPayload.cs +++ b/src/Neo/Network/P2P/Payloads/VersionPayload.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.Network.P2P.Capabilities; using System; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs index ee3b8a7747..2c2462d370 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Ledger; using Neo.Network.P2P.Payloads; using Neo.Plugins.DBFTPlugin.Messages; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs index 3c6ab8e243..b00fdd9393 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs @@ -11,6 +11,7 @@ using Akka.Actor; using Neo.Cryptography; +using Neo.Extensions; using Neo.Ledger; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/RpcClient/RpcClient.cs b/src/Plugins/RpcClient/RpcClient.cs index 27b0023ec0..7866c7e40f 100644 --- a/src/Plugins/RpcClient/RpcClient.cs +++ b/src/Plugins/RpcClient/RpcClient.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-17/Nep17Tracker.cs b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs index d4698cba1e..71bfceb49d 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.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.UnitTests/TestUtils.Block.cs b/tests/Neo.UnitTests/TestUtils.Block.cs index 4f663fec2d..350c0e4a87 100644 --- a/tests/Neo.UnitTests/TestUtils.Block.cs +++ b/tests/Neo.UnitTests/TestUtils.Block.cs @@ -11,6 +11,7 @@ using Akka.Util.Internal; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; From 0f6627a5785fe33cec8bc634bcab5382cef6f046 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 08:58:22 -0400 Subject: [PATCH 07/18] Added `HashSetExtensions`, `HashSetExtensions2`, `IpAddressExtensions`, `AssemblyExtensions`, `StringExtensdions` Deleted `Helper.cs` file --- src/Neo.Extensions/AssemblyExtensions.cs | 23 ++++ .../Collections/HashSetExtensions.cs | 42 ++++++ src/Neo.Extensions/Net/IpAddressExtensions.cs | 40 ++++++ src/Neo.Extensions/RandomExtensions.cs | 34 +++++ src/Neo.Extensions/StringExtensdions.cs | 36 +++++ .../GUI/CreateMultiSigContractDialog.cs | 1 + src/Neo.GUI/GUI/ImportCustomContractDialog.cs | 1 + src/Neo.GUI/GUI/ParametersEditor.cs | 1 + src/Neo.IO/Caching/HashSetCache.cs | 2 +- src/Neo.IO/Neo.IO.csproj | 2 +- src/Neo/Cryptography/ECC/ECCurve.cs | 1 + src/Neo/Extensions/HashSetExtensions.cs | 36 +++++ src/Neo/Helper.cs | 126 ------------------ .../P2P/Payloads/NetworkAddressWithTime.cs | 3 +- src/Neo/Network/P2P/Peer.cs | 9 +- src/Neo/Network/P2P/TaskManager.cs | 1 + src/Plugins/RpcClient/Utility.cs | 1 + .../Cryptography/MPTTrie/UT_Trie.cs | 2 +- .../UT_ContractClient.cs | 1 + tests/Neo.Network.RPC.Tests/UT_Nep17API.cs | 3 +- .../Cryptography/ECC/UT_ECFieldElement.cs | 1 + .../Cryptography/ECC/UT_ECPoint.cs | 1 + tests/Neo.UnitTests/Cryptography/UT_Base58.cs | 1 + tests/Neo.UnitTests/Cryptography/UT_Crypto.cs | 1 + tests/Neo.UnitTests/IO/UT_MemoryReader.cs | 1 + tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs | 1 + .../Manifest/UT_ContractManifest.cs | 1 + .../SmartContract/UT_SmartContractHelper.cs | 1 + tests/Neo.UnitTests/UT_Helper.cs | 8 +- .../Wallets/NEP6/UT_NEP6Contract.cs | 1 + .../Wallets/NEP6/UT_NEP6Wallet.cs | 1 + 31 files changed, 244 insertions(+), 139 deletions(-) create mode 100644 src/Neo.Extensions/AssemblyExtensions.cs create mode 100644 src/Neo.Extensions/Collections/HashSetExtensions.cs create mode 100644 src/Neo.Extensions/Net/IpAddressExtensions.cs create mode 100644 src/Neo.Extensions/RandomExtensions.cs create mode 100644 src/Neo.Extensions/StringExtensdions.cs create mode 100644 src/Neo/Extensions/HashSetExtensions.cs delete mode 100644 src/Neo/Helper.cs diff --git a/src/Neo.Extensions/AssemblyExtensions.cs b/src/Neo.Extensions/AssemblyExtensions.cs new file mode 100644 index 0000000000..4f9368c98b --- /dev/null +++ b/src/Neo.Extensions/AssemblyExtensions.cs @@ -0,0 +1,23 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// 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 +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using System.Reflection; + +namespace Neo.Extensions +{ + public static class AssemblyExtensions + { + public static string GetVersion(this Assembly assembly) + { + return assembly.GetName().Version!.ToString(3); + } + } +} diff --git a/src/Neo.Extensions/Collections/HashSetExtensions.cs b/src/Neo.Extensions/Collections/HashSetExtensions.cs new file mode 100644 index 0000000000..60cb14de42 --- /dev/null +++ b/src/Neo.Extensions/Collections/HashSetExtensions.cs @@ -0,0 +1,42 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// HashSetExtensions.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.Collections.Generic; + +namespace Neo.Extensions +{ + public static class HashSetExtensions + { + internal static void Remove(this HashSet set, ISet other) + { + if (set.Count > other.Count) + { + set.ExceptWith(other); + } + else + { + set.RemoveWhere(u => other.Contains(u)); + } + } + + internal static void Remove(this HashSet set, IReadOnlyDictionary other) + { + if (set.Count > other.Count) + { + set.ExceptWith(other.Keys); + } + else + { + set.RemoveWhere(u => other.ContainsKey(u)); + } + } + } +} diff --git a/src/Neo.Extensions/Net/IpAddressExtensions.cs b/src/Neo.Extensions/Net/IpAddressExtensions.cs new file mode 100644 index 0000000000..00b3065d0d --- /dev/null +++ b/src/Neo.Extensions/Net/IpAddressExtensions.cs @@ -0,0 +1,40 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// IpAddressExtensions.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.Net; + +namespace Neo.Extensions +{ + public static class IpAddressExtensions + { + /// + /// Checks if address is IPv4 Mapped to IPv6 format, if so, Map to IPv4. + /// Otherwise, return current address. + /// + internal static IPAddress UnMap(this IPAddress address) + { + if (address.IsIPv4MappedToIPv6) + address = address.MapToIPv4(); + return address; + } + + /// + /// Checks if IPEndPoint is IPv4 Mapped to IPv6 format, if so, unmap to IPv4. + /// Otherwise, return current endpoint. + /// + internal static IPEndPoint UnMap(this IPEndPoint endPoint) + { + if (!endPoint.Address.IsIPv4MappedToIPv6) + return endPoint; + return new IPEndPoint(endPoint.Address.UnMap(), endPoint.Port); + } + } +} diff --git a/src/Neo.Extensions/RandomExtensions.cs b/src/Neo.Extensions/RandomExtensions.cs new file mode 100644 index 0000000000..72bcac289f --- /dev/null +++ b/src/Neo.Extensions/RandomExtensions.cs @@ -0,0 +1,34 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// RandomExtensions.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.Numerics; + +namespace Neo.Extensions +{ + public static class RandomExtensions + { + public static BigInteger NextBigInteger(this Random rand, int sizeInBits) + { + if (sizeInBits < 0) + throw new ArgumentException("sizeInBits must be non-negative"); + if (sizeInBits == 0) + return 0; + Span b = stackalloc byte[sizeInBits / 8 + 1]; + rand.NextBytes(b); + if (sizeInBits % 8 == 0) + b[^1] = 0; + else + b[^1] &= (byte)((1 << sizeInBits % 8) - 1); + return new BigInteger(b); + } + } +} diff --git a/src/Neo.Extensions/StringExtensdions.cs b/src/Neo.Extensions/StringExtensdions.cs new file mode 100644 index 0000000000..25f95c97a7 --- /dev/null +++ b/src/Neo.Extensions/StringExtensdions.cs @@ -0,0 +1,36 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// StringExtensdions.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.Globalization; + +namespace Neo.Extensions +{ + public static class StringExtensdions + { + /// + /// Converts a hex to byte array. + /// + /// The hex to convert. + /// The converted byte array. + public static byte[] HexToBytes(this string value) + { + if (value == null || value.Length == 0) + return []; + if (value.Length % 2 == 1) + throw new FormatException(); + var result = new byte[value.Length / 2]; + for (var i = 0; i < result.Length; i++) + result[i] = byte.Parse(value.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier); + return result; + } + } +} diff --git a/src/Neo.GUI/GUI/CreateMultiSigContractDialog.cs b/src/Neo.GUI/GUI/CreateMultiSigContractDialog.cs index 5dd10f858f..d28696f138 100644 --- a/src/Neo.GUI/GUI/CreateMultiSigContractDialog.cs +++ b/src/Neo.GUI/GUI/CreateMultiSigContractDialog.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.SmartContract; using Neo.Wallets; using System; diff --git a/src/Neo.GUI/GUI/ImportCustomContractDialog.cs b/src/Neo.GUI/GUI/ImportCustomContractDialog.cs index b8df534699..8faa23d593 100644 --- a/src/Neo.GUI/GUI/ImportCustomContractDialog.cs +++ b/src/Neo.GUI/GUI/ImportCustomContractDialog.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; diff --git a/src/Neo.GUI/GUI/ParametersEditor.cs b/src/Neo.GUI/GUI/ParametersEditor.cs index 19eac82c31..f5156d6bfb 100644 --- a/src/Neo.GUI/GUI/ParametersEditor.cs +++ b/src/Neo.GUI/GUI/ParametersEditor.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.SmartContract; using System; using System.Collections.Generic; diff --git a/src/Neo.IO/Caching/HashSetCache.cs b/src/Neo.IO/Caching/HashSetCache.cs index 577893e924..6e39f5fd8b 100644 --- a/src/Neo.IO/Caching/HashSetCache.cs +++ b/src/Neo.IO/Caching/HashSetCache.cs @@ -15,7 +15,7 @@ namespace Neo.IO.Caching { - class HashSetCache : IReadOnlyCollection where T : IEquatable + internal class HashSetCache : IReadOnlyCollection where T : IEquatable { /// /// Sets where the Hashes are stored diff --git a/src/Neo.IO/Neo.IO.csproj b/src/Neo.IO/Neo.IO.csproj index a51ec1110a..79f5624602 100644 --- a/src/Neo.IO/Neo.IO.csproj +++ b/src/Neo.IO/Neo.IO.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Neo/Cryptography/ECC/ECCurve.cs b/src/Neo/Cryptography/ECC/ECCurve.cs index def1ee0cb1..805507a08e 100644 --- a/src/Neo/Cryptography/ECC/ECCurve.cs +++ b/src/Neo/Cryptography/ECC/ECCurve.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using System.Globalization; using System.Numerics; diff --git a/src/Neo/Extensions/HashSetExtensions.cs b/src/Neo/Extensions/HashSetExtensions.cs new file mode 100644 index 0000000000..48fdb9d43e --- /dev/null +++ b/src/Neo/Extensions/HashSetExtensions.cs @@ -0,0 +1,36 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// HashSetExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO.Caching; +using System; +using System.Collections.Generic; + +namespace Neo.Extensions +{ + /// + /// A helper class that provides common functions. + /// + public static class HashSetExtensions2 + { + internal static void Remove(this HashSet set, HashSetCache other) + where T : IEquatable + { + if (set.Count > other.Count) + { + set.ExceptWith(other); + } + else + { + set.RemoveWhere(u => other.Contains(u)); + } + } + } +} diff --git a/src/Neo/Helper.cs b/src/Neo/Helper.cs deleted file mode 100644 index 292be29cbb..0000000000 --- a/src/Neo/Helper.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2015-2024 The Neo Project. -// -// Helper.cs file belongs to the neo project and is free -// software distributed under the MIT software license, see the -// accompanying file LICENSE in the main directory of the -// repository or http://www.opensource.org/licenses/mit-license.php -// for more details. -// -// Redistribution and use in source and binary forms with or without -// modifications are permitted. - -using Neo.IO.Caching; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Numerics; -using System.Reflection; - -namespace Neo -{ - /// - /// A helper class that provides common functions. - /// - public static class Helper - { - internal static void Remove(this HashSet set, ISet other) - { - if (set.Count > other.Count) - { - set.ExceptWith(other); - } - else - { - set.RemoveWhere(u => other.Contains(u)); - } - } - - internal static void Remove(this HashSet set, HashSetCache other) - where T : IEquatable - { - if (set.Count > other.Count) - { - set.ExceptWith(other); - } - else - { - set.RemoveWhere(u => other.Contains(u)); - } - } - - internal static void Remove(this HashSet set, IReadOnlyDictionary other) - { - if (set.Count > other.Count) - { - set.ExceptWith(other.Keys); - } - else - { - set.RemoveWhere(u => other.ContainsKey(u)); - } - } - - internal static string GetVersion(this Assembly assembly) - { - CustomAttributeData attribute = assembly.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(AssemblyInformationalVersionAttribute)); - if (attribute == null) return assembly.GetName().Version.ToString(3); - return (string)attribute.ConstructorArguments[0].Value; - } - - /// - /// Converts a hex to byte array. - /// - /// The hex to convert. - /// The converted byte array. - public static byte[] HexToBytes(this string value) - { - if (value == null || value.Length == 0) - return Array.Empty(); - if (value.Length % 2 == 1) - throw new FormatException(); - byte[] result = new byte[value.Length / 2]; - for (int i = 0; i < result.Length; i++) - result[i] = byte.Parse(value.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier); - return result; - } - - internal static BigInteger NextBigInteger(this Random rand, int sizeInBits) - { - if (sizeInBits < 0) - throw new ArgumentException("sizeInBits must be non-negative"); - if (sizeInBits == 0) - return 0; - Span b = stackalloc byte[sizeInBits / 8 + 1]; - rand.NextBytes(b); - if (sizeInBits % 8 == 0) - b[^1] = 0; - else - b[^1] &= (byte)((1 << sizeInBits % 8) - 1); - return new BigInteger(b); - } - - /// - /// Checks if address is IPv4 Mapped to IPv6 format, if so, Map to IPv4. - /// Otherwise, return current address. - /// - internal static IPAddress Unmap(this IPAddress address) - { - if (address.IsIPv4MappedToIPv6) - address = address.MapToIPv4(); - return address; - } - - /// - /// Checks if IPEndPoint is IPv4 Mapped to IPv6 format, if so, unmap to IPv4. - /// Otherwise, return current endpoint. - /// - internal static IPEndPoint Unmap(this IPEndPoint endPoint) - { - if (!endPoint.Address.IsIPv4MappedToIPv6) - return endPoint; - return new IPEndPoint(endPoint.Address.Unmap(), endPoint.Port); - } - } -} diff --git a/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs b/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs index d3cfd15f66..0b7e0acc37 100644 --- a/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs +++ b/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.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.Network.P2P.Capabilities; using System; @@ -68,7 +69,7 @@ void ISerializable.Deserialize(ref MemoryReader reader) // Address ReadOnlyMemory data = reader.ReadMemory(16); - Address = new IPAddress(data.Span).Unmap(); + Address = new IPAddress(data.Span).UnMap(); // Capabilities Capabilities = new NodeCapability[reader.ReadVarInt(VersionPayload.MaxCapabilities)]; diff --git a/src/Neo/Network/P2P/Peer.cs b/src/Neo/Network/P2P/Peer.cs index 767d747b1d..074c5cf3ba 100644 --- a/src/Neo/Network/P2P/Peer.cs +++ b/src/Neo/Network/P2P/Peer.cs @@ -11,6 +11,7 @@ using Akka.Actor; using Akka.IO; +using Neo.Extensions; using Neo.IO; using System; using System.Buffers.Binary; @@ -138,7 +139,7 @@ protected virtual int ConnectingMax static Peer() { - localAddresses.UnionWith(NetworkInterface.GetAllNetworkInterfaces().SelectMany(p => p.GetIPProperties().UnicastAddresses).Select(p => p.Address.Unmap())); + localAddresses.UnionWith(NetworkInterface.GetAllNetworkInterfaces().SelectMany(p => p.GetIPProperties().UnicastAddresses).Select(p => p.Address.UnMap())); } /// @@ -163,7 +164,7 @@ protected void AddPeers(IEnumerable peers) /// Indicates whether the remote node is trusted. A trusted node will always be connected. protected void ConnectToPeer(IPEndPoint endPoint, bool isTrusted = false) { - endPoint = endPoint.Unmap(); + endPoint = endPoint.UnMap(); // If the address is the same, the ListenerTcpPort should be different, otherwise, return if (endPoint.Port == ListenerTcpPort && localAddresses.Contains(endPoint.Address)) return; @@ -210,7 +211,7 @@ protected override void OnReceive(object message) ConnectToPeer(connect.EndPoint, connect.IsTrusted); break; case Tcp.Connected connected: - OnTcpConnected(((IPEndPoint)connected.RemoteAddress).Unmap(), ((IPEndPoint)connected.LocalAddress).Unmap()); + OnTcpConnected(((IPEndPoint)connected.RemoteAddress).UnMap(), ((IPEndPoint)connected.LocalAddress).UnMap()); break; case Tcp.Bound _: tcp_listener = Sender; @@ -302,7 +303,7 @@ private void OnTcpCommandFailed(Tcp.Command cmd) switch (cmd) { case Tcp.Connect connect: - ImmutableInterlocked.Update(ref ConnectingPeers, p => p.Remove(((IPEndPoint)connect.RemoteAddress).Unmap())); + ImmutableInterlocked.Update(ref ConnectingPeers, p => p.Remove(((IPEndPoint)connect.RemoteAddress).UnMap())); break; } } diff --git a/src/Neo/Network/P2P/TaskManager.cs b/src/Neo/Network/P2P/TaskManager.cs index e9c12e58a4..c5708df923 100644 --- a/src/Neo/Network/P2P/TaskManager.cs +++ b/src/Neo/Network/P2P/TaskManager.cs @@ -12,6 +12,7 @@ using Akka.Actor; using Akka.Configuration; using Akka.IO; +using Neo.Extensions; using Neo.IO.Actors; using Neo.IO.Caching; using Neo.Ledger; diff --git a/src/Plugins/RpcClient/Utility.cs b/src/Plugins/RpcClient/Utility.cs index 659942f8f8..37331eec1b 100644 --- a/src/Plugins/RpcClient/Utility.cs +++ b/src/Plugins/RpcClient/Utility.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Network.P2P.Payloads.Conditions; 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 05592d366b..e601ec1f07 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Trie.cs @@ -17,7 +17,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using static Neo.Helper; +using static Neo.Extensions.HashSetExtensions; namespace Neo.Cryptography.MPTTrie.Tests { diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index c3cf226a3e..6ac90dafc5 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Manifest; using Neo.SmartContract.Native; diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs index 863d424405..d9a4cdb2ef 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract; using Neo.SmartContract.Native; @@ -19,7 +20,7 @@ using System.Linq; using System.Numerics; using System.Threading.Tasks; -using static Neo.Helper; +using static Neo.Extensions.HashSetExtensions; namespace Neo.Network.RPC.Tests { diff --git a/tests/Neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs b/tests/Neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs index 3d4e4c56f2..0d1e20c37a 100644 --- a/tests/Neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs +++ b/tests/Neo.UnitTests/Cryptography/ECC/UT_ECFieldElement.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using System; using System.Globalization; using System.Numerics; diff --git a/tests/Neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs b/tests/Neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs index 4b0c7d484f..e5767acd37 100644 --- a/tests/Neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs +++ b/tests/Neo.UnitTests/Cryptography/ECC/UT_ECPoint.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/tests/Neo.UnitTests/Cryptography/UT_Base58.cs b/tests/Neo.UnitTests/Cryptography/UT_Base58.cs index e7cb467dfa..091513862c 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_Base58.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_Base58.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using System; using System.Collections.Generic; diff --git a/tests/Neo.UnitTests/Cryptography/UT_Crypto.cs b/tests/Neo.UnitTests/Cryptography/UT_Crypto.cs index e311d6cafe..2f7de65b77 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_Crypto.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_Crypto.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.Wallets; using System; using System.Security.Cryptography; diff --git a/tests/Neo.UnitTests/IO/UT_MemoryReader.cs b/tests/Neo.UnitTests/IO/UT_MemoryReader.cs index a045a0b688..25278b3e22 100644 --- a/tests/Neo.UnitTests/IO/UT_MemoryReader.cs +++ b/tests/Neo.UnitTests/IO/UT_MemoryReader.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using System.IO; using System.Text; diff --git a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs index 1063413073..b78ba8e34a 100644 --- a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -14,6 +14,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 4e2e866281..fdbcf671b2 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index c1161213ce..520521f172 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 3f5ca78c98..626ea8d4b9 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -217,10 +217,10 @@ public void TestNextBigIntegerForRandom() public void TestUnmapForIPAddress() { var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); - addr.Unmap().Should().Be(addr); + addr.UnMap().Should().Be(addr); var addr2 = addr.MapToIPv6(); - addr2.Unmap().Should().Be(addr); + addr2.UnMap().Should().Be(addr); } [TestMethod] @@ -228,11 +228,11 @@ public void TestUnmapForIPEndPoin() { var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); var endPoint = new IPEndPoint(addr, 8888); - endPoint.Unmap().Should().Be(endPoint); + endPoint.UnMap().Should().Be(endPoint); var addr2 = addr.MapToIPv6(); var endPoint2 = new IPEndPoint(addr2, 8888); - endPoint2.Unmap().Should().Be(endPoint); + endPoint2.UnMap().Should().Be(endPoint); } } } diff --git a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs index 37f816c240..bac6c0d4eb 100644 --- a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs +++ b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Contract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract; using Neo.Wallets.NEP6; diff --git a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs index 71914c86f0..94deefc540 100644 --- a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs +++ b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.SmartContract; From 721ce587c536e4c42e6a05d29f7537bdd6480c4d Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 14:24:55 -0400 Subject: [PATCH 08/18] Added `ICollection`, `Memory`, `String`, `Unsafe` extensions --- src/Neo.Extensions/StringExtensdions.cs | 11 ++ src/Neo.Extensions/UnsafeData.cs | 31 +++++ .../Collections/ICollectionExtensions.cs | 74 +++++++++++ src/Neo/Extensions/MemoryExtensions.cs | 60 +++++++++ src/Neo/IO/Helper.cs | 118 ------------------ .../Network/P2P/Payloads/ExtensiblePayload.cs | 1 + src/Neo/SmartContract/MethodToken.cs | 1 + src/Neo/SmartContract/NefFile.cs | 1 + src/Neo/Wallets/Helper.cs | 5 +- .../Store/States/EngineLogState.cs | 1 + .../Store/States/ExecutionLogState.cs | 1 + .../Store/States/NotifyLogState.cs | 2 +- .../Consensus/ConsensusContext.Get.cs | 3 +- .../MPTTrie/Cryptography/MPTTrie/Node.cs | 7 +- src/Plugins/OracleService/OracleService.cs | 4 +- src/Plugins/TokensTracker/Extensions.cs | 5 +- tests/Neo.UnitTests/IO/UT_IOHelper.cs | 8 +- 17 files changed, 200 insertions(+), 133 deletions(-) create mode 100644 src/Neo.Extensions/UnsafeData.cs create mode 100644 src/Neo/Extensions/Collections/ICollectionExtensions.cs create mode 100644 src/Neo/Extensions/MemoryExtensions.cs diff --git a/src/Neo.Extensions/StringExtensdions.cs b/src/Neo.Extensions/StringExtensdions.cs index 25f95c97a7..937e207087 100644 --- a/src/Neo.Extensions/StringExtensdions.cs +++ b/src/Neo.Extensions/StringExtensdions.cs @@ -32,5 +32,16 @@ public static byte[] HexToBytes(this string value) result[i] = byte.Parse(value.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier); return result; } + + /// + /// Gets the size of the specified encoded in variable-length encoding. + /// + /// The specified . + /// The size of the . + public static int GetVarSize(this string value) + { + var size = Utility.StrictUTF8.GetByteCount(value); + return UnsafeData.GetVarSize(size) + size; + } } } diff --git a/src/Neo.Extensions/UnsafeData.cs b/src/Neo.Extensions/UnsafeData.cs new file mode 100644 index 0000000000..6d4c9a6f8e --- /dev/null +++ b/src/Neo.Extensions/UnsafeData.cs @@ -0,0 +1,31 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UnsafeData.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. + +namespace Neo.Extensions +{ + public static class UnsafeData + { + /// + /// Gets the size of variable-length of the data. + /// + /// The length of the data. + /// The size of variable-length of the data. + public static int GetVarSize(int value) + { + if (value < 0xFD) + return sizeof(byte); + else if (value <= 0xFFFF) + return sizeof(byte) + sizeof(ushort); + else + return sizeof(byte) + sizeof(uint); + } + } +} diff --git a/src/Neo/Extensions/Collections/ICollectionExtensions.cs b/src/Neo/Extensions/Collections/ICollectionExtensions.cs new file mode 100644 index 0000000000..724def6d80 --- /dev/null +++ b/src/Neo/Extensions/Collections/ICollectionExtensions.cs @@ -0,0 +1,74 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ICollectionExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace Neo.Extensions +{ + public static class ICollectionExtensions + { + /// + /// Gets the size of the specified array encoded in variable-length encoding. + /// + /// The type of the array element. + /// The specified array. + /// The size of the array. + public static int GetVarSize(this IReadOnlyCollection value) + { + int value_size; + var t = typeof(T); + if (typeof(ISerializable).IsAssignableFrom(t)) + { + value_size = value.OfType().Sum(p => p.Size); + } + else if (t.GetTypeInfo().IsEnum) + { + int element_size; + var u = t.GetTypeInfo().GetEnumUnderlyingType(); + if (u == typeof(sbyte) || u == typeof(byte)) + element_size = 1; + else if (u == typeof(short) || u == typeof(ushort)) + element_size = 2; + else if (u == typeof(int) || u == typeof(uint)) + element_size = 4; + else //if (u == typeof(long) || u == typeof(ulong)) + element_size = 8; + value_size = value.Count * element_size; + } + else + { + value_size = value.Count * Marshal.SizeOf(); + } + return UnsafeData.GetVarSize(value.Count) + value_size; + } + + /// + /// Converts an array to a byte array. + /// + /// The type of the array element. + /// The array to be converted. + /// The converted byte array. + public static byte[] ToByteArray(this IReadOnlyCollection value) + where T : ISerializable + { + using MemoryStream ms = new(); + using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); + writer.Write(value); + writer.Flush(); + return ms.ToArray(); + } + } +} diff --git a/src/Neo/Extensions/MemoryExtensions.cs b/src/Neo/Extensions/MemoryExtensions.cs new file mode 100644 index 0000000000..f6576387de --- /dev/null +++ b/src/Neo/Extensions/MemoryExtensions.cs @@ -0,0 +1,60 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// MemoryExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; +using System; +using System.Reflection; + +namespace Neo.Extensions +{ + public static class MemoryExtensions + { + /// + /// Converts a byte array to an object. + /// + /// The type to convert to. + /// The byte array to be converted. + /// The converted object. + public static T AsSerializable(this ReadOnlyMemory value) + where T : ISerializable, new() + { + if (value.IsEmpty) throw new FormatException(); + MemoryReader reader = new(value); + return reader.ReadSerializable(); + } + + /// + /// Converts a byte array to an object. + /// + /// The byte array to be converted. + /// The type to convert to. + /// The converted object. + public static ISerializable AsSerializable(this ReadOnlyMemory value, Type type) + { + if (!typeof(ISerializable).GetTypeInfo().IsAssignableFrom(type)) + throw new InvalidCastException(); + var serializable = (ISerializable)Activator.CreateInstance(type); + MemoryReader reader = new(value); + serializable.Deserialize(ref reader); + return serializable; + } + + /// + /// Gets the size of the specified array encoded in variable-length encoding. + /// + /// The specified array. + /// The size of the array. + public static int GetVarSize(this ReadOnlyMemory value) + { + return UnsafeData.GetVarSize(value.Length) + value.Length; + } + } +} diff --git a/src/Neo/IO/Helper.cs b/src/Neo/IO/Helper.cs index 2e6d362ee1..d0e5a00ec9 100644 --- a/src/Neo/IO/Helper.cs +++ b/src/Neo/IO/Helper.cs @@ -14,9 +14,6 @@ using System.Buffers.Binary; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; namespace Neo.IO { @@ -38,35 +35,6 @@ public static class Helper return reader.ReadSerializable(); } - /// - /// Converts a byte array to an object. - /// - /// The type to convert to. - /// The byte array to be converted. - /// The converted object. - public static T AsSerializable(this ReadOnlyMemory value) where T : ISerializable, new() - { - if (value.IsEmpty) throw new FormatException(); - MemoryReader reader = new(value); - return reader.ReadSerializable(); - } - - /// - /// Converts a byte array to an object. - /// - /// The byte array to be converted. - /// The type to convert to. - /// The converted object. - public static ISerializable AsSerializable(this ReadOnlyMemory value, Type type) - { - if (!typeof(ISerializable).GetTypeInfo().IsAssignableFrom(type)) - throw new InvalidCastException(); - ISerializable serializable = (ISerializable)Activator.CreateInstance(type); - MemoryReader reader = new(value); - serializable.Deserialize(ref reader); - return serializable; - } - /// /// Converts a byte array to an array. /// @@ -124,77 +92,6 @@ public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) return result; } - /// - /// Gets the size of variable-length of the data. - /// - /// The length of the data. - /// The size of variable-length of the data. - public static int GetVarSize(int value) - { - if (value < 0xFD) - return sizeof(byte); - else if (value <= 0xFFFF) - return sizeof(byte) + sizeof(ushort); - else - return sizeof(byte) + sizeof(uint); - } - - /// - /// Gets the size of the specified array encoded in variable-length encoding. - /// - /// The type of the array element. - /// The specified array. - /// The size of the array. - public static int GetVarSize(this IReadOnlyCollection value) - { - int value_size; - Type t = typeof(T); - if (typeof(ISerializable).IsAssignableFrom(t)) - { - value_size = value.OfType().Sum(p => p.Size); - } - else if (t.GetTypeInfo().IsEnum) - { - int element_size; - Type u = t.GetTypeInfo().GetEnumUnderlyingType(); - if (u == typeof(sbyte) || u == typeof(byte)) - element_size = 1; - else if (u == typeof(short) || u == typeof(ushort)) - element_size = 2; - else if (u == typeof(int) || u == typeof(uint)) - element_size = 4; - else //if (u == typeof(long) || u == typeof(ulong)) - element_size = 8; - value_size = value.Count * element_size; - } - else - { - value_size = value.Count * Marshal.SizeOf(); - } - return GetVarSize(value.Count) + value_size; - } - - /// - /// Gets the size of the specified array encoded in variable-length encoding. - /// - /// The specified array. - /// The size of the array. - public static int GetVarSize(this ReadOnlyMemory value) - { - return GetVarSize(value.Length) + value.Length; - } - - /// - /// Gets the size of the specified encoded in variable-length encoding. - /// - /// The specified . - /// The size of the . - public static int GetVarSize(this string value) - { - int size = Utility.StrictUTF8.GetByteCount(value); - return GetVarSize(size) + size; - } - /// /// Reads a byte array of the specified size from a . /// @@ -315,21 +212,6 @@ public static byte[] ToArray(this ISerializable value) return ms.ToArray(); } - /// - /// Converts an array to a byte array. - /// - /// The type of the array element. - /// The array to be converted. - /// The converted byte array. - public static byte[] ToByteArray(this IReadOnlyCollection value) where T : ISerializable - { - using MemoryStream ms = new(); - using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); - writer.Write(value); - writer.Flush(); - return ms.ToArray(); - } - /// /// Writes an object into a . /// diff --git a/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs index 306f6327ab..6e2b94a17d 100644 --- a/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/Neo/Network/P2P/Payloads/ExtensiblePayload.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.Persistence; using Neo.SmartContract; diff --git a/src/Neo/SmartContract/MethodToken.cs b/src/Neo/SmartContract/MethodToken.cs index 1b391edd32..1b8fa00242 100644 --- a/src/Neo/SmartContract/MethodToken.cs +++ b/src/Neo/SmartContract/MethodToken.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 System; diff --git a/src/Neo/SmartContract/NefFile.cs b/src/Neo/SmartContract/NefFile.cs index 3e343d3be2..5638447688 100644 --- a/src/Neo/SmartContract/NefFile.cs +++ b/src/Neo/SmartContract/NefFile.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.VM; diff --git a/src/Neo/Wallets/Helper.cs b/src/Neo/Wallets/Helper.cs index 1273bafc50..265315ff6d 100644 --- a/src/Neo/Wallets/Helper.cs +++ b/src/Neo/Wallets/Helper.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; @@ -93,7 +94,7 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot, UInt160[] hashes = tx.GetScriptHashesForVerifying(snapshot); // base size for transaction: includes const_header + signers + attributes + script + hashes - int size = Transaction.HeaderSize + tx.Signers.GetVarSize() + tx.Attributes.GetVarSize() + tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length), index = -1; + int size = Transaction.HeaderSize + tx.Signers.GetVarSize() + tx.Attributes.GetVarSize() + tx.Script.GetVarSize() + UnsafeData.GetVarSize(hashes.Length), index = -1; uint exec_fee_factor = NativeContract.Policy.GetExecFeeFactor(snapshot); long networkFee = 0; foreach (UInt160 hash in hashes) @@ -151,7 +152,7 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot, else if (IsMultiSigContract(witnessScript, out int m, out int n)) { int size_inv = 66 * m; - size += IO.Helper.GetVarSize(size_inv) + size_inv + witnessScript.GetVarSize(); + size += UnsafeData.GetVarSize(size_inv) + size_inv + witnessScript.GetVarSize(); networkFee += exec_fee_factor * MultiSignatureContractCost(m, n); } // We can support more contract types in the future. diff --git a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs index 96f9041aaf..4a997757f5 100644 --- a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.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; namespace Neo.Plugins.ApplicationLogs.Store.States diff --git a/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs b/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs index 210ac36283..ace7f0e42f 100644 --- a/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/ExecutionLogState.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.Ledger; using Neo.VM; diff --git a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs index 70b53268e5..87cc5e60ae 100644 --- a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs index edffc1cb09..d055ddbb4a 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Plugins.DBFTPlugin.Messages; using Neo.SmartContract; @@ -110,7 +111,7 @@ internal int GetExpectedBlockSizeWithoutTransactions(int expectedTransactions) sizeof(byte) + // PrimaryIndex UInt160.Length + // NextConsensus 1 + _witnessSize + // Witness - IO.Helper.GetVarSize(expectedTransactions); + UnsafeData.GetVarSize(expectedTransactions); } } } diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.cs index ef45548645..2e20f03a9d 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; @@ -31,11 +32,11 @@ public int Size switch (type) { case NodeType.BranchNode: - return size + BranchSize + IO.Helper.GetVarSize(Reference); + return size + BranchSize + UnsafeData.GetVarSize(Reference); case NodeType.ExtensionNode: - return size + ExtensionSize + IO.Helper.GetVarSize(Reference); + return size + ExtensionSize + UnsafeData.GetVarSize(Reference); case NodeType.LeafNode: - return size + LeafSize + IO.Helper.GetVarSize(Reference); + return size + LeafSize + UnsafeData.GetVarSize(Reference); case NodeType.HashNode: return size + HashSize; case NodeType.Empty: diff --git a/src/Plugins/OracleService/OracleService.cs b/src/Plugins/OracleService/OracleService.cs index 890e1c3b03..a976ed220f 100644 --- a/src/Plugins/OracleService/OracleService.cs +++ b/src/Plugins/OracleService/OracleService.cs @@ -446,8 +446,8 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req int size_inv = 66 * m; int size = Transaction.HeaderSize + tx.Signers.GetVarSize() + tx.Script.GetVarSize() - + IO.Helper.GetVarSize(hashes.Length) + witnessDict[NativeContract.Oracle.Hash].Size - + IO.Helper.GetVarSize(size_inv) + size_inv + oracleSignContract.Script.GetVarSize(); + + UnsafeData.GetVarSize(hashes.Length) + witnessDict[NativeContract.Oracle.Hash].Size + + UnsafeData.GetVarSize(size_inv) + size_inv + oracleSignContract.Script.GetVarSize(); var feePerByte = NativeContract.Policy.GetFeePerByte(snapshot); if (response.Result.Length > OracleResponse.MaxResultSize) diff --git a/src/Plugins/TokensTracker/Extensions.cs b/src/Plugins/TokensTracker/Extensions.cs index 7805056280..83b4371435 100644 --- a/src/Plugins/TokensTracker/Extensions.cs +++ b/src/Plugins/TokensTracker/Extensions.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.Persistence; using Neo.VM.Types; @@ -33,13 +34,13 @@ public static string ToBase64(this ReadOnlySpan item) public static int GetVarSize(this ByteString item) { var length = item.GetSpan().Length; - return IO.Helper.GetVarSize(length) + length; + return UnsafeData.GetVarSize(length) + length; } public static int GetVarSize(this BigInteger item) { var length = item.GetByteCount(); - return IO.Helper.GetVarSize(length) + length; + return UnsafeData.GetVarSize(length) + length; } public static IEnumerable<(TKey, TValue)> FindPrefix(this IStore db, byte[] prefix) diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index 48453c992a..8366ba9659 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -177,17 +177,17 @@ public void TestGetVarSizeInt() { if (i == 0) { - int result = Neo.IO.Helper.GetVarSize(1); + int result = UnsafeData.GetVarSize(1); Assert.AreEqual(1, result); } else if (i == 1) { - int result = Neo.IO.Helper.GetVarSize(0xFFFF); + int result = UnsafeData.GetVarSize(0xFFFF); Assert.AreEqual(3, result); } else { - int result = Neo.IO.Helper.GetVarSize(0xFFFFFF); + int result = UnsafeData.GetVarSize(0xFFFFFF); Assert.AreEqual(5, result); } } @@ -323,7 +323,7 @@ public void TestGetVarSizeGeneric() [TestMethod] public void TestGetVarSizeString() { - int result = Neo.IO.Helper.GetVarSize("AA"); + int result = "AA".GetVarSize(); Assert.AreEqual(3, result); } From 129a32f83787de204589355318d3cc9d8ab6e326 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 14:39:09 -0400 Subject: [PATCH 09/18] Adding `using` --- src/Neo/IO/Caching/ReflectionCache.cs | 1 + src/Neo/Network/P2P/Message.cs | 1 + src/Neo/Network/P2P/Payloads/AddrPayload.cs | 1 + src/Neo/Network/P2P/Payloads/Block.cs | 1 + .../P2P/Payloads/Conditions/AndCondition.cs | 1 + .../P2P/Payloads/Conditions/OrCondition.cs | 10 ++++- .../Network/P2P/Payloads/FilterAddPayload.cs | 1 + .../Network/P2P/Payloads/FilterLoadPayload.cs | 1 + .../Network/P2P/Payloads/HeadersPayload.cs | 1 + src/Neo/Network/P2P/Payloads/InvPayload.cs | 1 + .../P2P/Payloads/MerkleBlockPayload.cs | 1 + .../Network/P2P/Payloads/OracleResponse.cs | 1 + src/Neo/Network/P2P/Payloads/Signer.cs | 1 + src/Neo/Network/P2P/Payloads/Transaction.cs | 1 + src/Neo/Network/P2P/Payloads/Witness.cs | 1 + .../SmartContract/Native/LedgerContract.cs | 1 + src/Neo/SmartContract/Native/NeoToken.cs | 1 + .../SmartContract/Native/TransactionState.cs | 1 + src/Neo/SmartContract/Native/TrimmedBlock.cs | 1 + .../Store/States/BlockLogState.cs | 2 +- .../Store/States/TransactionEngineLogState.cs | 1 + .../Store/States/TransactionLogState.cs | 1 + .../DBFTPlugin/Messages/ConsensusMessage.cs | 1 + .../DBFTPlugin/Messages/PrepareRequest.cs | 1 + ...ecoveryMessage.ChangeViewPayloadCompact.cs | 1 + .../RecoveryMessage.CommitPayloadCompact.cs | 1 + ...coveryMessage.PreparationPayloadCompact.cs | 1 + .../RecoveryMessage/RecoveryMessage.cs | 1 + .../Cryptography/MPTTrie/Node.Extension.cs | 1 + .../MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs | 1 + .../RpcServer/RpcServer.SmartContract.cs | 3 +- .../SQLiteWallet/VerificationContract.cs | 1 + src/Plugins/StateService/Network/Vote.cs | 1 + .../StateService/Storage/StateStore.cs | 1 + .../Verification/VerificationService.cs | 1 + tests/Neo.UnitTests/IO/UT_IOHelper.cs | 45 +++++++------------ .../P2P/Payloads/UT_NetworkAddressWithTime.cs | 1 + .../Network/P2P/Payloads/UT_VersionPayload.cs | 1 + 38 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/Neo/IO/Caching/ReflectionCache.cs b/src/Neo/IO/Caching/ReflectionCache.cs index 5007b67740..f24f4e5ab6 100644 --- a/src/Neo/IO/Caching/ReflectionCache.cs +++ b/src/Neo/IO/Caching/ReflectionCache.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.Collections.Generic; using System.Reflection; diff --git a/src/Neo/Network/P2P/Message.cs b/src/Neo/Network/P2P/Message.cs index 9d3c63a85b..96c79f2b10 100644 --- a/src/Neo/Network/P2P/Message.cs +++ b/src/Neo/Network/P2P/Message.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.IO; +using Neo.Extensions; using Neo.IO; using Neo.IO.Caching; using System; diff --git a/src/Neo/Network/P2P/Payloads/AddrPayload.cs b/src/Neo/Network/P2P/Payloads/AddrPayload.cs index ebdceb65ec..90958a38ef 100644 --- a/src/Neo/Network/P2P/Payloads/AddrPayload.cs +++ b/src/Neo/Network/P2P/Payloads/AddrPayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/Block.cs b/src/Neo/Network/P2P/Payloads/Block.cs index 3c727b9886..ab28c6c363 100644 --- a/src/Neo/Network/P2P/Payloads/Block.cs +++ b/src/Neo/Network/P2P/Payloads/Block.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs index e395b10d5d..2fed4d32fb 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs index b06fc922a8..32c0bfd718 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; @@ -30,7 +31,14 @@ public class OrCondition : WitnessCondition /// public WitnessCondition[] Expressions; - public override int Size => base.Size + Expressions.GetVarSize(); + public override int Size + { + get + { + return base.Size + Expressions.GetVarSize(); + } + } + public override WitnessConditionType Type => WitnessConditionType.Or; protected override void DeserializeWithoutType(ref MemoryReader reader, int maxNestDepth) diff --git a/src/Neo/Network/P2P/Payloads/FilterAddPayload.cs b/src/Neo/Network/P2P/Payloads/FilterAddPayload.cs index ff4aa1287b..4f4e9df152 100644 --- a/src/Neo/Network/P2P/Payloads/FilterAddPayload.cs +++ b/src/Neo/Network/P2P/Payloads/FilterAddPayload.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/FilterLoadPayload.cs b/src/Neo/Network/P2P/Payloads/FilterLoadPayload.cs index 2608e0e7b0..f0eae27278 100644 --- a/src/Neo/Network/P2P/Payloads/FilterLoadPayload.cs +++ b/src/Neo/Network/P2P/Payloads/FilterLoadPayload.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/HeadersPayload.cs b/src/Neo/Network/P2P/Payloads/HeadersPayload.cs index 152ba32857..e5800d4544 100644 --- a/src/Neo/Network/P2P/Payloads/HeadersPayload.cs +++ b/src/Neo/Network/P2P/Payloads/HeadersPayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/InvPayload.cs b/src/Neo/Network/P2P/Payloads/InvPayload.cs index aa4d340d99..17625f6dc4 100644 --- a/src/Neo/Network/P2P/Payloads/InvPayload.cs +++ b/src/Neo/Network/P2P/Payloads/InvPayload.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.Collections.Generic; diff --git a/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs b/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs index aebb17d5d9..97f9ed0f27 100644 --- a/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs +++ b/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using System; using System.Collections; diff --git a/src/Neo/Network/P2P/Payloads/OracleResponse.cs b/src/Neo/Network/P2P/Payloads/OracleResponse.cs index 2770f556a8..bf3aa70cf4 100644 --- a/src/Neo/Network/P2P/Payloads/OracleResponse.cs +++ b/src/Neo/Network/P2P/Payloads/OracleResponse.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Persistence; diff --git a/src/Neo/Network/P2P/Payloads/Signer.cs b/src/Neo/Network/P2P/Payloads/Signer.cs index 79065408f4..9b5e317abc 100644 --- a/src/Neo/Network/P2P/Payloads/Signer.cs +++ b/src/Neo/Network/P2P/Payloads/Signer.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads.Conditions; diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index b922674d91..6f41b5141b 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -11,6 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/src/Neo/Network/P2P/Payloads/Witness.cs b/src/Neo/Network/P2P/Payloads/Witness.cs index 34932cc7fb..b3da47d2b7 100644 --- a/src/Neo/Network/P2P/Payloads/Witness.cs +++ b/src/Neo/Network/P2P/Payloads/Witness.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/SmartContract/Native/LedgerContract.cs b/src/Neo/SmartContract/Native/LedgerContract.cs index ea757ba348..10d86d730d 100644 --- a/src/Neo/SmartContract/Native/LedgerContract.cs +++ b/src/Neo/SmartContract/Native/LedgerContract.cs @@ -11,6 +11,7 @@ #pragma warning disable IDE0051 +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index f43a0d6079..e0690c8afc 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -12,6 +12,7 @@ #pragma warning disable IDE0051 using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using Neo.SmartContract.Iterators; diff --git a/src/Neo/SmartContract/Native/TransactionState.cs b/src/Neo/SmartContract/Native/TransactionState.cs index b17296b42d..050358f179 100644 --- a/src/Neo/SmartContract/Native/TransactionState.cs +++ b/src/Neo/SmartContract/Native/TransactionState.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.Network.P2P.Payloads; using Neo.VM; diff --git a/src/Neo/SmartContract/Native/TrimmedBlock.cs b/src/Neo/SmartContract/Native/TrimmedBlock.cs index 4cc4c39c0f..c2bab2567c 100644 --- a/src/Neo/SmartContract/Native/TrimmedBlock.cs +++ b/src/Neo/SmartContract/Native/TrimmedBlock.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.Network.P2P.Payloads; using Neo.VM; diff --git a/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs b/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs index 54369a672a..ce957b79f6 100644 --- a/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/BlockLogState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo; +using Neo.Extensions; using Neo.IO; namespace Neo.Plugins.ApplicationLogs.Store.States diff --git a/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs b/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs index 9417f984e2..80e5be7e97 100644 --- a/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/TransactionEngineLogState.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; namespace Neo.Plugins.ApplicationLogs.Store.States diff --git a/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs b/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs index 1667478509..bca012ec50 100644 --- a/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/TransactionLogState.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; namespace Neo.Plugins.ApplicationLogs.Store.States diff --git a/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs b/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs index de030d166d..f8cd8cbc14 100644 --- a/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs +++ b/src/Plugins/DBFTPlugin/Messages/ConsensusMessage.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Plugins.DBFTPlugin.Types; using System; diff --git a/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs b/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs index 495ccbd726..c5b150b572 100644 --- a/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs +++ b/src/Plugins/DBFTPlugin/Messages/PrepareRequest.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Plugins.DBFTPlugin.Types; using System; diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs index 2d7283cd22..40528d8aaf 100644 --- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs +++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.ChangeViewPayloadCompact.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs index 6d3880f3c0..dc7d532d30 100644 --- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs +++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.CommitPayloadCompact.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs index 8fae1596ef..cec8a45a3a 100644 --- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs +++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.PreparationPayloadCompact.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs index 2de33470ea..2feb919520 100644 --- a/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.cs +++ b/src/Plugins/DBFTPlugin/Messages/RecoveryMessage/RecoveryMessage.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.Network.P2P.Payloads; using Neo.Plugins.DBFTPlugin.Consensus; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Extension.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Extension.cs index 510db49250..0d68564732 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Extension.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Extension.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.SmartContract; using System; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs index 024a07f8c8..b1b7707729 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Leaf.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.SmartContract; using System; diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs index 2fe49d4965..7237906289 100644 --- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs +++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; @@ -189,7 +190,7 @@ private static Signer[] SignersFromJson(JArray _params, ProtocolSettings setting // Validate format - _ = IO.Helper.ToByteArray(ret).AsSerializableArray(); + _ = ret.ToByteArray().AsSerializableArray(); return ret; } diff --git a/src/Plugins/SQLiteWallet/VerificationContract.cs b/src/Plugins/SQLiteWallet/VerificationContract.cs index e128045adb..2f62a7174b 100644 --- a/src/Plugins/SQLiteWallet/VerificationContract.cs +++ b/src/Plugins/SQLiteWallet/VerificationContract.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.SmartContract; diff --git a/src/Plugins/StateService/Network/Vote.cs b/src/Plugins/StateService/Network/Vote.cs index e6840c7a9f..bba40f6a54 100644 --- a/src/Plugins/StateService/Network/Vote.cs +++ b/src/Plugins/StateService/Network/Vote.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/StateService/Storage/StateStore.cs b/src/Plugins/StateService/Storage/StateStore.cs index f2ca6d7d05..beb19818bb 100644 --- a/src/Plugins/StateService/Storage/StateStore.cs +++ b/src/Plugins/StateService/Storage/StateStore.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Akka.Actor; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/StateService/Verification/VerificationService.cs b/src/Plugins/StateService/Verification/VerificationService.cs index a8eb9fd030..3d77bc3501 100644 --- a/src/Plugins/StateService/Verification/VerificationService.cs +++ b/src/Plugins/StateService/Verification/VerificationService.cs @@ -11,6 +11,7 @@ using Akka.Actor; using Akka.Util.Internal; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index 8366ba9659..f43607384b 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -110,23 +110,12 @@ public void TestNullableArray() [TestMethod] public void TestAsSerializable() { - for (int i = 0; i < 2; i++) - { - if (i == 0) - { - byte[] caseArray = new byte[] { 0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00 }; - ISerializable result = Neo.IO.Helper.AsSerializable(caseArray, typeof(UInt160)); - Assert.AreEqual(UInt160.Zero, result); - } - else - { - Action action = () => Neo.IO.Helper.AsSerializable(Array.Empty(), typeof(double)); - action.Should().Throw(); - } - } + byte[] caseArray = [0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00]; + ISerializable result = caseArray.AsSerializable(); + Assert.AreEqual(UInt160.Zero, result); } [TestMethod] @@ -164,7 +153,7 @@ public void TestCompression() [TestMethod] public void TestAsSerializableArray() { - byte[] byteArray = Neo.IO.Helper.ToByteArray(new UInt160[] { UInt160.Zero }); + byte[] byteArray = new UInt160[] { UInt160.Zero }.ToByteArray(); UInt160[] result = Neo.IO.Helper.AsSerializableArray(byteArray); Assert.AreEqual(1, result.Length); Assert.AreEqual(UInt160.Zero, result[0]); @@ -234,7 +223,7 @@ public void TestGetVarSizeGeneric() { if (i == 0) { - int result = Neo.IO.Helper.GetVarSize(new UInt160[] { UInt160.Zero }); + int result = new UInt160[] { UInt160.Zero }.GetVarSize(); Assert.AreEqual(21, result); } else if (i == 1)//sbyte @@ -244,7 +233,7 @@ public void TestGetVarSizeGeneric() TestEnum0.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(2, result); } else if (i == 2)//byte @@ -254,7 +243,7 @@ public void TestGetVarSizeGeneric() TestEnum1.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(2, result); } else if (i == 3)//short @@ -264,7 +253,7 @@ public void TestGetVarSizeGeneric() TestEnum2.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(3, result); } else if (i == 4)//ushort @@ -274,7 +263,7 @@ public void TestGetVarSizeGeneric() TestEnum3.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(3, result); } else if (i == 5)//int @@ -284,7 +273,7 @@ public void TestGetVarSizeGeneric() TestEnum4.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(5, result); } else if (i == 6)//uint @@ -294,7 +283,7 @@ public void TestGetVarSizeGeneric() TestEnum5.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(5, result); } else if (i == 7)//long @@ -304,7 +293,7 @@ public void TestGetVarSizeGeneric() TestEnum6.case1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(9, result); } else if (i == 8) @@ -314,7 +303,7 @@ public void TestGetVarSizeGeneric() 1 }; IReadOnlyCollection testList = initList.AsReadOnly(); - int result = Neo.IO.Helper.GetVarSize(testList); + int result = testList.GetVarSize(); Assert.AreEqual(5, result); } } @@ -413,7 +402,7 @@ public void TestToArray() [TestMethod] public void TestToByteArrayGeneric() { - byte[] byteArray = Neo.IO.Helper.ToByteArray(new UInt160[] { UInt160.Zero }); + byte[] byteArray = new UInt160[] { UInt160.Zero }.ToByteArray(); Assert.AreEqual(Encoding.Default.GetString(new byte[] { 0x01,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NetworkAddressWithTime.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NetworkAddressWithTime.cs index 2ed86e4da7..3e2c6c336c 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NetworkAddressWithTime.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NetworkAddressWithTime.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_VersionPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_VersionPayload.cs index a77740a1e5..66bebf68d8 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_VersionPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_VersionPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; using Neo.Network.P2P.Payloads; From 397cc1f0119c91fb2d5fe33fcfdd4d407141d025 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 14:45:27 -0400 Subject: [PATCH 10/18] dotnet format --- tests/Neo.UnitTests/IO/UT_IOHelper.cs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index f43607384b..9158cf2b1d 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -110,10 +110,26 @@ public void TestNullableArray() [TestMethod] public void TestAsSerializable() { - byte[] caseArray = [0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00]; + byte[] caseArray = [0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00]; ISerializable result = caseArray.AsSerializable(); Assert.AreEqual(UInt160.Zero, result); } From a127386a110d1f7d179ed0aec326b45ad0bcd838 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 15:24:02 -0400 Subject: [PATCH 11/18] Added more Extensions --- src/Neo/Cryptography/Helper.cs | 2 +- src/Neo/Cryptography/MerkleTree.cs | 2 +- src/Neo/Extensions/ByteExtensions.cs | 45 +++ .../Collections/ICollectionExtensions.cs | 1 + .../Extensions/IO/BinaryReaderExtensions.cs | 79 +++++ .../Extensions/IO/BinaryWriterExtensions.cs | 137 ++++++++ .../Extensions/IO/ISerializableExtensions.cs | 33 ++ .../Extensions/IO/MemoryReaderExtensions.cs | 70 ++++ src/Neo/Extensions/MemoryExtensions.cs | 14 + src/Neo/Extensions/SpanExtensions.cs | 71 ++++ src/Neo/IO/Helper.cs | 329 ------------------ src/Neo/Network/P2P/Helper.cs | 2 +- .../Conditions/CalledByContractCondition.cs | 1 + .../Conditions/CalledByGroupCondition.cs | 1 + .../P2P/Payloads/Conditions/GroupCondition.cs | 1 + .../P2P/Payloads/Conditions/NotCondition.cs | 1 + .../Conditions/ScriptHashCondition.cs | 1 + src/Neo/Network/P2P/Payloads/Conflicts.cs | 1 + .../Network/P2P/Payloads/GetBlocksPayload.cs | 1 + src/Neo/Network/P2P/Payloads/Header.cs | 1 + src/Neo/Network/P2P/Payloads/WitnessRule.cs | 1 + src/Neo/Network/P2P/RemoteNode.cs | 1 + src/Neo/Persistence/SnapshotCache.cs | 2 +- src/Neo/SmartContract/ApplicationEngine.cs | 1 + src/Neo/SmartContract/BinarySerializer.cs | 1 + src/Neo/SmartContract/ContractState.cs | 2 +- .../SmartContract/Manifest/ContractGroup.cs | 2 +- .../Manifest/ContractPermission.cs | 2 +- .../Manifest/ContractPermissionDescriptor.cs | 2 +- .../Native/ContractManagement.cs | 2 +- src/Neo/SmartContract/Native/FungibleToken.cs | 2 +- .../SmartContract/Native/HashIndexState.cs | 2 +- .../SmartContract/Native/OracleContract.cs | 2 +- src/Neo/SmartContract/Native/OracleRequest.cs | 2 +- .../SmartContract/Native/RoleManagement.cs | 2 +- src/Neo/SmartContract/NotifyEventArgs.cs | 2 +- src/Neo/VM/Helper.cs | 1 + .../ApplicationLogs/Store/LogStorageStore.cs | 2 +- .../DBFTPlugin/Consensus/ConsensusContext.cs | 1 + .../DBFTPlugin/Messages/PrepareResponse.cs | 1 + .../MPTTrie/Cryptography/MPTTrie/Cache.cs | 2 +- .../MPTTrie/Cryptography/MPTTrie/Node.Hash.cs | 1 + src/Plugins/RpcServer/RpcServer.Node.cs | 2 +- src/Plugins/RpcServer/RpcServer.Wallet.cs | 2 +- src/Plugins/SQLiteWallet/SQLiteWallet.cs | 2 +- src/Plugins/StateService/Network/StateRoot.cs | 1 + src/Plugins/StateService/StatePlugin.cs | 2 +- .../StateService/Storage/StateSnapshot.cs | 2 +- src/Plugins/StorageDumper/StorageDumper.cs | 2 +- .../Trackers/NEP-11/Nep11BalanceKey.cs | 1 + .../Trackers/NEP-11/Nep11TransferKey.cs | 1 + .../Trackers/NEP-17/Nep17BalanceKey.cs | 1 + .../TokensTracker/Trackers/TokenBalance.cs | 1 + .../TokensTracker/Trackers/TokenTransfer.cs | 1 + .../Trackers/TokenTransferKey.cs | 1 + .../TokensTracker/Trackers/TrackerBase.cs | 1 + tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 1 + .../UT_RpcServer.Blockchain.cs | 1 + .../Cryptography/UT_MerkleTree.cs | 1 + .../Neo.UnitTests/IO/Caching/UT_DataCache.cs | 1 + tests/Neo.UnitTests/IO/UT_IOHelper.cs | 80 ++--- .../P2P/Capabilities/UT_FullNodeCapability.cs | 1 + .../P2P/Capabilities/UT_ServerCapability.cs | 1 + .../Network/P2P/Payloads/UT_AddrPayload.cs | 1 + .../Network/P2P/Payloads/UT_Conflicts.cs | 1 + .../P2P/Payloads/UT_ExtensiblePayload.cs | 1 + .../P2P/Payloads/UT_FilterAddPayload.cs | 1 + .../P2P/Payloads/UT_FilterLoadPayload.cs | 1 + .../P2P/Payloads/UT_GetBlockByIndexPayload.cs | 1 + .../P2P/Payloads/UT_GetBlocksPayload.cs | 1 + .../Network/P2P/Payloads/UT_HeadersPayload.cs | 1 + .../P2P/Payloads/UT_HighPriorityAttribute.cs | 1 + .../Network/P2P/Payloads/UT_InvPayload.cs | 1 + .../P2P/Payloads/UT_MerkleBlockPayload.cs | 1 + .../Network/P2P/Payloads/UT_NotValidBefore.cs | 1 + .../Network/P2P/Payloads/UT_Transaction.cs | 9 +- tests/Neo.UnitTests/Network/P2P/UT_Message.cs | 1 + .../Network/P2P/UT_RemoteNode.cs | 1 + .../Persistence/UT_MemoryStore.cs | 1 + .../SmartContract/Native/UT_GasToken.cs | 1 + .../SmartContract/Native/UT_PolicyContract.cs | 1 + .../SmartContract/UT_MethodToken.cs | 1 + .../Neo.UnitTests/SmartContract/UT_NefFile.cs | 1 + .../SmartContract/UT_Syscalls.cs | 1 + tests/Neo.UnitTests/TestUtils.cs | 1 + .../Wallets/UT_Wallets_Helper.cs | 1 + 86 files changed, 570 insertions(+), 396 deletions(-) create mode 100644 src/Neo/Extensions/ByteExtensions.cs create mode 100644 src/Neo/Extensions/IO/BinaryReaderExtensions.cs create mode 100644 src/Neo/Extensions/IO/BinaryWriterExtensions.cs create mode 100644 src/Neo/Extensions/IO/ISerializableExtensions.cs create mode 100644 src/Neo/Extensions/IO/MemoryReaderExtensions.cs create mode 100644 src/Neo/Extensions/SpanExtensions.cs delete mode 100644 src/Neo/IO/Helper.cs diff --git a/src/Neo/Cryptography/Helper.cs b/src/Neo/Cryptography/Helper.cs index 41e89f5a49..5ec4ea38d7 100644 --- a/src/Neo/Cryptography/Helper.cs +++ b/src/Neo/Cryptography/Helper.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Wallets; using Org.BouncyCastle.Crypto.Digests; diff --git a/src/Neo/Cryptography/MerkleTree.cs b/src/Neo/Cryptography/MerkleTree.cs index ed25171ef8..09afa29277 100644 --- a/src/Neo/Cryptography/MerkleTree.cs +++ b/src/Neo/Cryptography/MerkleTree.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using System; using System.Collections; using System.Collections.Generic; diff --git a/src/Neo/Extensions/ByteExtensions.cs b/src/Neo/Extensions/ByteExtensions.cs new file mode 100644 index 0000000000..a1e7e0f931 --- /dev/null +++ b/src/Neo/Extensions/ByteExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ByteExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; +using System; + +namespace Neo.Extensions +{ + public static class ByteExtensions2 + { + /// + /// Converts a byte array to an object. + /// + /// The type to convert to. + /// The byte array to be converted. + /// The offset into the byte array from which to begin using data. + /// The converted object. + public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable, new() + { + MemoryReader reader = new(value.AsMemory(start)); + return reader.ReadSerializable(); + } + + /// + /// Converts a byte array to an array. + /// + /// The type of the array element. + /// The byte array to be converted. + /// The maximum number of elements contained in the converted array. + /// The converted array. + public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable, new() + { + MemoryReader reader = new(value); + return reader.ReadSerializableArray(max); + } + } +} diff --git a/src/Neo/Extensions/Collections/ICollectionExtensions.cs b/src/Neo/Extensions/Collections/ICollectionExtensions.cs index 724def6d80..742446a4e8 100644 --- a/src/Neo/Extensions/Collections/ICollectionExtensions.cs +++ b/src/Neo/Extensions/Collections/ICollectionExtensions.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.Collections.Generic; using System.IO; diff --git a/src/Neo/Extensions/IO/BinaryReaderExtensions.cs b/src/Neo/Extensions/IO/BinaryReaderExtensions.cs new file mode 100644 index 0000000000..f3448d96e1 --- /dev/null +++ b/src/Neo/Extensions/IO/BinaryReaderExtensions.cs @@ -0,0 +1,79 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// BinaryReaderExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using System; +using System.IO; + +namespace Neo.Extensions +{ + public static class BinaryReaderExtensions + { + /// + /// Reads a byte array of the specified size from a . + /// + /// The for reading data. + /// The size of the byte array. + /// The byte array read from the . + public static byte[] ReadFixedBytes(this BinaryReader reader, int size) + { + var index = 0; + var data = new byte[size]; + + while (size > 0) + { + var bytesRead = reader.Read(data, index, size); + + if (bytesRead <= 0) + { + throw new FormatException(); + } + + size -= bytesRead; + index += bytesRead; + } + + return data; + } + + /// + /// Reads a byte array from a . + /// + /// The for reading data. + /// The maximum size of the byte array. + /// The byte array read from the . + public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x1000000) + { + return reader.ReadFixedBytes((int)reader.ReadVarInt((ulong)max)); + } + + /// + /// Reads an integer from a . + /// + /// The for reading data. + /// The maximum value of the integer. + /// The integer read from the . + public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) + { + var fb = reader.ReadByte(); + ulong value; + if (fb == 0xFD) + value = reader.ReadUInt16(); + else if (fb == 0xFE) + value = reader.ReadUInt32(); + else if (fb == 0xFF) + value = reader.ReadUInt64(); + else + value = fb; + if (value > max) throw new FormatException(); + return value; + } + } +} diff --git a/src/Neo/Extensions/IO/BinaryWriterExtensions.cs b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs new file mode 100644 index 0000000000..665eae1a69 --- /dev/null +++ b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs @@ -0,0 +1,137 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// BinaryWriterExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Neo.Extensions +{ + public static class BinaryWriterExtensions + { + /// + /// Writes an object into a . + /// + /// The for writing data. + /// The object to be written. + public static void Write(this BinaryWriter writer, ISerializable value) + { + value.Serialize(writer); + } + + /// + /// Writes an array into a . + /// + /// The type of the array element. + /// The for writing data. + /// The array to be written. + public static void Write(this BinaryWriter writer, IReadOnlyCollection value) + where T : ISerializable + { + writer.WriteVarInt(value.Count); + foreach (T item in value) + { + item.Serialize(writer); + } + } + + /// + /// Writes a into a . + /// + /// The for writing data. + /// The to be written. + /// The fixed size of the . + public static void WriteFixedString(this BinaryWriter writer, string value, int length) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + if (value.Length > length) + throw new ArgumentException(null, nameof(value)); + var bytes = Utility.StrictUTF8.GetBytes(value); + if (bytes.Length > length) + throw new ArgumentException(null, nameof(value)); + writer.Write(bytes); + if (bytes.Length < length) + writer.Write(stackalloc byte[length - bytes.Length]); + } + + /// + /// Writes an array into a . + /// + /// The type of the array element. + /// The for writing data. + /// The array to be written. + public static void WriteNullableArray(this BinaryWriter writer, T[] value) + where T : class, ISerializable + { + writer.WriteVarInt(value.Length); + foreach (var item in value) + { + var isNull = item is null; + writer.Write(!isNull); + if (isNull) continue; + item.Serialize(writer); + } + } + + /// + /// Writes a byte array into a . + /// + /// The for writing data. + /// The byte array to be written. + public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan value) + { + writer.WriteVarInt(value.Length); + writer.Write(value); + } + + /// + /// Writes an integer into a . + /// + /// The for writing data. + /// The integer to be written. + public static void WriteVarInt(this BinaryWriter writer, long value) + { + if (value < 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (value < 0xFD) + { + writer.Write((byte)value); + } + else if (value <= 0xFFFF) + { + writer.Write((byte)0xFD); + writer.Write((ushort)value); + } + else if (value <= 0xFFFFFFFF) + { + writer.Write((byte)0xFE); + writer.Write((uint)value); + } + else + { + writer.Write((byte)0xFF); + writer.Write(value); + } + } + + /// + /// Writes a into a . + /// + /// The for writing data. + /// The to be written. + public static void WriteVarString(this BinaryWriter writer, string value) + { + writer.WriteVarBytes(Utility.StrictUTF8.GetBytes(value)); + } + } +} diff --git a/src/Neo/Extensions/IO/ISerializableExtensions.cs b/src/Neo/Extensions/IO/ISerializableExtensions.cs new file mode 100644 index 0000000000..67b4f39519 --- /dev/null +++ b/src/Neo/Extensions/IO/ISerializableExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ISerializableExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; +using System.IO; + +namespace Neo.Extensions +{ + public static class ISerializableExtensions + { + /// + /// Converts an object to a byte array. + /// + /// The object to be converted. + /// The converted byte array. + public static byte[] ToArray(this ISerializable value) + { + using MemoryStream ms = new(); + using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); + value.Serialize(writer); + writer.Flush(); + return ms.ToArray(); + } + } +} diff --git a/src/Neo/Extensions/IO/MemoryReaderExtensions.cs b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs new file mode 100644 index 0000000000..5591724b80 --- /dev/null +++ b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs @@ -0,0 +1,70 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// MemoryReaderExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO; + +namespace Neo.Extensions +{ + /// + /// A helper class for serialization of NEO objects. + /// + public static class MemoryReaderExtensions + { + /// + /// Reads an array from a . + /// + /// The type of the array element. + /// The for reading data. + /// The maximum number of elements in the array. + /// The array read from the . + public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) + where T : class, ISerializable, new() + { + var array = new T[reader.ReadVarInt((ulong)max)]; + for (var i = 0; i < array.Length; i++) + array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null; + return array; + } + + /// + /// Reads an object from a . + /// + /// The type of the object. + /// The for reading data. + /// The object read from the . + public static T ReadSerializable(this ref MemoryReader reader) + where T : ISerializable, new() + { + T obj = new(); + obj.Deserialize(ref reader); + return obj; + } + + /// + /// Reads an array from a . + /// + /// The type of the array element. + /// The for reading data. + /// The maximum number of elements in the array. + /// The array read from the . + public static T[] ReadSerializableArray(this ref MemoryReader reader, int max = 0x1000000) + where T : ISerializable, new() + { + var array = new T[reader.ReadVarInt((ulong)max)]; + for (var i = 0; i < array.Length; i++) + { + array[i] = new T(); + array[i].Deserialize(ref reader); + } + return array; + } + } +} diff --git a/src/Neo/Extensions/MemoryExtensions.cs b/src/Neo/Extensions/MemoryExtensions.cs index f6576387de..c1331a5998 100644 --- a/src/Neo/Extensions/MemoryExtensions.cs +++ b/src/Neo/Extensions/MemoryExtensions.cs @@ -17,6 +17,20 @@ namespace Neo.Extensions { public static class MemoryExtensions { + /// + /// Converts a byte array to an array. + /// + /// The type of the array element. + /// The byte array to be converted. + /// The maximum number of elements contained in the converted array. + /// The converted array. + public static T[] AsSerializableArray(this ReadOnlyMemory value, int max = 0x1000000) where T : ISerializable, new() + { + if (value.IsEmpty) throw new FormatException(); + MemoryReader reader = new(value); + return reader.ReadSerializableArray(max); + } + /// /// Converts a byte array to an object. /// diff --git a/src/Neo/Extensions/SpanExtensions.cs b/src/Neo/Extensions/SpanExtensions.cs new file mode 100644 index 0000000000..03b5205738 --- /dev/null +++ b/src/Neo/Extensions/SpanExtensions.cs @@ -0,0 +1,71 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// SpanExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using K4os.Compression.LZ4; +using System; +using System.Buffers.Binary; + +namespace Neo.Extensions +{ + public static class SpanExtensions + { + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this byte[] data) + { + return CompressLz4(data.AsSpan()); + } + + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) + { + var maxLength = LZ4Codec.MaximumOutputSize(data.Length); + var buffer = new byte[sizeof(uint) + maxLength]; + BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); + var length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); + return buffer.AsMemory(0, sizeof(uint) + length); + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this byte[] data, int maxOutput) + { + return DecompressLz4(data.AsSpan(), maxOutput); + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) + { + var length = BinaryPrimitives.ReadInt32LittleEndian(data); + if (length < 0 || length > maxOutput) throw new FormatException(); + var result = new byte[length]; + if (LZ4Codec.Decode(data[4..], result) != length) + throw new FormatException(); + return result; + } + } +} diff --git a/src/Neo/IO/Helper.cs b/src/Neo/IO/Helper.cs deleted file mode 100644 index d0e5a00ec9..0000000000 --- a/src/Neo/IO/Helper.cs +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (C) 2015-2024 The Neo Project. -// -// Helper.cs file belongs to the neo project and is free -// software distributed under the MIT software license, see the -// accompanying file LICENSE in the main directory of the -// repository or http://www.opensource.org/licenses/mit-license.php -// for more details. -// -// Redistribution and use in source and binary forms with or without -// modifications are permitted. - -using K4os.Compression.LZ4; -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; - -namespace Neo.IO -{ - /// - /// A helper class for serialization of NEO objects. - /// - public static class Helper - { - /// - /// Converts a byte array to an object. - /// - /// The type to convert to. - /// The byte array to be converted. - /// The offset into the byte array from which to begin using data. - /// The converted object. - public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable, new() - { - MemoryReader reader = new(value.AsMemory(start)); - return reader.ReadSerializable(); - } - - /// - /// Converts a byte array to an array. - /// - /// The type of the array element. - /// The byte array to be converted. - /// The maximum number of elements contained in the converted array. - /// The converted array. - public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable, new() - { - MemoryReader reader = new(value); - return reader.ReadSerializableArray(max); - } - - /// - /// Converts a byte array to an array. - /// - /// The type of the array element. - /// The byte array to be converted. - /// The maximum number of elements contained in the converted array. - /// The converted array. - public static T[] AsSerializableArray(this ReadOnlyMemory value, int max = 0x1000000) where T : ISerializable, new() - { - if (value.IsEmpty) throw new FormatException(); - MemoryReader reader = new(value); - return reader.ReadSerializableArray(max); - } - - /// - /// Compresses the specified data using the LZ4 algorithm. - /// - /// The data to be compressed. - /// The compressed data. - public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) - { - int maxLength = LZ4Codec.MaximumOutputSize(data.Length); - byte[] buffer = new byte[sizeof(uint) + maxLength]; - BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); - int length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); - return buffer.AsMemory(0, sizeof(uint) + length); - } - - /// - /// Decompresses the specified data using the LZ4 algorithm. - /// - /// The compressed data. - /// The maximum data size after decompression. - /// The original data. - public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) - { - int length = BinaryPrimitives.ReadInt32LittleEndian(data); - if (length < 0 || length > maxOutput) throw new FormatException(); - byte[] result = new byte[length]; - if (LZ4Codec.Decode(data[4..], result) != length) - throw new FormatException(); - return result; - } - - /// - /// Reads a byte array of the specified size from a . - /// - /// The for reading data. - /// The size of the byte array. - /// The byte array read from the . - public static byte[] ReadFixedBytes(this BinaryReader reader, int size) - { - var index = 0; - var data = new byte[size]; - - while (size > 0) - { - var bytesRead = reader.Read(data, index, size); - - if (bytesRead <= 0) - { - throw new FormatException(); - } - - size -= bytesRead; - index += bytesRead; - } - - return data; - } - - /// - /// Reads an array from a . - /// - /// The type of the array element. - /// The for reading data. - /// The maximum number of elements in the array. - /// The array read from the . - public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) where T : class, ISerializable, new() - { - T[] array = new T[reader.ReadVarInt((ulong)max)]; - for (int i = 0; i < array.Length; i++) - array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null; - return array; - } - - /// - /// Reads an object from a . - /// - /// The type of the object. - /// The for reading data. - /// The object read from the . - public static T ReadSerializable(this ref MemoryReader reader) where T : ISerializable, new() - { - T obj = new(); - obj.Deserialize(ref reader); - return obj; - } - - /// - /// Reads an array from a . - /// - /// The type of the array element. - /// The for reading data. - /// The maximum number of elements in the array. - /// The array read from the . - public static T[] ReadSerializableArray(this ref MemoryReader reader, int max = 0x1000000) where T : ISerializable, new() - { - T[] array = new T[reader.ReadVarInt((ulong)max)]; - for (int i = 0; i < array.Length; i++) - { - array[i] = new T(); - array[i].Deserialize(ref reader); - } - return array; - } - - /// - /// Reads a byte array from a . - /// - /// The for reading data. - /// The maximum size of the byte array. - /// The byte array read from the . - public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x1000000) - { - return reader.ReadFixedBytes((int)reader.ReadVarInt((ulong)max)); - } - - /// - /// Reads an integer from a . - /// - /// The for reading data. - /// The maximum value of the integer. - /// The integer read from the . - public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) - { - byte fb = reader.ReadByte(); - ulong value; - if (fb == 0xFD) - value = reader.ReadUInt16(); - else if (fb == 0xFE) - value = reader.ReadUInt32(); - else if (fb == 0xFF) - value = reader.ReadUInt64(); - else - value = fb; - if (value > max) throw new FormatException(); - return value; - } - - /// - /// Converts an object to a byte array. - /// - /// The object to be converted. - /// The converted byte array. - public static byte[] ToArray(this ISerializable value) - { - using MemoryStream ms = new(); - using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); - value.Serialize(writer); - writer.Flush(); - return ms.ToArray(); - } - - /// - /// Writes an object into a . - /// - /// The for writing data. - /// The object to be written. - public static void Write(this BinaryWriter writer, ISerializable value) - { - value.Serialize(writer); - } - - /// - /// Writes an array into a . - /// - /// The type of the array element. - /// The for writing data. - /// The array to be written. - public static void Write(this BinaryWriter writer, IReadOnlyCollection value) where T : ISerializable - { - writer.WriteVarInt(value.Count); - foreach (T item in value) - { - item.Serialize(writer); - } - } - - /// - /// Writes a into a . - /// - /// The for writing data. - /// The to be written. - /// The fixed size of the . - public static void WriteFixedString(this BinaryWriter writer, string value, int length) - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - if (value.Length > length) - throw new ArgumentException(null, nameof(value)); - byte[] bytes = Utility.StrictUTF8.GetBytes(value); - if (bytes.Length > length) - throw new ArgumentException(null, nameof(value)); - writer.Write(bytes); - if (bytes.Length < length) - writer.Write(stackalloc byte[length - bytes.Length]); - } - - /// - /// Writes an array into a . - /// - /// The type of the array element. - /// The for writing data. - /// The array to be written. - public static void WriteNullableArray(this BinaryWriter writer, T[] value) where T : class, ISerializable - { - writer.WriteVarInt(value.Length); - foreach (var item in value) - { - bool isNull = item is null; - writer.Write(!isNull); - if (isNull) continue; - item.Serialize(writer); - } - } - - /// - /// Writes a byte array into a . - /// - /// The for writing data. - /// The byte array to be written. - public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan value) - { - writer.WriteVarInt(value.Length); - writer.Write(value); - } - - /// - /// Writes an integer into a . - /// - /// The for writing data. - /// The integer to be written. - public static void WriteVarInt(this BinaryWriter writer, long value) - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (value < 0xFD) - { - writer.Write((byte)value); - } - else if (value <= 0xFFFF) - { - writer.Write((byte)0xFD); - writer.Write((ushort)value); - } - else if (value <= 0xFFFFFFFF) - { - writer.Write((byte)0xFE); - writer.Write((uint)value); - } - else - { - writer.Write((byte)0xFF); - writer.Write(value); - } - } - - /// - /// Writes a into a . - /// - /// The for writing data. - /// The to be written. - public static void WriteVarString(this BinaryWriter writer, string value) - { - writer.WriteVarBytes(Utility.StrictUTF8.GetBytes(value)); - } - } -} diff --git a/src/Neo/Network/P2P/Helper.cs b/src/Neo/Network/P2P/Helper.cs index f171a7b0a3..ffbbc6a702 100644 --- a/src/Neo/Network/P2P/Helper.cs +++ b/src/Neo/Network/P2P/Helper.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs index f853743b72..a4b1b7c20a 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index 82dab60fcf..52aaa8033a 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index ee937aff8b..95e9747cc9 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs index 83ecd4d973..8bf90454b0 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs index 9199e1a9a2..de18bdfd1d 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Neo/Network/P2P/Payloads/Conflicts.cs b/src/Neo/Network/P2P/Payloads/Conflicts.cs index 082de2014d..a876468828 100644 --- a/src/Neo/Network/P2P/Payloads/Conflicts.cs +++ b/src/Neo/Network/P2P/Payloads/Conflicts.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Persistence; diff --git a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs index d12c8ae2cd..ccff8206c2 100644 --- a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs +++ b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Neo/Network/P2P/Payloads/Header.cs b/src/Neo/Network/P2P/Payloads/Header.cs index 9e1d77fb8a..8b3eda0e28 100644 --- a/src/Neo/Network/P2P/Payloads/Header.cs +++ b/src/Neo/Network/P2P/Payloads/Header.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index 3bac09e7f5..bb75cefd40 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads.Conditions; diff --git a/src/Neo/Network/P2P/RemoteNode.cs b/src/Neo/Network/P2P/RemoteNode.cs index a4bf0cc089..e570afeb13 100644 --- a/src/Neo/Network/P2P/RemoteNode.cs +++ b/src/Neo/Network/P2P/RemoteNode.cs @@ -13,6 +13,7 @@ using Akka.Configuration; using Akka.IO; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.IO.Actors; using Neo.IO.Caching; diff --git a/src/Neo/Persistence/SnapshotCache.cs b/src/Neo/Persistence/SnapshotCache.cs index 6731e5342f..07afdccfab 100644 --- a/src/Neo/Persistence/SnapshotCache.cs +++ b/src/Neo/Persistence/SnapshotCache.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using System; using System.Collections.Generic; diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index fab17a2bb1..5f319f7562 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/src/Neo/SmartContract/BinarySerializer.cs b/src/Neo/SmartContract/BinarySerializer.cs index 2bdeced678..29c33fee39 100644 --- a/src/Neo/SmartContract/BinarySerializer.cs +++ b/src/Neo/SmartContract/BinarySerializer.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index 5b413c41a4..c323028346 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.SmartContract.Manifest; using Neo.VM; diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index 231354327c..ffadf80769 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -11,7 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index 44c67fd9a1..429b195b87 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs index d950d25c62..6cebaa99ee 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.VM.Types; using System; diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index c533f029a6..ac0896a6c8 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -11,7 +11,7 @@ #pragma warning disable IDE0051 -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract.Iterators; diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index 4ab0f01589..33e98e8704 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.SmartContract.Manifest; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index 229458ffdd..bca7fb28ac 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 13a7264660..7c6785d5a3 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -12,7 +12,7 @@ #pragma warning disable IDE0051 using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.VM; diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index d18968ef00..2114ad301d 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.VM; using Neo.VM.Types; using Array = Neo.VM.Types.Array; diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index 6e989b78cf..6ee953e843 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 257efb3a66..9c88290c6d 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.VM; using Neo.VM.Types; diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 4a82041ea5..c656e7f3d1 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.SmartContract; diff --git a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs index 147a80034b..433359e261 100644 --- a/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs +++ b/src/Plugins/ApplicationLogs/Store/LogStorageStore.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.Plugins.ApplicationLogs.Store.States; using Neo.SmartContract; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs index abd0309783..a2792584bd 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs @@ -11,6 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs index b4608ff9af..3c49693c69 100644 --- a/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs +++ b/src/Plugins/DBFTPlugin/Messages/PrepareResponse.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Plugins.DBFTPlugin.Types; using System.IO; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs index d8baef8529..e832e8994b 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Cache.cs @@ -9,7 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using System.Collections.Generic; using System.IO; diff --git a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs index e0190dd146..dc58535fb3 100644 --- a/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs +++ b/src/Plugins/MPTTrie/Cryptography/MPTTrie/Node.Hash.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/RpcServer/RpcServer.Node.cs b/src/Plugins/RpcServer/RpcServer.Node.cs index 79a8884a0f..0bb0fbc981 100644 --- a/src/Plugins/RpcServer/RpcServer.Node.cs +++ b/src/Plugins/RpcServer/RpcServer.Node.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Akka.Actor; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P; diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs index 9083f916c6..6a2c9cb2ae 100644 --- a/src/Plugins/RpcServer/RpcServer.Wallet.cs +++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Akka.Actor; -using Neo.IO; +using Neo.Extensions; using Neo.Json; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/src/Plugins/SQLiteWallet/SQLiteWallet.cs b/src/Plugins/SQLiteWallet/SQLiteWallet.cs index a4004dcff0..65f86ea8ff 100644 --- a/src/Plugins/SQLiteWallet/SQLiteWallet.cs +++ b/src/Plugins/SQLiteWallet/SQLiteWallet.cs @@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore; using Neo.Cryptography; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using Neo.Wallets.NEP6; using System.Buffers.Binary; diff --git a/src/Plugins/StateService/Network/StateRoot.cs b/src/Plugins/StateService/Network/StateRoot.cs index 5b4e8610f2..7b3b7e9706 100644 --- a/src/Plugins/StateService/Network/StateRoot.cs +++ b/src/Plugins/StateService/Network/StateRoot.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P; diff --git a/src/Plugins/StateService/StatePlugin.cs b/src/Plugins/StateService/StatePlugin.cs index 03dcc55aac..a514f22ce7 100644 --- a/src/Plugins/StateService/StatePlugin.cs +++ b/src/Plugins/StateService/StatePlugin.cs @@ -12,8 +12,8 @@ using Akka.Actor; using Neo.ConsoleService; using Neo.Cryptography.MPTTrie; +using Neo.Extensions; using Neo.IEventHandlers; -using Neo.IO; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/StateService/Storage/StateSnapshot.cs b/src/Plugins/StateService/Storage/StateSnapshot.cs index 70ec006227..6dc1b323fd 100644 --- a/src/Plugins/StateService/Storage/StateSnapshot.cs +++ b/src/Plugins/StateService/Storage/StateSnapshot.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.MPTTrie; -using Neo.IO; +using Neo.Extensions; using Neo.Persistence; using Neo.Plugins.StateService.Network; using System; diff --git a/src/Plugins/StorageDumper/StorageDumper.cs b/src/Plugins/StorageDumper/StorageDumper.cs index 6f5498b3a2..184b6f61ac 100644 --- a/src/Plugins/StorageDumper/StorageDumper.cs +++ b/src/Plugins/StorageDumper/StorageDumper.cs @@ -10,8 +10,8 @@ // modifications are permitted. using Neo.ConsoleService; +using Neo.Extensions; using Neo.IEventHandlers; -using Neo.IO; using Neo.Json; using Neo.Ledger; using Neo.Network.P2P.Payloads; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs index 1f375f33d9..2965985653 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11BalanceKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM.Types; using System; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs index 5c999e8e00..9248267785 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-11/Nep11TransferKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.VM.Types; using System; diff --git a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs index bbceabec2b..817d789e5c 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17BalanceKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.IO; diff --git a/src/Plugins/TokensTracker/Trackers/TokenBalance.cs b/src/Plugins/TokensTracker/Trackers/TokenBalance.cs index f54a7c9856..a171fa40d7 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenBalance.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenBalance.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.IO; using System.Numerics; diff --git a/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs b/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs index 0a221850fc..9bb389b516 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenTransfer.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System.IO; using System.Numerics; diff --git a/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs b/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs index 252eb20af0..3c59131749 100644 --- a/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs +++ b/src/Plugins/TokensTracker/Trackers/TokenTransferKey.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using System; using System.Buffers.Binary; diff --git a/src/Plugins/TokensTracker/Trackers/TrackerBase.cs b/src/Plugins/TokensTracker/Trackers/TrackerBase.cs index 471362b019..40009e6d85 100644 --- a/src/Plugins/TokensTracker/Trackers/TrackerBase.cs +++ b/src/Plugins/TokensTracker/Trackers/TrackerBase.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index 4af0f557e3..ea2b0f4237 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Moq.Protected; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs index 5fd37b2bc3..3293072e09 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs +++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Blockchain.cs @@ -11,6 +11,7 @@ using Akka.Util.Internal; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; diff --git a/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs b/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs index f8a6b19b34..edcea4dd75 100644 --- a/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs +++ b/tests/Neo.UnitTests/Cryptography/UT_MerkleTree.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using System; using System.Collections; diff --git a/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs b/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs index 5235b99c70..7303bc5d14 100644 --- a/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs +++ b/tests/Neo.UnitTests/IO/Caching/UT_DataCache.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index 9158cf2b1d..2c7a1ef09f 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -31,7 +31,7 @@ public void TestAsSerializableGeneric() 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00 }; - UInt160 result = Neo.IO.Helper.AsSerializable(caseArray); + UInt160 result = caseArray.AsSerializable(); Assert.AreEqual(UInt160.Zero, result); } @@ -44,7 +44,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - byte[] result = Neo.IO.Helper.ReadFixedBytes(reader, 3); + byte[] result = reader.ReadFixedBytes(3); Assert.AreEqual("010203", result.ToHexString()); Assert.AreEqual(3, reader.BaseStream.Position); @@ -54,7 +54,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - byte[] result = Neo.IO.Helper.ReadFixedBytes(reader, 4); + byte[] result = reader.ReadFixedBytes(4); Assert.AreEqual("01020304", result.ToHexString()); Assert.AreEqual(4, reader.BaseStream.Position); @@ -64,7 +64,7 @@ public void TestReadFixedBytes() using (BinaryReader reader = new(new MemoryStream(data), Encoding.UTF8, false)) { - Assert.ThrowsException(() => Neo.IO.Helper.ReadFixedBytes(reader, 5)); + Assert.ThrowsException(() => reader.ReadFixedBytes(5)); Assert.AreEqual(4, reader.BaseStream.Position); } } @@ -87,7 +87,7 @@ public void TestNullableArray() using (MemoryStream stream = new()) using (BinaryWriter writter = new(stream)) { - Neo.IO.Helper.WriteNullableArray(writter, caseArray); + writter.WriteNullableArray(caseArray); data = stream.ToArray(); } @@ -103,7 +103,7 @@ public void TestNullableArray() // Read 100% MemoryReader reader = new(data); - var read = Neo.IO.Helper.ReadNullableArray(ref reader); + var read = reader.ReadNullableArray(); CollectionAssert.AreEqual(caseArray, read); } @@ -138,8 +138,8 @@ public void TestAsSerializable() public void TestCompression() { var data = new byte[] { 1, 2, 3, 4 }; - var byteArray = Neo.IO.Helper.CompressLz4(data); - var result = Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue); + var byteArray = data.CompressLz4(); + var result = byteArray.Span.DecompressLz4(byte.MaxValue); CollectionAssert.AreEqual(result, data); @@ -148,29 +148,29 @@ public void TestCompression() data = new byte[255]; for (int x = 0; x < data.Length; x++) data[x] = 1; - byteArray = Neo.IO.Helper.CompressLz4(data); - result = Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue); + byteArray = data.CompressLz4(); + result = byteArray.Span.DecompressLz4(byte.MaxValue); Assert.IsTrue(byteArray.Length < result.Length); CollectionAssert.AreEqual(result, data); // Error max length - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray.Span, byte.MaxValue - 1)); - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray.Span, -1)); + Assert.ThrowsException(() => byteArray.Span.DecompressLz4(byte.MaxValue - 1)); + Assert.ThrowsException(() => byteArray.Span.DecompressLz4(-1)); // Error length byte[] data_wrong = byteArray.ToArray(); data_wrong[0]++; - Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(data_wrong, byte.MaxValue)); + Assert.ThrowsException(() => data_wrong.DecompressLz4(byte.MaxValue)); } [TestMethod] public void TestAsSerializableArray() { byte[] byteArray = new UInt160[] { UInt160.Zero }.ToByteArray(); - UInt160[] result = Neo.IO.Helper.AsSerializableArray(byteArray); + UInt160[] result = byteArray.AsSerializableArray(); Assert.AreEqual(1, result.Length); Assert.AreEqual(UInt160.Zero, result[0]); } @@ -337,9 +337,9 @@ public void TestReadSerializable() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, UInt160.Zero); + writer.Write(UInt160.Zero); MemoryReader reader = new(stream.ToArray()); - UInt160 result = Neo.IO.Helper.ReadSerializable(ref reader); + UInt160 result = reader.ReadSerializable(); Assert.AreEqual(UInt160.Zero, result); } @@ -348,9 +348,9 @@ public void TestReadSerializableArray() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, new UInt160[] { UInt160.Zero }); + writer.Write(new UInt160[] { UInt160.Zero }); MemoryReader reader = new(stream.ToArray()); - UInt160[] resultArray = Neo.IO.Helper.ReadSerializableArray(ref reader); + UInt160[] resultArray = reader.ReadSerializableArray(); Assert.AreEqual(1, resultArray.Length); Assert.AreEqual(UInt160.Zero, resultArray[0]); } @@ -360,10 +360,10 @@ public void TestReadVarBytes() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarBytes(writer, new byte[] { 0xAA, 0xAA }); + writer.WriteVarBytes(new byte[] { 0xAA, 0xAA }); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - byte[] byteArray = Neo.IO.Helper.ReadVarBytes(reader, 10); + byte[] byteArray = reader.ReadVarBytes(10); Assert.AreEqual(Encoding.Default.GetString(new byte[] { 0xAA, 0xAA }), Encoding.Default.GetString(byteArray)); } @@ -376,30 +376,30 @@ public void TestReadVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFF); + writer.WriteVarInt(0xFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - ulong result = Neo.IO.Helper.ReadVarInt(reader, 0xFFFF); + ulong result = reader.ReadVarInt(0xFFFF); Assert.AreEqual((ulong)0xFFFF, result); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - ulong result = Neo.IO.Helper.ReadVarInt(reader, 0xFFFFFFFF); + ulong result = reader.ReadVarInt(0xFFFFFFFF); Assert.AreEqual(0xFFFFFFFF, result); } else { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new(stream); - Action action = () => Neo.IO.Helper.ReadVarInt(reader, 0xFFFFFFFF); + Action action = () => reader.ReadVarInt(0xFFFFFFFF); action.Should().Throw(); } } @@ -408,7 +408,7 @@ public void TestReadVarInt() [TestMethod] public void TestToArray() { - byte[] byteArray = Neo.IO.Helper.ToArray(UInt160.Zero); + byte[] byteArray = UInt160.Zero.ToArray(); Assert.AreEqual(Encoding.Default.GetString(new byte[] { 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, @@ -430,7 +430,7 @@ public void TestWrite() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, UInt160.Zero); + writer.Write(UInt160.Zero); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -445,7 +445,7 @@ public void TestWriteGeneric() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.Write(writer, new UInt160[] { UInt160.Zero }); + writer.Write(new UInt160[] { UInt160.Zero }); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -464,28 +464,28 @@ public void TestWriteFixedString() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, null, 0); + Action action = () => writer.WriteFixedString(null, 0); action.Should().Throw(); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, "AA", Encoding.UTF8.GetBytes("AA").Length - 1); + Action action = () => writer.WriteFixedString("AA", Encoding.UTF8.GetBytes("AA").Length - 1); action.Should().Throw(); } else if (i == 2) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteFixedString(writer, "拉拉", Encoding.UTF8.GetBytes("拉拉").Length - 1); + Action action = () => writer.WriteFixedString("拉拉", Encoding.UTF8.GetBytes("拉拉").Length - 1); action.Should().Throw(); } else if (i == 3) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteFixedString(writer, "AA", Encoding.UTF8.GetBytes("AA").Length + 1); + writer.WriteFixedString("AA", Encoding.UTF8.GetBytes("AA").Length + 1); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -501,7 +501,7 @@ public void TestWriteVarBytes() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarBytes(writer, new byte[] { 0xAA }); + writer.WriteVarBytes(new byte[] { 0xAA }); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -517,14 +517,14 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Action action = () => Neo.IO.Helper.WriteVarInt(writer, -1); + Action action = () => writer.WriteVarInt(-1); action.Should().Throw(); } else if (i == 1) { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFC); + writer.WriteVarInt(0xFC); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -534,7 +534,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFF); + writer.WriteVarInt(0xFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -545,7 +545,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xFFFFFFFF); + writer.WriteVarInt(0xFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -556,7 +556,7 @@ public void TestWriteVarInt() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarInt(writer, 0xAEFFFFFFFF); + writer.WriteVarInt(0xAEFFFFFFFF); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); @@ -571,7 +571,7 @@ public void TestWriteVarString() { MemoryStream stream = new(); BinaryWriter writer = new(stream); - Neo.IO.Helper.WriteVarString(writer, "a"); + writer.WriteVarString("a"); stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; stream.Read(byteArray, 0, (int)stream.Length); diff --git a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs index c3c5c2c86f..fbb2ca5106 100644 --- a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs +++ b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_FullNodeCapability.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; diff --git a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs index b113d59da7..cb538771dc 100644 --- a/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs +++ b/tests/Neo.UnitTests/Network/P2P/Capabilities/UT_ServerCapability.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Capabilities; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs index 6e189ad3ec..1308909d73 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_AddrPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs index ce46c5106d..f9a78d8e1a 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index 1a0ad19a9a..28fdcaf068 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs index 76eff8e198..ae5a0e7758 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterAddPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs index f73e9b5595..0661649215 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_FilterLoadPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs index 3aa4049d87..5859d974ce 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlockByIndexPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs index 6752525ac0..ccd4e7aaed 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_GetBlocksPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs index 2ac486ef06..d226294919 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HeadersPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs index 76808072d5..b9dbacde85 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs index 4735fddfe1..c799ff8289 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_InvPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs index f491d46749..b1849f1332 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_MerkleBlockPayload.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using System; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs index 8e7ad9087b..01ee23f5d6 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index ffd70e354e..b869ced106 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; using Neo.Extensions; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Ledger; @@ -827,7 +828,7 @@ public void Transaction_Serialize_Deserialize_Simple() "010000"); // empty witnesses // try to deserialize - Transaction tx2 = Neo.IO.Helper.AsSerializable(sTx); + Transaction tx2 = sTx.AsSerializable(); tx2.Version.Should().Be(0x00); tx2.Nonce.Should().Be(0x01020304); @@ -889,7 +890,7 @@ public void Transaction_Serialize_Deserialize_DistinctCosigners() // back to transaction (should fail, due to non-distinct cosigners) Transaction tx2 = null; Assert.ThrowsException(() => - tx2 = Neo.IO.Helper.AsSerializable(sTx) + tx2 = sTx.AsSerializable() ); Assert.IsNull(tx2); } @@ -934,7 +935,7 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners() byte[] sTx1 = txCosigners1.ToArray(); // back to transaction (should fail, due to non-distinct cosigners) - Assert.ThrowsException(() => Neo.IO.Helper.AsSerializable(sTx1)); + Assert.ThrowsException(() => sTx1.AsSerializable()); // ---------------------------- // this should fail (max + 1) @@ -969,7 +970,7 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners() // back to transaction (should fail, due to non-distinct cosigners) Transaction tx2 = null; Assert.ThrowsException(() => - tx2 = Neo.IO.Helper.AsSerializable(sTx2) + tx2 = sTx2.AsSerializable() ); Assert.IsNull(tx2); } diff --git a/tests/Neo.UnitTests/Network/P2P/UT_Message.cs b/tests/Neo.UnitTests/Network/P2P/UT_Message.cs index 35f99fc44f..7a43cf89a4 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_Message.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_Message.cs @@ -12,6 +12,7 @@ using Akka.IO; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs b/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs index 9f114e2708..cfa94a3113 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_RemoteNode.cs @@ -13,6 +13,7 @@ using Akka.TestKit.Xunit2; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P; using Neo.Network.P2P.Capabilities; diff --git a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs index 4cddf07e65..587c5ddcfc 100644 --- a/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs +++ b/tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs index 51617b6744..4f4bf49e52 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 703253364c..357783fdb1 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs b/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs index 9d687e1053..b6be60cdab 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_MethodToken.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using System; diff --git a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs index 40142e93be..b5fb90fe22 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.IO; using Neo.SmartContract; using System; diff --git a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs index 76448855d7..d6e1836573 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -12,6 +12,7 @@ using Akka.TestKit.Xunit2; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/TestUtils.cs b/tests/Neo.UnitTests/TestUtils.cs index 55492d882c..2020e7f2a3 100644 --- a/tests/Neo.UnitTests/TestUtils.cs +++ b/tests/Neo.UnitTests/TestUtils.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs b/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs index 843eeae192..055ea193f7 100644 --- a/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs +++ b/tests/Neo.UnitTests/Wallets/UT_Wallets_Helper.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography; +using Neo.Extensions; using Neo.IO; using Neo.Wallets; using System; From 9a8443605cf5a97aef9e2307253459ba041d6c25 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 7 Jul 2024 15:30:25 -0400 Subject: [PATCH 12/18] Move some methods --- src/Neo/Extensions/ByteExtensions.cs | 21 +++++++++++++++++++++ src/Neo/Extensions/SpanExtensions.cs | 21 +++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Neo/Extensions/ByteExtensions.cs b/src/Neo/Extensions/ByteExtensions.cs index a1e7e0f931..fa451008fc 100644 --- a/src/Neo/Extensions/ByteExtensions.cs +++ b/src/Neo/Extensions/ByteExtensions.cs @@ -16,6 +16,27 @@ namespace Neo.Extensions { public static class ByteExtensions2 { + /// + /// Compresses the specified data using the LZ4 algorithm. + /// + /// The data to be compressed. + /// The compressed data. + public static ReadOnlyMemory CompressLz4(this byte[] data) + { + return data.AsSpan().CompressLz4(); + } + + /// + /// Decompresses the specified data using the LZ4 algorithm. + /// + /// The compressed data. + /// The maximum data size after decompression. + /// The original data. + public static byte[] DecompressLz4(this byte[] data, int maxOutput) + { + return data.AsSpan().DecompressLz4(maxOutput); + } + /// /// Converts a byte array to an object. /// diff --git a/src/Neo/Extensions/SpanExtensions.cs b/src/Neo/Extensions/SpanExtensions.cs index 03b5205738..3bc650cbb8 100644 --- a/src/Neo/Extensions/SpanExtensions.cs +++ b/src/Neo/Extensions/SpanExtensions.cs @@ -22,9 +22,13 @@ public static class SpanExtensions /// /// The data to be compressed. /// The compressed data. - public static ReadOnlyMemory CompressLz4(this byte[] data) + public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) { - return CompressLz4(data.AsSpan()); + var maxLength = LZ4Codec.MaximumOutputSize(data.Length); + var buffer = new byte[sizeof(uint) + maxLength]; + BinaryPrimitives.WriteInt32LittleEndian(buffer, data.Length); + var length = LZ4Codec.Encode(data, buffer.AsSpan(sizeof(uint))); + return buffer.AsMemory(0, sizeof(uint) + length); } /// @@ -32,7 +36,7 @@ public static ReadOnlyMemory CompressLz4(this byte[] data) /// /// The data to be compressed. /// The compressed data. - public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) + public static ReadOnlyMemory CompressLz4(this Span data) { var maxLength = LZ4Codec.MaximumOutputSize(data.Length); var buffer = new byte[sizeof(uint) + maxLength]; @@ -47,9 +51,14 @@ public static ReadOnlyMemory CompressLz4(this ReadOnlySpan data) /// The compressed data. /// The maximum data size after decompression. /// The original data. - public static byte[] DecompressLz4(this byte[] data, int maxOutput) + public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) { - return DecompressLz4(data.AsSpan(), maxOutput); + var length = BinaryPrimitives.ReadInt32LittleEndian(data); + if (length < 0 || length > maxOutput) throw new FormatException(); + var result = new byte[length]; + if (LZ4Codec.Decode(data[4..], result) != length) + throw new FormatException(); + return result; } /// @@ -58,7 +67,7 @@ public static byte[] DecompressLz4(this byte[] data, int maxOutput) /// The compressed data. /// The maximum data size after decompression. /// The original data. - public static byte[] DecompressLz4(this ReadOnlySpan data, int maxOutput) + public static byte[] DecompressLz4(this Span data, int maxOutput) { var length = BinaryPrimitives.ReadInt32LittleEndian(data); if (length < 0 || length > maxOutput) throw new FormatException(); From b64435bfb5fcd974dbf91fe74c6031bb6fe922af Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 9 Jul 2024 14:14:03 -0400 Subject: [PATCH 13/18] Added Tests --- .github/workflows/main.yml | 2 + neo.sln | 7 +++ src/Neo.Extensions/BigIntegerExtensions.cs | 8 ++-- .../Neo.Extensions.Tests.csproj | 23 +++++++++ .../UT_BigIntegerExtensions.cs | 48 +++++++++++++++++++ tests/Neo.UnitTests/UT_Helper.cs | 10 ---- 6 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj create mode 100644 tests/Neo.Extensions.Tests/UT_BigIntegerExtensions.cs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5f315dd27..d634e15afb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -81,6 +81,7 @@ jobs: dotnet test ./tests/Neo.UnitTests --output ./bin/tests/Neo.UnitTests dotnet test ./tests/Neo.VM.Tests --output ./bin/tests/Neo.VM.Tests dotnet test ./tests/Neo.Json.UnitTests --output ./bin/tests/Neo.Json.UnitTests + dotnet test ./tests/Neo.Extensions.Tests --output ./bin/tests/Neo.Extensions.Tests # Plugins dotnet test ./tests/Neo.Cryptography.MPTTrie.Tests --output ./bin/tests/Neo.Cryptography.MPTTrie.Tests @@ -105,6 +106,7 @@ jobs: ${{ github.workspace }}/tests/Neo.Plugins.OracleService.Tests/TestResults/coverage.info ${{ github.workspace }}/tests/Neo.Plugins.RpcServer.Tests/TestResults/coverage.info ${{ github.workspace }}/tests/Neo.Plugins.Storage.Tests/TestResults/coverage.info + ${{ github.workspace }}/tests/Neo.Extensions.Tests/TestResults/coverage.info PublishPackage: if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') diff --git a/neo.sln b/neo.sln index b0de1c27b1..5d55b0d785 100644 --- a/neo.sln +++ b/neo.sln @@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokensTracker", "src\Plugin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcClient", "src\Plugins\RpcClient\RpcClient.csproj", "{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Extensions.Tests", "tests\Neo.Extensions.Tests\Neo.Extensions.Tests.csproj", "{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -216,6 +218,10 @@ Global {185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU {185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU {185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0}.Release|Any CPU.Build.0 = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -255,6 +261,7 @@ Global {FF76D8A4-356B-461A-8471-BC1B83E57BBC} = {C2DC830A-327A-42A7-807D-295216D30DBB} {5E4947F3-05D3-4806-B0F3-30DAC71B5986} = {C2DC830A-327A-42A7-807D-295216D30DBB} {185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0} = {C2DC830A-327A-42A7-807D-295216D30DBB} + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC} diff --git a/src/Neo.Extensions/BigIntegerExtensions.cs b/src/Neo.Extensions/BigIntegerExtensions.cs index 6856a2a426..38a0e60bb5 100644 --- a/src/Neo.Extensions/BigIntegerExtensions.cs +++ b/src/Neo.Extensions/BigIntegerExtensions.cs @@ -18,7 +18,7 @@ namespace Neo.Extensions { public static class BigIntegerExtensions { - internal static int GetLowestSetBit(this BigInteger i) + public static int GetLowestSetBit(this BigInteger i) { if (i.Sign == 0) return -1; @@ -33,7 +33,7 @@ internal static int GetLowestSetBit(this BigInteger i) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static BigInteger Mod(this BigInteger x, BigInteger y) + public static BigInteger Mod(this BigInteger x, BigInteger y) { x %= y; if (x.Sign < 0) @@ -41,7 +41,7 @@ internal static BigInteger Mod(this BigInteger x, BigInteger y) return x; } - internal static BigInteger ModInverse(this BigInteger a, BigInteger n) + public static BigInteger ModInverse(this BigInteger a, BigInteger n) { BigInteger i = n, v = 0, d = 1; while (a > 0) @@ -59,7 +59,7 @@ internal static BigInteger ModInverse(this BigInteger a, BigInteger n) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool TestBit(this BigInteger i, int index) + public static bool TestBit(this BigInteger i, int index) { return (i & (BigInteger.One << index)) > BigInteger.Zero; } diff --git a/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj new file mode 100644 index 0000000000..a2b2b20daf --- /dev/null +++ b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + enable + + + + + + + + + + + + + + + + + + diff --git a/tests/Neo.Extensions.Tests/UT_BigIntegerExtensions.cs b/tests/Neo.Extensions.Tests/UT_BigIntegerExtensions.cs new file mode 100644 index 0000000000..574dd87653 --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_BigIntegerExtensions.cs @@ -0,0 +1,48 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_BigIntegerExtensions.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 Neo.Extensions; +using System.Numerics; + +namespace Neo.Extensions.Tests +{ + [TestClass] + public class UT_BigIntegerExtensions + { + + [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 TestToByteArrayStandard() + { + BigInteger number = BigInteger.Zero; + Assert.AreEqual("", number.ToByteArrayStandard().ToHexString()); + + number = BigInteger.One; + Assert.AreEqual("01", number.ToByteArrayStandard().ToHexString()); + } + } +} diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 3f5ca78c98..7fa3902cba 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -191,16 +191,6 @@ public void TestGetVersion() version.Should().Be("0.0.0"); } - [TestMethod] - public void TestToByteArrayStandard() - { - BigInteger number = BigInteger.Zero; - Assert.AreEqual("", number.ToByteArrayStandard().ToHexString()); - - number = BigInteger.One; - Assert.AreEqual("01", number.ToByteArrayStandard().ToHexString()); - } - [TestMethod] public void TestNextBigIntegerForRandom() { From 58f7fee84a4559af18bb621592bd56cb06ce6a9f Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 9 Jul 2024 14:32:44 -0400 Subject: [PATCH 14/18] Added `tests` from `Part-2` --- .../Neo.Extensions.Tests/UT_ByteExtensions.cs | 37 +++++++++++++++++++ tests/Neo.UnitTests/UT_Helper.cs | 32 ---------------- 2 files changed, 37 insertions(+), 32 deletions(-) create mode 100644 tests/Neo.Extensions.Tests/UT_ByteExtensions.cs 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.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() { From e644bd3460224d427aa5ac42451f9a87d86457b6 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 9 Jul 2024 14:56:02 -0400 Subject: [PATCH 15/18] Added `tests` for `PART-4` --- .../Collections/HashSetExtensions.cs | 4 +- src/Neo.Extensions/Net/IpAddressExtensions.cs | 4 +- src/Neo.IO/Neo.IO.csproj | 1 + .../Collections/UT_HashSetExtensions.cs | 75 ++++++++++++ .../Neo.Extensions.Tests.csproj | 1 - .../Net/UT_IpAddressExtensions.cs | 43 +++++++ .../UT_AssemblyExtensions.cs | 33 +++++ .../UT_DateTimeExtensions.cs | 42 +++++++ .../UT_RandomExtensions.cs | 32 +++++ .../UT_StringExtensions.cs | 39 ++++++ tests/Neo.UnitTests/UT_Helper.cs | 115 ------------------ 11 files changed, 269 insertions(+), 120 deletions(-) create mode 100644 tests/Neo.Extensions.Tests/Collections/UT_HashSetExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/Net/UT_IpAddressExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/UT_AssemblyExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/UT_DateTimeExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/UT_RandomExtensions.cs create mode 100644 tests/Neo.Extensions.Tests/UT_StringExtensions.cs diff --git a/src/Neo.Extensions/Collections/HashSetExtensions.cs b/src/Neo.Extensions/Collections/HashSetExtensions.cs index 60cb14de42..9cf3f13b23 100644 --- a/src/Neo.Extensions/Collections/HashSetExtensions.cs +++ b/src/Neo.Extensions/Collections/HashSetExtensions.cs @@ -15,7 +15,7 @@ namespace Neo.Extensions { public static class HashSetExtensions { - internal static void Remove(this HashSet set, ISet other) + public static void Remove(this HashSet set, ISet other) { if (set.Count > other.Count) { @@ -27,7 +27,7 @@ internal static void Remove(this HashSet set, ISet other) } } - internal static void Remove(this HashSet set, IReadOnlyDictionary other) + public static void Remove(this HashSet set, IReadOnlyDictionary other) { if (set.Count > other.Count) { diff --git a/src/Neo.Extensions/Net/IpAddressExtensions.cs b/src/Neo.Extensions/Net/IpAddressExtensions.cs index 00b3065d0d..adafee142f 100644 --- a/src/Neo.Extensions/Net/IpAddressExtensions.cs +++ b/src/Neo.Extensions/Net/IpAddressExtensions.cs @@ -19,7 +19,7 @@ public static class IpAddressExtensions /// Checks if address is IPv4 Mapped to IPv6 format, if so, Map to IPv4. /// Otherwise, return current address. /// - internal static IPAddress UnMap(this IPAddress address) + public static IPAddress UnMap(this IPAddress address) { if (address.IsIPv4MappedToIPv6) address = address.MapToIPv4(); @@ -30,7 +30,7 @@ internal static IPAddress UnMap(this IPAddress address) /// Checks if IPEndPoint is IPv4 Mapped to IPv6 format, if so, unmap to IPv4. /// Otherwise, return current endpoint. /// - internal static IPEndPoint UnMap(this IPEndPoint endPoint) + public static IPEndPoint UnMap(this IPEndPoint endPoint) { if (!endPoint.Address.IsIPv4MappedToIPv6) return endPoint; diff --git a/src/Neo.IO/Neo.IO.csproj b/src/Neo.IO/Neo.IO.csproj index 79f5624602..deb98b053b 100644 --- a/src/Neo.IO/Neo.IO.csproj +++ b/src/Neo.IO/Neo.IO.csproj @@ -13,6 +13,7 @@ + diff --git a/tests/Neo.Extensions.Tests/Collections/UT_HashSetExtensions.cs b/tests/Neo.Extensions.Tests/Collections/UT_HashSetExtensions.cs new file mode 100644 index 0000000000..cb475a7e5c --- /dev/null +++ b/tests/Neo.Extensions.Tests/Collections/UT_HashSetExtensions.cs @@ -0,0 +1,75 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_HashSetExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.IO.Caching; +using System.Collections.Generic; +using System.Linq; + +namespace Neo.Extensions.Tests.Collections +{ + [TestClass] + public class UT_HashSetExtensions + { + [TestMethod] + public void TestRemoveHashsetDictionary() + { + var a = new HashSet + { + 1, + 2, + 3 + }; + + var b = new Dictionary + { + [2] = null + }; + + a.Remove(b); + + CollectionAssert.AreEqual(new int[] { 1, 3 }, a.ToArray()); + + b[4] = null; + b[5] = null; + b[1] = null; + a.Remove(b); + + CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); + } + + [TestMethod] + public void TestRemoveHashsetSet() + { + var a = new HashSet + { + 1, + 2, + 3 + }; + + var b = new SortedSet() + { + 2 + }; + + a.Remove(b); + + CollectionAssert.AreEqual(new int[] { 1, 3 }, a.ToArray()); + + b.Add(4); + b.Add(5); + b.Add(1); + a.Remove(b); + + CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); + } + } +} diff --git a/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj index a2b2b20daf..dd1f995e29 100644 --- a/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj +++ b/tests/Neo.Extensions.Tests/Neo.Extensions.Tests.csproj @@ -12,7 +12,6 @@ - diff --git a/tests/Neo.Extensions.Tests/Net/UT_IpAddressExtensions.cs b/tests/Neo.Extensions.Tests/Net/UT_IpAddressExtensions.cs new file mode 100644 index 0000000000..bbf26c5cb7 --- /dev/null +++ b/tests/Neo.Extensions.Tests/Net/UT_IpAddressExtensions.cs @@ -0,0 +1,43 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_IpAddressExtensions.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 Neo.Extensions; +using System.Net; + +namespace Neo.Extensions.Tests.Net +{ + [TestClass] + public class UT_IpAddressExtensions + { + [TestMethod] + public void TestUnmapForIPAddress() + { + var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); + addr.UnMap().Should().Be(addr); + + var addr2 = addr.MapToIPv6(); + addr2.UnMap().Should().Be(addr); + } + + [TestMethod] + public void TestUnmapForIPEndPoin() + { + var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); + var endPoint = new IPEndPoint(addr, 8888); + endPoint.UnMap().Should().Be(endPoint); + + var addr2 = addr.MapToIPv6(); + var endPoint2 = new IPEndPoint(addr2, 8888); + endPoint2.UnMap().Should().Be(endPoint); + } + } +} diff --git a/tests/Neo.Extensions.Tests/UT_AssemblyExtensions.cs b/tests/Neo.Extensions.Tests/UT_AssemblyExtensions.cs new file mode 100644 index 0000000000..43f66f95da --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_AssemblyExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_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 +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using FluentAssertions; +using System; +using System.Linq; + +namespace Neo.Extensions.Tests +{ + [TestClass] + public class UT_AssemblyExtensions + { + [TestMethod] + public void TestGetVersion() + { + // assembly without version + + var asm = AppDomain.CurrentDomain.GetAssemblies() + .Where(u => u.FullName == "Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null") + .FirstOrDefault(); + string version = asm?.GetVersion() ?? ""; + version.Should().Be("0.0.0"); + } + } +} diff --git a/tests/Neo.Extensions.Tests/UT_DateTimeExtensions.cs b/tests/Neo.Extensions.Tests/UT_DateTimeExtensions.cs new file mode 100644 index 0000000000..43414a8f81 --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_DateTimeExtensions.cs @@ -0,0 +1,42 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_DateTimeExtensions.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_DateTimeExtensions + { + private static readonly DateTime unixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + [TestMethod] + public void TestToTimestamp() + { + var time = DateTime.Now; + var expected = (uint)(time.ToUniversalTime() - unixEpoch).TotalSeconds; + var actual = time.ToTimestamp(); + + actual.Should().Be(expected); + } + + [TestMethod] + public void TestToTimestampMS() + { + var time = DateTime.Now; + var expected = (ulong)(time.ToUniversalTime() - unixEpoch).TotalMilliseconds; + var actual = time.ToTimestampMS(); + + actual.Should().Be(expected); + } + } +} diff --git a/tests/Neo.Extensions.Tests/UT_RandomExtensions.cs b/tests/Neo.Extensions.Tests/UT_RandomExtensions.cs new file mode 100644 index 0000000000..fb7c6a8cf7 --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_RandomExtensions.cs @@ -0,0 +1,32 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_RandomExtensions.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_RandomExtensions + { + [TestMethod] + public void TestNextBigIntegerForRandom() + { + Random ran = new(); + Action action1 = () => ran.NextBigInteger(-1); + action1.Should().Throw(); + + ran.NextBigInteger(0).Should().Be(0); + ran.NextBigInteger(8).Should().NotBeNull(); + ran.NextBigInteger(9).Should().NotBeNull(); + } + } +} diff --git a/tests/Neo.Extensions.Tests/UT_StringExtensions.cs b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs new file mode 100644 index 0000000000..9954f24765 --- /dev/null +++ b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs @@ -0,0 +1,39 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_StringExtensdions.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; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Neo.Extensions.Tests +{ + [TestClass] + public class UT_StringExtensions + { + [TestMethod] + public void TestHexToBytes() + { + string nullStr = null; + _ = nullStr.HexToBytes().ToHexString().Should().Be(Array.Empty().ToHexString()); + string emptyStr = ""; + emptyStr.HexToBytes().ToHexString().Should().Be(Array.Empty().ToHexString()); + string str1 = "hab"; + Action action = () => str1.HexToBytes(); + action.Should().Throw(); + string str2 = "0102"; + byte[] bytes = str2.HexToBytes(); + bytes.ToHexString().Should().Be(new byte[] { 0x01, 0x02 }.ToHexString()); + } + } +} diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 33976cc660..6cf1605a24 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -51,75 +51,6 @@ public void ToScriptHash() res.Should().Be(UInt160.Parse("2d3b96ae1bcc5a585e075e3b81920210dec16302")); } - [TestMethod] - public void TestHexToBytes() - { - string nullStr = null; - _ = nullStr.HexToBytes().ToHexString().Should().Be(Array.Empty().ToHexString()); - string emptyStr = ""; - emptyStr.HexToBytes().ToHexString().Should().Be(Array.Empty().ToHexString()); - string str1 = "hab"; - Action action = () => str1.HexToBytes(); - action.Should().Throw(); - string str2 = "0102"; - byte[] bytes = str2.HexToBytes(); - bytes.ToHexString().Should().Be(new byte[] { 0x01, 0x02 }.ToHexString()); - } - - [TestMethod] - public void TestRemoveHashsetDictionary() - { - var a = new HashSet - { - 1, - 2, - 3 - }; - - var b = new Dictionary - { - [2] = null - }; - - a.Remove(b); - - CollectionAssert.AreEqual(new int[] { 1, 3 }, a.ToArray()); - - b[4] = null; - b[5] = null; - b[1] = null; - a.Remove(b); - - CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); - } - - [TestMethod] - public void TestRemoveHashsetSet() - { - var a = new HashSet - { - 1, - 2, - 3 - }; - - var b = new SortedSet() - { - 2 - }; - - a.Remove(b); - - CollectionAssert.AreEqual(new int[] { 1, 3 }, a.ToArray()); - - b.Add(4); - b.Add(5); - b.Add(1); - a.Remove(b); - - CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); - } - [TestMethod] public void TestRemoveHashsetHashSetCache() { @@ -146,51 +77,5 @@ public void TestRemoveHashsetHashSetCache() CollectionAssert.AreEqual(new int[] { 3 }, a.ToArray()); } - - [TestMethod] - public void TestGetVersion() - { - // assembly without version - - var asm = AppDomain.CurrentDomain.GetAssemblies() - .Where(u => u.FullName == "Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null") - .FirstOrDefault(); - string version = asm?.GetVersion() ?? ""; - version.Should().Be("0.0.0"); - } - - [TestMethod] - public void TestNextBigIntegerForRandom() - { - Random ran = new(); - Action action1 = () => ran.NextBigInteger(-1); - action1.Should().Throw(); - - ran.NextBigInteger(0).Should().Be(0); - ran.NextBigInteger(8).Should().NotBeNull(); - ran.NextBigInteger(9).Should().NotBeNull(); - } - - [TestMethod] - public void TestUnmapForIPAddress() - { - var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); - addr.UnMap().Should().Be(addr); - - var addr2 = addr.MapToIPv6(); - addr2.UnMap().Should().Be(addr); - } - - [TestMethod] - public void TestUnmapForIPEndPoin() - { - var addr = new IPAddress(new byte[] { 127, 0, 0, 1 }); - var endPoint = new IPEndPoint(addr, 8888); - endPoint.UnMap().Should().Be(endPoint); - - var addr2 = addr.MapToIPv6(); - var endPoint2 = new IPEndPoint(addr2, 8888); - endPoint2.UnMap().Should().Be(endPoint); - } } } From 6fa0fdae2e6b129885f0c76b20fe3bc8b3dc033d Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Tue, 9 Jul 2024 15:02:02 -0400 Subject: [PATCH 16/18] Added `tests` for `PART-5` --- .../UT_StringExtensions.cs | 159 ++++++++++++++++++ tests/Neo.UnitTests/IO/UT_IOHelper.cs | 157 ----------------- 2 files changed, 159 insertions(+), 157 deletions(-) diff --git a/tests/Neo.Extensions.Tests/UT_StringExtensions.cs b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs index 9954f24765..9c8ea927da 100644 --- a/tests/Neo.Extensions.Tests/UT_StringExtensions.cs +++ b/tests/Neo.Extensions.Tests/UT_StringExtensions.cs @@ -35,5 +35,164 @@ public void TestHexToBytes() byte[] bytes = str2.HexToBytes(); bytes.ToHexString().Should().Be(new byte[] { 0x01, 0x02 }.ToHexString()); } + + [TestMethod] + public void TestGetVarSizeString() + { + int result = "AA".GetVarSize(); + Assert.AreEqual(3, result); + } + + [TestMethod] + public void TestGetVarSizeInt() + { + for (int i = 0; i < 3; i++) + { + if (i == 0) + { + int result = UnsafeData.GetVarSize(1); + Assert.AreEqual(1, result); + } + else if (i == 1) + { + int result = UnsafeData.GetVarSize(0xFFFF); + Assert.AreEqual(3, result); + } + else + { + int result = UnsafeData.GetVarSize(0xFFFFFF); + Assert.AreEqual(5, result); + } + } + } + + + [TestMethod] + public void TestGetVarSizeGeneric() + { + for (int i = 0; i < 9; i++) + { + if (i == 0) + { + int result = new UInt160[] { UInt160.Zero }.GetVarSize(); + Assert.AreEqual(21, result); + } + else if (i == 1)//sbyte + { + List initList = new() + { + TestEnum0.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(2, result); + } + else if (i == 2)//byte + { + List initList = new() + { + TestEnum1.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(2, result); + } + else if (i == 3)//short + { + List initList = new() + { + TestEnum2.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(3, result); + } + else if (i == 4)//ushort + { + List initList = new() + { + TestEnum3.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(3, result); + } + else if (i == 5)//int + { + List initList = new() + { + TestEnum4.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + else if (i == 6)//uint + { + List initList = new() + { + TestEnum5.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + else if (i == 7)//long + { + List initList = new() + { + TestEnum6.case1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(9, result); + } + else if (i == 8) + { + List initList = new() + { + 1 + }; + IReadOnlyCollection testList = initList.AsReadOnly(); + int result = testList.GetVarSize(); + Assert.AreEqual(5, result); + } + } + } + + enum TestEnum0 : sbyte + { + case1 = 1, case2 = 2 + } + + enum TestEnum1 : byte + { + case1 = 1, case2 = 2 + } + + enum TestEnum2 : short + { + case1 = 1, case2 = 2 + } + + enum TestEnum3 : ushort + { + case1 = 1, case2 = 2 + } + + enum TestEnum4 : int + { + case1 = 1, case2 = 2 + } + + enum TestEnum5 : uint + { + case1 = 1, case2 = 2 + } + + enum TestEnum6 : long + { + case1 = 1, case2 = 2 + } } } diff --git a/tests/Neo.UnitTests/IO/UT_IOHelper.cs b/tests/Neo.UnitTests/IO/UT_IOHelper.cs index 9158cf2b1d..122c6b5a87 100644 --- a/tests/Neo.UnitTests/IO/UT_IOHelper.cs +++ b/tests/Neo.UnitTests/IO/UT_IOHelper.cs @@ -175,163 +175,6 @@ public void TestAsSerializableArray() Assert.AreEqual(UInt160.Zero, result[0]); } - [TestMethod] - public void TestGetVarSizeInt() - { - for (int i = 0; i < 3; i++) - { - if (i == 0) - { - int result = UnsafeData.GetVarSize(1); - Assert.AreEqual(1, result); - } - else if (i == 1) - { - int result = UnsafeData.GetVarSize(0xFFFF); - Assert.AreEqual(3, result); - } - else - { - int result = UnsafeData.GetVarSize(0xFFFFFF); - Assert.AreEqual(5, result); - } - } - } - enum TestEnum0 : sbyte - { - case1 = 1, case2 = 2 - } - - enum TestEnum1 : byte - { - case1 = 1, case2 = 2 - } - - enum TestEnum2 : short - { - case1 = 1, case2 = 2 - } - - enum TestEnum3 : ushort - { - case1 = 1, case2 = 2 - } - - enum TestEnum4 : int - { - case1 = 1, case2 = 2 - } - - enum TestEnum5 : uint - { - case1 = 1, case2 = 2 - } - - enum TestEnum6 : long - { - case1 = 1, case2 = 2 - } - - [TestMethod] - public void TestGetVarSizeGeneric() - { - for (int i = 0; i < 9; i++) - { - if (i == 0) - { - int result = new UInt160[] { UInt160.Zero }.GetVarSize(); - Assert.AreEqual(21, result); - } - else if (i == 1)//sbyte - { - List initList = new() - { - TestEnum0.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(2, result); - } - else if (i == 2)//byte - { - List initList = new() - { - TestEnum1.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(2, result); - } - else if (i == 3)//short - { - List initList = new() - { - TestEnum2.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(3, result); - } - else if (i == 4)//ushort - { - List initList = new() - { - TestEnum3.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(3, result); - } - else if (i == 5)//int - { - List initList = new() - { - TestEnum4.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(5, result); - } - else if (i == 6)//uint - { - List initList = new() - { - TestEnum5.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(5, result); - } - else if (i == 7)//long - { - List initList = new() - { - TestEnum6.case1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(9, result); - } - else if (i == 8) - { - List initList = new() - { - 1 - }; - IReadOnlyCollection testList = initList.AsReadOnly(); - int result = testList.GetVarSize(); - Assert.AreEqual(5, result); - } - } - } - - [TestMethod] - public void TestGetVarSizeString() - { - int result = "AA".GetVarSize(); - Assert.AreEqual(3, result); - } - [TestMethod] public void TestReadSerializable() { From ff3c158a374ab633e65447e75ed21ac32bbc533a Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sat, 3 Aug 2024 18:08:24 -0400 Subject: [PATCH 17/18] Added the `Part` 7 --- ...ringExtensdions.cs => StringExtensions.cs} | 4 +- src/Neo.GUI/GUI/ElectionDialog.cs | 2 +- src/Neo.GUI/GUI/VotingDialog.cs | 2 +- .../Extensions/VM/ScriptBuilderExtensions.cs | 259 ++++++++++++++++++ .../ContractParametersContext.cs | 1 + src/Neo/SmartContract/Helper.cs | 1 + src/Neo/VM/Helper.cs | 236 ---------------- src/Neo/Wallets/AssetDescriptor.cs | 1 + src/Plugins/RpcClient/ContractClient.cs | 1 + .../Extensions/NativeContractExtensions.cs | 1 + .../Nep17NativeContractExtensions.cs | 1 + .../SmartContract/Native/UT_NativeContract.cs | 1 + .../UT_ApplicationEngine.Contract.cs | 1 + .../SmartContract/UT_ApplicationEngine.cs | 1 + .../SmartContract/UT_Contract.cs | 1 + tests/Neo.UnitTests/VM/UT_Helper.cs | 18 +- 16 files changed, 282 insertions(+), 249 deletions(-) rename src/Neo.Extensions/{StringExtensdions.cs => StringExtensions.cs} (93%) create mode 100644 src/Neo/Extensions/VM/ScriptBuilderExtensions.cs diff --git a/src/Neo.Extensions/StringExtensdions.cs b/src/Neo.Extensions/StringExtensions.cs similarity index 93% rename from src/Neo.Extensions/StringExtensdions.cs rename to src/Neo.Extensions/StringExtensions.cs index 937e207087..b84869b2e1 100644 --- a/src/Neo.Extensions/StringExtensdions.cs +++ b/src/Neo.Extensions/StringExtensions.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2024 The Neo Project. // -// StringExtensdions.cs file belongs to the neo project and is free +// StringExtensions.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 @@ -14,7 +14,7 @@ namespace Neo.Extensions { - public static class StringExtensdions + public static class StringExtensions { /// /// Converts a hex to byte array. diff --git a/src/Neo.GUI/GUI/ElectionDialog.cs b/src/Neo.GUI/GUI/ElectionDialog.cs index ddc730589e..ef644074d9 100644 --- a/src/Neo.GUI/GUI/ElectionDialog.cs +++ b/src/Neo.GUI/GUI/ElectionDialog.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract.Native; using Neo.VM; using System; diff --git a/src/Neo.GUI/GUI/VotingDialog.cs b/src/Neo.GUI/GUI/VotingDialog.cs index d289cc48ca..ff5749e181 100644 --- a/src/Neo.GUI/GUI/VotingDialog.cs +++ b/src/Neo.GUI/GUI/VotingDialog.cs @@ -10,7 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; -using Neo.IO; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs new file mode 100644 index 0000000000..575f056dfa --- /dev/null +++ b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs @@ -0,0 +1,259 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ScriptBuilderExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.Cryptography.ECC; +using Neo.IO; +using Neo.SmartContract; +using Neo.VM; +using System; +using System.Collections.Generic; +using System.Numerics; + +namespace Neo.Extensions +{ + public static class ScriptBuilderExtensions + { + /// + /// Emits the opcodes for creating an array. + /// + /// The type of the elements of the array. + /// The to be used. + /// The elements of the array. + /// The same instance as . + public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList list = null) + { + if (list is null || list.Count == 0) + return builder.Emit(OpCode.NEWARRAY0); + for (var i = list.Count - 1; i >= 0; i--) + builder.EmitPush(list[i]); + builder.EmitPush(list.Count); + return builder.Emit(OpCode.PACK); + } + + /// + /// Emits the opcodes for creating a map. + /// + /// The type of the key of the map. + /// The type of the value of the map. + /// The to be used. + /// The key/value pairs of the map. + /// The same instance as . + public static ScriptBuilder CreateMap(this ScriptBuilder builder, IEnumerable> map = null) + { + builder.Emit(OpCode.NEWMAP); + if (map != null) + foreach (var p in map) + { + builder.Emit(OpCode.DUP); + builder.EmitPush(p.Key); + builder.EmitPush(p.Value); + builder.Emit(OpCode.SETITEM); + } + return builder; + } + + /// + /// Emits the specified opcodes. + /// + /// The to be used. + /// The opcodes to emit. + /// The same instance as . + public static ScriptBuilder Emit(this ScriptBuilder builder, params OpCode[] ops) + { + foreach (var op in ops) + builder.Emit(op); + return builder; + } + + /// + /// Emits the opcodes for calling a contract dynamically. + /// + /// The to be used. + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The arguments for calling the contract. + /// The same instance as . + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object[] args) + { + return EmitDynamicCall(builder, scriptHash, method, CallFlags.All, args); + } + + /// + /// Emits the opcodes for calling a contract dynamically. + /// + /// The to be used. + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The for calling the contract. + /// The arguments for calling the contract. + /// The same instance as . + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object[] args) + { + builder.CreateArray(args); + builder.EmitPush(flags); + builder.EmitPush(method); + builder.EmitPush(scriptHash); + builder.EmitSysCall(ApplicationEngine.System_Contract_Call); + return builder; + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, ISerializable data) + { + return builder.EmitPush(data.ToArray()); + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParameter parameter) + { + if (parameter.Value is null) + builder.Emit(OpCode.PUSHNULL); + else + switch (parameter.Type) + { + case ContractParameterType.Signature: + case ContractParameterType.ByteArray: + builder.EmitPush((byte[])parameter.Value); + break; + case ContractParameterType.Boolean: + builder.EmitPush((bool)parameter.Value); + break; + case ContractParameterType.Integer: + if (parameter.Value is BigInteger bi) + builder.EmitPush(bi); + else + builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor([parameter.Value.GetType()]).Invoke([parameter.Value])); + break; + case ContractParameterType.Hash160: + builder.EmitPush((UInt160)parameter.Value); + break; + case ContractParameterType.Hash256: + builder.EmitPush((UInt256)parameter.Value); + break; + case ContractParameterType.PublicKey: + builder.EmitPush((ECPoint)parameter.Value); + break; + case ContractParameterType.String: + builder.EmitPush((string)parameter.Value); + break; + case ContractParameterType.Array: + { + var parameters = (IList)parameter.Value; + for (var i = parameters.Count - 1; i >= 0; i--) + builder.EmitPush(parameters[i]); + builder.EmitPush(parameters.Count); + builder.Emit(OpCode.PACK); + } + break; + case ContractParameterType.Map: + { + var pairs = (IList>)parameter.Value; + builder.CreateMap(pairs); + } + break; + default: + throw new ArgumentException(null, nameof(parameter)); + } + return builder; + } + + /// + /// Emits the opcodes for pushing the specified data onto the stack. + /// + /// The to be used. + /// The data to be pushed. + /// The same instance as . + public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) + { + switch (obj) + { + case bool data: + builder.EmitPush(data); + break; + case byte[] data: + builder.EmitPush(data); + break; + case string data: + builder.EmitPush(data); + break; + case BigInteger data: + builder.EmitPush(data); + break; + case ISerializable data: + builder.EmitPush(data); + break; + case sbyte data: + builder.EmitPush(data); + break; + case byte data: + builder.EmitPush(data); + break; + case short data: + builder.EmitPush(data); + break; + case char data: + builder.EmitPush(data); + break; + case ushort data: + builder.EmitPush(data); + break; + case int data: + builder.EmitPush(data); + break; + case uint data: + builder.EmitPush(data); + break; + case long data: + builder.EmitPush(data); + break; + case ulong data: + builder.EmitPush(data); + break; + case Enum data: + builder.EmitPush(BigInteger.Parse(data.ToString("d"))); + break; + case ContractParameter data: + builder.EmitPush(data); + break; + case null: + builder.Emit(OpCode.PUSHNULL); + break; + default: + throw new ArgumentException(null, nameof(obj)); + } + return builder; + } + + /// + /// Emits the opcodes for invoking an interoperable service. + /// + /// The to be used. + /// The hash of the interoperable service. + /// The arguments for calling the interoperable service. + /// The same instance as . + public static ScriptBuilder EmitSysCall(this ScriptBuilder builder, uint method, params object[] args) + { + for (var i = args.Length - 1; i >= 0; i--) + EmitPush(builder, args[i]); + return builder.EmitSysCall(method); + } + } +} diff --git a/src/Neo/SmartContract/ContractParametersContext.cs b/src/Neo/SmartContract/ContractParametersContext.cs index c4129f0ad1..ea5ea35ab8 100644 --- a/src/Neo/SmartContract/ContractParametersContext.cs +++ b/src/Neo/SmartContract/ContractParametersContext.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P.Payloads; diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs index d0bc3c939b..96ec2af03c 100644 --- a/src/Neo/SmartContract/Helper.cs +++ b/src/Neo/SmartContract/Helper.cs @@ -11,6 +11,7 @@ using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract.Manifest; diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 69cc7c8671..2d16760af3 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -11,7 +11,6 @@ using Neo.Cryptography.ECC; using Neo.Extensions; -using Neo.IO; using Neo.Json; using Neo.SmartContract; using Neo.VM.Types; @@ -30,241 +29,6 @@ namespace Neo.VM /// public static class Helper { - /// - /// Emits the opcodes for creating an array. - /// - /// The type of the elements of the array. - /// The to be used. - /// The elements of the array. - /// The same instance as . - public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList list = null) - { - if (list is null || list.Count == 0) - return builder.Emit(OpCode.NEWARRAY0); - for (int i = list.Count - 1; i >= 0; i--) - builder.EmitPush(list[i]); - builder.EmitPush(list.Count); - return builder.Emit(OpCode.PACK); - } - - /// - /// Emits the opcodes for creating a map. - /// - /// The type of the key of the map. - /// The type of the value of the map. - /// The to be used. - /// The key/value pairs of the map. - /// The same instance as . - public static ScriptBuilder CreateMap(this ScriptBuilder builder, IEnumerable> map = null) - { - builder.Emit(OpCode.NEWMAP); - if (map != null) - foreach (var p in map) - { - builder.Emit(OpCode.DUP); - builder.EmitPush(p.Key); - builder.EmitPush(p.Value); - builder.Emit(OpCode.SETITEM); - } - return builder; - } - - /// - /// Emits the specified opcodes. - /// - /// The to be used. - /// The opcodes to emit. - /// The same instance as . - public static ScriptBuilder Emit(this ScriptBuilder builder, params OpCode[] ops) - { - foreach (OpCode op in ops) - builder.Emit(op); - return builder; - } - - /// - /// Emits the opcodes for calling a contract dynamically. - /// - /// The to be used. - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The arguments for calling the contract. - /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object[] args) - { - return EmitDynamicCall(builder, scriptHash, method, CallFlags.All, args); - } - - /// - /// Emits the opcodes for calling a contract dynamically. - /// - /// The to be used. - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The for calling the contract. - /// The arguments for calling the contract. - /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object[] args) - { - builder.CreateArray(args); - builder.EmitPush(flags); - builder.EmitPush(method); - builder.EmitPush(scriptHash); - builder.EmitSysCall(ApplicationEngine.System_Contract_Call); - return builder; - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, ISerializable data) - { - return builder.EmitPush(data.ToArray()); - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParameter parameter) - { - if (parameter.Value is null) - builder.Emit(OpCode.PUSHNULL); - else - switch (parameter.Type) - { - case ContractParameterType.Signature: - case ContractParameterType.ByteArray: - builder.EmitPush((byte[])parameter.Value); - break; - case ContractParameterType.Boolean: - builder.EmitPush((bool)parameter.Value); - break; - case ContractParameterType.Integer: - if (parameter.Value is BigInteger bi) - builder.EmitPush(bi); - else - builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor(new[] { parameter.Value.GetType() }).Invoke(new[] { parameter.Value })); - break; - case ContractParameterType.Hash160: - builder.EmitPush((UInt160)parameter.Value); - break; - case ContractParameterType.Hash256: - builder.EmitPush((UInt256)parameter.Value); - break; - case ContractParameterType.PublicKey: - builder.EmitPush((ECPoint)parameter.Value); - break; - case ContractParameterType.String: - builder.EmitPush((string)parameter.Value); - break; - case ContractParameterType.Array: - { - IList parameters = (IList)parameter.Value; - for (int i = parameters.Count - 1; i >= 0; i--) - builder.EmitPush(parameters[i]); - builder.EmitPush(parameters.Count); - builder.Emit(OpCode.PACK); - } - break; - case ContractParameterType.Map: - { - var pairs = (IList>)parameter.Value; - builder.CreateMap(pairs); - } - break; - default: - throw new ArgumentException(null, nameof(parameter)); - } - return builder; - } - - /// - /// Emits the opcodes for pushing the specified data onto the stack. - /// - /// The to be used. - /// The data to be pushed. - /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) - { - switch (obj) - { - case bool data: - builder.EmitPush(data); - break; - case byte[] data: - builder.EmitPush(data); - break; - case string data: - builder.EmitPush(data); - break; - case BigInteger data: - builder.EmitPush(data); - break; - case ISerializable data: - builder.EmitPush(data); - break; - case sbyte data: - builder.EmitPush(data); - break; - case byte data: - builder.EmitPush(data); - break; - case short data: - builder.EmitPush(data); - break; - case char data: - builder.EmitPush((ushort)data); - break; - case ushort data: - builder.EmitPush(data); - break; - case int data: - builder.EmitPush(data); - break; - case uint data: - builder.EmitPush(data); - break; - case long data: - builder.EmitPush(data); - break; - case ulong data: - builder.EmitPush(data); - break; - case Enum data: - builder.EmitPush(BigInteger.Parse(data.ToString("d"))); - break; - case ContractParameter data: - builder.EmitPush(data); - break; - case null: - builder.Emit(OpCode.PUSHNULL); - break; - default: - throw new ArgumentException(null, nameof(obj)); - } - return builder; - } - - /// - /// Emits the opcodes for invoking an interoperable service. - /// - /// The to be used. - /// The hash of the interoperable service. - /// The arguments for calling the interoperable service. - /// The same instance as . - public static ScriptBuilder EmitSysCall(this ScriptBuilder builder, uint method, params object[] args) - { - for (int i = args.Length - 1; i >= 0; i--) - EmitPush(builder, args[i]); - return builder.EmitSysCall(method); - } - /// /// Generates the script for calling a contract dynamically. /// diff --git a/src/Neo/Wallets/AssetDescriptor.cs b/src/Neo/Wallets/AssetDescriptor.cs index 7b9be7b16b..e8ba27b4e4 100644 --- a/src/Neo/Wallets/AssetDescriptor.cs +++ b/src/Neo/Wallets/AssetDescriptor.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/src/Plugins/RpcClient/ContractClient.cs b/src/Plugins/RpcClient/ContractClient.cs index f4ec020abc..02b8edc5ef 100644 --- a/src/Plugins/RpcClient/ContractClient.cs +++ b/src/Plugins/RpcClient/ContractClient.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs index 9a282759a9..db2d23c16e 100644 --- a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs index a3f33f26a7..d32e16d0c6 100644 --- a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs @@ -10,6 +10,7 @@ // modifications are permitted. using FluentAssertions; +using Neo.Extensions; using Neo.IO; using Neo.Network.P2P.Payloads; using Neo.Persistence; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index f9a3089f9d..64d6338f0c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs index f9dc5e7b46..2d71b97e25 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.VM; using System.Linq; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index a670e3b4b7..0722a4e15c 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Manifest; using Neo.UnitTests.Extensions; diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs index 07ae320a0f..ecd8532faa 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.SmartContract; using Neo.SmartContract.Native; diff --git a/tests/Neo.UnitTests/VM/UT_Helper.cs b/tests/Neo.UnitTests/VM/UT_Helper.cs index 3e83256669..167566f27e 100644 --- a/tests/Neo.UnitTests/VM/UT_Helper.cs +++ b/tests/Neo.UnitTests/VM/UT_Helper.cs @@ -428,7 +428,7 @@ private void TestEmitPush3Ulong() { ScriptBuilder sb = new ScriptBuilder(); ulong temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -438,7 +438,7 @@ private void TestEmitPush3Long() { ScriptBuilder sb = new ScriptBuilder(); long temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -448,7 +448,7 @@ private void TestEmitPush3Uint() { ScriptBuilder sb = new ScriptBuilder(); uint temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -458,7 +458,7 @@ private void TestEmitPush3Int() { ScriptBuilder sb = new ScriptBuilder(); int temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -468,7 +468,7 @@ private void TestEmitPush3Ushort() { ScriptBuilder sb = new ScriptBuilder(); ushort temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -478,7 +478,7 @@ private void TestEmitPush3Char() { ScriptBuilder sb = new ScriptBuilder(); char temp = char.MinValue; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -488,7 +488,7 @@ private void TestEmitPush3Short() { ScriptBuilder sb = new ScriptBuilder(); short temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -498,7 +498,7 @@ private void TestEmitPush3Byte() { ScriptBuilder sb = new ScriptBuilder(); byte temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); @@ -508,7 +508,7 @@ private void TestEmitPush3Sbyte() { ScriptBuilder sb = new ScriptBuilder(); sbyte temp = 0; - VM.Helper.EmitPush(sb, temp); + sb.EmitPush(temp); byte[] tempArray = new byte[1]; tempArray[0] = (byte)OpCode.PUSH0; CollectionAssert.AreEqual(tempArray, sb.ToArray()); From b9a6cb4886c7c466349309c2918f8ae15503ad7f Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 4 Aug 2024 17:47:50 -0400 Subject: [PATCH 18/18] `PART-8` --- src/Neo/Extensions/UInt160Extensions.cs | 32 ++++++++++++++++ .../VM/EvaluationStackExtensions.cs | 37 +++++++++++++++++++ src/Neo/VM/Helper.cs | 33 +---------------- src/Plugins/RpcClient/Nep17API.cs | 1 + tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs | 1 + .../UT_TransactionManager.cs | 1 + 6 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 src/Neo/Extensions/UInt160Extensions.cs create mode 100644 src/Neo/Extensions/VM/EvaluationStackExtensions.cs diff --git a/src/Neo/Extensions/UInt160Extensions.cs b/src/Neo/Extensions/UInt160Extensions.cs new file mode 100644 index 0000000000..988d7e5d83 --- /dev/null +++ b/src/Neo/Extensions/UInt160Extensions.cs @@ -0,0 +1,32 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UInt160Extensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.VM; + +namespace Neo.Extensions +{ + public static class UInt160Extensions + { + /// + /// Generates the script for calling a contract dynamically. + /// + /// The hash of the contract to be called. + /// The method to be called in the contract. + /// The arguments for calling the contract. + /// The generated script. + public static byte[] MakeScript(this UInt160 scriptHash, string method, params object[] args) + { + using ScriptBuilder sb = new(); + sb.EmitDynamicCall(scriptHash, method, args); + return sb.ToArray(); + } + } +} diff --git a/src/Neo/Extensions/VM/EvaluationStackExtensions.cs b/src/Neo/Extensions/VM/EvaluationStackExtensions.cs new file mode 100644 index 0000000000..30684c01b2 --- /dev/null +++ b/src/Neo/Extensions/VM/EvaluationStackExtensions.cs @@ -0,0 +1,37 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// EvaluationStackExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.Json; +using Neo.VM; +using System; + +namespace Neo.Extensions +{ + public static class EvaluationStackExtensions + { + /// + /// Converts the to a JSON object. + /// + /// The to convert. + /// The maximum size in bytes of the result. + /// The represented by a JSON object. + public static JArray ToJson(this EvaluationStack stack, int maxSize = int.MaxValue) + { + if (maxSize <= 0) throw new ArgumentOutOfRangeException(nameof(maxSize)); + maxSize -= 2/*[]*/+ Math.Max(0, (stack.Count - 1))/*,*/; + JArray result = []; + foreach (var item in stack) + result.Add(item.ToJson(null, ref maxSize)); + if (maxSize < 0) throw new InvalidOperationException("Max size reached."); + return result; + } + } +} diff --git a/src/Neo/VM/Helper.cs b/src/Neo/VM/Helper.cs index 2d16760af3..efec792f13 100644 --- a/src/Neo/VM/Helper.cs +++ b/src/Neo/VM/Helper.cs @@ -29,20 +29,6 @@ namespace Neo.VM /// public static class Helper { - /// - /// Generates the script for calling a contract dynamically. - /// - /// The hash of the contract to be called. - /// The method to be called in the contract. - /// The arguments for calling the contract. - /// The generated script. - public static byte[] MakeScript(this UInt160 scriptHash, string method, params object[] args) - { - using ScriptBuilder sb = new(); - sb.EmitDynamicCall(scriptHash, method, args); - return sb.ToArray(); - } - /// /// Converts the to a JSON object. /// @@ -54,24 +40,7 @@ public static JObject ToJson(this StackItem item, int maxSize = int.MaxValue) return ToJson(item, null, ref maxSize); } - /// - /// Converts the to a JSON object. - /// - /// The to convert. - /// The maximum size in bytes of the result. - /// The represented by a JSON object. - public static JArray ToJson(this EvaluationStack stack, int maxSize = int.MaxValue) - { - if (maxSize <= 0) throw new ArgumentOutOfRangeException(nameof(maxSize)); - maxSize -= 2/*[]*/+ Math.Max(0, (stack.Count - 1))/*,*/; - JArray result = new(); - foreach (var item in stack) - result.Add(ToJson(item, null, ref maxSize)); - if (maxSize < 0) throw new InvalidOperationException("Max size reached."); - return result; - } - - private static JObject ToJson(StackItem item, HashSet context, ref int maxSize) + public static JObject ToJson(this StackItem item, HashSet context, ref int maxSize) { JObject json = new() { diff --git a/src/Plugins/RpcClient/Nep17API.cs b/src/Plugins/RpcClient/Nep17API.cs index 0870670231..c1f7324c4c 100644 --- a/src/Plugins/RpcClient/Nep17API.cs +++ b/src/Plugins/RpcClient/Nep17API.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; diff --git a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs index 7defa163ad..a05918c83f 100644 --- a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.Extensions; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index ae025cf65a..b7eecf2298 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -13,6 +13,7 @@ using Moq; using Neo.Cryptography; using Neo.Cryptography.ECC; +using Neo.Extensions; using Neo.IO; using Neo.Json; using Neo.Network.P2P;