Skip to content

Commit

Permalink
Problem: pause pruning is not included (#934)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsqe authored Nov 14, 2024
1 parent 2d4f901 commit 3300cc8
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

* (server) [#21941](https://github.com/cosmos/cosmos-sdk/pull/21941) Regenerate addrbook.json for in place testnet.
* (store) [#923](https://github.com/crypto-org-chain/cosmos-sdk/pull/923) Enable iavl async pruning.
* (store) [#934](https://github.com/crypto-org-chain/cosmos-sdk/pull/934) Add pause pruning.

### Bug Fixes

Expand Down
9 changes: 9 additions & 0 deletions store/iavl/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ func (st *Store) LastCommitID() types.CommitID {
}
}

// PausePruning implements CommitKVStore interface.
func (st *Store) PausePruning(pause bool) {
if pause {
st.tree.SetCommitting()
} else {
st.tree.UnsetCommitting()
}
}

// SetPruning panics as pruning options should be provided at initialization
// since IAVl accepts pruning options directly.
func (st *Store) SetPruning(_ pruningtypes.PruningOptions) {
Expand Down
10 changes: 10 additions & 0 deletions store/iavl/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type (
Get(key []byte) ([]byte, error)
Set(key, value []byte) (bool, error)
Remove(key []byte) ([]byte, bool, error)
SetCommitting()
UnsetCommitting()
SaveVersion() ([]byte, int64, error)
Version() int64
Hash() []byte
Expand Down Expand Up @@ -53,6 +55,14 @@ func (it *immutableTree) Remove(_ []byte) ([]byte, bool, error) {
panic("cannot call 'Remove' on an immutable IAVL tree")
}

func (it *immutableTree) SetCommitting() {
panic("cannot call 'SetCommitting' on an immutable IAVL tree")
}

func (it *immutableTree) UnsetCommitting() {
panic("cannot call 'UnsetCommitting' on an immutable IAVL tree")
}

func (it *immutableTree) SaveVersion() ([]byte, int64, error) {
panic("cannot call 'SaveVersion' on an immutable IAVL tree")
}
Expand Down
19 changes: 18 additions & 1 deletion store/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,16 @@ func (rs *Store) LastCommitID() types.CommitID {
return rs.lastCommitInfo.CommitID()
}

// PausePruning temporarily pauses the pruning of all individual stores which implement
// the PausablePruner interface.
func (rs *Store) PausePruning(pause bool) {
for _, store := range rs.stores {
if pauseable, ok := store.(types.PausablePruner); ok {
pauseable.PausePruning(pause)
}
}
}

// Commit implements Committer/CommitStore.
func (rs *Store) Commit() types.CommitID {
var previousHeight, version int64
Expand All @@ -485,7 +495,14 @@ func (rs *Store) Commit() types.CommitID {
rs.logger.Debug("commit header and version mismatch", "header_height", rs.commitHeader.Height, "version", version)
}

rs.lastCommitInfo = commitStores(version, rs.stores, rs.removalMap)
func() { // ensure unpause
// set the committing flag on all stores to block the pruning
rs.PausePruning(true)
// unset the committing flag on all stores to continue the pruning
defer rs.PausePruning(false)
rs.lastCommitInfo = commitStores(version, rs.stores, rs.removalMap)
}()

rs.lastCommitInfo.Timestamp = rs.commitHeader.Time
defer rs.flushMetadata(rs.db, version, rs.lastCommitInfo)

Expand Down
24 changes: 24 additions & 0 deletions store/rootmulti/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,30 @@ func TestMultiStore_PruningRestart(t *testing.T) {
require.Eventually(t, isPruned, 1*time.Second, 10*time.Millisecond, "expected error when loading pruned heights")
}

var _ types.PausablePruner = &pauseableCommitKVStoreStub{}

type pauseableCommitKVStoreStub struct {
types.CommitKVStore
pauseCalled []bool
}

func (p *pauseableCommitKVStoreStub) PausePruning(b bool) {
p.pauseCalled = append(p.pauseCalled, b)
}

func TestPausePruningOnCommit(t *testing.T) {
store := NewStore(dbm.NewMemDB(), log.NewNopLogger(), metrics.NewNoOpMetrics())
store.SetPruning(pruningtypes.NewCustomPruningOptions(2, 11))
store.MountStoreWithDB(testStoreKey1, types.StoreTypeIAVL, nil)
require.NoError(t, store.LoadLatestVersion())
myStub := &pauseableCommitKVStoreStub{CommitKVStore: store.stores[testStoreKey1].(types.CommitKVStore)}
store.stores[testStoreKey1] = myStub
// when
store.Commit()
// then
require.Equal(t, []bool{true, false}, myStub.pauseCalled)
}

// TestUnevenStoresHeightCheck tests if loading root store correctly errors when
// there's any module store with the wrong height
func TestUnevenStoresHeightCheck(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions store/types/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ type Committer interface {
GetPruning() pruningtypes.PruningOptions
}

type PausablePruner interface {
// PausePruning let the pruning handler know that the store is being committed
// or not, so the handler can decide to prune or not the store.
//
// NOTE: PausePruning(true) should be called before Commit() and PausePruning(false)
PausePruning(bool)
}

// Stores of MultiStore must implement CommitStore.
type CommitStore interface {
Committer
Expand Down

0 comments on commit 3300cc8

Please sign in to comment.