mirror of https://github.com/certusone/wasmd.git
Add MsgStoreCode and MsgInstantiateContract support to simulations (#831)
* Add MsgStoreCode and MsgInstantiateContract support to simulations * Check for permissions in codeInfo
This commit is contained in:
parent
fb2d2f2ab9
commit
23c75b18b8
|
@ -515,7 +515,7 @@ func NewWasmApp(
|
|||
distr.NewAppModule(appCodec, app.distrKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
|
||||
staking.NewAppModule(appCodec, app.stakingKeeper, app.accountKeeper, app.bankKeeper),
|
||||
upgrade.NewAppModule(app.upgradeKeeper),
|
||||
wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper),
|
||||
wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper, app.accountKeeper, app.bankKeeper),
|
||||
evidence.NewAppModule(app.evidenceKeeper),
|
||||
feegrantmodule.NewAppModule(appCodec, app.accountKeeper, app.bankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
|
||||
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.accountKeeper, app.bankKeeper, app.interfaceRegistry),
|
||||
|
@ -632,7 +632,7 @@ func NewWasmApp(
|
|||
slashing.NewAppModule(appCodec, app.slashingKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
|
||||
params.NewAppModule(app.paramsKeeper),
|
||||
evidence.NewAppModule(app.evidenceKeeper),
|
||||
wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper),
|
||||
wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper, app.accountKeeper, app.bankKeeper),
|
||||
ibc.NewAppModule(app.ibcKeeper),
|
||||
transferModule,
|
||||
)
|
||||
|
|
|
@ -20,4 +20,6 @@ const (
|
|||
DefaultWeightCommunitySpendProposal int = 5
|
||||
DefaultWeightTextProposal int = 5
|
||||
DefaultWeightParamChangeProposal int = 5
|
||||
DefaultWeightMsgStoreCode int = 100
|
||||
DefaultWeightMsgInstantiateContract int = 100
|
||||
)
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
simKeeper "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cast"
|
||||
|
@ -103,6 +104,8 @@ type AppModule struct {
|
|||
cdc codec.Codec
|
||||
keeper *Keeper
|
||||
validatorSetSource keeper.ValidatorSetSource
|
||||
accountKeeper types.AccountKeeper // for simulation
|
||||
bankKeeper simKeeper.BankKeeper
|
||||
}
|
||||
|
||||
// ConsensusVersion is a sequence number for state-breaking change of the
|
||||
|
@ -112,12 +115,20 @@ type AppModule struct {
|
|||
func (AppModule) ConsensusVersion() uint64 { return 1 }
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(cdc codec.Codec, keeper *Keeper, validatorSetSource keeper.ValidatorSetSource) AppModule {
|
||||
func NewAppModule(
|
||||
cdc codec.Codec,
|
||||
keeper *Keeper,
|
||||
validatorSetSource keeper.ValidatorSetSource,
|
||||
ak types.AccountKeeper,
|
||||
bk simKeeper.BankKeeper,
|
||||
) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
cdc: cdc,
|
||||
keeper: keeper,
|
||||
validatorSetSource: validatorSetSource,
|
||||
accountKeeper: ak,
|
||||
bankKeeper: bk,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +207,7 @@ func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
|
||||
// WeightedOperations returns the all the gov module operations with their respective weights.
|
||||
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
||||
return nil
|
||||
return simulation.WeightedOperations(&simState, am.accountKeeper, am.bankKeeper, am.keeper)
|
||||
}
|
||||
|
||||
// ____________________________________________________________________________
|
||||
|
|
|
@ -36,7 +36,7 @@ func setupTest(t *testing.T) testData {
|
|||
ctx, keepers := CreateTestInput(t, false, "iterator,staking,stargate")
|
||||
cdc := keeper.MakeTestCodec(t)
|
||||
data := testData{
|
||||
module: NewAppModule(cdc, keepers.WasmKeeper, keepers.StakingKeeper),
|
||||
module: NewAppModule(cdc, keepers.WasmKeeper, keepers.StakingKeeper, keepers.AccountKeeper, keepers.BankKeeper),
|
||||
ctx: ctx,
|
||||
acctKeeper: keepers.AccountKeeper,
|
||||
keeper: *keepers.WasmKeeper,
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
"github.com/CosmWasm/wasmd/app/params"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
//go:embed testdata/reflect.wasm
|
||||
var reflectContract []byte
|
||||
|
||||
// Simulation operation weights constants
|
||||
//nolint:gosec
|
||||
const (
|
||||
OpWeightMsgStoreCode = "op_weight_msg_store_code"
|
||||
OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract"
|
||||
)
|
||||
|
||||
// WasmKeeper is a subset of the wasm keeper used by simulations
|
||||
type WasmKeeper interface {
|
||||
GetParams(ctx sdk.Context) types.Params
|
||||
IterateCodeInfos(ctx sdk.Context, cb func(uint64, types.CodeInfo) bool)
|
||||
}
|
||||
|
||||
// WeightedOperations returns all the operations from the module with their respective weights
|
||||
func WeightedOperations(
|
||||
simstate *module.SimulationState,
|
||||
ak types.AccountKeeper,
|
||||
bk simulation.BankKeeper,
|
||||
wasmKeeper WasmKeeper,
|
||||
) simulation.WeightedOperations {
|
||||
var (
|
||||
weightMsgStoreCode int
|
||||
weightMsgInstantiateContract int
|
||||
)
|
||||
|
||||
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgStoreCode, &weightMsgStoreCode, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightMsgStoreCode = params.DefaultWeightMsgStoreCode
|
||||
},
|
||||
)
|
||||
|
||||
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgInstantiateContract, &weightMsgInstantiateContract, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightMsgInstantiateContract = params.DefaultWeightMsgInstantiateContract
|
||||
},
|
||||
)
|
||||
|
||||
return simulation.WeightedOperations{
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgStoreCode,
|
||||
SimulateMsgStoreCode(ak, bk, wasmKeeper),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgInstantiateContract,
|
||||
SimulateMsgInstantiateContract(ak, bk, wasmKeeper),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgStoreCode generates a MsgStoreCode with random values
|
||||
func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasmKeeper WasmKeeper) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand,
|
||||
app *baseapp.BaseApp,
|
||||
ctx sdk.Context,
|
||||
accs []simtypes.Account,
|
||||
chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
if wasmKeeper.GetParams(ctx).CodeUploadAccess.Permission != types.AccessTypeEverybody {
|
||||
return simtypes.NoOpMsg(types.ModuleName, types.MsgStoreCode{}.Type(), "no chain permission"), nil, nil
|
||||
}
|
||||
|
||||
config := &types.AccessConfig{
|
||||
Permission: types.AccessTypeEverybody,
|
||||
}
|
||||
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
msg := types.MsgStoreCode{
|
||||
Sender: simAccount.Address.String(),
|
||||
WASMByteCode: reflectContract,
|
||||
InstantiatePermission: config,
|
||||
}
|
||||
|
||||
txCtx := simulation.OperationInput{
|
||||
R: r,
|
||||
App: app,
|
||||
TxGen: simappparams.MakeTestEncodingConfig().TxConfig,
|
||||
Cdc: nil,
|
||||
Msg: &msg,
|
||||
MsgType: msg.Type(),
|
||||
Context: ctx,
|
||||
SimAccount: simAccount,
|
||||
AccountKeeper: ak,
|
||||
Bankkeeper: bk,
|
||||
ModuleName: types.ModuleName,
|
||||
}
|
||||
|
||||
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgInstantiateContract generates a MsgInstantiateContract with random values
|
||||
func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKeeper, wasmKeeper WasmKeeper) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand,
|
||||
app *baseapp.BaseApp,
|
||||
ctx sdk.Context,
|
||||
accs []simtypes.Account,
|
||||
chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
|
||||
var codeID uint64
|
||||
wasmKeeper.IterateCodeInfos(ctx, func(u uint64, info types.CodeInfo) bool {
|
||||
if info.InstantiateConfig.Permission != types.AccessTypeEverybody {
|
||||
return false
|
||||
}
|
||||
codeID = u
|
||||
return true
|
||||
})
|
||||
|
||||
if codeID == 0 {
|
||||
return simtypes.NoOpMsg(types.ModuleName, types.MsgInstantiateContract{}.Type(), "no codes with permission available"), nil, nil
|
||||
}
|
||||
|
||||
spendable := bk.SpendableCoins(ctx, simAccount.Address)
|
||||
|
||||
msg := types.MsgInstantiateContract{
|
||||
Sender: simAccount.Address.String(),
|
||||
Admin: simtypes.RandomAccounts(r, 1)[0].Address.String(),
|
||||
CodeID: codeID,
|
||||
Label: simtypes.RandStringOfLength(r, 10),
|
||||
Msg: []byte(`{}`),
|
||||
Funds: simtypes.RandSubsetCoins(r, spendable),
|
||||
}
|
||||
|
||||
txCtx := simulation.OperationInput{
|
||||
R: r,
|
||||
App: app,
|
||||
TxGen: simappparams.MakeTestEncodingConfig().TxConfig,
|
||||
Cdc: nil,
|
||||
Msg: &msg,
|
||||
MsgType: msg.Type(),
|
||||
Context: ctx,
|
||||
SimAccount: simAccount,
|
||||
AccountKeeper: ak,
|
||||
Bankkeeper: bk,
|
||||
ModuleName: types.ModuleName,
|
||||
}
|
||||
|
||||
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue