-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Snap/merge range and proof #1913
Changes from 1 commit
5cd826f
3ecb395
d2fe491
2cd3157
3603e28
d8f5811
40a3d04
fb6c899
07e99f5
c0b933a
529aef2
ca360e9
fdf6af2
9f9f2fe
bad7267
92a98df
727801b
b4ae2b6
a123730
d249186
21f9453
2d7c6e8
46c7b8a
0bb2edc
ce20e08
ec2f917
dd21cc0
571eb6e
b614c2e
89cf035
20e2aa0
faa0884
59440ac
35b46d0
cb26dd7
1454ad5
d4b4232
4f4940f
909914d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,8 @@ | |
"github.com/NethermindEth/juno/core/felt" | ||
) | ||
|
||
func (t *Trie) IterateAndGenerateProof(startValue *felt.Felt, consumer func(key, value *felt.Felt) (bool, error)) ([]ProofNode, bool, error) { | ||
func (t *Trie) IterateAndGenerateProof(startValue *felt.Felt, consumer func(key, value *felt.Felt) (bool, error), | ||
) ([]ProofNode, bool, error) { | ||
var lastKey *felt.Felt | ||
|
||
finished, err := t.Iterate(startValue, func(key, value *felt.Felt) (bool, error) { | ||
|
@@ -13,7 +14,7 @@ | |
return consumer(key, value) | ||
}) | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
|
||
proofset := map[felt.Felt]ProofNode{} | ||
|
@@ -26,13 +27,12 @@ | |
// actually check that the server did not skip leafs. | ||
leftProof, err := GetProof(&startKey, t) | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
for _, proof := range leftProof { | ||
// Well.. using the trie hash here is kinda slow... but I just need it to work right now. | ||
proofset[*proof.Hash(t.hash)] = proof | ||
} | ||
|
||
} | ||
|
||
if !finished && lastKey != nil { | ||
|
@@ -40,7 +40,7 @@ | |
lastKey := NewKey(t.height, feltBts[:]) | ||
rightProof, err := GetProof(&lastKey, t) | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
|
||
for _, proof := range rightProof { | ||
|
@@ -56,7 +56,9 @@ | |
return proofs, finished, nil | ||
} | ||
|
||
func VerifyRange(root, startKey *felt.Felt, keys, values []*felt.Felt, proofs []ProofNode, hash hashFunc) (hasMore bool, valid bool, err error) { | ||
func VerifyRange(root, startKey *felt.Felt, keys, values []*felt.Felt, proofs []ProofNode, hash hashFunc, | ||
asdacap marked this conversation as resolved.
Show resolved
Hide resolved
|
||
treeHeight uint8, | ||
) (hasMore, valid bool, oerr error) { | ||
proofMap := map[felt.Felt]ProofNode{} | ||
for _, proof := range proofs { | ||
proofHash := proof.Hash(hash) | ||
|
@@ -67,21 +69,21 @@ | |
// Special case where the whole trie is sent in one go. | ||
// We just need to completely reconstruct the trie. | ||
|
||
tempTrie, err := newTrie(newMemStorage(), 251, hash) //nolint:gomnd | ||
tempTrie, err := newTrie(newMemStorage(), treeHeight, hash) | ||
if err != nil { | ||
return false, false, err | ||
} | ||
|
||
for i, key := range keys { | ||
_, err := tempTrie.Put(key, values[i]) | ||
_, err = tempTrie.Put(key, values[i]) | ||
if err != nil { | ||
return false, false, err | ||
} | ||
} | ||
|
||
recalculatedRoot, err := tempTrie.Root() | ||
if err != nil { | ||
return false, false, err | ||
} | ||
|
||
if !root.Equal(recalculatedRoot) { | ||
|
@@ -97,30 +99,20 @@ | |
} | ||
|
||
proofKeys := map[felt.Felt]Key{} | ||
err = buildKeys(NewKey(0, []byte{}), root, proofMap, proofKeys, 0) | ||
err := buildKeys(NewKey(0, []byte{}), root, proofMap, proofKeys, 0) | ||
asdacap marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err != nil { | ||
return false, false, err | ||
} | ||
|
||
// No idea how this work | ||
/* | ||
proofValuesArray := []*felt.Felt{} | ||
proofKeysArray := []*Key{} | ||
for f, key := range proofKeys { | ||
proofValuesArray = append(proofValuesArray, &f) | ||
proofKeysArray = append(proofKeysArray, &key) | ||
} | ||
|
||
VerifyRangeProof(root, keys, values, nil, nil, nil, hash) | ||
*/ | ||
// TODO: Verify here proof here | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to 1) verify the left and right proofs here (assuming both exist), and, 2) calculate the root hash of the new trie built from the keys and boundary proofs right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, I don't know what you have in mind for this. IMO, last time, I just add the leaves first, then add the proof one by one (key->hash, not key->proffnode), unless the exact key already have a node. |
||
|
||
hasMoreKeyCheck := startKey | ||
asdacap marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if len(keys) > 0 { | ||
hasMoreKeyCheck = keys[len(keys)-1] | ||
} | ||
|
||
feltBytes := hasMoreKeyCheck.Bytes() | ||
asdacap marked this conversation as resolved.
Show resolved
Hide resolved
|
||
hasMoreKeyCheckKey := NewKey(251, feltBytes[:]) | ||
hasMoreKeyCheckKey := NewKey(treeHeight, feltBytes[:]) | ||
|
||
// does this actually work on all case? | ||
hasMore = false | ||
|
@@ -146,7 +138,7 @@ | |
ch := proofNode.Edge.Child | ||
err := buildKeys(chKey, ch, proofMap, keys, depth+1) | ||
if err != nil { | ||
return err | ||
} | ||
} else { | ||
binary := proofNode.Binary | ||
|
@@ -155,14 +147,14 @@ | |
ch := binary.LeftHash | ||
err := buildKeys(chKey, ch, proofMap, keys, depth+1) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
chKey = currentKey.AppendBit(true) | ||
ch = binary.RightHash | ||
err = buildKeys(chKey, ch, proofMap, keys, depth+1) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious why this approach was taken. Would it not have been simpler to check if there are any leaves to the left (/right) of the startQuery (/endQuery), and return a left (/right) proof if there were? I find the iteration and consumer logic a bit confusing tbh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of this function is to just get the proofs required for the given range and trie right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change the function signature to
func (t *Trie) GenerateProof(startRangeKey, endRangeKey *felt.Felt) ([]ProofNode, bool, error)
then we could remove the iteration and consumer logic, and simplify this a lot (by just checking if there are any nodes to the left of the startRangeKey, and the right of endRangeKey). What are your thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of the function is BOTH iterate and generate proof. Think higher level. The reason its a consumer function is that the condition to stop getting leaves is complicated. It need to stop on:
Also, these are relatively large array. Where possible you don't wanna have one []*felt.Felt buffer. EG: in case of class, you actually just want the []core.Class, not the KV, but you do need the proof and you do need the class in the exact order.