fix: add simulation tests for new param change (#14728)
This commit is contained in:
parent
1ad8e86d1d
commit
d3c3194185
@ -168,10 +168,11 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* (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`.
|
||||
* (x/simulation) [#14751](https://github.com/cosmos/cosmos-sdk/pull/14751) Remove the `MsgType` field from `simulation.OperationInput` struct.
|
||||
* (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`.
|
||||
|
||||
@ -101,6 +101,10 @@ All the upgrade imports are now renamed to use `cosmossdk.io/x/upgrade` instead
|
||||
|
||||
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
|
||||
|
||||
@ -68,7 +68,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)
|
||||
}
|
||||
|
||||
|
||||
@ -17,9 +17,6 @@ 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(simulation.StoreDecoderRegistry)
|
||||
|
||||
@ -27,6 +24,18 @@ type AppModuleSimulation interface {
|
||||
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 {
|
||||
@ -76,12 +85,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
|
||||
@ -115,16 +140,18 @@ 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 {
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
@ -12,14 +12,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
|
||||
@ -29,9 +32,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
|
||||
|
||||
@ -179,9 +179,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
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyMaxMemoCharacters = "MaxMemoCharacters"
|
||||
keyTxSigLimit = "TxSigLimit"
|
||||
keyTxSizeCostPerByte = "TxSizeCostPerByte"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMaxMemoCharacters,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenMaxMemoChars(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTxSigLimit,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenTxSigLimit(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTxSizeCostPerByte,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenTxSizeCostPerByte(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"auth/MaxMemoCharacters", "MaxMemoCharacters", "\"181\"", "auth"},
|
||||
{"auth/TxSigLimit", "TxSigLimit", "\"7\"", "auth"},
|
||||
{"auth/TxSizeCostPerByte", "TxSizeCostPerByte", "\"12\"", "auth"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, 3)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
47
x/auth/simulation/proposals.go
Normal file
47
x/auth/simulation/proposals.go
Normal file
@ -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
x/auth/simulation/proposals_test.go
Normal file
45
x/auth/simulation/proposals_test.go
Normal file
@ -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)
|
||||
}
|
||||
@ -207,12 +207,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 simtypes.StoreDecoderRegistry) {
|
||||
sdr[keeper.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
|
||||
@ -3,6 +3,7 @@ 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"
|
||||
@ -10,7 +11,6 @@ import (
|
||||
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 (
|
||||
|
||||
@ -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
|
||||
|
||||
@ -183,9 +183,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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyDefaultSendEnabled),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%v", RandomGenesisDefaultSendEnabledParam(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"bank/DefaultSendEnabled", "DefaultSendEnabled", "true", "bank"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, len(expected))
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
43
x/bank/simulation/proposals.go
Normal file
43
x/bank/simulation/proposals.go
Normal file
@ -0,0 +1,43 @@
|
||||
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/bank/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.DefaultSendEnabled = r.Intn(2) == 0
|
||||
|
||||
return &types.MsgUpdateParams{
|
||||
Authority: authority.String(),
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
44
x/bank/simulation/proposals_test.go
Normal file
44
x/bank/simulation/proposals_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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/bank/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/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)
|
||||
|
||||
fmt.Println(msgUpdateParams)
|
||||
assert.Equal(t, sdk.AccAddress(address.Module("gov")).String(), msgUpdateParams.Authority)
|
||||
assert.Assert(t, len(msgUpdateParams.Params.SendEnabled) == 0) //nolint:staticcheck
|
||||
assert.Equal(t, true, msgUpdateParams.Params.DefaultSendEnabled)
|
||||
}
|
||||
@ -163,11 +163,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents performs a no-op
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for capability module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
|
||||
@ -185,10 +185,9 @@ 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(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 distribution module's types
|
||||
|
||||
@ -18,13 +18,11 @@ import (
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
//
|
||||
//nolint:gosec // these are not hardcoded credentials.
|
||||
const (
|
||||
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address"
|
||||
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward"
|
||||
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission"
|
||||
OpWeightMsgFundCommunityPool = "op_weight_msg_fund_community_pool"
|
||||
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address" //nolint:gosec
|
||||
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward" //nolint:gosec
|
||||
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission" //nolint:gosec
|
||||
OpWeightMsgFundCommunityPool = "op_weight_msg_fund_community_pool" //nolint:gosec
|
||||
|
||||
DefaultWeightMsgSetWithdrawAddress int = 50
|
||||
DefaultWeightMsgWithdrawDelegationReward int = 50
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keyCommunityTax = "communitytax"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyCommunityTax,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenCommunityTax(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"distribution/communitytax", "communitytax", "\"0.120000000000000000\"", "distribution"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, 1)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
44
x/distribution/simulation/proposals.go
Normal file
44
x/distribution/simulation/proposals.go
Normal file
@ -0,0 +1,44 @@
|
||||
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/distribution/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
const (
|
||||
DefaultWeightMsgUpdateParams int = 50
|
||||
|
||||
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.CommunityTax = simtypes.RandomDecAmount(r, sdk.NewDec(1))
|
||||
params.WithdrawAddrEnabled = r.Intn(2) == 0
|
||||
|
||||
return &types.MsgUpdateParams{
|
||||
Authority: authority.String(),
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
42
x/distribution/simulation/proposals_test.go
Normal file
42
x/distribution/simulation/proposals_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
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/distribution/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/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.DeepEqual(t, sdk.NewDec(0), msgUpdateParams.Params.CommunityTax)
|
||||
assert.Equal(t, true, msgUpdateParams.Params.WithdrawAddrEnabled)
|
||||
}
|
||||
@ -177,12 +177,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the evidence content functions used to
|
||||
// simulate governance proposals.
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for evidence module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
sdr[types.StoreKey] = simulation.NewDecodeStore(am.keeper)
|
||||
|
||||
@ -208,12 +208,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the feegrant content functions used to
|
||||
// simulate governance proposals.
|
||||
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for feegrant module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
sdr[feegrant.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
|
||||
@ -334,10 +334,15 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
|
||||
// ProposalContents returns all the gov content functions used to
|
||||
// simulate governance proposals.
|
||||
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { //nolint:staticcheck
|
||||
return simulation.ProposalContents()
|
||||
}
|
||||
|
||||
// ProposalMsgs returns all the gov msgs used to simulate governance proposals.
|
||||
func (AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
|
||||
return simulation.ProposalMsgs()
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for gov module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
sdr[govtypes.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
@ -347,6 +352,7 @@ func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
||||
return simulation.WeightedOperations(
|
||||
simState.AppParams, simState.Cdc,
|
||||
am.accountKeeper, am.bankKeeper, am.keeper, simState.Contents,
|
||||
am.accountKeeper, am.bankKeeper, am.keeper,
|
||||
simState.ProposalMsgs, simState.LegacyProposalContents,
|
||||
)
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ var (
|
||||
TypeMsgVoteWeighted = sdk.MsgTypeURL(&v1.MsgVoteWeighted{})
|
||||
TypeMsgSubmitProposal = sdk.MsgTypeURL(&v1.MsgSubmitProposal{})
|
||||
TypeMsgCancelProposal = sdk.MsgTypeURL(&v1.MsgCancelProposal{})
|
||||
TypeMsgUpdateParams = sdk.MsgTypeURL(&v1.MsgUpdateParams{})
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
@ -45,7 +46,7 @@ const (
|
||||
)
|
||||
|
||||
// WeightedOperations returns all the operations from the module with their respective weights
|
||||
func WeightedOperations(appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, wContents []simtypes.WeightedProposalContent) simulation.WeightedOperations {
|
||||
func WeightedOperations(appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, wMsgs []simtypes.WeightedProposalMsg, wContents []simtypes.WeightedProposalContent) simulation.WeightedOperations { //nolint:staticcheck
|
||||
var (
|
||||
weightMsgDeposit int
|
||||
weightMsgVote int
|
||||
@ -77,20 +78,36 @@ func WeightedOperations(appParams simtypes.AppParams, cdc codec.JSONCodec, ak ty
|
||||
},
|
||||
)
|
||||
|
||||
// generate the weighted operations for the proposal contents
|
||||
// generate the weighted operations for the proposal msgs
|
||||
var wProposalOps simulation.WeightedOperations
|
||||
for _, wMsg := range wMsgs {
|
||||
wMsg := wMsg // pin variable
|
||||
var weight int
|
||||
appParams.GetOrGenerate(cdc, wMsg.AppParamsKey(), &weight, nil,
|
||||
func(_ *rand.Rand) { weight = wMsg.DefaultWeight() })
|
||||
|
||||
wProposalOps = append(
|
||||
wProposalOps,
|
||||
simulation.NewWeightedOperation(
|
||||
weight,
|
||||
SimulateMsgSubmitProposal(ak, bk, k, wMsg.MsgSimulatorFn()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// generate the weighted operations for the proposal contents
|
||||
var wLegacyProposalOps 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,
|
||||
wLegacyProposalOps = append(
|
||||
wLegacyProposalOps,
|
||||
simulation.NewWeightedOperation(
|
||||
weight,
|
||||
SimulateMsgSubmitProposal(ak, bk, k, wContent.ContentSimulatorFn()),
|
||||
SimulateMsgSubmitLegacyProposal(ak, bk, k, wContent.ContentSimulatorFn()),
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -114,34 +131,43 @@ func WeightedOperations(appParams simtypes.AppParams, cdc codec.JSONCodec, ak ty
|
||||
),
|
||||
}
|
||||
|
||||
return append(wProposalOps, wGovOps...)
|
||||
return append(wGovOps, append(wProposalOps, wLegacyProposalOps...)...)
|
||||
}
|
||||
|
||||
// SimulateMsgSubmitProposal simulates creating a msg Submit Proposal
|
||||
// voting on the proposal, and subsequently slashing the proposal. It is implemented using
|
||||
// future operations.
|
||||
func SimulateMsgSubmitProposal(ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, contentSim simtypes.ContentSimulatorFn) simtypes.Operation {
|
||||
// The states are:
|
||||
// column 1: All validators vote
|
||||
// column 2: 90% vote
|
||||
// column 3: 75% vote
|
||||
// column 4: 40% vote
|
||||
// column 5: 15% vote
|
||||
// column 6: noone votes
|
||||
// All columns sum to 100 for simplicity, values chosen by @valardragon semi-arbitrarily,
|
||||
// feel free to change.
|
||||
numVotesTransitionMatrix, _ := simulation.CreateTransitionMatrix([][]int{
|
||||
{20, 10, 0, 0, 0, 0},
|
||||
{55, 50, 20, 10, 0, 0},
|
||||
{25, 25, 30, 25, 30, 15},
|
||||
{0, 15, 30, 25, 30, 30},
|
||||
{0, 0, 20, 30, 30, 30},
|
||||
{0, 0, 0, 10, 10, 25},
|
||||
})
|
||||
func SimulateMsgSubmitProposal(ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, msgSim simtypes.MsgSimulatorFn) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand,
|
||||
app *baseapp.BaseApp,
|
||||
ctx sdk.Context,
|
||||
accs []simtypes.Account,
|
||||
chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
deposit, skip, err := randomDeposit(r, ctx, ak, bk, k, simAccount.Address, true)
|
||||
switch {
|
||||
case skip:
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgSubmitProposal, "skip deposit"), nil, nil
|
||||
case err != nil:
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgSubmitProposal, "unable to generate deposit"), nil, err
|
||||
}
|
||||
|
||||
statePercentageArray := []float64{1, .9, .75, .4, .15, 0}
|
||||
curNumVotesState := 1
|
||||
msgs := []sdk.Msg{}
|
||||
proposalMsg := msgSim(r, ctx, accs)
|
||||
if proposalMsg != nil {
|
||||
msgs = append(msgs, proposalMsg)
|
||||
}
|
||||
|
||||
return simulateMsgSubmitProposal(ak, bk, k, msgs, simAccount, deposit)(r, app, ctx, accs, chainID)
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgSubmitLegacyProposal simulates creating a msg Submit Proposal
|
||||
// voting on the proposal, and subsequently slashing the proposal. It is implemented using
|
||||
// future operations.
|
||||
func SimulateMsgSubmitLegacyProposal(ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, contentSim simtypes.ContentSimulatorFn) simtypes.Operation { //nolint:staticcheck
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
accs []simtypes.Account, chainID string,
|
||||
@ -167,7 +193,54 @@ func SimulateMsgSubmitProposal(ak types.AccountKeeper, bk types.BankKeeper, k *k
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgSubmitProposal, "error converting legacy content into proposal message"), nil, err
|
||||
}
|
||||
|
||||
msg, err := v1.NewMsgSubmitProposal([]sdk.Msg{contentMsg}, deposit, simAccount.Address.String(), "", "Title of proposal", "Short description of proposal")
|
||||
return simulateMsgSubmitProposal(ak, bk, k, []sdk.Msg{contentMsg}, simAccount, deposit)(r, app, ctx, accs, chainID)
|
||||
}
|
||||
}
|
||||
|
||||
func simulateMsgSubmitProposal(
|
||||
ak types.AccountKeeper,
|
||||
bk types.BankKeeper,
|
||||
k *keeper.Keeper,
|
||||
proposalMsgs []sdk.Msg,
|
||||
simAccount simtypes.Account,
|
||||
deposit sdk.Coins,
|
||||
) simtypes.Operation {
|
||||
// The states are:
|
||||
// column 1: All validators vote
|
||||
// column 2: 90% vote
|
||||
// column 3: 75% vote
|
||||
// column 4: 40% vote
|
||||
// column 5: 15% vote
|
||||
// column 6: noone votes
|
||||
// All columns sum to 100 for simplicity, values chosen by @valardragon semi-arbitrarily,
|
||||
// feel free to change.
|
||||
numVotesTransitionMatrix, _ := simulation.CreateTransitionMatrix([][]int{
|
||||
{20, 10, 0, 0, 0, 0},
|
||||
{55, 50, 20, 10, 0, 0},
|
||||
{25, 25, 30, 25, 30, 15},
|
||||
{0, 15, 30, 25, 30, 30},
|
||||
{0, 0, 20, 30, 30, 30},
|
||||
{0, 0, 0, 10, 10, 25},
|
||||
})
|
||||
|
||||
statePercentageArray := []float64{1, .9, .75, .4, .15, 0}
|
||||
curNumVotesState := 1
|
||||
|
||||
return func(
|
||||
r *rand.Rand,
|
||||
app *baseapp.BaseApp,
|
||||
ctx sdk.Context,
|
||||
accs []simtypes.Account,
|
||||
chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
msg, err := v1.NewMsgSubmitProposal(
|
||||
proposalMsgs,
|
||||
deposit,
|
||||
simAccount.Address.String(),
|
||||
simtypes.RandStringOfLength(r, 100),
|
||||
simtypes.RandStringOfLength(r, 100),
|
||||
simtypes.RandStringOfLength(r, 100),
|
||||
)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(msg), "unable to generate a submit proposal msg"), nil, err
|
||||
}
|
||||
|
||||
@ -6,11 +6,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/configurator"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
@ -36,20 +36,31 @@ import (
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
)
|
||||
|
||||
type MockWeightedProposalContent struct {
|
||||
var (
|
||||
_ simtypes.WeightedProposalMsg = MockWeightedProposals{}
|
||||
_ simtypes.WeightedProposalContent = MockWeightedProposals{} //nolint:staticcheck
|
||||
)
|
||||
|
||||
type MockWeightedProposals struct {
|
||||
n int
|
||||
}
|
||||
|
||||
func (m MockWeightedProposalContent) AppParamsKey() string {
|
||||
func (m MockWeightedProposals) AppParamsKey() string {
|
||||
return fmt.Sprintf("AppParamsKey-%d", m.n)
|
||||
}
|
||||
|
||||
func (m MockWeightedProposalContent) DefaultWeight() int {
|
||||
func (m MockWeightedProposals) DefaultWeight() int {
|
||||
return m.n
|
||||
}
|
||||
|
||||
func (m MockWeightedProposalContent) ContentSimulatorFn() simtypes.ContentSimulatorFn {
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) simtypes.Content {
|
||||
func (m MockWeightedProposals) MsgSimulatorFn() simtypes.MsgSimulatorFn {
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m MockWeightedProposals) ContentSimulatorFn() simtypes.ContentSimulatorFn { //nolint:staticcheck
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) simtypes.Content { //nolint:staticcheck
|
||||
return v1beta1.NewTextProposal(
|
||||
fmt.Sprintf("title-%d: %s", m.n, simtypes.RandStringOfLength(r, 100)),
|
||||
fmt.Sprintf("description-%d: %s", m.n, simtypes.RandStringOfLength(r, 4000)),
|
||||
@ -57,13 +68,18 @@ func (m MockWeightedProposalContent) ContentSimulatorFn() simtypes.ContentSimula
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the MockWeightedProposalContent satisfied the WeightedProposalContent interface
|
||||
var _ simtypes.WeightedProposalContent = MockWeightedProposalContent{}
|
||||
|
||||
func mockWeightedProposalContent(n int) []simtypes.WeightedProposalContent {
|
||||
wpc := make([]simtypes.WeightedProposalContent, n)
|
||||
func mockWeightedProposalMsg(n int) []simtypes.WeightedProposalMsg {
|
||||
wpc := make([]simtypes.WeightedProposalMsg, n)
|
||||
for i := 0; i < n; i++ {
|
||||
wpc[i] = MockWeightedProposalContent{i}
|
||||
wpc[i] = MockWeightedProposals{i}
|
||||
}
|
||||
return wpc
|
||||
}
|
||||
|
||||
func mockWeightedLegacyProposalContent(n int) []simtypes.WeightedProposalContent { //nolint:staticcheck
|
||||
wpc := make([]simtypes.WeightedProposalContent, n) //nolint:staticcheck
|
||||
for i := 0; i < n; i++ {
|
||||
wpc[i] = MockWeightedProposals{i}
|
||||
}
|
||||
return wpc
|
||||
}
|
||||
@ -73,12 +89,10 @@ func TestWeightedOperations(t *testing.T) {
|
||||
suite, ctx := createTestSuite(t, false)
|
||||
app := suite.App
|
||||
ctx.WithChainID("test-chain")
|
||||
|
||||
cdc := suite.cdc
|
||||
appParams := make(simtypes.AppParams)
|
||||
|
||||
weightesOps := simulation.WeightedOperations(appParams, cdc, suite.AccountKeeper,
|
||||
suite.BankKeeper, suite.GovKeeper, mockWeightedProposalContent(3),
|
||||
weightesOps := simulation.WeightedOperations(appParams, govcodec.ModuleCdc, suite.AccountKeeper,
|
||||
suite.BankKeeper, suite.GovKeeper, mockWeightedProposalMsg(3), mockWeightedLegacyProposalContent(1),
|
||||
)
|
||||
|
||||
// setup 3 accounts
|
||||
@ -91,18 +105,19 @@ func TestWeightedOperations(t *testing.T) {
|
||||
opMsgRoute string
|
||||
opMsgName string
|
||||
}{
|
||||
{0, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{1, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{2, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{simulation.DefaultWeightMsgDeposit, types.ModuleName, simulation.TypeMsgDeposit},
|
||||
{simulation.DefaultWeightMsgVote, types.ModuleName, simulation.TypeMsgVote},
|
||||
{simulation.DefaultWeightMsgVoteWeighted, types.ModuleName, simulation.TypeMsgVoteWeighted},
|
||||
{simulation.DefaultWeightMsgCancelProposal, types.ModuleName, simulation.TypeMsgCancelProposal},
|
||||
{0, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{1, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{2, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
{0, types.ModuleName, simulation.TypeMsgSubmitProposal},
|
||||
}
|
||||
|
||||
for i, w := range weightesOps {
|
||||
operationMsg, _, _ := w.Op()(r, app.BaseApp, ctx, accs, ctx.ChainID())
|
||||
// require.NoError(t, err) // TODO check if it should be NoError
|
||||
operationMsg, _, err := w.Op()(r, app.BaseApp, ctx.WithBlockGasMeter(storetypes.NewInfiniteGasMeter()), accs, ctx.ChainID())
|
||||
require.NoError(t, err)
|
||||
|
||||
// the following checks are very much dependent from the ordering of the output given
|
||||
// by WeightedOperations. if the ordering in WeightedOperations changes some tests
|
||||
@ -128,7 +143,37 @@ func TestSimulateMsgSubmitProposal(t *testing.T) {
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash}})
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgSubmitProposal(suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, MockWeightedProposalContent{3}.ContentSimulatorFn())
|
||||
op := simulation.SimulateMsgSubmitProposal(suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, MockWeightedProposals{3}.MsgSimulatorFn())
|
||||
operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
var msg v1.MsgSubmitProposal
|
||||
err = govcodec.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, operationMsg.OK)
|
||||
require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Proposer)
|
||||
require.NotEqual(t, len(msg.InitialDeposit), 0)
|
||||
require.Equal(t, "560969stake", msg.InitialDeposit[0].String())
|
||||
require.Equal(t, simulation.TypeMsgSubmitProposal, sdk.MsgTypeURL(&msg))
|
||||
}
|
||||
|
||||
// TestSimulateMsgSubmitProposal tests the normal scenario of a valid message of type TypeMsgSubmitProposal.
|
||||
// Abnormal scenarios, where errors occur, are not tested here.
|
||||
func TestSimulateMsgSubmitLegacyProposal(t *testing.T) {
|
||||
suite, ctx := createTestSuite(t, false)
|
||||
app := suite.App
|
||||
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3)
|
||||
|
||||
// begin a new block
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash}})
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgSubmitLegacyProposal(suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, MockWeightedProposals{3}.ContentSimulatorFn())
|
||||
operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -323,7 +368,6 @@ func TestSimulateMsgVoteWeighted(t *testing.T) {
|
||||
}
|
||||
|
||||
type suite struct {
|
||||
cdc codec.Codec
|
||||
AccountKeeper authkeeper.AccountKeeper
|
||||
BankKeeper bankkeeper.Keeper
|
||||
GovKeeper *keeper.Keeper
|
||||
@ -345,7 +389,7 @@ func createTestSuite(t *testing.T, isCheckTx bool) (suite, sdk.Context) {
|
||||
configurator.ConsensusModule(),
|
||||
configurator.DistributionModule(),
|
||||
configurator.GovModule(),
|
||||
), &res.AccountKeeper, &res.BankKeeper, &res.GovKeeper, &res.StakingKeeper, &res.DistributionKeeper, &res.cdc)
|
||||
), &res.AccountKeeper, &res.BankKeeper, &res.GovKeeper, &res.StakingKeeper, &res.DistributionKeeper)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{})
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyVotingParams = "votingparams"
|
||||
keyDepositParams = "depositparams"
|
||||
keyTallyParams = "tallyparams"
|
||||
subkeyQuorum = "quorum"
|
||||
subkeyThreshold = "threshold"
|
||||
subkeyVeto = "veto"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyVotingParams,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"voting_period": "%d"}`, GenVotingParamsVotingPeriod(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyDepositParams,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"max_deposit_period": "%d"}`, GenDepositParamsDepositPeriod(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTallyParams,
|
||||
func(r *rand.Rand) string {
|
||||
changes := []struct {
|
||||
key string
|
||||
value sdk.Dec
|
||||
}{
|
||||
{subkeyQuorum, GenTallyParamsQuorum(r)},
|
||||
{subkeyThreshold, GenTallyParamsThreshold(r)},
|
||||
{subkeyVeto, GenTallyParamsVeto(r)},
|
||||
}
|
||||
|
||||
pc := make(map[string]string)
|
||||
numChanges := simtypes.RandIntBetween(r, 1, len(changes))
|
||||
for i := 0; i < numChanges; i++ {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
|
||||
_, ok := pc[c.key]
|
||||
for ok {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
_, ok = pc[c.key]
|
||||
}
|
||||
|
||||
pc[c.key] = c.value.String()
|
||||
}
|
||||
|
||||
bz, _ := json.Marshal(pc)
|
||||
return string(bz)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"gov/votingparams", "votingparams", "{\"voting_period\": \"82639000000000\"}", "gov"},
|
||||
{"gov/depositparams", "depositparams", "{\"max_deposit_period\": \"47332000000000\"}", "gov"},
|
||||
{"gov/tallyparams", "tallyparams", "{\"threshold\":\"0.509000000000000000\"}", "gov"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
require.Len(t, paramChanges, 3)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
@ -12,19 +12,40 @@ import (
|
||||
// OpWeightSubmitTextProposal app params key for text proposal
|
||||
const OpWeightSubmitTextProposal = "op_weight_submit_text_proposal"
|
||||
|
||||
// ProposalMsgs defines the module weighted proposals' contents
|
||||
func ProposalMsgs() []simtypes.WeightedProposalMsg {
|
||||
return []simtypes.WeightedProposalMsg{
|
||||
simulation.NewWeightedProposalMsg(
|
||||
OpWeightSubmitTextProposal,
|
||||
DefaultWeightTextProposal,
|
||||
SimulateTextProposal,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateTextProposal returns a random text proposal content.
|
||||
// A text proposal is a proposal that contains no msgs.
|
||||
func SimulateTextProposal(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProposalContents defines the module weighted proposals' contents
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func ProposalContents() []simtypes.WeightedProposalContent {
|
||||
return []simtypes.WeightedProposalContent{
|
||||
simulation.NewWeightedProposalContent(
|
||||
OpWeightMsgDeposit,
|
||||
DefaultWeightTextProposal,
|
||||
SimulateTextProposalContent,
|
||||
SimulateLegacyTextProposalContent,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateTextProposalContent returns a random text proposal content.
|
||||
func SimulateTextProposalContent(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) simtypes.Content {
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func SimulateLegacyTextProposalContent(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) simtypes.Content {
|
||||
return v1beta1.NewTextProposal(
|
||||
simtypes.RandStringOfLength(r, 140),
|
||||
simtypes.RandStringOfLength(r, 5000),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -173,12 +173,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the group content functions used to
|
||||
// simulate governance proposals.
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for group module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
|
||||
sdr[group.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
|
||||
@ -191,9 +191,9 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// 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 mint module's types.
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keyInflationRateChange = "InflationRateChange"
|
||||
keyInflationMax = "InflationMax"
|
||||
keyInflationMin = "InflationMin"
|
||||
keyGoalBonded = "GoalBonded"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationRateChange,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationRateChange(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationMax,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationMax(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationMin,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationMin(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyGoalBonded,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenGoalBonded(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/simulation"
|
||||
)
|
||||
|
||||
func TestParamChangest(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"mint/InflationRateChange", "InflationRateChange", "\"0.230000000000000000\"", "mint"},
|
||||
{"mint/InflationMax", "InflationMax", "\"0.200000000000000000\"", "mint"},
|
||||
{"mint/InflationMin", "InflationMin", "\"0.070000000000000000\"", "mint"},
|
||||
{"mint/GoalBonded", "GoalBonded", "\"0.670000000000000000\"", "mint"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
require.Len(t, paramChanges, 4)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
48
x/mint/simulation/proposals.go
Normal file
48
x/mint/simulation/proposals.go
Normal file
@ -0,0 +1,48 @@
|
||||
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/mint/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.BlocksPerYear = uint64(simtypes.RandIntBetween(r, 1, 1000000))
|
||||
params.GoalBonded = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 100)), 2)
|
||||
params.InflationMin = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 50)), 2)
|
||||
params.InflationMax = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 50, 100)), 2)
|
||||
params.InflationRateChange = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 100)), 2)
|
||||
params.MintDenom = simtypes.RandStringOfLength(r, 10)
|
||||
|
||||
return &types.MsgUpdateParams{
|
||||
Authority: authority.String(),
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
46
x/mint/simulation/proposals_test.go
Normal file
46
x/mint/simulation/proposals_test.go
Normal file
@ -0,0 +1,46 @@
|
||||
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/mint/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/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(122877), msgUpdateParams.Params.BlocksPerYear)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(95, 2), msgUpdateParams.Params.GoalBonded)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(94, 2), msgUpdateParams.Params.InflationMax)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(23, 2), msgUpdateParams.Params.InflationMin)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(89, 2), msgUpdateParams.Params.InflationRateChange)
|
||||
assert.Equal(t, "XhhuTSkuxK", msgUpdateParams.Params.MintDenom)
|
||||
}
|
||||
@ -16,13 +16,10 @@ import (
|
||||
"cosmossdk.io/x/nft/keeper"
|
||||
)
|
||||
|
||||
//nolint:gosec // these are not hardcoded credentials.
|
||||
const (
|
||||
// OpWeightMsgSend Simulation operation weights constants
|
||||
OpWeightMsgSend = "op_weight_msg_send"
|
||||
)
|
||||
OpWeightMsgSend = "op_weight_msg_send" //nolint:gosec
|
||||
|
||||
const (
|
||||
// WeightSend nft operations weights
|
||||
WeightSend = 100
|
||||
)
|
||||
|
||||
@ -114,12 +114,6 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
proposal.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the params content functions used to
|
||||
// simulate governance proposals.
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder doesn't register any type.
|
||||
func (AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ func min(a int, b int) int {
|
||||
// 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) simulation.ContentSimulatorFn {
|
||||
func SimulateParamChangeProposalContent(paramChangePool []simulation.LegacyParamChange) simulation.ContentSimulatorFn { //nolint:staticcheck
|
||||
numProposals := 0
|
||||
// Bound the maximum number of simultaneous parameter changes
|
||||
maxSimultaneousParamChanges := min(len(paramChangePool), 1000)
|
||||
@ -27,7 +27,7 @@ func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange
|
||||
panic("param changes array is empty")
|
||||
}
|
||||
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simulation.Account) simulation.Content {
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simulation.Account) simulation.Content { //nolint:staticcheck
|
||||
numChanges := simulation.RandIntBetween(r, 1, maxSimultaneousParamChanges)
|
||||
paramChanges := make([]proposal.ParamChange, numChanges)
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ func (pc MockParamChange) SimValue() simtypes.SimValFn {
|
||||
}
|
||||
|
||||
// make sure that the MockParamChange satisfied the ParamChange interface
|
||||
var _ simtypes.ParamChange = MockParamChange{}
|
||||
var _ simtypes.LegacyParamChange = MockParamChange{}
|
||||
|
||||
func TestSimulateParamChangeProposalContent(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
@ -45,7 +45,7 @@ func TestSimulateParamChangeProposalContent(t *testing.T) {
|
||||
|
||||
ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil)
|
||||
accounts := simtypes.RandomAccounts(r, 3)
|
||||
paramChangePool := []simtypes.ParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}}
|
||||
paramChangePool := []simtypes.LegacyParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}}
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateParamChangeProposalContent(paramChangePool)
|
||||
|
||||
@ -12,7 +12,9 @@ const (
|
||||
)
|
||||
|
||||
// ProposalContents defines the module weighted proposals' contents
|
||||
func ProposalContents(paramChanges []simtypes.ParamChange) []simtypes.WeightedProposalContent {
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func ProposalContents(paramChanges []simtypes.LegacyParamChange) []simtypes.WeightedProposalContent {
|
||||
return []simtypes.WeightedProposalContent{
|
||||
simulation.NewWeightedProposalContent(
|
||||
OpWeightSubmitParamChangeProposal,
|
||||
|
||||
@ -21,7 +21,7 @@ func TestProposalContents(t *testing.T) {
|
||||
ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil)
|
||||
accounts := simtypes.RandomAccounts(r, 3)
|
||||
|
||||
paramChangePool := []simtypes.ParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}}
|
||||
paramChangePool := []simtypes.LegacyParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}}
|
||||
|
||||
// execute ProposalContents function
|
||||
weightedProposalContent := simulation.ProposalContents(paramChangePool)
|
||||
|
||||
@ -86,52 +86,78 @@ func RandomParams(r *rand.Rand) Params {
|
||||
}
|
||||
}
|
||||
|
||||
// Param change proposals
|
||||
// Legacy param change proposals
|
||||
|
||||
// ParamChange defines the object used for simulating parameter change proposals
|
||||
type ParamChange struct {
|
||||
// LegacyParamChange defines the object used for simulating parameter change proposals
|
||||
type LegacyParamChange struct {
|
||||
subspace string
|
||||
key string
|
||||
simValue simulation.SimValFn
|
||||
}
|
||||
|
||||
func (spc ParamChange) Subspace() string {
|
||||
func (spc LegacyParamChange) Subspace() string {
|
||||
return spc.subspace
|
||||
}
|
||||
|
||||
func (spc ParamChange) Key() string {
|
||||
func (spc LegacyParamChange) Key() string {
|
||||
return spc.key
|
||||
}
|
||||
|
||||
func (spc ParamChange) SimValue() simulation.SimValFn {
|
||||
func (spc LegacyParamChange) SimValue() simulation.SimValFn {
|
||||
return spc.simValue
|
||||
}
|
||||
|
||||
// NewSimParamChange creates a new ParamChange instance
|
||||
func NewSimParamChange(subspace, key string, simVal simulation.SimValFn) simulation.ParamChange {
|
||||
return ParamChange{
|
||||
// ComposedKey creates a new composed key for the legacy param change proposal
|
||||
func (spc LegacyParamChange) ComposedKey() string {
|
||||
return spc.Subspace() + "/" + spc.Key()
|
||||
}
|
||||
|
||||
// NewSimLegacyParamChange creates a new LegacyParamChange instance
|
||||
func NewSimLegacyParamChange(subspace, key string, simVal simulation.SimValFn) simulation.LegacyParamChange {
|
||||
return LegacyParamChange{
|
||||
subspace: subspace,
|
||||
key: key,
|
||||
simValue: simVal,
|
||||
}
|
||||
}
|
||||
|
||||
// ComposedKey creates a new composed key for the param change proposal
|
||||
func (spc ParamChange) ComposedKey() string {
|
||||
return spc.Subspace() + "/" + spc.Key()
|
||||
// Proposal Msgs
|
||||
|
||||
// WeightedProposalMsg defines a common struct for proposal msgs defined by external modules (i.e outside gov)
|
||||
type WeightedProposalMsg struct {
|
||||
appParamsKey string // key used to retrieve the value of the weight from the simulation application params
|
||||
defaultWeight int // default weight
|
||||
msgSimulatorFn simulation.MsgSimulatorFn // msg simulator function
|
||||
}
|
||||
|
||||
// Proposal Contents
|
||||
func NewWeightedProposalMsg(appParamsKey string, defaultWeight int, msgSimulatorFn simulation.MsgSimulatorFn) simulation.WeightedProposalMsg {
|
||||
return &WeightedProposalMsg{appParamsKey: appParamsKey, defaultWeight: defaultWeight, msgSimulatorFn: msgSimulatorFn}
|
||||
}
|
||||
|
||||
// WeightedProposalContent defines a common struct for proposal contents defined by
|
||||
// external modules (i.e outside gov)
|
||||
func (w WeightedProposalMsg) AppParamsKey() string {
|
||||
return w.appParamsKey
|
||||
}
|
||||
|
||||
func (w WeightedProposalMsg) DefaultWeight() int {
|
||||
return w.defaultWeight
|
||||
}
|
||||
|
||||
func (w WeightedProposalMsg) MsgSimulatorFn() simulation.MsgSimulatorFn {
|
||||
return w.msgSimulatorFn
|
||||
}
|
||||
|
||||
// Legacy Proposal Content
|
||||
|
||||
// WeightedProposalContent defines a common struct for proposal content defined by external modules (i.e outside gov)
|
||||
//
|
||||
//nolint:staticcheck
|
||||
type WeightedProposalContent struct {
|
||||
appParamsKey string // key used to retrieve the value of the weight from the simulation application params
|
||||
defaultWeight int // default weight
|
||||
contentSimulatorFn simulation.ContentSimulatorFn // content simulator function
|
||||
}
|
||||
|
||||
func NewWeightedProposalContent(appParamsKey string, defaultWeight int, contentSimulatorFn simulation.ContentSimulatorFn) simulation.WeightedProposalContent {
|
||||
func NewWeightedProposalContent(appParamsKey string, defaultWeight int, contentSimulatorFn simulation.ContentSimulatorFn) simulation.WeightedProposalContent { //nolint:staticcheck
|
||||
return &WeightedProposalContent{appParamsKey: appParamsKey, defaultWeight: defaultWeight, contentSimulatorFn: contentSimulatorFn}
|
||||
}
|
||||
|
||||
@ -143,11 +169,11 @@ func (w WeightedProposalContent) DefaultWeight() int {
|
||||
return w.defaultWeight
|
||||
}
|
||||
|
||||
func (w WeightedProposalContent) ContentSimulatorFn() simulation.ContentSimulatorFn {
|
||||
func (w WeightedProposalContent) ContentSimulatorFn() simulation.ContentSimulatorFn { //nolint:staticcheck
|
||||
return w.contentSimulatorFn
|
||||
}
|
||||
|
||||
// Param change proposals
|
||||
// Consensus Params
|
||||
|
||||
// randomConsensusParams returns random simulation consensus parameters, it extracts the Evidence from the Staking genesis state.
|
||||
func randomConsensusParams(r *rand.Rand, appState json.RawMessage, cdc codec.JSONCodec) *tmproto.ConsensusParams {
|
||||
|
||||
@ -12,13 +12,13 @@ import (
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
)
|
||||
|
||||
func TestParamChange(t *testing.T) {
|
||||
func TestLegacyParamChange(t *testing.T) {
|
||||
subspace, key := "theSubspace", "key"
|
||||
f := func(r *rand.Rand) string {
|
||||
return "theResult"
|
||||
}
|
||||
|
||||
pChange := NewSimParamChange(subspace, key, f)
|
||||
pChange := NewSimLegacyParamChange(subspace, key, f)
|
||||
|
||||
require.Equal(t, subspace, pChange.Subspace())
|
||||
require.Equal(t, key, pChange.Key())
|
||||
@ -30,7 +30,7 @@ func TestNewWeightedProposalContent(t *testing.T) {
|
||||
key := "theKey"
|
||||
weight := 1
|
||||
content := &testContent{}
|
||||
f := func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content {
|
||||
f := func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { //nolint:staticcheck
|
||||
return content
|
||||
}
|
||||
|
||||
|
||||
@ -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(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 slashing module's types
|
||||
|
||||
@ -18,10 +18,9 @@ import (
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
//
|
||||
//nolint:gosec // these are not hardcoded credentials.
|
||||
const (
|
||||
OpWeightMsgUnjail = "op_weight_msg_unjail"
|
||||
OpWeightMsgUnjail = "op_weight_msg_unjail" //nolint:gosec
|
||||
|
||||
DefaultWeightMsgUnjail = 100
|
||||
)
|
||||
|
||||
@ -31,6 +30,7 @@ func WeightedOperations(
|
||||
bk types.BankKeeper, k keeper.Keeper, sk types.StakingKeeper,
|
||||
) simulation.WeightedOperations {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
|
||||
var weightMsgUnjail int
|
||||
appParams.GetOrGenerate(cdc, OpWeightMsgUnjail, &weightMsgUnjail, nil,
|
||||
func(_ *rand.Rand) {
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keySignedBlocksWindow = "SignedBlocksWindow"
|
||||
keyMinSignedPerWindow = "MinSignedPerWindow"
|
||||
keySlashFractionDowntime = "SlashFractionDowntime"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keySignedBlocksWindow,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenSignedBlocksWindow(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMinSignedPerWindow,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenMinSignedPerWindow(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keySlashFractionDowntime,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenSlashFractionDowntime(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"slashing/SignedBlocksWindow", "SignedBlocksWindow", "\"231\"", "slashing"},
|
||||
{"slashing/MinSignedPerWindow", "MinSignedPerWindow", "\"0.700000000000000000\"", "slashing"},
|
||||
{"slashing/SlashFractionDowntime", "SlashFractionDowntime", "\"0.020833333333333333\"", "slashing"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, 3)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
48
x/slashing/simulation/proposals.go
Normal file
48
x/slashing/simulation/proposals.go
Normal file
@ -0,0 +1,48 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
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/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
// 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.DowntimeJailDuration = time.Duration(simtypes.RandTimestamp(r).UnixNano())
|
||||
params.SignedBlocksWindow = int64(simtypes.RandIntBetween(r, 1, 1000))
|
||||
params.MinSignedPerWindow = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 100)), 2)
|
||||
params.SlashFractionDoubleSign = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 100)), 2)
|
||||
params.SlashFractionDowntime = sdk.NewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 100)), 2)
|
||||
|
||||
return &types.MsgUpdateParams{
|
||||
Authority: authority.String(),
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
46
x/slashing/simulation/proposals_test.go
Normal file
46
x/slashing/simulation/proposals_test.go
Normal file
@ -0,0 +1,46 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
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/slashing/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/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, int64(905), msgUpdateParams.Params.SignedBlocksWindow)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(7, 2), msgUpdateParams.Params.MinSignedPerWindow)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(60, 2), msgUpdateParams.Params.SlashFractionDoubleSign)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(89, 2), msgUpdateParams.Params.SlashFractionDowntime)
|
||||
assert.Equal(t, 3313479009*time.Second, msgUpdateParams.Params.DowntimeJailDuration)
|
||||
}
|
||||
@ -289,9 +289,9 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// 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 staking module's types
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyMaxValidators),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", genMaxValidators(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyUnbondingTime),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", genUnbondingTime(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyHistoricalEntries),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", getHistEntries(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/simulation"
|
||||
)
|
||||
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"staking/MaxValidators", "MaxValidators", "82", "staking"},
|
||||
{"staking/UnbondingTime", "UnbondingTime", "\"275307000000000\"", "staking"},
|
||||
{"staking/HistoricalEntries", "HistoricalEntries", "9149", "staking"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, 3)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
||||
49
x/staking/simulation/proposals.go
Normal file
49
x/staking/simulation/proposals.go
Normal file
@ -0,0 +1,49 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
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/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// 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.BondDenom = simtypes.RandStringOfLength(r, 10)
|
||||
params.HistoricalEntries = uint32(simtypes.RandIntBetween(r, 0, 1000))
|
||||
params.MaxEntries = uint32(simtypes.RandIntBetween(r, 1, 1000))
|
||||
params.MaxValidators = uint32(simtypes.RandIntBetween(r, 1, 1000))
|
||||
params.UnbondingTime = time.Duration(simtypes.RandTimestamp(r).UnixNano())
|
||||
params.MinCommissionRate = simtypes.RandomDecAmount(r, sdk.NewDec(1))
|
||||
|
||||
return &types.MsgUpdateParams{
|
||||
Authority: authority.String(),
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
47
x/staking/simulation/proposals_test.go
Normal file
47
x/staking/simulation/proposals_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
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/staking/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/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, "GqiQWIXnku", msgUpdateParams.Params.BondDenom)
|
||||
assert.Equal(t, uint32(213), msgUpdateParams.Params.MaxEntries)
|
||||
assert.Equal(t, uint32(300), msgUpdateParams.Params.HistoricalEntries)
|
||||
assert.Equal(t, uint32(539), msgUpdateParams.Params.MaxValidators)
|
||||
assert.Equal(t, 8898194435*time.Second, msgUpdateParams.Params.UnbondingTime)
|
||||
assert.DeepEqual(t, sdk.NewDecWithPrec(579040435581502128, 18), msgUpdateParams.Params.MinCommissionRate)
|
||||
}
|
||||
@ -100,6 +100,10 @@ func (p Params) Validate() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateHistoricalEntries(p.HistoricalEntries); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user