Skip to content

Commit

Permalink
Add simulation for gov (CosmWasm#1064)
Browse files Browse the repository at this point in the history
* add struct for sim gov

* add proposal for store contract

* change wasm file

* add proposal instantiate contract

* change admin account

* add sim gov proposals Update Admin

* add sim gov execute contract

* fix some bug

* add sim gov clear admin

* add comment

* fix lint
  • Loading branch information
GNaD13 authored and conorpp committed Feb 1, 2023
1 parent 3f89e27 commit e22b9df
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 2 deletions.
7 changes: 7 additions & 0 deletions app/params/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ const (
DefaultWeightCommunitySpendProposal int = 5
DefaultWeightTextProposal int = 5
DefaultWeightParamChangeProposal int = 5

DefaultWeightMsgStoreCode int = 50
DefaultWeightMsgInstantiateContract int = 100
DefaultWeightMsgExecuteContract int = 100

DefaultWeightStoreCodeProposal int = 5
DefaultWeightInstantiateContractProposal int = 5
DefaultWeightUpdateAdminProposal int = 5
DefaultWeightExecuteContractProposal int = 5
DefaultWeightClearAdminProposal int = 5
)
4 changes: 2 additions & 2 deletions x/wasm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
}

// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return nil
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return simulation.ProposalContents(am.bankKeeper, am.keeper)
}

// RandomizedParams creates randomized bank param changes for the simulator.
Expand Down
221 changes: 221 additions & 0 deletions x/wasm/simulation/proposals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
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"
)

const (
WeightStoreCodeProposal = "weight_store_code_proposal"
WeightInstantiateContractProposal = "weight_instantiate_contract_proposal"
WeightUpdateAdminProposal = "weight_update_admin_proposal"
WeightExeContractProposal = "weight_execute_contract_proposal"
WeightClearAdminProposal = "weight_clear_admin_proposal"
)

func ProposalContents(bk BankKeeper, wasmKeeper WasmKeeper) []simtypes.WeightedProposalContent {
return []simtypes.WeightedProposalContent{
// simulation.NewWeightedProposalContent(
// WeightStoreCodeProposal,
// params.DefaultWeightStoreCodeProposal,
// SimulateStoreCodeProposal(wasmKeeper),
// ),
simulation.NewWeightedProposalContent(
WeightInstantiateContractProposal,
params.DefaultWeightInstantiateContractProposal,
SimulateInstantiateContractProposal(
bk,
wasmKeeper,
DefaultSimulationCodeIDSelector,
),
),
simulation.NewWeightedProposalContent(
WeightUpdateAdminProposal,
params.DefaultWeightUpdateAdminProposal,
SimulateUpdateAdminProposal(
wasmKeeper,
DefaultSimulateUpdateAdminProposalContractSelector,
),
),
simulation.NewWeightedProposalContent(
WeightExeContractProposal,
params.DefaultWeightExecuteContractProposal,
SimulateExecuteContractProposal(
bk,
wasmKeeper,
DefaultSimulationExecuteContractSelector,
DefaultSimulationExecuteSenderSelector,
DefaultSimulationExecutePayloader,
),
),
simulation.NewWeightedProposalContent(
WeightClearAdminProposal,
params.DefaultWeightClearAdminProposal,
SimulateClearAdminProposal(
wasmKeeper,
DefaultSimulateClearAdminProposalContractSelector,
),
),
}
}

// simulate store code proposal (unused now)
// Current problem: out of gas (defaul gaswanted config of gov SimulateMsgSubmitProposal is 10_000_000)
// but this proposal may need more than it
func SimulateStoreCodeProposal(wasmKeeper WasmKeeper) simtypes.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
simAccount, _ := simtypes.RandomAcc(r, accs)

wasmBz := testdata.ReflectContractWasm()

permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission.With(simAccount.Address)

return types.NewStoreCodeProposal(
simtypes.RandStringOfLength(r, 10),
simtypes.RandStringOfLength(r, 10),
simAccount.Address.String(),
wasmBz,
&permission,
false,
)
}
}

// Simulate instantiate contract proposal
func SimulateInstantiateContractProposal(bk BankKeeper, wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
simAccount, _ := simtypes.RandomAcc(r, accs)
// admin
adminAccount, _ := simtypes.RandomAcc(r, accs)
// get codeID
codeID := codeSelector(ctx, wasmKeeper)
if codeID == 0 {
return nil
}

return types.NewInstantiateContractProposal(
simtypes.RandStringOfLength(r, 10),
simtypes.RandStringOfLength(r, 10),
simAccount.Address.String(),
adminAccount.Address.String(),
codeID,
simtypes.RandStringOfLength(r, 10),
[]byte(`{}`),
sdk.Coins{},
)
}
}

// Simulate execute contract proposal
func SimulateExecuteContractProposal(
bk BankKeeper,
wasmKeeper WasmKeeper,
contractSelector MsgExecuteContractSelector,
senderSelector MsgExecuteSenderSelector,
payloader MsgExecutePayloader,
) simtypes.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
ctAddress := contractSelector(ctx, wasmKeeper)
if ctAddress == nil {
return nil
}

simAccount, err := senderSelector(wasmKeeper, ctx, ctAddress, accs)
if err != nil {
return nil
}

msg := types.MsgExecuteContract{
Sender: simAccount.Address.String(),
Contract: ctAddress.String(),
Funds: sdk.Coins{},
}

if err := payloader(&msg); err != nil {
return nil
}

return types.NewExecuteContractProposal(
simtypes.RandStringOfLength(r, 10),
simtypes.RandStringOfLength(r, 10),
simAccount.Address.String(),
ctAddress.String(),
msg.Msg,
sdk.Coins{},
)
}
}

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

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

// Simulate update admin contract proposal
func SimulateUpdateAdminProposal(wasmKeeper WasmKeeper, contractSelector UpdateAdminContractSelector) simtypes.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
simAccount, _ := simtypes.RandomAcc(r, accs)
ctAddress, _ := contractSelector(ctx, wasmKeeper, simAccount.Address.String())
if ctAddress == nil {
return nil
}

return types.NewUpdateAdminProposal(
simtypes.RandStringOfLength(r, 10),
simtypes.RandStringOfLength(r, 10),
simtypes.RandomAccounts(r, 1)[0].Address.String(),
ctAddress.String(),
)
}
}

type ClearAdminContractSelector func(sdk.Context, WasmKeeper) sdk.AccAddress

func DefaultSimulateClearAdminProposalContractSelector(
ctx sdk.Context,
wasmKeeper WasmKeeper,
) sdk.AccAddress {
var contractAddr sdk.AccAddress
wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool {
contractAddr = address
return true
})
return contractAddr
}

// Simulate clear admin proposal
func SimulateClearAdminProposal(wasmKeeper WasmKeeper, contractSelector ClearAdminContractSelector) simtypes.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
ctAddress := contractSelector(ctx, wasmKeeper)
if ctAddress == nil {
return nil
}

return types.NewClearAdminProposal(
simtypes.RandStringOfLength(r, 10),
simtypes.RandStringOfLength(r, 10),
ctAddress.String(),
)
}
}
52 changes: 52 additions & 0 deletions x/wasm/types/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ func init() { // register new content types with the sdk
govtypes.RegisterProposalTypeCodec(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal")
}

func NewStoreCodeProposal(
title string,
description string,
runAs string,
wasmBz []byte,
permission *AccessConfig,
unpinCode bool,
) *StoreCodeProposal {
return &StoreCodeProposal{title, description, runAs, wasmBz, permission, unpinCode}
}

// ProposalRoute returns the routing key of a parameter change proposal.
func (p StoreCodeProposal) ProposalRoute() string { return RouterKey }

Expand Down Expand Up @@ -143,6 +154,19 @@ func (p StoreCodeProposal) MarshalYAML() (interface{}, error) {
}, nil
}

func NewInstantiateContractProposal(
title string,
description string,
runAs string,
admin string,
codeID uint64,
label string,
msg RawContractMessage,
funds sdk.Coins,
) *InstantiateContractProposal {
return &InstantiateContractProposal{title, description, runAs, admin, codeID, label, msg, funds}
}

// ProposalRoute returns the routing key of a parameter change proposal.
func (p InstantiateContractProposal) ProposalRoute() string { return RouterKey }

Expand Down Expand Up @@ -334,6 +358,17 @@ func (p SudoContractProposal) MarshalYAML() (interface{}, error) {
}, nil
}

func NewExecuteContractProposal(
title string,
description string,
runAs string,
contract string,
msg RawContractMessage,
funds sdk.Coins,
) *ExecuteContractProposal {
return &ExecuteContractProposal{title, description, runAs, contract, msg, funds}
}

// ProposalRoute returns the routing key of a parameter change proposal.
func (p ExecuteContractProposal) ProposalRoute() string { return RouterKey }

Expand Down Expand Up @@ -397,6 +432,15 @@ func (p ExecuteContractProposal) MarshalYAML() (interface{}, error) {
}, nil
}

func NewUpdateAdminProposal(
title string,
description string,
newAdmin string,
contract string,
) *UpdateAdminProposal {
return &UpdateAdminProposal{title, description, newAdmin, contract}
}

// ProposalRoute returns the routing key of a parameter change proposal.
func (p UpdateAdminProposal) ProposalRoute() string { return RouterKey }

Expand Down Expand Up @@ -433,6 +477,14 @@ func (p UpdateAdminProposal) String() string {
`, p.Title, p.Description, p.Contract, p.NewAdmin)
}

func NewClearAdminProposal(
title string,
description string,
contract string,
) *ClearAdminProposal {
return &ClearAdminProposal{title, description, contract}
}

// ProposalRoute returns the routing key of a parameter change proposal.
func (p ClearAdminProposal) ProposalRoute() string { return RouterKey }

Expand Down

0 comments on commit e22b9df

Please sign in to comment.