diff --git a/baseapp/abci.go b/baseapp/abci.go index 2bfb22063134..ac56a0c284bb 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -25,6 +25,7 @@ import ( ) const initialAppVersion = 0 +const StoreInfoPath = "info" type AppVersionError struct { Actual uint64 @@ -826,7 +827,30 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R resp := queryable.Query(req) resp.Height = req.Height + if path[1] == StoreInfoPath { + commitInfo, err := app.cms.GetCommitInfoFromDB(resp.Height) + if err != nil { + return sdkerrors.QueryResult(err) + } + + // sort the commitInfo, otherwise it returns in a different order every height + sort.Slice(commitInfo.StoreInfos, func(i, j int) bool { + return commitInfo.StoreInfos[i].Name < commitInfo.StoreInfos[j].Name + }) + + bz, err := codec.ProtoMarshalJSON(commitInfo, app.interfaceRegistry) + if err != nil { + return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response")) + } + + return abci.ResponseQuery{ + Codespace: sdkerrors.RootCodespace, + Height: req.Height, + Value: bz, + } + } return resp + } func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery { diff --git a/server/mock/store.go b/server/mock/store.go index 110e873bee48..948903c94bfa 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -78,6 +78,10 @@ func (ms multiStore) GetCommitKVStore(key sdk.StoreKey) sdk.CommitKVStore { panic("not implemented") } +func (ms multiStore) GetCommitInfoFromDB(ver int64) (*store.CommitInfo, error) { + panic("not implemented") +} + func (ms multiStore) GetCommitStore(key sdk.StoreKey) sdk.CommitStore { panic("not implemented") } diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 233e24033825..86a80f2346c2 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -207,7 +207,7 @@ func (rs *Store) loadVersion(ver int64, upgrades *types.StoreUpgrades) error { // load old data if we are not version 0 if ver != 0 { var err error - cInfo, err = rs.getCommitInfoFromDb(ver) + cInfo, err = rs.GetCommitInfoFromDB(ver) if err != nil { return err } @@ -625,7 +625,7 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proof is unexpectedly empty; ensure height has not been pruned")) } - commitInfo, err := rs.getCommitInfoFromDb(res.Height) + commitInfo, err := rs.GetCommitInfoFromDB(res.Height) if err != nil { return sdkerrors.QueryResult(err) } @@ -983,7 +983,7 @@ func (rs *Store) flushLastCommitInfo(cInfo *types.CommitInfo) { } // Gets commitInfo from disk. -func (rs *Store) getCommitInfoFromDb(ver int64) (*types.CommitInfo, error) { +func (rs *Store) GetCommitInfoFromDB(ver int64) (*types.CommitInfo, error) { cInfoKey := fmt.Sprintf(commitInfoKeyFmt, ver) bz, err := rs.db.Get([]byte(cInfoKey)) @@ -1025,7 +1025,7 @@ func (rs *Store) GetAppVersion() (uint64, error) { } func (rs *Store) doProofsQuery(req abci.RequestQuery) abci.ResponseQuery { - commitInfo, err := rs.getCommitInfoFromDb(req.Height) + commitInfo, err := rs.GetCommitInfoFromDB(req.Height) if err != nil { return sdkerrors.QueryResult(err) } diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index 337906c8581a..bead03663bfc 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -214,7 +214,7 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { expectedCommitID := getExpectedCommitID(store, 1) checkStore(t, store, expectedCommitID, commitID) - ci, err := store.getCommitInfoFromDb(1) + ci, err := store.GetCommitInfoFromDB(1) require.NoError(t, err) require.Equal(t, int64(1), ci.Version) require.Equal(t, 3, len(ci.StoreInfos)) @@ -298,7 +298,7 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { require.Equal(t, v4, rl4.Get(k4)) // check commitInfo in storage - ci, err = store.getCommitInfoFromDb(2) + ci, err = store.GetCommitInfoFromDB(2) require.NoError(t, err) require.Equal(t, int64(2), ci.Version) require.Equal(t, 4, len(ci.StoreInfos), ci.StoreInfos) @@ -354,7 +354,7 @@ func TestMultiStoreRestart(t *testing.T) { multi.Commit() - cinfo, err := multi.getCommitInfoFromDb(int64(i)) + cinfo, err := multi.GetCommitInfoFromDB(int64(i)) require.NoError(t, err) require.Equal(t, int64(i), cinfo.Version) } @@ -369,7 +369,7 @@ func TestMultiStoreRestart(t *testing.T) { multi.Commit() - flushedCinfo, err := multi.getCommitInfoFromDb(3) + flushedCinfo, err := multi.GetCommitInfoFromDB(3) require.Nil(t, err) require.NotEqual(t, initCid, flushedCinfo, "CID is different after flush to disk") @@ -379,7 +379,7 @@ func TestMultiStoreRestart(t *testing.T) { multi.Commit() - postFlushCinfo, err := multi.getCommitInfoFromDb(4) + postFlushCinfo, err := multi.GetCommitInfoFromDB(4) require.NoError(t, err) require.Equal(t, int64(4), postFlushCinfo.Version, "Commit changed after in-memory commit") diff --git a/store/types/store.go b/store/types/store.go index a78ce355bf71..35382b6d4be5 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -164,6 +164,9 @@ type CommitMultiStore interface { // Panics on a nil key. GetCommitKVStore(key StoreKey) CommitKVStore + // Panics on a nil version. + GetCommitInfoFromDB(ver int64) (*CommitInfo, error) + // Load the latest persisted version. Called once after all calls to // Mount*Store() are complete. LoadLatestVersion() error