Sim refactor 3: move weighted operations to modules (#4869)

* move GenesisState generators to modules

* minor change on slashing genState generator

* move simulation params back to modules (#4839)

move simulation params back to modules (#4839)

* cleanup params

* various fixes

* move store decoders to modules

* fix

* module pattern

* split generators for param change

* param changes

* revert util pkg

* banksim

* compile

* update Decoders params

* fix

* address @colin-axner comments

* move weighted operations to modules

* cleanup

* cleanup

* Update cmd_test.go

* simulation manager

* mino fixes

* cleanup

* add GenerateGenesisState to simulation manager

* Apply suggestions from code review

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* address @rigelrozanski comments

* changelog

* Apply suggestions from code review

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* restructure modules simulation pkgs

* remove cycle deps

* rename funcs and add missing params

* modularize simulator param changes

* build

* fix params keys

* make format

* various fixes

* fix tests

* minor updates to sim_test

* cleanup

* more cleanup

* modularize genesis generators

* minor cleanup

* remove cdc from generators

* remove cdc

* add get or generate

* fix non-determinism in simulation

* changelog and x/simulation godoc

* cleanup operations

* update operations to use baseapp

* updates and cleanup operations

* update operations

* restructure sim ops params

* rename sim /operations/msg.go to /operations.go

* move GenTx to a helper pkg to avoid circle deps

* rm msg.ValidateBasic

* changelog

* random fees; delete auth's DeductFees sim operation

* add chain-id for sig verification

* Update x/simulation/account.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* fix bank, gov and distr errors

* fix staking and slashing errors; increase prob for send enabled

* increase gas x10

* make format

* fix some distr and staking edge cases

* fix all edge cases

* golang ci

* rename acc vars; default no fees to 0stake

* cleanup; check for exchange rate and skip invalid ops

* fixes

* check for max entries

* add pubkey to genaccounts

* fix gov bug

* update staking sim ops

* fix small redelegation error

* fix small self delegation on unjail

* rm inf loop on random val/accs

* copy array

* add ok boolean to RandomValidator return values

* format

* build

* add WeightedOperations to AppModuleSimulation

* define each module proposals content as part of the module pattern

* Update x/bank/simulation/operations.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Update simapp/helpers/test_helpers.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* address @colin-axner comments

* add genaccount pubkey validation

* fix test

* update operations and move RandomFees to x/simulation

* update gov ops

* address @alexanderbez comments

* avoid modifications to config

* reorder params

* modularized sim operations working

* changelog

* Update types/module/simulation.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* Update x/simulation/params.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* Update x/simulation/params.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* update /types/module

* Update x/distribution/simulation/genesis.go

Co-Authored-By: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>

* remove named return values

* ensure all operations are simulated

* golangci

* add nolint

* disable whitespace and funlen linter

* disable godox

* add TODO on unjail

* update ops weights

* remove dup

* update godoc

* remove unused func

* build fixes

* move weights to the same file

* scopelint

* changelog

* address @AdityaSripal comments

* address @alexanderbez comments
This commit is contained in:
Federico Kunze 2019-12-05 10:29:54 +01:00 committed by GitHub
parent 12ff486a57
commit 722a633f54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 880 additions and 519 deletions

View File

@ -172,12 +172,15 @@ generalized genesis accounts through the `GenesisAccount` interface.
* (simulation) [\#4824](https://github.com/cosmos/cosmos-sdk/issues/4824) PrintAllInvariants flag will print all failed invariants
* (simulation) [\#4490](https://github.com/cosmos/cosmos-sdk/issues/4490) add `InitialBlockHeight` flag to resume a simulation from a given block
* Support exporting the simulation stats to a given JSON file
* (simulation) [\#4847](https://github.com/cosmos/cosmos-sdk/issues/4847), [\#4838](https://github.com/cosmos/cosmos-sdk/pull/4838) `SimApp` and simulation refactors
* (simulation) [\#4847](https://github.com/cosmos/cosmos-sdk/issues/4847), [\#4838](https://github.com/cosmos/cosmos-sdk/pull/4838) and [\#4869](https://github.com/cosmos/cosmos-sdk/pull/4869) `SimApp` and simulation refactors:
* Implement `SimulationManager` for executing modules' simulation functionalities in a modularized way
* Add `RegisterStoreDecoders` to the `SimulationManager` for decoding each module's types
* Add `GenerateGenesisStates` to the `SimulationManager` to generate a randomized `GenState` for each module
* Add `RandomizedParams` to the `SimulationManager` that registers each modules' parameters `Content` to simulate
`ParamChangeProposal`s
* Add `RandomizedParams` to the `SimulationManager` that registers each modules' parameters in order to
simulate `ParamChangeProposal`s' `Content`s
* Add `WeightedOperations` to the `SimulationManager` that define simulation operations (modules' `Msg`s) with their
respective weights (i.e chance of being simulated).
* Add `ProposalContents` to the `SimulationManager` to register each module's governance proposal `Content`s.
* (simulation) [\#4893](https://github.com/cosmos/cosmos-sdk/issues/4893) Change SimApp keepers to be public and add getter functions for keys and codec
* (simulation) [\#4906](https://github.com/cosmos/cosmos-sdk/issues/4906) Add simulation `Config` struct that wraps simulation flags
* (simulation) [\#4935](https://github.com/cosmos/cosmos-sdk/issues/4935) Update simulation to reflect a proper `ABCI` application without bypassing `BaseApp` semantics

View File

@ -226,10 +226,10 @@ func NewSimApp(
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
crisis.NewAppModule(&app.CrisisKeeper),
supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
gov.NewAppModule(app.GovKeeper, app.AccountKeeper, app.SupplyKeeper),
mint.NewAppModule(app.MintKeeper),
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper),
slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
distr.NewAppModule(app.DistrKeeper, app.AccountKeeper, app.SupplyKeeper, app.StakingKeeper),
staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
@ -260,11 +260,12 @@ func NewSimApp(
auth.NewAppModule(app.AccountKeeper),
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
gov.NewAppModule(app.GovKeeper, app.AccountKeeper, app.SupplyKeeper),
mint.NewAppModule(app.MintKeeper),
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper),
distr.NewAppModule(app.DistrKeeper, app.AccountKeeper, app.SupplyKeeper, app.StakingKeeper),
slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
params.NewAppModule(), // NOTE: only used for simulation to generate randomized param change proposals
)
app.sm.RegisterStoreDecoders()

View File

@ -2,23 +2,6 @@ package simapp
// Simulation parameter constants
const (
StakePerAccount = "stake_per_account"
InitiallyBondedValidators = "initially_bonded_validators"
OpWeightDeductFee = "op_weight_deduct_fee"
OpWeightMsgSend = "op_weight_msg_send"
OpWeightMsgMultiSend = "op_weight_msg_multisend"
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address"
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward"
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission"
OpWeightSubmitTextProposal = "op_weight_submit_text_proposal"
OpWeightSubmitCommunitySpendProposal = "op_weight_submit_community_spend_proposal"
OpWeightSubmitParamChangeProposal = "op_weight_submit_param_change_proposal"
OpWeightMsgDeposit = "op_weight_msg_deposit"
OpWeightMsgVote = "op_weight_msg_vote"
OpWeightMsgCreateValidator = "op_weight_msg_create_validator"
OpWeightMsgEditValidator = "op_weight_msg_edit_validator"
OpWeightMsgDelegate = "op_weight_msg_delegate"
OpWeightMsgUndelegate = "op_weight_msg_undelegate"
OpWeightMsgBeginRedelegate = "op_weight_msg_begin_redelegate"
OpWeightMsgUnjail = "op_weight_msg_unjail"
StakePerAccount = "stake_per_account"
InitiallyBondedValidators = "initially_bonded_validators"
)

19
simapp/params/doc.go Normal file
View File

@ -0,0 +1,19 @@
/*
Package params defines the simulation parameters in the simapp.
It contains the default weights used for each transaction used on the module's
simulation. These weights define the chance for a transaction to be simulated at
any gived operation.
You can repace the default values for the weights by providing a params.json
file with the weights defined for each of the transaction operations:
{
"op_weight_msg_send": 60,
"op_weight_msg_delegate": 100,
}
In the example above, the `MsgSend` has 60% chance to be simulated, while the
`MsgDelegate` will always be simulated.
*/
package params

22
simapp/params/weights.go Normal file
View File

@ -0,0 +1,22 @@
package params
// Default simulation operation weights for messages and gov proposals
const (
DefaultWeightMsgSend int = 100
DefaultWeightMsgMultiSend int = 10
DefaultWeightMsgSetWithdrawAddress int = 50
DefaultWeightMsgWithdrawDelegationReward int = 50
DefaultWeightMsgWithdrawValidatorCommission int = 50
DefaultWeightMsgDeposit int = 100
DefaultWeightMsgVote int = 67
DefaultWeightMsgUnjail int = 100
DefaultWeightMsgCreateValidator int = 100
DefaultWeightMsgEditValidator int = 5
DefaultWeightMsgDelegate int = 100
DefaultWeightMsgUndelegate int = 100
DefaultWeightMsgBeginRedelegate int = 100
DefaultWeightCommunitySpendProposal int = 5
DefaultWeightTextProposal int = 5
DefaultWeightParamChangeProposal int = 5
)

View File

@ -36,7 +36,8 @@ func BenchmarkFullAppSimulation(b *testing.B) {
// TODO: parameterize numbers, save for a later PR
_, simParams, simErr := simulation.SimulateFromSeed(
b, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
// export state and params before the simulation error is checked
@ -86,7 +87,8 @@ func BenchmarkInvariants(b *testing.B) {
// 2. Run parameterized simulation (w/o invariants)
_, simParams, simErr := simulation.SimulateFromSeed(
b, ioutil.Discard, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
// export state and params before the simulation error is checked

View File

@ -18,19 +18,13 @@ import (
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation"
"github.com/cosmos/cosmos-sdk/x/gov"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/params"
paramsim "github.com/cosmos/cosmos-sdk/x/params/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingsim "github.com/cosmos/cosmos-sdk/x/staking/simulation"
"github.com/cosmos/cosmos-sdk/x/supply"
)
@ -39,201 +33,6 @@ func init() {
GetSimulatorFlags()
}
func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedOperation {
ap := make(simulation.AppParams)
paramChanges := app.sm.GenerateParamChanges(config.Seed)
if config.ParamsFile != "" {
bz, err := ioutil.ReadFile(config.ParamsFile)
if err != nil {
panic(err)
}
app.cdc.MustUnmarshalJSON(bz, &ap)
}
// nolint: govet
return []simulation.WeightedOperation{
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgSend, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
banksim.SimulateMsgSend(app.AccountKeeper, app.BankKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgMultiSend, &v, nil,
func(_ *rand.Rand) {
v = 40
})
return v
}(nil),
banksim.SimulateMsgMultiSend(app.AccountKeeper, app.BankKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgSetWithdrawAddress, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgSetWithdrawAddress(app.AccountKeeper, app.DistrKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgWithdrawDelegationReward, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgWithdrawDelegatorReward(app.AccountKeeper, app.DistrKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgWithdrawValidatorCommission, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgWithdrawValidatorCommission(app.AccountKeeper, app.DistrKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightSubmitTextProposal, &v, nil,
func(_ *rand.Rand) {
v = 20
})
return v
}(nil),
govsim.SimulateSubmitProposal(app.AccountKeeper, app.GovKeeper, govsim.SimulateTextProposalContent),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightSubmitCommunitySpendProposal, &v, nil,
func(_ *rand.Rand) {
v = 20
})
return v
}(nil),
govsim.SimulateSubmitProposal(app.AccountKeeper, app.GovKeeper, distrsim.SimulateCommunityPoolSpendProposalContent(app.DistrKeeper)),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightSubmitParamChangeProposal, &v, nil,
func(_ *rand.Rand) {
v = 20
})
return v
}(nil),
govsim.SimulateSubmitProposal(app.AccountKeeper, app.GovKeeper, paramsim.SimulateParamChangeProposalContent(paramChanges)),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgDeposit, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
govsim.SimulateMsgDeposit(app.AccountKeeper, app.GovKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgVote, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
govsim.SimulateMsgVote(app.AccountKeeper, app.GovKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgCreateValidator, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgCreateValidator(app.AccountKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgEditValidator, &v, nil,
func(_ *rand.Rand) {
v = 20
})
return v
}(nil),
stakingsim.SimulateMsgEditValidator(app.AccountKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgDelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgDelegate(app.AccountKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgUndelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgUndelegate(app.AccountKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgBeginRedelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgBeginRedelegate(app.AccountKeeper, app.StakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(app.cdc, OpWeightMsgUnjail, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
slashingsim.SimulateMsgUnjail(app.AccountKeeper, app.SlashingKeeper, app.StakingKeeper),
},
}
}
// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of
// an IAVLStore for faster simulation speed.
func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
@ -276,7 +75,8 @@ func TestFullAppSimulation(t *testing.T) {
// Run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
// export state and params before the simulation error is checked
@ -331,7 +131,8 @@ func TestAppImportExport(t *testing.T) {
// Run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
// export state and simParams before the simulation error is checked
@ -417,7 +218,6 @@ func TestAppImportExport(t *testing.T) {
fmt.Printf("compared %d key/value pairs between %s and %s\n", len(failedKVAs), storeKeyA, storeKeyB)
require.Equal(t, len(failedKVAs), 0, GetSimulationLog(storeKeyA.Name(), app.sm.StoreDecoders, app.cdc, failedKVAs, failedKVBs))
}
}
func TestAppSimulationAfterImport(t *testing.T) {
@ -449,7 +249,8 @@ func TestAppSimulationAfterImport(t *testing.T) {
// Run randomized simulation
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
// export state and params before the simulation error is checked
@ -504,7 +305,8 @@ func TestAppSimulationAfterImport(t *testing.T) {
// Run randomized simulation on imported app
_, _, err = simulation.SimulateFromSeed(
t, os.Stdout, newApp.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(newApp, config), newApp.ModuleAccountAddrs(), config,
SimulationOperations(newApp, newApp.Codec(), config),
newApp.ModuleAccountAddrs(), config,
)
require.NoError(t, err)
@ -550,7 +352,8 @@ func TestAppStateDeterminism(t *testing.T) {
_, _, err := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
testAndRunTxs(app, config), app.ModuleAccountAddrs(), config,
SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)
require.NoError(t, err)

View File

@ -30,6 +30,7 @@ func AppStateFn(cdc *codec.Codec, simManager *module.SimulationManager) simulati
genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0)
}
chainID = config.ChainID
switch {
case config.ParamsFile != "" && config.GenesisFile != "":
panic("cannot provide both a genesis file and a params file")

View File

@ -10,6 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
@ -84,6 +85,28 @@ func NewConfigFromFlags() simulation.Config {
}
}
// SimulationOperations retrieves the simulation params from the provided file path
// and returns all the modules weighted operations
func SimulationOperations(app *SimApp, cdc *codec.Codec, config simulation.Config) []simulation.WeightedOperation {
simState := module.SimulationState{
AppParams: make(simulation.AppParams),
Cdc: cdc,
}
if config.ParamsFile != "" {
bz, err := ioutil.ReadFile(config.ParamsFile)
if err != nil {
panic(err)
}
app.cdc.MustUnmarshalJSON(bz, &simState.AppParams)
}
simState.ParamChanges = app.sm.GenerateParamChanges(config.Seed)
simState.Contents = app.sm.GetProposalContents(simState)
return app.sm.WeightedOperations(simState)
}
//---------------------------------------------------------------------
// Simulation Utils

View File

@ -2,6 +2,7 @@ package module
import (
"encoding/json"
"math/rand"
"time"
@ -13,14 +14,20 @@ import (
// AppModuleSimulation defines the standard functions that every module should expose
// for the SDK blockchain simulator
type AppModuleSimulation interface {
// register a func to decode the each module's defined types from their corresponding store key
RegisterStoreDecoder(sdk.StoreDecoderRegistry)
// randomized genesis states
GenerateGenesisState(input *SimulationState)
// content functions used to simulate governance proposals
ProposalContents(simState SimulationState) []simulation.WeightedProposalContent
// randomized module parameters for param change proposals
RandomizedParams(r *rand.Rand) []simulation.ParamChange
// 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
}
// SimulationManager defines a simulation manager that provides the high level utility
@ -40,6 +47,17 @@ func NewSimulationManager(modules ...AppModuleSimulation) *SimulationManager {
}
}
// GetProposalContents returns each module's proposal content generator function
// with their default operation weight and key.
func (sm *SimulationManager) GetProposalContents(simState SimulationState) []simulation.WeightedProposalContent {
var wContents []simulation.WeightedProposalContent
for _, module := range sm.Modules {
wContents = append(wContents, module.ProposalContents(simState)...)
}
return wContents
}
// RegisterStoreDecoders registers each of the modules' store decoders into a map
func (sm *SimulationManager) RegisterStoreDecoders() {
for _, module := range sm.Modules {
@ -49,9 +67,9 @@ func (sm *SimulationManager) RegisterStoreDecoders() {
// GenerateGenesisStates generates a randomized GenesisState for each of the
// registered modules
func (sm *SimulationManager) GenerateGenesisStates(input *SimulationState) {
func (sm *SimulationManager) GenerateGenesisStates(simState *SimulationState) {
for _, module := range sm.Modules {
module.GenerateGenesisState(input)
module.GenerateGenesisState(simState)
}
}
@ -67,16 +85,28 @@ func (sm *SimulationManager) GenerateParamChanges(seed int64) (paramChanges []si
return
}
// WeightedOperations returns all the modules' weighted operations of an application
func (sm *SimulationManager) WeightedOperations(simState SimulationState) []simulation.WeightedOperation {
var wOps []simulation.WeightedOperation
for _, module := range sm.Modules {
wOps = append(wOps, module.WeightedOperations(simState)...)
}
return wOps
}
// SimulationState is the input parameters used on each of the module's randomized
// GenesisState generator function
type SimulationState struct {
AppParams simulation.AppParams
Cdc *codec.Codec // application codec
Rand *rand.Rand // random number
GenState map[string]json.RawMessage // genesis state
Accounts []simulation.Account // simulation accounts
InitialStake int64 // initial coins per account
NumBonded int64 // number of initially bonded acconts
GenTimestamp time.Time // genesis timestamp
UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration
Cdc *codec.Codec // application codec
Rand *rand.Rand // random number
GenState map[string]json.RawMessage // genesis state
Accounts []simulation.Account // simulation accounts
InitialStake int64 // initial coins per account
NumBonded int64 // number of initially bonded accounts
GenTimestamp time.Time // genesis timestamp
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
}

View File

@ -22,7 +22,7 @@ import (
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the auth module.
@ -71,30 +71,9 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the auth module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for auth module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the auth module
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized auth param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the auth module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
accountKeeper AccountKeeper
}
@ -102,9 +81,8 @@ type AppModule struct {
// NewAppModule creates a new AppModule object
func NewAppModule(accountKeeper AccountKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
accountKeeper: accountKeeper,
AppModuleBasic: AppModuleBasic{},
accountKeeper: accountKeeper,
}
}
@ -156,3 +134,32 @@ func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the auth module
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams creates randomized auth param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for auth module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations doesn't return any auth module operation.
func (AppModule) WeightedOperations(_ module.SimulationState) []sim.WeightedOperation {
return nil
}

View File

@ -24,7 +24,7 @@ import (
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the bank module.
@ -67,28 +67,9 @@ func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the bank module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder performs a no-op.
func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
// GenerateGenesisState creates a randomized GenState of the bank module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized bank param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the bank module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
accountKeeper types.AccountKeeper
@ -97,10 +78,9 @@ type AppModule struct {
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper, accountKeeper types.AccountKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
accountKeeper: accountKeeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
}
}
@ -150,3 +130,32 @@ func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// 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.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams creates randomized bank param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder performs a no-op.
func (AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
// WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation {
return simulation.WeightedOperations(
simState.AppParams, simState.Cdc, am.accountKeeper, am.keeper,
)
}

View File

@ -7,13 +7,50 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/internal/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// Simulation operation weights constants
const (
OpWeightMsgSend = "op_weight_msg_send"
OpWeightMsgMultiSend = "op_weight_msg_multisend"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper,
bk keeper.Keeper) simulation.WeightedOperations {
var weightMsgSend, weightMsgMultiSend int
appParams.GetOrGenerate(cdc, OpWeightMsgSend, &weightMsgSend, nil,
func(_ *rand.Rand) {
weightMsgSend = simappparams.DefaultWeightMsgSend
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgMultiSend, &weightMsgMultiSend, nil,
func(_ *rand.Rand) {
weightMsgMultiSend = simappparams.DefaultWeightMsgMultiSend
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgSend,
SimulateMsgSend(ak, bk),
),
simulation.NewWeightedOperation(
weightMsgMultiSend,
SimulateMsgMultiSend(ak, bk),
),
}
}
// SimulateMsgSend tests and runs a single msg send where both
// accounts already exist.
// nolint: funlen
@ -51,12 +88,15 @@ func SimulateMsgSend(ak types.AccountKeeper, bk keeper.Keeper) simulation.Operat
func sendMsgSend(
r *rand.Rand, app *baseapp.BaseApp, ak types.AccountKeeper,
msg types.MsgSend, ctx sdk.Context, chainID string, privkeys []crypto.PrivKey,
) (err error) {
) error {
account := ak.GetAccount(ctx, msg.FromAddress)
coins := account.SpendableCoins(ctx.BlockTime())
var fees sdk.Coins
var (
fees sdk.Coins
err error
)
coins, hasNeg := coins.SafeSub(msg.Amount)
if !hasNeg {
fees, err = simulation.RandomFees(r, ctx, coins)
@ -181,7 +221,7 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simulation.O
func sendMsgMultiSend(
r *rand.Rand, app *baseapp.BaseApp, ak types.AccountKeeper,
msg types.MsgMultiSend, ctx sdk.Context, chainID string, privkeys []crypto.PrivKey,
) (err error) {
) error {
accountNumbers := make([]uint64, len(msg.Inputs))
sequenceNumbers := make([]uint64, len(msg.Inputs))
@ -196,7 +236,10 @@ func sendMsgMultiSend(
feePayer := ak.GetAccount(ctx, msg.Inputs[0].Address)
coins := feePayer.SpendableCoins(ctx.BlockTime())
var fees sdk.Coins
var (
fees sdk.Coins
err error
)
coins, hasNeg := coins.SafeSub(msg.Inputs[0].Coins)
if !hasNeg {
fees, err = simulation.RandomFees(r, ctx, coins)

View File

@ -18,12 +18,13 @@ import (
"github.com/cosmos/cosmos-sdk/x/distribution/simulation"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
sim "github.com/cosmos/cosmos-sdk/x/simulation"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the distribution module.
@ -72,42 +73,25 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the distribution module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for distribution module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the distribution module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized distribution param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the distribution module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
supplyKeeper types.SupplyKeeper
keeper Keeper
accountKeeper types.AccountKeeper
stakingKeeper stakingkeeper.Keeper
supplyKeeper types.SupplyKeeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper, supplyKeeper types.SupplyKeeper) AppModule {
func NewAppModule(keeper Keeper, accountKeeper types.AccountKeeper,
supplyKeeper types.SupplyKeeper, stakingKeeper stakingkeeper.Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
supplyKeeper: supplyKeeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
supplyKeeper: supplyKeeper,
stakingKeeper: stakingKeeper,
}
}
@ -167,3 +151,34 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the distribution module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents returns all the distribution content functions used to
// simulate governance proposals.
func (am AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return simulation.ProposalContents(am.keeper)
}
// RandomizedParams creates randomized distribution param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for distribution module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation {
return simulation.WeightedOperations(simState.AppParams, simState.Cdc,
am.accountKeeper, am.keeper, am.stakingKeeper)
}

View File

@ -6,23 +6,72 @@ import (
"math/rand"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
// Simulation operation weights constants
const (
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address"
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward"
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(
appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper,
k keeper.Keeper, sk stakingkeeper.Keeper,
) simulation.WeightedOperations {
var weightMsgSetWithdrawAddress int
appParams.GetOrGenerate(cdc, OpWeightMsgSetWithdrawAddress, &weightMsgSetWithdrawAddress, nil,
func(_ *rand.Rand) {
weightMsgSetWithdrawAddress = simappparams.DefaultWeightMsgSetWithdrawAddress
},
)
var weightMsgWithdrawDelegationReward int
appParams.GetOrGenerate(cdc, OpWeightMsgWithdrawDelegationReward, &weightMsgWithdrawDelegationReward, nil,
func(_ *rand.Rand) {
weightMsgWithdrawDelegationReward = simappparams.DefaultWeightMsgWithdrawDelegationReward
},
)
var weightMsgWithdrawValidatorCommission int
appParams.GetOrGenerate(cdc, OpWeightMsgWithdrawValidatorCommission, &weightMsgWithdrawValidatorCommission, nil,
func(_ *rand.Rand) {
weightMsgWithdrawValidatorCommission = simappparams.DefaultWeightMsgWithdrawValidatorCommission
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgSetWithdrawAddress,
SimulateMsgSetWithdrawAddress(ak, k),
),
simulation.NewWeightedOperation(
weightMsgWithdrawDelegationReward,
SimulateMsgWithdrawDelegatorReward(ak, k, sk),
),
simulation.NewWeightedOperation(
weightMsgWithdrawValidatorCommission,
SimulateMsgWithdrawValidatorCommission(ak, k, sk),
),
}
}
// SimulateMsgSetWithdrawAddress generates a MsgSetWithdrawAddress with random values.
// nolint: funlen
func SimulateMsgSetWithdrawAddress(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
) (simulation.OperationMsg, []simulation.FutureOperation, error) {
if !k.GetWithdrawAddrEnabled(ctx) {
return simulation.NoOpMsg(types.ModuleName), nil, nil
}
@ -59,9 +108,9 @@ func SimulateMsgSetWithdrawAddress(ak types.AccountKeeper, k keeper.Keeper) simu
// SimulateMsgWithdrawDelegatorReward generates a MsgWithdrawDelegatorReward with random values.
// nolint: funlen
func SimulateMsgWithdrawDelegatorReward(ak types.AccountKeeper, k keeper.Keeper, sk stakingkeeper.Keeper) simulation.Operation {
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
) (simulation.OperationMsg, []simulation.FutureOperation, error) {
simAccount, _ := simulation.RandomAcc(r, accs)
delegations := sk.GetAllDelegatorDelegations(ctx, simAccount.Address)
if len(delegations) == 0 {
@ -148,29 +197,3 @@ func SimulateMsgWithdrawValidatorCommission(ak types.AccountKeeper, k keeper.Kee
return simulation.NewOperationMsg(msg, true, ""), nil, nil
}
}
// SimulateCommunityPoolSpendProposalContent generates random community-pool-spend proposal content
// nolint: funlen
func SimulateCommunityPoolSpendProposalContent(k keeper.Keeper) govsim.ContentSimulator {
return func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) govtypes.Content {
simAccount, _ := simulation.RandomAcc(r, accs)
balance := k.GetFeePool(ctx).CommunityPool
if balance.Empty() {
return nil
}
denomIndex := r.Intn(len(balance))
amount, err := simulation.RandPositiveInt(r, balance[denomIndex].Amount.TruncateInt())
if err != nil {
return nil
}
return types.NewCommunityPoolSpendProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
simAccount.Address,
sdk.NewCoins(sdk.NewCoin(balance[denomIndex].Denom, amount)),
)
}
}

View File

@ -0,0 +1,52 @@
package simulation
import (
"math/rand"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// OpWeightSubmitCommunitySpendProposal app params key for community spend proposal
const OpWeightSubmitCommunitySpendProposal = "op_weight_submit_community_spend_proposal"
// ProposalContents defines the module weighted proposals' contents
func ProposalContents(k keeper.Keeper) []simulation.WeightedProposalContent {
return []simulation.WeightedProposalContent{
{
AppParamsKey: OpWeightSubmitCommunitySpendProposal,
DefaultWeight: simappparams.DefaultWeightCommunitySpendProposal,
ContentSimulatorFn: SimulateCommunityPoolSpendProposalContent(k),
},
}
}
// SimulateCommunityPoolSpendProposalContent generates random community-pool-spend proposal content
// nolint: funlen
func SimulateCommunityPoolSpendProposalContent(k keeper.Keeper) simulation.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) govtypes.Content {
simAccount, _ := simulation.RandomAcc(r, accs)
balance := k.GetFeePool(ctx).CommunityPool
if balance.Empty() {
return nil
}
denomIndex := r.Intn(len(balance))
amount, err := simulation.RandPositiveInt(r, balance[denomIndex].Amount.TruncateInt())
if err != nil {
return nil
}
return types.NewCommunityPoolSpendProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
simAccount.Address,
sdk.NewCoins(sdk.NewCoin(balance[denomIndex].Denom, amount)),
)
}
}

View File

@ -26,7 +26,7 @@ import (
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the gov module.
@ -95,42 +95,22 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the gov module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for gov module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the gov module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized gov param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the gov module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
supplyKeeper types.SupplyKeeper
keeper Keeper
accountKeeper types.AccountKeeper
supplyKeeper types.SupplyKeeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper, supplyKeeper types.SupplyKeeper) AppModule {
func NewAppModule(keeper Keeper, accountKeeper types.AccountKeeper, supplyKeeper types.SupplyKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
supplyKeeper: supplyKeeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
supplyKeeper: supplyKeeper,
}
}
@ -189,3 +169,35 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val
EndBlocker(ctx, am.keeper)
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the gov module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents returns all the gov content functions used to
// simulate governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return simulation.ProposalContents()
}
// RandomizedParams creates randomized gov param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for gov module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation {
return simulation.WeightedOperations(
simState.AppParams, simState.Cdc,
am.accountKeeper, am.keeper, simState.Contents)
}

View File

@ -7,7 +7,9 @@ import (
"time"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
"github.com/cosmos/cosmos-sdk/x/gov/types"
@ -16,16 +18,72 @@ import (
var initialProposalID = uint64(100000000000000)
// ContentSimulator defines a function type alias for generating random proposal
// content.
type ContentSimulator func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) types.Content
// Simulation operation weights constants
const (
OpWeightMsgDeposit = "op_weight_msg_deposit"
OpWeightMsgVote = "op_weight_msg_vote"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper,
k keeper.Keeper, wContents []simulation.WeightedProposalContent) simulation.WeightedOperations {
var (
weightMsgDeposit int
weightMsgVote int
)
appParams.GetOrGenerate(cdc, OpWeightMsgDeposit, &weightMsgDeposit, nil,
func(_ *rand.Rand) {
weightMsgDeposit = simappparams.DefaultWeightMsgDeposit
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgVote, &weightMsgVote, nil,
func(_ *rand.Rand) {
weightMsgVote = simappparams.DefaultWeightMsgVote
},
)
// generate the weighted operations for the proposal contents
var wProposalOps simulation.WeightedOperations
for _, wContent := range wContents {
wContent := wContent // pin variable
var weight int
appParams.GetOrGenerate(cdc, wContent.AppParamsKey, &weight, nil,
func(_ *rand.Rand) { weight = wContent.DefaultWeight })
wProposalOps = append(
wProposalOps,
simulation.NewWeightedOperation(
weight,
SimulateSubmitProposal(ak, k, wContent.ContentSimulatorFn),
),
)
}
wGovOps := simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgDeposit,
SimulateMsgDeposit(ak, k),
),
simulation.NewWeightedOperation(
weightMsgVote,
SimulateMsgVote(ak, k),
),
}
return append(wProposalOps, wGovOps...)
}
// SimulateSubmitProposal simulates creating a msg Submit Proposal
// voting on the proposal, and subsequently slashing the proposal. It is implemented using
// future operations.
// nolint: funlen
func SimulateSubmitProposal(ak types.AccountKeeper, k keeper.Keeper,
contentSim ContentSimulator) simulation.Operation {
func SimulateSubmitProposal(
ak types.AccountKeeper, k keeper.Keeper, contentSim simulation.ContentSimulatorFn,
) simulation.Operation {
// The states are:
// column 1: All validators vote
// column 2: 90% vote
@ -127,14 +185,6 @@ func SimulateSubmitProposal(ak types.AccountKeeper, k keeper.Keeper,
}
}
// SimulateTextProposalContent returns random text proposal content.
func SimulateTextProposalContent(r *rand.Rand, _ sdk.Context, _ []simulation.Account) types.Content {
return types.NewTextProposal(
simulation.RandStringOfLength(r, 140),
simulation.RandStringOfLength(r, 5000),
)
}
// SimulateMsgDeposit generates a MsgDeposit with random values.
// nolint: funlen
func SimulateMsgDeposit(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {

View File

@ -0,0 +1,32 @@
package simulation
import (
"math/rand"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// OpWeightSubmitTextProposal app params key for text proposal
const OpWeightSubmitTextProposal = "op_weight_submit_text_proposal"
// ProposalContents defines the module weighted proposals' contents
func ProposalContents() []simulation.WeightedProposalContent {
return []simulation.WeightedProposalContent{
{
AppParamsKey: OpWeightSubmitTextProposal,
DefaultWeight: simappparams.DefaultWeightTextProposal,
ContentSimulatorFn: SimulateTextProposalContent,
},
}
}
// SimulateTextProposalContent returns a random text proposal content.
func SimulateTextProposalContent(r *rand.Rand, _ sdk.Context, _ []simulation.Account) types.Content {
return types.NewTextProposal(
simulation.RandStringOfLength(r, 140),
simulation.RandStringOfLength(r, 5000),
)
}

View File

@ -22,7 +22,7 @@ import (
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the mint module.
@ -69,30 +69,9 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the mint module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for mint module's types.
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the mint module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized mint param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the mint module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
}
@ -100,9 +79,8 @@ type AppModule struct {
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
}
}
@ -156,3 +134,32 @@ func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the mint module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams creates randomized mint param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for mint module's types.
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations doesn't return any mint module operation.
func (AppModule) WeightedOperations(_ module.SimulationState) []sim.WeightedOperation {
return nil
}

View File

@ -2,18 +2,23 @@ package params
import (
"encoding/json"
"math/rand"
"github.com/gorilla/mux"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/params/simulation"
"github.com/cosmos/cosmos-sdk/x/params/types"
sim "github.com/cosmos/cosmos-sdk/x/simulation"
)
var (
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the params module.
@ -44,3 +49,44 @@ func (AppModuleBasic) GetTxCmd(_ *codec.Codec) *cobra.Command { return nil }
// GetQueryCmd returns no root query command for the params module.
func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
//____________________________________________________________________________
// AppModule implements an application module for the distribution module.
type AppModule struct {
AppModuleBasic
}
// NewAppModule creates a new AppModule object
func NewAppModule() AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState performs a no-op.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
}
// ProposalContents returns all the params content functions used to
// simulate governance proposals.
func (am AppModule) ProposalContents(simState module.SimulationState) []sim.WeightedProposalContent {
return simulation.ProposalContents(simState.ParamChanges)
}
// RandomizedParams creates randomized distribution param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return nil
}
// RegisterStoreDecoder doesn't register any type.
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {}
// WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule) WeightedOperations(_ module.SimulationState) []sim.WeightedOperation {
return nil
}

View File

@ -4,16 +4,15 @@ import (
"math/rand"
sdk "github.com/cosmos/cosmos-sdk/types"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// SimulateParamChangeProposalContent returns random parameter change content.
// It will generate a ParameterChangeProposal object with anywhere between 1 and
// the total amount of defined parameters changes, all of which have random valid values.
func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange) govsim.ContentSimulator {
func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange) simulation.ContentSimulatorFn {
return func(r *rand.Rand, _ sdk.Context, _ []simulation.Account) govtypes.Content {
lenParamChange := len(paramChangePool)
@ -22,7 +21,7 @@ func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange
}
numChanges := simulation.RandIntBetween(r, 1, lenParamChange)
paramChanges := make([]params.ParamChange, numChanges)
paramChanges := make([]types.ParamChange, numChanges)
// map from key to empty struct; used only for look-up of the keys of the
// parameters that are already in the random set of changes.
@ -41,10 +40,10 @@ func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange
// add a new distinct parameter to the set of changes and register the key
// to avoid further duplicates
paramChangesKeys[spc.ComposedKey()] = struct{}{}
paramChanges[i] = params.NewParamChangeWithSubkey(spc.Subspace, spc.Key, spc.Subkey, spc.SimValue(r))
paramChanges[i] = types.NewParamChangeWithSubkey(spc.Subspace, spc.Key, spc.Subkey, spc.SimValue(r))
}
return params.NewParameterChangeProposal(
return types.NewParameterChangeProposal(
simulation.RandStringOfLength(r, 140), // title
simulation.RandStringOfLength(r, 5000), // description
paramChanges, // set of changes

View File

@ -0,0 +1,20 @@
package simulation
import (
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// OpWeightSubmitParamChangeProposal app params key for param change proposal
const OpWeightSubmitParamChangeProposal = "op_weight_submit_param_change_proposal"
// ProposalContents defines the module weighted proposals' contents
func ProposalContents(paramChanges []simulation.ParamChange) []simulation.WeightedProposalContent {
return []simulation.WeightedProposalContent{
{
AppParamsKey: OpWeightSubmitParamChangeProposal,
DefaultWeight: simappparams.DefaultWeightParamChangeProposal,
ContentSimulatorFn: SimulateParamChangeProposalContent(paramChanges),
},
}
}

View File

@ -199,6 +199,14 @@ type WeightedOperation struct {
Op Operation
}
// NewWeightedOperation creates a new WeightedOperation instance
func NewWeightedOperation(weight int, op Operation) WeightedOperation {
return WeightedOperation{
Weight: weight,
Op: op,
}
}
// WeightedOperations is the group of all weighted operations to simulate.
type WeightedOperations []WeightedOperation

View File

@ -6,6 +6,8 @@ import (
"math/rand"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)
const (
@ -45,7 +47,8 @@ type ParamSimulator func(r *rand.Rand)
// GetOrGenerate attempts to get a given parameter by key from the AppParams
// object. If it exists, it'll be decoded and returned. Otherwise, the provided
// ParamSimulator is used to generate a random value.
// ParamSimulator is used to generate a random value or default value (eg: in the
// case of operation weights where Rand is not used).
func (sp AppParams) GetOrGenerate(cdc *codec.Codec, key string, ptr interface{}, r *rand.Rand, ps ParamSimulator) {
if v, ok := sp[key]; ok && v != nil {
cdc.MustUnmarshalJSON(v, ptr)
@ -55,6 +58,10 @@ func (sp AppParams) GetOrGenerate(cdc *codec.Codec, key string, ptr interface{},
ps(r)
}
// ContentSimulatorFn defines a function type alias for generating random proposal
// content.
type ContentSimulatorFn func(r *rand.Rand, ctx sdk.Context, accs []Account) govtypes.Content
// Params define the parameters necessary for running the simulations
type Params struct {
PastEvidenceFraction float64
@ -65,7 +72,7 @@ type Params struct {
BlockSizeTransitionMatrix TransitionMatrix
}
// RandomParams for simulation
// RandomParams returns random simulation parameters
func RandomParams(r *rand.Rand) Params {
return Params{
PastEvidenceFraction: r.Float64(),
@ -105,3 +112,14 @@ func NewSimParamChange(subspace, key, subkey string, simVal SimValFn) ParamChang
func (spc ParamChange) ComposedKey() string {
return fmt.Sprintf("%s/%s/%s", spc.Subspace, spc.Key, spc.Subkey)
}
//-----------------------------------------------------------------------------
// Proposal Contents
// WeightedProposalContent defines a common struct for proposal contents defined by
// external modules (i.e outside gov)
type WeightedProposalContent struct {
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
}

View File

@ -18,12 +18,13 @@ import (
"github.com/cosmos/cosmos-sdk/x/slashing/client/rest"
"github.com/cosmos/cosmos-sdk/x/slashing/internal/types"
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the slashing module.
@ -74,42 +75,22 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the slashing module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for slashing module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the slashing module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized slashing param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the slashing module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
stakingKeeper types.StakingKeeper
accountKeeper types.AccountKeeper
stakingKeeper stakingkeeper.Keeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper, stakingKeeper types.StakingKeeper) AppModule {
func NewAppModule(keeper Keeper, accountKeeper types.AccountKeeper, stakingKeeper stakingkeeper.Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
stakingKeeper: stakingKeeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
stakingKeeper: stakingKeeper,
}
}
@ -167,3 +148,33 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the slashing module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams creates randomized slashing param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for slashing module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations returns the all the slashing module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation {
return simulation.WeightedOperations(simState.AppParams, simState.Cdc,
am.accountKeeper, am.keeper, am.stakingKeeper)
}

View File

@ -5,7 +5,9 @@ import (
"math/rand"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing/internal/keeper"
@ -13,6 +15,32 @@ import (
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
// Simulation operation weights constants
const (
OpWeightMsgUnjail = "op_weight_msg_unjail"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(
appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper,
k keeper.Keeper, sk stakingkeeper.Keeper,
) simulation.WeightedOperations {
var weightMsgUnjail int
appParams.GetOrGenerate(cdc, OpWeightMsgUnjail, &weightMsgUnjail, nil,
func(_ *rand.Rand) {
weightMsgUnjail = simappparams.DefaultWeightMsgUnjail
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgUnjail,
SimulateMsgUnjail(ak, k, sk),
),
}
}
// SimulateMsgUnjail generates a MsgUnjail with random values
// nolint: funlen
func SimulateMsgUnjail(ak types.AccountKeeper, k keeper.Keeper, sk stakingkeeper.Keeper) simulation.Operation {

View File

@ -27,7 +27,7 @@ import (
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleSimulation = AppModuleSimulation{}
_ module.AppModuleSimulation = AppModule{}
)
// AppModuleBasic defines the basic application module used by the staking module.
@ -99,30 +99,9 @@ func (AppModuleBasic) BuildCreateValidatorMsg(cliCtx context.CLIContext,
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the staking module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for staking module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the staking module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams creates randomized staking param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
//____________________________________________________________________________
// AppModule implements an application module for the staking module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
accountKeeper types.AccountKeeper
@ -133,11 +112,10 @@ type AppModule struct {
func NewAppModule(keeper Keeper, accountKeeper types.AccountKeeper, supplyKeeper types.SupplyKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
accountKeeper: accountKeeper,
supplyKeeper: supplyKeeper,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
supplyKeeper: supplyKeeper,
}
}
@ -194,3 +172,33 @@ func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return EndBlocker(ctx, am.keeper)
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the staking module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams creates randomized staking param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []sim.ParamChange {
return simulation.ParamChanges(r)
}
// RegisterStoreDecoder registers a decoder for staking module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations returns the all the staking module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation {
return simulation.WeightedOperations(simState.AppParams, simState.Cdc,
am.accountKeeper, am.keeper)
}

View File

@ -6,13 +6,92 @@ import (
"math/rand"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Simulation operation weights constants
const (
OpWeightMsgCreateValidator = "op_weight_msg_create_validator"
OpWeightMsgEditValidator = "op_weight_msg_edit_validator"
OpWeightMsgDelegate = "op_weight_msg_delegate"
OpWeightMsgUndelegate = "op_weight_msg_undelegate"
OpWeightMsgBeginRedelegate = "op_weight_msg_begin_redelegate"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(
appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper,
k keeper.Keeper,
) simulation.WeightedOperations {
var (
weightMsgCreateValidator int
weightMsgEditValidator int
weightMsgDelegate int
weightMsgUndelegate int
weightMsgBeginRedelegate int
)
appParams.GetOrGenerate(cdc, OpWeightMsgCreateValidator, &weightMsgCreateValidator, nil,
func(_ *rand.Rand) {
weightMsgCreateValidator = simappparams.DefaultWeightMsgCreateValidator
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgEditValidator, &weightMsgEditValidator, nil,
func(_ *rand.Rand) {
weightMsgEditValidator = simappparams.DefaultWeightMsgEditValidator
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgDelegate, &weightMsgDelegate, nil,
func(_ *rand.Rand) {
weightMsgDelegate = simappparams.DefaultWeightMsgDelegate
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgUndelegate, &weightMsgUndelegate, nil,
func(_ *rand.Rand) {
weightMsgUndelegate = simappparams.DefaultWeightMsgUndelegate
},
)
appParams.GetOrGenerate(cdc, OpWeightMsgBeginRedelegate, &weightMsgBeginRedelegate, nil,
func(_ *rand.Rand) {
weightMsgBeginRedelegate = simappparams.DefaultWeightMsgBeginRedelegate
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgCreateValidator,
SimulateMsgCreateValidator(ak, k),
),
simulation.NewWeightedOperation(
weightMsgEditValidator,
SimulateMsgEditValidator(ak, k),
),
simulation.NewWeightedOperation(
weightMsgDelegate,
SimulateMsgDelegate(ak, k),
),
simulation.NewWeightedOperation(
weightMsgUndelegate,
SimulateMsgUndelegate(ak, k),
),
simulation.NewWeightedOperation(
weightMsgBeginRedelegate,
SimulateMsgBeginRedelegate(ak, k),
),
}
}
// SimulateMsgCreateValidator generates a MsgCreateValidator with random values
// nolint: funlen
func SimulateMsgCreateValidator(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {

View File

@ -70,30 +70,9 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
//____________________________________________________________________________
// AppModuleSimulation defines the module simulation functions used by the supply module.
type AppModuleSimulation struct{}
// RegisterStoreDecoder registers a decoder for supply module's types
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// GenerateGenesisState creates a randomized GenState of the supply module.
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RandomizedParams doesn't create any randomized supply param changes for the simulator.
func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange {
return nil
}
//____________________________________________________________________________
// AppModule implements an application module for the supply module.
type AppModule struct {
AppModuleBasic
AppModuleSimulation
keeper Keeper
ak types.AccountKeeper
@ -102,10 +81,9 @@ type AppModule struct {
// NewAppModule creates a new AppModule object
func NewAppModule(keeper Keeper, ak types.AccountKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
AppModuleSimulation: AppModuleSimulation{},
keeper: keeper,
ak: ak,
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
ak: ak,
}
}
@ -161,3 +139,32 @@ func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}
//____________________________________________________________________________
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the supply module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// ProposalContents doesn't return any content functions for governance proposals.
func (AppModule) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent {
return nil
}
// RandomizedParams doesn't create any randomized supply param changes for the simulator.
func (AppModule) RandomizedParams(_ *rand.Rand) []sim.ParamChange {
return nil
}
// RegisterStoreDecoder registers a decoder for supply module's types
func (AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[StoreKey] = simulation.DecodeStore
}
// WeightedOperations doesn't return any operation for the nft module.
func (AppModule) WeightedOperations(_ module.SimulationState) []sim.WeightedOperation {
return nil
}