0g-chain/x/committee/simulation/proposals.go
Denali Marsh cae7503f7b
Token holder governance (#917)
* Committee types (#899)

* committee types

* refactor to committee interface

* include tokencommitee stringer method

* add members to BaseCommittee

* address revisions

* update querier

* update querier

* fix compilation errors, tests, etc.

* Update MsgVote with vote type (#900)

* add vote to msg

* update querier/rest

* update example cli vote msg

* remove incorrect comments

* address revisions

* update handler, stub keeper method

* add vote type to vote struct

* Committee module keeper logic for token holder governance (#902)

* fix keeper/test compilation errors

* fix keeper/test compilation errors pt 2

* add setters to committee interface

* fix sims compilation errors

* fix incentive tests compilation errors

* update types, expected keepers

* core keeper logic

* don't allow bond denom

* implement vote tallying

* query proposal polling status

* update module keepers in app.go

* register committee interface

* fix failing incentive test

* commitee types tests

* refactor GetProposalResult by committee types

* update invariants

* implement most proposal keeper tests

* add nulls to custom enums

* remove abstain vote type

* add test for close proposal

* remove outdated TODOs

* update ProcessProposals

* switch on committee type directly

* reintroduce Abstain votes and update vote tallying

* don't allow divide by 0 panics

* delete unused setters on committee interface

* clean up tally methods return values for querier

* update enum validation to catch negative ints

* reintroduce setters for sims compilation

* address revisions

* remove commented out test

* implement ProcessProposals test

* additional revisions

* Committee migrations (#909)

* add committee v14 legacy types

* update migration imports for compile

* addRegisterCodec() to committee v14 legacy types

* migrate committee genesis state from v14 to v15

* set stability committee permissions properly

* fix committee allowed params

* migration test, kava-7 sample data

* add concrete types to committees (#911)

* revisions: migrate + tests

* register msgs on legacy codec

* Prepare Committee module for migrations (#906)

* remove invariants

* edits

* fix abci test

* fix keeper querier tests

* add committee interface registration

* use codec.Codec

* don't allow null vote types

* don't allow null tally option

* minor spelling fixes

* update example cli proposal

* fix cli tally query

* enable vote abstain from cli

* include vote options in cli help text

* call CloseProposal from handler

* custom enum marshaling

* committee: fix failing tests (#921)

* fix failing tests

* fix: spelling

Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com>
Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com>
Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
2021-06-07 18:08:03 +02:00

174 lines
5.3 KiB
Go

package simulation
import (
"fmt"
"math/rand"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
appparams "github.com/kava-labs/kava/app/params"
"github.com/kava-labs/kava/x/committee/keeper"
"github.com/kava-labs/kava/x/committee/types"
)
const OpWeightSubmitCommitteeChangeProposal = "op_weight_submit_committee_change_proposal"
// ProposalContents defines the module weighted proposals' contents
func ProposalContents(k keeper.Keeper, paramChanges []simulation.ParamChange) []simulation.WeightedProposalContent {
return []simulation.WeightedProposalContent{
{
AppParamsKey: OpWeightSubmitCommitteeChangeProposal,
DefaultWeight: appparams.OpWeightSubmitCommitteeChangeProposal,
ContentSimulatorFn: SimulateCommitteeChangeProposalContent(k, paramChanges),
},
}
}
// SimulateCommitteeChangeProposalContent generates gov proposal contents that either:
// - create new committees
// - change existing committees
// - delete committees
// It does not alter the fallback committee.
func SimulateCommitteeChangeProposalContent(k keeper.Keeper, paramChanges []simulation.ParamChange) simulation.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) govtypes.Content {
allowedParams := paramChangeToAllowedParams(paramChanges)
// get current committees, ignoring the fallback committee
var committees []types.Committee
k.IterateCommittees(ctx, func(com types.Committee) bool {
if com.GetID() != FallbackCommitteeID {
committees = append(committees, com)
}
return false
})
if len(committees) < 1 { // create a committee if none exist
com, err := RandomCommittee(r, firstNAccounts(25, accs), allowedParams) // limit num members to avoid overflowing hardcoded gov ops gas limit
if err != nil {
panic(err)
}
return types.NewCommitteeChangeProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
com,
)
}
// create a proposal content
var content govtypes.Content
switch choice := r.Intn(100); {
// create committee
case choice < 20:
com, err := RandomCommittee(r, firstNAccounts(25, accs), allowedParams) // limit num members to avoid overflowing hardcoded gov ops gas limit
if err != nil {
panic(err)
}
content = types.NewCommitteeChangeProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
com,
)
// update committee
case choice < 80:
com := committees[r.Intn(len(committees))]
// update members
if r.Intn(100) < 50 {
if len(accs) == 0 {
panic("must have at least one account available to use as committee member")
}
var members []sdk.AccAddress
for len(members) < 1 {
members = RandomAddresses(r, firstNAccounts(25, accs)) // limit num members to avoid overflowing hardcoded gov ops gas limit
}
com.SetMembers(members)
}
// update permissions
if r.Intn(100) < 50 {
com.SetPermissions(RandomPermissions(r, allowedParams))
}
// update proposal duration
if r.Intn(100) < 50 {
dur, err := RandomPositiveDuration(r, 0, AverageBlockTime*100)
if err != nil {
panic(err)
}
com.SetProposalDuration(dur)
}
// update vote threshold
if r.Intn(100) < 50 {
// VoteThreshold must be in interval (0,1]
com.SetVoteThreshold(simulation.RandomDecAmount(r, sdk.MustNewDecFromStr("1").Sub(sdk.SmallestDec())).Add(sdk.SmallestDec()))
}
content = types.NewCommitteeChangeProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
com,
)
// delete committee
default:
com := committees[r.Intn(len(committees))]
content = types.NewCommitteeDeleteProposal(
simulation.RandStringOfLength(r, 10),
simulation.RandStringOfLength(r, 100),
com.GetID(),
)
}
return content
}
}
// Example custom ParamChangeProposal generator to only generate change to interesting cdp params.
// This allows more control over what params are changed within a simulation.
/*
func SimulateCDPParamChangeProposalContent(cdpKeeper cdpkeeper.Keeper, paramChangePool []simulation.ParamChange) simulation.ContentSimulatorFn {
return func(r *rand.Rand, ctx sdk.Context, _ []simulation.Account) govtypes.Content {
var paramChanges []paramstypes.ParamChange
// alter sub params
cp := cdpKeeper.GetParams(ctx).CollateralParams
if len(cp) == 0 {
return nil
}
cp[0].StabilityFee = sdk.MustNewDecFromStr("0.000001")
paramChanges = append(
paramChanges,
paramstypes.NewParamChange(cdptypes.ModuleName, "?", string(cdptypes.ModuleCdc.MustMarshalJSON(cp))),
)
// alter normal param
for _, pc := range paramChangePool {
if pc.Subspace == cdptypes.ModuleName && pc.Key == string(cdptypes.KeyGlobalDebtLimit) {
paramChanges = append(
paramChanges,
paramstypes.NewParamChange(pc.Subspace, pc.Key, pc.SimValue(r)),
)
}
}
return paramstypes.NewParameterChangeProposal(
simulation.RandStringOfLength(r, 140), // title
simulation.RandStringOfLength(r, 5000), // description
paramChanges, // set of changes
)
}
}
*/
func firstNAccounts(n int, accs []simulation.Account) []simulation.Account {
if n < 0 {
panic(fmt.Sprintf("n must be ≥ 0"))
}
if n > len(accs) {
return accs
}
return accs[:n]
}