diff --git a/Makefile b/Makefile index 8ecb8d5afa..1311e48f56 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g') +BINDIR ?= $(GOPATH)/bin +SIMAPP = ./app # for dockerized protobuf tools PROTO_CONTAINER := cosmwasm/prototools-docker:v0.1.0 @@ -94,6 +96,9 @@ BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(ldflags)' -trimpath CORAL_BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(coral_ldflags)' -trimpath FLEX_BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(flex_ldflags)' -trimpath +# The below include contains the tools and runsim targets. +include contrib/devtools/Makefile + all: install lint test build: go.sum @@ -172,6 +177,13 @@ test-cover: benchmark: @go test -mod=readonly -bench=. ./... +test-sim-import-export: runsim + @echo "Running application import/export simulation. This may take several minutes..." + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppImportExport + +test-sim-multi-seed-short: runsim + @echo "Running short multi-seed application simulation. This may take awhile!" + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation ############################################################################### ### Linting ### @@ -208,4 +220,5 @@ proto-check-breaking: .PHONY: all build-linux install install-debug \ go-mod-cache draw-deps clean build format \ - test test-all test-build test-cover test-unit test-race + test test-all test-build test-cover test-unit test-race \ + test-sim-import-export \ diff --git a/README.md b/README.md index 7d0d472468..f2627e914a 100644 --- a/README.md +++ b/README.md @@ -209,5 +209,6 @@ Or even testing the app and bringing up critical issues. The following have help * Rick Dudley [AFDudley](https://github.com/AFDudley) * KamiD [KamiD](https://github.com/KamiD) * Valery Litvin [litvintech](https://github.com/litvintech) +* Leonardo Bragagnolo [bragaz](https://github.com/bragaz) Sorry if I forgot you from this list, just contact me or add yourself in a PR :) diff --git a/app/app.go b/app/app.go index 582aeaf8ef..651c86cd05 100644 --- a/app/app.go +++ b/app/app.go @@ -417,7 +417,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b 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(&app.wasmKeeper, app.stakingKeeper), + wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper), evidence.NewAppModule(app.evidenceKeeper), ibc.NewAppModule(app.ibcKeeper), params.NewAppModule(app.paramsKeeper), @@ -469,7 +469,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b distr.NewAppModule(appCodec, app.distrKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper), slashing.NewAppModule(appCodec, app.slashingKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper), params.NewAppModule(app.paramsKeeper), - wasm.NewAppModule(&app.wasmKeeper, app.stakingKeeper), + wasm.NewAppModule(appCodec, &app.wasmKeeper, app.stakingKeeper), evidence.NewAppModule(app.evidenceKeeper), ibc.NewAppModule(app.ibcKeeper), transferModule, @@ -616,6 +616,10 @@ func (app *WasmApp) RegisterTendermintService(clientCtx client.Context) { tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) } +func (app *WasmApp) AppCodec() codec.JSONMarshaler { + return app.appCodec +} + // RegisterSwaggerAPI registers swagger route with API Server func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) { statikFS, err := fs.New() diff --git a/app/sim_test.go b/app/sim_test.go new file mode 100644 index 0000000000..adf408e7b9 --- /dev/null +++ b/app/sim_test.go @@ -0,0 +1,230 @@ +package app + +import ( + "encoding/json" + "fmt" + "github.com/CosmWasm/wasmd/x/wasm" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" + ibchost "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/simulation" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + "os" + "path/filepath" + "testing" +) + +// Get flags every time the simulator is run +func init() { + simapp.GetSimulatorFlags() +} + +type StoreKeysPrefixes struct { + A sdk.StoreKey + B sdk.StoreKey + Prefixes [][]byte +} + +// SetupSimulation wraps simapp.SetupSimulation in order to create any export directory if they do not exist yet +func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { + config, db, dir, logger, skip, err := simapp.SetupSimulation(dirPrefix, dbName) + if err != nil { + return simtypes.Config{}, nil, "", nil, false, err + } + + paths := []string{config.ExportParamsPath, config.ExportStatePath, config.ExportStatsPath} + for _, path := range paths { + if len(path) == 0 { + continue + } + + path = filepath.Dir(path) + if _, err := os.Stat(path); os.IsNotExist(err) { + if err := os.MkdirAll(path, os.ModePerm); err != nil { + panic(err) + } + } + } + + return config, db, dir, logger, skip, err +} + +// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the +// each's module store key and the prefix bytes of the KVPair's key. +func GetSimulationLog(storeName string, sdr sdk.StoreDecoderRegistry, kvAs, kvBs []kv.Pair) (log string) { + for i := 0; i < len(kvAs); i++ { + if len(kvAs[i].Value) == 0 && len(kvBs[i].Value) == 0 { + // skip if the value doesn't have any bytes + continue + } + + decoder, ok := sdr[storeName] + if ok { + log += decoder(kvAs[i], kvBs[i]) + } else { + log += fmt.Sprintf("store A %s => %s\nstore B %s => %s\n", kvAs[i].Key, kvAs[i].Value, kvBs[i].Key, kvBs[i].Value) + } + } + + return log +} + +// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of +// an IAVLStore for faster simulation speed. +func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { + bapp.SetFauxMerkleMode() +} + +func TestAppImportExport(t *testing.T) { + config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application import/export simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + app := NewWasmApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, wasm.EnableAllProposals, EmptyBaseAppOptions{}, nil, fauxMerkleModeOpt) + require.Equal(t, appName, app.Name()) + + // Run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simapp.AppStateFn(app.AppCodec(), app.SimulationManager()), + simtypes.RandomAccounts, + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } + + fmt.Printf("exporting genesis...\n") + + exported, err := app.ExportAppStateAndValidators(false, []string{}) + require.NoError(t, err) + + fmt.Printf("importing genesis...\n") + + _, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2") + require.NoError(t, err, "simulation setup failed") + + defer func() { + newDB.Close() + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp := NewWasmApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, wasm.EnableAllProposals, EmptyBaseAppOptions{}, nil, fauxMerkleModeOpt) + require.Equal(t, appName, newApp.Name()) + + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState) + newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) + + fmt.Printf("comparing stores...\n") + + storeKeysPrefixes := []StoreKeysPrefixes{ + {app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}}, + {app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey], + [][]byte{ + stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey, + stakingtypes.HistoricalInfoKey, + }}, + {app.keys[slashingtypes.StoreKey], newApp.keys[slashingtypes.StoreKey], [][]byte{}}, + {app.keys[minttypes.StoreKey], newApp.keys[minttypes.StoreKey], [][]byte{}}, + {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}}, + {app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}}, + {app.keys[paramstypes.StoreKey], newApp.keys[paramstypes.StoreKey], [][]byte{}}, + {app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}}, + {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, + {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, + {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, + {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, + {app.keys[wasm.StoreKey], newApp.keys[wasm.StoreKey], [][]byte{}}, + } + + for _, skp := range storeKeysPrefixes { + storeA := ctxA.KVStore(skp.A) + storeB := ctxB.KVStore(skp.B) + + failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes) + require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare") + + fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B) + require.Len(t, failedKVAs, 0, GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + } +} + +func TestFullAppSimulation(t *testing.T) { + config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + app := NewWasmApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, + wasm.EnableAllProposals, simapp.EmptyAppOptions{}, nil, fauxMerkleModeOpt) + require.Equal(t, "WasmApp", app.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simapp.AppStateFn(app.appCodec, app.SimulationManager()), + simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } +} diff --git a/contrib/devtools/Makefile b/contrib/devtools/Makefile new file mode 100644 index 0000000000..ac05cc6779 --- /dev/null +++ b/contrib/devtools/Makefile @@ -0,0 +1,85 @@ +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := "\\" +else + GO := $(shell command -v go 2> /dev/null) + FS := "/" +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + +############################################################################### +### Functions ### +############################################################################### + +go_get = $(if $(findstring Windows_NT,$(OS)),\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\ +,\ +mkdir -p $(GITHUBDIR)$(FS)$(1) &&\ +(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\ +)\ +cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3) + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd) + + +############################################################################### +### Tools ### +############################################################################### + +PREFIX ?= /usr/local +BIN ?= $(PREFIX)/bin +UNAME_S ?= $(shell uname -s) +UNAME_M ?= $(shell uname -m) + +GOPATH ?= $(shell $(GO) env GOPATH) +GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com + +BUF_VERSION ?= 0.11.0 + +TOOLS_DESTDIR ?= $(GOPATH)/bin +STATIK = $(TOOLS_DESTDIR)/statik +RUNSIM = $(TOOLS_DESTDIR)/runsim +GOLANGCI_LINT = $(TOOLS_DESTDIR)/golangci-lint + +tools: tools-stamp +tools-stamp: statik runsim golangci-lint + # Create dummy file to satisfy dependency and avoid + # rebuilding when this Makefile target is hit twice + # in a row. + touch $@ + +statik: $(STATIK) +$(STATIK): + @echo "Installing statik..." + @(cd /tmp && go get github.com/rakyll/statik@v0.1.6) + +# Install the runsim binary with a temporary workaround of entering an outside +# directory as the "go get" command ignores the -mod option and will polute the +# go.{mod, sum} files. +# +# ref: https://github.com/golang/go/issues/30515 +runsim: $(RUNSIM) +$(RUNSIM): + @echo "Installing runsim..." + @(cd /tmp && go get github.com/cosmos/tools/cmd/runsim@v1.0.0) + +golangci-lint: $(GOLANGCI_LINT) +$(GOLANGCI_LINT): + @echo "Installing golangci-lint..." + @(cd /tmp && go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.28.0) + +tools-clean: + rm -f $(STATIK) $(GOLANGCI_LINT) $(RUNSIM) + rm -f tools-stamp + +.PHONY: tools-clean statik runsim diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md new file mode 100644 index 0000000000..659804a611 --- /dev/null +++ b/contrib/devtools/README.md @@ -0,0 +1,6 @@ +## Contributors + +Thanks to the entire Cosmos SDK team and the contributors who put their efforts into making simulation testing +easier to implement. 🤗 + +https://github.com/cosmos/cosmos-sdk/blob/master/contrib/devtools/Makefile \ No newline at end of file diff --git a/x/wasm/module.go b/x/wasm/module.go index 1d45ae517d..b74a8bb78e 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -9,6 +9,7 @@ import ( "github.com/CosmWasm/wasmd/x/wasm/client/rest" "github.com/CosmWasm/wasmd/x/wasm/internal/keeper" "github.com/CosmWasm/wasmd/x/wasm/internal/types" + "github.com/CosmWasm/wasmd/x/wasm/simulation" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -94,14 +95,16 @@ func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) // AppModule implements an application module for the wasm module. type AppModule struct { AppModuleBasic + cdc codec.Marshaler keeper *Keeper validatorSetSource keeper.ValidatorSetSource } // NewAppModule creates a new AppModule object -func NewAppModule(keeper *Keeper, validatorSetSource keeper.ValidatorSetSource) AppModule { +func NewAppModule(cdc codec.Marshaler, keeper *Keeper, validatorSetSource keeper.ValidatorSetSource) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, + cdc: cdc, keeper: keeper, validatorSetSource: validatorSetSource, } @@ -163,6 +166,7 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato // GenerateGenesisState creates a randomized GenState of the bank module. func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) } // ProposalContents doesn't return any content functions for governance proposals. @@ -171,8 +175,8 @@ func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.We } // RandomizedParams creates randomized bank param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return nil +func (am AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { + return simulation.ParamChanges(r, am.cdc) } // RegisterStoreDecoder registers a decoder for supply module's types diff --git a/x/wasm/module_test.go b/x/wasm/module_test.go index 6094c0e658..ed61e75bd2 100644 --- a/x/wasm/module_test.go +++ b/x/wasm/module_test.go @@ -34,8 +34,9 @@ type testData struct { // returns a cleanup function, which must be defered on func setupTest(t *testing.T) testData { ctx, keepers := CreateTestInput(t, false, "staking,stargate", nil, nil) + cdc := keeper.MakeTestCodec(t) data := testData{ - module: NewAppModule(keepers.WasmKeeper, keepers.StakingKeeper), + module: NewAppModule(cdc, keepers.WasmKeeper, keepers.StakingKeeper), ctx: ctx, acctKeeper: keepers.AccountKeeper, keeper: *keepers.WasmKeeper, diff --git a/x/wasm/simulation/genesis.go b/x/wasm/simulation/genesis.go new file mode 100644 index 0000000000..fb61889f8a --- /dev/null +++ b/x/wasm/simulation/genesis.go @@ -0,0 +1,25 @@ +package simulation + +import ( + "github.com/CosmWasm/wasmd/x/wasm/internal/types" + "github.com/cosmos/cosmos-sdk/types/module" +) + +// RandomizeGenState generates a random GenesisState for wasm +func RandomizedGenState(simstate *module.SimulationState) { + params := RandomParams(simstate.Rand) + wasmGenesis := types.GenesisState{ + Params: params, + Codes: nil, + Contracts: nil, + Sequences: nil, + GenMsgs: nil, + } + + _, err := simstate.Cdc.MarshalJSON(&wasmGenesis) + if err != nil { + panic(err) + } + + simstate.GenState[types.ModuleName] = simstate.Cdc.MustMarshalJSON(&wasmGenesis) +} diff --git a/x/wasm/simulation/params.go b/x/wasm/simulation/params.go new file mode 100644 index 0000000000..516e6c48ea --- /dev/null +++ b/x/wasm/simulation/params.go @@ -0,0 +1,47 @@ +package simulation + +import ( + "fmt" + "math/rand" + + "github.com/CosmWasm/wasmd/x/wasm/internal/types" + "github.com/cosmos/cosmos-sdk/codec" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +func ParamChanges(r *rand.Rand, cdc codec.Marshaler) []simtypes.ParamChange { + params := RandomParams(r) + return []simtypes.ParamChange{ + simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyUploadAccess), + func(r *rand.Rand) string { + jsonBz, err := cdc.MarshalJSON(¶ms.CodeUploadAccess) + if err != nil { + panic(err) + } + return string(jsonBz) + }, + ), + simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyInstantiateAccess), + func(r *rand.Rand) string { + return fmt.Sprintf("%q", params.CodeUploadAccess.Permission.String()) + }, + ), + simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyMaxWasmCodeSize), + func(r *rand.Rand) string { + return fmt.Sprintf(`"%d"`, params.MaxWasmCodeSize) + }, + ), + } +} + +func RandomParams(r *rand.Rand) types.Params { + permissionType := types.AccessType(simtypes.RandIntBetween(r, 1, 3)) + account, _ := simtypes.RandomAcc(r, simtypes.RandomAccounts(r, 10)) + accessConfig := permissionType.With(account.Address) + return types.Params{ + CodeUploadAccess: accessConfig, + InstantiateDefaultPermission: accessConfig.Permission, + MaxWasmCodeSize: uint64(simtypes.RandIntBetween(r, 1, 600) * 1024), + } +}