From c4b1795c7d0c6f2b65ace46b1e03e051f68714be Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Wed, 9 Aug 2023 14:54:05 -0300 Subject: [PATCH 1/3] tree: add new method LoadKeyForProof Signed-off-by: Ignacio Hagopian --- tree.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tree.go b/tree.go index b6bb8d5c..39a68a03 100644 --- a/tree.go +++ b/tree.go @@ -835,6 +835,33 @@ func groupKeys(keys keylist, depth byte) []keylist { return groups } +func (n *InternalNode) LoadKeyForProof(key []byte, resolver NodeResolverFn) error { + // Each internal node that is part of the proof needs to load all it's + // children since it's needed for proof openings. + childrenKey := make([]byte, n.depth+1) + copy(childrenKey, key[:n.depth]) + for i := range n.children { + if _, ok := n.children[i].(HashedNode); ok { + childrenKey[n.depth] = byte(i) + serialized, err := resolver(childrenKey) + if err != nil { + return err + } + c, err := ParseNode(serialized, n.depth+1) + if err != nil { + return err + } + n.children[i] = c + } + if child, ok := n.children[i].(*InternalNode); ok { + if err := child.LoadKeyForProof(childrenKey, resolver); err != nil { + return err + } + } + } + return nil +} + func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn) (*ProofElements, []byte, [][]byte, error) { var ( groups = groupKeys(keys, n.depth) From ead3a2520a8da47c9d70be517568e185c0cbb589 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Wed, 9 Aug 2023 15:17:20 -0300 Subject: [PATCH 2/3] tree: extend method to also return value Signed-off-by: Ignacio Hagopian --- tree.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tree.go b/tree.go index 39a68a03..802a0372 100644 --- a/tree.go +++ b/tree.go @@ -835,7 +835,7 @@ func groupKeys(keys keylist, depth byte) []keylist { return groups } -func (n *InternalNode) LoadKeyForProof(key []byte, resolver NodeResolverFn) error { +func (n *InternalNode) GetAndLoadForProof(key []byte, resolver NodeResolverFn) ([]byte, error) { // Each internal node that is part of the proof needs to load all it's // children since it's needed for proof openings. childrenKey := make([]byte, n.depth+1) @@ -845,21 +845,23 @@ func (n *InternalNode) LoadKeyForProof(key []byte, resolver NodeResolverFn) erro childrenKey[n.depth] = byte(i) serialized, err := resolver(childrenKey) if err != nil { - return err + return nil, fmt.Errorf("resolving node: %s", err) } c, err := ParseNode(serialized, n.depth+1) if err != nil { - return err + return nil, fmt.Errorf("parsing resolved node: %s", err) } n.children[i] = c } - if child, ok := n.children[i].(*InternalNode); ok { - if err := child.LoadKeyForProof(childrenKey, resolver); err != nil { - return err - } - } } - return nil + switch child := n.children[key[n.depth+1]].(type) { + case *InternalNode: // If next node is an internal node, recurse. + return child.GetAndLoadForProof(childrenKey, resolver) + case *LeafNode: // If next node is a leaf node, return the value. + return child.Get(key, nil) + default: + panic("invalid node type") + } } func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn) (*ProofElements, []byte, [][]byte, error) { From e0c4061afc685b7625bc60cca961f9db742a73ed Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Wed, 4 Oct 2023 09:38:57 -0300 Subject: [PATCH 3/3] fix typo Signed-off-by: Ignacio Hagopian --- tree.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tree.go b/tree.go index 802a0372..04d256f8 100644 --- a/tree.go +++ b/tree.go @@ -836,7 +836,7 @@ func groupKeys(keys keylist, depth byte) []keylist { } func (n *InternalNode) GetAndLoadForProof(key []byte, resolver NodeResolverFn) ([]byte, error) { - // Each internal node that is part of the proof needs to load all it's + // Each internal node that is part of the proof needs to load all its // children since it's needed for proof openings. childrenKey := make([]byte, n.depth+1) copy(childrenKey, key[:n.depth])