private bool TryDelete(ref MPTNode node, ReadOnlySpan <byte> path) { switch (node) { case LeafNode _: { if (path.IsEmpty) { node = HashNode.EmptyNode; return(true); } return(false); } case ExtensionNode extensionNode: { if (path.StartsWith(extensionNode.Key)) { var result = TryDelete(ref extensionNode.Next, path[extensionNode.Key.Length..]);
public static unsafe MPTNode Decode(ReadOnlySpan <byte> data) { if (data.IsEmpty) { return(null); fixed(byte *pointer = data) { using UnmanagedMemoryStream stream = new UnmanagedMemoryStream(pointer, data.Length); using BinaryReader reader = new BinaryReader(stream); MPTNode n = (MPTNode)ReflectionCache <NodeType> .CreateInstance((NodeType)reader.ReadByte()); if (n is null) { throw new InvalidOperationException(); } n.DecodeSpecific(reader); return(n); } }
private ReadOnlySpan <byte> Seek(ref MPTNode node, ReadOnlySpan <byte> path, out MPTNode start) { switch (node) { case LeafNode leafNode: { if (path.IsEmpty) { start = leafNode; return(ReadOnlySpan <byte> .Empty); } break; } case HashNode hashNode: { if (hashNode.IsEmpty) { break; } var newNode = Resolve(hashNode); if (newNode is null) { break; } node = newNode; return(Seek(ref node, path, out start)); } case BranchNode branchNode: { if (path.IsEmpty) { start = branchNode; return(ReadOnlySpan <byte> .Empty); } return(Concat(path[..1], Seek(ref branchNode.Children[path[0]], path[1..], out start)));
private bool GetProof(ref MPTNode node, ReadOnlySpan <byte> path, HashSet <byte[]> set) { switch (node) { case LeafNode leafNode: { if (path.IsEmpty) { set.Add(leafNode.Encode()); return(true); } break; } case HashNode hashNode: { if (hashNode.IsEmpty) { break; } var newNode = Resolve(hashNode); if (newNode is null) { break; } node = newNode; return(GetProof(ref node, path, set)); } case BranchNode branchNode: { set.Add(branchNode.Encode()); if (path.IsEmpty) { return(GetProof(ref branchNode.Children[BranchNode.ChildCount - 1], path, set)); } return(GetProof(ref branchNode.Children[path[0]], path[1..], set));
private bool TryGet(ref MPTNode node, ReadOnlySpan <byte> path, out ReadOnlySpan <byte> value) { switch (node) { case LeafNode leafNode: { if (path.IsEmpty) { value = leafNode.Value; return(true); } break; } case HashNode hashNode: { if (hashNode.IsEmpty) { break; } var newNode = Resolve(hashNode); if (newNode is null) { break; } node = newNode; return(TryGet(ref node, path, out value)); } case BranchNode branchNode: { if (path.IsEmpty) { return(TryGet(ref branchNode.Children[BranchNode.ChildCount - 1], path, out value)); } return(TryGet(ref branchNode.Children[path[0]], path[1..], out value));
private void PutToStore(MPTNode node) { store.Put(Prefix, node.Hash.ToArray(), node.Encode()); }
private MPTNode Resolve(HashNode n) { var data = store.TryGet(Prefix, n.Hash.ToArray()); return(MPTNode.Decode(data)); }
public MPTTrie(ISnapshot store, UInt256 root) { this.store = store ?? throw new ArgumentNullException(); this.root = root is null ? HashNode.EmptyNode : new HashNode(root); }
internal override void DecodeSpecific(BinaryReader reader) { Key = reader.ReadVarBytes(MaxKeyLength); Next = new HashNode(); Next.DecodeSpecific(reader); }