Skip to content

Commit

Permalink
chore: Add check for uneven stores' height (backport cosmos#14410) (c…
Browse files Browse the repository at this point in the history
…osmos#15114)

Co-authored-by: khanh-notional <50263489+catShaark@users.noreply.github.com>
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
  • Loading branch information
3 people authored and JeancarloBarrios committed Sep 28, 2024
1 parent 013595c commit 3964a94
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

## Improvements

* (store) [#14410](https://github.com/cosmos/cosmos-sdk/pull/14410) `rootmulti.Store.loadVersion` has validation to check if all the module stores' height is correct, it will error if any module store has incorrect height.

## [v0.45.14](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.14) - 2023-02-16

### Features
Expand Down
11 changes: 10 additions & 1 deletion store/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func (rs *Store) loadVersion(ver int64, upgrades *types.StoreUpgrades) error {
if upgrades.IsAdded(key.Name()) || upgrades.RenamedFrom(key.Name()) != "" {
storeParams.initialVersion = uint64(ver) + 1
} else if commitID.Version != ver && storeParams.typ == types.StoreTypeIAVL {
return fmt.Errorf("version of store %q mismatch root store's version; expected %d got %d; new stores should be added using StoreUpgrades", key.Name(), ver, commitID.Version)
return fmt.Errorf("version of store %s mismatch root store's version; expected %d got %d", key.Name(), ver, commitID.Version)
}

store, err := rs.loadCommitStoreFromParams(key, commitID, storeParams)
Expand Down Expand Up @@ -1026,6 +1026,15 @@ type storeParams struct {
initialVersion uint64
}

func newStoreParams(key types.StoreKey, db dbm.DB, typ types.StoreType, initialVersion uint64) storeParams { // nolint
return storeParams{
key: key,
db: db,
typ: typ,
initialVersion: initialVersion,
}
}

func GetLatestVersion(db dbm.DB) int64 {
bz, err := db.Get([]byte(latestVersionKey))
if err != nil {
Expand Down
35 changes: 34 additions & 1 deletion store/rootmulti/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) {
migratedID := restore.Commit()
require.Equal(t, migratedID.Version, int64(2))

reload, _ := newMultiStoreWithModifiedMounts(db, pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))
reload, _ := newMultiStoreWithModifiedMounts(db, types.PruneNothing)
// unmount store3 since store3 was deleted
unmountStore(reload, "store3")

Expand Down Expand Up @@ -643,6 +643,32 @@ func TestMultiStore_PruningRestart(t *testing.T) {
}
}

// TestUnevenStoresHeightCheck tests if loading root store correctly errors when
// there's any module store with the wrong height
func TestUnevenStoresHeightCheck(t *testing.T) {
var db dbm.DB = dbm.NewMemDB()
store := newMultiStoreWithMounts(db, types.PruneNothing)
err := store.LoadLatestVersion()
require.Nil(t, err)

// commit to increment store's height
store.Commit()

// mount store4 to root store
store.MountStoreWithDB(types.NewKVStoreKey("store4"), types.StoreTypeIAVL, nil)

// load the stores without upgrades
err = store.LoadLatestVersion()
require.Error(t, err)

// now, let's load with upgrades...
upgrades := &types.StoreUpgrades{
Added: []string{"store4"},
}
err = store.LoadLatestVersionAndUpgrade(upgrades)
require.Nil(t, err)
}

func TestSetInitialVersion(t *testing.T) {
db := coretesting.NewMemDB()
multi := newMultiStoreWithMounts(db, pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))
Expand Down Expand Up @@ -780,6 +806,13 @@ func newMultiStoreWithModifiedMounts(db dbm.DB, pruningOpts types.PruningOptions
return store, upgrades
}

func unmountStore(rootStore *Store, storeKeyName string) {
sk := rootStore.keysByName[storeKeyName]
delete(rootStore.stores, sk)
delete(rootStore.storesParams, sk)
delete(rootStore.keysByName, storeKeyName)
}

func checkStore(t *testing.T, store *Store, expect, got types.CommitID) {
t.Helper()
require.Equal(t, expect, got)
Expand Down

0 comments on commit 3964a94

Please sign in to comment.