github.com/cosmos/cosmos-sdk@v0.50.10/x/staking/keeper/validator_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"time"
     5  
     6  	abci "github.com/cometbft/cometbft/abci/types"
     7  	"github.com/golang/mock/gomock"
     8  
     9  	"cosmossdk.io/math"
    10  
    11  	sdk "github.com/cosmos/cosmos-sdk/types"
    12  	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    13  	"github.com/cosmos/cosmos-sdk/x/staking/testutil"
    14  	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    15  )
    16  
    17  func (s *KeeperTestSuite) applyValidatorSetUpdates(ctx sdk.Context, keeper *stakingkeeper.Keeper, expectedUpdatesLen int) []abci.ValidatorUpdate {
    18  	updates, err := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
    19  	s.Require().NoError(err)
    20  	if expectedUpdatesLen >= 0 {
    21  		s.Require().Equal(expectedUpdatesLen, len(updates), "%v", updates)
    22  	}
    23  	return updates
    24  }
    25  
    26  func (s *KeeperTestSuite) TestValidator() {
    27  	ctx, keeper := s.ctx, s.stakingKeeper
    28  	require := s.Require()
    29  
    30  	valPubKey := PKs[0]
    31  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
    32  	valTokens := keeper.TokensFromConsensusPower(ctx, 10)
    33  
    34  	// test how the validator is set from a purely unbonbed pool
    35  	validator := testutil.NewValidator(s.T(), valAddr, valPubKey)
    36  	validator, _ = validator.AddTokensFromDel(valTokens)
    37  	require.Equal(stakingtypes.Unbonded, validator.Status)
    38  	require.Equal(valTokens, validator.Tokens)
    39  	require.Equal(valTokens, validator.DelegatorShares.RoundInt())
    40  	require.NoError(keeper.SetValidator(ctx, validator))
    41  	require.NoError(keeper.SetValidatorByPowerIndex(ctx, validator))
    42  	require.NoError(keeper.SetValidatorByConsAddr(ctx, validator))
    43  
    44  	// ensure update
    45  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
    46  	updates := s.applyValidatorSetUpdates(ctx, keeper, 1)
    47  	validator, err := keeper.GetValidator(ctx, valAddr)
    48  	require.NoError(err)
    49  	require.Equal(validator.ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
    50  
    51  	// after the save the validator should be bonded
    52  	require.Equal(stakingtypes.Bonded, validator.Status)
    53  	require.Equal(valTokens, validator.Tokens)
    54  	require.Equal(valTokens, validator.DelegatorShares.RoundInt())
    55  
    56  	// check each store for being saved
    57  	consAddr, err := validator.GetConsAddr()
    58  	require.NoError(err)
    59  	resVal, err := keeper.GetValidatorByConsAddr(ctx, consAddr)
    60  	require.NoError(err)
    61  	require.True(validator.MinEqual(&resVal))
    62  
    63  	resVals, err := keeper.GetLastValidators(ctx)
    64  	require.NoError(err)
    65  	require.Equal(1, len(resVals))
    66  	require.True(validator.MinEqual(&resVals[0]))
    67  
    68  	resVals, err = keeper.GetBondedValidatorsByPower(ctx)
    69  	require.NoError(err)
    70  	require.Equal(1, len(resVals))
    71  	require.True(validator.MinEqual(&resVals[0]))
    72  
    73  	allVals, err := keeper.GetAllValidators(ctx)
    74  	require.NoError(err)
    75  	require.Equal(1, len(allVals))
    76  
    77  	// check the last validator power
    78  	power := int64(100)
    79  	require.NoError(keeper.SetLastValidatorPower(ctx, valAddr, power))
    80  	resPower, err := keeper.GetLastValidatorPower(ctx, valAddr)
    81  	require.NoError(err)
    82  	require.Equal(power, resPower)
    83  	require.NoError(keeper.DeleteLastValidatorPower(ctx, valAddr))
    84  	resPower, err = keeper.GetLastValidatorPower(ctx, valAddr)
    85  	require.NoError(err)
    86  	require.Equal(int64(0), resPower)
    87  }
    88  
    89  // This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator
    90  func (s *KeeperTestSuite) TestValidatorBasics() {
    91  	ctx, keeper := s.ctx, s.stakingKeeper
    92  	require := s.Require()
    93  
    94  	// construct the validators
    95  	var validators [3]stakingtypes.Validator
    96  	powers := []int64{9, 8, 7}
    97  	for i, power := range powers {
    98  		validators[i] = testutil.NewValidator(s.T(), sdk.ValAddress(PKs[i].Address().Bytes()), PKs[i])
    99  		validators[i].Status = stakingtypes.Unbonded
   100  		validators[i].Tokens = math.ZeroInt()
   101  		tokens := keeper.TokensFromConsensusPower(ctx, power)
   102  
   103  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   104  	}
   105  
   106  	require.Equal(keeper.TokensFromConsensusPower(ctx, 9), validators[0].Tokens)
   107  	require.Equal(keeper.TokensFromConsensusPower(ctx, 8), validators[1].Tokens)
   108  	require.Equal(keeper.TokensFromConsensusPower(ctx, 7), validators[2].Tokens)
   109  
   110  	// check the empty keeper first
   111  	_, err := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
   112  	require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
   113  	resVals, err := keeper.GetLastValidators(ctx)
   114  	require.NoError(err)
   115  	require.Zero(len(resVals))
   116  
   117  	resVals, err = keeper.GetValidators(ctx, 2)
   118  	require.NoError(err)
   119  	require.Len(resVals, 0)
   120  
   121  	// set and retrieve a record
   122  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   123  	validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], true)
   124  	require.NoError(keeper.SetValidatorByConsAddr(ctx, validators[0]))
   125  	resVal, err := keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
   126  	require.NoError(err)
   127  	require.True(validators[0].MinEqual(&resVal))
   128  
   129  	// retrieve from consensus
   130  	resVal, err = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address()))
   131  	require.NoError(err)
   132  	require.True(validators[0].MinEqual(&resVal))
   133  	resVal, err = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
   134  	require.NoError(err)
   135  	require.True(validators[0].MinEqual(&resVal))
   136  
   137  	resVals, err = keeper.GetLastValidators(ctx)
   138  	require.NoError(err)
   139  	require.Equal(1, len(resVals))
   140  	require.True(validators[0].MinEqual(&resVals[0]))
   141  	require.Equal(stakingtypes.Bonded, validators[0].Status)
   142  	require.True(keeper.TokensFromConsensusPower(ctx, 9).Equal(validators[0].BondedTokens()))
   143  
   144  	// modify a records, save, and retrieve
   145  	validators[0].Status = stakingtypes.Bonded
   146  	validators[0].Tokens = keeper.TokensFromConsensusPower(ctx, 10)
   147  	validators[0].DelegatorShares = math.LegacyNewDecFromInt(validators[0].Tokens)
   148  	validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], true)
   149  	resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[0].Address().Bytes()))
   150  	require.NoError(err)
   151  	require.True(validators[0].MinEqual(&resVal))
   152  
   153  	resVals, err = keeper.GetLastValidators(ctx)
   154  	require.NoError(err)
   155  	require.Equal(1, len(resVals))
   156  	require.True(validators[0].MinEqual(&resVals[0]))
   157  
   158  	// add other validators
   159  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   160  	validators[1] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[1], true)
   161  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   162  	validators[2] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[2], true)
   163  	resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
   164  	require.NoError(err)
   165  	require.True(validators[1].MinEqual(&resVal))
   166  	resVal, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[2].Address().Bytes()))
   167  	require.NoError(err)
   168  	require.True(validators[2].MinEqual(&resVal))
   169  
   170  	resVals, err = keeper.GetLastValidators(ctx)
   171  	require.NoError(err)
   172  	require.Equal(3, len(resVals))
   173  
   174  	// remove a record
   175  
   176  	bz, err := keeper.ValidatorAddressCodec().StringToBytes(validators[1].GetOperator())
   177  	require.NoError(err)
   178  
   179  	// shouldn't be able to remove if status is not unbonded
   180  	require.EqualError(keeper.RemoveValidator(ctx, bz), "cannot call RemoveValidator on bonded or unbonding validators: failed to remove validator")
   181  
   182  	// shouldn't be able to remove if there are still tokens left
   183  	validators[1].Status = stakingtypes.Unbonded
   184  	require.NoError(keeper.SetValidator(ctx, validators[1]))
   185  	require.EqualError(keeper.RemoveValidator(ctx, bz), "attempting to remove a validator which still contains tokens: failed to remove validator")
   186  
   187  	validators[1].Tokens = math.ZeroInt()                    // ...remove all tokens
   188  	require.NoError(keeper.SetValidator(ctx, validators[1])) // ...set the validator
   189  	require.NoError(keeper.RemoveValidator(ctx, bz))         // Now it can be removed.
   190  	_, err = keeper.GetValidator(ctx, sdk.ValAddress(PKs[1].Address().Bytes()))
   191  	require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
   192  }
   193  
   194  func (s *KeeperTestSuite) TestUpdateValidatorByPowerIndex() {
   195  	ctx, keeper := s.ctx, s.stakingKeeper
   196  	require := s.Require()
   197  
   198  	valPubKey := PKs[0]
   199  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   200  	valTokens := keeper.TokensFromConsensusPower(ctx, 100)
   201  
   202  	// add a validator
   203  	validator := testutil.NewValidator(s.T(), valAddr, PKs[0])
   204  	validator, delSharesCreated := validator.AddTokensFromDel(valTokens)
   205  	require.Equal(stakingtypes.Unbonded, validator.Status)
   206  	require.Equal(valTokens, validator.Tokens)
   207  
   208  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   209  	stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true)
   210  	validator, err := keeper.GetValidator(ctx, valAddr)
   211  	require.NoError(err)
   212  	require.Equal(valTokens, validator.Tokens)
   213  
   214  	power := stakingtypes.GetValidatorsByPowerIndexKey(validator, keeper.PowerReduction(ctx), keeper.ValidatorAddressCodec())
   215  	require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
   216  
   217  	// burn half the delegator shares
   218  	require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
   219  	validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(math.LegacyNewDec(2)))
   220  	require.Equal(keeper.TokensFromConsensusPower(ctx, 50), burned)
   221  	stakingkeeper.TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out
   222  	require.False(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
   223  
   224  	validator, err = keeper.GetValidator(ctx, valAddr)
   225  	require.NoError(err)
   226  
   227  	power = stakingtypes.GetValidatorsByPowerIndexKey(validator, keeper.PowerReduction(ctx), keeper.ValidatorAddressCodec())
   228  	require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
   229  
   230  	// set new validator by power index
   231  	require.NoError(keeper.DeleteValidatorByPowerIndex(ctx, validator))
   232  	require.False(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
   233  	require.NoError(keeper.SetNewValidatorByPowerIndex(ctx, validator))
   234  	require.True(stakingkeeper.ValidatorByPowerIndexExists(ctx, keeper, power))
   235  }
   236  
   237  func (s *KeeperTestSuite) TestApplyAndReturnValidatorSetUpdatesPowerDecrease() {
   238  	ctx, keeper := s.ctx, s.stakingKeeper
   239  	require := s.Require()
   240  
   241  	powers := []int64{100, 100}
   242  	var validators [2]stakingtypes.Validator
   243  
   244  	for i, power := range powers {
   245  		validators[i] = testutil.NewValidator(s.T(), sdk.ValAddress(PKs[i].Address().Bytes()), PKs[i])
   246  		tokens := keeper.TokensFromConsensusPower(ctx, power)
   247  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   248  
   249  	}
   250  
   251  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   252  	validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], false)
   253  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   254  	validators[1] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[1], false)
   255  	s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.NotBondedPoolName, stakingtypes.BondedPoolName, gomock.Any())
   256  	s.applyValidatorSetUpdates(ctx, keeper, 2)
   257  
   258  	// check initial power
   259  	require.Equal(int64(100), validators[0].GetConsensusPower(keeper.PowerReduction(ctx)))
   260  	require.Equal(int64(100), validators[1].GetConsensusPower(keeper.PowerReduction(ctx)))
   261  
   262  	// test multiple value change
   263  	// tendermintUpdate set: {c1, c3} -> {c1', c3'}
   264  	delTokens1 := keeper.TokensFromConsensusPower(ctx, 20)
   265  	delTokens2 := keeper.TokensFromConsensusPower(ctx, 30)
   266  	validators[0], _ = validators[0].RemoveDelShares(math.LegacyNewDecFromInt(delTokens1))
   267  	validators[1], _ = validators[1].RemoveDelShares(math.LegacyNewDecFromInt(delTokens2))
   268  	validators[0] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[0], false)
   269  	validators[1] = stakingkeeper.TestingUpdateValidator(keeper, ctx, validators[1], false)
   270  
   271  	// power has changed
   272  	require.Equal(int64(80), validators[0].GetConsensusPower(keeper.PowerReduction(ctx)))
   273  	require.Equal(int64(70), validators[1].GetConsensusPower(keeper.PowerReduction(ctx)))
   274  
   275  	// CometBFT updates should reflect power change
   276  	updates := s.applyValidatorSetUpdates(ctx, keeper, 2)
   277  	require.Equal(validators[0].ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
   278  	require.Equal(validators[1].ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[1])
   279  }
   280  
   281  func (s *KeeperTestSuite) TestUpdateValidatorCommission() {
   282  	ctx, keeper := s.ctx, s.stakingKeeper
   283  	require := s.Require()
   284  
   285  	// Set MinCommissionRate to 0.05
   286  	params, err := keeper.GetParams(ctx)
   287  	require.NoError(err)
   288  	params.MinCommissionRate = math.LegacyNewDecWithPrec(5, 2)
   289  	require.NoError(keeper.SetParams(ctx, params))
   290  
   291  	commission1 := stakingtypes.NewCommissionWithTime(
   292  		math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(3, 1),
   293  		math.LegacyNewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour),
   294  	)
   295  	commission2 := stakingtypes.NewCommission(math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(3, 1), math.LegacyNewDecWithPrec(1, 1))
   296  
   297  	val1 := testutil.NewValidator(s.T(), sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
   298  	val2 := testutil.NewValidator(s.T(), sdk.ValAddress(PKs[1].Address().Bytes()), PKs[1])
   299  
   300  	val1, _ = val1.SetInitialCommission(commission1)
   301  	val2, _ = val2.SetInitialCommission(commission2)
   302  
   303  	require.NoError(keeper.SetValidator(ctx, val1))
   304  	require.NoError(keeper.SetValidator(ctx, val2))
   305  
   306  	testCases := []struct {
   307  		validator   stakingtypes.Validator
   308  		newRate     math.LegacyDec
   309  		expectedErr bool
   310  	}{
   311  		{val1, math.LegacyZeroDec(), true},
   312  		{val2, math.LegacyNewDecWithPrec(-1, 1), true},
   313  		{val2, math.LegacyNewDecWithPrec(4, 1), true},
   314  		{val2, math.LegacyNewDecWithPrec(3, 1), true},
   315  		{val2, math.LegacyNewDecWithPrec(1, 2), true},
   316  		{val2, math.LegacyNewDecWithPrec(2, 1), false},
   317  	}
   318  
   319  	for i, tc := range testCases {
   320  		commission, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate)
   321  
   322  		if tc.expectedErr {
   323  			require.Error(err, "expected error for test case #%d with rate: %s", i, tc.newRate)
   324  		} else {
   325  			require.NoError(err,
   326  				"unexpected error for test case #%d with rate: %s", i, tc.newRate,
   327  			)
   328  
   329  			tc.validator.Commission = commission
   330  			err = keeper.SetValidator(ctx, tc.validator)
   331  			require.NoError(err)
   332  
   333  			bz, err := keeper.ValidatorAddressCodec().StringToBytes(tc.validator.GetOperator())
   334  			require.NoError(err)
   335  
   336  			val, err := keeper.GetValidator(ctx, bz)
   337  			require.NoError(err,
   338  				"expected to find validator for test case #%d with rate: %s", i, tc.newRate,
   339  			)
   340  
   341  			require.Equal(tc.newRate, val.Commission.Rate,
   342  				"expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate,
   343  			)
   344  			require.Equal(ctx.BlockHeader().Time, val.Commission.UpdateTime,
   345  				"expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate,
   346  			)
   347  		}
   348  	}
   349  }
   350  
   351  func (s *KeeperTestSuite) TestValidatorToken() {
   352  	ctx, keeper := s.ctx, s.stakingKeeper
   353  	require := s.Require()
   354  
   355  	valPubKey := PKs[0]
   356  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   357  	addTokens := keeper.TokensFromConsensusPower(ctx, 10)
   358  	delTokens := keeper.TokensFromConsensusPower(ctx, 5)
   359  
   360  	validator := testutil.NewValidator(s.T(), valAddr, valPubKey)
   361  	validator, _, err := keeper.AddValidatorTokensAndShares(ctx, validator, addTokens)
   362  	require.NoError(err)
   363  	require.Equal(addTokens, validator.Tokens)
   364  	validator, _ = keeper.GetValidator(ctx, valAddr)
   365  	require.Equal(math.LegacyNewDecFromInt(addTokens), validator.DelegatorShares)
   366  
   367  	_, _, err = keeper.RemoveValidatorTokensAndShares(ctx, validator, math.LegacyNewDecFromInt(delTokens))
   368  	require.NoError(err)
   369  	validator, _ = keeper.GetValidator(ctx, valAddr)
   370  	require.Equal(delTokens, validator.Tokens)
   371  	require.True(validator.DelegatorShares.Equal(math.LegacyNewDecFromInt(delTokens)))
   372  
   373  	_, err = keeper.RemoveValidatorTokens(ctx, validator, delTokens)
   374  	require.NoError(err)
   375  	validator, _ = keeper.GetValidator(ctx, valAddr)
   376  	require.True(validator.Tokens.IsZero())
   377  }
   378  
   379  func (s *KeeperTestSuite) TestUnbondingValidator() {
   380  	ctx, keeper := s.ctx, s.stakingKeeper
   381  	require := s.Require()
   382  
   383  	valPubKey := PKs[0]
   384  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   385  	validator := testutil.NewValidator(s.T(), valAddr, valPubKey)
   386  	addTokens := keeper.TokensFromConsensusPower(ctx, 10)
   387  
   388  	// set unbonding validator
   389  	endTime := time.Now()
   390  	endHeight := ctx.BlockHeight() + 10
   391  	require.NoError(keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()}))
   392  
   393  	resVals, err := keeper.GetUnbondingValidators(ctx, endTime, endHeight)
   394  	require.NoError(err)
   395  	require.Equal(1, len(resVals))
   396  	require.Equal(valAddr.String(), resVals[0])
   397  
   398  	// add another unbonding validator
   399  	valAddr1 := sdk.ValAddress(PKs[1].Address().Bytes())
   400  	validator1 := testutil.NewValidator(s.T(), valAddr1, PKs[1])
   401  	validator1.UnbondingHeight = endHeight
   402  	validator1.UnbondingTime = endTime
   403  	require.NoError(keeper.InsertUnbondingValidatorQueue(ctx, validator1))
   404  
   405  	resVals, err = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
   406  	require.NoError(err)
   407  	require.Equal(2, len(resVals))
   408  
   409  	// delete unbonding validator from the queue
   410  	require.NoError(keeper.DeleteValidatorQueue(ctx, validator1))
   411  	resVals, err = keeper.GetUnbondingValidators(ctx, endTime, endHeight)
   412  	require.NoError(err)
   413  	require.Equal(1, len(resVals))
   414  	require.Equal(valAddr.String(), resVals[0])
   415  
   416  	// check unbonding mature validators
   417  	ctx = ctx.WithBlockHeight(endHeight).WithBlockTime(endTime)
   418  	err = keeper.UnbondAllMatureValidators(ctx)
   419  	require.EqualError(err, "validator in the unbonding queue was not found: validator does not exist")
   420  
   421  	require.NoError(keeper.SetValidator(ctx, validator))
   422  	ctx = ctx.WithBlockHeight(endHeight).WithBlockTime(endTime)
   423  
   424  	err = keeper.UnbondAllMatureValidators(ctx)
   425  	require.EqualError(err, "unexpected validator in unbonding queue; status was not unbonding")
   426  
   427  	validator.Status = stakingtypes.Unbonding
   428  	require.NoError(keeper.SetValidator(ctx, validator))
   429  	require.NoError(keeper.UnbondAllMatureValidators(ctx))
   430  	validator, err = keeper.GetValidator(ctx, valAddr)
   431  	require.ErrorIs(err, stakingtypes.ErrNoValidatorFound)
   432  
   433  	require.NoError(keeper.SetUnbondingValidatorsQueue(ctx, endTime, endHeight, []string{valAddr.String()}))
   434  	validator = testutil.NewValidator(s.T(), valAddr, valPubKey)
   435  	validator, _ = validator.AddTokensFromDel(addTokens)
   436  	validator.Status = stakingtypes.Unbonding
   437  	require.NoError(keeper.SetValidator(ctx, validator))
   438  	require.NoError(keeper.UnbondAllMatureValidators(ctx))
   439  	validator, err = keeper.GetValidator(ctx, valAddr)
   440  	require.NoError(err)
   441  	require.Equal(stakingtypes.Unbonded, validator.Status)
   442  }