-
Notifications
You must be signed in to change notification settings - Fork 0
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
fix: Add refnode at InitialVersion pointing at version 1 root #2
Conversation
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) |
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.
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?
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.
Cosmos v0.47.x doesn't use the WorkingHash/WorkingVersion afaik, they are just defined on the iavl interface and unused by the rootmultistore
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.
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:
- Not possible via "regular" rollbacks since you can't load
InitialVersion-1
to writeInitialVersion
again - 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 callsWorkingHash()
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
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.
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 💯
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.
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.
6365e4e
to
01ca777
Compare
This reverts commit 6365e4e. Adding this just so we have reference of the other option
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.
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 |
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.
Well done explaining the logic branches here 👍
require.NoError(t, err) | ||
|
||
// ------------------------------ | ||
// Verify |
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 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() |
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.
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)) |
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 prefer assert & comparing hex strings as well 👍
}) | ||
|
||
t.Run("3. AvailableVersions()", func(t *testing.T) { | ||
versions := tree.AvailableVersions() |
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 attention to detail on exercising all affected API calls is excellent
Background
InitialVersion
. This was part of the patch in order to preserve node hashes and thus apphash.InitialVersion
is not found when it should, there is no separate rootnode lookup based on the differentInitialVersion
instead of root node versionChanges
InitialVersion
that points at version 1 root node