Skip to content

Commit 7fc2ed6

Browse files
sunnya97rigelrozanski
authored andcommitted
Merge pull request #1859: slashing to governance for non-voting validators
* added slashing to governance non voting * minor formatting
1 parent 53d30af commit 7fc2ed6

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

PENDING.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ FEATURES
3737
* This allows SDK users to initialize a new project repository.
3838
* [tests] Remotenet commands for AWS (awsnet)
3939
* [store] Add transient store
40+
* [gov] Add slashing for validators who do not vote on a proposal
4041

4142
IMPROVEMENTS
4243
* [baseapp] Allow any alphanumeric character in route

cmd/gaia/app/app.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,8 @@ func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) ab
146146
// application updates every end block
147147
// nolint: unparam
148148
func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
149-
149+
tags := gov.EndBlocker(ctx, app.govKeeper)
150150
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
151-
tags, _ := gov.EndBlocker(ctx, app.govKeeper)
152151

153152
return abci.ResponseEndBlock{
154153
ValidatorUpdates: validatorUpdates,

x/gov/endblocker_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/stretchr/testify/require"
77

88
sdk "github.com/cosmos/cosmos-sdk/types"
9+
"github.com/cosmos/cosmos-sdk/x/stake"
910
abci "github.com/tendermint/tendermint/abci/types"
1011
)
1112

@@ -166,3 +167,49 @@ func TestTickPassedVotingPeriod(t *testing.T) {
166167
depositsIterator.Close()
167168
require.Equal(t, StatusRejected, keeper.GetProposal(ctx, proposalID).GetStatus())
168169
}
170+
171+
func TestSlashing(t *testing.T) {
172+
mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10)
173+
SortAddresses(addrs)
174+
mapp.BeginBlock(abci.RequestBeginBlock{})
175+
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
176+
govHandler := NewHandler(keeper)
177+
stakeHandler := stake.NewHandler(sk)
178+
179+
createValidators(t, stakeHandler, ctx, addrs[:3], []int64{25, 6, 7})
180+
181+
initTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
182+
val0Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[0]).GetPower().Quo(initTotalPower)
183+
val1Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[1]).GetPower().Quo(initTotalPower)
184+
val2Initial := keeper.ds.GetValidatorSet().Validator(ctx, addrs[2]).GetPower().Quo(initTotalPower)
185+
186+
newProposalMsg := NewMsgSubmitProposal("Test", "test", ProposalTypeText, addrs[0], sdk.Coins{sdk.NewCoin("steak", 15)})
187+
188+
res := govHandler(ctx, newProposalMsg)
189+
require.True(t, res.IsOK())
190+
var proposalID int64
191+
keeper.cdc.UnmarshalBinaryBare(res.Data, &proposalID)
192+
193+
ctx = ctx.WithBlockHeight(10)
194+
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, proposalID).GetStatus())
195+
196+
newVoteMsg := NewMsgVote(addrs[0], proposalID, OptionYes)
197+
res = govHandler(ctx, newVoteMsg)
198+
require.True(t, res.IsOK())
199+
200+
EndBlocker(ctx, keeper)
201+
202+
ctx = ctx.WithBlockHeight(215)
203+
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, proposalID).GetStatus())
204+
205+
EndBlocker(ctx, keeper)
206+
207+
endTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
208+
val0End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[0]).GetPower().Quo(endTotalPower)
209+
val1End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[1]).GetPower().Quo(endTotalPower)
210+
val2End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[2]).GetPower().Quo(endTotalPower)
211+
212+
require.True(t, val0End.GTE(val0Initial))
213+
require.True(t, val1End.LT(val1Initial))
214+
require.True(t, val2End.LT(val2Initial))
215+
}

x/gov/handler.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {
9494
}
9595

9696
// Called every block, process inflation, update validator set
97-
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals []sdk.AccAddress) {
97+
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
9898

9999
resTags = sdk.NewTags()
100100

@@ -112,6 +112,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals
112112
}
113113

114114
var passes bool
115+
var nonVotingVals []sdk.AccAddress
115116

116117
// Check if earliest Active Proposal ended voting period yet
117118
for shouldPopActiveProposalQueue(ctx, keeper) {
@@ -137,11 +138,20 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags, nonVotingVals
137138
}
138139
keeper.SetProposal(ctx, activeProposal)
139140

141+
for _, valAddr := range nonVotingVals {
142+
val := keeper.ds.GetValidatorSet().Validator(ctx, valAddr)
143+
keeper.ds.GetValidatorSet().Slash(ctx,
144+
val.GetPubKey(),
145+
ctx.BlockHeight(),
146+
val.GetPower().RoundInt64(),
147+
keeper.GetTallyingProcedure(ctx).GovernancePenalty)
148+
}
149+
140150
resTags.AppendTag(tags.Action, action)
141151
resTags.AppendTag(tags.ProposalID, proposalIDBytes)
142152
}
143153

144-
return resTags, nonVotingVals
154+
return resTags
145155
}
146156
func shouldPopInactiveProposalQueue(ctx sdk.Context, keeper Keeper) bool {
147157
depositProcedure := keeper.GetDepositProcedure(ctx)

x/gov/test_common.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
5050
// gov and stake endblocker
5151
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
5252
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
53-
tags, _ := EndBlocker(ctx, keeper)
53+
tags := EndBlocker(ctx, keeper)
5454
return abci.ResponseEndBlock{
5555
Tags: tags,
5656
}

0 commit comments

Comments
 (0)