Governance Quorum (#3053)

This commit is contained in:
Sunny Aggarwal 2018-12-10 18:50:20 +08:00 committed by Jae Kwon
parent 133134ca52
commit 945803d586
8 changed files with 40 additions and 6 deletions

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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
}

View File

@ -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{})