Skip to content

Commit

Permalink
Add MsgStoreCode and MsgInstantiateContract support to simulations (#831
Browse files Browse the repository at this point in the history
)

* Add MsgStoreCode and MsgInstantiateContract support to simulations

* Check for permissions in codeInfo
  • Loading branch information
pinosu committed May 3, 2022
1 parent fb2d2f2 commit 23c75b1
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 5 deletions.
4 changes: 2 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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,
)
Expand Down
2 changes: 2 additions & 0 deletions app/params/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ const (
DefaultWeightCommunitySpendProposal int = 5
DefaultWeightTextProposal int = 5
DefaultWeightParamChangeProposal int = 5
DefaultWeightMsgStoreCode int = 100
DefaultWeightMsgInstantiateContract int = 100
)
15 changes: 13 additions & 2 deletions x/wasm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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,
}
}

Expand Down Expand Up @@ -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)
}

// ____________________________________________________________________________
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
163 changes: 163 additions & 0 deletions x/wasm/simulation/operations.go
Original file line number Diff line number Diff line change
@@ -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 added x/wasm/simulation/testdata/reflect.wasm
Binary file not shown.

0 comments on commit 23c75b1

Please sign in to comment.