diff --git a/.pending/improvements/sdk/4235-Add-parameter-c b/.pending/improvements/sdk/4235-Add-parameter-c new file mode 100644 index 000000000000..93d9f77fd5c2 --- /dev/null +++ b/.pending/improvements/sdk/4235-Add-parameter-c @@ -0,0 +1 @@ +#4235 Add parameter change proposal messages to simulation. diff --git a/.pending/improvements/sdk/4235-Update-the-mint b/.pending/improvements/sdk/4235-Update-the-mint new file mode 100644 index 000000000000..b399f014cacf --- /dev/null +++ b/.pending/improvements/sdk/4235-Update-the-mint @@ -0,0 +1,2 @@ +#4235 Update the minting module params to implement params.ParamSet so +individual keys can be set via proposals instead of passing a struct. diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index f8ebb62c0a71..eab5e95cd315 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -30,6 +30,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" "github.com/cosmos/cosmos-sdk/x/mint" + 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" @@ -151,72 +152,76 @@ func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimest genesisAccounts = append(genesisAccounts, gacc) } - authGenesis := auth.GenesisState{ - Params: auth.Params{ - MaxMemoCharacters: uint64(simulation.RandIntBetween(r, 100, 200)), - TxSigLimit: uint64(r.Intn(7) + 1), - TxSizeCostPerByte: uint64(simulation.RandIntBetween(r, 5, 15)), - SigVerifyCostED25519: uint64(simulation.RandIntBetween(r, 500, 1000)), - SigVerifyCostSecp256k1: uint64(simulation.RandIntBetween(r, 500, 1000)), + authGenesis := auth.NewGenesisState( + nil, + auth.Params{ + MaxMemoCharacters: simulation.ModuleParamSimulator["MaxMemoCharacters"](r).(uint64), + TxSigLimit: simulation.ModuleParamSimulator["TxSigLimit"](r).(uint64), + TxSizeCostPerByte: simulation.ModuleParamSimulator["TxSizeCostPerByte"](r).(uint64), + SigVerifyCostED25519: simulation.ModuleParamSimulator["SigVerifyCostED25519"](r).(uint64), + SigVerifyCostSecp256k1: simulation.ModuleParamSimulator["SigVerifyCostSecp256k1"](r).(uint64), }, - } + ) fmt.Printf("Selected randomly generated auth parameters:\n\t%+v\n", authGenesis) bankGenesis := bank.NewGenesisState(r.Int63n(2) == 0) fmt.Printf("Selected randomly generated bank parameters:\n\t%+v\n", bankGenesis) // Random genesis states - vp := time.Duration(r.Intn(2*172800)) * time.Second - govGenesis := gov.GenesisState{ - StartingProposalID: uint64(r.Intn(100)), - DepositParams: gov.DepositParams{ - MinDeposit: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(r.Intn(1e3)))}, + vp := simulation.ModuleParamSimulator["VotingParams/VotingPeriod"](r).(time.Duration) + govGenesis := gov.NewGenesisState( + uint64(r.Intn(100)), + gov.DepositParams{ + MinDeposit: simulation.ModuleParamSimulator["DepositParams/MinDeposit"](r).(sdk.Coins), MaxDepositPeriod: vp, }, - VotingParams: gov.VotingParams{ + gov.VotingParams{ VotingPeriod: vp, }, - TallyParams: gov.TallyParams{ - Quorum: sdk.NewDecWithPrec(334, 3), - Threshold: sdk.NewDecWithPrec(5, 1), - Veto: sdk.NewDecWithPrec(334, 3), + gov.TallyParams{ + Quorum: simulation.ModuleParamSimulator["TallyParams/Quorum"](r).(sdk.Dec), + Threshold: simulation.ModuleParamSimulator["TallyParams/Threshold"](r).(sdk.Dec), + Veto: simulation.ModuleParamSimulator["TallyParams/Veto"](r).(sdk.Dec), }, - } + ) fmt.Printf("Selected randomly generated governance parameters:\n\t%+v\n", govGenesis) - stakingGenesis := staking.GenesisState{ - Pool: staking.InitialPool(), - Params: staking.Params{ - UnbondingTime: time.Duration(simulation.RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second, - MaxValidators: uint16(r.Intn(250) + 1), + stakingGenesis := staking.NewGenesisState( + staking.InitialPool(), + staking.Params{ + UnbondingTime: simulation.ModuleParamSimulator["UnbondingTime"](r).(time.Duration), + MaxValidators: simulation.ModuleParamSimulator["MaxValidators"](r).(uint16), BondDenom: sdk.DefaultBondDenom, }, - } + nil, + nil, + ) fmt.Printf("Selected randomly generated staking parameters:\n\t%+v\n", stakingGenesis) slashingGenesis := slashing.GenesisState{ Params: slashing.Params{ MaxEvidenceAge: stakingGenesis.Params.UnbondingTime, - SignedBlocksWindow: int64(simulation.RandIntBetween(r, 10, 1000)), - MinSignedPerWindow: sdk.NewDecWithPrec(int64(r.Intn(10)), 1), - DowntimeJailDuration: time.Duration(simulation.RandIntBetween(r, 60, 60*60*24)) * time.Second, - SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))), - SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))), + SignedBlocksWindow: simulation.ModuleParamSimulator["SignedBlocksWindow"](r).(int64), + MinSignedPerWindow: simulation.ModuleParamSimulator["MinSignedPerWindow"](r).(sdk.Dec), + DowntimeJailDuration: simulation.ModuleParamSimulator["DowntimeJailDuration"](r).(time.Duration), + SlashFractionDoubleSign: simulation.ModuleParamSimulator["SlashFractionDoubleSign"](r).(sdk.Dec), + SlashFractionDowntime: simulation.ModuleParamSimulator["SlashFractionDowntime"](r).(sdk.Dec), }, } fmt.Printf("Selected randomly generated slashing parameters:\n\t%+v\n", slashingGenesis) - mintGenesis := mint.GenesisState{ - Minter: mint.InitialMinter( + mintGenesis := mint.NewGenesisState( + mint.InitialMinter( sdk.NewDecWithPrec(int64(r.Intn(99)), 2)), - Params: mint.NewParams( + mint.NewParams( sdk.DefaultBondDenom, - sdk.NewDecWithPrec(int64(r.Intn(99)), 2), - sdk.NewDecWithPrec(20, 2), - sdk.NewDecWithPrec(7, 2), - sdk.NewDecWithPrec(67, 2), - uint64(60*60*8766/5)), - } + simulation.ModuleParamSimulator["InflationRateChange"](r).(sdk.Dec), + simulation.ModuleParamSimulator["InflationMax"](r).(sdk.Dec), + simulation.ModuleParamSimulator["InflationMin"](r).(sdk.Dec), + simulation.ModuleParamSimulator["GoalBonded"](r).(sdk.Dec), + uint64(60*60*8766/5), + ), + ) fmt.Printf("Selected randomly generated minting parameters:\n\t%+v\n", mintGenesis) var validators []staking.Validator @@ -282,7 +287,8 @@ func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation { {50, distrsim.SimulateMsgSetWithdrawAddress(app.accountKeeper, app.distrKeeper)}, {50, distrsim.SimulateMsgWithdrawDelegatorReward(app.accountKeeper, app.distrKeeper)}, {50, distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper)}, - {5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper)}, + {5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, govsim.SimulateTextProposalContent)}, + {5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, paramsim.SimulateParamChangeProposalContent)}, {100, govsim.SimulateMsgDeposit(app.govKeeper)}, {100, stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper)}, {5, stakingsim.SimulateMsgEditValidator(app.stakingKeeper)}, diff --git a/x/gov/params.go b/x/gov/params.go index ed0fa5ea4c8c..112e92186206 100644 --- a/x/gov/params.go +++ b/x/gov/params.go @@ -27,7 +27,7 @@ func (dp DepositParams) Equal(dp2 DepositParams) bool { // Param around Tallying votes in governance type TallyParams struct { Quorum sdk.Dec `json:"quorum"` // Minimum percentage of total stake needed to vote for a result to be considered valid - Threshold sdk.Dec `json:"threshold"` // Minimum propotion of Yes votes for proposal to pass. Initial value: 0.5 + Threshold sdk.Dec `json:"threshold"` // Minimum proportion of Yes votes for proposal to pass. Initial value: 0.5 Veto sdk.Dec `json:"veto"` // Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3 } diff --git a/x/gov/simulation/msgs.go b/x/gov/simulation/msgs.go index bd5822c31426..2202add659b9 100644 --- a/x/gov/simulation/msgs.go +++ b/x/gov/simulation/msgs.go @@ -12,13 +12,18 @@ import ( "github.com/cosmos/cosmos-sdk/x/simulation" ) +// ContentSimulator defines a function type alias for generating random proposal +// content. +type ContentSimulator func(r *rand.Rand) gov.Content + // SimulateSubmittingVotingAndSlashingForProposal simulates creating a msg Submit Proposal // voting on the proposal, and subsequently slashing the proposal. It is implemented using // future operations. // TODO: Vote more intelligently, so we can actually do some checks regarding votes passing or failing // TODO: Actually check that validator slashings happened -func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper) simulation.Operation { +func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, contentSim ContentSimulator) simulation.Operation { handler := gov.NewHandler(k) + // The states are: // column 1: All validators vote // column 2: 90% vote @@ -36,38 +41,49 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper) simulation.Ope {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 []simulation.Account) ( - opMsg simulation.OperationMsg, fOps []simulation.FutureOperation, err error) { + + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, + ) (opMsg simulation.OperationMsg, fOps []simulation.FutureOperation, err error) { // 1) submit proposal now sender := simulation.RandomAcc(r, accs) - msg, err := simulationCreateMsgSubmitProposal(r, sender) + content := contentSim(r) + msg, err := simulationCreateMsgSubmitProposal(r, content, sender) if err != nil { return simulation.NoOpMsg(), nil, err } + ok := simulateHandleMsgSubmitProposal(msg, handler, ctx) - opMsg = simulation.NewOperationMsg(msg, ok, "") + opMsg = simulation.NewOperationMsg(msg, ok, content.ProposalType()) // don't schedule votes if proposal failed if !ok { return opMsg, nil, nil } + proposalID := k.GetLastProposalID(ctx) + // 2) Schedule operations for votes // 2.1) first pick a number of people to vote. curNumVotesState = numVotesTransitionMatrix.NextState(r, curNumVotesState) numVotes := int(math.Ceil(float64(len(accs)) * statePercentageArray[curNumVotesState])) + // 2.2) select who votes and when whoVotes := r.Perm(len(accs)) + // didntVote := whoVotes[numVotes:] whoVotes = whoVotes[:numVotes] votingPeriod := k.GetVotingParams(ctx).VotingPeriod + fops := make([]simulation.FutureOperation, numVotes+1) for i := 0; i < numVotes; i++ { whenVote := ctx.BlockHeader().Time.Add(time.Duration(r.Int63n(int64(votingPeriod.Seconds()))) * time.Second) fops[i] = simulation.FutureOperation{BlockTime: whenVote, Op: operationSimulateMsgVote(k, accs[whoVotes[i]], proposalID)} } + // 3) Make an operation to ensure slashes were done correctly. (Really should be a future invariant) // TODO: Find a way to check if a validator was slashed other than just checking their balance a block // before and after. @@ -76,24 +92,6 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper) simulation.Ope } } -// SimulateMsgSubmitProposal simulates a msg Submit Proposal -// Note: Currently doesn't ensure that the proposal txt is in JSON form -func SimulateMsgSubmitProposal(k gov.Keeper) simulation.Operation { - handler := gov.NewHandler(k) - return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account) ( - opMsg simulation.OperationMsg, fOps []simulation.FutureOperation, err error) { - - sender := simulation.RandomAcc(r, accs) - msg, err := simulationCreateMsgSubmitProposal(r, sender) - if err != nil { - return simulation.NoOpMsg(), nil, err - } - ok := simulateHandleMsgSubmitProposal(msg, handler, ctx) - opMsg = simulation.NewOperationMsg(msg, ok, "") - return opMsg, nil, nil - } -} - func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, handler sdk.Handler, ctx sdk.Context) (ok bool) { ctx, write := ctx.CacheContext() ok = handler(ctx, msg).IsOK() @@ -103,16 +101,16 @@ func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, handler sdk.Hand return ok } -func simulationCreateMsgSubmitProposal(r *rand.Rand, sender simulation.Account) (msg gov.MsgSubmitProposal, err error) { - deposit := randomDeposit(r) - msg = gov.NewMsgSubmitProposal( - gov.NewTextProposal( - simulation.RandStringOfLength(r, 5), - simulation.RandStringOfLength(r, 5), - ), - deposit, - sender.Address, +// SimulateTextProposalContent returns random text proposal content. +func SimulateTextProposalContent(r *rand.Rand) gov.Content { + return gov.NewTextProposal( + simulation.RandStringOfLength(r, 140), + simulation.RandStringOfLength(r, 5000), ) +} + +func simulationCreateMsgSubmitProposal(r *rand.Rand, c gov.Content, s simulation.Account) (msg gov.MsgSubmitProposal, err error) { + msg = gov.NewMsgSubmitProposal(c, randomDeposit(r), s.Address) if msg.ValidateBasic() != nil { err = fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) } diff --git a/x/mint/keeper.go b/x/mint/keeper.go index 42a9f19fbaa5..327e9c1ad1a0 100644 --- a/x/mint/keeper.go +++ b/x/mint/keeper.go @@ -6,6 +6,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/params" ) +var minterKey = []byte{0x00} // the one key to use for the keeper store + const ( // ModuleName is the name of the module ModuleName = "minting" @@ -42,23 +44,6 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, return keeper } -//____________________________________________________________________ -// Keys - -var ( - minterKey = []byte{0x00} // the one key to use for the keeper store - - // params store for inflation params - ParamStoreKeyParams = []byte("params") -) - -// ParamTable for staking module -func ParamKeyTable() params.KeyTable { - return params.NewKeyTable( - ParamStoreKeyParams, Params{}, - ) -} - //______________________________________________________________________ // get the minter @@ -81,14 +66,13 @@ func (k Keeper) SetMinter(ctx sdk.Context, minter Minter) { //______________________________________________________________________ -// get inflation params from the global param store -func (k Keeper) GetParams(ctx sdk.Context) Params { - var params Params - k.paramSpace.Get(ctx, ParamStoreKeyParams, ¶ms) +// GetParams returns the total set of slashing parameters. +func (k Keeper) GetParams(ctx sdk.Context) (params Params) { + k.paramSpace.GetParamSet(ctx, ¶ms) return params } // set inflation params from the global param store func (k Keeper) SetParams(ctx sdk.Context, params Params) { - k.paramSpace.Set(ctx, ParamStoreKeyParams, ¶ms) + k.paramSpace.SetParamSet(ctx, ¶ms) } diff --git a/x/mint/params.go b/x/mint/params.go index f1bd7e37d944..d51d46fff952 100644 --- a/x/mint/params.go +++ b/x/mint/params.go @@ -4,6 +4,17 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/params" +) + +// Parameter store keys +var ( + KeyMintDenom = []byte("MintDenom") + KeyInflationRateChange = []byte("InflationRateChange") + KeyInflationMax = []byte("InflationMax") + KeyInflationMin = []byte("InflationMin") + KeyGoalBonded = []byte("GoalBonded") + KeyBlocksPerYear = []byte("BlocksPerYear") ) // mint parameters @@ -16,6 +27,11 @@ type Params struct { BlocksPerYear uint64 `json:"blocks_per_year"` // expected blocks per year } +// ParamTable for minting module. +func ParamKeyTable() params.KeyTable { + return params.NewKeyTable().RegisterParamSet(&Params{}) +} + func NewParams(mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded sdk.Dec, blocksPerYear uint64) Params { @@ -70,3 +86,15 @@ func (p Params) String() string { p.InflationMin, p.GoalBonded, p.BlocksPerYear, ) } + +// Implements params.ParamSet +func (p *Params) ParamSetPairs() params.ParamSetPairs { + return params.ParamSetPairs{ + {KeyMintDenom, &p.MintDenom}, + {KeyInflationRateChange, &p.InflationRateChange}, + {KeyInflationMax, &p.InflationMax}, + {KeyInflationMin, &p.InflationMin}, + {KeyGoalBonded, &p.GoalBonded}, + {KeyBlocksPerYear, &p.BlocksPerYear}, + } +} diff --git a/x/params/simulation/msgs.go b/x/params/simulation/msgs.go new file mode 100644 index 000000000000..1771baff1c82 --- /dev/null +++ b/x/params/simulation/msgs.go @@ -0,0 +1,136 @@ +package simulation + +import ( + "fmt" + "math/rand" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/params" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +type simParamChange struct { + subspace string + key string + subkey string + simValue func(r *rand.Rand) string +} + +func (spc simParamChange) compKey() string { + return fmt.Sprintf("%s/%s/%s", spc.subkey, spc.key, spc.subkey) +} + +// paramChangePool defines a static slice of possible simulated parameter changes +// where each simParamChange corresponds to a ParamChange with a simValue +// function to generate a simulated new value. +// +// TODO: governance parameters (blocked on an upgrade to go-amino) +var paramChangePool = []simParamChange{ + // staking parameters + { + "staking", + "MaxValidators", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("%d", simulation.ModuleParamSimulator["MaxValidators"](r).(uint16)) + }, + }, + { + "staking", + "UnbondingTime", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["UnbondingTime"](r).(time.Duration)) + }, + }, + // slashing parameters + { + "slashing", + "SignedBlocksWindow", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["SignedBlocksWindow"](r).(int64)) + }, + }, + { + "slashing", + "MinSignedPerWindow", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["MinSignedPerWindow"](r).(sdk.Dec)) + }, + }, + { + "slashing", + "SlashFractionDowntime", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["SlashFractionDowntime"](r).(sdk.Dec)) + }, + }, + // minting parameters + { + "mint", + "InflationRateChange", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["InflationRateChange"](r).(sdk.Dec)) + }, + }, + // auth parameters + { + "auth", + "MaxMemoCharacters", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["MaxMemoCharacters"](r).(uint64)) + }, + }, + { + "auth", + "TxSigLimit", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["TxSigLimit"](r).(uint64)) + }, + }, + { + "auth", + "TxSizeCostPerByte", + "", + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator["TxSizeCostPerByte"](r).(uint64)) + }, + }, +} + +// SimulateParamChangeProposalContent returns random parameter change content. +// It will generate a ParameterChangeProposal object with anywhere between 1 and +// 3 parameter changes all of which have random, but valid values. +func SimulateParamChangeProposalContent(r *rand.Rand) gov.Content { + numChanges := simulation.RandIntBetween(r, 1, len(paramChangePool)/2) + paramChanges := make([]params.ParamChange, numChanges, numChanges) + paramChangesKeys := make(map[string]struct{}) + + for i := 0; i < numChanges; i++ { + spc := paramChangePool[r.Intn(len(paramChangePool))] + + // do not include duplicate parameter changes for a given subspace/key + _, ok := paramChangesKeys[spc.compKey()] + for ok { + spc = paramChangePool[r.Intn(len(paramChangePool))] + _, ok = paramChangesKeys[spc.compKey()] + } + + paramChangesKeys[spc.compKey()] = struct{}{} + paramChanges[i] = params.NewParamChange(spc.subspace, spc.key, spc.subkey, spc.simValue(r)) + } + + return params.NewParameterChangeProposal( + simulation.RandStringOfLength(r, 140), + simulation.RandStringOfLength(r, 5000), + paramChanges, + ) +} diff --git a/x/simulation/params.go b/x/simulation/params.go index 6202ec6fef37..11b43d69d7f8 100644 --- a/x/simulation/params.go +++ b/x/simulation/params.go @@ -2,6 +2,9 @@ package simulation import ( "math/rand" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -32,6 +35,75 @@ var ( {15, 92, 1}, {0, 3, 99}, }) + + // ModuleParamSimulator defines module parameter value simulators. All + // values simulated should be within valid acceptable range for the given + // parameter. + ModuleParamSimulator = map[string]func(r *rand.Rand) interface{}{ + "MaxMemoCharacters": func(r *rand.Rand) interface{} { + return uint64(RandIntBetween(r, 100, 200)) + }, + "TxSigLimit": func(r *rand.Rand) interface{} { + return uint64(r.Intn(7) + 1) + }, + "TxSizeCostPerByte": func(r *rand.Rand) interface{} { + return uint64(RandIntBetween(r, 5, 15)) + }, + "SigVerifyCostED25519": func(r *rand.Rand) interface{} { + return uint64(RandIntBetween(r, 500, 1000)) + }, + "SigVerifyCostSecp256k1": func(r *rand.Rand) interface{} { + return uint64(RandIntBetween(r, 500, 1000)) + }, + "DepositParams/MinDeposit": func(r *rand.Rand) interface{} { + return sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(r.Intn(1e3)))} + }, + "VotingParams/VotingPeriod": func(r *rand.Rand) interface{} { + return time.Duration(r.Intn(2*172800)) * time.Second + }, + "TallyParams/Quorum": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(334, 3) + }, + "TallyParams/Threshold": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(5, 1) + }, + "TallyParams/Veto": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(334, 3) + }, + "UnbondingTime": func(r *rand.Rand) interface{} { + return time.Duration(RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second + }, + "MaxValidators": func(r *rand.Rand) interface{} { + return uint16(r.Intn(250) + 1) + }, + "SignedBlocksWindow": func(r *rand.Rand) interface{} { + return int64(RandIntBetween(r, 10, 1000)) + }, + "MinSignedPerWindow": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(int64(r.Intn(10)), 1) + }, + "DowntimeJailDuration": func(r *rand.Rand) interface{} { + return time.Duration(RandIntBetween(r, 60, 60*60*24)) * time.Second + }, + "SlashFractionDoubleSign": func(r *rand.Rand) interface{} { + return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))) + }, + "SlashFractionDowntime": func(r *rand.Rand) interface{} { + return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))) + }, + "InflationRateChange": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(int64(r.Intn(99)), 2) + }, + "InflationMax": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(20, 2) + }, + "InflationMin": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(7, 2) + }, + "GoalBonded": func(r *rand.Rand) interface{} { + return sdk.NewDecWithPrec(67, 2) + }, + } ) // Simulation parameters