github.com/Finschia/finschia-sdk@v0.48.1/x/evidence/keeper/infraction_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"time"
     5  
     6  	sdk "github.com/Finschia/finschia-sdk/types"
     7  	"github.com/Finschia/finschia-sdk/x/evidence/types"
     8  	"github.com/Finschia/finschia-sdk/x/staking"
     9  	"github.com/Finschia/finschia-sdk/x/staking/teststaking"
    10  )
    11  
    12  func (suite *KeeperTestSuite) TestHandleDoubleSign() {
    13  	ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1)
    14  	suite.populateValidators(ctx)
    15  
    16  	power := int64(100)
    17  	stakingParams := suite.app.StakingKeeper.GetParams(ctx)
    18  	operatorAddr, val := valAddresses[0], pubkeys[0]
    19  	tstaking := teststaking.NewHelper(suite.T(), ctx, suite.app.StakingKeeper)
    20  
    21  	selfDelegation := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true)
    22  
    23  	// execute end-blocker and verify validator attributes
    24  	staking.EndBlocker(ctx, suite.app.StakingKeeper)
    25  	suite.Equal(
    26  		suite.app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)).String(),
    27  		sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(selfDelegation))).String(),
    28  	)
    29  	suite.Equal(selfDelegation, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
    30  
    31  	// handle a signature to set signing info
    32  	suite.app.SlashingKeeper.HandleValidatorSignature(ctx, val.Address(), selfDelegation.Int64(), true)
    33  
    34  	// double sign less than max age
    35  	oldTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens()
    36  	evidence := &types.Equivocation{
    37  		Height:           0,
    38  		Time:             time.Unix(0, 0),
    39  		Power:            power,
    40  		ConsensusAddress: sdk.ConsAddress(val.Address()).String(),
    41  	}
    42  	suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)
    43  
    44  	// should be jailed and tombstoned
    45  	suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
    46  	suite.True(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
    47  
    48  	// tokens should be decreased
    49  	newTokens := suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens()
    50  	suite.True(newTokens.LT(oldTokens))
    51  
    52  	// submit duplicate evidence
    53  	suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)
    54  
    55  	// tokens should be the same (capped slash)
    56  	suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
    57  
    58  	// jump to past the unbonding period
    59  	ctx = ctx.WithBlockTime(time.Unix(1, 0).Add(stakingParams.UnbondingTime))
    60  
    61  	// require we cannot unjail
    62  	suite.Error(suite.app.SlashingKeeper.Unjail(ctx, operatorAddr))
    63  
    64  	// require we be able to unbond now
    65  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
    66  	del, _ := suite.app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(operatorAddr), operatorAddr)
    67  	validator, _ := suite.app.StakingKeeper.GetValidator(ctx, operatorAddr)
    68  	totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt()
    69  	tstaking.Ctx = ctx
    70  	tstaking.Denom = stakingParams.BondDenom
    71  	tstaking.Undelegate(sdk.AccAddress(operatorAddr), operatorAddr, totalBond, true)
    72  
    73  	// query evidence from store
    74  	evidences := suite.app.EvidenceKeeper.GetAllEvidence(ctx)
    75  	suite.Len(evidences, 1)
    76  }
    77  
    78  func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() {
    79  	ctx := suite.ctx.WithIsCheckTx(false).WithBlockHeight(1).WithBlockTime(time.Now())
    80  	suite.populateValidators(ctx)
    81  
    82  	power := int64(100)
    83  	stakingParams := suite.app.StakingKeeper.GetParams(ctx)
    84  	operatorAddr, val := valAddresses[0], pubkeys[0]
    85  	tstaking := teststaking.NewHelper(suite.T(), ctx, suite.app.StakingKeeper)
    86  
    87  	amt := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true)
    88  
    89  	// execute end-blocker and verify validator attributes
    90  	staking.EndBlocker(ctx, suite.app.StakingKeeper)
    91  	suite.Equal(
    92  		suite.app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)),
    93  		sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))),
    94  	)
    95  	suite.Equal(amt, suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
    96  
    97  	evidence := &types.Equivocation{
    98  		Height:           0,
    99  		Time:             ctx.BlockTime(),
   100  		Power:            power,
   101  		ConsensusAddress: sdk.ConsAddress(val.Address()).String(),
   102  	}
   103  
   104  	cp := suite.app.BaseApp.GetConsensusParams(ctx)
   105  
   106  	ctx = ctx.WithConsensusParams(cp)
   107  	ctx = ctx.WithBlockTime(ctx.BlockTime().Add(cp.Evidence.MaxAgeDuration + 1))
   108  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + cp.Evidence.MaxAgeNumBlocks + 1)
   109  	suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)
   110  
   111  	suite.False(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
   112  	suite.False(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
   113  }