From 0cb83eeef73cd33ad01d3fc0ce5422dd4cba7faa Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 10 Jun 2025 15:12:21 +0200 Subject: [PATCH] MPTTrie clean --- .../{Cryptography/MPTTrie => }/Cache.cs | 14 +++--- .../Neo.Cryptography.MPTTrie.csproj | 4 +- .../{Cryptography/MPTTrie => }/Node.Branch.cs | 4 +- .../MPTTrie => }/Node.Extension.cs | 21 ++++++--- .../{Cryptography/MPTTrie => }/Node.Hash.cs | 13 +++--- .../{Cryptography/MPTTrie => }/Node.Leaf.cs | 7 ++- .../{Cryptography/MPTTrie => }/Node.cs | 45 +++++++++---------- .../{Cryptography/MPTTrie => }/NodeType.cs | 0 .../{Cryptography/MPTTrie => }/Trie.Delete.cs | 2 +- .../{Cryptography/MPTTrie => }/Trie.Find.cs | 2 +- .../{Cryptography/MPTTrie => }/Trie.Get.cs | 2 +- .../{Cryptography/MPTTrie => }/Trie.Proof.cs | 2 +- .../{Cryptography/MPTTrie => }/Trie.Put.cs | 4 +- .../{Cryptography/MPTTrie => }/Trie.cs | 0 .../Cryptography/MPTTrie/UT_Cache.cs | 11 +++-- 15 files changed, 66 insertions(+), 65 deletions(-) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Cache.cs (91%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Node.Branch.cs (94%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Node.Extension.cs (78%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Node.Hash.cs (77%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Node.Leaf.cs (88%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Node.cs (86%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/NodeType.cs (100%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.Delete.cs (98%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.Find.cs (99%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.Get.cs (97%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.Proof.cs (97%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.Put.cs (97%) rename src/Neo.Cryptography.MPTTrie/{Cryptography/MPTTrie => }/Trie.cs (100%) diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Cache.cs b/src/Neo.Cryptography.MPTTrie/Cache.cs similarity index 91% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Cache.cs rename to src/Neo.Cryptography.MPTTrie/Cache.cs index 8a690e712e..d4fbdc3ea5 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Cache.cs +++ b/src/Neo.Cryptography.MPTTrie/Cache.cs @@ -26,10 +26,10 @@ private enum TrackState : byte Deleted } - private class Trackable + private class Trackable(Node node, TrackState state) { - public Node Node; - public TrackState State; + public Node Node { get; internal set; } = node; + public TrackState State { get; internal set; } = state; } private readonly IStoreSnapshot _store; @@ -44,7 +44,7 @@ public Cache(IStoreSnapshot store, byte prefix) private byte[] Key(UInt256 hash) { - byte[] buffer = new byte[UInt256.Length + 1]; + var buffer = new byte[UInt256.Length + 1]; using (var ms = new MemoryStream(buffer, true)) using (var writer = new BinaryWriter(ms)) { @@ -65,11 +65,7 @@ private Trackable ResolveInternal(UInt256 hash) var n = _store.TryGet(Key(hash), out var data) ? data.AsSerializable() : null; - t = new Trackable - { - Node = n, - State = TrackState.None, - }; + t = new Trackable(n, TrackState.None); _cache.Add(hash, t); return t; } diff --git a/src/Neo.Cryptography.MPTTrie/Neo.Cryptography.MPTTrie.csproj b/src/Neo.Cryptography.MPTTrie/Neo.Cryptography.MPTTrie.csproj index 56821ad193..9e7b105fbf 100644 --- a/src/Neo.Cryptography.MPTTrie/Neo.Cryptography.MPTTrie.csproj +++ b/src/Neo.Cryptography.MPTTrie/Neo.Cryptography.MPTTrie.csproj @@ -1,9 +1,9 @@ - + net9.0 Neo.Cryptography.MPT - Neo.Cryptography + Neo.Cryptography.MPTTrie true diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Branch.cs b/src/Neo.Cryptography.MPTTrie/Node.Branch.cs similarity index 94% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Branch.cs rename to src/Neo.Cryptography.MPTTrie/Node.Branch.cs index 086e50dcb2..810c7e0488 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Branch.cs +++ b/src/Neo.Cryptography.MPTTrie/Node.Branch.cs @@ -17,13 +17,13 @@ namespace Neo.Cryptography.MPTTrie partial class Node { public const int BranchChildCount = 17; - public Node[] Children; + public Node[] Children { get; internal set; } public static Node NewBranch() { var n = new Node { - type = NodeType.BranchNode, + Type = NodeType.BranchNode, Reference = 1, Children = new Node[BranchChildCount], }; diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Extension.cs b/src/Neo.Cryptography.MPTTrie/Node.Extension.cs similarity index 78% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Extension.cs rename to src/Neo.Cryptography.MPTTrie/Node.Extension.cs index fe612cc590..b3bce088d7 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Extension.cs +++ b/src/Neo.Cryptography.MPTTrie/Node.Extension.cs @@ -20,21 +20,30 @@ namespace Neo.Cryptography.MPTTrie partial class Node { public const int MaxKeyLength = (ApplicationEngine.MaxStorageKeySize + sizeof(int)) * 2; - public ReadOnlyMemory Key; - public Node Next; + public ReadOnlyMemory Key { get; set; } = ReadOnlyMemory.Empty; + + internal Node _next; + + public Node Next + { + get => _next; + set { _next = value; } + } public static Node NewExtension(byte[] key, Node next) { - if (key is null || next is null) throw new ArgumentNullException(nameof(NewExtension)); + ArgumentNullException.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(next); + if (key.Length == 0) throw new InvalidOperationException(nameof(NewExtension)); - var n = new Node + + return new Node { - type = NodeType.ExtensionNode, + Type = NodeType.ExtensionNode, Key = key, Next = next, Reference = 1, }; - return n; } protected int ExtensionSize => Key.GetVarSize() + Next.SizeAsChild; diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Hash.cs b/src/Neo.Cryptography.MPTTrie/Node.Hash.cs similarity index 77% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Hash.cs rename to src/Neo.Cryptography.MPTTrie/Node.Hash.cs index 8dd8d7aa42..f87b693a51 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Hash.cs +++ b/src/Neo.Cryptography.MPTTrie/Node.Hash.cs @@ -21,24 +21,23 @@ partial class Node public static Node NewHash(UInt256 hash) { ArgumentNullException.ThrowIfNull(hash); - var n = new Node + return new Node { - type = NodeType.HashNode, - hash = hash, + Type = NodeType.HashNode, + _hash = hash, }; - return n; } - protected int HashSize => hash.Size; + protected static int HashSize => UInt256.Length; private void SerializeHash(BinaryWriter writer) { - writer.Write(hash); + writer.Write(_hash); } private void DeserializeHash(ref MemoryReader reader) { - hash = reader.ReadSerializable(); + _hash = reader.ReadSerializable(); } } } diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs b/src/Neo.Cryptography.MPTTrie/Node.Leaf.cs similarity index 88% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs rename to src/Neo.Cryptography.MPTTrie/Node.Leaf.cs index 98edd79d07..2e4f9dca05 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.Leaf.cs +++ b/src/Neo.Cryptography.MPTTrie/Node.Leaf.cs @@ -20,18 +20,17 @@ namespace Neo.Cryptography.MPTTrie partial class Node { public const int MaxValueLength = 3 + ApplicationEngine.MaxStorageValueSize + sizeof(bool); - public ReadOnlyMemory Value; + public ReadOnlyMemory Value { get; set; } = ReadOnlyMemory.Empty; public static Node NewLeaf(byte[] value) { ArgumentNullException.ThrowIfNull(value); - var n = new Node + return new Node { - type = NodeType.LeafNode, + Type = NodeType.LeafNode, Value = value, Reference = 1, }; - return n; } protected int LeafSize => Value.GetVarSize(); diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.cs b/src/Neo.Cryptography.MPTTrie/Node.cs similarity index 86% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.cs rename to src/Neo.Cryptography.MPTTrie/Node.cs index 4db6f5e969..843f5e76bb 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Node.cs +++ b/src/Neo.Cryptography.MPTTrie/Node.cs @@ -18,18 +18,17 @@ namespace Neo.Cryptography.MPTTrie { public partial class Node : ISerializable { - private NodeType type; - private UInt256 hash; - public int Reference; - public UInt256 Hash => hash ??= new UInt256(Crypto.Hash256(ToArrayWithoutReference())); - public NodeType Type => type; - public bool IsEmpty => type == NodeType.Empty; + private UInt256 _hash; + public int Reference { get; internal set; } + public UInt256 Hash => _hash ??= new UInt256(Crypto.Hash256(ToArrayWithoutReference())); + public NodeType Type { get; internal set; } + public bool IsEmpty => Type == NodeType.Empty; public int Size { get { var size = sizeof(NodeType); - return type switch + return Type switch { NodeType.BranchNode => size + BranchSize + Reference.GetVarSize(), NodeType.ExtensionNode => size + ExtensionSize + Reference.GetVarSize(), @@ -43,19 +42,19 @@ public int Size public Node() { - type = NodeType.Empty; + Type = NodeType.Empty; } public void SetDirty() { - hash = null; + _hash = null; } public int SizeAsChild { get { - return type switch + return Type switch { NodeType.BranchNode or NodeType.ExtensionNode or NodeType.LeafNode => NewHash(Hash).Size, NodeType.HashNode or NodeType.Empty => Size, @@ -66,7 +65,7 @@ public int SizeAsChild public void SerializeAsChild(BinaryWriter writer) { - switch (type) + switch (Type) { case NodeType.BranchNode: case NodeType.ExtensionNode: @@ -85,8 +84,8 @@ public void SerializeAsChild(BinaryWriter writer) private void SerializeWithoutReference(BinaryWriter writer) { - writer.Write((byte)type); - switch (type) + writer.Write((byte)Type); + switch (Type) { case NodeType.BranchNode: SerializeBranch(writer); @@ -110,7 +109,7 @@ private void SerializeWithoutReference(BinaryWriter writer) public void Serialize(BinaryWriter writer) { SerializeWithoutReference(writer); - if (type == NodeType.BranchNode || type == NodeType.ExtensionNode || type == NodeType.LeafNode) + if (Type == NodeType.BranchNode || Type == NodeType.ExtensionNode || Type == NodeType.LeafNode) writer.WriteVarInt(Reference); } @@ -126,8 +125,8 @@ public byte[] ToArrayWithoutReference() public void Deserialize(ref MemoryReader reader) { - type = (NodeType)reader.ReadByte(); - switch (type) + Type = (NodeType)reader.ReadByte(); + switch (Type) { case NodeType.BranchNode: DeserializeBranch(ref reader); @@ -153,12 +152,12 @@ public void Deserialize(ref MemoryReader reader) private Node CloneAsChild() { - return type switch + return Type switch { NodeType.BranchNode or NodeType.ExtensionNode or NodeType.LeafNode => new Node { - type = NodeType.HashNode, - hash = Hash, + Type = NodeType.HashNode, + _hash = Hash, }, NodeType.HashNode or NodeType.Empty => Clone(), _ => throw new InvalidOperationException(nameof(Clone)), @@ -167,12 +166,12 @@ private Node CloneAsChild() public Node Clone() { - switch (type) + switch (Type) { case NodeType.BranchNode: var n = new Node { - type = type, + Type = Type, Reference = Reference, Children = new Node[BranchChildCount], }; @@ -184,7 +183,7 @@ public Node Clone() case NodeType.ExtensionNode: return new Node { - type = type, + Type = Type, Key = Key, Next = Next.CloneAsChild(), Reference = Reference, @@ -192,7 +191,7 @@ public Node Clone() case NodeType.LeafNode: return new Node { - type = type, + Type = Type, Value = Value, Reference = Reference, }; diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/NodeType.cs b/src/Neo.Cryptography.MPTTrie/NodeType.cs similarity index 100% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/NodeType.cs rename to src/Neo.Cryptography.MPTTrie/NodeType.cs diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs b/src/Neo.Cryptography.MPTTrie/Trie.Delete.cs similarity index 98% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs rename to src/Neo.Cryptography.MPTTrie/Trie.Delete.cs index 46a8860eba..1b5ec937c6 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Delete.cs +++ b/src/Neo.Cryptography.MPTTrie/Trie.Delete.cs @@ -45,7 +45,7 @@ private bool TryDelete(ref Node node, ReadOnlySpan path) if (path.StartsWith(node.Key.Span)) { var oldHash = node.Hash; - var result = TryDelete(ref node.Next, path[node.Key.Length..]); + var result = TryDelete(ref node._next, path[node.Key.Length..]); if (!result) return false; if (!_full) _cache.DeleteNode(oldHash); if (node.Next.IsEmpty) diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Find.cs b/src/Neo.Cryptography.MPTTrie/Trie.Find.cs similarity index 99% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Find.cs rename to src/Neo.Cryptography.MPTTrie/Trie.Find.cs index 17ef61807a..6dea23b341 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Find.cs +++ b/src/Neo.Cryptography.MPTTrie/Trie.Find.cs @@ -57,7 +57,7 @@ private ReadOnlySpan Seek(ref Node node, ReadOnlySpan path, out Node } if (path.StartsWith(node.Key.Span)) { - return new([.. 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)) { diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Get.cs b/src/Neo.Cryptography.MPTTrie/Trie.Get.cs similarity index 97% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Get.cs rename to src/Neo.Cryptography.MPTTrie/Trie.Get.cs index e23a66c224..008b300f36 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Get.cs +++ b/src/Neo.Cryptography.MPTTrie/Trie.Get.cs @@ -78,7 +78,7 @@ private bool TryGet(ref Node node, ReadOnlySpan path, out ReadOnlySpan path, HashSet se if (path.StartsWith(node.Key.Span)) { set.Add(node.ToArrayWithoutReference()); - return GetProof(ref node.Next, path[node.Key.Length..], set); + return GetProof(ref node._next, path[node.Key.Length..], set); } break; } diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Put.cs b/src/Neo.Cryptography.MPTTrie/Trie.Put.cs similarity index 97% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Put.cs rename to src/Neo.Cryptography.MPTTrie/Trie.Put.cs index 58959d9e4b..f1e808033c 100644 --- a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.Put.cs +++ b/src/Neo.Cryptography.MPTTrie/Trie.Put.cs @@ -19,7 +19,7 @@ partial class Trie [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReadOnlySpan CommonPrefix(ReadOnlySpan a, ReadOnlySpan b) { - int offset = a.CommonPrefixLength(b); + var offset = a.CommonPrefixLength(b); return a[..offset]; } @@ -60,7 +60,7 @@ private void Put(ref Node node, ReadOnlySpan path, Node val) if (path.StartsWith(node.Key.Span)) { var oldHash = node.Hash; - Put(ref node.Next, path[node.Key.Length..], val); + Put(ref node._next, path[node.Key.Length..], val); if (!_full) _cache.DeleteNode(oldHash); node.SetDirty(); _cache.PutNode(node); diff --git a/src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.cs b/src/Neo.Cryptography.MPTTrie/Trie.cs similarity index 100% rename from src/Neo.Cryptography.MPTTrie/Cryptography/MPTTrie/Trie.cs rename to src/Neo.Cryptography.MPTTrie/Trie.cs 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 a809fc5031..da04275802 100644 --- a/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs +++ b/tests/Neo.Cryptography.MPTTrie.Tests/Cryptography/MPTTrie/UT_Cache.cs @@ -14,13 +14,12 @@ using Neo.Persistence.Providers; using System.Text; -namespace Neo.Cryptography.MPTTrie.Tests +namespace Neo.Cryptography.MPTTrie.Tests.Cryptography.MPTTrie { - [TestClass] public class UT_Cache { - private readonly byte Prefix = 0xf0; + private const byte Prefix = 0xf0; [TestMethod] public void TestResolveLeaf() @@ -56,7 +55,7 @@ public void TestResolveBranch() [TestMethod] public void TestResolveExtension() { - var e = Node.NewExtension(new byte[] { 0x01 }, new Node()); + var e = Node.NewExtension([0x01], new Node()); var store = new MemoryStore(); store.Put(e.Hash.ToKey(), e.ToArray()); var snapshot = store.GetSnapshot(); @@ -95,7 +94,7 @@ public void TestGetAndChangedBranch() [TestMethod] public void TestGetAndChangedExtension() { - var e = Node.NewExtension(new byte[] { 0x01 }, new Node()); + var e = Node.NewExtension([0x01], new Node()); var store = new MemoryStore(); store.Put(e.Hash.ToKey(), e.ToArray()); var snapshot = store.GetSnapshot(); @@ -159,7 +158,7 @@ public void TestPutAndChangedBranch() [TestMethod] public void TestPutAndChangedExtension() { - var e = Node.NewExtension(new byte[] { 0x01 }, new Node()); + var e = Node.NewExtension([0x01], new Node()); var h = e.Hash; var store = new MemoryStore(); var snapshot = store.GetSnapshot();