From d0619a9dda692ce916dc0a815913900337bc2f5e Mon Sep 17 00:00:00 2001 From: khanh-notional <50263489+catShaark@users.noreply.github.com> Date: Tue, 11 Apr 2023 03:30:28 +0700 Subject: [PATCH 1/2] feat: More flexibility for `CacheMultiStoreWithVersion` (#15683) ## Description Closes: [cosmos/gaia#2313](https://github.com/cosmos/gaia/issues/2313) The gaia v9 upgrade causes node to errors out when querying historical states before the upgrade. This is because we added a new module store in the upgrade which is the `provider module store`. Thus, every times we load the multi store for querying at a height prior to the upgrade, we try to load the `provider module store` and fail since it has not existed before the upgrade. I make changes to `CacheMultiStoreWithVersion` so that if we fail to load any module store at a given height, we check if that module store has existed at that height or not (using `getCommitInfo()`), we can ignore the error if the store hasn't existed at that given height. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... * [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title * [ ] added `!` to the type prefix if API or client breaking change * [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) * [ ] provided a link to the relevant issue or specification * [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules) * [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) * [ ] added a changelog entry to `CHANGELOG.md` * [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) * [ ] updated the relevant documentation or specification * [ ] reviewed "Files changed" and left comments if necessary * [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... * [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title * [ ] confirmed `!` in the type prefix if API or client breaking change * [ ] confirmed all author checklist items have been addressed * [ ] reviewed state machine logic * [ ] reviewed API design and naming * [ ] reviewed documentation is accurate * [ ] reviewed tests and test coverage * [ ] manually tested (if applicable) (cherry picked from commit d5a618db6a431ee3b6a39c16e6057f47a57d4b1c) # Conflicts: # store/CHANGELOG.md --- store/CHANGELOG.md | 38 +++++++++++++++++++++++++++++++++++ store/rootmulti/store.go | 25 ++++++++++++++++++++++- store/rootmulti/store_test.go | 11 ++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 store/CHANGELOG.md diff --git a/store/CHANGELOG.md b/store/CHANGELOG.md new file mode 100644 index 000000000000..bc16c71f122a --- /dev/null +++ b/store/CHANGELOG.md @@ -0,0 +1,38 @@ + + +# Changelog + +## [Unreleased] + +### Features + +* [#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. + +## [v0.1.0-alpha.1](https://github.com/cosmos/cosmos-sdk/releases/tag/store%2Fv0.1.0-alpha.1) - 2023-03-17 + +### Features + +* [#14746](https://github.com/cosmos/cosmos-sdk/pull/14746) The `store` module is extracted to have a separate go.mod file which allows it be a standalone module. +* [#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. \ No newline at end of file diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index ce08464c03b5..ae9e5cff7ec0 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -501,6 +501,8 @@ func (rs *Store) CacheMultiStore() types.CacheMultiStore { // iterating at past heights. func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStore, error) { cachedStores := make(map[types.StoreKey]types.CacheWrapper) + var commitInfo *types.CommitInfo + storeInfos := map[string]bool{} for key, store := range rs.stores { var cacheStore types.KVStore switch store.GetStoreType() { @@ -513,9 +515,30 @@ func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStor // version does not exist or is pruned, an error should be returned. var err error cacheStore, err = store.(*iavl.Store).GetImmutable(version) + // if we got error from loading a module store + // we fetch commit info of this version + // we use commit info to check if the store existed at this version or not if err != nil { - return nil, err + if commitInfo == nil { + var errCommitInfo error + commitInfo, errCommitInfo = rs.GetCommitInfo(version) + + if errCommitInfo != nil { + return nil, errCommitInfo + } + + for _, storeInfo := range commitInfo.StoreInfos { + storeInfos[storeInfo.Name] = true + } + } + + // If the store existed at this version, it means there's actually an error + // getting the root store at this version. + if storeInfos[key.Name()] { + return nil, err + } } + default: cacheStore = store } diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index 78e56e9acfb7..41ee371b2b00 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -99,6 +99,17 @@ func TestCacheMultiStoreWithVersion(t *testing.T) { require.NotNil(t, kvStore) require.Equal(t, kvStore.Get(k), v) + // add new module stores (store4 and store5) to multi stores and commit + ms.MountStoreWithDB(types.NewKVStoreKey("store4"), types.StoreTypeIAVL, nil) + ms.MountStoreWithDB(types.NewKVStoreKey("store5"), types.StoreTypeIAVL, nil) + err = ms.LoadLatestVersionAndUpgrade(&types.StoreUpgrades{Added: []string{"store4", "store5"}}) + require.NoError(t, err) + ms.Commit() + + // cache multistore of version before adding store4 should works + _, err = ms.CacheMultiStoreWithVersion(1) + require.NoError(t, err) + // require we cannot commit (write) to a cache-versioned multi-store require.Panics(t, func() { kvStore.Set(k, []byte("newValue")) From c448c20a0b416ddd2f7ebc1bac39552e207a1b94 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 10 Apr 2023 22:37:42 +0200 Subject: [PATCH 2/2] fix changelog --- CHANGELOG.md | 1 + store/CHANGELOG.md | 38 -------------------------------------- 2 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 store/CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ee01546976..2448d1a1be12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Improvements +* (store) [#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. * [#15448](https://github.com/cosmos/cosmos-sdk/pull/15448) Automatically populate the block timestamp for historical queries. In contexts where the block timestamp is needed for previous states, the timestamp will now be set. Note, when querying against a node it must be re-synced in order to be able to automatically populate the block timestamp. Otherwise, the block timestamp will be populated for heights going forward once upgraded. * [#14019](https://github.com/cosmos/cosmos-sdk/issues/14019) Remove the interface casting to allow other implementations of a `CommitMultiStore`. diff --git a/store/CHANGELOG.md b/store/CHANGELOG.md deleted file mode 100644 index bc16c71f122a..000000000000 --- a/store/CHANGELOG.md +++ /dev/null @@ -1,38 +0,0 @@ - - -# Changelog - -## [Unreleased] - -### Features - -* [#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. - -## [v0.1.0-alpha.1](https://github.com/cosmos/cosmos-sdk/releases/tag/store%2Fv0.1.0-alpha.1) - 2023-03-17 - -### Features - -* [#14746](https://github.com/cosmos/cosmos-sdk/pull/14746) The `store` module is extracted to have a separate go.mod file which allows it be a standalone module. -* [#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. \ No newline at end of file