Skip to content

Commit e6f70d1

Browse files
PaddyMcmergify[bot]
authored andcommitted
fix: get latest version in store after legacy pruning fails (#1067)
(cherry picked from commit 00941d2)
1 parent b31498d commit e6f70d1

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

nodedb.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,15 @@ func (ndb *nodeDB) deleteVersionsTo(toVersion int64) error {
726726
if err := ndb.deleteLegacyVersions(legacyLatestVersion); err != nil {
727727
ndb.logger.Error("Error deleting legacy versions", "err", err)
728728
}
729-
first = legacyLatestVersion + 1
729+
// NOTE: When pruning is broken for legacy versions we need to find the
730+
// latest non legacy version in the store
731+
// TODO: Make sure legacy pruning works as expected and does not fail
732+
firstNonLegacyVersion, err := ndb.getFirstNonLegacyVersion()
733+
if err != nil {
734+
return err
735+
}
736+
first = firstNonLegacyVersion
737+
730738
// reset the legacy latest version forcibly to avoid multiple calls
731739
ndb.resetLegacyLatestVersion(-1)
732740
}
@@ -768,6 +776,35 @@ func (ndb *nodeDB) legacyRootKey(version int64) []byte {
768776
return legacyRootKeyFormat.Key(version)
769777
}
770778

779+
// getFirstNonLegacyVersion binary searches the store for the first non-legacy version
780+
func (ndb *nodeDB) getFirstNonLegacyVersion() (int64, error) {
781+
ndb.mtx.Lock()
782+
firstVersion := ndb.firstVersion
783+
ndb.mtx.Unlock()
784+
785+
// Find the first version
786+
_, latestVersion, err := ndb.getLatestVersion()
787+
if err != nil {
788+
return 0, err
789+
}
790+
for firstVersion < latestVersion {
791+
version := (latestVersion + firstVersion) >> 1
792+
has, err := ndb.hasVersion(version)
793+
if err != nil {
794+
return 0, err
795+
}
796+
if has {
797+
latestVersion = version
798+
} else {
799+
firstVersion = version + 1
800+
}
801+
}
802+
803+
ndb.resetFirstVersion(latestVersion)
804+
805+
return latestVersion, nil
806+
}
807+
771808
func (ndb *nodeDB) getFirstVersion() (int64, error) {
772809
ndb.mtx.Lock()
773810
firstVersion := ndb.firstVersion

nodedb_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,43 @@ func TestCloseNodeDB(t *testing.T) {
446446
require.NoError(t, ndb.Close())
447447
require.NoError(t, ndb.Close()) // must not block or fail on second call
448448
}
449+
450+
func TestGetFirstNonLegacyVersion(t *testing.T) {
451+
db := dbm.NewMemDB()
452+
ndb := newNodeDB(db, 0, DefaultOptions(), NewNopLogger())
453+
454+
// Test case 1: Empty database
455+
firstVersion, err := ndb.getFirstNonLegacyVersion()
456+
require.NoError(t, err)
457+
require.Equal(t, int64(0), firstVersion)
458+
459+
// Test case 2: Database with only legacy versions
460+
// Create a legacy version at version 1
461+
legacyRoot := GetRootKey(1)
462+
require.NoError(t, ndb.batch.Set(ndb.legacyRootKey(1), legacyRoot))
463+
require.NoError(t, ndb.batch.Write())
464+
465+
firstVersion, err = ndb.getFirstNonLegacyVersion()
466+
require.NoError(t, err)
467+
require.Equal(t, int64(0), firstVersion)
468+
469+
// Test case 3: Database with both legacy and non-legacy versions
470+
// Create a non-legacy version at version 2
471+
nonLegacyRoot := GetRootKey(2)
472+
require.NoError(t, ndb.batch.Set(ndb.nodeKey(nonLegacyRoot), []byte{}))
473+
require.NoError(t, ndb.batch.Write())
474+
475+
firstVersion, err = ndb.getFirstNonLegacyVersion()
476+
require.NoError(t, err)
477+
require.Equal(t, int64(2), firstVersion)
478+
479+
// Test case 4: Database with multiple non-legacy versions
480+
// Create another non-legacy version at version 3
481+
nonLegacyRoot3 := GetRootKey(3)
482+
require.NoError(t, ndb.batch.Set(ndb.nodeKey(nonLegacyRoot3), []byte{}))
483+
require.NoError(t, ndb.batch.Write())
484+
485+
firstVersion, err = ndb.getFirstNonLegacyVersion()
486+
require.NoError(t, err)
487+
require.Equal(t, int64(2), firstVersion) // Should still return the first non-legacy version
488+
}

0 commit comments

Comments
 (0)