Skip to content

Commit

Permalink
insertNode not playing well with pre set inner nodes..
Browse files Browse the repository at this point in the history
  • Loading branch information
rian committed May 31, 2024
1 parent 5cad816 commit 26a315c
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
Binary file removed core/trie/__debug_bin425255013
Binary file not shown.
8 changes: 4 additions & 4 deletions core/trie/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,13 @@ func BuildTrie(leftProof, rightProof []StorageNode, keys []*felt.Felt, values []
}

for _, sNode := range leftProof {
_, err := tempTrie.PutInner(sNode.key, sNode.node) // Correctly sets root.left here (len is correct)
_, err := tempTrie.PutInner(sNode.key, sNode.node)
if err != nil {
return nil, err
}
}

for _, sNode := range rightProof { // Note setting the leaf..
for _, sNode := range rightProof {
_, err := tempTrie.PutInner(sNode.key, sNode.node)
if err != nil {
return nil, err
Expand All @@ -431,13 +431,13 @@ func BuildTrie(leftProof, rightProof []StorageNode, keys []*felt.Felt, values []
builtRightNode, err := tempTrie.GetNodeFromKey(builtRootNode.Right) // correct

for i := range len(keys) {
_, err := tempTrie.Put(keys[i], values[i])
_, err := tempTrie.PutWithProof(keys[i], values[i], leftProof, rightProof) // This is where the issues arises
if err != nil {
return nil, err
}
}
builtRootNode, err = tempTrie.GetNodeFromKey(builtRootKey) // correct
builtLeftNode, err = tempTrie.GetNodeFromKey(builtRootNode.Left) // leftPath gets overwritten...
builtLeftNode, err = tempTrie.GetNodeFromKey(builtRootNode.Left) // leftPath was getting overwritten... now the right is (parent sibling)
builtRightNode, err = tempTrie.GetNodeFromKey(builtRootNode.Right) // correct
fmt.Println(builtLeftNode, builtRightNode)

Expand Down
68 changes: 67 additions & 1 deletion core/trie/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ func (t *Trie) replaceLinkWithNewParent(key *Key, commonKey Key, siblingParent S
}

func (t *Trie) insertOrUpdateValue(nodeKey *Key, node *Node, nodes []StorageNode, sibling StorageNode) error {

commonKey, _ := findCommonKey(nodeKey, sibling.key)

newParent := &Node{}
Expand Down Expand Up @@ -339,7 +340,6 @@ func (t *Trie) Put(key, value *felt.Felt) (*felt.Felt, error) {
// trying to insert 0 to a key that does not exist
return nil, nil // no-op
}

err := t.insertOrUpdateValue(&nodeKey, node, nodes, sibling)
if err != nil {
return nil, err
Expand All @@ -348,6 +348,72 @@ func (t *Trie) Put(key, value *felt.Felt) (*felt.Felt, error) {
}
}

// Put updates the corresponding `value` for a `key`
func (t *Trie) PutWithProof(key, value *felt.Felt, lProofPath, rProofPath []StorageNode) (*felt.Felt, error) {
if key.Cmp(t.maxKey) > 0 {
return nil, fmt.Errorf("key %s exceeds trie height %d", key, t.height)
}

old := felt.Zero
nodeKey := t.feltToKey(key)
node := &Node{
Value: value,
}

oldValue, err := t.updateLeaf(nodeKey, node, value)
// xor operation, because we don't want to return result if the error is nil and the old value is nil
if (err != nil) != (oldValue != nil) {
return oldValue, err
}

nodes, err := t.nodesFromRoot(&nodeKey) // correct for key,value
if err != nil {
return nil, err
}
defer func() {
for _, n := range nodes {
nodePool.Put(n.node)
}
}()

// empty trie, make new value root
if len(nodes) == 0 {
return t.handleEmptyTrie(old, nodeKey, node, value)
} else {
// Since we short-circuit in leaf updates, we will only end up here for deletions
// Delete if key already exist
sibling := nodes[len(nodes)-1]
oldValue, err = t.deleteExistingKey(sibling, nodeKey, nodes)
// xor operation, because we don't want to return if the error is nil and the old value is nil
if (err != nil) != (oldValue != nil) {
return oldValue, err
} else if value.IsZero() {
// trying to insert 0 to a key that does not exist
return nil, nil // no-op
}

// todo : make less dumb
for i, proof := range lProofPath {
if proof.key.Equal(sibling.key) {
sibling = lProofPath[i+1]
break
}
}
for i, proof := range rProofPath {
if proof.key.Equal(sibling.key) {
sibling = rProofPath[i+1]
break
}
}

err := t.insertOrUpdateValue(&nodeKey, node, nodes, sibling) // This doesn't play well with proof constructed tries..
if err != nil {
return nil, err
}
return &old, nil
}
}

// Put updates the corresponding `value` for a `key`
// Note only a single node is modified. It's the callers responsibility
// To ensure it doesn't break the trie.
Expand Down

0 comments on commit 26a315c

Please sign in to comment.