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

feat: Support Adds in a Deep Subtree #8

Merged
merged 42 commits into from
Nov 10, 2022

Conversation

Manav-Aggarwal
Copy link
Member

@Manav-Aggarwal Manav-Aggarwal commented Oct 21, 2022

We need to support adds in a Deep Subtree, because a transaction being fraud-proven may add keys.

Description of how to do it here: #1 (comment)

Note that there is extra data that needs to go into the proof for this in order to allow IAVL to have the data it needs to do rebalancing.

@Manav-Aggarwal Manav-Aggarwal linked an issue Oct 21, 2022 that may be closed by this pull request
@Manav-Aggarwal Manav-Aggarwal self-assigned this Oct 21, 2022
@Manav-Aggarwal Manav-Aggarwal changed the title Add test to check add operation in deepsubtree: WIP feat: Add test to check add operation in deepsubtree: WIP Oct 21, 2022
@Manav-Aggarwal Manav-Aggarwal changed the title feat: Add test to check add operation in deepsubtree: WIP feat: Support Adds and Deletes in a Deep Subtree Oct 21, 2022
@Manav-Aggarwal Manav-Aggarwal force-pushed the manva/add_add_and_delete branch 3 times, most recently from 4b0cf54 to 4f54740 Compare October 27, 2022 13:50
@Manav-Aggarwal Manav-Aggarwal marked this pull request as ready for review October 28, 2022 09:29
Comment on lines 145 to 136
fmt.Println("PRINT TREE")
_ = printNode(tree.ndb, tree.root, 0)
fmt.Println("PRINT TREE END")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use Println in tests. Use t.Log.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Check root hashes are equal
require.Equal(dst.root.hash, tree.root.hash)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @musalbas mentioned add a bunch of (potentially larger) randomized tests, that:

  • batch-add
  • batch-remove

IMO, looking into the SMT tests for inspiration (even if it does not do rebalancing), is a good idea. Add some light fuzzing maybe.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, add table-driven tests for each public method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented in #15

deepsubtree.go Show resolved Hide resolved
if !bytes.Equal(key, node.key) {
return nil, false, fmt.Errorf("adding new keys is not supported")
switch bytes.Compare(key, node.key) {
case -1:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment to each case

* Export siblings

* Add deepsubtree constructor

* Support empty root hashes

* Use working hash instead of root.hash
@Manav-Aggarwal Manav-Aggarwal changed the base branch from tzdybal/simple_dst to manav/dst_with_updates November 1, 2022 16:31
deepsubtree.go Show resolved Hide resolved
deepsubtree.go Outdated Show resolved Hide resolved
deepsubtree.go Outdated Show resolved Hide resolved
deepsubtree.go Outdated Show resolved Hide resolved
deepsubtree.go Outdated Show resolved Hide resolved
deepsubtree.go Outdated Show resolved Hide resolved
@Manav-Aggarwal Manav-Aggarwal changed the base branch from manav/dst_with_updates to deepsubtrees November 3, 2022 21:56
@Manav-Aggarwal Manav-Aggarwal changed the title feat: Support Adds and Deletes in a Deep Subtree feat: Support Adds in a Deep Subtree Nov 4, 2022
Copy link
Member

@tzdybal tzdybal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving as this is just a PR for topic branch.

Cleanup suggested by Matt make a lot of sense 👍 , but we may as well revisit it later.

deepsubtree.go Outdated
}

// Returns the sibling node of a leaf node with given key
func (tree *ImmutableTree) getSiblingNode(key []byte) (*Node, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks kind of redundant. recursiveGetSiblingNode already returns node or error. I guess this may be a leftover after refactoring.

Copy link
Member Author

@Manav-Aggarwal Manav-Aggarwal Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turned getSiblingNode into an exported method. Cleaner to have a wrapper method with fewer arguments and stay consistent with how Remove and Set have recursiveRemove and recursiveSet as well.

@MSevey
Copy link

MSevey commented Nov 8, 2022

but we may as well revisit it later.

Why not just address it now? Not addressing it now means I wasted my time reviewing and will need to do the same review again in the future which doesn't make sense.

Additionally, addressing reviews helps developers apply those improves to future code, thus further reducing the review burden.

Copy link

@MSevey MSevey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you maybe didn't push the changes? I do see the diff reflecting your comments.

@Manav-Aggarwal
Copy link
Member Author

Sorry about that, just pushed the changes.

@codecov-commenter
Copy link

Codecov Report

❗ No coverage uploaded for pull request base (deepsubtrees@690c59a). Click here to learn what that means.
The diff coverage is n/a.

@@               Coverage Diff               @@
##             deepsubtrees       #8   +/-   ##
===============================================
  Coverage                ?   63.48%           
===============================================
  Files                   ?       28           
  Lines                   ?     4869           
  Branches                ?        0           
===============================================
  Hits                    ?     3091           
  Misses                  ?     1369           
  Partials                ?      409           

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

deepsubtree.go Outdated
orphans := dst.prepareOrphansSlice()
node.persisted = false
newNode, err := dst.balance(node, &orphans)
node.persisted = true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be be after the error check?

Copy link
Member Author

@Manav-Aggarwal Manav-Aggarwal Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't change code behavior, but you're correct, it's cleaner to do the error check right after the call :)

@@ -247,26 +522,40 @@ func (node *Node) getLowestKey() []byte {
return lowestKey
}

func (dst *DeepSubTree) AddProof(proof *ics23.CommitmentProof) error {
proof = ics23.Decompress(proof)
func (dst *DeepSubTree) AddExistenceProof(existProof *ics23.ExistenceProof) error {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export should have comment

Copy link

@MSevey MSevey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question and one comment, both can be handled in a follow up. 👍

@Manav-Aggarwal Manav-Aggarwal merged commit 6142e14 into deepsubtrees Nov 10, 2022
@Manav-Aggarwal
Copy link
Member Author

Manav-Aggarwal commented Nov 10, 2022

Closing this, thanks for all the valuable comments @MSevey, @tzdybal, and @liamsi!

Manav-Aggarwal added a commit that referenced this pull request Dec 20, 2022
* ICS23-style approach for DeepSubTree creation

* Fix deepsubtree, all checks pass

* Update documentation for deep subtrees

* Fix deepsubtree to accomodate left/right paths both

* Refactor test code

* Refactor TestDeepSubtreeStepByStep

* Address comments

* Refactor code

* Disable gocritic and unused

* Add description

* Refactor code to check err in Set

* Modify traversal conditions to be clearer

* feat: build deep subtree from ICS23 inclusion proofs (#9)

* feat: build deep subtree from ICS23 inclusion proofs

* feat: handle non-existence proofs

* linter: goimports deepsubtree.go

* refactor: addExistenceProofProof -> addExistenceProof

* fix: un-hardcode size of byte array

* Add more comments

* Refactor ndb.Commit call outside for loop

* verify that in the case that dst.root != nil that the root node hash matches the provided hash and check dst.root != nil first

* Add strings and use strings.Repeat

* Delete addPath and AddPath

* Remove print statements

* Refactor recomputeHash usage

Co-authored-by: Matthew Sevey <[email protected]>

* return err directly

Co-authored-by: Matthew Sevey <[email protected]>

* Address linting checks

* Use tm-db instead of cosmos-db

* Fix linter

* Add test to check add operation in deepsubtree: WIP

* Add insert key functionality WIP

* Try replicating non-inclusion proofs

* Add sibling nodes to nonExistenceProofs

* Refactor test code

* Finish adding add functionality to dst

* Add Remove functionality to dst

* Fix linting errors

* Fix GetSiblingNode

* Remove more print statements

* Add comment for each case in recursive set

* Change which methods are exported and document exported methods

* feat: Support Empty Hashes and Add constructor (#11)

* Export siblings

* Add deepsubtree constructor

* Support empty root hashes

* Use working hash instead of root.hash

* Use tm-db instead of cosmos-db

* Return nil in BuildTree

* Address comments

* Address more comments

Co-authored-by: Tomasz Zdybał <[email protected]>
Co-authored-by: Matthew Sevey <[email protected]>
Manav-Aggarwal added a commit that referenced this pull request Dec 20, 2022
* ICS23-style approach for DeepSubTree creation

* Fix deepsubtree, all checks pass

* Update documentation for deep subtrees

* Fix deepsubtree to accomodate left/right paths both

* Refactor test code

* Refactor TestDeepSubtreeStepByStep

* Address comments

* Refactor code

* Disable gocritic and unused

* Add description

* Refactor code to check err in Set

* Modify traversal conditions to be clearer

* feat: build deep subtree from ICS23 inclusion proofs (#9)

* feat: build deep subtree from ICS23 inclusion proofs

* feat: handle non-existence proofs

* linter: goimports deepsubtree.go

* refactor: addExistenceProofProof -> addExistenceProof

* fix: un-hardcode size of byte array

* Add more comments

* Refactor ndb.Commit call outside for loop

* verify that in the case that dst.root != nil that the root node hash matches the provided hash and check dst.root != nil first

* Add strings and use strings.Repeat

* Delete addPath and AddPath

* Remove print statements

* Refactor recomputeHash usage

Co-authored-by: Matthew Sevey <[email protected]>

* return err directly

Co-authored-by: Matthew Sevey <[email protected]>

* Address linting checks

* Use tm-db instead of cosmos-db

* Fix linter

* Add test to check add operation in deepsubtree: WIP

* Add insert key functionality WIP

* Try replicating non-inclusion proofs

* Add sibling nodes to nonExistenceProofs

* Refactor test code

* Finish adding add functionality to dst

* Add Remove functionality to dst

* Fix linting errors

* Fix GetSiblingNode

* Remove more print statements

* Add comment for each case in recursive set

* Change which methods are exported and document exported methods

* feat: Support Empty Hashes and Add constructor (#11)

* Export siblings

* Add deepsubtree constructor

* Support empty root hashes

* Use working hash instead of root.hash

* Use tm-db instead of cosmos-db

* Return nil in BuildTree

* Address comments

* Address more comments

Co-authored-by: Tomasz Zdybał <[email protected]>
Co-authored-by: Matthew Sevey <[email protected]>
Manav-Aggarwal added a commit that referenced this pull request Jan 18, 2023
* feat: Deep tree structure with Updates (#13)

* ICS23-style approach for DeepSubTree creation

* Fix deepsubtree, all checks pass

* Update documentation for deep subtrees

* Fix deepsubtree to accomodate left/right paths both

* Refactor test code

* Refactor TestDeepSubtreeStepByStep

* Address comments

* Refactor code

* Disable gocritic and unused

* Add description

* Refactor code to check err in Set

* Modify traversal conditions to be clearer

* feat: build deep subtree from ICS23 inclusion proofs (#9)

* feat: build deep subtree from ICS23 inclusion proofs

* feat: handle non-existence proofs

* linter: goimports deepsubtree.go

* refactor: addExistenceProofProof -> addExistenceProof

* fix: un-hardcode size of byte array

* Add more comments

* Refactor ndb.Commit call outside for loop

* verify that in the case that dst.root != nil that the root node hash matches the provided hash and check dst.root != nil first

* Add strings and use strings.Repeat

* Delete addPath and AddPath

* Remove print statements

* Refactor recomputeHash usage

Co-authored-by: Matthew Sevey <[email protected]>

* return err directly

Co-authored-by: Matthew Sevey <[email protected]>

* Address linting checks

* Use tm-db instead of cosmos-db

* Fix linter

* Update comment

Co-authored-by: Matthew Sevey <[email protected]>

* Add error checking for node hash

* turn lengthByte into a const

* Refactor linkNode

* Update comment

Co-authored-by: Tomasz Zdybał <[email protected]>
Co-authored-by: Matthew Sevey <[email protected]>

* feat: Support Adds in a Deep Subtree (#8)

* ICS23-style approach for DeepSubTree creation

* Fix deepsubtree, all checks pass

* Update documentation for deep subtrees

* Fix deepsubtree to accomodate left/right paths both

* Refactor test code

* Refactor TestDeepSubtreeStepByStep

* Address comments

* Refactor code

* Disable gocritic and unused

* Add description

* Refactor code to check err in Set

* Modify traversal conditions to be clearer

* feat: build deep subtree from ICS23 inclusion proofs (#9)

* feat: build deep subtree from ICS23 inclusion proofs

* feat: handle non-existence proofs

* linter: goimports deepsubtree.go

* refactor: addExistenceProofProof -> addExistenceProof

* fix: un-hardcode size of byte array

* Add more comments

* Refactor ndb.Commit call outside for loop

* verify that in the case that dst.root != nil that the root node hash matches the provided hash and check dst.root != nil first

* Add strings and use strings.Repeat

* Delete addPath and AddPath

* Remove print statements

* Refactor recomputeHash usage

Co-authored-by: Matthew Sevey <[email protected]>

* return err directly

Co-authored-by: Matthew Sevey <[email protected]>

* Address linting checks

* Use tm-db instead of cosmos-db

* Fix linter

* Add test to check add operation in deepsubtree: WIP

* Add insert key functionality WIP

* Try replicating non-inclusion proofs

* Add sibling nodes to nonExistenceProofs

* Refactor test code

* Finish adding add functionality to dst

* Add Remove functionality to dst

* Fix linting errors

* Fix GetSiblingNode

* Remove more print statements

* Add comment for each case in recursive set

* Change which methods are exported and document exported methods

* feat: Support Empty Hashes and Add constructor (#11)

* Export siblings

* Add deepsubtree constructor

* Support empty root hashes

* Use working hash instead of root.hash

* Use tm-db instead of cosmos-db

* Return nil in BuildTree

* Address comments

* Address more comments

Co-authored-by: Tomasz Zdybał <[email protected]>
Co-authored-by: Matthew Sevey <[email protected]>

* Add randomized tests for adding/removing keys (#16)

* Add go fuzz tests

* Add membership proof for existing keys

* Build tree after adding membership proof

* Make batch add fuzz tests work

* Do not commit version twice for dst

* Save version out of dst.Set condition

* Set rootHash to workingHash

* Fix edge cases

* Refactor DST Non-Existence Proof

* Change cacheSize

* Add test data and sibling nodes for each node in path

* Fix GetSiblingNodes

* Add more test data

* testing: fuzz: failing test case

* Use set for keys

* Add more test data

* Refactor existence proofs code

* Add required info for remove operation

* Add children of siblings as well

* Remove debug code

* Add testdata that breaks current code

* Fix bug

* Add failing testcase

* Add breaking testcase

* IAVL with tracing

* Fuzz tests pass

* Refactor tracing code

* Remove redundant code

* Remove working hash in calls to AddExistenceProof

* Clean up flag

* Make build tree a private method

* Add back whitespace in node.go

* Add new ci for fuzz

* Refactor more

* Refactor out getKey method

* Change name to reapInclusionProofs

* Refactor set and remove in DST

* Factor out add existence proofs from Remove DST for consistency with Set

* Refactor into testContext

* Clean up setInDST

Co-authored-by: Tomasz Zdybał <[email protected]>

* Add tracing to Trees and Deep Subtrees (#18)

* Add go fuzz tests

* Add membership proof for existing keys

* Build tree after adding membership proof

* Make batch add fuzz tests work

* Do not commit version twice for dst

* Save version out of dst.Set condition

* Set rootHash to workingHash

* Fix edge cases

* Refactor DST Non-Existence Proof

* Change cacheSize

* Add test data and sibling nodes for each node in path

* Fix GetSiblingNodes

* Add more test data

* testing: fuzz: failing test case

* Use set for keys

* Add more test data

* Refactor existence proofs code

* Add required info for remove operation

* Add children of siblings as well

* Remove debug code

* Add testdata that breaks current code

* Fix bug

* Add failing testcase

* Add breaking testcase

* IAVL with tracing

* Fuzz tests pass

* Refactor tracing code

* Remove redundant code

* Remove working hash in calls to AddExistenceProof

* Clean up flag

* Make build tree a private method

* Add back whitespace in node.go

* Add new ci for fuzz

* Refactor more

* Refactor out getKey method

* Change name to reapInclusionProofs

* Refactor set and remove in DST

* Factor out add existence proofs from Remove DST for consistency with Set

* Refactor into testContext

* Clean up setInDST

* Add method for get

* Export methods

* Add witness data to deep subtree

* Verify operation in witness data

* Refactor and verify operation for get and remove

* Add set witness data

* Add tracing to tree

* add getter for witness data

* Verify existence proofs in dst

* Cleanup

* Reset witness data on tracing enabled

* Add node to keysAccessed even not in cache

* Add initial root hash

* Refactor GetInitialRootHash

* Modify GetInitialRootHash

* Add test data

* Add get to dst tests: fails right now

* Refactor and add tracing for root key as well

* Add docs

* Add more docs

* Update comments

* Update log message

Co-authored-by: Tomasz Zdybał <[email protected]>

* allocate length

Co-authored-by: Tomasz Zdybał <[email protected]>

* fix: remove `RangeProofs` (cosmos#586)

Co-authored-by: colin axnér <[email protected]>
Co-authored-by: Marko <[email protected]>

* Update go.mod file

* Add new line at end of .golangci.yml

Co-authored-by: Tomasz Zdybał <[email protected]>
Co-authored-by: Matthew Sevey <[email protected]>
Co-authored-by: cool-developer <[email protected]>
Co-authored-by: colin axnér <[email protected]>
Co-authored-by: Marko <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Adds in a Deep Subtree
5 participants