Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(x/gov): add MaxVoteOptionsLen #20087

Merged
merged 12 commits into from
Apr 22, 2024
105 changes: 83 additions & 22 deletions api/cosmos/gov/module/v1/module.pulsar.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions x/gov/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* [#20087](https://github.com/cosmos/cosmos-sdk/pull/20087) add `MaxVoteOptionsLen`
* [#19592](https://github.com/cosmos/cosmos-sdk/pull/19592) Add custom tally function.
* [#19304](https://github.com/cosmos/cosmos-sdk/pull/19304) Add `MsgSudoExec` for allowing executing any message as a sudo.
* [#19101](https://github.com/cosmos/cosmos-sdk/pull/19101) Add message based params configuration.
Expand Down
2 changes: 2 additions & 0 deletions x/gov/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1beta1/g

For a weighted vote to be valid, the `options` field must not contain duplicate vote options, and the sum of weights of all options must be equal to 1.

The maximum number of vote options can be limited by the developer via a config parameter, named `MaxVoteOptionsLen`, which gets passed into the gov keeper.

### Quorum

Quorum is defined as the minimum percentage of voting power that needs to be
Expand Down
3 changes: 3 additions & 0 deletions x/gov/keeper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Config struct {
MaxMetadataLen uint64
// MaxSummaryLen defines the amount of characters that can be used for proposal summary
MaxSummaryLen uint64
// MaxVoteOptionsLen defines the maximum number of vote options a proposal can have
marcello33 marked this conversation as resolved.
Show resolved Hide resolved
MaxVoteOptionsLen uint64
// CalculateVoteResultsAndVotingPowerFn is a function signature for calculating vote results and voting power
// Keeping it nil will use the default implementation
CalculateVoteResultsAndVotingPowerFn CalculateVoteResultsAndVotingPowerFn
Expand All @@ -37,6 +39,7 @@ func DefaultConfig() Config {
MaxTitleLen: 255,
MaxMetadataLen: 255,
MaxSummaryLen: 10200,
MaxVoteOptionsLen: 0, // means all supported options
CalculateVoteResultsAndVotingPowerFn: nil,
}
}
13 changes: 13 additions & 0 deletions x/gov/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ func NewKeeper(
if config.MaxSummaryLen == 0 {
config.MaxSummaryLen = defaultConfig.MaxSummaryLen
}
// If MaxVoteOptionsLen not set by app developer, set to default value.
if config.MaxVoteOptionsLen == 0 {
config.MaxVoteOptionsLen = defaultConfig.MaxVoteOptionsLen
}

sb := collections.NewSchemaBuilder(env.KVStoreService)
k := &Keeper{
Expand Down Expand Up @@ -230,3 +234,12 @@ func (k Keeper) assertSummaryLength(summary string) error {
}
return nil
}

// assertVoteOptionsLen returns an error if given vote options length
// is greater than a pre-defined MaxVoteOptionsLen.
func (k Keeper) assertVoteOptionsLen(options v1.WeightedVoteOptions) error {
if uint64(len(options)) > k.config.MaxVoteOptionsLen {
marcello33 marked this conversation as resolved.
Show resolved Hide resolved
return types.ErrTooManyVoteOptions.Wrapf("got %d options, maximum allowed is %d", len(options), k.config.MaxVoteOptionsLen)
}
return nil
}
5 changes: 5 additions & 0 deletions x/gov/keeper/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func (k Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr sdk.Ac
return err
}

err = k.assertVoteOptionsLen(options)
if err != nil {
return err
}

for _, option := range options {
switch proposal.ProposalType {
case v1.ProposalType_PROPOSAL_TYPE_OPTIMISTIC:
Expand Down
4 changes: 4 additions & 0 deletions x/gov/proto/cosmos/gov/module/v1/module.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ message Module {
// max_summary_len defines the maximum proposal summary length.
// Defaults to 10200 if not explicitly set.
uint64 max_summary_len = 4;

// max_vote_options_len defines the maximum number of vote options a proposal can have.
// Defaults to 0 if not explicitly set.
uint64 max_vote_options_len = 5;
}
1 change: 1 addition & 0 deletions x/gov/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ var (
ErrInvalidDepositDenom = errors.Register(ModuleName, 23, "invalid deposit denom")
ErrTitleTooLong = errors.Register(ModuleName, 24, "title too long")
ErrTooLateToCancel = errors.Register(ModuleName, 25, "too late to cancel proposal")
ErrTooManyVoteOptions = errors.Register(ModuleName, 26, "too many vote options")
)
Loading