From 99821d4ea1b6a61c7589dfd6432a9ca70657e562 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:21:00 +0100 Subject: [PATCH 1/4] fix: Add Extra Check for Reformatted Root Node in GetNode (backport #1007) (#1009) Co-authored-by: cool-developer <51834436+cool-develope@users.noreply.github.com> Co-authored-by: Marko Baricevic --- CHANGELOG.md | 4 ++++ mutable_tree_test.go | 24 ++++++++++++++++++++++++ nodedb.go | 14 ++++++++++++++ 3 files changed, 42 insertions(+) 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 be10074db..c866ba0cc 100644 --- a/mutable_tree_test.go +++ b/mutable_tree_test.go @@ -1453,3 +1453,27 @@ func TestMutableTreeClose(t *testing.T) { require.NoError(t, tree.Close()) } + +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) } From d6b098dea30a198428691ba1313757593c68c056 Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Tue, 26 Nov 2024 12:27:15 +0100 Subject: [PATCH 2/4] changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e33e2d88..5a800a8c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # Changelog +## v1.2.2 November 26, 2024 ### Bug Fixes - [#1007](https://github.com/cosmos/iavl/pull/1007) Add the extra check for the reformatted root node in `GetNode` +## v1.2.1 July 31, 2024 + ### Improvements - [#961](https://github.com/cosmos/iavl/pull/961) Add new `GetLatestVersion` API to get the latest version. From b7bf354b5a4e180610f2f1541ceab293e0d52910 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:19:56 +0000 Subject: [PATCH 3/4] cache first version for legacy versions (backport #1018) (#1019) Co-authored-by: yihuang Co-authored-by: Marko --- CHANGELOG.md | 2 ++ nodedb.go | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a800a8c0..b860fbc20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - [#961](https://github.com/cosmos/iavl/pull/961) Add new `GetLatestVersion` API to get the latest version. - [#965](https://github.com/cosmos/iavl/pull/965) Use expected interface for expected IAVL `Logger`. - [#970](https://github.com/cosmos/iavl/pull/970) Close the pruning process when the nodeDB is closed. +- [#980](https://github.com/cosmos/iavl/pull/980) Use the `sdk/core/store.KVStoreWithBatch` interface instead of `iavl/db.DB` interface +- [#1018](https://github.com/cosmos/iavl/pull/1018) Cache first version for legacy versions, fix performance regression after upgrade. ## v1.2.0 May 13, 2024 diff --git a/nodedb.go b/nodedb.go index 8f2ccb480..f1833b2eb 100644 --- a/nodedb.go +++ b/nodedb.go @@ -740,6 +740,7 @@ func (ndb *nodeDB) getFirstVersion() (int64, error) { if itr.Valid() { var version int64 legacyRootKeyFormat.Scan(itr.Key(), &version) + ndb.resetFirstVersion(version) return version, nil } // Find the first version From 4f98c8acd426932196c72398e03429ad5fb66112 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Tue, 17 Dec 2024 15:03:23 +0100 Subject: [PATCH 4/4] fix: Better lock handling on close (#1024) --- nodedb.go | 9 +++++---- nodedb_test.go | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nodedb.go b/nodedb.go index f1833b2eb..53db1908e 100644 --- a/nodedb.go +++ b/nodedb.go @@ -602,7 +602,7 @@ func (ndb *nodeDB) startPruning() { for { select { case <-ndb.ctx.Done(): - ndb.done <- struct{}{} + close(ndb.done) return default: ndb.mtx.Lock() @@ -1121,14 +1121,15 @@ func (ndb *nodeDB) traverseOrphans(prevVersion, curVersion int64, fn func(*Node) // Close the nodeDB. func (ndb *nodeDB) Close() error { - ndb.mtx.Lock() - defer ndb.mtx.Unlock() - ndb.cancel() + if ndb.opts.AsyncPruning { <-ndb.done // wait for the pruning process to finish } + ndb.mtx.Lock() + defer ndb.mtx.Unlock() + if ndb.batch != nil { if err := ndb.batch.Close(); err != nil { return err diff --git a/nodedb_test.go b/nodedb_test.go index 3e88c354f..b2d4796ab 100644 --- a/nodedb_test.go +++ b/nodedb_test.go @@ -444,4 +444,5 @@ func TestCloseNodeDB(t *testing.T) { opts.AsyncPruning = true ndb := newNodeDB(db, 0, opts, NewNopLogger()) require.NoError(t, ndb.Close()) + require.NoError(t, ndb.Close()) // must not block or fail on second call }