Skip to content

Commit

Permalink
feat: expedited proposals (#2)
Browse files Browse the repository at this point in the history
* feat: expedited proposals

h/t osmosis-labs#240

* fix: correctly generate random threshold params

* fix: update randomised genesis state tests
  • Loading branch information
johnletey authored Jun 18, 2022
1 parent 379239e commit 08a6bbc
Show file tree
Hide file tree
Showing 53 changed files with 1,129 additions and 412 deletions.
4 changes: 4 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5110,6 +5110,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 @@ -5144,6 +5145,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 @@ -5214,6 +5216,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) | | expedited_voting_period defines the length of the expedited voting period. |



Expand Down Expand Up @@ -5647,6 +5650,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: 17 additions & 0 deletions 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 @@ -173,6 +174,14 @@ message VotingParams {

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

// expedited_voting_period defines the 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 +209,14 @@ 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
12 changes: 10 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 @@ -321,7 +322,12 @@ Where proposal.json contains:
}
content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, recpAddr, amount)

msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from)
isExpedited, err := cmd.Flags().GetBool(FlagIsExpedited)
if err != nil {
return err
}

msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from, isExpedited)
if err != nil {
return err
}
Expand All @@ -330,5 +336,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 08a6bbc

Please sign in to comment.