Skip to content
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

Closed
wants to merge 39 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5cd826f
updating verify proof range to handle empty proof keys
Jun 7, 2024
3ecb395
test non set proof key - wip
Jun 7, 2024
d2fe491
wip - proof to Path doesn't work
Jun 7, 2024
2cd3157
store the hashes of children in ProofToPath
Jun 8, 2024
3603e28
ProoftoPath update to handle unset proof key
Jun 8, 2024
d8f5811
test - wip
Jun 8, 2024
40a3d04
test - wip
Jun 9, 2024
fb6c899
test passes! :D
Jun 10, 2024
07e99f5
lint
Jun 10, 2024
c0b933a
tidy
Jun 10, 2024
529aef2
fixing tests that broke wip
Jun 10, 2024
ca360e9
build4keyTrie passes again!
Jun 11, 2024
fdf6af2
fixed more tests
Jun 11, 2024
9f9f2fe
fix test wip
Jun 11, 2024
bad7267
fix more tests
Jun 11, 2024
92a98df
fix test -wip
Jun 11, 2024
727801b
fix tests wip
Jun 11, 2024
b4ae2b6
wip
Jun 11, 2024
a123730
all tests passgit add .
Jun 12, 2024
d249186
lint
Jun 12, 2024
21f9453
tidy
Jun 12, 2024
2d7c6e8
tidy logic
Jun 12, 2024
46c7b8a
tidy logic
Jun 12, 2024
0bb2edc
tidy logic
Jun 12, 2024
ce20e08
comment: update getLeftRightHash
Jun 12, 2024
ec2f917
update ProofToPath comment
Jun 12, 2024
dd21cc0
bubble up getLeftRightHash err
Jun 12, 2024
571eb6e
Trie iterate
asdacap Jun 14, 2024
b614c2e
Address comment
asdacap Jun 14, 2024
89cf035
Merge branch 'feature/trie-iterate' into snap/merge-range-and-proof
asdacap Jun 19, 2024
20e2aa0
Snap support
asdacap Jun 20, 2024
faa0884
Finished is needed internally
asdacap Jun 20, 2024
59440ac
Missed a printf
asdacap Jun 20, 2024
35b46d0
Format
asdacap Jun 20, 2024
cb26dd7
Fix lint
asdacap Jun 20, 2024
1454ad5
Update core/trie/key.go
asdacap Jun 25, 2024
d4b4232
Update core/trie/snap_support.go
asdacap Jun 25, 2024
4f4940f
address keys
asdacap Jun 27, 2024
909914d
Fix lint
asdacap Jun 27, 2024
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
Prev Previous commit
Next Next commit
tidy logic
  • Loading branch information
rian committed Jun 12, 2024
commit 46c7b8a8655159c2aeb6202e7431486ed7f18a39
87 changes: 32 additions & 55 deletions core/trie/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@
proofs := [2][]ProofNode{}
leftProof, err := GetProof(leftBoundary, tri)
if err != nil {
return proofs, err

Check warning on line 66 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L66

Added line #L66 was not covered by tests
}
rightProof, err := GetProof(rightBoundary, tri)
if err != nil {
return proofs, err

Check warning on line 70 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L70

Added line #L70 was not covered by tests
}
proofs[0] = leftProof
proofs[1] = rightProof
Expand Down Expand Up @@ -219,18 +219,18 @@
) (bool, error) {
// Step 0: checks
if len(keys) != len(values) {
return false, fmt.Errorf("inconsistent proof data, number of keys: %d, number of values: %d", len(keys), len(values))

Check warning on line 222 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L222

Added line #L222 was not covered by tests
}

// Ensure all keys are monotonic increasing
if err := ensureMonotonicIncreasing(proofKeys, keys); err != nil {
return false, err

Check warning on line 227 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L227

Added line #L227 was not covered by tests
}

// Ensure the inner values contain no deletions
for _, value := range values {
if value.Equal(&felt.Zero) {
return false, errors.New("range contains deletion")

Check warning on line 233 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L233

Added line #L233 was not covered by tests
}
}

Expand All @@ -240,12 +240,12 @@
for i := 0; i < 2; i++ {
if proofs[i] != nil {
if !VerifyProof(root, proofKeys[i], proofValues[i], proofs[i], hash) {
return false, fmt.Errorf("invalid proof for key %x", proofKeys[i].String())

Check warning on line 243 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L243

Added line #L243 was not covered by tests
}

proofPaths[i], err = ProofToPath(proofs[i], proofKeys[i], hash)
if err != nil {
return false, err

Check warning on line 248 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L248

Added line #L248 was not covered by tests
}
}
}
Expand All @@ -253,16 +253,16 @@
// Step 2: Build trie from proofPaths and keys
tmpTrie, err := BuildTrie(proofPaths[0], proofPaths[1], keys, values)
if err != nil {
return false, err

Check warning on line 256 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L256

Added line #L256 was not covered by tests
}

// Verify that the recomputed root hash matches the provided root hash
recomputedRoot, err := tmpTrie.Root()
if err != nil {
return false, err

Check warning on line 262 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L262

Added line #L262 was not covered by tests
}
if !recomputedRoot.Equal(root) {
return false, errors.New("root hash mismatch")

Check warning on line 265 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L265

Added line #L265 was not covered by tests
}

return true, nil
Expand All @@ -272,67 +272,58 @@
if proofKeys[0] != nil {
leftProofFelt := proofKeys[0].Felt()
if leftProofFelt.Cmp(keys[0]) >= 0 {
return errors.New("range is not monotonically increasing")

Check warning on line 275 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L275

Added line #L275 was not covered by tests
}
}
if proofKeys[1] != nil {
rightProofFelt := proofKeys[1].Felt()
if keys[len(keys)-1].Cmp(&rightProofFelt) >= 0 {
return errors.New("range is not monotonically increasing")

Check warning on line 281 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L281

Added line #L281 was not covered by tests
}
}
if len(keys) >= 2 {
for i := 0; i < len(keys)-1; i++ {
if keys[i].Cmp(keys[i+1]) >= 0 {
return errors.New("range is not monotonically increasing")

Check warning on line 287 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L287

Added line #L287 was not covered by tests
}
}
}
return nil
}

// shouldSquish determines if the node needs compressed, and if so, the len needed to arrive at the next key
func shouldSquish(idx int, proofNodes []ProofNode, hashF hashFunc) (int, uint8, error) {
// compressNode determines if the node needs compressed, and if so, the len needed to arrive at the next key
func compressNode(idx int, proofNodes []ProofNode, hashF hashFunc) (int, uint8, error) {
parent := &proofNodes[idx]
if idx == len(proofNodes)-1 { // The node may have children, but we can only derive their hashes here
var isEdge int

if idx == len(proofNodes)-1 {
if parent.Edge != nil {
isEdge = 1
} else if parent.Binary != nil {
isEdge = 0
return 1, parent.Len(), nil
}
return isEdge, parent.Len(), nil
return 0, parent.Len(), nil
}

child := &proofNodes[idx+1]

if parent.Edge != nil && child.Binary != nil {
switch {
case parent.Edge != nil && child.Binary != nil:
return 1, parent.Edge.Path.len, nil
}

if parent.Binary != nil && child.Edge != nil {
case parent.Binary != nil && child.Edge != nil:
childHash := child.Hash(hashF)
if parent.Binary.LeftHash.Equal(childHash) {
return 1, child.Edge.Path.len, nil
} else if parent.Binary.RightHash.Equal(childHash) {
if parent.Binary.LeftHash.Equal(childHash) || parent.Binary.RightHash.Equal(childHash) {
return 1, child.Edge.Path.len, nil
} else {
return 0, 0, errors.New("can't determine the child hash from the parent and child")

Check warning on line 315 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L315

Added line #L315 was not covered by tests
}
}

if parent.Binary != nil && child.Binary != nil {
return 0, 1, nil
}

return 0, 1, nil
}

func assignChild(i, squishedParent int, crntNode *Node, nilKey, leafKey, crntKey *Key, proofNodes []ProofNode, hashF hashFunc) (*Key, error) {

Check failure on line 322 in core/trie/proof.go

View workflow job for this annotation

GitHub Actions / lint

line is 142 characters (lll)
childInd := i + squishedParent + 1
childKey, err := getChildKey(childInd, crntKey, leafKey, nilKey, proofNodes, hashF)
if err != nil {
return nil, err

Check warning on line 326 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L326

Added line #L326 was not covered by tests
}
if leafKey.Test(leafKey.len - crntKey.len - 1) {
crntNode.Right = childKey
Expand Down Expand Up @@ -363,39 +354,39 @@
}
}

var crntKey *Key
crntNode := Node{}
var parentKey *Key
parentNode := Node{}

// Set the key of the current node
squishedParent, squishParentOffset, err := shouldSquish(i, proofNodes, hashF)
compressParent, compressParentOffset, err := compressNode(i, proofNodes, hashF)
if err != nil {
return nil, err

Check warning on line 363 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L363

Added line #L363 was not covered by tests
}
crntKey, err = getCrntKey(i, squishParentOffset, leafKey, pNode, pathNodes, proofNodes)
parentKey, err = getParentKey(i, compressParentOffset, leafKey, pNode, pathNodes, proofNodes)
if err != nil {
return nil, err

Check warning on line 367 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L367

Added line #L367 was not covered by tests
}

// Set the value of the current node
crntNode.Value = pNode.Hash(hashF)

// End of the line, no children
if crntKey.len == 251 { //nolint:gomnd
// Don't store leafs along proof paths
if parentKey.len == 251 { //nolint:gomnd
break

Check warning on line 372 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L372

Added line #L372 was not covered by tests
}

// Set the value of the current node
parentNode.Value = pNode.Hash(hashF)

// Set the child key of the current node.
childKey, err := assignChild(i, squishedParent, &crntNode, &nilKey, leafKey, crntKey, proofNodes, hashF)
childKey, err := assignChild(i, compressParent, &parentNode, &nilKey, leafKey, parentKey, proofNodes, hashF)
if err != nil {
return nil, err

Check warning on line 381 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L381

Added line #L381 was not covered by tests
}

// Set the LeftHash and RightHash values
crntNode.LeftHash, crntNode.RightHash = getLeftRightHash(i, proofNodes)
parentNode.LeftHash, parentNode.RightHash = getLeftRightHash(i, proofNodes)

pathNodes = append(pathNodes, StorageNode{key: crntKey, node: &crntNode})
pathNodes = append(pathNodes, StorageNode{key: parentKey, node: &parentNode})

// break early
// break early since we don't store leafs along proof paths, or if no more nodes exist along the proof paths
if childKey.len == 0 || childKey.len == 251 {
break
}
Expand Down Expand Up @@ -434,14 +425,14 @@
return leftHash, rightHash
}

func getCrntKey(idx int, squishParentOffset uint8, leafKey *Key, pNode ProofNode, pathNodes []StorageNode, proofNodes []ProofNode) (*Key, error) {
func getParentKey(idx int, squishParentOffset uint8, leafKey *Key, pNode ProofNode, pathNodes []StorageNode, proofNodes []ProofNode) (*Key, error) {

Check failure on line 428 in core/trie/proof.go

View workflow job for this annotation

GitHub Actions / lint

line is 148 characters (lll)
var crntKey *Key
var err error

var height uint8
if len(pathNodes) > 0 {
if proofNodes[idx].Edge != nil {
height = pathNodes[len(pathNodes)-1].key.len + proofNodes[idx].Edge.Path.len

Check warning on line 435 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L435

Added line #L435 was not covered by tests
} else {
height = pathNodes[len(pathNodes)-1].key.len + 1
}
Expand All @@ -458,41 +449,27 @@
}

func getChildKey(childIdx int, crntKey, leafKey, nilKey *Key, proofNodes []ProofNode, hashF hashFunc) (*Key, error) {
var squishChildOffset uint8
var squishChild int
var err error
if childIdx > len(proofNodes)-1 {
return nilKey, nil
} else {
squishChild, squishChildOffset, err = shouldSquish(childIdx, proofNodes, hashF)
if err != nil {
return nil, err
}
}
if crntKey.len+uint8(squishChild)+squishChildOffset == 251 { //nolint:gomnd
return nilKey, nil

compressChild, compressChildOffset, err := compressNode(childIdx, proofNodes, hashF)
if err != nil {
return nil, err

Check warning on line 458 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L458

Added line #L458 was not covered by tests
}
key, err := leafKey.SubKey(crntKey.len + uint8(squishChild) + squishChildOffset)
return key, err
}

func getHeight(idx int, pathNodes []StorageNode, proofNodes []ProofNode) uint8 {
if len(pathNodes) > 0 {
if proofNodes[idx].Edge != nil {
return pathNodes[len(pathNodes)-1].key.len + proofNodes[idx].Edge.Path.len
} else {
return pathNodes[len(pathNodes)-1].key.len + 1
}
} else {
return 0
if crntKey.len+uint8(compressChild)+compressChildOffset == 251 { //nolint:gomnd
return nilKey, nil
}

return leafKey.SubKey(crntKey.len + uint8(compressChild) + compressChildOffset)
}

// BuildTrie builds a trie using the proof paths (including inner nodes), and then sets all the keys-values (leaves)
func BuildTrie(leftProofPath, rightProofPath []StorageNode, keys, values []*felt.Felt) (*Trie, error) { //nolint:gocyclo
tempTrie, err := NewTriePedersen(newMemStorage(), 251) //nolint:gomnd
if err != nil {
return nil, err

Check warning on line 472 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L472

Added line #L472 was not covered by tests
}

// merge proof paths
Expand All @@ -500,40 +477,40 @@
// Can't store nil keys so stop merging
if leftProofPath[i].node.Left == nil || leftProofPath[i].node.Right == nil ||
rightProofPath[i].node.Left == nil || rightProofPath[i].node.Right == nil {
break

Check warning on line 480 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L480

Added line #L480 was not covered by tests
}
if leftProofPath[i].key.Equal(rightProofPath[i].key) {
leftProofPath[i].node.Right = rightProofPath[i].node.Right
rightProofPath[i].node.Left = leftProofPath[i].node.Left
} else {
break

Check warning on line 486 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L486

Added line #L486 was not covered by tests
}
}

for _, sNode := range leftProofPath {
if sNode.node.Left == nil || sNode.node.Right == nil {
break

Check warning on line 492 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L492

Added line #L492 was not covered by tests
}
_, err := tempTrie.PutInner(sNode.key, sNode.node)
if err != nil {
return nil, err

Check warning on line 496 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L496

Added line #L496 was not covered by tests
}
}

for _, sNode := range rightProofPath {
if sNode.node.Left == nil || sNode.node.Right == nil {
break

Check warning on line 502 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L502

Added line #L502 was not covered by tests
}
_, err := tempTrie.PutInner(sNode.key, sNode.node)
if err != nil {
return nil, err

Check warning on line 506 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L506

Added line #L506 was not covered by tests
}
}

for i := range len(keys) {
_, err := tempTrie.PutWithProof(keys[i], values[i], leftProofPath, rightProofPath)
if err != nil {
return nil, err

Check warning on line 513 in core/trie/proof.go

View check run for this annotation

Codecov / codecov/patch

core/trie/proof.go#L513

Added line #L513 was not covered by tests
}
}
return tempTrie, nil
Expand Down
Loading