cosmos-sdk/x/evidence/keeper/infraction_test.go

126 lines
4.8 KiB
Go

package keeper_test
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/tendermint/tendermint/crypto"
)
func newTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
commission := staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
return staking.NewMsgCreateValidator(
address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt),
staking.Description{}, commission, sdk.OneInt(),
)
}
func (suite *KeeperTestSuite) TestHandleDoubleSign() {
ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1)
suite.populateValidators(ctx)
power := int64(100)
stakingParams := suite.app.StakingKeeper.GetParams(ctx)
selfDelegation := sdk.TokensFromConsensusPower(power)
operatorAddr, val := valAddresses[0], pubkeys[0]
// create validator
res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, selfDelegation))
suite.NoError(err)
suite.NotNil(res)
// execute end-blocker and verify validator attributes
staking.EndBlocker(ctx, suite.app.StakingKeeper)
suite.Equal(
suite.app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)).String(),
sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(selfDelegation))).String(),
)
suite.Equal(selfDelegation, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
// handle a signature to set signing info
suite.app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), selfDelegation.Int64(), true)
// double sign less than max age
oldTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens()
evidence := types.Equivocation{
Height: 0,
Time: time.Unix(0, 0),
Power: power,
ConsensusAddress: sdk.ConsAddress(val.Address()),
}
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
// should be jailed and tombstoned
suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
suite.True(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
// tokens should be decreased
newTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens()
suite.True(newTokens.LT(oldTokens))
// submit duplicate evidence
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
// tokens should be the same (capped slash)
suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
// jump to past the unbonding period
ctx = ctx.WithBlockTime(time.Unix(1, 0).Add(stakingParams.UnbondingTime))
// require we cannot unjail
suite.Error(suite.app.SlashingKeeper.Unjail(ctx, operatorAddr))
// require we be able to unbond now
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
del, _ := suite.app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(operatorAddr), operatorAddr)
validator, _ := suite.app.StakingKeeper.GetValidator(ctx, operatorAddr)
totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt()
msgUnbond := staking.NewMsgUndelegate(sdk.AccAddress(operatorAddr), operatorAddr, sdk.NewCoin(stakingParams.BondDenom, totalBond))
res, err = staking.NewHandler(suite.app.StakingKeeper)(ctx, msgUnbond)
suite.NoError(err)
suite.NotNil(res)
}
func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() {
ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1).WithBlockTime(time.Now())
suite.populateValidators(ctx)
power := int64(100)
stakingParams := suite.app.StakingKeeper.GetParams(ctx)
amt := sdk.TokensFromConsensusPower(power)
operatorAddr, val := valAddresses[0], pubkeys[0]
// create validator
res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt))
suite.NoError(err)
suite.NotNil(res)
// execute end-blocker and verify validator attributes
staking.EndBlocker(ctx, suite.app.StakingKeeper)
suite.Equal(
suite.app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)),
sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))),
)
suite.Equal(amt, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
evidence := types.Equivocation{
Height: 0,
Time: ctx.BlockTime(),
Power: power,
ConsensusAddress: sdk.ConsAddress(val.Address()),
}
cp := suite.app.BaseApp.GetConsensusParams(ctx)
ctx = ctx.WithConsensusParams(cp)
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(cp.Evidence.MaxAgeDuration + 1))
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + cp.Evidence.MaxAgeNumBlocks + 1)
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
suite.False(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
suite.False(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
}