github.com/Finschia/finschia-sdk@v0.48.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 validator = 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 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 332 require.True(t, validator.IsBonded()) 333 334 selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) 335 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 336 337 // add bonded tokens to pool for delegations 338 bondedPool := app.StakingKeeper.GetBondedPool(ctx) 339 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 340 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 341 342 // create a second delegation to this validator 343 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 344 validator, issuedShares = validator.AddTokensFromDel(delTokens) 345 require.True(t, validator.IsBonded()) 346 require.Equal(t, delTokens, issuedShares.RoundInt()) 347 348 // add bonded tokens to pool for delegations 349 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 350 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 351 352 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 353 delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) 354 app.StakingKeeper.SetDelegation(ctx, delegation) 355 356 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 357 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], app.StakingKeeper.TokensFromConsensusPower(ctx, 6).ToDec()) 358 require.NoError(t, err) 359 360 // end block 361 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 362 363 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 364 require.True(t, found) 365 require.Equal(t, app.StakingKeeper.TokensFromConsensusPower(ctx, 14), validator.Tokens) 366 require.Equal(t, types.Unbonding, validator.Status) 367 require.True(t, validator.Jailed) 368 } 369 370 func TestUndelegateFromUnbondingValidator(t *testing.T) { 371 _, app, ctx := createTestInput() 372 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 373 delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) 374 375 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 376 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 377 378 // create a validator with a self-delegation 379 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 380 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 381 382 validator, issuedShares := validator.AddTokensFromDel(delTokens) 383 require.Equal(t, delTokens, issuedShares.RoundInt()) 384 385 // add bonded tokens to pool for delegations 386 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 387 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins)) 388 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 389 390 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 391 require.True(t, validator.IsBonded()) 392 393 selfDelegation := types.NewDelegation(addrVals[0].Bytes(), addrVals[0], issuedShares) 394 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 395 396 // add bonded tokens to pool for delegations 397 bondedPool := app.StakingKeeper.GetBondedPool(ctx) 398 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 399 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 400 401 // create a second delegation to this validator 402 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 403 404 validator, issuedShares = validator.AddTokensFromDel(delTokens) 405 require.Equal(t, delTokens, issuedShares.RoundInt()) 406 407 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 408 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 409 410 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 411 delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) 412 app.StakingKeeper.SetDelegation(ctx, delegation) 413 414 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 415 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 416 417 header := ctx.BlockHeader() 418 blockHeight := int64(10) 419 header.Height = blockHeight 420 blockTime := time.Unix(333, 0) 421 header.Time = blockTime 422 ctx = ctx.WithBlockHeader(header) 423 424 // unbond the all self-delegation to put validator in unbonding state 425 val0AccAddr := sdk.AccAddress(addrVals[0]) 426 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) 427 require.NoError(t, err) 428 429 // end block 430 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 431 432 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 433 require.True(t, found) 434 require.Equal(t, blockHeight, validator.UnbondingHeight) 435 params := app.StakingKeeper.GetParams(ctx) 436 require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) 437 438 blockHeight2 := int64(20) 439 blockTime2 := time.Unix(444, 0).UTC() 440 ctx = ctx.WithBlockHeight(blockHeight2) 441 ctx = ctx.WithBlockTime(blockTime2) 442 443 // unbond some of the other delegation's shares 444 _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDec(6)) 445 require.NoError(t, err) 446 447 // retrieve the unbonding delegation 448 ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0]) 449 require.True(t, found) 450 require.Len(t, ubd.Entries, 1) 451 require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) 452 assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) 453 assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) 454 } 455 456 func TestUndelegateFromUnbondedValidator(t *testing.T) { 457 _, app, ctx := createTestInput() 458 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 459 delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) 460 461 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 462 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 463 464 // add bonded tokens to pool for delegations 465 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 466 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins)) 467 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 468 469 // create a validator with a self-delegation 470 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 471 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 472 473 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 474 validator, issuedShares := validator.AddTokensFromDel(valTokens) 475 require.Equal(t, valTokens, issuedShares.RoundInt()) 476 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 477 require.True(t, validator.IsBonded()) 478 479 val0AccAddr := sdk.AccAddress(addrVals[0]) 480 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 481 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 482 483 // add bonded tokens to pool for delegations 484 bondedPool := app.StakingKeeper.GetBondedPool(ctx) 485 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 486 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 487 488 // create a second delegation to this validator 489 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 490 validator, issuedShares = validator.AddTokensFromDel(delTokens) 491 require.Equal(t, delTokens, issuedShares.RoundInt()) 492 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 493 require.True(t, validator.IsBonded()) 494 delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) 495 app.StakingKeeper.SetDelegation(ctx, delegation) 496 497 ctx = ctx.WithBlockHeight(10) 498 ctx = ctx.WithBlockTime(time.Unix(333, 0)) 499 500 // unbond the all self-delegation to put validator in unbonding state 501 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) 502 require.NoError(t, err) 503 504 // end block 505 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 506 507 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 508 require.True(t, found) 509 require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) 510 params := app.StakingKeeper.GetParams(ctx) 511 require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) 512 513 // unbond the validator 514 ctx = ctx.WithBlockTime(validator.UnbondingTime) 515 app.StakingKeeper.UnbondAllMatureValidators(ctx) 516 517 // Make sure validator is still in state because there is still an outstanding delegation 518 validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) 519 require.True(t, found) 520 require.Equal(t, validator.Status, types.Unbonded) 521 522 // unbond some of the other delegation's shares 523 unbondTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) 524 _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], unbondTokens.ToDec()) 525 require.NoError(t, err) 526 527 // unbond rest of the other delegation's shares 528 remainingTokens := delTokens.Sub(unbondTokens) 529 _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], remainingTokens.ToDec()) 530 require.NoError(t, err) 531 532 // now validator should be deleted from state 533 validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) 534 require.False(t, found, "%v", validator) 535 } 536 537 func TestUnbondingAllDelegationFromValidator(t *testing.T) { 538 _, app, ctx := createTestInput() 539 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 540 delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) 541 542 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 543 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 544 545 // add bonded tokens to pool for delegations 546 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 547 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), delCoins)) 548 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 549 550 // create a validator with a self-delegation 551 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 552 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 553 554 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 555 validator, issuedShares := validator.AddTokensFromDel(valTokens) 556 require.Equal(t, valTokens, issuedShares.RoundInt()) 557 558 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 559 require.True(t, validator.IsBonded()) 560 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 561 562 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 563 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 564 565 // create a second delegation to this validator 566 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 567 validator, issuedShares = validator.AddTokensFromDel(delTokens) 568 require.Equal(t, delTokens, issuedShares.RoundInt()) 569 570 // add bonded tokens to pool for delegations 571 bondedPool := app.StakingKeeper.GetBondedPool(ctx) 572 require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins)) 573 app.AccountKeeper.SetModuleAccount(ctx, bondedPool) 574 575 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 576 require.True(t, validator.IsBonded()) 577 578 delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) 579 app.StakingKeeper.SetDelegation(ctx, delegation) 580 581 ctx = ctx.WithBlockHeight(10) 582 ctx = ctx.WithBlockTime(time.Unix(333, 0)) 583 584 // unbond the all self-delegation to put validator in unbonding state 585 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) 586 require.NoError(t, err) 587 588 // end block 589 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 590 591 // unbond all the remaining delegation 592 _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], delTokens.ToDec()) 593 require.NoError(t, err) 594 595 // validator should still be in state and still be in unbonding state 596 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 597 require.True(t, found) 598 require.Equal(t, validator.Status, types.Unbonding) 599 600 // unbond the validator 601 ctx = ctx.WithBlockTime(validator.UnbondingTime) 602 app.StakingKeeper.UnbondAllMatureValidators(ctx) 603 604 // validator should now be deleted from state 605 _, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) 606 require.False(t, found) 607 } 608 609 // Make sure that that the retrieving the delegations doesn't affect the state 610 func TestGetRedelegationsFromSrcValidator(t *testing.T) { 611 _, app, ctx := createTestInput() 612 613 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 614 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 615 616 rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, 617 time.Unix(0, 0), sdk.NewInt(5), 618 sdk.NewDec(5)) 619 620 // set and retrieve a record 621 app.StakingKeeper.SetRedelegation(ctx, rd) 622 resBond, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) 623 require.True(t, found) 624 625 // get the redelegations one time 626 redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) 627 require.Equal(t, 1, len(redelegations)) 628 require.Equal(t, redelegations[0], resBond) 629 630 // get the redelegations a second time, should be exactly the same 631 redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) 632 require.Equal(t, 1, len(redelegations)) 633 require.Equal(t, redelegations[0], resBond) 634 } 635 636 // tests Get/Set/Remove/Has UnbondingDelegation 637 func TestRedelegation(t *testing.T) { 638 _, app, ctx := createTestInput() 639 640 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 641 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 642 643 rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, 644 time.Unix(0, 0).UTC(), sdk.NewInt(5), 645 sdk.NewDec(5)) 646 647 // test shouldn't have and redelegations 648 has := app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) 649 require.False(t, has) 650 651 // set and retrieve a record 652 app.StakingKeeper.SetRedelegation(ctx, rd) 653 resRed, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) 654 require.True(t, found) 655 656 redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) 657 require.Equal(t, 1, len(redelegations)) 658 require.Equal(t, redelegations[0], resRed) 659 660 redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) 661 require.Equal(t, 1, len(redelegations)) 662 require.Equal(t, redelegations[0], resRed) 663 664 redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) 665 require.Equal(t, 1, len(redelegations)) 666 require.Equal(t, redelegations[0], resRed) 667 668 // check if has the redelegation 669 has = app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) 670 require.True(t, has) 671 672 // modify a records, save, and retrieve 673 rd.Entries[0].SharesDst = sdk.NewDec(21) 674 app.StakingKeeper.SetRedelegation(ctx, rd) 675 676 resRed, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) 677 require.True(t, found) 678 require.Equal(t, rd, resRed) 679 680 redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) 681 require.Equal(t, 1, len(redelegations)) 682 require.Equal(t, redelegations[0], resRed) 683 684 redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) 685 require.Equal(t, 1, len(redelegations)) 686 require.Equal(t, redelegations[0], resRed) 687 688 // delete a record 689 app.StakingKeeper.RemoveRedelegation(ctx, rd) 690 _, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) 691 require.False(t, found) 692 693 redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) 694 require.Equal(t, 0, len(redelegations)) 695 696 redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) 697 require.Equal(t, 0, len(redelegations)) 698 } 699 700 func TestRedelegateToSameValidator(t *testing.T) { 701 _, app, ctx := createTestInput() 702 703 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(0)) 704 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 705 706 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 707 startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), valTokens)) 708 709 // add bonded tokens to pool for delegations 710 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 711 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins)) 712 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 713 714 // create a validator with a self-delegation 715 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 716 validator, issuedShares := validator.AddTokensFromDel(valTokens) 717 require.Equal(t, valTokens, issuedShares.RoundInt()) 718 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 719 require.True(t, validator.IsBonded()) 720 721 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 722 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 723 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 724 725 _, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) 726 require.Error(t, err) 727 } 728 729 func TestRedelegationMaxEntries(t *testing.T) { 730 _, app, ctx := createTestInput() 731 732 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 733 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 734 735 startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 20) 736 startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) 737 738 // add bonded tokens to pool for delegations 739 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 740 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins)) 741 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 742 743 // create a validator with a self-delegation 744 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 745 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 746 validator, issuedShares := validator.AddTokensFromDel(valTokens) 747 require.Equal(t, valTokens, issuedShares.RoundInt()) 748 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 749 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 750 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 751 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 752 753 // create a second validator 754 validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1]) 755 validator2, issuedShares = validator2.AddTokensFromDel(valTokens) 756 require.Equal(t, valTokens, issuedShares.RoundInt()) 757 758 validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) 759 require.Equal(t, types.Bonded, validator2.Status) 760 761 maxEntries := app.StakingKeeper.MaxEntries(ctx) 762 763 // redelegations should pass 764 var completionTime time.Time 765 for i := uint32(0); i < maxEntries; i++ { 766 var err error 767 completionTime, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) 768 require.NoError(t, err) 769 } 770 771 // an additional redelegation should fail due to max entries 772 _, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) 773 require.Error(t, err) 774 775 // mature redelegations 776 ctx = ctx.WithBlockTime(completionTime) 777 _, err = app.StakingKeeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) 778 require.NoError(t, err) 779 780 // redelegation should work again 781 _, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) 782 require.NoError(t, err) 783 } 784 785 func TestRedelegateSelfDelegation(t *testing.T) { 786 _, app, ctx := createTestInput() 787 788 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 789 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 790 791 startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30) 792 startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) 793 794 // add bonded tokens to pool for delegations 795 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 796 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins)) 797 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 798 799 // create a validator with a self-delegation 800 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 801 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 802 803 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 804 validator, issuedShares := validator.AddTokensFromDel(valTokens) 805 require.Equal(t, valTokens, issuedShares.RoundInt()) 806 807 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 808 809 val0AccAddr := sdk.AccAddress(addrVals[0]) 810 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 811 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 812 813 // create a second validator 814 validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1]) 815 validator2, issuedShares = validator2.AddTokensFromDel(valTokens) 816 require.Equal(t, valTokens, issuedShares.RoundInt()) 817 validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) 818 require.Equal(t, types.Bonded, validator2.Status) 819 820 // create a second delegation to validator 1 821 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 822 validator, issuedShares = validator.AddTokensFromDel(delTokens) 823 require.Equal(t, delTokens, issuedShares.RoundInt()) 824 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 825 826 delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) 827 app.StakingKeeper.SetDelegation(ctx, delegation) 828 829 _, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) 830 require.NoError(t, err) 831 832 // end block 833 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 2) 834 835 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 836 require.True(t, found) 837 require.Equal(t, valTokens, validator.Tokens) 838 require.Equal(t, types.Unbonding, validator.Status) 839 } 840 841 func TestRedelegateFromUnbondingValidator(t *testing.T) { 842 _, app, ctx := createTestInput() 843 844 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 845 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 846 847 startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30) 848 startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) 849 850 // add bonded tokens to pool for delegations 851 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 852 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins)) 853 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 854 855 // create a validator with a self-delegation 856 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 857 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 858 859 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 860 validator, issuedShares := validator.AddTokensFromDel(valTokens) 861 require.Equal(t, valTokens, issuedShares.RoundInt()) 862 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 863 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 864 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 865 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 866 867 // create a second delegation to this validator 868 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 869 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 870 validator, issuedShares = validator.AddTokensFromDel(delTokens) 871 require.Equal(t, delTokens, issuedShares.RoundInt()) 872 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 873 delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) 874 app.StakingKeeper.SetDelegation(ctx, delegation) 875 876 // create a second validator 877 validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1]) 878 validator2, issuedShares = validator2.AddTokensFromDel(valTokens) 879 require.Equal(t, valTokens, issuedShares.RoundInt()) 880 validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) 881 882 header := ctx.BlockHeader() 883 blockHeight := int64(10) 884 header.Height = blockHeight 885 blockTime := time.Unix(333, 0) 886 header.Time = blockTime 887 ctx = ctx.WithBlockHeader(header) 888 889 // unbond the all self-delegation to put validator in unbonding state 890 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) 891 require.NoError(t, err) 892 893 // end block 894 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 895 896 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 897 require.True(t, found) 898 require.Equal(t, blockHeight, validator.UnbondingHeight) 899 params := app.StakingKeeper.GetParams(ctx) 900 require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) 901 902 // change the context 903 header = ctx.BlockHeader() 904 blockHeight2 := int64(20) 905 header.Height = blockHeight2 906 blockTime2 := time.Unix(444, 0) 907 header.Time = blockTime2 908 ctx = ctx.WithBlockHeader(header) 909 910 // unbond some of the other delegation's shares 911 redelegateTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) 912 _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegateTokens.ToDec()) 913 require.NoError(t, err) 914 915 // retrieve the unbonding delegation 916 ubd, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1]) 917 require.True(t, found) 918 require.Len(t, ubd.Entries, 1) 919 assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) 920 assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) 921 } 922 923 func TestRedelegateFromUnbondedValidator(t *testing.T) { 924 _, app, ctx := createTestInput() 925 926 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) 927 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 928 929 startTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 30) 930 startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) 931 932 // add bonded tokens to pool for delegations 933 notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) 934 require.NoError(t, simapp.FundModuleAccount(app, ctx, notBondedPool.GetName(), startCoins)) 935 app.AccountKeeper.SetModuleAccount(ctx, notBondedPool) 936 937 // create a validator with a self-delegation 938 validator := teststaking.NewValidator(t, addrVals[0], PKs[0]) 939 app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) 940 941 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 942 validator, issuedShares := validator.AddTokensFromDel(valTokens) 943 require.Equal(t, valTokens, issuedShares.RoundInt()) 944 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 945 val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) 946 selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) 947 app.StakingKeeper.SetDelegation(ctx, selfDelegation) 948 949 // create a second delegation to this validator 950 app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) 951 delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 952 validator, issuedShares = validator.AddTokensFromDel(delTokens) 953 require.Equal(t, delTokens, issuedShares.RoundInt()) 954 validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) 955 delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) 956 app.StakingKeeper.SetDelegation(ctx, delegation) 957 958 // create a second validator 959 validator2 := teststaking.NewValidator(t, addrVals[1], PKs[1]) 960 validator2, issuedShares = validator2.AddTokensFromDel(valTokens) 961 require.Equal(t, valTokens, issuedShares.RoundInt()) 962 validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) 963 require.Equal(t, types.Bonded, validator2.Status) 964 965 ctx = ctx.WithBlockHeight(10) 966 ctx = ctx.WithBlockTime(time.Unix(333, 0)) 967 968 // unbond the all self-delegation to put validator in unbonding state 969 _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) 970 require.NoError(t, err) 971 972 // end block 973 applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) 974 975 validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) 976 require.True(t, found) 977 require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) 978 params := app.StakingKeeper.GetParams(ctx) 979 require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) 980 981 // unbond the validator 982 app.StakingKeeper.UnbondingToUnbonded(ctx, validator) 983 984 // redelegate some of the delegation's shares 985 redelegationTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) 986 _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegationTokens.ToDec()) 987 require.NoError(t, err) 988 989 // no red should have been found 990 red, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) 991 require.False(t, found, "%v", red) 992 }