Governance Quorum (#3053)
This commit is contained in:
parent
133134ca52
commit
945803d586
|
@ -31,6 +31,7 @@ FEATURES
|
|||
- [\#2961](https://github.com/cosmos/cosmos-sdk/issues/2961) Add --force flag to gaiacli keys delete command to skip passphrase check and force key deletion unconditionally.
|
||||
|
||||
* Gaia
|
||||
- [gov] Added minimum quorum needed for vote to pass
|
||||
|
||||
* SDK
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ func run(rootDir string) {
|
|||
_ = proxyApp.Stop()
|
||||
}()
|
||||
|
||||
var state tmsm.State = tmsm.LoadState(tmDB)
|
||||
state := tmsm.LoadState(tmDB)
|
||||
if state.LastBlockHeight == 0 {
|
||||
// Send InitChain msg
|
||||
fmt.Println("Sending InitChain msg")
|
||||
|
|
|
@ -111,10 +111,6 @@ option that casts a `NoWithVeto` vote.*
|
|||
Quorum is defined as the minimum percentage of voting power that needs to be
|
||||
casted on a proposal for the result to be valid.
|
||||
|
||||
In the initial version of the governance module, there will be no quorum
|
||||
enforced by the protocol. Participation is ensured via the combination of
|
||||
inheritance and validator's punishment for non-voting.
|
||||
|
||||
### Threshold
|
||||
|
||||
Threshold is defined as the minimum proportion of `Yes` votes (excluding
|
||||
|
|
|
@ -24,6 +24,7 @@ type VotingParams struct {
|
|||
|
||||
```go
|
||||
type TallyParams struct {
|
||||
Quorum sdk.Dec // Minimum percentage of stake that needs to vote for a proposal to be considered valid
|
||||
Threshold sdk.Dec // Minimum proportion of Yes votes for proposal to pass. Initial value: 0.5
|
||||
Veto sdk.Dec // Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
|
||||
GovernancePenalty sdk.Dec // Penalty if validator does not vote
|
||||
|
|
|
@ -51,6 +51,7 @@ func DefaultGenesisState() GenesisState {
|
|||
VotingPeriod: time.Duration(172800) * time.Second,
|
||||
},
|
||||
TallyParams: TallyParams{
|
||||
Quorum: sdk.NewDecWithPrec(334, 3),
|
||||
Threshold: sdk.NewDecWithPrec(5, 1),
|
||||
Veto: sdk.NewDecWithPrec(334, 3),
|
||||
GovernancePenalty: sdk.NewDecWithPrec(1, 2),
|
||||
|
|
|
@ -14,6 +14,7 @@ type DepositParams struct {
|
|||
|
||||
// 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
|
||||
Veto sdk.Dec `json:"veto"` // Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
|
||||
GovernancePenalty sdk.Dec `json:"governance_penalty"` // Penalty if validator does not vote
|
||||
|
|
|
@ -93,7 +93,15 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
|
|||
NoWithVeto: results[OptionNoWithVeto],
|
||||
}
|
||||
|
||||
// If no one votes, proposal fails
|
||||
// If there is no staked coins, the proposal fails
|
||||
if keeper.vs.TotalPower(ctx).Equal(sdk.ZeroDec()) {
|
||||
return false, tallyResults
|
||||
}
|
||||
// If there is not enough quorum of votes, the proposal fails
|
||||
if totalVotingPower.Quo(keeper.vs.TotalPower(ctx)).LT(tallyParams.Quorum) {
|
||||
return false, tallyResults
|
||||
}
|
||||
// If no one votes (everyone abstains), proposal fails
|
||||
if totalVotingPower.Sub(results[OptionAbstain]).Equal(sdk.ZeroDec()) {
|
||||
return false, tallyResults
|
||||
}
|
||||
|
|
|
@ -59,6 +59,32 @@ func TestTallyNoOneVotes(t *testing.T) {
|
|||
require.True(t, tallyResults.Equals(EmptyTallyResult()))
|
||||
}
|
||||
|
||||
func TestTallyNoQuorum(t *testing.T) {
|
||||
mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10)
|
||||
mapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||
stakeHandler := stake.NewHandler(sk)
|
||||
|
||||
valAddrs := make([]sdk.ValAddress, len(addrs[:2]))
|
||||
for i, addr := range addrs[:2] {
|
||||
valAddrs[i] = sdk.ValAddress(addr)
|
||||
}
|
||||
|
||||
createValidators(t, stakeHandler, ctx, valAddrs, []int64{2, 5})
|
||||
stake.EndBlocker(ctx, sk)
|
||||
|
||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
||||
proposalID := proposal.GetProposalID()
|
||||
proposal.SetStatus(StatusVotingPeriod)
|
||||
keeper.SetProposal(ctx, proposal)
|
||||
|
||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||
require.Nil(t, err)
|
||||
|
||||
passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
||||
require.False(t, passes)
|
||||
}
|
||||
|
||||
func TestTallyOnlyValidatorsAllYes(t *testing.T) {
|
||||
mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10)
|
||||
mapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
|
Loading…
Reference in New Issue