github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/evidence/internal/keeper/infraction_test.go (about) 1 package keeper_test 2 3 import ( 4 "time" 5 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/evidence/internal/types" 8 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking" 9 10 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 11 ) 12 13 func newTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator { 14 commission := staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) 15 return staking.NewMsgCreateValidator( 16 address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt), 17 staking.Description{}, commission, sdk.OneInt(), 18 ) 19 } 20 21 func (suite *KeeperTestSuite) TestHandleDoubleSign() { 22 ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1) 23 suite.populateValidators(ctx) 24 25 power := int64(100) 26 stakingParams := suite.app.StakingKeeper.GetParams(ctx) 27 amt := sdk.TokensFromConsensusPower(power) 28 operatorAddr, val := valAddresses[0], pubkeys[0] 29 30 // create validator 31 res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) 32 suite.NoError(err) 33 suite.NotNil(res) 34 35 // execute end-blocker and verify validator attributes 36 staking.EndBlocker(ctx, suite.app.StakingKeeper) 37 suite.Equal( 38 suite.app.BankKeeper.GetCoins(ctx, sdk.AccAddress(operatorAddr)), 39 sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))), 40 ) 41 suite.Equal(amt, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens()) 42 43 // handle a signature to set signing info 44 suite.app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true) 45 46 // double sign less than max age 47 oldTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens() 48 evidence := types.Equivocation{ 49 Height: 0, 50 Time: time.Unix(0, 0), 51 Power: power, 52 ConsensusAddress: sdk.ConsAddress(val.Address()), 53 } 54 suite.keeper.HandleDoubleSign(ctx, evidence) 55 56 // should be jailed and tombstoned 57 suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed()) 58 suite.True(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address()))) 59 60 // tokens should be decreased 61 newTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens() 62 suite.True(newTokens.LT(oldTokens)) 63 64 // submit duplicate evidence 65 suite.keeper.HandleDoubleSign(ctx, evidence) 66 67 // tokens should be the same (capped slash) 68 suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens)) 69 70 // jump to past the unbonding period 71 ctx.SetBlockTime(time.Unix(1, 0).Add(stakingParams.UnbondingTime)) 72 73 // require we cannot unjail 74 suite.Error(suite.app.SlashingKeeper.Unjail(ctx, operatorAddr)) 75 76 // require we be able to unbond now 77 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 78 del, _ := suite.app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(operatorAddr), operatorAddr) 79 validator, _ := suite.app.StakingKeeper.GetValidator(ctx, operatorAddr) 80 totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt() 81 msgUnbond := staking.NewMsgUndelegate(sdk.AccAddress(operatorAddr), operatorAddr, sdk.NewCoin(stakingParams.BondDenom, totalBond)) 82 res, err = staking.NewHandler(suite.app.StakingKeeper)(ctx, msgUnbond) 83 suite.NoError(err) 84 suite.NotNil(res) 85 } 86 87 func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() { 88 ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1).WithBlockTime(time.Now()) 89 suite.populateValidators(ctx) 90 91 power := int64(100) 92 stakingParams := suite.app.StakingKeeper.GetParams(ctx) 93 amt := sdk.TokensFromConsensusPower(power) 94 operatorAddr, val := valAddresses[0], pubkeys[0] 95 96 // create validator 97 res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) 98 suite.NoError(err) 99 suite.NotNil(res) 100 101 // execute end-blocker and verify validator attributes 102 staking.EndBlocker(ctx, suite.app.StakingKeeper) 103 suite.Equal( 104 suite.app.BankKeeper.GetCoins(ctx, sdk.AccAddress(operatorAddr)), 105 sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))), 106 ) 107 suite.Equal(amt, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens()) 108 109 evidence := types.Equivocation{ 110 Height: 0, 111 Time: ctx.BlockTime(), 112 Power: power, 113 ConsensusAddress: sdk.ConsAddress(val.Address()), 114 } 115 ctx.SetBlockTime(ctx.BlockTime().Add(suite.app.EvidenceKeeper.MaxEvidenceAge(ctx) + 1)) 116 suite.keeper.HandleDoubleSign(ctx, evidence) 117 118 suite.False(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed()) 119 suite.False(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address()))) 120 }