refactor: Baseapp audit changes (backport #14379) (#14392)

Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com>
This commit is contained in:
mergify[bot] 2022-12-22 21:22:26 +00:00 committed by GitHub
parent cdc438f442
commit e8c6d1c7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 189 additions and 217 deletions

View File

@ -52,10 +52,10 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
} }
// initialize states with a correct header // initialize states with a correct header
app.setDeliverState(initHeader) app.setState(runTxModeDeliver, initHeader)
app.setCheckState(initHeader) app.setState(runTxModeCheck, initHeader)
app.setPrepareProposalState(initHeader) app.setState(runTxPrepareProposal, initHeader)
app.setProcessProposalState(initHeader) app.setState(runTxProcessProposal, initHeader)
// Store the consensus params in the BaseApp's paramstore. Note, this must be // 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 // 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 // already be initialized in InitChain. Otherwise app.deliverState will be
// nil, since it is reset on Commit. // nil, since it is reset on Commit.
if app.deliverState == nil { if app.deliverState == nil {
app.setDeliverState(req.Header) app.setState(runTxModeDeliver, req.Header)
} else { } else {
// In the first block, app.deliverState.ctx will already be initialized // In the first block, app.deliverState.ctx will already be initialized
// by InitChain. Context is now updated with Header information. // 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 // 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 // Tendermint that the Status is ACCEPT. However, the application is also able
// to implement optimizations such as executing the entire proposed block // 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 // If a panic is detected during execution of an application's ProcessProposal
// handler, it will be recovered and we will reject the proposal. // 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 // NOTE: This is safe because Tendermint holds a lock on the mempool for
// Commit. Use the header from this latest block. // Commit. Use the header from this latest block.
app.setCheckState(header) app.setState(runTxModeCheck, header)
app.setPrepareProposalState(header) app.setState(runTxPrepareProposal, header)
app.setProcessProposalState(header) app.setState(runTxProcessProposal, header)
// empty/reset the deliver state // empty/reset the deliver state
app.deliverState = nil app.deliverState = nil

View File

@ -351,11 +351,11 @@ func (app *BaseApp) Init() error {
emptyHeader := tmproto.Header{} emptyHeader := tmproto.Header{}
// needed for the export command which inits from store but never calls initchain // 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) // needed for ABCI Replay Blocks mode which calls Prepare/Process proposal (InitChain is not called)
app.setPrepareProposalState(emptyHeader) app.setState(runTxPrepareProposal, emptyHeader)
app.setProcessProposalState(emptyHeader) app.setState(runTxProcessProposal, emptyHeader)
app.Seal() app.Seal()
rms, ok := app.cms.(*rootmulti.Store) rms, ok := app.cms.(*rootmulti.Store)
@ -403,49 +403,32 @@ func (app *BaseApp) Seal() { app.sealed = true }
// IsSealed returns true if the BaseApp is sealed and false otherwise. // IsSealed returns true if the BaseApp is sealed and false otherwise.
func (app *BaseApp) IsSealed() bool { return app.sealed } func (app *BaseApp) IsSealed() bool { return app.sealed }
// setCheckState sets the BaseApp's checkState with a branched multi-store // setState sets the BaseApp's state for the corresponding mode with a branched
// (i.e. a CacheMultiStore) and a new Context with the same multi-store branch, // multi-store (i.e. a CacheMultiStore) and a new Context with the same
// provided header, and minimum gas prices set. It is set on InitChain and reset // multi-store branch, and provided header.
// on Commit. func (app *BaseApp) setState(mode runTxMode, header tmproto.Header) {
func (app *BaseApp) setCheckState(header tmproto.Header) {
ms := app.cms.CacheMultiStore() ms := app.cms.CacheMultiStore()
app.checkState = &state{ baseState := &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, ms: ms,
ctx: sdk.NewContext(ms, header, false, app.logger), ctx: sdk.NewContext(ms, header, false, app.logger),
} }
}
// setPrepareProposalState sets the BaseApp's prepareProposalState with a switch mode {
// branched multi-store (i.e. a CacheMultiStore) and a new Context with the case runTxModeCheck:
// same multi-store branch, and provided header. It is set on InitChain and Commit. // Minimum gas prices are also set. It is set on InitChain and reset on Commit.
func (app *BaseApp) setPrepareProposalState(header tmproto.Header) { baseState.ctx = baseState.ctx.WithIsCheckTx(true).WithMinGasPrices(app.minGasPrices)
ms := app.cms.CacheMultiStore() app.checkState = baseState
app.prepareProposalState = &state{ case runTxModeDeliver:
ms: ms, // It is set on InitChain and BeginBlock and set to nil on Commit.
ctx: sdk.NewContext(ms, header, false, app.logger), app.deliverState = baseState
} case runTxPrepareProposal:
} // It is set on InitChain and Commit.
app.prepareProposalState = baseState
// setProcessProposalState sets the BaseApp's processProposalState with a case runTxProcessProposal:
// branched multi-store (i.e. a CacheMultiStore) and a new Context with the // It is set on InitChain and Commit.
// same multi-store branch, and provided header. It is set on InitChain and Commit. app.processProposalState = baseState
func (app *BaseApp) setProcessProposalState(header tmproto.Header) { default:
ms := app.cms.CacheMultiStore() panic(fmt.Sprintf("invalid runTxMode for setState: %d", mode))
app.processProposalState = &state{
ms: ms,
ctx: sdk.NewContext(ms, header, false, app.logger),
} }
} }
@ -553,7 +536,8 @@ func validateBasicTxMsgs(msgs []sdk.Msg) error {
} }
// Returns the application's deliverState if app is in runTxModeDeliver, // 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 { func (app *BaseApp) getState(mode runTxMode) *state {
switch mode { switch mode {
case runTxModeDeliver: case runTxModeDeliver:

View File

@ -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(&paramsmodulev1.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",
}),
},
},
}))
}

View File

@ -14,20 +14,48 @@ import (
"testing" "testing"
"unsafe" "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/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db" dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil"
"github.com/cosmos/cosmos-sdk/client" "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/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/runtime"
storetypes "github.com/cosmos/cosmos-sdk/store/types" 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" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/mempool"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" 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/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 ( var (
@ -42,6 +70,132 @@ func defaultLogger() log.Logger {
return log.NewNopLogger() 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(&paramsmodulev1.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{} type MsgKeyValueImpl struct{}
func (m MsgKeyValueImpl) Set(ctx context.Context, msg *baseapptestutil.MsgKeyValue) (*baseapptestutil.MsgCreateKeyValueResponse, error) { func (m MsgKeyValueImpl) Set(ctx context.Context, msg *baseapptestutil.MsgKeyValue) (*baseapptestutil.MsgCreateKeyValueResponse, error) {