Skip to content

Commit

Permalink
feat!: expedited proposals (#240)
Browse files Browse the repository at this point in the history
* make proto-all

* make proto-all with IsExpedited flag

* expedited_voting_period on voting params

* go mod tidy

* add IsExpedited flag to all proposals

* implement the foundation for expedited proposals

* add validation for voting period params

* validate tally params - expedited must be greater than or equal to regular tally

* fix cli

* fix problems with querying tally params

* TestProposalPassedEndblocker for expedited

* update TestCmdParams

* fix TestMigrate v040

* fix TestGRPCQueryProposal

* fix v043 TestMigrateJSON

* fix TestRandomizedGenState

* fix TestSimulateMsgSubmitProposal

* TestExpeditedToRegularConversion

* fix TestIntegrationTestSuite/TestCmdParams/text_output

* test TestExpeditedProposal_PassAndConversionToRegular

* attempt to fix TestAppStateDeterminism

* fix TestRandomizedGenState after changing rand generation bounds

* fix TestParamChanges

* Update x/gov/abci.go

* Update x/gov/abci.go

* Update x/gov/types/keys.go

* refactor to have isExpedited flag on the proposal struct

* fix tests

* clean up proto files and remove is_expedited from CommunityPoolSpendProposal

* fix migrate tests

* fix proto

* Update x/gov/abci.go

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* Update proto/cosmos/gov/v1beta1/gov.proto

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* expedited vote threshold must be strictly greater than regular

* fix Cmd tests

* fix another cmd test

* Add spec for emergency voting (#249)

* Add simple changelog

* Update x/gov/spec/01_concepts.md

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* Update x/gov/types/keys.go

Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>

* remove redundant isExpedited flag from ContentFromProposalType

* Update x/gov/abci.go

Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 16, 2022
1 parent 7ae03dd commit ae817b9
Show file tree
Hide file tree
Showing 57 changed files with 1,245 additions and 427 deletions.
4 changes: 4 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5117,6 +5117,7 @@ Proposal defines the core field members of a governance proposal.
| `total_deposit` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
| `voting_start_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
| `voting_end_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
| `is_expedited` | [bool](#bool) | | |



Expand Down Expand Up @@ -5151,6 +5152,7 @@ TallyParams defines the params for tallying votes on governance proposals.
| `quorum` | [bytes](#bytes) | | Minimum percentage of total stake needed to vote for a result to be considered valid. |
| `threshold` | [bytes](#bytes) | | Minimum proportion of Yes votes for proposal to pass. Default value: 0.5. |
| `veto_threshold` | [bytes](#bytes) | | Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. Default value: 1/3. |
| `expedited_threshold` | [bytes](#bytes) | | Minimum proportion of Yes votes for an expedited proposal to pass. Default value: 0.67. |



Expand Down Expand Up @@ -5221,6 +5223,7 @@ VotingParams defines the params for voting on governance proposals.
| ----- | ---- | ----- | ----------- |
| `voting_period` | [google.protobuf.Duration](#google.protobuf.Duration) | | voting_period defines the length of the voting period. |
| `proposal_voting_periods` | [ProposalVotingPeriod](#cosmos.gov.v1beta1.ProposalVotingPeriod) | repeated | proposal_voting_periods defines custom voting periods for proposal types. |
| `expedited_voting_period` | [google.protobuf.Duration](#google.protobuf.Duration) | | Length of the expedited voting period. |



Expand Down Expand Up @@ -5654,6 +5657,7 @@ proposal Content.
| `content` | [google.protobuf.Any](#google.protobuf.Any) | | |
| `initial_deposit` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
| `proposer` | [string](#string) | | |
| `is_expedited` | [bool](#bool) | | |



Expand Down
17 changes: 16 additions & 1 deletion proto/cosmos/gov/v1beta1/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ message Proposal {
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""];
google.protobuf.Timestamp voting_end_time = 9
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""];
bool is_expedited = 10;
}

// ProposalStatus enumerates the valid statuses of a proposal.
Expand Down Expand Up @@ -170,9 +171,16 @@ message VotingParams {
(gogoproto.jsontag) = "voting_period,omitempty",
(gogoproto.moretags) = "yaml:\"voting_period\""
];

// proposal_voting_periods defines custom voting periods for proposal types.
repeated ProposalVotingPeriod proposal_voting_periods = 2 [(gogoproto.nullable) = false];

// Length of the expedited voting period.
google.protobuf.Duration expedited_voting_period = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "expedited_voting_period,omitempty",
(gogoproto.moretags) = "yaml:\"expedited_voting_period\""
];
}

// TallyParams defines the params for tallying votes on governance proposals.
Expand Down Expand Up @@ -200,6 +208,13 @@ message TallyParams {
(gogoproto.jsontag) = "veto_threshold,omitempty",
(gogoproto.moretags) = "yaml:\"veto_threshold\""
];

// Minimum proportion of Yes votes for an expedited proposal to pass. Default value: 0.67.
bytes expedited_threshold = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "expedited_threshold,omitempty"
];
}

// ProposalVotingPeriod defines custom voting periods for a unique governance
Expand Down
3 changes: 2 additions & 1 deletion proto/cosmos/gov/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ message MsgSubmitProposal {
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"initial_deposit\""
];
string proposer = 3;
string proposer = 3;
bool is_expedited = 4;
}

// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type.
Expand Down
13 changes: 11 additions & 2 deletions x/distribution/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
var (
FlagCommission = "commission"
FlagMaxMessagesPerTx = "max-msgs"
FlagIsExpedited = "is-expedited"
)

const (
Expand Down Expand Up @@ -279,7 +280,7 @@ func GetCmdSubmitProposal() *cobra.Command {
The proposal details must be supplied via a JSON file.
Example:
$ %s tx gov submit-proposal community-pool-spend <path/to/proposal.json> --from=<key_or_address>
$ %s tx gov submit-proposal community-pool-spend <path/to/proposal.json> --from=<key_or_address> --is-expedited=false
Where proposal.json contains:
Expand Down Expand Up @@ -319,9 +320,15 @@ Where proposal.json contains:
if err != nil {
return err
}

isExpedited, err := cmd.Flags().GetBool(FlagIsExpedited)
if err != nil {
return err
}

content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, recpAddr, amount)

msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from)
msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from, isExpedited)
if err != nil {
return err
}
Expand All @@ -330,5 +337,7 @@ Where proposal.json contains:
},
}

cmd.Flags().Bool(FlagIsExpedited, false, "If true, makes the proposal an expedited one")

return cmd
}
2 changes: 1 addition & 1 deletion x/distribution/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func postProposalHandlerFn(clientCtx client.Context) http.HandlerFunc {

content := types.NewCommunityPoolSpendProposal(req.Title, req.Description, req.Recipient, req.Amount)

msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, req.Proposer)
msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, req.Proposer, req.IsExpedited)
if rest.CheckBadRequestError(w, err) {
return
}
Expand Down
1 change: 1 addition & 0 deletions x/distribution/client/rest/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type (

Title string `json:"title" yaml:"title"`
Description string `json:"description" yaml:"description"`
IsExpedited bool `json:"is_expedited" yaml:"is_expedited"`
Recipient sdk.AccAddress `json:"recipient" yaml:"recipient"`
Amount sdk.Coins `json:"amount" yaml:"amount"`
Proposer sdk.AccAddress `json:"proposer" yaml:"proposer"`
Expand Down
41 changes: 32 additions & 9 deletions x/gov/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,20 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {

passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)

if burnDeposits {
keeper.DeleteDeposits(ctx, proposal.ProposalId)
} else {
keeper.RefundDeposits(ctx, proposal.ProposalId)
// If an expedited proposal fails, we do not want to update
// the deposit at this point since the proposal is converted to regular.
// As a result, the deposits are either deleted or refunded in all casses
// EXCEPT when an expedited proposal fails.
if !(proposal.IsExpedited && !passes) {
if burnDeposits {
keeper.DeleteDeposits(ctx, proposal.ProposalId)
} else {
keeper.RefundDeposits(ctx, proposal.ProposalId)
}
}

keeper.RemoveFromActiveProposalQueue(ctx, proposal.ProposalId, proposal.VotingEndTime)

if passes {
handler := keeper.Router().GetRoute(proposal.ProposalRoute())
cacheCtx, writeCache := ctx.CacheContext()
Expand Down Expand Up @@ -82,15 +90,30 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
logMsg = fmt.Sprintf("passed, but failed on execution: %s", err)
}
} else {
proposal.Status = types.StatusRejected
tagValue = types.AttributeValueProposalRejected
logMsg = "rejected"
if proposal.IsExpedited {
// When expedited proposal fails, it is converted
// to a regular proposal. As a result, the voting period is extended, and,
// once the regular voting period expires again, the tally is repeated
// according to the regular proposal rules.
proposal.IsExpedited = false
votingParams := keeper.GetVotingParams(ctx)
proposal.VotingEndTime = proposal.VotingStartTime.Add(votingParams.VotingPeriod)

keeper.InsertActiveProposalQueue(ctx, proposal.ProposalId, proposal.VotingEndTime)

tagValue = types.AttributeValueExpeditedProposalRejected
logMsg = "expedited proposal converted to regular"
} else {
// When regular proposal fails, it is rejected and
// the proposal with that id is done forever.
proposal.Status = types.StatusRejected
tagValue = types.AttributeValueProposalRejected
logMsg = "rejected"
}
}

proposal.FinalTallyResult = tallyResults

keeper.SetProposal(ctx, proposal)
keeper.RemoveFromActiveProposalQueue(ctx, proposal.ProposalId, proposal.VotingEndTime)

// when proposal become active
keeper.AfterProposalVotingPeriodEnded(ctx, proposal.ProposalId)
Expand Down
Loading

0 comments on commit ae817b9

Please sign in to comment.