Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,7 +44,7 @@ public Cache(IStoreSnapshot store, byte prefix)

private byte[] Key(UInt256 hash)
{
byte[] buffer = new byte[UInt256.Length + 1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest the following code to avoid using streams, which is more efficient
var buffer = new byte[UInt256.Length + 1];
buffer[0] = prefix;
Array.Copy(hash.ToArray(), 0, buffer, 1, UInt256.Length);
return buffer;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, but this should be done in a different PR, this aims to change only the style

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to open a new PR for this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest the following code to avoid using streams, which is more efficient var buffer = new byte[UInt256.Length + 1]; buffer[0] = prefix; Array.Copy(hash.ToArray(), 0, buffer, 1, UInt256.Length); return buffer;

It's good to create a new PR.

var buffer = new byte[UInt256.Length + 1];
using (var ms = new MemoryStream(buffer, true))
using (var writer = new BinaryWriter(ms))
{
Expand All @@ -65,11 +65,7 @@ private Trackable ResolveInternal(UInt256 hash)

var n = _store.TryGet(Key(hash), out var data) ? data.AsSerializable<Node>() : null;

t = new Trackable
{
Node = n,
State = TrackState.None,
};
t = new Trackable(n, TrackState.None);
_cache.Add(hash, t);
return t;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.Cryptography.MPTTrie/Neo.Cryptography.MPTTrie.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<PackageId>Neo.Cryptography.MPT</PackageId>
<RootNamespace>Neo.Cryptography</RootNamespace>
<RootNamespace>Neo.Cryptography.MPTTrie</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,30 @@ namespace Neo.Cryptography.MPTTrie
partial class Node
{
public const int MaxKeyLength = (ApplicationEngine.MaxStorageKeySize + sizeof(int)) * 2;
public ReadOnlyMemory<byte> Key;
public Node Next;
public ReadOnlyMemory<byte> Key { get; set; } = ReadOnlyMemory<byte>.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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<UInt256>();
_hash = reader.ReadSerializable<UInt256>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,17 @@ namespace Neo.Cryptography.MPTTrie
partial class Node
{
public const int MaxValueLength = 3 + ApplicationEngine.MaxStorageValueSize + sizeof(bool);
public ReadOnlyMemory<byte> Value;
public ReadOnlyMemory<byte> Value { get; set; } = ReadOnlyMemory<byte>.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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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,
Expand All @@ -66,7 +65,7 @@ public int SizeAsChild

public void SerializeAsChild(BinaryWriter writer)
{
switch (type)
switch (Type)
{
case NodeType.BranchNode:
case NodeType.ExtensionNode:
Expand All @@ -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);
Expand All @@ -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);
}

Expand All @@ -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);
Expand All @@ -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)),
Expand All @@ -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],
};
Expand All @@ -184,15 +183,15 @@ public Node Clone()
case NodeType.ExtensionNode:
return new Node
{
type = type,
Type = Type,
Key = Key,
Next = Next.CloneAsChild(),
Reference = Reference,
};
case NodeType.LeafNode:
return new Node
{
type = type,
Type = Type,
Value = Value,
Reference = Reference,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private bool TryDelete(ref Node node, ReadOnlySpan<byte> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private ReadOnlySpan<byte> Seek(ref Node node, ReadOnlySpan<byte> 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))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private bool TryGet(ref Node node, ReadOnlySpan<byte> path, out ReadOnlySpan<byt
{
if (path.StartsWith(node.Key.Span))
{
return TryGet(ref node.Next, path[node.Key.Length..], out value);
return TryGet(ref node._next, path[node.Key.Length..], out value);
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private bool GetProof(ref Node node, ReadOnlySpan<byte> path, HashSet<byte[]> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ partial class Trie
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ReadOnlySpan<byte> CommonPrefix(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b)
{
int offset = a.CommonPrefixLength(b);
var offset = a.CommonPrefixLength(b);
return a[..offset];
}

Expand Down Expand Up @@ -60,7 +60,7 @@ private void Put(ref Node node, ReadOnlySpan<byte> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down