Skip to content
This repository was archived by the owner on Jan 20, 2026. It is now read-only.
Closed
61 changes: 48 additions & 13 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/legacytm"
"github.com/cosmos/cosmos-sdk/utils"
)

// InitChain implements the ABCI interface. It runs the initialization logic
Expand Down Expand Up @@ -929,7 +930,7 @@ func splitPath(requestPath string) (path []string) {
}

// ABCI++
func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (resp *abci.ResponsePrepareProposal, err error) {
defer telemetry.MeasureSince(time.Now(), "abci", "prepare_proposal")

header := tmproto.Header{
Expand Down Expand Up @@ -963,21 +964,40 @@ func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepar

app.preparePrepareProposalState()

defer func() {
if err := recover(); err != nil {
app.logger.Error(
"panic recovered in PrepareProposal",
"height", req.Height,
"time", req.Time,
"panic", err,
)

resp = &abci.ResponsePrepareProposal{
TxRecords: utils.Map(req.Txs, func(tx []byte) *abci.TxRecord {
return &abci.TxRecord{Action: abci.TxRecord_UNMODIFIED, Tx: tx}
}),
}
}
}()

if app.prepareProposalHandler != nil {
res, err := app.prepareProposalHandler(app.prepareProposalState.ctx, req)
resp, err = app.prepareProposalHandler(app.prepareProposalState.ctx, req)
if err != nil {
return nil, err
}

if cp := app.GetConsensusParams(app.prepareProposalState.ctx); cp != nil {
res.ConsensusParamUpdates = cp
resp.ConsensusParamUpdates = cp
}
return res, nil
} else {
return nil, errors.New("no prepare proposal handler")

return resp, nil
}

return nil, errors.New("no prepare proposal handler")
}

func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (resp *abci.ResponseProcessProposal, err error) {
defer telemetry.MeasureSince(time.Now(), "abci", "process_proposal")

header := tmproto.Header{
Expand Down Expand Up @@ -1018,21 +1038,36 @@ func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProces
}

// NOTE: header hash is not set in NewContext, so we manually set it here

app.prepareProcessProposalState(gasMeter, req.Hash)

defer func() {
if err := recover(); err != nil {
app.logger.Error(
"panic recovered in ProcessProposal",
"height", req.Height,
"time", req.Time,
"hash", fmt.Sprintf("%X", req.Hash),
"panic", err,
)

resp = &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
}
}()

if app.processProposalHandler != nil {
res, err := app.processProposalHandler(app.processProposalState.ctx, req)
resp, err = app.processProposalHandler(app.processProposalState.ctx, req)
if err != nil {
return nil, err
}

if cp := app.GetConsensusParams(app.processProposalState.ctx); cp != nil {
res.ConsensusParamUpdates = cp
resp.ConsensusParamUpdates = cp
}
return res, nil
} else {
return nil, errors.New("no process proposal handler")

return resp, nil
}

return nil, errors.New("no process proposal handler")
}

func (app *BaseApp) FinalizeBlock(ctx context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
Expand Down
26 changes: 19 additions & 7 deletions storev2/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func NewStore(
// Commit implements interface Committer, called by ABCI Commit
func (rs *Store) Commit(bumpVersion bool) types.CommitID {
if !bumpVersion {
return rs.lastCommitInfo.CommitID()
panic("Commit should always bump version in root multistore")
}
if err := rs.flush(); err != nil {
panic(err)
Expand Down Expand Up @@ -206,8 +206,8 @@ func (rs *Store) GetStoreType() types.StoreType {
}

// Implements interface CacheWrapper
func (rs *Store) CacheWrap(storeKey types.StoreKey) types.CacheWrap {
return rs.CacheMultiStore().CacheWrap(storeKey)
func (rs *Store) CacheWrap(_ types.StoreKey) types.CacheWrap {
return rs.CacheMultiStore().(types.CacheWrap)
}

// Implements interface CacheWrapper
Expand Down Expand Up @@ -237,6 +237,8 @@ func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStor
if version <= 0 || (rs.lastCommitInfo != nil && version == rs.lastCommitInfo.Version) {
return rs.CacheMultiStore(), nil
}
rs.mtx.RLock()
defer rs.mtx.RUnlock()
stores := make(map[types.StoreKey]types.CacheWrapper)
// add the transient/mem stores registered in current app.
for k, store := range rs.ckvStores {
Expand Down Expand Up @@ -354,6 +356,12 @@ func (rs *Store) LoadVersionAndUpgrade(version int64, upgrades *types.StoreUpgra
if err := rs.scStore.Initialize(initialStores); err != nil {
return err
}
if version > 0 {
_, err := rs.scStore.LoadVersion(version, false)
if err != nil {
return nil
}
}

var treeUpgrades []*proto.TreeNameUpgrade
for _, key := range storesKeys {
Expand Down Expand Up @@ -486,6 +494,7 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
return sdkerrors.QueryResult(err)
}
var store types.Queryable
var commitInfo *types.CommitInfo

if !req.Prove && version < rs.lastCommitInfo.Version && rs.ssStore != nil {
// Serve abci query from ss store if no proofs needed
Expand All @@ -498,9 +507,13 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
return sdkerrors.QueryResult(err)
}
store = types.Queryable(commitment.NewStore(scStore.GetTreeByName(storeName), rs.logger))
commitInfo = convertCommitInfo(scStore.LastCommitInfo())
commitInfo = amendCommitInfo(commitInfo, rs.storesParams)
} else {
// Serve directly from latest sc store
store = types.Queryable(commitment.NewStore(rs.scStore.GetTreeByName(storeName), rs.logger))
commitInfo = convertCommitInfo(rs.scStore.LastCommitInfo())
commitInfo = amendCommitInfo(commitInfo, rs.storesParams)
}

// trim the path and execute the query
Expand All @@ -509,14 +522,13 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {

if !req.Prove || !rootmulti.RequireProof(subPath) {
return res
} else if commitInfo != nil {
// Restore origin path and append proof op.
res.ProofOps.Ops = append(res.ProofOps.Ops, commitInfo.ProofOp(storeName))
}
if res.ProofOps == nil || len(res.ProofOps.Ops) == 0 {
return sdkerrors.QueryResult(errors.Wrap(sdkerrors.ErrInvalidRequest, "proof is unexpectedly empty; ensure height has not been pruned"))
}
commitInfo := convertCommitInfo(rs.scStore.LastCommitInfo())
commitInfo = amendCommitInfo(commitInfo, rs.storesParams)
// Restore origin path and append proof op.
res.ProofOps.Ops = append(res.ProofOps.Ops, commitInfo.ProofOp(storeName))
return res
}

Expand Down
2 changes: 1 addition & 1 deletion storev2/state/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
if req.Height > 0 && req.Height > st.version {
return sdkerrors.QueryResult(errors.Wrap(sdkerrors.ErrInvalidHeight, "invalid height"))
}
res.Height = st.version
switch req.Path {
case "/key": // get by key
res.Key = req.Data // data holds the key bytes
Expand All @@ -106,7 +107,6 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
pairs := kv.Pairs{
Pairs: make([]kv.Pair, 0),
}

subspace := req.Data
res.Key = subspace
iterator := types.KVStorePrefixIterator(st, subspace)
Expand Down
5 changes: 0 additions & 5 deletions x/accesscontrol/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,11 +579,6 @@ func (k Keeper) GetMessageDependencies(ctx sdk.Context, msg sdk.Msg) []acltypes.
ctx.Logger().Error(errorMessage)
}
}
if dependencyMapping.DynamicEnabled {
// there was an issue with dynamic generation, so lets disable it
// this will not error, the validation check was done in previous calls already
_ = k.SetDependencyMappingDynamicFlag(ctx, messageKey, false)
}
return dependencyMapping.AccessOps
}

Expand Down
7 changes: 4 additions & 3 deletions x/accesscontrol/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ func TestInvalidGetMessageDependencies(t *testing.T) {
delete(app.AccessControlKeeper.MessageDependencyGeneratorMapper, undelegateKey)
accessOps := app.AccessControlKeeper.GetMessageDependencies(ctx, &stakingUndelegate)
require.Equal(t, types.SynchronousMessageDependencyMapping("").AccessOps, accessOps)
require.False(t, app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey).DynamicEnabled)
// no longer gets disabled such that there arent writes in the dependency generation path
require.True(t, app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey).DynamicEnabled)
}

func TestWasmDependencyMapping(t *testing.T) {
Expand Down Expand Up @@ -2433,14 +2434,14 @@ func (suite *KeeperTestSuite) TestMessageDependencies() {
req.Equal(delegateStaticMapping.AccessOps, accessOps)
// verify dynamic got disabled
dependencyMapping = app.AccessControlKeeper.GetResourceDependencyMapping(ctx, delegateKey)
req.Equal(false, dependencyMapping.DynamicEnabled)
req.Equal(true, dependencyMapping.DynamicEnabled)

// lets also try with undelegate, but this time there is no dynamic generator, so we disable it as well
accessOps = app.AccessControlKeeper.GetMessageDependencies(ctx, &stakingUndelegate)
req.Equal(undelegateStaticMapping.AccessOps, accessOps)
// verify dynamic got disabled
dependencyMapping = app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey)
req.Equal(false, dependencyMapping.DynamicEnabled)
req.Equal(true, dependencyMapping.DynamicEnabled)
}

func (suite *KeeperTestSuite) TestImportContractReferences() {
Expand Down