Merge PR #2395: Remove governance slashing

This commit is contained in:
Sunny Aggarwal 2018-09-25 11:45:20 -07:00 committed by Christopher Goes
parent a04d5cf26d
commit 15e848e43c
7 changed files with 25 additions and 109 deletions

View File

@ -36,6 +36,7 @@ BREAKING CHANGES
* `cosmosvaladdr` / `cosmosvalpub` => `cosmosvaloper` / `cosmosvaloperpub`
* [x/stake] [#1013] TendermintUpdates now uses transient store
* [x/gov] [#2195] Governance uses BFT Time
* [x/gov] \#2256 Removed slashing for governance non-voting validators
* SDK
* [core] [\#1807](https://github.com/cosmos/cosmos-sdk/issues/1807) Switch from use of rational to decimal

View File

@ -28,7 +28,6 @@ type TallyingProcedure struct {
Threshold sdk.Dec // Minimum propotion 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
GracePeriod time.Time // If validator entered validator set in this period of blocks before vote ended, governance penalty does not apply
}
```
@ -192,14 +191,10 @@ And the pseudocode for the `ProposalProcessingQueue`:
tallyingProcedure = load(GlobalParams, 'TallyingProcedure')
// Slash validators that did not vote, or update tally if they voted
// Update tally if validator voted they voted
for each validator in validators
if (validator.bondTime < CurrentTime - tallyingProcedure.GracePeriod)
// only slash if validator entered validator set before grace period
if (!tmpValMap(validator).HasVoted)
slash validator by tallyingProcedure.GovernancePenalty
else
proposal.updateTally(tmpValMap(validator).Vote, (validator.TotalShares - tmpValMap(validator).Minus))
if tmpValMap(validator).HasVoted
proposal.updateTally(tmpValMap(validator).Vote, (validator.TotalShares - tmpValMap(validator).Minus))

View File

@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/stake"
abci "github.com/tendermint/tendermint/abci/types"
)
@ -194,62 +193,3 @@ func TestTickPassedVotingPeriod(t *testing.T) {
require.Equal(t, StatusRejected, keeper.GetProposal(ctx, proposalID).GetStatus())
require.True(t, keeper.GetProposal(ctx, proposalID).GetTallyResult().Equals(EmptyTallyResult()))
}
func TestSlashing(t *testing.T) {
mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10)
SortAddresses(addrs)
mapp.BeginBlock(abci.RequestBeginBlock{})
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
govHandler := NewHandler(keeper)
stakeHandler := stake.NewHandler(sk)
valAddrs := make([]sdk.ValAddress, len(addrs[:3]))
for i, addr := range addrs[:3] {
valAddrs[i] = sdk.ValAddress(addr)
}
createValidators(t, stakeHandler, ctx, valAddrs, []int64{25, 6, 7})
initTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
val0Initial := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[0])).GetPower().Quo(initTotalPower)
val1Initial := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[1])).GetPower().Quo(initTotalPower)
val2Initial := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[2])).GetPower().Quo(initTotalPower)
newProposalMsg := NewMsgSubmitProposal("Test", "test", ProposalTypeText, addrs[0], sdk.Coins{sdk.NewInt64Coin("steak", 15)})
res := govHandler(ctx, newProposalMsg)
require.True(t, res.IsOK())
var proposalID int64
keeper.cdc.UnmarshalBinaryBare(res.Data, &proposalID)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, proposalID).GetStatus())
newVoteMsg := NewMsgVote(addrs[0], proposalID, OptionYes)
res = govHandler(ctx, newVoteMsg)
require.True(t, res.IsOK())
EndBlocker(ctx, keeper)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(keeper.GetDepositProcedure(ctx).MaxDepositPeriod).Add(keeper.GetDepositProcedure(ctx).MaxDepositPeriod)
ctx = ctx.WithBlockHeader(newHeader)
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, proposalID).GetStatus())
EndBlocker(ctx, keeper)
require.False(t, keeper.GetProposal(ctx, proposalID).GetTallyResult().Equals(EmptyTallyResult()))
endTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
val0End := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[0])).GetPower().Quo(endTotalPower)
val1End := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[1])).GetPower().Quo(endTotalPower)
val2End := keeper.ds.GetValidatorSet().Validator(ctx, sdk.ValAddress(addrs[2])).GetPower().Quo(endTotalPower)
require.True(t, val0End.GTE(val0Initial))
require.True(t, val1End.LT(val1Initial))
require.True(t, val2End.LT(val2Initial))
}

View File

@ -134,7 +134,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
continue
}
passes, tallyResults, nonVotingVals := tally(ctx, keeper, activeProposal)
passes, tallyResults := tally(ctx, keeper, activeProposal)
proposalIDBytes := keeper.cdc.MustMarshalBinaryBare(activeProposal.GetProposalID())
var action []byte
if passes {
@ -152,18 +152,6 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
logger.Info(fmt.Sprintf("proposal %d (%s) tallied; passed: %v",
activeProposal.GetProposalID(), activeProposal.GetTitle(), passes))
for _, valAddr := range nonVotingVals {
val := keeper.ds.GetValidatorSet().Validator(ctx, valAddr)
keeper.ds.GetValidatorSet().Slash(ctx,
val.GetConsAddr(),
ctx.BlockHeight(),
val.GetPower().RoundInt64(),
keeper.GetTallyingProcedure(ctx).GovernancePenalty)
logger.Info(fmt.Sprintf("validator %s failed to vote on proposal %d; slashing",
val.GetOperator(), activeProposal.GetProposalID()))
}
resTags.AppendTag(tags.Action, action)
resTags.AppendTag(tags.ProposalID, proposalIDBytes)
}

View File

@ -220,7 +220,7 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke
} else if proposal.GetStatus() == StatusPassed || proposal.GetStatus() == StatusRejected {
tallyResult = proposal.GetTallyResult()
} else {
_, tallyResult, _ = tally(ctx, keeper, proposal)
_, tallyResult = tally(ctx, keeper, proposal)
}
bz, err2 := codec.MarshalJSONIndent(keeper.cdc, tallyResult)

View File

@ -13,7 +13,7 @@ type validatorGovInfo struct {
Vote VoteOption // Vote of the validator
}
func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tallyResults TallyResult, nonVoting []sdk.ValAddress) {
func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tallyResults TallyResult) {
results := make(map[VoteOption]sdk.Dec)
results[OptionYes] = sdk.ZeroDec()
results[OptionAbstain] = sdk.ZeroDec()
@ -70,12 +70,9 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
keeper.deleteVote(ctx, vote.ProposalID, vote.Voter)
}
// iterate over the validators again to tally their voting power and see
// who didn't vote
nonVoting = []sdk.ValAddress{}
// iterate over the validators again to tally their voting power
for _, val := range currValidators {
if val.Vote == OptionEmpty {
nonVoting = append(nonVoting, val.Address)
continue
}
@ -98,19 +95,17 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
// If no one votes, proposal fails
if totalVotingPower.Sub(results[OptionAbstain]).Equal(sdk.ZeroDec()) {
return false, tallyResults, nonVoting
return false, tallyResults
}
// If more than 1/3 of voters veto, proposal fails
if results[OptionNoWithVeto].Quo(totalVotingPower).GT(tallyingProcedure.Veto) {
return false, tallyResults, nonVoting
return false, tallyResults
}
// If more than 1/2 of non-abstaining voters vote Yes, proposal passes
if results[OptionYes].Quo(totalVotingPower.Sub(results[OptionAbstain])).GT(tallyingProcedure.Threshold) {
return true, tallyResults, nonVoting
return true, tallyResults
}
// If more than 1/2 of non-abstaining voters vote No, proposal fails
SortValAddresses(nonVoting)
return false, tallyResults, nonVoting
return false, tallyResults
}

View File

@ -51,7 +51,7 @@ func TestTallyNoOneVotes(t *testing.T) {
proposal.SetStatus(StatusVotingPeriod)
keeper.SetProposal(ctx, proposal)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.True(t, tallyResults.Equals(EmptyTallyResult()))
@ -80,7 +80,7 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -109,7 +109,7 @@ func TestTallyOnlyValidators51No(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
require.Nil(t, err)
passes, _, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
}
@ -139,7 +139,7 @@ func TestTallyOnlyValidators51Yes(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -170,7 +170,7 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNoWithVeto)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -201,7 +201,7 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -232,7 +232,7 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -261,11 +261,9 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)
passes, tallyResults, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.Equal(t, 1, len(nonVoting))
require.Equal(t, sdk.ValAddress(addrs[0]), nonVoting[0])
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}
@ -299,7 +297,7 @@ func TestTallyDelgatorOverride(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -333,10 +331,9 @@ func TestTallyDelgatorInherit(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
require.Nil(t, err)
passes, tallyResults, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.True(t, passes)
require.Equal(t, 0, len(nonVoting))
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}
@ -372,7 +369,7 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -417,7 +414,7 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
@ -458,7 +455,7 @@ func TestTallyJailedValidator(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))