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