github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/staking/handler_test.go (about) 1 package staking 2 3 import ( 4 "strings" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 11 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 12 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1" 13 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 14 15 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 16 keep "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/keeper" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 18 ) 19 20 func TestValidatorByPowerIndex(t *testing.T) { 21 validatorAddr, validatorAddr3 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) 22 23 initPower := int64(1000000) 24 initBond := sdk.TokensFromConsensusPower(initPower) 25 ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower) 26 27 // create validator 28 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) 29 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 30 require.NoError(t, err) 31 require.NotNil(t, res) 32 33 // must end-block 34 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 35 require.Equal(t, 1, len(updates)) 36 37 // verify the self-delegation exists 38 bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 39 require.True(t, found) 40 gotBond := bond.Shares.RoundInt() 41 require.Equal(t, initBond, gotBond) 42 43 // verify that the by power index exists 44 validator, found := keeper.GetValidator(ctx, validatorAddr) 45 require.True(t, found) 46 power := GetValidatorsByPowerIndexKey(validator) 47 require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) 48 49 // create a second validator keep it bonded 50 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], initBond) 51 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 52 require.NoError(t, err) 53 require.NotNil(t, res) 54 55 // must end-block 56 updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) 57 require.Equal(t, 1, len(updates)) 58 59 // slash and jail the first validator 60 consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) 61 keeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) 62 keeper.Jail(ctx, consAddr0) 63 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 64 65 validator, found = keeper.GetValidator(ctx, validatorAddr) 66 require.True(t, found) 67 require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding 68 require.Equal(t, initBond.QuoRaw(2), validator.Tokens) // ensure tokens slashed 69 keeper.Unjail(ctx, consAddr0) 70 71 // the old power record should have been deleted as the power changed 72 require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) 73 74 // but the new power record should have been created 75 validator, found = keeper.GetValidator(ctx, validatorAddr) 76 require.True(t, found) 77 power2 := GetValidatorsByPowerIndexKey(validator) 78 require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2)) 79 80 // now the new record power index should be the same as the original record 81 power3 := GetValidatorsByPowerIndexKey(validator) 82 require.Equal(t, power2, power3) 83 84 // unbond self-delegation 85 totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() 86 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) 87 msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) 88 89 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 90 require.NoError(t, err) 91 require.NotNil(t, res) 92 93 var finishTime time.Time 94 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 95 96 ctx.SetBlockTime(finishTime) 97 EndBlocker(ctx, keeper) 98 EndBlocker(ctx, keeper) 99 100 // verify that by power key nolonger exists 101 _, found = keeper.GetValidator(ctx, validatorAddr) 102 require.False(t, found) 103 require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power3)) 104 } 105 106 func TestDuplicatesMsgCreateValidator(t *testing.T) { 107 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 108 109 addr1, addr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) 110 pk1, pk2 := keep.PKs[0], keep.PKs[1] 111 112 valTokens := sdk.TokensFromConsensusPower(10) 113 msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, valTokens) 114 res, err := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper) 115 require.NoError(t, err) 116 require.NotNil(t, res) 117 118 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 119 120 validator, found := keeper.GetValidator(ctx, addr1) 121 require.True(t, found) 122 assert.Equal(t, sdk.Bonded, validator.Status) 123 assert.Equal(t, addr1, validator.OperatorAddress) 124 assert.Equal(t, pk1, validator.ConsPubKey) 125 assert.Equal(t, valTokens, validator.BondedTokens()) 126 assert.Equal(t, valTokens.ToDec(), validator.DelegatorShares) 127 assert.Equal(t, Description{}, validator.Description) 128 129 // two validators can't have the same operator address 130 msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens) 131 res, err = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper) 132 require.Error(t, err) 133 require.Nil(t, res) 134 135 // two validators can't have the same pubkey 136 msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, valTokens) 137 res, err = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper) 138 require.Error(t, err) 139 require.Nil(t, res) 140 141 // must have different pubkey and operator 142 msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, valTokens) 143 res, err = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper) 144 require.NoError(t, err) 145 require.NotNil(t, res) 146 147 // must end-block 148 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 149 require.Equal(t, 1, len(updates)) 150 151 validator, found = keeper.GetValidator(ctx, addr2) 152 153 require.True(t, found) 154 assert.Equal(t, sdk.Bonded, validator.Status) 155 assert.Equal(t, addr2, validator.OperatorAddress) 156 assert.Equal(t, pk2, validator.ConsPubKey) 157 assert.True(sdk.IntEq(t, valTokens, validator.Tokens)) 158 assert.True(sdk.DecEq(t, valTokens.ToDec(), validator.DelegatorShares)) 159 assert.Equal(t, Description{}, validator.Description) 160 } 161 162 func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { 163 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 164 165 addr := sdk.ValAddress(keep.Addrs[0]) 166 invalidPk := secp256k1.GenPrivKey().PubKey() 167 168 // invalid pukKey type should not be allowed 169 msgCreateValidator := NewTestMsgCreateValidator(addr, invalidPk, sdk.NewInt(10)) 170 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 171 require.Error(t, err) 172 require.Nil(t, res) 173 174 ctx.SetConsensusParams(&abci.ConsensusParams{ 175 Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeSecp256k1}}, 176 }) 177 178 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 179 require.NoError(t, err) 180 require.NotNil(t, res) 181 } 182 183 func TestLegacyValidatorDelegations(t *testing.T) { 184 ctx, _, keeper, _ := keep.CreateTestInput(t, false, int64(1000)) 185 186 bondAmount := sdk.TokensFromConsensusPower(10) 187 valAddr := sdk.ValAddress(keep.Addrs[0]) 188 valConsPubKey, valConsAddr := keep.PKs[0], sdk.ConsAddress(keep.PKs[0].Address()) 189 delAddr := keep.Addrs[1] 190 191 // create validator 192 msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) 193 res, err := handleMsgCreateValidator(ctx, msgCreateVal, keeper) 194 require.NoError(t, err) 195 require.NotNil(t, res) 196 197 // must end-block 198 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 199 require.Equal(t, 1, len(updates)) 200 201 // verify the validator exists and has the correct attributes 202 validator, found := keeper.GetValidator(ctx, valAddr) 203 require.True(t, found) 204 require.Equal(t, sdk.Bonded, validator.Status) 205 require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) 206 require.Equal(t, bondAmount, validator.BondedTokens()) 207 208 // delegate tokens to the validator 209 msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount) 210 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 211 require.NoError(t, err) 212 require.NotNil(t, res) 213 214 // verify validator bonded shares 215 validator, found = keeper.GetValidator(ctx, valAddr) 216 require.True(t, found) 217 require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt()) 218 require.Equal(t, bondAmount.MulRaw(2), validator.BondedTokens()) 219 220 // unbond validator total self-delegations (which should jail the validator) 221 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, bondAmount) 222 msgUndelegate := NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) 223 224 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 225 require.NoError(t, err) 226 require.NotNil(t, res) 227 228 var finishTime time.Time 229 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 230 ctx.SetBlockTime(finishTime) 231 EndBlocker(ctx, keeper) 232 233 // verify the validator record still exists, is jailed, and has correct tokens 234 validator, found = keeper.GetValidator(ctx, valAddr) 235 require.True(t, found) 236 require.True(t, validator.Jailed) 237 require.Equal(t, bondAmount, validator.Tokens) 238 239 // verify delegation still exists 240 bond, found := keeper.GetDelegation(ctx, delAddr, valAddr) 241 require.True(t, found) 242 require.Equal(t, bondAmount, bond.Shares.RoundInt()) 243 require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) 244 245 // verify the validator can still self-delegate 246 msgSelfDelegate := NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount) 247 res, err = handleMsgDelegate(ctx, msgSelfDelegate, keeper) 248 require.NoError(t, err) 249 require.NotNil(t, res) 250 251 // verify validator bonded shares 252 validator, found = keeper.GetValidator(ctx, valAddr) 253 require.True(t, found) 254 require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt()) 255 require.Equal(t, bondAmount.MulRaw(2), validator.Tokens) 256 257 // unjail the validator now that is has non-zero self-delegated shares 258 keeper.Unjail(ctx, valConsAddr) 259 260 // verify the validator can now accept delegations 261 msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount) 262 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 263 require.NoError(t, err) 264 require.NotNil(t, res) 265 266 // verify validator bonded shares 267 validator, found = keeper.GetValidator(ctx, valAddr) 268 require.True(t, found) 269 require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt()) 270 require.Equal(t, bondAmount.MulRaw(3), validator.Tokens) 271 272 // verify new delegation 273 bond, found = keeper.GetDelegation(ctx, delAddr, valAddr) 274 require.True(t, found) 275 require.Equal(t, bondAmount.MulRaw(2), bond.Shares.RoundInt()) 276 require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt()) 277 } 278 279 func TestIncrementsMsgDelegate(t *testing.T) { 280 initPower := int64(1000) 281 initBond := sdk.TokensFromConsensusPower(initPower) 282 ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower) 283 params := keeper.GetParams(ctx) 284 285 bondAmount := sdk.TokensFromConsensusPower(10) 286 validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] 287 288 // first create validator 289 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount) 290 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 291 require.NoError(t, err) 292 require.NotNil(t, res) 293 294 // apply TM updates 295 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 296 297 validator, found := keeper.GetValidator(ctx, validatorAddr) 298 require.True(t, found) 299 require.Equal(t, sdk.Bonded, validator.Status) 300 require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) 301 require.Equal(t, bondAmount, validator.BondedTokens(), "validator: %v", validator) 302 303 _, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) 304 require.False(t, found) 305 306 bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 307 require.True(t, found) 308 require.Equal(t, bondAmount, bond.Shares.RoundInt()) 309 310 bondedTokens := keeper.TotalBondedTokens(ctx) 311 require.Equal(t, bondAmount.ToDec().Int, bondedTokens.Int) 312 313 // just send the same msgbond multiple times 314 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount) 315 316 for i := int64(0); i < 5; i++ { 317 ctx.SetBlockHeight(i) 318 319 res, err := handleMsgDelegate(ctx, msgDelegate, keeper) 320 require.NoError(t, err) 321 require.NotNil(t, res) 322 323 //Check that the accounts and the bond account have the appropriate values 324 validator, found := keeper.GetValidator(ctx, validatorAddr) 325 require.True(t, found) 326 bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) 327 require.True(t, found) 328 329 expBond := bondAmount.MulRaw(i + 1) 330 expDelegatorShares := bondAmount.MulRaw(i + 2) // (1 self delegation) 331 expDelegatorAcc := initBond.Sub(expBond) 332 333 gotBond := bond.Shares.RoundInt() 334 gotDelegatorShares := validator.DelegatorShares.RoundInt() 335 gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom) 336 337 require.Equal(t, expBond, gotBond, 338 "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", 339 i, expBond, gotBond, validator, bond) 340 require.Equal(t, expDelegatorShares, gotDelegatorShares, 341 "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", 342 i, expDelegatorShares, gotDelegatorShares, validator, bond) 343 require.Equal(t, expDelegatorAcc.ToDec().Int, gotDelegatorAcc.Int, 344 "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", 345 i, expDelegatorAcc, gotDelegatorAcc, validator, bond) 346 } 347 } 348 349 func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { 350 validatorAddr := sdk.ValAddress(keep.Addrs[0]) 351 352 initPower := int64(100) 353 initBond := sdk.TokensFromConsensusPower(100) 354 ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower) 355 356 // create validator 357 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) 358 msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) 359 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 360 require.NoError(t, err) 361 require.NotNil(t, res) 362 363 // must end-block 364 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 365 require.Equal(t, 1, len(updates)) 366 367 // verify the self-delegation exists 368 bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 369 require.True(t, found) 370 gotBond := bond.Shares.RoundInt() 371 require.Equal(t, initBond, gotBond, 372 "initBond: %v\ngotBond: %v\nbond: %v\n", 373 initBond, gotBond, bond) 374 375 newMinSelfDelegation := sdk.OneInt() 376 msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) 377 res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper) 378 require.Error(t, err) 379 require.Nil(t, res) 380 } 381 382 func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { 383 validatorAddr := sdk.ValAddress(keep.Addrs[0]) 384 385 initPower := int64(100) 386 initBond := sdk.TokensFromConsensusPower(100) 387 ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower) 388 389 // create validator 390 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) 391 msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) 392 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 393 require.NoError(t, err) 394 require.NotNil(t, res) 395 396 // must end-block 397 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 398 require.Equal(t, 1, len(updates)) 399 400 // verify the self-delegation exists 401 bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 402 require.True(t, found) 403 gotBond := bond.Shares.RoundInt() 404 require.Equal(t, initBond, gotBond, 405 "initBond: %v\ngotBond: %v\nbond: %v\n", 406 initBond, gotBond, bond) 407 408 newMinSelfDelegation := initBond.Add(sdk.OneInt()) 409 msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) 410 res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper) 411 require.Error(t, err) 412 require.Nil(t, res) 413 } 414 415 func TestIncrementsMsgUnbond(t *testing.T) { 416 initPower := int64(1000) 417 initBond := sdk.TokensFromConsensusPower(initPower) 418 ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower) 419 420 params := keeper.GetParams(ctx) 421 denom := params.BondDenom 422 423 // create validator, delegate 424 validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] 425 426 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) 427 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 428 require.NoError(t, err) 429 require.NotNil(t, res) 430 431 // initial balance 432 amt1 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom) 433 434 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, initBond) 435 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 436 require.NoError(t, err) 437 require.NotNil(t, res) 438 439 // balance should have been subtracted after delegation 440 amt2 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom) 441 require.True(sdk.DecEq(t, amt1.Sub(sdk.NewDecFromInt(initBond)), amt2)) 442 443 // apply TM updates 444 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 445 446 validator, found := keeper.GetValidator(ctx, validatorAddr) 447 require.True(t, found) 448 require.Equal(t, initBond.MulRaw(2), validator.DelegatorShares.RoundInt()) 449 require.Equal(t, initBond.MulRaw(2), validator.BondedTokens()) 450 451 // just send the same msgUnbond multiple times 452 // TODO use decimals here 453 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 454 msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 455 numUnbonds := int64(5) 456 457 for i := int64(0); i < numUnbonds; i++ { 458 res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) 459 require.NoError(t, err) 460 require.NotNil(t, res) 461 462 var finishTime time.Time 463 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 464 465 ctx.SetBlockTime(finishTime) 466 EndBlocker(ctx, keeper) 467 468 // check that the accounts and the bond account have the appropriate values 469 validator, found = keeper.GetValidator(ctx, validatorAddr) 470 require.True(t, found) 471 bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) 472 require.True(t, found) 473 474 expBond := sdk.NewDecFromInt(initBond).Sub(unbondAmt.Amount.Mul(sdk.NewDec(i + 1))) 475 expDelegatorShares := sdk.NewDecFromInt(initBond.MulRaw(2)).Sub(unbondAmt.Amount.Mul(sdk.NewDec(i + 1))) 476 expDelegatorAcc := sdk.NewDecFromInt(initBond).Sub(expBond) 477 478 gotBond := bond.Shares.RoundInt() 479 gotDelegatorShares := validator.DelegatorShares.RoundInt() 480 gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom) 481 482 require.Equal(t, expBond.Int, gotBond.ToDec().Int, 483 "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", 484 i, expBond, gotBond, validator, bond) 485 require.Equal(t, expDelegatorShares.Int, gotDelegatorShares.ToDec().Int, 486 "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", 487 i, expDelegatorShares, gotDelegatorShares, validator, bond) 488 require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(), 489 "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", 490 i, expDelegatorAcc, gotDelegatorAcc, validator, bond) 491 } 492 493 // these are more than we have bonded now 494 errorCases := []sdk.Int{ 495 //1<<64 - 1, // more than int64 power 496 //1<<63 + 1, // more than int64 power 497 sdk.TokensFromConsensusPower(1<<63 - 1), 498 sdk.TokensFromConsensusPower(1 << 31), 499 initBond, 500 } 501 502 for _, c := range errorCases { 503 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, c) 504 msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 505 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 506 require.Error(t, err) 507 require.Nil(t, res) 508 } 509 510 leftBonded := sdk.NewDecFromInt(initBond).Sub(unbondAmt.Amount.Mul(sdk.NewDec(numUnbonds))) 511 512 // should be able to unbond remaining 513 unbondAmt = sdk.NewCoin(sdk.DefaultBondDenom, leftBonded) 514 msgUndelegate = NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 515 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 516 require.NoError(t, err, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) 517 require.NotNil(t, res, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) 518 } 519 520 func TestMultipleMsgCreateValidator(t *testing.T) { 521 initPower := int64(1000) 522 initTokens := sdk.TokensFromConsensusPower(initPower) 523 ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower) 524 525 params := keeper.GetParams(ctx) 526 blockTime := time.Now().UTC() 527 ctx.SetBlockTime(blockTime) 528 529 validatorAddrs := []sdk.ValAddress{ 530 sdk.ValAddress(keep.Addrs[0]), 531 sdk.ValAddress(keep.Addrs[1]), 532 sdk.ValAddress(keep.Addrs[2]), 533 } 534 delegatorAddrs := []sdk.AccAddress{ 535 keep.Addrs[0], 536 keep.Addrs[1], 537 keep.Addrs[2], 538 } 539 540 // bond them all 541 for i, validatorAddr := range validatorAddrs { 542 valTokens := sdk.TokensFromConsensusPower(10) 543 msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, keep.PKs[i], valTokens) 544 545 res, err := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) 546 require.NoError(t, err) 547 require.NotNil(t, res) 548 549 // verify that the account is bonded 550 validators := keeper.GetValidators(ctx, 100) 551 require.Equal(t, (i + 1), len(validators)) 552 553 val := validators[i] 554 balanceExpd := initTokens.Sub(valTokens) 555 balanceGot := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom) 556 557 require.Equal(t, i+1, len(validators), "expected %d validators got %d, validators: %v", i+1, len(validators), validators) 558 require.Equal(t, valTokens, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", 10, val.DelegatorShares) 559 require.Equal(t, balanceExpd.ToDec().Int, balanceGot.Int, "expected account to have %d, got %d", balanceExpd, balanceGot) 560 } 561 562 EndBlocker(ctx, keeper) 563 564 // unbond them all by removing delegation 565 for i, validatorAddr := range validatorAddrs { 566 _, found := keeper.GetValidator(ctx, validatorAddr) 567 require.True(t, found) 568 569 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) 570 msgUndelegate := NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation 571 res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) 572 require.NoError(t, err) 573 require.NotNil(t, res) 574 575 var finishTime time.Time 576 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 577 578 // adds validator into unbonding queue 579 EndBlocker(ctx, keeper) 580 581 // removes validator from queue and set 582 EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), keeper) 583 584 // Check that the validator is deleted from state 585 validators := keeper.GetValidators(ctx, 100) 586 require.Equal(t, len(validatorAddrs)-(i+1), len(validators), 587 "expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators)) 588 589 _, found = keeper.GetValidator(ctx, validatorAddr) 590 require.False(t, found) 591 592 gotBalance := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom) 593 require.Equal(t, initTokens.ToDec().Int, gotBalance.Int, "expected account to have %d, got %d", initTokens, gotBalance) 594 } 595 } 596 597 func TestMultipleMsgDelegate(t *testing.T) { 598 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 599 validatorAddr, delegatorAddrs := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1:] 600 601 // first make a validator 602 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) 603 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 604 require.NoError(t, err) 605 require.NotNil(t, res) 606 607 // delegate multiple parties 608 for _, delegatorAddr := range delegatorAddrs { 609 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) 610 res, err := handleMsgDelegate(ctx, msgDelegate, keeper) 611 require.NoError(t, err) 612 require.NotNil(t, res) 613 614 // check that the account is bonded 615 bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) 616 require.True(t, found) 617 require.NotNil(t, bond, "expected delegatee bond %d to exist", bond) 618 } 619 620 // unbond them all 621 for _, delegatorAddr := range delegatorAddrs { 622 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 623 msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 624 625 res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) 626 require.NoError(t, err) 627 require.NotNil(t, res) 628 629 var finishTime time.Time 630 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 631 632 ctx.SetBlockTime(finishTime) 633 EndBlocker(ctx, keeper) 634 635 // check that the account is unbonded 636 _, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) 637 require.False(t, found) 638 } 639 } 640 641 func TestJailValidator(t *testing.T) { 642 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 643 validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] 644 645 // create the validator 646 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) 647 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 648 require.NoError(t, err) 649 require.NotNil(t, res) 650 651 // bond a delegator 652 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) 653 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 654 require.NoError(t, err) 655 require.NotNil(t, res) 656 657 // unbond the validators bond portion 658 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 659 msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) 660 res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) 661 require.NoError(t, err) 662 require.NotNil(t, res) 663 664 var finishTime time.Time 665 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 666 667 ctx.SetBlockTime(finishTime) 668 EndBlocker(ctx, keeper) 669 670 validator, found := keeper.GetValidator(ctx, validatorAddr) 671 require.True(t, found) 672 require.True(t, validator.Jailed, "%v", validator) 673 674 // test that the delegator can still withdraw their bonds 675 msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 676 677 res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) 678 require.NoError(t, err) 679 require.NotNil(t, res) 680 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 681 682 ctx.SetBlockTime(finishTime) 683 EndBlocker(ctx, keeper) 684 685 // verify that the pubkey can now be reused 686 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 687 require.NoError(t, err) 688 require.NotNil(t, res) 689 } 690 691 func TestValidatorQueue(t *testing.T) { 692 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 693 validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] 694 695 // set the unbonding time 696 params := keeper.GetParams(ctx) 697 params.UnbondingTime = 7 * time.Second 698 keeper.SetParams(ctx, params) 699 700 // create the validator 701 valTokens := sdk.TokensFromConsensusPower(10) 702 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) 703 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 704 require.NoError(t, err) 705 require.NotNil(t, res) 706 707 // bond a delegator 708 delTokens := sdk.TokensFromConsensusPower(10) 709 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, delTokens) 710 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 711 require.NoError(t, err) 712 require.NotNil(t, res) 713 714 EndBlocker(ctx, keeper) 715 716 // unbond the all self-delegation to put validator in unbonding state 717 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens) 718 msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) 719 res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) 720 require.NoError(t, err) 721 require.NotNil(t, res) 722 723 var finishTime time.Time 724 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 725 726 ctx.SetBlockTime(finishTime) 727 EndBlocker(ctx, keeper) 728 729 origHeader := ctx.BlockHeader() 730 731 validator, found := keeper.GetValidator(ctx, validatorAddr) 732 require.True(t, found) 733 require.True(t, validator.IsUnbonding(), "%v", validator) 734 735 // should still be unbonding at time 6 seconds later 736 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6)) 737 EndBlocker(ctx, keeper) 738 739 validator, found = keeper.GetValidator(ctx, validatorAddr) 740 require.True(t, found) 741 require.True(t, validator.IsUnbonding(), "%v", validator) 742 743 // should be in unbonded state at time 7 seconds later 744 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7)) 745 EndBlocker(ctx, keeper) 746 747 validator, found = keeper.GetValidator(ctx, validatorAddr) 748 require.True(t, found) 749 require.True(t, validator.IsUnbonded(), "%v", validator) 750 } 751 752 func TestUnbondingPeriod(t *testing.T) { 753 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 754 validatorAddr := sdk.ValAddress(keep.Addrs[0]) 755 756 // set the unbonding time 757 params := keeper.GetParams(ctx) 758 params.UnbondingTime = 7 * time.Second 759 keeper.SetParams(ctx, params) 760 761 // create the validator 762 valTokens := sdk.TokensFromConsensusPower(10) 763 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) 764 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 765 require.NoError(t, err) 766 require.NotNil(t, res) 767 768 EndBlocker(ctx, keeper) 769 770 // begin unbonding 771 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) 772 msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) 773 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 774 require.NoError(t, err) 775 require.NotNil(t, res) 776 777 origHeader := ctx.BlockHeader() 778 779 _, found := keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 780 require.True(t, found, "should not have unbonded") 781 782 // cannot complete unbonding at same time 783 EndBlocker(ctx, keeper) 784 _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 785 require.True(t, found, "should not have unbonded") 786 787 // cannot complete unbonding at time 6 seconds later 788 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6)) 789 EndBlocker(ctx, keeper) 790 _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 791 require.True(t, found, "should not have unbonded") 792 793 // can complete unbonding at time 7 seconds later 794 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7)) 795 EndBlocker(ctx, keeper) 796 _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 797 require.False(t, found, "should have unbonded") 798 } 799 800 func TestUnbondingFromUnbondingValidator(t *testing.T) { 801 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 802 validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] 803 804 // create the validator 805 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) 806 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 807 require.NoError(t, err) 808 require.NotNil(t, res) 809 810 // bond a delegator 811 msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) 812 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 813 require.NoError(t, err) 814 require.NotNil(t, res) 815 816 // unbond the validators bond portion 817 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 818 msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) 819 res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) 820 require.NoError(t, err) 821 require.NotNil(t, res) 822 823 // change the ctx to Block Time one second before the validator would have unbonded 824 var finishTime time.Time 825 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) 826 ctx.SetBlockTime(finishTime.Add(time.Second * -1)) 827 828 // unbond the delegator from the validator 829 msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) 830 res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) 831 require.NoError(t, err) 832 require.NotNil(t, res) 833 834 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx))) 835 836 // Run the EndBlocker 837 EndBlocker(ctx, keeper) 838 839 // Check to make sure that the unbonding delegation is no longer in state 840 // (meaning it was deleted in the above EndBlocker) 841 _, found := keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) 842 require.False(t, found, "should be removed from state") 843 } 844 845 func TestRedelegationPeriod(t *testing.T) { 846 ctx, AccMapper, keeper, _ := keep.CreateTestInput(t, false, 1000) 847 validatorAddr, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) 848 denom := keeper.GetParams(ctx).BondDenom 849 850 // set the unbonding time 851 params := keeper.GetParams(ctx) 852 params.UnbondingTime = 7 * time.Second 853 keeper.SetParams(ctx, params) 854 855 // create the validators 856 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) 857 858 // initial balance 859 amt1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom) 860 861 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 862 require.NoError(t, err) 863 require.NotNil(t, res) 864 865 // balance should have been subtracted after creation 866 amt2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom) 867 require.Equal(t, amt1.Sub(sdk.NewDec(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") 868 869 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10)) 870 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 871 require.NoError(t, err) 872 require.NotNil(t, res) 873 874 bal1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins() 875 876 // begin redelegate 877 redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 878 msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) 879 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 880 require.NoError(t, err) 881 require.NotNil(t, res) 882 883 // origin account should not lose tokens as with a regular delegation 884 bal2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins() 885 require.Equal(t, bal1, bal2) 886 887 origHeader := ctx.BlockHeader() 888 889 // cannot complete redelegation at same time 890 EndBlocker(ctx, keeper) 891 _, found := keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) 892 require.True(t, found, "should not have unbonded") 893 894 // cannot complete redelegation at time 6 seconds later 895 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6)) 896 EndBlocker(ctx, keeper) 897 _, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) 898 require.True(t, found, "should not have unbonded") 899 900 // can complete redelegation at time 7 seconds later 901 ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7)) 902 EndBlocker(ctx, keeper) 903 _, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) 904 require.False(t, found, "should have unbonded") 905 } 906 907 func TestTransitiveRedelegation(t *testing.T) { 908 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 909 validatorAddr := sdk.ValAddress(keep.Addrs[0]) 910 validatorAddr2 := sdk.ValAddress(keep.Addrs[1]) 911 validatorAddr3 := sdk.ValAddress(keep.Addrs[2]) 912 913 blockTime := time.Now().UTC() 914 ctx.SetBlockTime(blockTime) 915 916 // create the validators 917 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) 918 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 919 require.NoError(t, err) 920 require.NotNil(t, res) 921 922 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10)) 923 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 924 require.NoError(t, err) 925 require.NotNil(t, res) 926 927 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], sdk.NewInt(10)) 928 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 929 require.NoError(t, err) 930 require.NotNil(t, res) 931 932 // begin redelegate 933 redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) 934 msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) 935 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 936 require.NoError(t, err) 937 require.NotNil(t, res) 938 939 // cannot redelegation to next validator while first delegation exists 940 msgBeginRedelegate = NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) 941 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 942 require.Error(t, err) 943 require.Nil(t, res) 944 945 params := keeper.GetParams(ctx) 946 ctx.SetBlockTime(blockTime.Add(params.UnbondingTime)) 947 948 // complete first redelegation 949 EndBlocker(ctx, keeper) 950 951 // now should be able to redelegate from the second validator to the third 952 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 953 require.NoError(t, err) 954 require.NotNil(t, res) 955 } 956 957 func TestMultipleRedelegationAtSameTime(t *testing.T) { 958 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 959 valAddr := sdk.ValAddress(keep.Addrs[0]) 960 valAddr2 := sdk.ValAddress(keep.Addrs[1]) 961 962 // set the unbonding time 963 params := keeper.GetParams(ctx) 964 params.UnbondingTime = 1 * time.Second 965 keeper.SetParams(ctx, params) 966 967 // create the validators 968 valTokens := sdk.TokensFromConsensusPower(10) 969 msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) 970 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 971 require.NoError(t, err) 972 require.NotNil(t, res) 973 974 msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) 975 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 976 require.NoError(t, err) 977 require.NotNil(t, res) 978 979 // end block to bond them 980 EndBlocker(ctx, keeper) 981 982 // begin a redelegate 983 selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) 984 redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) 985 msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) 986 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 987 require.NoError(t, err) 988 require.NotNil(t, res) 989 990 // there should only be one entry in the redelegation object 991 rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 992 require.True(t, found) 993 require.Len(t, rd.Entries, 1) 994 995 // start a second redelegation at this same time as the first 996 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 997 require.NoError(t, err) 998 require.NotNil(t, res) 999 1000 // now there should be two entries 1001 rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 1002 require.True(t, found) 1003 require.Len(t, rd.Entries, 2) 1004 1005 // move forward in time, should complete both redelegations 1006 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) 1007 EndBlocker(ctx, keeper) 1008 1009 rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 1010 require.False(t, found) 1011 } 1012 1013 func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { 1014 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1015 valAddr := sdk.ValAddress(keep.Addrs[0]) 1016 valAddr2 := sdk.ValAddress(keep.Addrs[1]) 1017 1018 // set the unbonding time 1019 params := keeper.GetParams(ctx) 1020 params.UnbondingTime = 10 * time.Second 1021 keeper.SetParams(ctx, params) 1022 1023 // create the validators 1024 valTokens := sdk.TokensFromConsensusPower(10) 1025 msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) 1026 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1027 require.NoError(t, err) 1028 require.NotNil(t, res) 1029 1030 msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) 1031 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1032 require.NoError(t, err) 1033 require.NotNil(t, res) 1034 1035 // end block to bond them 1036 EndBlocker(ctx, keeper) 1037 1038 // begin a redelegate 1039 selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) 1040 redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) 1041 msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) 1042 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 1043 require.NoError(t, err) 1044 require.NotNil(t, res) 1045 1046 // move forward in time and start a second redelegation 1047 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1048 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 1049 require.NoError(t, err) 1050 require.NotNil(t, res) 1051 1052 // now there should be two entries 1053 rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 1054 require.True(t, found) 1055 require.Len(t, rd.Entries, 2) 1056 1057 // move forward in time, should complete the first redelegation, but not the second 1058 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1059 EndBlocker(ctx, keeper) 1060 rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 1061 require.True(t, found) 1062 require.Len(t, rd.Entries, 1) 1063 1064 // move forward in time, should complete the second redelegation 1065 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1066 EndBlocker(ctx, keeper) 1067 rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) 1068 require.False(t, found) 1069 } 1070 1071 func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { 1072 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1073 valAddr := sdk.ValAddress(keep.Addrs[0]) 1074 1075 // set the unbonding time 1076 params := keeper.GetParams(ctx) 1077 params.UnbondingTime = 1 * time.Second 1078 keeper.SetParams(ctx, params) 1079 1080 // create the validator 1081 valTokens := sdk.TokensFromConsensusPower(10) 1082 msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) 1083 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1084 require.NoError(t, err) 1085 require.NotNil(t, res) 1086 1087 // end block to bond 1088 EndBlocker(ctx, keeper) 1089 1090 // begin an unbonding delegation 1091 selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) 1092 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) 1093 msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) 1094 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1095 require.NoError(t, err) 1096 require.NotNil(t, res) 1097 1098 // there should only be one entry in the ubd object 1099 ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1100 require.True(t, found) 1101 require.Len(t, ubd.Entries, 1) 1102 1103 // start a second ubd at this same time as the first 1104 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1105 require.NoError(t, err) 1106 require.NotNil(t, res) 1107 1108 // now there should be two entries 1109 ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1110 require.True(t, found) 1111 require.Len(t, ubd.Entries, 2) 1112 1113 // move forwaubd in time, should complete both ubds 1114 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) 1115 EndBlocker(ctx, keeper) 1116 1117 ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1118 require.False(t, found) 1119 } 1120 1121 func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { 1122 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1123 valAddr := sdk.ValAddress(keep.Addrs[0]) 1124 1125 // set the unbonding time 1126 params := keeper.GetParams(ctx) 1127 params.UnbondingTime = 10 * time.Second 1128 keeper.SetParams(ctx, params) 1129 1130 // create the validator 1131 valTokens := sdk.TokensFromConsensusPower(10) 1132 msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) 1133 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1134 require.NoError(t, err) 1135 require.NotNil(t, res) 1136 1137 // end block to bond 1138 EndBlocker(ctx, keeper) 1139 1140 // begin an unbonding delegation 1141 selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) 1142 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) 1143 msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) 1144 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1145 require.NoError(t, err) 1146 require.NotNil(t, res) 1147 1148 // there should only be one entry in the ubd object 1149 ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1150 require.True(t, found) 1151 require.Len(t, ubd.Entries, 1) 1152 1153 // move forwaubd in time and start a second redelegation 1154 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1155 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1156 require.NoError(t, err) 1157 require.NotNil(t, res) 1158 1159 // now there should be two entries 1160 ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1161 require.True(t, found) 1162 require.Len(t, ubd.Entries, 2) 1163 1164 // move forwaubd in time, should complete the first redelegation, but not the second 1165 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1166 EndBlocker(ctx, keeper) 1167 ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1168 require.True(t, found) 1169 require.Len(t, ubd.Entries, 1) 1170 1171 // move forwaubd in time, should complete the second redelegation 1172 ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) 1173 EndBlocker(ctx, keeper) 1174 ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) 1175 require.False(t, found) 1176 } 1177 1178 func TestUnbondingWhenExcessValidators(t *testing.T) { 1179 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1180 validatorAddr1 := sdk.ValAddress(keep.Addrs[0]) 1181 validatorAddr2 := sdk.ValAddress(keep.Addrs[1]) 1182 validatorAddr3 := sdk.ValAddress(keep.Addrs[2]) 1183 1184 // set the unbonding time 1185 params := keeper.GetParams(ctx) 1186 params.MaxValidators = 2 1187 keeper.SetParams(ctx, params) 1188 1189 // add three validators 1190 valTokens1 := sdk.TokensFromConsensusPower(50) 1191 msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, keep.PKs[0], valTokens1) 1192 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1193 require.NoError(t, err) 1194 require.NotNil(t, res) 1195 1196 // apply TM updates 1197 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1198 require.Equal(t, 1, len(keeper.GetLastValidators(ctx))) 1199 1200 valTokens2 := sdk.TokensFromConsensusPower(30) 1201 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], valTokens2) 1202 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1203 require.NoError(t, err) 1204 require.NotNil(t, res) 1205 1206 // apply TM updates 1207 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1208 require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) 1209 1210 valTokens3 := sdk.TokensFromConsensusPower(10) 1211 msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], valTokens3) 1212 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1213 require.NoError(t, err) 1214 require.NotNil(t, res) 1215 1216 // apply TM updates 1217 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1218 require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) 1219 1220 // unbond the validator-2 1221 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2) 1222 msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) 1223 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1224 require.NoError(t, err) 1225 require.NotNil(t, res) 1226 1227 // apply TM updates 1228 keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1229 1230 // because there are extra validators waiting to get in, the queued 1231 // validator (aka. validator-1) should make it into the bonded group, thus 1232 // the total number of validators should stay the same 1233 vals := keeper.GetLastValidators(ctx) 1234 require.Equal(t, 2, len(vals), "vals %v", vals) 1235 val1, found := keeper.GetValidator(ctx, validatorAddr1) 1236 require.True(t, found) 1237 require.Equal(t, sdk.Bonded, val1.Status, "%v", val1) 1238 } 1239 1240 func TestBondUnbondRedelegateSlashTwice(t *testing.T) { 1241 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1242 valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2] 1243 consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) 1244 1245 valTokens := sdk.TokensFromConsensusPower(10) 1246 msgCreateValidator := NewTestMsgCreateValidator(valA, keep.PKs[0], valTokens) 1247 res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1248 require.NoError(t, err) 1249 require.NotNil(t, res) 1250 1251 msgCreateValidator = NewTestMsgCreateValidator(valB, keep.PKs[1], valTokens) 1252 res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) 1253 require.NoError(t, err) 1254 require.NotNil(t, res) 1255 1256 // delegate 10 stake 1257 msgDelegate := NewTestMsgDelegate(del, valA, valTokens) 1258 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 1259 require.NoError(t, err) 1260 require.NotNil(t, res) 1261 1262 // apply Tendermint updates 1263 updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1264 require.Equal(t, 2, len(updates)) 1265 1266 // a block passes 1267 ctx.SetBlockHeight(1) 1268 1269 // begin unbonding 4 stake 1270 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4)) 1271 msgUndelegate := NewMsgUndelegate(del, valA, unbondAmt) 1272 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1273 require.NoError(t, err) 1274 require.NotNil(t, res) 1275 1276 // begin redelegate 6 stake 1277 redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(6)) 1278 msgBeginRedelegate := NewMsgBeginRedelegate(del, valA, valB, redAmt) 1279 res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) 1280 require.NoError(t, err) 1281 require.NotNil(t, res) 1282 1283 // destination delegation should have 6 shares 1284 delegation, found := keeper.GetDelegation(ctx, del, valB) 1285 require.True(t, found) 1286 require.Equal(t, redAmt.Amount, delegation.Shares) 1287 1288 // must apply validator updates 1289 updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) 1290 require.Equal(t, 2, len(updates)) 1291 1292 // slash the validator by half 1293 keeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1)) 1294 1295 // unbonding delegation should have been slashed by half 1296 ubd, found := keeper.GetUnbondingDelegation(ctx, del, valA) 1297 require.True(t, found) 1298 require.Len(t, ubd.Entries, 1) 1299 require.Equal(t, unbondAmt.Amount.QuoInt64(2).Int, ubd.Entries[0].Balance.ToDec().Int) 1300 1301 // redelegation should have been slashed by half 1302 redelegation, found := keeper.GetRedelegation(ctx, del, valA, valB) 1303 require.True(t, found) 1304 require.Len(t, redelegation.Entries, 1) 1305 1306 // destination delegation should have been slashed by half 1307 delegation, found = keeper.GetDelegation(ctx, del, valB) 1308 require.True(t, found) 1309 require.Equal(t, redAmt.Amount.QuoInt64(2), delegation.Shares) 1310 1311 // validator power should have been reduced by half 1312 validator, found := keeper.GetValidator(ctx, valA) 1313 require.True(t, found) 1314 require.Equal(t, valTokens.QuoRaw(2), validator.GetBondedTokens()) 1315 1316 // slash the validator for an infraction committed after the unbonding and redelegation begin 1317 ctx.SetBlockHeight(3) 1318 keeper.Slash(ctx, consAddr0, 2, 10, sdk.NewDecWithPrec(5, 1)) 1319 1320 // unbonding delegation should be unchanged 1321 ubd, found = keeper.GetUnbondingDelegation(ctx, del, valA) 1322 require.True(t, found) 1323 require.Len(t, ubd.Entries, 1) 1324 require.Equal(t, unbondAmt.Amount.QuoInt64(2).Int, ubd.Entries[0].Balance.ToDec().Int) 1325 1326 // redelegation should be unchanged 1327 redelegation, found = keeper.GetRedelegation(ctx, del, valA, valB) 1328 require.True(t, found) 1329 require.Len(t, redelegation.Entries, 1) 1330 1331 // destination delegation should be unchanged 1332 delegation, found = keeper.GetDelegation(ctx, del, valB) 1333 require.True(t, found) 1334 require.Equal(t, redAmt.Amount.QuoInt64(2), delegation.Shares) 1335 1336 // end blocker 1337 EndBlocker(ctx, keeper) 1338 1339 // validator power should have been reduced to zero 1340 // validator should be in unbonding state 1341 validator, _ = keeper.GetValidator(ctx, valA) 1342 require.Equal(t, validator.GetStatus(), sdk.Unbonding) 1343 } 1344 1345 func TestInvalidMsg(t *testing.T) { 1346 k := keep.Keeper{} 1347 h := NewHandler(k) 1348 1349 res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) 1350 require.Error(t, err) 1351 require.Nil(t, res) 1352 require.True(t, strings.Contains(err.Error(), "unrecognized staking message type")) 1353 } 1354 1355 func TestInvalidCoinDenom(t *testing.T) { 1356 ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000) 1357 valA, valB, delAddr := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2] 1358 1359 valTokens := sdk.TokensFromConsensusPower(100) 1360 invalidCoin := sdk.NewCoin("churros", valTokens) 1361 validCoin := sdk.NewCoin(sdk.DefaultBondDenom, valTokens) 1362 oneCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) 1363 1364 commission := types.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.ZeroDec()) 1365 1366 msgCreate := types.NewMsgCreateValidator(valA, keep.PKs[0], invalidCoin, Description{}, commission, sdk.OneInt()) 1367 res, err := handleMsgCreateValidator(ctx, msgCreate, keeper) 1368 require.Error(t, err) 1369 require.Nil(t, res) 1370 1371 msgCreate = types.NewMsgCreateValidator(valA, keep.PKs[0], validCoin, Description{}, commission, sdk.OneInt()) 1372 res, err = handleMsgCreateValidator(ctx, msgCreate, keeper) 1373 require.NoError(t, err) 1374 require.NotNil(t, res) 1375 1376 msgCreate = types.NewMsgCreateValidator(valB, keep.PKs[1], validCoin, Description{}, commission, sdk.OneInt()) 1377 res, err = handleMsgCreateValidator(ctx, msgCreate, keeper) 1378 require.NoError(t, err) 1379 require.NotNil(t, res) 1380 1381 msgDelegate := types.NewMsgDelegate(delAddr, valA, invalidCoin) 1382 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 1383 require.Error(t, err) 1384 require.Nil(t, res) 1385 1386 msgDelegate = types.NewMsgDelegate(delAddr, valA, validCoin) 1387 res, err = handleMsgDelegate(ctx, msgDelegate, keeper) 1388 require.NoError(t, err) 1389 require.NotNil(t, res) 1390 1391 msgUndelegate := types.NewMsgUndelegate(delAddr, valA, invalidCoin) 1392 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1393 require.Error(t, err) 1394 require.Nil(t, res) 1395 1396 msgUndelegate = types.NewMsgUndelegate(delAddr, valA, oneCoin) 1397 res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) 1398 require.NoError(t, err) 1399 require.NotNil(t, res) 1400 1401 msgRedelegate := types.NewMsgBeginRedelegate(delAddr, valA, valB, invalidCoin) 1402 res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) 1403 require.Error(t, err) 1404 require.Nil(t, res) 1405 1406 msgRedelegate = types.NewMsgBeginRedelegate(delAddr, valA, valB, oneCoin) 1407 res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) 1408 require.NoError(t, err) 1409 require.NotNil(t, res) 1410 }