Merge pull request #1859: slashing to governance for non-voting validators

* added slashing to governance non voting

* minor formatting
This commit is contained in:
Sunny Aggarwal 2018-07-29 22:11:21 -07:00 committed by Rigel
parent 53d30aff88
commit 7fc2ed61d7
5 changed files with 62 additions and 5 deletions

View File

@ -37,6 +37,7 @@ FEATURES
* This allows SDK users to initialize a new project repository.
* [tests] Remotenet commands for AWS (awsnet)
* [store] Add transient store
* [gov] Add slashing for validators who do not vote on a proposal
IMPROVEMENTS
* [baseapp] Allow any alphanumeric character in route

View File

@ -146,9 +146,8 @@ func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) ab
// application updates every end block
// nolint: unparam
func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
tags := gov.EndBlocker(ctx, app.govKeeper)
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
tags, _ := gov.EndBlocker(ctx, app.govKeeper)
return abci.ResponseEndBlock{
ValidatorUpdates: validatorUpdates,

View File

@ -6,6 +6,7 @@ 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"
)
@ -166,3 +167,49 @@ func TestTickPassedVotingPeriod(t *testing.T) {
depositsIterator.Close()
require.Equal(t, StatusRejected, keeper.GetProposal(ctx, proposalID).GetStatus())
}
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)
createValidators(t, stakeHandler, ctx, addrs[:3], []int64{25, 6, 7})
initTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
val0Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[0]).GetPower().Quo(initTotalPower)
val1Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[1]).GetPower().Quo(initTotalPower)
val2Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[2]).GetPower().Quo(initTotalPower)
newProposalMsg := NewMsgSubmitProposal("Test", "test", ProposalTypeText, addrs[0], sdk.Coins{sdk.NewCoin("steak", 15)})
res := govHandler(ctx, newProposalMsg)
require.True(t, res.IsOK())
var proposalID int64
keeper.cdc.UnmarshalBinaryBare(res.Data, &proposalID)
ctx = ctx.WithBlockHeight(10)
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)
ctx = ctx.WithBlockHeight(215)
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, proposalID).GetStatus())
EndBlocker(ctx, keeper)
endTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
val0End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[0]).GetPower().Quo(endTotalPower)
val1End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[1]).GetPower().Quo(endTotalPower)
val2End := keeper.ds.GetValidatorSet().Validator(ctx, 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

@ -94,7 +94,7 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {
}
// Called every block, process inflation, update validator set
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals []sdk.AccAddress) {
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
resTags = sdk.NewTags()
@ -112,6 +112,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals
}
var passes bool
var nonVotingVals []sdk.AccAddress
// Check if earliest Active Proposal ended voting period yet
for shouldPopActiveProposalQueue(ctx, keeper) {
@ -137,11 +138,20 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals
}
keeper.SetProposal(ctx, activeProposal)
for _, valAddr := range nonVotingVals {
val := keeper.ds.GetValidatorSet().Validator(ctx, valAddr)
keeper.ds.GetValidatorSet().Slash(ctx,
val.GetPubKey(),
ctx.BlockHeight(),
val.GetPower().RoundInt64(),
keeper.GetTallyingProcedure(ctx).GovernancePenalty)
}
resTags.AppendTag(tags.Action, action)
resTags.AppendTag(tags.ProposalID, proposalIDBytes)
}
return resTags, nonVotingVals
return resTags
}
func shouldPopInactiveProposalQueue(ctx sdk.Context, keeper Keeper) bool {
depositProcedure := keeper.GetDepositProcedure(ctx)

View File

@ -50,7 +50,7 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
// gov and stake endblocker
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
tags, _ := EndBlocker(ctx, keeper)
tags := EndBlocker(ctx, keeper)
return abci.ResponseEndBlock{
Tags: tags,
}