Merge pull request #1859: slashing to governance for non-voting validators
* added slashing to governance non voting * minor formatting
This commit is contained in:
parent
53d30aff88
commit
7fc2ed61d7
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue