github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/staking/keeper/validator_test.go (about)

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