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  }