Merge PR #2395: Remove governance slashing
This commit is contained in:
parent
a04d5cf26d
commit
15e848e43c
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
|
|
Loading…
Reference in New Issue