diff --git a/baseapp/abci.go b/baseapp/abci.go index b755b4155861..e704c386facc 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -52,10 +52,10 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC } // initialize states with a correct header - app.setDeliverState(initHeader) - app.setCheckState(initHeader) - app.setPrepareProposalState(initHeader) - app.setProcessProposalState(initHeader) + app.setState(runTxModeDeliver, initHeader) + app.setState(runTxModeCheck, initHeader) + app.setState(runTxPrepareProposal, initHeader) + app.setState(runTxProcessProposal, initHeader) // Store the consensus params in the BaseApp's paramstore. Note, this must be // done after the deliver state and context have been set as it's persisted @@ -162,7 +162,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg // already be initialized in InitChain. Otherwise app.deliverState will be // nil, since it is reset on Commit. if app.deliverState == nil { - app.setDeliverState(req.Header) + app.setState(runTxModeDeliver, req.Header) } else { // In the first block, app.deliverState.ctx will already be initialized // by InitChain. Context is now updated with Header information. @@ -277,7 +277,7 @@ func (app *BaseApp) PrepareProposal(req abci.RequestPrepareProposal) (resp abci. // that all transactions are valid. If all transactions are valid, then we inform // Tendermint that the Status is ACCEPT. However, the application is also able // to implement optimizations such as executing the entire proposed block -// immediately. It may even execute the block in parallel. +// immediately. // // If a panic is detected during execution of an application's ProcessProposal // handler, it will be recovered and we will reject the proposal. @@ -423,9 +423,9 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // // NOTE: This is safe because Tendermint holds a lock on the mempool for // Commit. Use the header from this latest block. - app.setCheckState(header) - app.setPrepareProposalState(header) - app.setProcessProposalState(header) + app.setState(runTxModeCheck, header) + app.setState(runTxPrepareProposal, header) + app.setState(runTxProcessProposal, header) // empty/reset the deliver state app.deliverState = nil diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 04c5deffb567..1e95dac964ee 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -350,11 +350,11 @@ func (app *BaseApp) Init() error { emptyHeader := tmproto.Header{} // needed for the export command which inits from store but never calls initchain - app.setCheckState(emptyHeader) + app.setState(runTxModeCheck, emptyHeader) // needed for ABCI Replay Blocks mode which calls Prepare/Process proposal (InitChain is not called) - app.setPrepareProposalState(emptyHeader) - app.setProcessProposalState(emptyHeader) + app.setState(runTxPrepareProposal, emptyHeader) + app.setState(runTxProcessProposal, emptyHeader) app.Seal() if app.cms == nil { @@ -402,49 +402,32 @@ func (app *BaseApp) Seal() { app.sealed = true } // IsSealed returns true if the BaseApp is sealed and false otherwise. func (app *BaseApp) IsSealed() bool { return app.sealed } -// setCheckState sets the BaseApp's checkState with a branched multi-store -// (i.e. a CacheMultiStore) and a new Context with the same multi-store branch, -// provided header, and minimum gas prices set. It is set on InitChain and reset -// on Commit. -func (app *BaseApp) setCheckState(header tmproto.Header) { +// setState sets the BaseApp's state for the corresponding mode with a branched +// multi-store (i.e. a CacheMultiStore) and a new Context with the same +// multi-store branch, and provided header. +func (app *BaseApp) setState(mode runTxMode, header tmproto.Header) { ms := app.cms.CacheMultiStore() - app.checkState = &state{ - ms: ms, - ctx: sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices), - } -} - -// setDeliverState sets the BaseApp's deliverState with a branched multi-store -// (i.e. a CacheMultiStore) and a new Context with the same multi-store branch, -// and provided header. It is set on InitChain and BeginBlock and set to nil on -// Commit. -func (app *BaseApp) setDeliverState(header tmproto.Header) { - ms := app.cms.CacheMultiStore() - app.deliverState = &state{ - ms: ms, - ctx: sdk.NewContext(ms, header, false, app.logger), - } -} - -// setPrepareProposalState sets the BaseApp's prepareProposalState with a -// branched multi-store (i.e. a CacheMultiStore) and a new Context with the -// same multi-store branch, and provided header. It is set on InitChain and Commit. -func (app *BaseApp) setPrepareProposalState(header tmproto.Header) { - ms := app.cms.CacheMultiStore() - app.prepareProposalState = &state{ + baseState := &state{ ms: ms, ctx: sdk.NewContext(ms, header, false, app.logger), } -} -// setProcessProposalState sets the BaseApp's processProposalState with a -// branched multi-store (i.e. a CacheMultiStore) and a new Context with the -// same multi-store branch, and provided header. It is set on InitChain and Commit. -func (app *BaseApp) setProcessProposalState(header tmproto.Header) { - ms := app.cms.CacheMultiStore() - app.processProposalState = &state{ - ms: ms, - ctx: sdk.NewContext(ms, header, false, app.logger), + switch mode { + case runTxModeCheck: + // Minimum gas prices are also set. It is set on InitChain and reset on Commit. + baseState.ctx = baseState.ctx.WithIsCheckTx(true).WithMinGasPrices(app.minGasPrices) + app.checkState = baseState + case runTxModeDeliver: + // It is set on InitChain and BeginBlock and set to nil on Commit. + app.deliverState = baseState + case runTxPrepareProposal: + // It is set on InitChain and Commit. + app.prepareProposalState = baseState + case runTxProcessProposal: + // It is set on InitChain and Commit. + app.processProposalState = baseState + default: + panic(fmt.Sprintf("invalid runTxMode for setState: %d", mode)) } } @@ -552,7 +535,8 @@ func validateBasicTxMsgs(msgs []sdk.Msg) error { } // Returns the application's deliverState if app is in runTxModeDeliver, -// otherwise it returns the application's checkstate. +// prepareProposalState if app is in runTxPrepareProposal, processProposalState +// if app is in runTxProcessProposal, and checkState otherwise. func (app *BaseApp) getState(mode runTxMode) *state { switch mode { case runTxModeDeliver: diff --git a/baseapp/util_test.go b/baseapp/util_test.go deleted file mode 100644 index f35a47bb264e..000000000000 --- a/baseapp/util_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package baseapp_test - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" - tmtypes "github.com/tendermint/tendermint/types" - - runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" - appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" - authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1" - bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1" - consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1" - mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1" - paramsmodulev1 "cosmossdk.io/api/cosmos/params/module/v1" - stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1" - txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1" - "cosmossdk.io/core/appconfig" - "cosmossdk.io/depinject" - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/testutil/mock" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/mempool" - _ "github.com/cosmos/cosmos-sdk/x/auth" - _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - _ "github.com/cosmos/cosmos-sdk/x/bank" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - _ "github.com/cosmos/cosmos-sdk/x/consensus" - _ "github.com/cosmos/cosmos-sdk/x/mint" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - _ "github.com/cosmos/cosmos-sdk/x/params" - _ "github.com/cosmos/cosmos-sdk/x/staking" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts -// that also act as delegators. -func GenesisStateWithSingleValidator(t *testing.T, codec codec.Codec, builder *runtime.AppBuilder) map[string]json.RawMessage { - t.Helper() - - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - require.NoError(t, err) - - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balances := []banktypes.Balance{ - { - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), - }, - } - - genesisState := builder.DefaultGenesis() - // sus - genesisState, err = simtestutil.GenesisStateWithValSet(codec, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) - require.NoError(t, err) - - return genesisState -} - -func makeTestConfig() depinject.Config { - return appconfig.Compose(&appv1alpha1.Config{ - Modules: []*appv1alpha1.ModuleConfig{ - { - Name: "runtime", - Config: appconfig.WrapAny(&runtimev1alpha1.Module{ - AppName: "BaseAppApp", - BeginBlockers: []string{ - "mint", - "staking", - "auth", - "bank", - "params", - "consensus", - }, - EndBlockers: []string{ - "staking", - "auth", - "bank", - "mint", - "params", - "consensus", - }, - OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{ - { - ModuleName: "auth", - KvStoreKey: "acc", - }, - }, - InitGenesis: []string{ - "auth", - "bank", - "staking", - "mint", - "params", - "consensus", - }, - }), - }, - { - Name: "auth", - Config: appconfig.WrapAny(&authmodulev1.Module{ - Bech32Prefix: "cosmos", - ModuleAccountPermissions: []*authmodulev1.ModuleAccountPermission{ - {Account: authtypes.FeeCollectorName}, - {Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}}, - {Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, - {Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, - }, - }), - }, - { - Name: "bank", - Config: appconfig.WrapAny(&bankmodulev1.Module{}), - }, - { - Name: "params", - Config: appconfig.WrapAny(¶msmodulev1.Module{}), - }, - { - Name: "staking", - Config: appconfig.WrapAny(&stakingmodulev1.Module{}), - }, - { - Name: "mint", - Config: appconfig.WrapAny(&mintmodulev1.Module{}), - }, - { - Name: "consensus", - Config: appconfig.WrapAny(&consensusmodulev1.Module{}), - }, - { - Name: "tx", - Config: appconfig.WrapAny(&txconfigv1.Config{}), - }, - }, - }) -} - -func makeMinimalConfig() depinject.Config { - var mempoolOpt runtime.BaseAppOption = baseapp.SetMempool(mempool.NewSenderNonceMempool()) - return depinject.Configs( - depinject.Supply(mempoolOpt), - appconfig.Compose(&appv1alpha1.Config{ - Modules: []*appv1alpha1.ModuleConfig{ - { - Name: "runtime", - Config: appconfig.WrapAny(&runtimev1alpha1.Module{ - AppName: "BaseAppApp", - }), - }, - }, - })) -} diff --git a/baseapp/utils_test.go b/baseapp/utils_test.go index 7d3763f1c515..b2f4b541aefe 100644 --- a/baseapp/utils_test.go +++ b/baseapp/utils_test.go @@ -14,20 +14,48 @@ import ( "testing" "unsafe" + runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1" + bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1" + consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1" + mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1" + paramsmodulev1 "cosmossdk.io/api/cosmos/params/module/v1" + stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1" + txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1" + "cosmossdk.io/core/appconfig" + "cosmossdk.io/depinject" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/runtime" storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/testutil/mock" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/mempool" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + _ "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/signing" + _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + _ "github.com/cosmos/cosmos-sdk/x/bank" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + _ "github.com/cosmos/cosmos-sdk/x/consensus" + _ "github.com/cosmos/cosmos-sdk/x/mint" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + _ "github.com/cosmos/cosmos-sdk/x/params" + _ "github.com/cosmos/cosmos-sdk/x/staking" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) var ParamStoreKey = []byte("paramstore") @@ -40,6 +68,132 @@ func defaultLogger() log.Logger { return log.NewNopLogger() } +// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts +// that also act as delegators. +func GenesisStateWithSingleValidator(t *testing.T, codec codec.Codec, builder *runtime.AppBuilder) map[string]json.RawMessage { + t.Helper() + + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() + require.NoError(t, err) + + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balances := []banktypes.Balance{ + { + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), + }, + } + + genesisState := builder.DefaultGenesis() + // sus + genesisState, err = simtestutil.GenesisStateWithValSet(codec, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) + require.NoError(t, err) + + return genesisState +} + +func makeTestConfig() depinject.Config { + return appconfig.Compose(&appv1alpha1.Config{ + Modules: []*appv1alpha1.ModuleConfig{ + { + Name: "runtime", + Config: appconfig.WrapAny(&runtimev1alpha1.Module{ + AppName: "BaseAppApp", + BeginBlockers: []string{ + "mint", + "staking", + "auth", + "bank", + "params", + "consensus", + }, + EndBlockers: []string{ + "staking", + "auth", + "bank", + "mint", + "params", + "consensus", + }, + OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{ + { + ModuleName: "auth", + KvStoreKey: "acc", + }, + }, + InitGenesis: []string{ + "auth", + "bank", + "staking", + "mint", + "params", + "consensus", + }, + }), + }, + { + Name: "auth", + Config: appconfig.WrapAny(&authmodulev1.Module{ + Bech32Prefix: "cosmos", + ModuleAccountPermissions: []*authmodulev1.ModuleAccountPermission{ + {Account: authtypes.FeeCollectorName}, + {Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}}, + {Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, + {Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, + }, + }), + }, + { + Name: "bank", + Config: appconfig.WrapAny(&bankmodulev1.Module{}), + }, + { + Name: "params", + Config: appconfig.WrapAny(¶msmodulev1.Module{}), + }, + { + Name: "staking", + Config: appconfig.WrapAny(&stakingmodulev1.Module{}), + }, + { + Name: "mint", + Config: appconfig.WrapAny(&mintmodulev1.Module{}), + }, + { + Name: "consensus", + Config: appconfig.WrapAny(&consensusmodulev1.Module{}), + }, + { + Name: "tx", + Config: appconfig.WrapAny(&txconfigv1.Config{}), + }, + }, + }) +} + +func makeMinimalConfig() depinject.Config { + var mempoolOpt runtime.BaseAppOption = baseapp.SetMempool(mempool.NewSenderNonceMempool()) + return depinject.Configs( + depinject.Supply(mempoolOpt), + appconfig.Compose(&appv1alpha1.Config{ + Modules: []*appv1alpha1.ModuleConfig{ + { + Name: "runtime", + Config: appconfig.WrapAny(&runtimev1alpha1.Module{ + AppName: "BaseAppApp", + }), + }, + }, + })) +} + type MsgKeyValueImpl struct{} func (m MsgKeyValueImpl) Set(ctx context.Context, msg *baseapptestutil.MsgKeyValue) (*baseapptestutil.MsgCreateKeyValueResponse, error) {