Skip to content

Commit

Permalink
fix: add simulation tests for new param change (#14728)
Browse files Browse the repository at this point in the history
(cherry picked from commit d3c3194)

# Conflicts:
#	CHANGELOG.md
#	types/module/simulation.go
#	x/auth/simulation/params.go
#	x/bank/simulation/params.go
#	x/distribution/simulation/params.go
#	x/gov/simulation/operations.go
#	x/gov/simulation/operations_test.go
#	x/gov/simulation/params.go
#	x/mint/simulation/params.go
#	x/slashing/simulation/params.go
#	x/staking/simulation/params.go
  • Loading branch information
julienrbrt authored and mergify[bot] committed Jan 27, 2023
1 parent 33986a3 commit 94b4db9
Show file tree
Hide file tree
Showing 54 changed files with 979 additions and 426 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking Changes

<<<<<<< HEAD
=======
* (simulation) [#14728](https://github.com/cosmos/cosmos-sdk/pull/14728) Rename the `ParamChanges` field to `LegacyParamChange` and `Contents` to `LegacyProposalContents` in `simulation.SimulationState`. Additionally it adds a `ProposalMsgs` field to `simulation.SimulationState`.
* (x/upgrade) [14764](https://github.com/cosmos/cosmos-sdk/pull/14764) The `x/upgrade` module is extracted to have a separate go.mod file which allows it to be a standalone module.
* (x/gov) [#14782](https://github.com/cosmos/cosmos-sdk/pull/14782) Move the `metadata` argument in `govv1.NewProposal` alongside `title` and `summary`.
* (store) [#14746](https://github.com/cosmos/cosmos-sdk/pull/14746) Extract Store in its own go.mod and rename the package to `cosmossdk.io/store`.
* (simulation) [#14751](https://github.com/cosmos/cosmos-sdk/pull/14751) Remove the `MsgType` field from `simulation.OperationInput` struct.
* (crypto/keyring) [#13734](https://github.com/cosmos/cosmos-sdk/pull/13834) The keyring's `Sign` method now takes a new `signMode` argument. It is only used if the signing key is a Ledger hardware device. You can set it to 0 in all other cases.
* (x/evidence) [14724](https://github.com/cosmos/cosmos-sdk/pull/14724) Extract Evidence in its own go.mod and rename the package to `cosmossdk.io/x/evidence`.
* (x/nft) [#14725](https://github.com/cosmos/cosmos-sdk/pull/14725) Extract NFT in its own go.mod and rename the package to `cosmossdk.io/x/nft`.
* (tx) [#14634](https://github.com/cosmos/cosmos-sdk/pull/14634) Move the `tx` go module to `x/tx`.
* (snapshots) [#14597](https://github.com/cosmos/cosmos-sdk/pull/14597) Move `snapshots` to `store/snapshots`, rename and bump proto package to v1.
* (crypto/keyring) [#14151](https://github.com/cosmos/cosmos-sdk/pull/14151) Move keys presentation from `crypto/keyring` to `client/keys`
* (modules) [#13850](https://github.com/cosmos/cosmos-sdk/pull/13850) and [#14046](https://github.com/cosmos/cosmos-sdk/pull/14046) Remove gogoproto stringer annotations. This removes the custom `String()` methods on all types that were using the annotations.
* (x/auth) [#13850](https://github.com/cosmos/cosmos-sdk/pull/13850/) Remove `MarshalYAML` methods from module (`x/...`) types.
>>>>>>> d3c319418 (fix: add simulation tests for new param change (#14728))
* (x/auth) [#13877](https://github.com/cosmos/cosmos-sdk/pull/13877) Rename `AccountKeeper`'s `GetNextAccountNumber` to `NextAccountNumber`.
* (x/evidence) [#13740](https://github.com/cosmos/cosmos-sdk/pull/13740) The `NewQueryEvidenceRequest` function now takes `hash` as a HEX encoded `string`.
* (server) [#13485](https://github.com/cosmos/cosmos-sdk/pull/13485) The `Application` service now requires the `RegisterNodeService` method to be implemented.
Expand Down
4 changes: 4 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ This guide provides instructions for upgrading to specific versions of Cosmos SD

Remove `RandomizedParams` from `AppModuleSimulation` interface. Previously, it used to generate random parameter changes during simulations, however, it does so through ParamChangeProposal which is now legacy. Since all modules were migrated, we can now safely remove this from `AppModuleSimulation` interface.

Moreover, to support the `MsgUpdateParams` governance proposals for each modules, `AppModuleSimulation` now defines a `AppModule.ProposalMsgs` method in addition to `AppModule.ProposalContents`. That method defines the messages that can be used to submit a proposal and that should be tested in simulation.

When a module has no proposal messages or proposal content to be tested by simulation, the `AppModule.ProposalMsgs` and `AppModule.ProposalContents` methods can be deleted.

### gRPC

A new gRPC service, `proto/cosmos/base/node/v1beta1/query.proto`, has been introduced
Expand Down
3 changes: 2 additions & 1 deletion testutil/sims/simulation_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ func SimulationOperations(app runtime.AppI, cdc codec.JSONCodec, config simtypes
}
}

simState.Contents = app.SimulationManager().GetProposalContents(simState)
simState.LegacyProposalContents = app.SimulationManager().GetProposalContents(simState) //nolint:staticcheck
simState.ProposalMsgs = app.SimulationManager().GetProposalMsgs(simState)
return app.SimulationManager().WeightedOperations(simState)
}

Expand Down
50 changes: 46 additions & 4 deletions types/module/simulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,25 @@ type AppModuleSimulation interface {
// randomized genesis states
GenerateGenesisState(input *SimulationState)

// content functions used to simulate governance proposals
ProposalContents(simState SimulationState) []simulation.WeightedProposalContent

// register a func to decode the each module's defined types from their corresponding store key
RegisterStoreDecoder(sdk.StoreDecoderRegistry)

// simulation operations (i.e msgs) with their respective weight
WeightedOperations(simState SimulationState) []simulation.WeightedOperation
}

// HasProposalMsgs defines the messages that can be used to simulate governance (v1) proposals
type HasProposalMsgs interface {
// msg functions used to simulate governance proposals
ProposalMsgs(simState SimulationState) []simulation.WeightedProposalMsg
}

// HasProposalContents defines the contents that can be used to simulate legacy governance (v1beta1) proposals
type HasProposalContents interface {
// content functions used to simulate governance proposals
ProposalContents(simState SimulationState) []simulation.WeightedProposalContent //nolint:staticcheck
}

// SimulationManager defines a simulation manager that provides the high level utility
// for managing and executing simulation functionalities for a group of modules
type SimulationManager struct {
Expand Down Expand Up @@ -78,12 +87,28 @@ func NewSimulationManagerFromAppModules(modules map[string]interface{}, override
return NewSimulationManager(simModules...)
}

// Deprecated: Use GetProposalMsgs instead.
// GetProposalContents returns each module's proposal content generator function
// with their default operation weight and key.
func (sm *SimulationManager) GetProposalContents(simState SimulationState) []simulation.WeightedProposalContent {
wContents := make([]simulation.WeightedProposalContent, 0, len(sm.Modules))
for _, module := range sm.Modules {
wContents = append(wContents, module.ProposalContents(simState)...)
if module, ok := module.(HasProposalContents); ok {
wContents = append(wContents, module.ProposalContents(simState)...)
}
}

return wContents
}

// GetProposalMsgs returns each module's proposal msg generator function
// with their default operation weight and key.
func (sm *SimulationManager) GetProposalMsgs(simState SimulationState) []simulation.WeightedProposalMsg {
wContents := make([]simulation.WeightedProposalMsg, 0, len(sm.Modules))
for _, module := range sm.Modules {
if module, ok := module.(HasProposalMsgs); ok {
wContents = append(wContents, module.ProposalMsgs(simState)...)
}
}

return wContents
Expand Down Expand Up @@ -117,6 +142,7 @@ func (sm *SimulationManager) WeightedOperations(simState SimulationState) []simu
// SimulationState is the input parameters used on each of the module's randomized
// GenesisState generator function
type SimulationState struct {
<<<<<<< HEAD
AppParams simulation.AppParams
Cdc codec.JSONCodec // application codec
Rand *rand.Rand // random number
Expand All @@ -128,4 +154,20 @@ type SimulationState struct {
UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration
ParamChanges []simulation.ParamChange // simulated parameter changes from modules
Contents []simulation.WeightedProposalContent // proposal content generator functions with their default weight and app sim key
=======
AppParams simulation.AppParams
Cdc codec.JSONCodec // application codec
Rand *rand.Rand // random number
GenState map[string]json.RawMessage // genesis state
Accounts []simulation.Account // simulation accounts
InitialStake sdkmath.Int // initial coins per account
NumBonded int64 // number of initially bonded accounts
BondDenom string // denom to be used as default
GenTimestamp time.Time // genesis timestamp
UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration
LegacyParamChange []simulation.LegacyParamChange // simulated parameter changes from modules
//nolint:staticcheck
LegacyProposalContents []simulation.WeightedProposalContent // proposal content generator functions with their default weight and app sim key
ProposalMsgs []simulation.WeightedProposalMsg // proposal msg generator functions with their default weight and app sim key
>>>>>>> d3c319418 (fix: add simulation tests for new param change (#14728))
}
13 changes: 12 additions & 1 deletion types/simulation/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
)

// Deprecated: Use WeightedProposalMsg instead.
type WeightedProposalContent interface {
AppParamsKey() string // key used to retrieve the value of the weight from the simulation application params
DefaultWeight() int // default weight
ContentSimulatorFn() ContentSimulatorFn // content simulator function
}

// Deprecated: Use MsgSimulatorFn instead.
type ContentSimulatorFn func(r *rand.Rand, ctx sdk.Context, accs []Account) Content

// Deprecated: Use MsgSimulatorFn instead.
type Content interface {
GetTitle() string
GetDescription() string
Expand All @@ -28,9 +31,17 @@ type Content interface {
String() string
}

type WeightedProposalMsg interface {
AppParamsKey() string // key used to retrieve the value of the weight from the simulation application params
DefaultWeight() int // default weight
MsgSimulatorFn() MsgSimulatorFn // msg simulator function
}

type MsgSimulatorFn func(r *rand.Rand, ctx sdk.Context, accs []Account) sdk.Msg

type SimValFn func(r *rand.Rand) string

type ParamChange interface {
type LegacyParamChange interface {
Subspace() string
Key() string
SimValue() SimValFn
Expand Down
6 changes: 3 additions & 3 deletions x/auth/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ func (am AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState, am.randGenAccountsFn)
}

// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return nil
// ProposalMsgs returns msgs used for governance proposals for simulations.
func (AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
return simulation.ProposalMsgs()
}

// RegisterStoreDecoder registers a decoder for auth module's types
Expand Down
37 changes: 0 additions & 37 deletions x/auth/simulation/params_test.go

This file was deleted.

47 changes: 47 additions & 0 deletions x/auth/simulation/proposals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package simulation

import (
"math/rand"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)

// Simulation operation weights constants
const (
DefaultWeightMsgUpdateParams int = 100

OpWeightMsgUpdateParams = "op_weight_msg_update_params" //nolint:gosec
)

// ProposalMsgs defines the module weighted proposals' contents
func ProposalMsgs() []simtypes.WeightedProposalMsg {
return []simtypes.WeightedProposalMsg{
simulation.NewWeightedProposalMsg(
OpWeightMsgUpdateParams,
DefaultWeightMsgUpdateParams,
SimulateMsgUpdateParams,
),
}
}

// SimulateMsgUpdateParams returns a random MsgUpdateParams
func SimulateMsgUpdateParams(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg {
// use the default gov module account address as authority
var authority sdk.AccAddress = address.Module("gov")

params := types.DefaultParams()
params.MaxMemoCharacters = uint64(simtypes.RandIntBetween(r, 1, 1000))
params.TxSigLimit = uint64(simtypes.RandIntBetween(r, 1, 1000))
params.TxSizeCostPerByte = uint64(simtypes.RandIntBetween(r, 1, 1000))
params.SigVerifyCostED25519 = uint64(simtypes.RandIntBetween(r, 1, 1000))
params.SigVerifyCostSecp256k1 = uint64(simtypes.RandIntBetween(r, 1, 1000))

return &types.MsgUpdateParams{
Authority: authority.String(),
Params: params,
}
}
45 changes: 45 additions & 0 deletions x/auth/simulation/proposals_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package simulation_test

import (
"math/rand"
"testing"

tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"gotest.tools/v3/assert"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/auth/simulation"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)

func TestProposalMsgs(t *testing.T) {
// initialize parameters
s := rand.NewSource(1)
r := rand.New(s)

ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil)
accounts := simtypes.RandomAccounts(r, 3)

// execute ProposalMsgs function
weightedProposalMsgs := simulation.ProposalMsgs()
assert.Assert(t, len(weightedProposalMsgs) == 1)

w0 := weightedProposalMsgs[0]

// tests w0 interface:
assert.Equal(t, simulation.OpWeightMsgUpdateParams, w0.AppParamsKey())
assert.Equal(t, simulation.DefaultWeightMsgUpdateParams, w0.DefaultWeight())

msg := w0.MsgSimulatorFn()(r, ctx, accounts)
msgUpdateParams, ok := msg.(*types.MsgUpdateParams)
assert.Assert(t, ok)

assert.Equal(t, sdk.AccAddress(address.Module("gov")).String(), msgUpdateParams.Authority)
assert.Equal(t, uint64(999), msgUpdateParams.Params.MaxMemoCharacters)
assert.Equal(t, uint64(905), msgUpdateParams.Params.TxSigLimit)
assert.Equal(t, uint64(151), msgUpdateParams.Params.TxSizeCostPerByte)
assert.Equal(t, uint64(213), msgUpdateParams.Params.SigVerifyCostED25519)
assert.Equal(t, uint64(539), msgUpdateParams.Params.SigVerifyCostSecp256k1)
}
6 changes: 0 additions & 6 deletions x/authz/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}

// ProposalContents returns all the authz content functions used to
// simulate governance proposals.
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
return nil
}

// RegisterStoreDecoder registers a decoder for authz module's types
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[keeper.StoreKey] = simulation.NewDecodeStore(am.cdc)
Expand Down
2 changes: 1 addition & 1 deletion x/authz/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package authz
import (
"time"

"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec"

"github.com/cosmos/gogoproto/proto"

cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
)

var (
Expand Down
8 changes: 3 additions & 5 deletions x/authz/simulation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ var (
)

// Simulation operation weights constants
//
//nolint:gosec // these are not hardcoded credentials.
const (
OpWeightMsgGrant = "op_weight_msg_grant"
OpWeightRevoke = "op_weight_msg_revoke"
OpWeightExec = "op_weight_msg_execute"
OpWeightMsgGrant = "op_weight_msg_grant" //nolint:gosec
OpWeightRevoke = "op_weight_msg_revoke" //nolint:gosec
OpWeightExec = "op_weight_msg_execute" //nolint:gosec
)

// authz operations weights
Expand Down
6 changes: 3 additions & 3 deletions x/bank/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}

// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent {
return nil
// ProposalMsgs returns msgs used for governance proposals for simulations.
func (AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
return simulation.ProposalMsgs()
}

// RegisterStoreDecoder registers a decoder for supply module's types
Expand Down
10 changes: 4 additions & 6 deletions x/bank/simulation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ import (
)

// Simulation operation weights constants
//
//nolint:gosec // these are not hardcoded credentials.
const (
OpWeightMsgSend = "op_weight_msg_send"
OpWeightMsgMultiSend = "op_weight_msg_multisend"
DefaultWeightMsgSend = 100 // from simappparams.DefaultWeightMsgSend
DefaultWeightMsgMultiSend = 10 // from simappparams.DefaultWeightMsgMultiSend
OpWeightMsgSend = "op_weight_msg_send" //nolint:gosec
OpWeightMsgMultiSend = "op_weight_msg_multisend" //nolint:gosec
DefaultWeightMsgSend = 100 // from simappparams.DefaultWeightMsgSend
DefaultWeightMsgMultiSend = 10 // from simappparams.DefaultWeightMsgMultiSend
)

// WeightedOperations returns all the operations from the module with their respective weights
Expand Down
Loading

0 comments on commit 94b4db9

Please sign in to comment.