github.com/Finschia/finschia-sdk@v0.49.1/x/staking/keeper/validator_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  	abci "github.com/tendermint/tendermint/abci/types"
    11  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    12  
    13  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
    14  	"github.com/Finschia/finschia-sdk/simapp"
    15  	sdk "github.com/Finschia/finschia-sdk/types"
    16  	"github.com/Finschia/finschia-sdk/x/staking/keeper"
    17  	"github.com/Finschia/finschia-sdk/x/staking/teststaking"
    18  	"github.com/Finschia/finschia-sdk/x/staking/types"
    19  )
    20  
    21  func newMonikerValidator(tb testing.TB, operator sdk.ValAddress, pubKey cryptotypes.PubKey, moniker string) types.Validator {
    22  	tb.Helper()
    23  	v, err := types.NewValidator(operator, pubKey, types.Description{Moniker: moniker})
    24  	require.NoError(tb, err)
    25  	return v
    26  }
    27  
    28  func bootstrapValidatorTest(tb testing.TB, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
    29  	tb.Helper()
    30  	_, app, ctx := createTestInput()
    31  
    32  	addrDels, addrVals := generateAddresses(app, ctx, numAddrs)
    33  
    34  	amt := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
    35  	totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
    36  
    37  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
    38  	// set bonded pool supply
    39  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
    40  
    41  	require.NoError(tb, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), totalSupply))
    42  
    43  	return app, ctx, addrDels, addrVals
    44  }
    45  
    46  func initValidators(tb testing.TB, power int64, numAddrs int, powers []int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
    47  	tb.Helper()
    48  	app, ctx, addrs, valAddrs := bootstrapValidatorTest(tb, power, numAddrs)
    49  	pks := simapp.CreateTestPubKeys(numAddrs)
    50  
    51  	vs := make([]types.Validator, len(powers))
    52  	for i, power := range powers {
    53  		vs[i] = teststaking.NewValidator(tb, sdk.ValAddress(addrs[i]), pks[i])
    54  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
    55  		vs[i], _ = vs[i].AddTokensFromDel(tokens)
    56  	}
    57  	return app, ctx, addrs, valAddrs, vs
    58  }
    59  
    60  func TestSetValidator(t *testing.T) {
    61  	app, ctx, _, _ := bootstrapValidatorTest(t, 10, 100)
    62  
    63  	valPubKey := PKs[0]
    64  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
    65  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
    66  
    67  	// test how the validator is set from a purely unbonbed pool
    68  	validator := teststaking.NewValidator(t, valAddr, valPubKey)
    69  	validator, _ = validator.AddTokensFromDel(valTokens)
    70  	require.Equal(t, types.Unbonded, validator.Status)
    71  	assert.Equal(t, valTokens, validator.Tokens)
    72  	assert.Equal(t, valTokens, validator.DelegatorShares.RoundInt())
    73  	app.StakingKeeper.SetValidator(ctx, validator)
    74  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator)
    75  
    76  	// ensure update
    77  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
    78  	validator, found := app.StakingKeeper.GetValidator(ctx, valAddr)
    79  	require.True(t, found)
    80  	require.Equal(t, validator.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
    81  
    82  	// after the save the validator should be bonded
    83  	require.Equal(t, types.Bonded, validator.Status)
    84  	assert.Equal(t, valTokens, validator.Tokens)
    85  	assert.Equal(t, valTokens, validator.DelegatorShares.RoundInt())
    86  
    87  	// Check each store for being saved
    88  	resVal, found := app.StakingKeeper.GetValidator(ctx, valAddr)
    89  	assert.True(ValEq(t, validator, resVal))
    90  	require.True(t, found)
    91  
    92  	resVals := app.StakingKeeper.GetLastValidators(ctx)
    93  	require.Equal(t, 1, len(resVals))
    94  	assert.True(ValEq(t, validator, resVals[0]))
    95  
    96  	resVals = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
    97  	require.Equal(t, 1, len(resVals))
    98  	require.True(ValEq(t, validator, resVals[0]))
    99  
   100  	resVals = app.StakingKeeper.GetValidators(ctx, 1)
   101  	require.Equal(t, 1, len(resVals))
   102  	require.True(ValEq(t, validator, resVals[0]))
   103  
   104  	resVals = app.StakingKeeper.GetValidators(ctx, 10)
   105  	require.Equal(t, 1, len(resVals))
   106  	require.True(ValEq(t, validator, resVals[0]))
   107  
   108  	allVals := app.StakingKeeper.GetAllValidators(ctx)
   109  	require.Equal(t, 1, len(allVals))
   110  }
   111  
   112  func TestUpdateValidatorByPowerIndex(t *testing.T) {
   113  	app, ctx, _, _ := bootstrapValidatorTest(t, 0, 100)
   114  	_, addrVals := generateAddresses(app, ctx, 1)
   115  
   116  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   117  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   118  
   119  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 1234)))))
   120  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 10000)))))
   121  
   122  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   123  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   124  
   125  	// add a validator
   126  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   127  	validator, delSharesCreated := validator.AddTokensFromDel(app.StakingKeeper.TokensFromConsensusPower(ctx, 100))
   128  	require.Equal(t, types.Unbonded, validator.Status)
   129  	require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 100), validator.Tokens)
   130  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   131  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   132  	require.True(t, found)
   133  	require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 100), validator.Tokens)
   134  
   135  	power := types.GetValidatorsByPowerIndexKey(validator, app.StakingKeeper.PowerReduction(ctx))
   136  	require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power))
   137  
   138  	// burn half the delegator shares
   139  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   140  	validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(sdk.NewDec(2)))
   141  	require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 50), burned)
   142  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) // update the validator, possibly kicking it out
   143  	require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power))
   144  
   145  	validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   146  	require.True(t, found)
   147  
   148  	power = types.GetValidatorsByPowerIndexKey(validator, app.StakingKeeper.PowerReduction(ctx))
   149  	require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power))
   150  }
   151  
   152  func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
   153  	numVals := 10
   154  	maxVals := 5
   155  
   156  	// create context, keeper, and pool for tests
   157  	app, ctx, _, valAddrs := bootstrapValidatorTest(t, 0, 100)
   158  
   159  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   160  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   161  
   162  	// create keeper parameters
   163  	params := app.StakingKeeper.GetParams(ctx)
   164  	params.MaxValidators = uint32(maxVals)
   165  	app.StakingKeeper.SetParams(ctx, params)
   166  
   167  	// create a random pool
   168  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 1234)))))
   169  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 10000)))))
   170  
   171  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   172  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   173  
   174  	validators := make([]types.Validator, numVals)
   175  	for i := 0; i < len(validators); i++ {
   176  		moniker := fmt.Sprintf("val#%d", int64(i))
   177  		val := newMonikerValidator(t, valAddrs[i], PKs[i], moniker)
   178  		delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, int64((i+1)*10))
   179  		val, _ = val.AddTokensFromDel(delTokens)
   180  
   181  		val = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, val, true)
   182  		validators[i] = val
   183  	}
   184  
   185  	nextCliffVal := validators[numVals-maxVals+1]
   186  
   187  	// remove enough tokens to kick out the validator below the current cliff
   188  	// validator and next in line cliff validator
   189  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal)
   190  	shares := app.StakingKeeper.TokensFromConsensusPower(ctx, 21)
   191  	nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec())
   192  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, nextCliffVal, true)
   193  
   194  	expectedValStatus := map[int]types.BondStatus{
   195  		9: types.Bonded, 8: types.Bonded, 7: types.Bonded, 5: types.Bonded, 4: types.Bonded,
   196  		0: types.Unbonding, 1: types.Unbonding, 2: types.Unbonding, 3: types.Unbonding, 6: types.Unbonding,
   197  	}
   198  
   199  	// require all the validators have their respective statuses
   200  	for valIdx, status := range expectedValStatus {
   201  		valAddr := validators[valIdx].OperatorAddress
   202  		addr, err := sdk.ValAddressFromBech32(valAddr)
   203  		assert.NoError(t, err)
   204  		val, _ := app.StakingKeeper.GetValidator(ctx, addr)
   205  
   206  		assert.Equal(
   207  			t, status, val.GetStatus(),
   208  			fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status),
   209  		)
   210  	}
   211  }
   212  
   213  func TestSlashToZeroPowerRemoved(t *testing.T) {
   214  	// initialize setup
   215  	app, ctx, _, addrVals := bootstrapValidatorTest(t, 100, 20)
   216  
   217  	// add a validator
   218  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   219  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 100)
   220  
   221  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   222  
   223  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), valTokens))))
   224  
   225  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   226  
   227  	validator, _ = validator.AddTokensFromDel(valTokens)
   228  	require.Equal(t, types.Unbonded, validator.Status)
   229  	require.Equal(t, valTokens, validator.Tokens)
   230  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   231  	require.NoError(t, err)
   232  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   233  	require.Equal(t, valTokens, validator.Tokens, "\nvalidator %v\npool %v", validator, valTokens)
   234  
   235  	// slash the validator by 100%
   236  	app.StakingKeeper.Slash(ctx, sdk.ConsAddress(PKs[0].Address()), 0, 100, sdk.OneDec())
   237  	// apply TM updates
   238  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)
   239  	// validator should be unbonding
   240  	validator, _ = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   241  	require.Equal(t, validator.GetStatus(), types.Unbonding)
   242  }
   243  
   244  // This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator
   245  func TestValidatorBasics(t *testing.T) {
   246  	app, ctx, _, addrVals := bootstrapValidatorTest(t, 1000, 20)
   247  
   248  	// construct the validators
   249  	var validators [3]types.Validator
   250  	powers := []int64{9, 8, 7}
   251  	for i, power := range powers {
   252  		validators[i] = teststaking.NewValidator(t, addrVals[i], PKs[i])
   253  		validators[i].Status = types.Unbonded
   254  		validators[i].Tokens = sdk.ZeroInt()
   255  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   256  
   257  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   258  	}
   259  	assert.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 9), validators[0].Tokens)
   260  	assert.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 8), validators[1].Tokens)
   261  	assert.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 7), validators[2].Tokens)
   262  
   263  	// check the empty keeper first
   264  	_, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   265  	require.False(t, found)
   266  	resVals := app.StakingKeeper.GetLastValidators(ctx)
   267  	require.Zero(t, len(resVals))
   268  
   269  	resVals = app.StakingKeeper.GetValidators(ctx, 2)
   270  	require.Zero(t, len(resVals))
   271  
   272  	// set and retrieve a record
   273  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
   274  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validators[0])
   275  	require.NoError(t, err)
   276  	resVal, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   277  	require.True(t, found)
   278  	assert.True(ValEq(t, validators[0], resVal))
   279  
   280  	// retrieve from consensus
   281  	resVal, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address()))
   282  	require.True(t, found)
   283  	assert.True(ValEq(t, validators[0], resVal))
   284  	resVal, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
   285  	require.True(t, found)
   286  	assert.True(ValEq(t, validators[0], resVal))
   287  
   288  	resVals = app.StakingKeeper.GetLastValidators(ctx)
   289  	require.Equal(t, 1, len(resVals))
   290  	assert.True(ValEq(t, validators[0], resVals[0]))
   291  	assert.Equal(t, types.Bonded, validators[0].Status)
   292  	assert.True(sdk.IntEq(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 9), validators[0].BondedTokens()))
   293  
   294  	// modify a records, save, and retrieve
   295  	validators[0].Status = types.Bonded
   296  	validators[0].Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   297  	validators[0].DelegatorShares = validators[0].Tokens.ToDec()
   298  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
   299  	resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   300  	require.True(t, found)
   301  	assert.True(ValEq(t, validators[0], resVal))
   302  
   303  	resVals = app.StakingKeeper.GetLastValidators(ctx)
   304  	require.Equal(t, 1, len(resVals))
   305  	assert.True(ValEq(t, validators[0], resVals[0]))
   306  
   307  	// add other validators
   308  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true)
   309  	validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true)
   310  	resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
   311  	require.True(t, found)
   312  	assert.True(ValEq(t, validators[1], resVal))
   313  	resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[2])
   314  	require.True(t, found)
   315  	assert.True(ValEq(t, validators[2], resVal))
   316  
   317  	resVals = app.StakingKeeper.GetLastValidators(ctx)
   318  	require.Equal(t, 3, len(resVals))
   319  	assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here
   320  	assert.True(ValEq(t, validators[1], resVals[1]))
   321  	assert.True(ValEq(t, validators[2], resVals[2]))
   322  
   323  	// remove a record
   324  
   325  	// shouldn't be able to remove if status is not unbonded
   326  	assert.PanicsWithValue(t,
   327  		"cannot call RemoveValidator on bonded or unbonding validators",
   328  		func() { app.StakingKeeper.RemoveValidator(ctx, validators[1].GetOperator()) })
   329  
   330  	// shouldn't be able to remove if there are still tokens left
   331  	validators[1].Status = types.Unbonded
   332  	app.StakingKeeper.SetValidator(ctx, validators[1])
   333  	assert.PanicsWithValue(t,
   334  		"attempting to remove a validator which still contains tokens",
   335  		func() { app.StakingKeeper.RemoveValidator(ctx, validators[1].GetOperator()) })
   336  
   337  	validators[1].Tokens = sdk.ZeroInt()                                // ...remove all tokens
   338  	app.StakingKeeper.SetValidator(ctx, validators[1])                  // ...set the validator
   339  	app.StakingKeeper.RemoveValidator(ctx, validators[1].GetOperator()) // Now it can be removed.
   340  	_, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
   341  	require.False(t, found)
   342  }
   343  
   344  // test how the validators are sorted, tests GetBondedValidatorsByPower
   345  func TestGetValidatorSortingUnmixed(t *testing.T) {
   346  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   347  
   348  	// initialize some validators into the state
   349  	amts := []sdk.Int{
   350  		sdk.NewIntFromUint64(0),
   351  		app.StakingKeeper.PowerReduction(ctx).MulRaw(100),
   352  		app.StakingKeeper.PowerReduction(ctx),
   353  		app.StakingKeeper.PowerReduction(ctx).MulRaw(400),
   354  		app.StakingKeeper.PowerReduction(ctx).MulRaw(200),
   355  	}
   356  	n := len(amts)
   357  	var validators [5]types.Validator
   358  	for i, amt := range amts {
   359  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   360  		validators[i].Status = types.Bonded
   361  		validators[i].Tokens = amt
   362  		validators[i].DelegatorShares = sdk.NewDecFromInt(amt)
   363  		keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true)
   364  	}
   365  
   366  	// first make sure everything made it in to the gotValidator group
   367  	resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   368  	assert.Equal(t, n, len(resValidators))
   369  	assert.Equal(t, sdk.NewInt(400).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[0].BondedTokens(), "%v", resValidators)
   370  	assert.Equal(t, sdk.NewInt(200).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[1].BondedTokens(), "%v", resValidators)
   371  	assert.Equal(t, sdk.NewInt(100).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[2].BondedTokens(), "%v", resValidators)
   372  	assert.Equal(t, sdk.NewInt(1).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[3].BondedTokens(), "%v", resValidators)
   373  	assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators)
   374  	assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators)
   375  	assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators)
   376  	assert.Equal(t, validators[1].OperatorAddress, resValidators[2].OperatorAddress, "%v", resValidators)
   377  	assert.Equal(t, validators[2].OperatorAddress, resValidators[3].OperatorAddress, "%v", resValidators)
   378  	assert.Equal(t, validators[0].OperatorAddress, resValidators[4].OperatorAddress, "%v", resValidators)
   379  
   380  	// test a basic increase in voting power
   381  	validators[3].Tokens = sdk.NewInt(500).Mul(app.StakingKeeper.PowerReduction(ctx))
   382  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   383  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   384  	require.Equal(t, len(resValidators), n)
   385  	assert.True(ValEq(t, validators[3], resValidators[0]))
   386  
   387  	// test a decrease in voting power
   388  	validators[3].Tokens = sdk.NewInt(300).Mul(app.StakingKeeper.PowerReduction(ctx))
   389  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   390  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   391  	require.Equal(t, len(resValidators), n)
   392  	assert.True(ValEq(t, validators[3], resValidators[0]))
   393  	assert.True(ValEq(t, validators[4], resValidators[1]))
   394  
   395  	// test equal voting power, different age
   396  	validators[3].Tokens = sdk.NewInt(200).Mul(app.StakingKeeper.PowerReduction(ctx))
   397  	ctx = ctx.WithBlockHeight(10)
   398  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   399  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   400  	require.Equal(t, len(resValidators), n)
   401  	assert.True(ValEq(t, validators[3], resValidators[0]))
   402  	assert.True(ValEq(t, validators[4], resValidators[1]))
   403  
   404  	// no change in voting power - no change in sort
   405  	ctx = ctx.WithBlockHeight(20)
   406  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[4], true)
   407  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   408  	require.Equal(t, len(resValidators), n)
   409  	assert.True(ValEq(t, validators[3], resValidators[0]))
   410  	assert.True(ValEq(t, validators[4], resValidators[1]))
   411  
   412  	// change in voting power of both validators, both still in v-set, no age change
   413  	validators[3].Tokens = sdk.NewInt(300).Mul(app.StakingKeeper.PowerReduction(ctx))
   414  	validators[4].Tokens = sdk.NewInt(300).Mul(app.StakingKeeper.PowerReduction(ctx))
   415  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   416  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   417  	require.Equal(t, len(resValidators), n)
   418  	ctx = ctx.WithBlockHeight(30)
   419  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[4], true)
   420  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   421  	require.Equal(t, len(resValidators), n, "%v", resValidators)
   422  	assert.True(ValEq(t, validators[3], resValidators[0]))
   423  	assert.True(ValEq(t, validators[4], resValidators[1]))
   424  }
   425  
   426  func TestGetValidatorSortingMixed(t *testing.T) {
   427  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   428  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   429  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   430  
   431  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 501)))))
   432  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), app.StakingKeeper.TokensFromConsensusPower(ctx, 0)))))
   433  
   434  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   435  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   436  
   437  	// now 2 max resValidators
   438  	params := app.StakingKeeper.GetParams(ctx)
   439  	params.MaxValidators = 2
   440  	app.StakingKeeper.SetParams(ctx, params)
   441  
   442  	// initialize some validators into the state
   443  	amts := []sdk.Int{
   444  		sdk.NewIntFromUint64(0),
   445  		app.StakingKeeper.PowerReduction(ctx).MulRaw(100),
   446  		app.StakingKeeper.PowerReduction(ctx),
   447  		app.StakingKeeper.PowerReduction(ctx).MulRaw(400),
   448  		app.StakingKeeper.PowerReduction(ctx).MulRaw(200),
   449  	}
   450  
   451  	var validators [5]types.Validator
   452  	for i, amt := range amts {
   453  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   454  		validators[i].DelegatorShares = sdk.NewDecFromInt(amt)
   455  		validators[i].Status = types.Bonded
   456  		validators[i].Tokens = amt
   457  		keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true)
   458  	}
   459  
   460  	val0, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
   461  	require.True(t, found)
   462  	val1, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1]))
   463  	require.True(t, found)
   464  	val2, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[2]))
   465  	require.True(t, found)
   466  	val3, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[3]))
   467  	require.True(t, found)
   468  	val4, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[4]))
   469  	require.True(t, found)
   470  	require.Equal(t, types.Bonded, val0.Status)
   471  	require.Equal(t, types.Unbonding, val1.Status)
   472  	require.Equal(t, types.Unbonding, val2.Status)
   473  	require.Equal(t, types.Bonded, val3.Status)
   474  	require.Equal(t, types.Bonded, val4.Status)
   475  
   476  	// first make sure everything made it in to the gotValidator group
   477  	resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   478  	// The validators returned should match the max validators
   479  	assert.Equal(t, 2, len(resValidators))
   480  	assert.Equal(t, sdk.NewInt(400).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[0].BondedTokens(), "%v", resValidators)
   481  	assert.Equal(t, sdk.NewInt(200).Mul(app.StakingKeeper.PowerReduction(ctx)), resValidators[1].BondedTokens(), "%v", resValidators)
   482  	assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators)
   483  	assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators)
   484  }
   485  
   486  // TODO separate out into multiple tests
   487  func TestGetValidatorsEdgeCases(t *testing.T) {
   488  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   489  
   490  	// set max validators to 2
   491  	params := app.StakingKeeper.GetParams(ctx)
   492  	nMax := uint32(2)
   493  	params.MaxValidators = nMax
   494  	app.StakingKeeper.SetParams(ctx, params)
   495  
   496  	// initialize some validators into the state
   497  	powers := []int64{0, 100, 400, 400}
   498  	var validators [4]types.Validator
   499  	for i, power := range powers {
   500  		moniker := fmt.Sprintf("val#%d", int64(i))
   501  		validators[i] = newMonikerValidator(t, sdk.ValAddress(addrs[i]), PKs[i], moniker)
   502  
   503  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   504  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   505  
   506  		notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   507  		require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(params.BondDenom, tokens))))
   508  		app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   509  		validators[i] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true)
   510  	}
   511  
   512  	// ensure that the first two bonded validators are the largest validators
   513  	resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   514  	require.Equal(t, nMax, uint32(len(resValidators)))
   515  	assert.True(ValEq(t, validators[2], resValidators[0]))
   516  	assert.True(ValEq(t, validators[3], resValidators[1]))
   517  
   518  	// delegate 500 tokens to validator 0
   519  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0])
   520  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 500)
   521  	validators[0], _ = validators[0].AddTokensFromDel(delTokens)
   522  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   523  
   524  	newTokens := sdk.NewCoins()
   525  
   526  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), newTokens))
   527  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   528  
   529  	// test that the two largest validators are
   530  	//   a) validator 0 with 500 tokens
   531  	//   b) validator 2 with 400 tokens (delegated before validator 3)
   532  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
   533  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   534  	require.Equal(t, nMax, uint32(len(resValidators)))
   535  	assert.True(ValEq(t, validators[0], resValidators[0]))
   536  	assert.True(ValEq(t, validators[2], resValidators[1]))
   537  
   538  	// A validator which leaves the bonded validator set due to a decrease in voting power,
   539  	// then increases to the original voting power, does not get its spot back in the
   540  	// case of a tie.
   541  	//
   542  	// Order of operations for this test:
   543  	//  - validator 3 enter validator set with 1 new token
   544  	//  - validator 3 removed validator set by removing 201 tokens (validator 2 enters)
   545  	//  - validator 3 adds 200 tokens (equal to validator 2 now) and does not get its spot back
   546  
   547  	// validator 3 enters bonded validator set
   548  	ctx = ctx.WithBlockHeight(40)
   549  
   550  	var found bool
   551  	validators[3], found = app.StakingKeeper.GetValidator(ctx, validators[3].GetOperator())
   552  	assert.True(t, found)
   553  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3])
   554  	validators[3], _ = validators[3].AddTokensFromDel(app.StakingKeeper.TokensFromConsensusPower(ctx, 1))
   555  
   556  	notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
   557  	newTokens = sdk.NewCoins(sdk.NewCoin(params.BondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 1)))
   558  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), newTokens))
   559  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   560  
   561  	validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   562  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   563  	require.Equal(t, nMax, uint32(len(resValidators)))
   564  	assert.True(ValEq(t, validators[0], resValidators[0]))
   565  	assert.True(ValEq(t, validators[3], resValidators[1]))
   566  
   567  	// validator 3 kicked out temporarily
   568  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3])
   569  	rmTokens := validators[3].TokensFromShares(sdk.NewDec(201)).TruncateInt()
   570  	validators[3], _ = validators[3].RemoveDelShares(sdk.NewDec(201))
   571  
   572  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   573  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(params.BondDenom, rmTokens))))
   574  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   575  
   576  	validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   577  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   578  	require.Equal(t, nMax, uint32(len(resValidators)))
   579  	assert.True(ValEq(t, validators[0], resValidators[0]))
   580  	assert.True(ValEq(t, validators[2], resValidators[1]))
   581  
   582  	// validator 3 does not get spot back
   583  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3])
   584  	validators[3], _ = validators[3].AddTokensFromDel(sdk.NewInt(200))
   585  
   586  	notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
   587  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(params.BondDenom, sdk.NewInt(200)))))
   588  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   589  
   590  	validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true)
   591  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   592  	require.Equal(t, nMax, uint32(len(resValidators)))
   593  	assert.True(ValEq(t, validators[0], resValidators[0]))
   594  	assert.True(ValEq(t, validators[2], resValidators[1]))
   595  	_, exists := app.StakingKeeper.GetValidator(ctx, validators[3].GetOperator())
   596  	require.True(t, exists)
   597  }
   598  
   599  func TestValidatorBondHeight(t *testing.T) {
   600  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   601  
   602  	// now 2 max resValidators
   603  	params := app.StakingKeeper.GetParams(ctx)
   604  	params.MaxValidators = 2
   605  	app.StakingKeeper.SetParams(ctx, params)
   606  
   607  	// initialize some validators into the state
   608  	var validators [3]types.Validator
   609  	validators[0] = teststaking.NewValidator(t, sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0])
   610  	validators[1] = teststaking.NewValidator(t, sdk.ValAddress(addrs[1]), PKs[1])
   611  	validators[2] = teststaking.NewValidator(t, sdk.ValAddress(addrs[2]), PKs[2])
   612  
   613  	tokens0 := app.StakingKeeper.TokensFromConsensusPower(ctx, 200)
   614  	tokens1 := app.StakingKeeper.TokensFromConsensusPower(ctx, 100)
   615  	tokens2 := app.StakingKeeper.TokensFromConsensusPower(ctx, 100)
   616  	validators[0], _ = validators[0].AddTokensFromDel(tokens0)
   617  	validators[1], _ = validators[1].AddTokensFromDel(tokens1)
   618  	validators[2], _ = validators[2].AddTokensFromDel(tokens2)
   619  
   620  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
   621  
   622  	////////////////////////////////////////
   623  	// If two validators both increase to the same voting power in the same block,
   624  	// the one with the first transaction should become bonded
   625  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true)
   626  	validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true)
   627  
   628  	resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   629  	require.Equal(t, uint32(len(resValidators)), params.MaxValidators)
   630  
   631  	assert.True(ValEq(t, validators[0], resValidators[0]))
   632  	assert.True(ValEq(t, validators[1], resValidators[1]))
   633  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[1])
   634  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[2])
   635  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 50)
   636  	validators[1], _ = validators[1].AddTokensFromDel(delTokens)
   637  	validators[2], _ = validators[2].AddTokensFromDel(delTokens)
   638  	validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true)
   639  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   640  	require.Equal(t, params.MaxValidators, uint32(len(resValidators)))
   641  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true)
   642  	assert.True(ValEq(t, validators[0], resValidators[0]))
   643  	assert.True(ValEq(t, validators[2], resValidators[1]))
   644  }
   645  
   646  func TestFullValidatorSetPowerChange(t *testing.T) {
   647  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   648  	params := app.StakingKeeper.GetParams(ctx)
   649  	max := 2
   650  	params.MaxValidators = uint32(2)
   651  	app.StakingKeeper.SetParams(ctx, params)
   652  
   653  	// initialize some validators into the state
   654  	powers := []int64{0, 100, 400, 400, 200}
   655  	var validators [5]types.Validator
   656  	for i, power := range powers {
   657  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   658  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   659  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   660  		keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true)
   661  	}
   662  	for i := range powers {
   663  		var found bool
   664  		validators[i], found = app.StakingKeeper.GetValidator(ctx, validators[i].GetOperator())
   665  		require.True(t, found)
   666  	}
   667  	assert.Equal(t, types.Unbonded, validators[0].Status)
   668  	assert.Equal(t, types.Unbonding, validators[1].Status)
   669  	assert.Equal(t, types.Bonded, validators[2].Status)
   670  	assert.Equal(t, types.Bonded, validators[3].Status)
   671  	assert.Equal(t, types.Unbonded, validators[4].Status)
   672  	resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   673  	assert.Equal(t, max, len(resValidators))
   674  	assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs
   675  	assert.True(ValEq(t, validators[3], resValidators[1]))
   676  
   677  	// test a swap in voting power
   678  
   679  	tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 600)
   680  	validators[0], _ = validators[0].AddTokensFromDel(tokens)
   681  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
   682  	resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx)
   683  	assert.Equal(t, max, len(resValidators))
   684  	assert.True(ValEq(t, validators[0], resValidators[0]))
   685  	assert.True(ValEq(t, validators[2], resValidators[1]))
   686  }
   687  
   688  func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) {
   689  	app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20)
   690  
   691  	powers := []int64{10, 20}
   692  	var validators [2]types.Validator
   693  	for i, power := range powers {
   694  		valPubKey := PKs[i+1]
   695  		valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   696  
   697  		validators[i] = teststaking.NewValidator(t, valAddr, valPubKey)
   698  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   699  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   700  	}
   701  
   702  	// test from nothing to something
   703  	//  tendermintUpdate set: {} -> {c1, c3}
   704  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
   705  	app.StakingKeeper.SetValidator(ctx, validators[0])
   706  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0])
   707  	app.StakingKeeper.SetValidator(ctx, validators[1])
   708  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[1])
   709  
   710  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   711  	validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].GetOperator())
   712  	validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].GetOperator())
   713  	assert.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
   714  	assert.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   715  }
   716  
   717  func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) {
   718  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   719  
   720  	powers := []int64{10, 20}
   721  	var validators [2]types.Validator
   722  	for i, power := range powers {
   723  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   724  
   725  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   726  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   727  
   728  	}
   729  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   730  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   731  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   732  
   733  	// test identical,
   734  	//  tendermintUpdate set: {} -> {}
   735  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   736  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   737  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
   738  }
   739  
   740  func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) {
   741  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   742  
   743  	powers := []int64{10, 20}
   744  	var validators [2]types.Validator
   745  	for i, power := range powers {
   746  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   747  
   748  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   749  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   750  
   751  	}
   752  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   753  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   754  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   755  
   756  	// test single value change
   757  	//  tendermintUpdate set: {} -> {c1'}
   758  	validators[0].Status = types.Bonded
   759  	validators[0].Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 600)
   760  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   761  
   762  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   763  	require.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   764  }
   765  
   766  func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) {
   767  	powers := []int64{10, 20}
   768  	// TODO: use it in other places
   769  	app, ctx, _, _, validators := initValidators(t, 1000, 20, powers)
   770  
   771  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   772  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   773  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   774  
   775  	// test multiple value change
   776  	//  tendermintUpdate set: {c1, c3} -> {c1', c3'}
   777  	delTokens1 := app.StakingKeeper.TokensFromConsensusPower(ctx, 190)
   778  	delTokens2 := app.StakingKeeper.TokensFromConsensusPower(ctx, 80)
   779  	validators[0], _ = validators[0].AddTokensFromDel(delTokens1)
   780  	validators[1], _ = validators[1].AddTokensFromDel(delTokens2)
   781  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   782  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   783  
   784  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   785  	require.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   786  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
   787  }
   788  
   789  func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) {
   790  	powers := []int64{10, 20, 5, 15, 25}
   791  	app, ctx, _, _, validators := initValidators(t, 1000, 20, powers)
   792  
   793  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   794  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   795  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   796  
   797  	// test validtor added at the beginning
   798  	//  tendermintUpdate set: {} -> {c0}
   799  	app.StakingKeeper.SetValidator(ctx, validators[2])
   800  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[2])
   801  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   802  	validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].GetOperator())
   803  	require.Equal(t, validators[2].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   804  
   805  	// test validtor added at the beginning
   806  	//  tendermintUpdate set: {} -> {c0}
   807  	app.StakingKeeper.SetValidator(ctx, validators[3])
   808  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[3])
   809  	updates = applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   810  	validators[3], _ = app.StakingKeeper.GetValidator(ctx, validators[3].GetOperator())
   811  	require.Equal(t, validators[3].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   812  
   813  	// test validtor added at the end
   814  	//  tendermintUpdate set: {} -> {c0}
   815  	app.StakingKeeper.SetValidator(ctx, validators[4])
   816  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[4])
   817  	updates = applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   818  	validators[4], _ = app.StakingKeeper.GetValidator(ctx, validators[4].GetOperator())
   819  	require.Equal(t, validators[4].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   820  }
   821  
   822  func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) {
   823  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   824  	params := types.DefaultParams()
   825  	params.MaxValidators = 2
   826  	app.StakingKeeper.SetParams(ctx, params)
   827  
   828  	powers := []int64{10, 20, 5}
   829  	var validators [5]types.Validator
   830  	for i, power := range powers {
   831  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   832  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   833  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   834  	}
   835  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   836  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   837  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   838  
   839  	// test validator added at the end but not inserted in the valset
   840  	//  tendermintUpdate set: {} -> {}
   841  	keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], false)
   842  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
   843  
   844  	// test validator change its power and become a gotValidator (pushing out an existing)
   845  	//  tendermintUpdate set: {}     -> {c0, c4}
   846  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
   847  
   848  	tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   849  	validators[2], _ = validators[2].AddTokensFromDel(tokens)
   850  	app.StakingKeeper.SetValidator(ctx, validators[2])
   851  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[2])
   852  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   853  	validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].GetOperator())
   854  	require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1])
   855  	require.Equal(t, validators[2].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   856  }
   857  
   858  func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) {
   859  	app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20)
   860  
   861  	powers := []int64{100, 100}
   862  	var validators [2]types.Validator
   863  	for i, power := range powers {
   864  		validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i])
   865  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   866  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   867  	}
   868  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   869  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   870  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   871  
   872  	// check initial power
   873  	require.Equal(t, int64(100), validators[0].GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
   874  	require.Equal(t, int64(100), validators[1].GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
   875  
   876  	// test multiple value change
   877  	//  tendermintUpdate set: {c1, c3} -> {c1', c3'}
   878  	delTokens1 := app.StakingKeeper.TokensFromConsensusPower(ctx, 20)
   879  	delTokens2 := app.StakingKeeper.TokensFromConsensusPower(ctx, 30)
   880  	validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec())
   881  	validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec())
   882  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false)
   883  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false)
   884  
   885  	// power has changed
   886  	require.Equal(t, int64(80), validators[0].GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
   887  	require.Equal(t, int64(70), validators[1].GetConsensusPower(app.StakingKeeper.PowerReduction(ctx)))
   888  
   889  	// Tendermint updates should reflect power change
   890  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   891  	require.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   892  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
   893  }
   894  
   895  func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) {
   896  	app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20)
   897  	params := app.StakingKeeper.GetParams(ctx)
   898  	params.MaxValidators = uint32(3)
   899  
   900  	app.StakingKeeper.SetParams(ctx, params)
   901  
   902  	powers := []int64{100, 100}
   903  	var validators [2]types.Validator
   904  
   905  	// initialize some validators into the state
   906  	for i, power := range powers {
   907  		valPubKey := PKs[i+1]
   908  		valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   909  
   910  		validators[i] = teststaking.NewValidator(t, valAddr, valPubKey)
   911  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   912  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   913  
   914  		app.StakingKeeper.SetValidator(ctx, validators[i])
   915  		app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
   916  	}
   917  
   918  	// verify initial Tendermint updates are correct
   919  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, len(validators))
   920  	validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].GetOperator())
   921  	validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].GetOperator())
   922  	require.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   923  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
   924  
   925  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
   926  
   927  	// update initial validator set
   928  	for i, power := range powers {
   929  
   930  		app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[i])
   931  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   932  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   933  
   934  		app.StakingKeeper.SetValidator(ctx, validators[i])
   935  		app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
   936  	}
   937  
   938  	// add a new validator that goes from zero power, to non-zero power, back to
   939  	// zero power
   940  	valPubKey := PKs[len(validators)+1]
   941  	valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   942  	amt := sdk.NewInt(100)
   943  
   944  	validator := teststaking.NewValidator(t, valAddr, valPubKey)
   945  	validator, _ = validator.AddTokensFromDel(amt)
   946  
   947  	app.StakingKeeper.SetValidator(ctx, validator)
   948  
   949  	validator, _ = validator.RemoveDelShares(amt.ToDec())
   950  	app.StakingKeeper.SetValidator(ctx, validator)
   951  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator)
   952  
   953  	// add a new validator that increases in power
   954  	valPubKey = PKs[len(validators)+2]
   955  	valAddr = sdk.ValAddress(valPubKey.Address().Bytes())
   956  
   957  	validator = teststaking.NewValidator(t, valAddr, valPubKey)
   958  	tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 500)
   959  	validator, _ = validator.AddTokensFromDel(tokens)
   960  	app.StakingKeeper.SetValidator(ctx, validator)
   961  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator)
   962  
   963  	// verify initial Tendermint updates are correct
   964  	updates = applyValidatorSetUpdates(t, ctx, app.StakingKeeper, len(validators)+1)
   965  	validator, _ = app.StakingKeeper.GetValidator(ctx, validator.GetOperator())
   966  	validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].GetOperator())
   967  	validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].GetOperator())
   968  	require.Equal(t, validator.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
   969  	require.Equal(t, validators[0].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
   970  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[2])
   971  }
   972  
   973  func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) {
   974  	app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20)
   975  	params := app.StakingKeeper.GetParams(ctx)
   976  	params.MaxValidators = uint32(2)
   977  
   978  	app.StakingKeeper.SetParams(ctx, params)
   979  
   980  	powers := []int64{100, 200, 300}
   981  	var validators [3]types.Validator
   982  
   983  	// initialize some validators into the state
   984  	for i, power := range powers {
   985  		moniker := fmt.Sprintf("%d", i)
   986  		valPubKey := PKs[i+1]
   987  		valAddr := sdk.ValAddress(valPubKey.Address().Bytes())
   988  
   989  		validators[i] = newMonikerValidator(t, valAddr, valPubKey, moniker)
   990  		tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, power)
   991  		validators[i], _ = validators[i].AddTokensFromDel(tokens)
   992  		app.StakingKeeper.SetValidator(ctx, validators[i])
   993  		app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
   994  	}
   995  
   996  	// verify initial Tendermint updates are correct
   997  	updates := applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   998  	validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].GetOperator())
   999  	validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].GetOperator())
  1000  	require.Equal(t, validators[2].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
  1001  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[1])
  1002  
  1003  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
  1004  
  1005  	// delegate to validator with lowest power but not enough to bond
  1006  	ctx = ctx.WithBlockHeight(1)
  1007  
  1008  	var found bool
  1009  	validators[0], found = app.StakingKeeper.GetValidator(ctx, validators[0].GetOperator())
  1010  	require.True(t, found)
  1011  
  1012  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0])
  1013  	tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1)
  1014  	validators[0], _ = validators[0].AddTokensFromDel(tokens)
  1015  	app.StakingKeeper.SetValidator(ctx, validators[0])
  1016  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0])
  1017  
  1018  	// verify initial Tendermint updates are correct
  1019  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
  1020  
  1021  	// create a series of events that will bond and unbond the validator with
  1022  	// lowest power in a single block context (height)
  1023  	ctx = ctx.WithBlockHeight(2)
  1024  
  1025  	validators[1], found = app.StakingKeeper.GetValidator(ctx, validators[1].GetOperator())
  1026  	require.True(t, found)
  1027  
  1028  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0])
  1029  	validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares)
  1030  	app.StakingKeeper.SetValidator(ctx, validators[0])
  1031  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0])
  1032  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
  1033  
  1034  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[1])
  1035  	tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 250)
  1036  	validators[1], _ = validators[1].AddTokensFromDel(tokens)
  1037  	app.StakingKeeper.SetValidator(ctx, validators[1])
  1038  	app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[1])
  1039  
  1040  	// verify initial Tendermint updates are correct
  1041  	updates = applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
  1042  	require.Equal(t, validators[1].ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)), updates[0])
  1043  
  1044  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 0)
  1045  }
  1046  
  1047  func TestUpdateValidatorCommission(t *testing.T) {
  1048  	app, ctx, _, addrVals := bootstrapValidatorTest(t, 1000, 20)
  1049  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Now().UTC()})
  1050  
  1051  	commission1 := types.NewCommissionWithTime(
  1052  		sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1),
  1053  		sdk.NewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour),
  1054  	)
  1055  	commission2 := types.NewCommission(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), sdk.NewDecWithPrec(1, 1))
  1056  
  1057  	val1 := teststaking.NewValidator(t, addrVals[0], PKs[0])
  1058  	val2 := teststaking.NewValidator(t, addrVals[1], PKs[1])
  1059  
  1060  	val1, _ = val1.SetInitialCommission(commission1)
  1061  	val2, _ = val2.SetInitialCommission(commission2)
  1062  
  1063  	app.StakingKeeper.SetValidator(ctx, val1)
  1064  	app.StakingKeeper.SetValidator(ctx, val2)
  1065  
  1066  	testCases := []struct {
  1067  		validator   types.Validator
  1068  		newRate     sdk.Dec
  1069  		expectedErr bool
  1070  	}{
  1071  		{val1, sdk.ZeroDec(), true},
  1072  		{val2, sdk.NewDecWithPrec(-1, 1), true},
  1073  		{val2, sdk.NewDecWithPrec(4, 1), true},
  1074  		{val2, sdk.NewDecWithPrec(3, 1), true},
  1075  		{val2, sdk.NewDecWithPrec(2, 1), false},
  1076  	}
  1077  
  1078  	for i, tc := range testCases {
  1079  		commission, err := app.StakingKeeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate)
  1080  
  1081  		if tc.expectedErr {
  1082  			require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate)
  1083  		} else {
  1084  			tc.validator.Commission = commission
  1085  			app.StakingKeeper.SetValidator(ctx, tc.validator)
  1086  			val, found := app.StakingKeeper.GetValidator(ctx, tc.validator.GetOperator())
  1087  
  1088  			require.True(t, found,
  1089  				"expected to find validator for test case #%d with rate: %s", i, tc.newRate,
  1090  			)
  1091  			require.NoError(t, err,
  1092  				"unexpected error for test case #%d with rate: %s", i, tc.newRate,
  1093  			)
  1094  			require.Equal(t, tc.newRate, val.Commission.Rate,
  1095  				"expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate,
  1096  			)
  1097  			require.Equal(t, ctx.BlockHeader().Time, val.Commission.UpdateTime,
  1098  				"expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate,
  1099  			)
  1100  		}
  1101  	}
  1102  }
  1103  
  1104  func applyValidatorSetUpdates(t *testing.T, ctx sdk.Context, k keeper.Keeper, expectedUpdatesLen int) []abci.ValidatorUpdate {
  1105  	t.Helper()
  1106  	updates, err := k.ApplyAndReturnValidatorSetUpdates(ctx)
  1107  	require.NoError(t, err)
  1108  	if expectedUpdatesLen >= 0 {
  1109  		require.Equal(t, expectedUpdatesLen, len(updates), "%v", updates)
  1110  	}
  1111  	return updates
  1112  }