diff --git a/tests/integration/slashing/keeper/keeper_test.go b/tests/integration/slashing/keeper/keeper_test.go index 574f1358f78e..ba833207c61d 100644 --- a/tests/integration/slashing/keeper/keeper_test.go +++ b/tests/integration/slashing/keeper/keeper_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "gotest.tools/v3/assert" "github.com/cosmos/cosmos-sdk/baseapp" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -27,9 +27,7 @@ import ( // The default power validators are initialized to have within tests var InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) -type KeeperTestSuite struct { - suite.Suite - +type fixture struct { ctx sdk.Context slashingKeeper slashingkeeper.Keeper stakingKeeper *stakingkeeper.Keeper @@ -41,52 +39,58 @@ type KeeperTestSuite struct { msgServer slashingtypes.MsgServer } -func (s *KeeperTestSuite) SetupTest() { +func initFixture(t assert.TestingT) *fixture { + f := &fixture{} app, err := simtestutil.Setup( testutil.AppConfig, - &s.bankKeeper, - &s.accountKeeper, - &s.slashingKeeper, - &s.stakingKeeper, - &s.interfaceRegistry, + &f.bankKeeper, + &f.accountKeeper, + &f.slashingKeeper, + &f.stakingKeeper, + &f.interfaceRegistry, ) - s.Require().NoError(err) + assert.NilError(t, err) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) // TestParams set the SignedBlocksWindow to 1000 and MaxMissedBlocksPerWindow to 500 - s.slashingKeeper.SetParams(ctx, testutil.TestParams()) - addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 5, s.stakingKeeper.TokensFromConsensusPower(ctx, 200)) + f.slashingKeeper.SetParams(ctx, testutil.TestParams()) + addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, ctx, 5, f.stakingKeeper.TokensFromConsensusPower(ctx, 200)) info1 := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[0]), int64(4), int64(3), time.Unix(2, 0), false, int64(10)) info2 := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addrDels[1]), int64(5), int64(4), time.Unix(2, 0), false, int64(10)) - s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1) - s.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2) + f.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[0]), info1) + f.slashingKeeper.SetValidatorSigningInfo(ctx, sdk.ConsAddress(addrDels[1]), info2) - queryHelper := baseapp.NewQueryServerTestHelper(ctx, s.interfaceRegistry) - slashingtypes.RegisterQueryServer(queryHelper, s.slashingKeeper) + queryHelper := baseapp.NewQueryServerTestHelper(ctx, f.interfaceRegistry) + slashingtypes.RegisterQueryServer(queryHelper, f.slashingKeeper) queryClient := slashingtypes.NewQueryClient(queryHelper) - s.queryClient = queryClient + f.queryClient = queryClient + + f.addrDels = addrDels + f.ctx = ctx + f.msgServer = slashingkeeper.NewMsgServerImpl(f.slashingKeeper) - s.addrDels = addrDels - s.ctx = ctx - s.msgServer = slashingkeeper.NewMsgServerImpl(s.slashingKeeper) + return f } -func (s *KeeperTestSuite) TestUnJailNotBonded() { - ctx := s.ctx +func TestUnJailNotBonded(t *testing.T) { + t.Parallel() + f := initFixture(t) - p := s.stakingKeeper.GetParams(ctx) + ctx := f.ctx + + p := f.stakingKeeper.GetParams(ctx) p.MaxValidators = 5 - s.stakingKeeper.SetParams(ctx, p) + f.stakingKeeper.SetParams(ctx, p) - addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 6, s.stakingKeeper.TokensFromConsensusPower(ctx, 200)) + addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, ctx, 6, f.stakingKeeper.TokensFromConsensusPower(ctx, 200)) valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels) pks := simtestutil.CreateTestPubKeys(6) - tstaking := stakingtestutil.NewHelper(s.T(), ctx, s.stakingKeeper) + tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper) // create max (5) validators all with the same power for i := uint32(0); i < p.MaxValidators; i++ { @@ -94,46 +98,46 @@ func (s *KeeperTestSuite) TestUnJailNotBonded() { tstaking.CreateValidatorWithValPower(addr, val, 100, true) } - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // create a 6th validator with less power than the cliff validator (won't be bonded) addr, val := valAddrs[5], pks[5] - amt := s.stakingKeeper.TokensFromConsensusPower(ctx, 50) + amt := f.stakingKeeper.TokensFromConsensusPower(ctx, 50) msg := tstaking.CreateValidatorMsg(addr, val, amt) msg.MinSelfDelegation = amt res, err := tstaking.CreateValidatorWithMsg(ctx, msg) - s.Require().NoError(err) - s.Require().NotNil(res) + assert.NilError(t, err) + assert.Assert(t, res != nil) - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) tstaking.CheckValidator(addr, stakingtypes.Unbonded, false) // unbond below minimum self-delegation - s.Require().Equal(p.BondDenom, tstaking.Denom) - tstaking.Undelegate(sdk.AccAddress(addr), addr, s.stakingKeeper.TokensFromConsensusPower(ctx, 1), true) + assert.Equal(t, p.BondDenom, tstaking.Denom) + tstaking.Undelegate(sdk.AccAddress(addr), addr, f.stakingKeeper.TokensFromConsensusPower(ctx, 1), true) - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // verify that validator is jailed tstaking.CheckValidator(addr, -1, true) // verify we cannot unjail (yet) - s.Require().Error(s.slashingKeeper.Unjail(ctx, addr)) + assert.ErrorContains(t, f.slashingKeeper.Unjail(ctx, addr), "cannot be unjailed") - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // bond to meet minimum self-delegation tstaking.DelegateWithPower(sdk.AccAddress(addr), addr, 1) - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) // verify we can immediately unjail - s.Require().NoError(s.slashingKeeper.Unjail(ctx, addr)) + assert.NilError(t, f.slashingKeeper.Unjail(ctx, addr)) tstaking.CheckValidator(addr, -1, false) } @@ -141,133 +145,142 @@ func (s *KeeperTestSuite) TestUnJailNotBonded() { // Test a new validator entering the validator set // Ensure that SigningInfo.StartHeight is set correctly // and that they are not immediately jailed -func (s *KeeperTestSuite) TestHandleNewValidator() { - ctx := s.ctx +func TestHandleNewValidator(t *testing.T) { + t.Parallel() + f := initFixture(t) + + ctx := f.ctx - addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 0)) + addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, ctx, 1, f.stakingKeeper.TokensFromConsensusPower(ctx, 0)) valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels) pks := simtestutil.CreateTestPubKeys(1) addr, val := valAddrs[0], pks[0] - tstaking := stakingtestutil.NewHelper(s.T(), ctx, s.stakingKeeper) - ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 1) + tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper) + ctx = ctx.WithBlockHeight(f.slashingKeeper.SignedBlocksWindow(ctx) + 1) // Validator created amt := tstaking.CreateValidatorWithValPower(addr, val, 100, true) - staking.EndBlocker(ctx, s.stakingKeeper) - s.Require().Equal( - s.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)), - sdk.NewCoins(sdk.NewCoin(s.stakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))), + staking.EndBlocker(ctx, f.stakingKeeper) + assert.DeepEqual( + t, f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)), + sdk.NewCoins(sdk.NewCoin(f.stakingKeeper.GetParams(ctx).BondDenom, InitTokens.Sub(amt))), ) - s.Require().Equal(amt, s.stakingKeeper.Validator(ctx, addr).GetBondedTokens()) + assert.DeepEqual(t, amt, f.stakingKeeper.Validator(ctx, addr).GetBondedTokens()) // Now a validator, for two blocks - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, true) - ctx = ctx.WithBlockHeight(s.slashingKeeper.SignedBlocksWindow(ctx) + 2) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, true) + ctx = ctx.WithBlockHeight(f.slashingKeeper.SignedBlocksWindow(ctx) + 2) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), 100, false) - info, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) - s.Require().True(found) - s.Require().Equal(s.slashingKeeper.SignedBlocksWindow(ctx)+1, info.StartHeight) - s.Require().Equal(int64(2), info.IndexOffset) - s.Require().Equal(int64(1), info.MissedBlocksCounter) - s.Require().Equal(time.Unix(0, 0).UTC(), info.JailedUntil) + info, found := f.slashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) + assert.Assert(t, found) + assert.Equal(t, f.slashingKeeper.SignedBlocksWindow(ctx)+1, info.StartHeight) + assert.Equal(t, int64(2), info.IndexOffset) + assert.Equal(t, int64(1), info.MissedBlocksCounter) + assert.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil) // validator should be bonded still, should not have been jailed or slashed - validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - s.Require().Equal(stakingtypes.Bonded, validator.GetStatus()) - bondPool := s.stakingKeeper.GetBondedPool(ctx) - expTokens := s.stakingKeeper.TokensFromConsensusPower(ctx, 100) + validator, _ := f.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) + assert.Equal(t, stakingtypes.Bonded, validator.GetStatus()) + bondPool := f.stakingKeeper.GetBondedPool(ctx) + expTokens := f.stakingKeeper.TokensFromConsensusPower(ctx, 100) // adding genesis validator tokens - expTokens = expTokens.Add(s.stakingKeeper.TokensFromConsensusPower(ctx, 1)) - s.Require().True(expTokens.Equal(s.bankKeeper.GetBalance(ctx, bondPool.GetAddress(), s.stakingKeeper.BondDenom(ctx)).Amount)) + expTokens = expTokens.Add(f.stakingKeeper.TokensFromConsensusPower(ctx, 1)) + assert.Assert(t, expTokens.Equal(f.bankKeeper.GetBalance(ctx, bondPool.GetAddress(), f.stakingKeeper.BondDenom(ctx)).Amount)) } // Test a jailed validator being "down" twice // Ensure that they're only slashed once -func (s *KeeperTestSuite) TestHandleAlreadyJailed() { +func TestHandleAlreadyJailed(t *testing.T) { + t.Parallel() + f := initFixture(t) + // initial setup - ctx := s.ctx + ctx := f.ctx - addrDels := simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 1, s.stakingKeeper.TokensFromConsensusPower(ctx, 200)) + addrDels := simtestutil.AddTestAddrsIncremental(f.bankKeeper, f.stakingKeeper, ctx, 1, f.stakingKeeper.TokensFromConsensusPower(ctx, 200)) valAddrs := simtestutil.ConvertAddrsToValAddrs(addrDels) pks := simtestutil.CreateTestPubKeys(1) addr, val := valAddrs[0], pks[0] power := int64(100) - tstaking := stakingtestutil.NewHelper(s.T(), ctx, s.stakingKeeper) + tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper) amt := tstaking.CreateValidatorWithValPower(addr, val, power, true) - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) // 1000 first blocks OK height := int64(0) - for ; height < s.slashingKeeper.SignedBlocksWindow(ctx); height++ { + for ; height < f.slashingKeeper.SignedBlocksWindow(ctx); height++ { ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true) } // 501 blocks missed - for ; height < s.slashingKeeper.SignedBlocksWindow(ctx)+(s.slashingKeeper.SignedBlocksWindow(ctx)-s.slashingKeeper.MinSignedPerWindow(ctx))+1; height++ { + for ; height < f.slashingKeeper.SignedBlocksWindow(ctx)+(f.slashingKeeper.SignedBlocksWindow(ctx)-f.slashingKeeper.MinSignedPerWindow(ctx))+1; height++ { ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false) } // end block - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) // validator should have been jailed and slashed - validator, _ := s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - s.Require().Equal(stakingtypes.Unbonding, validator.GetStatus()) + validator, _ := f.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) + assert.Equal(t, stakingtypes.Unbonding, validator.GetStatus()) // validator should have been slashed - resultingTokens := amt.Sub(s.stakingKeeper.TokensFromConsensusPower(ctx, 1)) - s.Require().Equal(resultingTokens, validator.GetTokens()) + resultingTokens := amt.Sub(f.stakingKeeper.TokensFromConsensusPower(ctx, 1)) + assert.DeepEqual(t, resultingTokens, validator.GetTokens()) // another block missed ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, false) // validator should not have been slashed twice - validator, _ = s.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - s.Require().Equal(resultingTokens, validator.GetTokens()) + validator, _ = f.stakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) + assert.DeepEqual(t, resultingTokens, validator.GetTokens()) } // Test a validator dipping in and out of the validator set // Ensure that missed blocks are tracked correctly and that // the start height of the signing info is reset correctly -func (s *KeeperTestSuite) TestValidatorDippingInAndOut() { +func TestValidatorDippingInAndOut(t *testing.T) { + t.Parallel() + f := initFixture(t) + // initial setup - ctx := s.ctx - params := s.stakingKeeper.GetParams(ctx) + ctx := f.ctx + params := f.stakingKeeper.GetParams(ctx) params.MaxValidators = 1 - s.stakingKeeper.SetParams(ctx, params) + f.stakingKeeper.SetParams(ctx, params) power := int64(100) pks := simtestutil.CreateTestPubKeys(3) - simtestutil.AddTestAddrsFromPubKeys(s.bankKeeper, s.stakingKeeper, ctx, pks, s.stakingKeeper.TokensFromConsensusPower(ctx, 200)) + simtestutil.AddTestAddrsFromPubKeys(f.bankKeeper, f.stakingKeeper, ctx, pks, f.stakingKeeper.TokensFromConsensusPower(ctx, 200)) addr, val := pks[0].Address(), pks[0] consAddr := sdk.ConsAddress(addr) - tstaking := stakingtestutil.NewHelper(s.T(), ctx, s.stakingKeeper) + tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper) valAddr := sdk.ValAddress(addr) tstaking.CreateValidatorWithValPower(valAddr, val, power, true) - validatorUpdates := staking.EndBlocker(ctx, s.stakingKeeper) - s.Require().Equal(2, len(validatorUpdates)) + validatorUpdates := staking.EndBlocker(ctx, f.stakingKeeper) + assert.Equal(t, 2, len(validatorUpdates)) tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false) // 100 first blocks OK height := int64(0) for ; height < int64(100); height++ { ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), power, true) } // kick first validator out of validator set tstaking.CreateValidatorWithValPower(sdk.ValAddress(pks[1].Address()), pks[1], power+1, true) - validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper) - s.Require().Equal(2, len(validatorUpdates)) + validatorUpdates = staking.EndBlocker(ctx, f.stakingKeeper) + assert.Equal(t, 2, len(validatorUpdates)) tstaking.CheckValidator(sdk.ValAddress(pks[1].Address()), stakingtypes.Bonded, false) tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, false) @@ -278,68 +291,64 @@ func (s *KeeperTestSuite) TestValidatorDippingInAndOut() { // validator added back in tstaking.DelegateWithPower(sdk.AccAddress(pks[2].Address()), valAddr, 50) - validatorUpdates = staking.EndBlocker(ctx, s.stakingKeeper) - s.Require().Equal(2, len(validatorUpdates)) + validatorUpdates = staking.EndBlocker(ctx, f.stakingKeeper) + assert.Equal(t, 2, len(validatorUpdates)) tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false) newPower := power + 50 // validator misses a block - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) height++ // shouldn't be jailed/kicked yet tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false) // validator misses an additional 500 more blocks within the SignedBlockWindow (here 1000 blocks). - latest := s.slashingKeeper.SignedBlocksWindow(ctx) + height + latest := f.slashingKeeper.SignedBlocksWindow(ctx) + height // misses 500 blocks + within the signing windows i.e. 700-1700 // validators misses all 1000 block of a SignedBlockWindows for ; height < latest+1; height++ { ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) } // should now be jailed & kicked - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true) // check all the signing information - signInfo, found := s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) - s.Require().True(found) - s.Require().Equal(int64(700), signInfo.StartHeight) - s.Require().Equal(int64(0), signInfo.MissedBlocksCounter) - s.Require().Equal(int64(0), signInfo.IndexOffset) + signInfo, found := f.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) + assert.Assert(t, found) + assert.Equal(t, int64(700), signInfo.StartHeight) + assert.Equal(t, int64(0), signInfo.MissedBlocksCounter) + assert.Equal(t, int64(0), signInfo.IndexOffset) // some blocks pass height = int64(5000) ctx = ctx.WithBlockHeight(height) // validator rejoins and starts signing again - s.stakingKeeper.Unjail(ctx, consAddr) + f.stakingKeeper.Unjail(ctx, consAddr) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, true) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, true) // validator should not be kicked since we reset counter/array when it was jailed - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) tstaking.CheckValidator(valAddr, stakingtypes.Bonded, false) // check start height is correctly set - signInfo, found = s.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) - s.Require().True(found) - s.Require().Equal(height, signInfo.StartHeight) + signInfo, found = f.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) + assert.Assert(t, found) + assert.Equal(t, height, signInfo.StartHeight) // validator misses 501 blocks after SignedBlockWindow period (1000 blocks) - latest = s.slashingKeeper.SignedBlocksWindow(ctx) + height - for ; height < latest+s.slashingKeeper.MinSignedPerWindow(ctx); height++ { + latest = f.slashingKeeper.SignedBlocksWindow(ctx) + height + for ; height < latest+f.slashingKeeper.MinSignedPerWindow(ctx); height++ { ctx = ctx.WithBlockHeight(height) - s.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) + f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), newPower, false) } // validator should now be jailed & kicked - staking.EndBlocker(ctx, s.stakingKeeper) + staking.EndBlocker(ctx, f.stakingKeeper) tstaking.CheckValidator(valAddr, stakingtypes.Unbonding, true) } - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -}