diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e6eae9e1..6e33e2d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog +### Bug Fixes + +- [#1007](https://github.com/cosmos/iavl/pull/1007) Add the extra check for the reformatted root node in `GetNode` + ### Improvements - [#961](https://github.com/cosmos/iavl/pull/961) Add new `GetLatestVersion` API to get the latest version. diff --git a/mutable_tree_test.go b/mutable_tree_test.go index c866ba0cc..b5b5f342f 100644 --- a/mutable_tree_test.go +++ b/mutable_tree_test.go @@ -1477,3 +1477,27 @@ func TestReferenceRootPruning(t *testing.T) { _, err = tree.Set([]byte("foo"), []byte("bar*")) require.NoError(t, err) } + +func TestReferenceRootPruning(t *testing.T) { + memDB := dbm.NewMemDB() + tree := NewMutableTree(memDB, 0, true, NewNopLogger()) + + _, err := tree.Set([]byte("foo"), []byte("bar")) + require.NoError(t, err) + _, _, err = tree.SaveVersion() + require.NoError(t, err) + + _, _, err = tree.SaveVersion() + require.NoError(t, err) + + _, err = tree.Set([]byte("foo1"), []byte("bar")) + require.NoError(t, err) + _, _, err = tree.SaveVersion() + require.NoError(t, err) + + err = tree.DeleteVersionsTo(1) + require.NoError(t, err) + + _, err = tree.Set([]byte("foo"), []byte("bar*")) + require.NoError(t, err) +} diff --git a/nodedb.go b/nodedb.go index 7810acbf2..8f2ccb480 100644 --- a/nodedb.go +++ b/nodedb.go @@ -159,6 +159,20 @@ func (ndb *nodeDB) GetNode(nk []byte) (*Node, error) { if err != nil { return nil, fmt.Errorf("can't get node %v: %v", nk, err) } + if buf == nil && !isLegcyNode { + // if the node is reformatted by pruning, check against (version, 0) + nKey := GetNodeKey(nk) + if nKey.nonce == 1 { + nodeKey = ndb.nodeKey((&NodeKey{ + version: nKey.version, + nonce: 0, + }).GetKey()) + buf, err = ndb.db.Get(nodeKey) + if err != nil { + return nil, fmt.Errorf("can't get the reformatted node %v: %v", nk, err) + } + } + } if buf == nil { return nil, fmt.Errorf("Value missing for key %v corresponding to nodeKey %x", nk, nodeKey) }