Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add weighted operations run simulation #1055

Merged
merged 16 commits into from
Nov 2, 2022
3 changes: 3 additions & 0 deletions app/params/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const (
DefaultWeightMsgStoreCode int = 50
DefaultWeightMsgInstantiateContract int = 100
DefaultWeightMsgExecuteContract int = 100
DefaultWeightMsgUpdateAdmin int = 25
DefaultWeightMsgClearAdmin int = 10
DefaultWeightMsgMigrateContract int = 50

DefaultWeightStoreCodeProposal int = 5
DefaultWeightInstantiateContractProposal int = 5
Expand Down
7 changes: 7 additions & 0 deletions x/wasm/keeper/testdata/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ import (
//go:embed reflect.wasm
var reflectContract []byte

//go:embed reflect_1_1.wasm
var migrateReflectContract []byte

func ReflectContractWasm() []byte {
return reflectContract
}

func MigrateReflectContractWasm() []byte {
return migrateReflectContract
}

// ReflectHandleMsg is used to encode handle messages
type ReflectHandleMsg struct {
Reflect *ReflectPayload `json:"reflect_msg,omitempty"`
Expand Down
Binary file added x/wasm/keeper/testdata/reflect_1_1.wasm
Binary file not shown.
216 changes: 213 additions & 3 deletions x/wasm/simulation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const (
OpWeightMsgStoreCode = "op_weight_msg_store_code"
OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract"
OpWeightMsgExecuteContract = "op_weight_msg_execute_contract"
OpWeightMsgUpdateAdmin = "op_weight_msg_update_admin"
OpWeightMsgClearAdmin = "op_weight_msg_clear_admin"
OpWeightMsgMigrateContract = "op_weight_msg_migrate_contract"
OpReflectContractPath = "op_reflect_contract_path"
)

Expand Down Expand Up @@ -54,6 +57,9 @@ func WeightedOperations(
weightMsgStoreCode int
weightMsgInstantiateContract int
weightMsgExecuteContract int
weightMsgUpdateAdmin int
weightMsgClearAdmin int
weightMsgMigrateContract int
wasmContractPath string
)

Expand All @@ -62,7 +68,6 @@ func WeightedOperations(
weightMsgStoreCode = params.DefaultWeightMsgStoreCode
},
)

simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgInstantiateContract, &weightMsgInstantiateContract, nil,
func(_ *rand.Rand) {
weightMsgInstantiateContract = params.DefaultWeightMsgInstantiateContract
Expand All @@ -73,6 +78,21 @@ func WeightedOperations(
weightMsgExecuteContract = params.DefaultWeightMsgExecuteContract
},
)
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgUpdateAdmin, &weightMsgUpdateAdmin, nil,
func(_ *rand.Rand) {
weightMsgUpdateAdmin = params.DefaultWeightMsgUpdateAdmin
},
)
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgClearAdmin, &weightMsgClearAdmin, nil,
func(_ *rand.Rand) {
weightMsgClearAdmin = params.DefaultWeightMsgClearAdmin
},
)
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgMigrateContract, &weightMsgMigrateContract, nil,
func(_ *rand.Rand) {
weightMsgMigrateContract = params.DefaultWeightMsgMigrateContract
},
)
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpReflectContractPath, &wasmContractPath, nil,
func(_ *rand.Rand) {
wasmContractPath = ""
Expand All @@ -81,7 +101,7 @@ func WeightedOperations(

var wasmBz []byte
if wasmContractPath == "" {
wasmBz = testdata.ReflectContractWasm()
wasmBz = testdata.MigrateReflectContractWasm()
} else {
var err error
wasmBz, err = os.ReadFile(wasmContractPath)
Expand Down Expand Up @@ -110,6 +130,194 @@ func WeightedOperations(
DefaultSimulationExecutePayloader,
),
),
simulation.NewWeightedOperation(
weightMsgUpdateAdmin,
SimulateMsgUpdateAmin(
ak,
bk,
wasmKeeper,
DefaultSimulationUpdateAdminContractSelector,
),
),
simulation.NewWeightedOperation(
weightMsgClearAdmin,
SimulateMsgClearAdmin(
ak,
bk,
wasmKeeper,
DefaultSimulationClearAdminContractSelector,
),
),
simulation.NewWeightedOperation(
weightMsgMigrateContract,
SimulateMsgMigrateContract(
ak,
bk,
wasmKeeper,
DefaultSimulationMigrateContractSelector,
DefaultSimulationMigrateCodeIDSelector,
),
),
}
}

type (
MsgMigrateContractSelector func(sdk.Context, WasmKeeper, string) (sdk.AccAddress, types.ContractInfo)
MsgMigrateCodeIDSelector func(sdk.Context, WasmKeeper, uint64) uint64
)

func DefaultSimulationMigrateContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) (sdk.AccAddress, types.ContractInfo) {
var contractAddress sdk.AccAddress
var contractInfo types.ContractInfo
wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool {
if info.Admin != adminAddress {
return false
}
contractAddress = address
contractInfo = info
return true
})
return contractAddress, contractInfo
}

func DefaultSimulationMigrateCodeIDSelector(ctx sdk.Context, wasmKeeper WasmKeeper, currentCodeID uint64) uint64 {
var codeID uint64
wasmKeeper.IterateCodeInfos(ctx, func(u uint64, info types.CodeInfo) bool {
if (info.InstantiateConfig.Permission != types.AccessTypeEverybody) || (u == currentCodeID) {
return false
}
codeID = u
return true
})
return codeID
}

func SimulateMsgMigrateContract(
ak types.AccountKeeper,
bk BankKeeper,
wasmKeeper WasmKeeper,
contractSelector MsgMigrateContractSelector,
codeIDSelector MsgMigrateCodeIDSelector,
) 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)
ctAddress, info := contractSelector(ctx, wasmKeeper, simAccount.Address.String())
if ctAddress == nil {
return simtypes.NoOpMsg(types.ModuleName, types.MsgMigrateContract{}.Type(), "no contract instance available"), nil, nil
}

codeID := codeIDSelector(ctx, wasmKeeper, info.CodeID)
if codeID == 0 {
return simtypes.NoOpMsg(types.ModuleName, types.MsgMigrateContract{}.Type(), "no target contract available"), nil, nil
}
migrateMsg := types.MsgMigrateContract{
Sender: simAccount.Address.String(),
Contract: ctAddress.String(),
CodeID: codeID,
Msg: []byte(`{}`),
}

txCtx := BuildOperationInput(r, app, ctx, &migrateMsg, simAccount, ak, bk, nil)
return simulation.GenAndDeliverTxWithRandFees(txCtx)
}
}

type MsgClearAdminContractSelector func(sdk.Context, WasmKeeper, string) sdk.AccAddress

func DefaultSimulationClearAdminContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) sdk.AccAddress {
var ctAddress sdk.AccAddress
wasmKeeper.IterateContractInfo(ctx, func(addr sdk.AccAddress, info types.ContractInfo) bool {
if info.Admin != adminAddress {
return false
}
ctAddress = addr
return true
})
return ctAddress
}

func SimulateMsgClearAdmin(
ak types.AccountKeeper,
bk BankKeeper,
wasmKeeper WasmKeeper,
contractSelector MsgClearAdminContractSelector,
) simtypes.Operation {
return func(
r *rand.Rand,
app *baseapp.BaseApp,
ctx sdk.Context,
accounts []simtypes.Account,
chainID string,
) (OperationMsg simtypes.OperationMsg, futureOps []simtypes.FutureOperation, err error) {
simAccount, _ := simtypes.RandomAcc(r, accounts)
ctAddress := contractSelector(ctx, wasmKeeper, simAccount.Address.String())
if ctAddress == nil {
return simtypes.NoOpMsg(types.ModuleName, types.MsgClearAdmin{}.Type(), "no contract instance available"), nil, nil
}

msg := types.MsgClearAdmin{
Sender: simAccount.Address.String(),
Contract: ctAddress.String(),
}
txCtx := BuildOperationInput(r, app, ctx, &msg, simAccount, ak, bk, nil)
return simulation.GenAndDeliverTxWithRandFees(txCtx)
}
}

type MsgUpdateAdminContractSelector func(sdk.Context, WasmKeeper, string) (sdk.AccAddress, types.ContractInfo)

// DefaultSimulationUpdateAdminContractSelector picks the first contract which Admin != ""
func DefaultSimulationUpdateAdminContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) (sdk.AccAddress, types.ContractInfo) {
var contractAddress sdk.AccAddress
var contractInfo types.ContractInfo
wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool {
if info.Admin != adminAddress {
return false
}
contractAddress = address
contractInfo = info
return true
})
return contractAddress, contractInfo
}

func SimulateMsgUpdateAmin(
ak types.AccountKeeper,
bk BankKeeper,
wasmKeeper WasmKeeper,
contractSelector MsgUpdateAdminContractSelector,
) 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)
ctAddress, _ := contractSelector(ctx, wasmKeeper, simAccount.Address.String())
if ctAddress == nil {
return simtypes.NoOpMsg(types.ModuleName, types.MsgUpdateAdmin{}.Type(), "no contract instance available"), nil, nil
}

newAdmin, _ := simtypes.RandomAcc(r, accs)
if newAdmin.Address.String() == simAccount.Address.String() {
return simtypes.NoOpMsg(types.ModuleName, types.MsgUpdateAdmin{}.Type(), "new admin cannot be the same as current admin"), nil, nil
}

msg := types.MsgUpdateAdmin{
Sender: simAccount.Address.String(),
NewAdmin: newAdmin.Address.String(),
Contract: ctAddress.String(),
}
txCtx := BuildOperationInput(r, app, ctx, &msg, simAccount, ak, bk, nil)
return simulation.GenAndDeliverTxWithRandFees(txCtx)
}
}

Expand Down Expand Up @@ -180,9 +388,11 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk BankKeeper, wasmK
}
}

adminAccount, _ := simtypes.RandomAcc(r, accs)

msg := types.MsgInstantiateContract{
Sender: simAccount.Address.String(),
Admin: simtypes.RandomAccounts(r, 1)[0].Address.String(),
Admin: adminAccount.Address.String(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

CodeID: codeID,
Label: simtypes.RandStringOfLength(r, 10),
Msg: []byte(`{}`),
Expand Down
7 changes: 4 additions & 3 deletions x/wasm/simulation/proposals.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package simulation
import (
"math/rand"

"github.com/CosmWasm/wasmd/app/params"
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
"github.com/CosmWasm/wasmd/x/wasm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
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/keeper/testdata"
"github.com/CosmWasm/wasmd/x/wasm/types"
)

const (
Expand Down