diff --git a/store/CHANGELOG.md b/store/CHANGELOG.md index f46df2cbae..6e1b7210fa 100644 --- a/store/CHANGELOG.md +++ b/store/CHANGELOG.md @@ -29,10 +29,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#15568](https://github.com/cosmos/cosmos-sdk/pull/15568) Migrate the `iavl` to the new key format. * Remove `DeleteVersion`, `DeleteVersions`, `LazyLoadVersionForOverwriting` from `iavl` tree API. - * Add `DeleteVersionsTo` and `SaveChangeSet`, since it will keep versions sequentially like `fromVersion` to `toVersion`. + * Add `DeleteVersionsTo`, since it will keep versions sequentially like `fromVersion` to `toVersion`. * Refactor the pruning manager to use `DeleteVersionsTo`. * [#15712](https://github.com/cosmos/cosmos-sdk/pull/15712) Add `WorkingHash` function to the store interface to get the current app hash before commit. - +* [#15432](https://github.com/cosmos/cosmos-sdk/pull/15432) Add `TraverseStateChanges` to the store interface to get the state changes between two versions. * [#14645](https://github.com/cosmos/cosmos-sdk/pull/14645) Add limit to the length of key and value. * [#15683](https://github.com/cosmos/cosmos-sdk/pull/15683) `rootmulti.Store.CacheMultiStoreWithVersion` now can handle loading archival states that don't persist any of the module stores the current state has. * [#16060](https://github.com/cosmos/cosmos-sdk/pull/16060) Support saving restoring snapshot locally. diff --git a/store/iavl/tree_test.go b/store/iavl/tree_test.go index 1113cbaf91..4e837262ae 100644 --- a/store/iavl/tree_test.go +++ b/store/iavl/tree_test.go @@ -19,6 +19,10 @@ func TestImmutableTreePanics(t *testing.T) { require.Panics(t, func() { _, _, _ = it.SaveVersion() }) require.Panics(t, func() { _ = it.DeleteVersionsTo(int64(1)) }) + val, err := it.GetVersioned(nil, 1) + require.Error(t, err) + require.Nil(t, val) + imm, err := it.GetImmutable(1) require.Error(t, err) require.Nil(t, imm) diff --git a/store/metrics/telemetry.go b/store/metrics/telemetry.go index dc7366307f..d5bc55c45b 100644 --- a/store/metrics/telemetry.go +++ b/store/metrics/telemetry.go @@ -37,7 +37,7 @@ func NewMetrics(labels [][]string) Metrics { return gatherer } -// MeasureSince provides a wrapper functionality for emitting a a time measure +// MeasureSince provides a wrapper functionality for emitting a time measure // metric with global labels (if any). func (m Metrics) MeasureSince(keys ...string) { start := time.Now() diff --git a/store/pruning/manager.go b/store/pruning/manager.go index dbd972e8ec..9a99e49151 100644 --- a/store/pruning/manager.go +++ b/store/pruning/manager.go @@ -21,7 +21,7 @@ type Manager struct { opts types.PruningOptions snapshotInterval uint64 // Snapshots are taken in a separate goroutine from the regular execution - // and can be delivered asynchrounously via HandleHeightSnapshot. + // and can be delivered asynchrounously via HandleSnapshotHeight. // Therefore, we sync access to pruneSnapshotHeights with this mutex. pruneSnapshotHeightsMx sync.RWMutex // These are the heights that are multiples of snapshotInterval and kept for state sync snapshots. @@ -65,11 +65,11 @@ func (m *Manager) GetOptions() types.PruningOptions { return m.opts } -// HandleHeightSnapshot persists the snapshot height to be pruned at the next appropriate -// height defined by the pruning strategy. Flushes the update to disk and panics if the flush fails. -// The input height must be greater than 0 and pruning strategy any but pruning nothing. -// If one of these conditions is not met, this function does nothing. -func (m *Manager) HandleHeightSnapshot(height int64) { +// HandleSnapshotHeight persists the snapshot height to be pruned at the next appropriate +// height defined by the pruning strategy. It flushes the update to disk and panics if the flush fails. +// The input height must be greater than 0, and the pruning strategy must not be set to pruning nothing. +// If either of these conditions is not met, this function does nothing. +func (m *Manager) HandleSnapshotHeight(height int64) { if m.opts.GetPruningStrategy() == types.PruningNothing || height <= 0 { return } @@ -77,7 +77,7 @@ func (m *Manager) HandleHeightSnapshot(height int64) { m.pruneSnapshotHeightsMx.Lock() defer m.pruneSnapshotHeightsMx.Unlock() - m.logger.Debug("HandleHeightSnapshot", "height", height) + m.logger.Debug("HandleSnapshotHeight", "height", height) m.pruneSnapshotHeights = append(m.pruneSnapshotHeights, height) sort.Slice(m.pruneSnapshotHeights, func(i, j int) bool { return m.pruneSnapshotHeights[i] < m.pruneSnapshotHeights[j] }) k := 1 @@ -118,7 +118,7 @@ func (m *Manager) GetPruningHeight(height int64) int64 { m.pruneSnapshotHeightsMx.RLock() defer m.pruneSnapshotHeightsMx.RUnlock() - // - snapshotInterval is zero as that means that all heights can be pruned. + // snapshotInterval is zero, indicating that all heights can be pruned if m.snapshotInterval <= 0 { return pruneHeight } diff --git a/store/pruning/manager_test.go b/store/pruning/manager_test.go index 56d8323f38..006891de85 100644 --- a/store/pruning/manager_test.go +++ b/store/pruning/manager_test.go @@ -111,7 +111,7 @@ func TestStrategies(t *testing.T) { for curHeight := int64(0); curHeight < 110000; curHeight++ { if tc.snapshotInterval != 0 { if curHeight > int64(tc.snapshotInterval) && curHeight%int64(tc.snapshotInterval) == int64(tc.snapshotInterval)-1 { - manager.HandleHeightSnapshot(curHeight - int64(tc.snapshotInterval) + 1) + manager.HandleSnapshotHeight(curHeight - int64(tc.snapshotInterval) + 1) snHeight = curHeight } } @@ -214,10 +214,10 @@ func TestHandleSnapshotHeight_DbErr_Panic(t *testing.T) { } }() - manager.HandleHeightSnapshot(10) + manager.HandleSnapshotHeight(10) } -func TestHandleHeightSnapshot_LoadFromDisk(t *testing.T) { +func TestHandleSnapshotHeight_LoadFromDisk(t *testing.T) { snapshotInterval := uint64(10) // Setup @@ -233,7 +233,7 @@ func TestHandleHeightSnapshot_LoadFromDisk(t *testing.T) { snapshotHeightStr := fmt.Sprintf("snaphost height: %d", snapshotHeight) if snapshotHeight > int64(snapshotInterval) && snapshotHeight%int64(snapshotInterval) == 1 { // Test flush - manager.HandleHeightSnapshot(snapshotHeight - 1) + manager.HandleSnapshotHeight(snapshotHeight - 1) expected = 1 } @@ -251,27 +251,6 @@ func TestHandleHeightSnapshot_LoadFromDisk(t *testing.T) { } } -func TestHandleHeightSnapshot_DbErr_Panic(t *testing.T) { - ctrl := gomock.NewController(t) - - // Setup - dbMock := mock.NewMockDB(ctrl) - - dbMock.EXPECT().SetSync(gomock.Any(), gomock.Any()).Return(errors.New(dbErr)).Times(1) - - manager := pruning.NewManager(dbMock, log.NewNopLogger()) - manager.SetOptions(types.NewPruningOptions(types.PruningEverything)) - require.NotNil(t, manager) - - defer func() { - if r := recover(); r == nil { - t.Fail() - } - }() - - manager.HandleHeightSnapshot(10) -} - func TestLoadPruningSnapshotHeights(t *testing.T) { var ( manager = pruning.NewManager(db.NewMemDB(), log.NewNopLogger()) diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 622c7693e9..1b0a64857d 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -337,10 +337,10 @@ func moveKVStoreData(oldDB, newDB types.KVStore) error { } // PruneSnapshotHeight prunes the given height according to the prune strategy. -// If PruneNothing, this is a no-op. -// If other strategy, this height is persisted until the snapshot is operated. +// If the strategy is PruneNothing, this is a no-op. +// For other strategies, this height is persisted until the snapshot is operated. func (rs *Store) PruneSnapshotHeight(height int64) { - rs.pruningManager.HandleHeightSnapshot(height) + rs.pruningManager.HandleSnapshotHeight(height) } // SetInterBlockCache sets the Store's internal inter-block (persistent) cache. @@ -654,7 +654,7 @@ func (rs *Store) handlePruning(version int64) error { // PruneStores prunes all history upto the specific height of the multi store. func (rs *Store) PruneStores(pruningHeight int64) (err error) { if pruningHeight <= 0 { - rs.logger.Debug("pruning skipped, height is smaller than 0") + rs.logger.Debug("pruning skipped, height is less than or equal to 0") return nil } @@ -676,9 +676,11 @@ func (rs *Store) PruneStores(pruningHeight int64) (err error) { continue } - if errors.Is(err, iavltree.ErrVersionDoesNotExist) && err != nil { + if errors.Is(err, iavltree.ErrVersionDoesNotExist) { return err } + + rs.logger.Error("failed to prune store", "key", key, "err", err) } return nil }