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

fix: Add refnode at InitialVersion pointing at version 1 root #2

Merged
merged 17 commits into from
Aug 21, 2024

Conversation

drklee3
Copy link
Member

@drklee3 drklee3 commented Aug 12, 2024

Background

  • Nodes are saved with version 1 instead of InitialVersion. This was part of the patch in order to preserve node hashes and thus apphash.
  • Loading version at InitialVersion is not found when it should, there is no separate rootnode lookup based on the different InitialVersion instead of root node version

Changes

  • Add test to reproduce issue to load versions due to our patch
  • Add initial patch to add a new refnode at InitialVersion that points at version 1 root node
  • Set the refnode at (InitialVersion, 0)
    • nonce of 0 similar to pruning such that it is only used by reference nodes and not shown as a valid version.

@drklee3 drklee3 changed the title test: Update test for loading patched initial version fix: Add refnode at InitialVersion pointing at version 1 root Aug 12, 2024
return tree.root.hashWithCount(tree.WorkingVersion())
// Use tree.version instead of tree.WorkingVersion() because tree.version
// is always the latest version
return tree.root.hashWithCount(tree.version + 1)
Copy link
Member

Choose a reason for hiding this comment

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

just saying out loud here that this must've been included in the live data we have or we would have gotten app hash mismatches with mainnet?

Copy link
Member

Choose a reason for hiding this comment

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

Cosmos v0.47.x doesn't use the WorkingHash/WorkingVersion afaik, they are just defined on the iavl interface and unused by the rootmultistore

Copy link
Member Author

@drklee3 drklee3 Aug 20, 2024

Choose a reason for hiding this comment

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

right - this mostly updated to ensure the tree tests pass and keep the behavior consistent.

I thought it could be a potential issue with rollbacks via LoadVersionForOverwriting - two cases:

  1. Not possible via "regular" rollbacks since you can't load InitialVersion-1 to write InitialVersion again
  2. Creating a new tree with an existing node database, which is dependent on cosmos sdk behavior. If the node database still exists for this tree and we create a new tree at InitialVersion, this would hit the codepath in SaveVersion() that calls WorkingHash() that produces an incorrect mismatch

Added a test for the second case to make sure we aren't depending on cosmos handling it properly and WorkingHash() is correct in that case

Copy link
Member

Choose a reason for hiding this comment

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

Right, I forgot about the WorkingHash within those methods 🤦. I read through the LoadVersionForOverwriting test, nice comments there too -- some great thinking into how the iavl library is used 💯

Copy link
Member

@pirtleshell pirtleshell left a comment

Choose a reason for hiding this comment

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

excellent test coverage and we love a fix that doesn't require syncing from the upgrades again (or injecting more complex data into the tree than a reference node pointer to an existing data node)

seems good to merge as long as test for pruning are on our radar and either included here or in a different pr.

@drklee3 drklee3 marked this pull request as ready for review August 16, 2024 18:57
mutable_tree.go Outdated Show resolved Hide resolved
@drklee3 drklee3 force-pushed the dl-v1.2.0-initial-node-ver branch from 6365e4e to 01ca777 Compare August 16, 2024 19:58
Copy link
Member

@nddeluca nddeluca left a comment

Choose a reason for hiding this comment

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

Approved! Great testing -- I'm confident from reading the tests that we've not only fixed the iavl hash compatibility with new modified trees on upgrades, but fetching versions and pruning also will work as expected.

The only thing I saw is there is one test that is still skipped -- I'm not sure if that's meant to be a reference or we missed updating it.

@@ -761,10 +764,43 @@ func (tree *MutableTree) SaveVersion() ([]byte, int64, error) {
}
}
} else {
// No nodeKey, assign new nodeKeys and save nodes. This happens when
Copy link
Member

Choose a reason for hiding this comment

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

Well done explaining the logic branches here 👍

mutable_tree_test.go Outdated Show resolved Hide resolved
require.NoError(t, err)

// ------------------------------
// Verify
Copy link
Member

Choose a reason for hiding this comment

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

I like the comment and the test organization 🏎️

require.False(t, hasVersion1, "version 1 should not be found")

// Internal ndb methods for good measure
firstVersion, err := tree.ndb.getFirstVersion()
Copy link
Member

Choose a reason for hiding this comment

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

Defensive testing is great 🛡️

@@ -1952,5 +1955,5 @@ func TestWorkingHashWithInitialVersion(t *testing.T) {

commitHash1, _, err := tree.SaveVersion()
require.NoError(t, err)
require.Equal(t, commitHash1, commitHash)
assert.Equal(t, hex.EncodeToString(commitHash1), hex.EncodeToString(commitHash))
Copy link
Member

Choose a reason for hiding this comment

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

I prefer assert & comparing hex strings as well 👍

})

t.Run("3. AvailableVersions()", func(t *testing.T) {
versions := tree.AvailableVersions()
Copy link
Member

Choose a reason for hiding this comment

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

The attention to detail on exercising all affected API calls is excellent

@drklee3 drklee3 merged commit a6787a0 into release/v1.2.0-kava-v0.26-x Aug 21, 2024
4 checks passed
@drklee3 drklee3 deleted the dl-v1.2.0-initial-node-ver branch August 21, 2024 16:22
@drklee3 drklee3 mentioned this pull request Aug 21, 2024
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.

3 participants