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

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/Finschia/finschia-sdk/simapp"
    11  	sdk "github.com/Finschia/finschia-sdk/types"
    12  	"github.com/Finschia/finschia-sdk/x/staking/keeper"
    13  	"github.com/Finschia/finschia-sdk/x/staking/teststaking"
    14  	"github.com/Finschia/finschia-sdk/x/staking/types"
    15  )
    16  
    17  // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations
    18  func TestDelegation(t *testing.T) {
    19  	_, app, ctx := createTestInput()
    20  
    21  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000))
    22  	valAddrs := simapp.ConvertAddrsToValAddrs(addrDels)
    23  
    24  	// construct the validators
    25  	amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
    26  	var validators [3]types.Validator
    27  	for i, amt := range amts {
    28  		validators[i] = teststaking.NewValidator(t, valAddrs[i], PKs[i])
    29  		validators[i], _ = validators[i].AddTokensFromDel(amt)
    30  	}
    31  
    32  	validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true)
    33  	validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true)
    34  	validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true)
    35  
    36  	// first add a validators[0] to delegate too
    37  	bond1to1 := types.NewDelegation(addrDels[0], valAddrs[0], sdk.NewDec(9))
    38  
    39  	// check the empty keeper first
    40  	_, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
    41  	require.False(t, found)
    42  
    43  	// set and retrieve a record
    44  	app.StakingKeeper.SetDelegation(ctx, bond1to1)
    45  	resBond, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
    46  	require.True(t, found)
    47  	require.Equal(t, bond1to1, resBond)
    48  
    49  	// modify a records, save, and retrieve
    50  	bond1to1.Shares = sdk.NewDec(99)
    51  	app.StakingKeeper.SetDelegation(ctx, bond1to1)
    52  	resBond, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
    53  	require.True(t, found)
    54  	require.Equal(t, bond1to1, resBond)
    55  
    56  	// add some more records
    57  	bond1to2 := types.NewDelegation(addrDels[0], valAddrs[1], sdk.NewDec(9))
    58  	bond1to3 := types.NewDelegation(addrDels[0], valAddrs[2], sdk.NewDec(9))
    59  	bond2to1 := types.NewDelegation(addrDels[1], valAddrs[0], sdk.NewDec(9))
    60  	bond2to2 := types.NewDelegation(addrDels[1], valAddrs[1], sdk.NewDec(9))
    61  	bond2to3 := types.NewDelegation(addrDels[1], valAddrs[2], sdk.NewDec(9))
    62  	app.StakingKeeper.SetDelegation(ctx, bond1to2)
    63  	app.StakingKeeper.SetDelegation(ctx, bond1to3)
    64  	app.StakingKeeper.SetDelegation(ctx, bond2to1)
    65  	app.StakingKeeper.SetDelegation(ctx, bond2to2)
    66  	app.StakingKeeper.SetDelegation(ctx, bond2to3)
    67  
    68  	// test all bond retrieve capabilities
    69  	resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 5)
    70  	require.Equal(t, 3, len(resBonds))
    71  	require.Equal(t, bond1to1, resBonds[0])
    72  	require.Equal(t, bond1to2, resBonds[1])
    73  	require.Equal(t, bond1to3, resBonds[2])
    74  	resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[0])
    75  	require.Equal(t, 3, len(resBonds))
    76  	resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 2)
    77  	require.Equal(t, 2, len(resBonds))
    78  	resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
    79  	require.Equal(t, 3, len(resBonds))
    80  	require.Equal(t, bond2to1, resBonds[0])
    81  	require.Equal(t, bond2to2, resBonds[1])
    82  	require.Equal(t, bond2to3, resBonds[2])
    83  	allBonds := app.StakingKeeper.GetAllDelegations(ctx)
    84  	require.Equal(t, 6, len(allBonds))
    85  	require.Equal(t, bond1to1, allBonds[0])
    86  	require.Equal(t, bond1to2, allBonds[1])
    87  	require.Equal(t, bond1to3, allBonds[2])
    88  	require.Equal(t, bond2to1, allBonds[3])
    89  	require.Equal(t, bond2to2, allBonds[4])
    90  	require.Equal(t, bond2to3, allBonds[5])
    91  
    92  	resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[0], 3)
    93  	require.Equal(t, 3, len(resVals))
    94  	resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[1], 4)
    95  	require.Equal(t, 3, len(resVals))
    96  
    97  	for i := 0; i < 3; i++ {
    98  		resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[0], valAddrs[i])
    99  		require.Nil(t, err)
   100  		require.Equal(t, valAddrs[i], resVal.GetOperator())
   101  
   102  		resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[1], valAddrs[i])
   103  		require.Nil(t, err)
   104  		require.Equal(t, valAddrs[i], resVal.GetOperator())
   105  
   106  		resDels := app.StakingKeeper.GetValidatorDelegations(ctx, valAddrs[i])
   107  		require.Len(t, resDels, 2)
   108  	}
   109  
   110  	// test total bonded for single delegator
   111  	expBonded := bond1to1.Shares.Add(bond2to1.Shares).Add(bond1to3.Shares)
   112  	resDelBond := app.StakingKeeper.GetDelegatorBonded(ctx, addrDels[0])
   113  	require.Equal(t, expBonded, sdk.NewDecFromInt(resDelBond))
   114  
   115  	// delete a record
   116  	app.StakingKeeper.RemoveDelegation(ctx, bond2to3)
   117  	_, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
   118  	require.False(t, found)
   119  	resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
   120  	require.Equal(t, 2, len(resBonds))
   121  	require.Equal(t, bond2to1, resBonds[0])
   122  	require.Equal(t, bond2to2, resBonds[1])
   123  
   124  	resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[1])
   125  	require.Equal(t, 2, len(resBonds))
   126  
   127  	// delete all the records from delegator 2
   128  	app.StakingKeeper.RemoveDelegation(ctx, bond2to1)
   129  	app.StakingKeeper.RemoveDelegation(ctx, bond2to2)
   130  	_, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[0])
   131  	require.False(t, found)
   132  	_, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[1])
   133  	require.False(t, found)
   134  	resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
   135  	require.Equal(t, 0, len(resBonds))
   136  }
   137  
   138  // tests Get/Set/Remove UnbondingDelegation
   139  func TestUnbondingDelegation(t *testing.T) {
   140  	_, app, ctx := createTestInput()
   141  
   142  	delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(10000))
   143  	valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs)
   144  
   145  	ubd := types.NewUnbondingDelegation(
   146  		delAddrs[0],
   147  		valAddrs[0],
   148  		0,
   149  		time.Unix(0, 0).UTC(),
   150  		sdk.NewInt(5),
   151  	)
   152  
   153  	// set and retrieve a record
   154  	app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
   155  	resUnbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
   156  	require.True(t, found)
   157  	require.Equal(t, ubd, resUnbond)
   158  
   159  	// modify a records, save, and retrieve
   160  	expUnbond := sdk.NewInt(21)
   161  	ubd.Entries[0].Balance = expUnbond
   162  	app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
   163  
   164  	resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
   165  	require.Equal(t, 1, len(resUnbonds))
   166  
   167  	resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
   168  	require.Equal(t, 1, len(resUnbonds))
   169  
   170  	resUnbond, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
   171  	require.True(t, found)
   172  	require.Equal(t, ubd, resUnbond)
   173  
   174  	resDelUnbond := app.StakingKeeper.GetDelegatorUnbonding(ctx, delAddrs[0])
   175  	require.Equal(t, expUnbond, resDelUnbond)
   176  
   177  	// delete a record
   178  	app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd)
   179  	_, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])
   180  	require.False(t, found)
   181  
   182  	resUnbonds = app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
   183  	require.Equal(t, 0, len(resUnbonds))
   184  
   185  	resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, delAddrs[0])
   186  	require.Equal(t, 0, len(resUnbonds))
   187  }
   188  
   189  func TestUnbondDelegation(t *testing.T) {
   190  	_, app, ctx := createTestInput()
   191  
   192  	delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000))
   193  	valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs)
   194  
   195  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   196  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   197  
   198  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))))
   199  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   200  
   201  	// create a validator and a delegator to that validator
   202  	// note this validator starts not-bonded
   203  	validator := teststaking.NewValidator(t, valAddrs[0], PKs[0])
   204  
   205  	validator, issuedShares := validator.AddTokensFromDel(startTokens)
   206  	require.Equal(t, startTokens, issuedShares.RoundInt())
   207  
   208  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   209  
   210  	delegation := types.NewDelegation(delAddrs[0], valAddrs[0], issuedShares)
   211  	app.StakingKeeper.SetDelegation(ctx, delegation)
   212  
   213  	bondTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
   214  	amount, err := app.StakingKeeper.Unbond(ctx, delAddrs[0], valAddrs[0], bondTokens.ToDec())
   215  	require.NoError(t, err)
   216  	require.Equal(t, bondTokens, amount) // shares to be added to an unbonding delegation
   217  
   218  	delegation, found := app.StakingKeeper.GetDelegation(ctx, delAddrs[0], valAddrs[0])
   219  	require.True(t, found)
   220  	validator, found = app.StakingKeeper.GetValidator(ctx, valAddrs[0])
   221  	require.True(t, found)
   222  
   223  	remainingTokens := startTokens.Sub(bondTokens)
   224  	require.Equal(t, remainingTokens, delegation.Shares.RoundInt())
   225  	require.Equal(t, remainingTokens, validator.BondedTokens())
   226  }
   227  
   228  func TestUnbondingDelegationsMaxEntries(t *testing.T) {
   229  	_, app, ctx := createTestInput()
   230  
   231  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000))
   232  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   233  
   234  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   235  
   236  	bondDenom := app.StakingKeeper.BondDenom(ctx)
   237  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   238  
   239  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))))
   240  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   241  
   242  	// create a validator and a delegator to that validator
   243  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   244  
   245  	validator, issuedShares := validator.AddTokensFromDel(startTokens)
   246  	require.Equal(t, startTokens, issuedShares.RoundInt())
   247  
   248  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   249  	require.True(sdk.IntEq(t, startTokens, validator.BondedTokens()))
   250  	require.True(t, validator.IsBonded())
   251  
   252  	delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares)
   253  	app.StakingKeeper.SetDelegation(ctx, delegation)
   254  
   255  	maxEntries := app.StakingKeeper.MaxEntries(ctx)
   256  
   257  	oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   258  	oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   259  
   260  	// should all pass
   261  	var completionTime time.Time
   262  	for i := uint32(0); i < maxEntries; i++ {
   263  		var err error
   264  		completionTime, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1))
   265  		require.NoError(t, err)
   266  	}
   267  
   268  	newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   269  	newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   270  	require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries))))
   271  	require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries))))
   272  
   273  	oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   274  	oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   275  
   276  	// an additional unbond should fail due to max entries
   277  	_, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1))
   278  	require.Error(t, err)
   279  
   280  	newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   281  	newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   282  
   283  	require.True(sdk.IntEq(t, newBonded, oldBonded))
   284  	require.True(sdk.IntEq(t, newNotBonded, oldNotBonded))
   285  
   286  	// mature unbonding delegations
   287  	ctx = ctx.WithBlockTime(completionTime)
   288  	_, err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0])
   289  	require.NoError(t, err)
   290  
   291  	newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   292  	newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   293  	require.True(sdk.IntEq(t, newBonded, oldBonded))
   294  	require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries))))
   295  
   296  	oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   297  
   298  	// unbonding  should work again
   299  	_, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1))
   300  	require.NoError(t, err)
   301  
   302  	newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
   303  	newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
   304  	require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1)))
   305  	require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1)))
   306  }
   307  
   308  // // test undelegating self delegation from a validator pushing it below MinSelfDelegation
   309  // // shift it from the bonded to unbonding state and jailed
   310  func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) {
   311  	_, app, ctx := createTestInput()
   312  
   313  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000))
   314  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   315  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   316  	delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens))
   317  
   318  	// create a validator with a self-delegation
   319  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   320  
   321  	validator.MinSelfDelegation = delTokens
   322  	validator, issuedShares := validator.AddTokensFromDel(delTokens)
   323  	require.Equal(t, delTokens, issuedShares.RoundInt())
   324  
   325  	// add bonded tokens to pool for delegations
   326  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   327  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins))
   328  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   329  
   330  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   331  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   332  	require.NoError(t, err)
   333  	require.True(t, validator.IsBonded())
   334  
   335  	selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares)
   336  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   337  
   338  	// add bonded tokens to pool for delegations
   339  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   340  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   341  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   342  
   343  	// create a second delegation to this validator
   344  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   345  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   346  	require.True(t, validator.IsBonded())
   347  	require.Equal(t, delTokens, issuedShares.RoundInt())
   348  
   349  	// add bonded tokens to pool for delegations
   350  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   351  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   352  
   353  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   354  	delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares)
   355  	app.StakingKeeper.SetDelegation(ctx, delegation)
   356  
   357  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   358  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], app.StakingKeeper.TokensFromConsensusPower(ctx, 6).ToDec())
   359  	require.NoError(t, err)
   360  
   361  	// end block
   362  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   363  
   364  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   365  	require.True(t, found)
   366  	require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 14), validator.Tokens)
   367  	require.Equal(t, types.Unbonding, validator.Status)
   368  	require.True(t, validator.Jailed)
   369  }
   370  
   371  func TestUndelegateFromUnbondingValidator(t *testing.T) {
   372  	_, app, ctx := createTestInput()
   373  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   374  	delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens))
   375  
   376  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   377  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   378  
   379  	// create a validator with a self-delegation
   380  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   381  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   382  	require.NoError(t, err)
   383  
   384  	validator, issuedShares := validator.AddTokensFromDel(delTokens)
   385  	require.Equal(t, delTokens, issuedShares.RoundInt())
   386  
   387  	// add bonded tokens to pool for delegations
   388  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   389  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins))
   390  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   391  
   392  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   393  	require.True(t, validator.IsBonded())
   394  
   395  	selfDelegation := types.NewDelegation(addrVals[0].Bytes(), addrVals[0], issuedShares)
   396  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   397  
   398  	// add bonded tokens to pool for delegations
   399  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   400  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   401  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   402  
   403  	// create a second delegation to this validator
   404  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   405  
   406  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   407  	require.Equal(t, delTokens, issuedShares.RoundInt())
   408  
   409  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   410  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   411  
   412  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   413  	delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares)
   414  	app.StakingKeeper.SetDelegation(ctx, delegation)
   415  
   416  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   417  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   418  
   419  	header := ctx.BlockHeader()
   420  	blockHeight := int64(10)
   421  	header.Height = blockHeight
   422  	blockTime := time.Unix(333, 0)
   423  	header.Time = blockTime
   424  	ctx = ctx.WithBlockHeader(header)
   425  
   426  	// unbond the all self-delegation to put validator in unbonding state
   427  	val0AccAddr := sdk.AccAddress(addrVals[0])
   428  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec())
   429  	require.NoError(t, err)
   430  
   431  	// end block
   432  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   433  
   434  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   435  	require.True(t, found)
   436  	require.Equal(t, blockHeight, validator.UnbondingHeight)
   437  	params := app.StakingKeeper.GetParams(ctx)
   438  	require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
   439  
   440  	blockHeight2 := int64(20)
   441  	blockTime2 := time.Unix(444, 0).UTC()
   442  	ctx = ctx.WithBlockHeight(blockHeight2)
   443  	ctx = ctx.WithBlockTime(blockTime2)
   444  
   445  	// unbond some of the other delegation's shares
   446  	_, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDec(6))
   447  	require.NoError(t, err)
   448  
   449  	// retrieve the unbonding delegation
   450  	ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0])
   451  	require.True(t, found)
   452  	require.Len(t, ubd.Entries, 1)
   453  	require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6)))
   454  	assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight)
   455  	assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime))
   456  }
   457  
   458  func TestUndelegateFromUnbondedValidator(t *testing.T) {
   459  	_, app, ctx := createTestInput()
   460  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   461  	delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens))
   462  
   463  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   464  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   465  
   466  	// add bonded tokens to pool for delegations
   467  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   468  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins))
   469  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   470  
   471  	// create a validator with a self-delegation
   472  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   473  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   474  	require.NoError(t, err)
   475  
   476  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   477  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   478  	require.Equal(t, valTokens, issuedShares.RoundInt())
   479  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   480  	require.True(t, validator.IsBonded())
   481  
   482  	val0AccAddr := sdk.AccAddress(addrVals[0])
   483  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   484  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   485  
   486  	// add bonded tokens to pool for delegations
   487  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   488  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   489  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   490  
   491  	// create a second delegation to this validator
   492  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   493  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   494  	require.Equal(t, delTokens, issuedShares.RoundInt())
   495  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   496  	require.True(t, validator.IsBonded())
   497  	delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares)
   498  	app.StakingKeeper.SetDelegation(ctx, delegation)
   499  
   500  	ctx = ctx.WithBlockHeight(10)
   501  	ctx = ctx.WithBlockTime(time.Unix(333, 0))
   502  
   503  	// unbond the all self-delegation to put validator in unbonding state
   504  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec())
   505  	require.NoError(t, err)
   506  
   507  	// end block
   508  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   509  
   510  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   511  	require.True(t, found)
   512  	require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight)
   513  	params := app.StakingKeeper.GetParams(ctx)
   514  	require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
   515  
   516  	// unbond the validator
   517  	ctx = ctx.WithBlockTime(validator.UnbondingTime)
   518  	app.StakingKeeper.UnbondAllMatureValidators(ctx)
   519  
   520  	// Make sure validator is still in state because there is still an outstanding delegation
   521  	validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   522  	require.True(t, found)
   523  	require.Equal(t, validator.Status, types.Unbonded)
   524  
   525  	// unbond some of the other delegation's shares
   526  	unbondTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
   527  	_, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], unbondTokens.ToDec())
   528  	require.NoError(t, err)
   529  
   530  	// unbond rest of the other delegation's shares
   531  	remainingTokens := delTokens.Sub(unbondTokens)
   532  	_, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], remainingTokens.ToDec())
   533  	require.NoError(t, err)
   534  
   535  	//  now validator should be deleted from state
   536  	validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   537  	require.False(t, found, "%v", validator)
   538  }
   539  
   540  func TestUnbondingAllDelegationFromValidator(t *testing.T) {
   541  	_, app, ctx := createTestInput()
   542  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   543  	delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens))
   544  
   545  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   546  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   547  
   548  	// add bonded tokens to pool for delegations
   549  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   550  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins))
   551  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   552  
   553  	// create a validator with a self-delegation
   554  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   555  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   556  	require.NoError(t, err)
   557  
   558  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   559  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   560  	require.Equal(t, valTokens, issuedShares.RoundInt())
   561  
   562  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   563  	require.True(t, validator.IsBonded())
   564  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   565  
   566  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   567  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   568  
   569  	// create a second delegation to this validator
   570  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   571  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   572  	require.Equal(t, delTokens, issuedShares.RoundInt())
   573  
   574  	// add bonded tokens to pool for delegations
   575  	bondedPool := app.StakingKeeper.GetBondedPool(ctx)
   576  	require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
   577  	app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
   578  
   579  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   580  	require.True(t, validator.IsBonded())
   581  
   582  	delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares)
   583  	app.StakingKeeper.SetDelegation(ctx, delegation)
   584  
   585  	ctx = ctx.WithBlockHeight(10)
   586  	ctx = ctx.WithBlockTime(time.Unix(333, 0))
   587  
   588  	// unbond the all self-delegation to put validator in unbonding state
   589  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec())
   590  	require.NoError(t, err)
   591  
   592  	// end block
   593  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   594  
   595  	// unbond all the remaining delegation
   596  	_, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], delTokens.ToDec())
   597  	require.NoError(t, err)
   598  
   599  	// validator should still be in state and still be in unbonding state
   600  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   601  	require.True(t, found)
   602  	require.Equal(t, validator.Status, types.Unbonding)
   603  
   604  	// unbond the validator
   605  	ctx = ctx.WithBlockTime(validator.UnbondingTime)
   606  	app.StakingKeeper.UnbondAllMatureValidators(ctx)
   607  
   608  	// validator should now be deleted from state
   609  	_, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
   610  	require.False(t, found)
   611  }
   612  
   613  // Make sure that that the retrieving the delegations doesn't affect the state
   614  func TestGetRedelegationsFromSrcValidator(t *testing.T) {
   615  	_, app, ctx := createTestInput()
   616  
   617  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   618  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   619  
   620  	rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
   621  		time.Unix(0, 0), sdk.NewInt(5),
   622  		sdk.NewDec(5))
   623  
   624  	// set and retrieve a record
   625  	app.StakingKeeper.SetRedelegation(ctx, rd)
   626  	resBond, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
   627  	require.True(t, found)
   628  
   629  	// get the redelegations one time
   630  	redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
   631  	require.Equal(t, 1, len(redelegations))
   632  	require.Equal(t, redelegations[0], resBond)
   633  
   634  	// get the redelegations a second time, should be exactly the same
   635  	redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
   636  	require.Equal(t, 1, len(redelegations))
   637  	require.Equal(t, redelegations[0], resBond)
   638  }
   639  
   640  // tests Get/Set/Remove/Has UnbondingDelegation
   641  func TestRedelegation(t *testing.T) {
   642  	_, app, ctx := createTestInput()
   643  
   644  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   645  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   646  
   647  	rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
   648  		time.Unix(0, 0).UTC(), sdk.NewInt(5),
   649  		sdk.NewDec(5))
   650  
   651  	// test shouldn't have and redelegations
   652  	has := app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
   653  	require.False(t, has)
   654  
   655  	// set and retrieve a record
   656  	app.StakingKeeper.SetRedelegation(ctx, rd)
   657  	resRed, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
   658  	require.True(t, found)
   659  
   660  	redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
   661  	require.Equal(t, 1, len(redelegations))
   662  	require.Equal(t, redelegations[0], resRed)
   663  
   664  	redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5)
   665  	require.Equal(t, 1, len(redelegations))
   666  	require.Equal(t, redelegations[0], resRed)
   667  
   668  	redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
   669  	require.Equal(t, 1, len(redelegations))
   670  	require.Equal(t, redelegations[0], resRed)
   671  
   672  	// check if has the redelegation
   673  	has = app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
   674  	require.True(t, has)
   675  
   676  	// modify a records, save, and retrieve
   677  	rd.Entries[0].SharesDst = sdk.NewDec(21)
   678  	app.StakingKeeper.SetRedelegation(ctx, rd)
   679  
   680  	resRed, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
   681  	require.True(t, found)
   682  	require.Equal(t, rd, resRed)
   683  
   684  	redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0])
   685  	require.Equal(t, 1, len(redelegations))
   686  	require.Equal(t, redelegations[0], resRed)
   687  
   688  	redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5)
   689  	require.Equal(t, 1, len(redelegations))
   690  	require.Equal(t, redelegations[0], resRed)
   691  
   692  	// delete a record
   693  	app.StakingKeeper.RemoveRedelegation(ctx, rd)
   694  	_, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
   695  	require.False(t, found)
   696  
   697  	redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5)
   698  	require.Equal(t, 0, len(redelegations))
   699  
   700  	redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil)
   701  	require.Equal(t, 0, len(redelegations))
   702  }
   703  
   704  func TestRedelegateToSameValidator(t *testing.T) {
   705  	_, app, ctx := createTestInput()
   706  
   707  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(0))
   708  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   709  
   710  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   711  	startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), valTokens))
   712  
   713  	// add bonded tokens to pool for delegations
   714  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   715  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins))
   716  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   717  
   718  	// create a validator with a self-delegation
   719  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   720  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   721  	require.Equal(t, valTokens, issuedShares.RoundInt())
   722  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   723  	require.True(t, validator.IsBonded())
   724  
   725  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   726  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   727  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   728  
   729  	_, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5))
   730  	require.Error(t, err)
   731  }
   732  
   733  func TestRedelegationMaxEntries(t *testing.T) {
   734  	_, app, ctx := createTestInput()
   735  
   736  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   737  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   738  
   739  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 20)
   740  	startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))
   741  
   742  	// add bonded tokens to pool for delegations
   743  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   744  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins))
   745  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   746  
   747  	// create a validator with a self-delegation
   748  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   749  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   750  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   751  	require.Equal(t, valTokens, issuedShares.RoundInt())
   752  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   753  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   754  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   755  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   756  
   757  	// create a second validator
   758  	validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1])
   759  	validator2, issuedShares = validator2.AddTokensFromDel(valTokens)
   760  	require.Equal(t, valTokens, issuedShares.RoundInt())
   761  
   762  	validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true)
   763  	require.Equal(t, types.Bonded, validator2.Status)
   764  
   765  	maxEntries := app.StakingKeeper.MaxEntries(ctx)
   766  
   767  	// redelegations should pass
   768  	var completionTime time.Time
   769  	for i := uint32(0); i < maxEntries; i++ {
   770  		var err error
   771  		completionTime, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1))
   772  		require.NoError(t, err)
   773  	}
   774  
   775  	// an additional redelegation should fail due to max entries
   776  	_, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1))
   777  	require.Error(t, err)
   778  
   779  	// mature redelegations
   780  	ctx = ctx.WithBlockTime(completionTime)
   781  	_, err = app.StakingKeeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1])
   782  	require.NoError(t, err)
   783  
   784  	// redelegation should work again
   785  	_, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1))
   786  	require.NoError(t, err)
   787  }
   788  
   789  func TestRedelegateSelfDelegation(t *testing.T) {
   790  	_, app, ctx := createTestInput()
   791  
   792  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   793  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   794  
   795  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30)
   796  	startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))
   797  
   798  	// add bonded tokens to pool for delegations
   799  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   800  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins))
   801  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   802  
   803  	// create a validator with a self-delegation
   804  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   805  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   806  	require.NoError(t, err)
   807  
   808  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   809  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   810  	require.Equal(t, valTokens, issuedShares.RoundInt())
   811  
   812  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   813  
   814  	val0AccAddr := sdk.AccAddress(addrVals[0])
   815  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   816  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   817  
   818  	// create a second validator
   819  	validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1])
   820  	validator2, issuedShares = validator2.AddTokensFromDel(valTokens)
   821  	require.Equal(t, valTokens, issuedShares.RoundInt())
   822  	validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true)
   823  	require.Equal(t, types.Bonded, validator2.Status)
   824  
   825  	// create a second delegation to validator 1
   826  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   827  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   828  	require.Equal(t, delTokens, issuedShares.RoundInt())
   829  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   830  
   831  	delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares)
   832  	app.StakingKeeper.SetDelegation(ctx, delegation)
   833  
   834  	_, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec())
   835  	require.NoError(t, err)
   836  
   837  	// end block
   838  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2)
   839  
   840  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   841  	require.True(t, found)
   842  	require.Equal(t, valTokens, validator.Tokens)
   843  	require.Equal(t, types.Unbonding, validator.Status)
   844  }
   845  
   846  func TestRedelegateFromUnbondingValidator(t *testing.T) {
   847  	_, app, ctx := createTestInput()
   848  
   849  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   850  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   851  
   852  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30)
   853  	startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))
   854  
   855  	// add bonded tokens to pool for delegations
   856  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   857  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins))
   858  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   859  
   860  	// create a validator with a self-delegation
   861  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   862  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   863  	require.NoError(t, err)
   864  
   865  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   866  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   867  	require.Equal(t, valTokens, issuedShares.RoundInt())
   868  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   869  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   870  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   871  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   872  
   873  	// create a second delegation to this validator
   874  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   875  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   876  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   877  	require.Equal(t, delTokens, issuedShares.RoundInt())
   878  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   879  	delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares)
   880  	app.StakingKeeper.SetDelegation(ctx, delegation)
   881  
   882  	// create a second validator
   883  	validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1])
   884  	validator2, issuedShares = validator2.AddTokensFromDel(valTokens)
   885  	require.Equal(t, valTokens, issuedShares.RoundInt())
   886  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true)
   887  
   888  	header := ctx.BlockHeader()
   889  	blockHeight := int64(10)
   890  	header.Height = blockHeight
   891  	blockTime := time.Unix(333, 0)
   892  	header.Time = blockTime
   893  	ctx = ctx.WithBlockHeader(header)
   894  
   895  	// unbond the all self-delegation to put validator in unbonding state
   896  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec())
   897  	require.NoError(t, err)
   898  
   899  	// end block
   900  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   901  
   902  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   903  	require.True(t, found)
   904  	require.Equal(t, blockHeight, validator.UnbondingHeight)
   905  	params := app.StakingKeeper.GetParams(ctx)
   906  	require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
   907  
   908  	// change the context
   909  	header = ctx.BlockHeader()
   910  	blockHeight2 := int64(20)
   911  	header.Height = blockHeight2
   912  	blockTime2 := time.Unix(444, 0)
   913  	header.Time = blockTime2
   914  	ctx = ctx.WithBlockHeader(header)
   915  
   916  	// unbond some of the other delegation's shares
   917  	redelegateTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
   918  	_, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegateTokens.ToDec())
   919  	require.NoError(t, err)
   920  
   921  	// retrieve the unbonding delegation
   922  	ubd, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1])
   923  	require.True(t, found)
   924  	require.Len(t, ubd.Entries, 1)
   925  	assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight)
   926  	assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime))
   927  }
   928  
   929  func TestRedelegateFromUnbondedValidator(t *testing.T) {
   930  	_, app, ctx := createTestInput()
   931  
   932  	addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0))
   933  	addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
   934  
   935  	startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30)
   936  	startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens))
   937  
   938  	// add bonded tokens to pool for delegations
   939  	notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
   940  	require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins))
   941  	app.AccountKeeper.SetModuleAccount(ctx, notBondedPool)
   942  
   943  	// create a validator with a self-delegation
   944  	validator := teststaking.NewValidator(t, addrVals[0], PKs[0])
   945  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
   946  	require.NoError(t, err)
   947  
   948  	valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   949  	validator, issuedShares := validator.AddTokensFromDel(valTokens)
   950  	require.Equal(t, valTokens, issuedShares.RoundInt())
   951  	validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   952  	val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
   953  	selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
   954  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
   955  
   956  	// create a second delegation to this validator
   957  	app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator)
   958  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10)
   959  	validator, issuedShares = validator.AddTokensFromDel(delTokens)
   960  	require.Equal(t, delTokens, issuedShares.RoundInt())
   961  	_ = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
   962  	delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares)
   963  	app.StakingKeeper.SetDelegation(ctx, delegation)
   964  
   965  	// create a second validator
   966  	validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1])
   967  	validator2, issuedShares = validator2.AddTokensFromDel(valTokens)
   968  	require.Equal(t, valTokens, issuedShares.RoundInt())
   969  	validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true)
   970  	require.Equal(t, types.Bonded, validator2.Status)
   971  
   972  	ctx = ctx.WithBlockHeight(10)
   973  	ctx = ctx.WithBlockTime(time.Unix(333, 0))
   974  
   975  	// unbond the all self-delegation to put validator in unbonding state
   976  	_, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec())
   977  	require.NoError(t, err)
   978  
   979  	// end block
   980  	applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1)
   981  
   982  	validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
   983  	require.True(t, found)
   984  	require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight)
   985  	params := app.StakingKeeper.GetParams(ctx)
   986  	require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime))
   987  
   988  	// unbond the validator
   989  	app.StakingKeeper.UnbondingToUnbonded(ctx, validator)
   990  
   991  	// redelegate some of the delegation's shares
   992  	redelegationTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6)
   993  	_, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegationTokens.ToDec())
   994  	require.NoError(t, err)
   995  
   996  	// no red should have been found
   997  	red, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
   998  	require.False(t, found, "%v", red)
   999  }