Skip to content

Commit

Permalink
Merge pull request #67 from sei-protocol/KeepLastVersion
Browse files Browse the repository at this point in the history
KeepLastVersion config for pruning
  • Loading branch information
Kbhat1 authored Jun 25, 2024
2 parents 2f1baf4 + 12c0bcc commit 50e236f
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 35 deletions.
5 changes: 5 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ type StateStoreConfig struct {
// ImportNumWorkers defines the number of goroutines used during import
// defaults to 1
ImportNumWorkers int `mapstructure:"import-num-workers"`

// Whether to keep last version of a key during pruning or delete
// defaults to true
KeepLastVersion bool `mapstructure:"keep-last-version"`
}

func DefaultStateCommitConfig() StateCommitConfig {
Expand All @@ -98,5 +102,6 @@ func DefaultStateStoreConfig() StateStoreConfig {
KeepRecent: DefaultSSKeepRecent,
PruneIntervalSeconds: DefaultSSPruneInterval,
ImportNumWorkers: DefaultSSImportWorkers,
KeepLastVersion: true,
}
}
4 changes: 4 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ ss-prune-interval = {{ .StateStore.PruneIntervalSeconds }}
# defaults to 1
ss-import-num-workers = {{ .StateStore.ImportNumWorkers }}
# KeepLastVersion defines whether to keep last version of a key during pruning or delete
# defaults to true
ss-keep-last-version = {{ .StateStore.KeepLastVersion }}
`
8 changes: 5 additions & 3 deletions ss/pebbledb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,16 @@ func (db *Database) Prune(version int64) error {
}

// Seek to next key if we are at a version which is higher than prune height
if currVersionDecoded > version {
// Do not seek to next key if KeepLastVersion is false and we need to delete the previous key in pruning
if currVersionDecoded > version && (db.config.KeepLastVersion || prevVersionDecoded > version) {
itr.NextPrefix()
continue
}

// Delete a key if another entry for that key exists a larger version than original but leq to the prune height
// Delete a key if another entry for that key exists at a larger version than original but leq to the prune height
// Also delete a key if it has been tombstoned and its version is leq to the prune height
if prevVersionDecoded <= version && (bytes.Equal(prevKey, currKey) || valTombstoned(prevValEncoded)) {
// Also delete a key if KeepLastVersion is false and version is leq to the prune height
if prevVersionDecoded <= version && (bytes.Equal(prevKey, currKey) || valTombstoned(prevValEncoded) || !db.config.KeepLastVersion) {
err = batch.Delete(prevKeyEncoded, nil)
if err != nil {
return err
Expand Down
5 changes: 3 additions & 2 deletions ss/pebbledb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (

func TestStorageTestSuite(t *testing.T) {
s := &sstest.StorageTestSuite{
NewDB: func(dir string) (types.StateStore, error) {
return New(dir, config.DefaultStateStoreConfig())
NewDB: func(dir string, config config.StateStoreConfig) (types.StateStore, error) {
return New(dir, config)
},
Config: config.DefaultStateStoreConfig(),
EmptyBatchSize: 12,
}

Expand Down
121 changes: 91 additions & 30 deletions ss/test/storage_test_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"sync"

"github.com/cosmos/iavl"
"github.com/sei-protocol/sei-db/config"
"github.com/sei-protocol/sei-db/ss/types"
"github.com/stretchr/testify/suite"
"golang.org/x/exp/slices"
Expand All @@ -18,13 +19,14 @@ const (
type StorageTestSuite struct {
suite.Suite

NewDB func(dir string) (types.StateStore, error)
NewDB func(dir string, config config.StateStoreConfig) (types.StateStore, error)
EmptyBatchSize int
SkipTests []string
Config config.StateStoreConfig
}

func (s *StorageTestSuite) TestDatabaseClose() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
s.Require().NoError(db.Close())

Expand All @@ -34,7 +36,7 @@ func (s *StorageTestSuite) TestDatabaseClose() {

func (s *StorageTestSuite) TestDatabaseLatestVersion() {
tempDir := s.T().TempDir()
db, err := s.NewDB(tempDir)
db, err := s.NewDB(tempDir, s.Config)
s.Require().NoError(err)

lv, err := db.GetLatestVersion()
Expand All @@ -55,7 +57,7 @@ func (s *StorageTestSuite) TestDatabaseLatestVersion() {
err = db.Close()
s.Require().NoError(err)

newDB, err := s.NewDB(tempDir)
newDB, err := s.NewDB(tempDir, s.Config)
s.Require().NoError(err)
defer newDB.Close()

Expand All @@ -66,7 +68,7 @@ func (s *StorageTestSuite) TestDatabaseLatestVersion() {
}

func (s *StorageTestSuite) TestDatabaseVersionedKeys() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand All @@ -80,7 +82,7 @@ func (s *StorageTestSuite) TestDatabaseVersionedKeys() {
}

func (s *StorageTestSuite) TestDatabaseGetVersionedKey() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -149,7 +151,7 @@ func (s *StorageTestSuite) TestDatabaseGetVersionedKey() {

func (s *StorageTestSuite) TestDatabaseVersionZero() {
// Db should write all keys at version 0 at version 1
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -183,7 +185,7 @@ func (s *StorageTestSuite) TestDatabaseVersionZero() {
}

func (s *StorageTestSuite) TestDatabaseApplyChangeset() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -220,7 +222,7 @@ func (s *StorageTestSuite) TestDatabaseApplyChangeset() {
}

func (s *StorageTestSuite) TestDatabaseIteratorEmptyDomain() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand All @@ -230,7 +232,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorEmptyDomain() {
}

func (s *StorageTestSuite) TestDatabaseIteratorClose() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand All @@ -243,7 +245,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorClose() {
}

func (s *StorageTestSuite) TestDatabaseIteratorDomain() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -274,7 +276,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorDomain() {
}

func (s *StorageTestSuite) TestDatabaseIterator() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -332,7 +334,7 @@ func (s *StorageTestSuite) TestDatabaseIterator() {
s.Require().Nil(iter3)
}
func (s *StorageTestSuite) TestDatabaseIteratorRangedDeletes() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand All @@ -357,7 +359,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorRangedDeletes() {
}

func (s *StorageTestSuite) TestDatabaseIteratorDeletes() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -393,7 +395,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorDeletes() {
}

func (s *StorageTestSuite) TestDatabaseIteratorMultiVersion() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -439,7 +441,7 @@ func (s *StorageTestSuite) TestDatabaseIteratorMultiVersion() {

// Tests bug where iterator loops continuously
func (s *StorageTestSuite) TestDatabaseBugInitialReverseIteration() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -468,7 +470,7 @@ func (s *StorageTestSuite) TestDatabaseBugInitialReverseIteration() {
}

func (s *StorageTestSuite) TestDatabaseBugInitialForwardIteration() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -498,7 +500,7 @@ func (s *StorageTestSuite) TestDatabaseBugInitialForwardIteration() {
}

func (s *StorageTestSuite) TestDatabaseBugInitialForwardIterationHigher() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -526,7 +528,7 @@ func (s *StorageTestSuite) TestDatabaseBugInitialForwardIterationHigher() {
}

func (s *StorageTestSuite) TestDatabaseBugInitialReverseIterationHigher() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -555,7 +557,7 @@ func (s *StorageTestSuite) TestDatabaseBugInitialReverseIterationHigher() {
}

func (s *StorageTestSuite) TestDatabaseIteratorNoDomain() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -584,7 +586,7 @@ func (s *StorageTestSuite) TestDatabasePrune() {
s.T().SkipNow()
}

db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -648,7 +650,7 @@ func (s *StorageTestSuite) TestDatabasePrune() {
}

func (s *StorageTestSuite) TestDatabasePruneAndTombstone() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand All @@ -669,7 +671,7 @@ func (s *StorageTestSuite) TestDatabasePruneKeepRecent() {
s.T().SkipNow()
}

db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -712,8 +714,66 @@ func (s *StorageTestSuite) TestDatabasePruneKeepRecent() {
s.Require().Equal([]byte("value003"), bz)
}

func (s *StorageTestSuite) TestDatabasePruneKeepLastVersion() {
// Update config to set KeepLastVersion to false
stateStoreConfig := s.Config
stateStoreConfig.KeepLastVersion = false
db, err := s.NewDB(s.T().TempDir(), stateStoreConfig)
s.Require().NoError(err)
defer db.Close()

s.Require().NoError(DBApplyChangeset(db, 100, storeKey1, [][]byte{[]byte("key000")}, [][]byte{[]byte("value001")}))
s.Require().NoError(DBApplyChangeset(db, 100, storeKey1, [][]byte{[]byte("key001")}, [][]byte{[]byte("value002")}))
s.Require().NoError(DBApplyChangeset(db, 200, storeKey1, [][]byte{[]byte("key002")}, [][]byte{[]byte("value003")}))
s.Require().NoError(DBApplyChangeset(db, 200, storeKey1, [][]byte{[]byte("key003")}, [][]byte{[]byte("value004")}))

// prune version 150
s.Require().NoError(db.Prune(150))

// Verify that all keys before prune height are deleted
bz, err := db.Get(storeKey1, 100, []byte("key000"))
s.Require().NoError(err)
s.Require().Nil(bz)

bz, err = db.Get(storeKey1, 160, []byte("key001"))
s.Require().NoError(err)
s.Require().Nil(bz)

// Verify keys after prune height can be retrieved
bz, err = db.Get(storeKey1, 200, []byte("key002"))
s.Require().NoError(err)
s.Require().Equal([]byte("value003"), bz)

bz, err = db.Get(storeKey1, 220, []byte("key003"))
s.Require().NoError(err)
s.Require().Equal([]byte("value004"), bz)

// Now reset KeepLastVersion to true and verify latest version of key exists
newDB, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer newDB.Close()

s.Require().NoError(DBApplyChangeset(newDB, 100, storeKey1, [][]byte{[]byte("key000")}, [][]byte{[]byte("value001")}))
s.Require().NoError(DBApplyChangeset(newDB, 100, storeKey1, [][]byte{[]byte("key001")}, [][]byte{[]byte("value002")}))
s.Require().NoError(DBApplyChangeset(newDB, 200, storeKey1, [][]byte{[]byte("key002")}, [][]byte{[]byte("value003")}))
s.Require().NoError(DBApplyChangeset(newDB, 200, storeKey1, [][]byte{[]byte("key003")}, [][]byte{[]byte("value004")}))

// prune version 150
s.Require().NoError(newDB.Prune(150))

// Can still retrieve those keys because KeepLastVersion is true
bz, err = newDB.Get(storeKey1, 160, []byte("key000"))
s.Require().NoError(err)
s.Require().Equal([]byte("value001"), bz)

bz, err = newDB.Get(storeKey1, 180, []byte("key001"))
s.Require().NoError(err)
s.Require().Equal([]byte("value002"), bz)

}

func (s *StorageTestSuite) TestDatabaseReverseIterator() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -768,7 +828,7 @@ func (s *StorageTestSuite) TestDatabaseReverseIterator() {
}

func (s *StorageTestSuite) TestParallelWrites() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -814,7 +874,7 @@ func (s *StorageTestSuite) TestParallelWrites() {
}

func (s *StorageTestSuite) TestParallelWriteAndPruning() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -875,7 +935,7 @@ func (s *StorageTestSuite) TestParallelWriteAndPruning() {
}

func (s *StorageTestSuite) TestDatabaseParallelDeleteIteration() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -948,7 +1008,7 @@ func (s *StorageTestSuite) TestDatabaseParallelDeleteIteration() {
}

func (s *StorageTestSuite) TestDatabaseParallelWriteDelete() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -1010,7 +1070,8 @@ func (s *StorageTestSuite) TestDatabaseParallelWriteDelete() {
}

func (s *StorageTestSuite) TestParallelIterationAndPruning() {
db, err := s.NewDB(s.T().TempDir())
fmt.Printf("DEBUG - config %+v\n", s.Config)
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down Expand Up @@ -1085,7 +1146,7 @@ func (s *StorageTestSuite) TestParallelIterationAndPruning() {
}

func (s *StorageTestSuite) TestDatabaseParallelIterationVersions() {
db, err := s.NewDB(s.T().TempDir())
db, err := s.NewDB(s.T().TempDir(), s.Config)
s.Require().NoError(err)
defer db.Close()

Expand Down

0 comments on commit 50e236f

Please sign in to comment.