github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/distribution/distribution_suit_test.go (about) 1 package distribution 2 3 import ( 4 "testing" 5 "time" 6 7 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 8 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 9 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 10 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 11 "github.com/fibonacci-chain/fbc/x/distribution/keeper" 12 "github.com/fibonacci-chain/fbc/x/distribution/types" 13 "github.com/fibonacci-chain/fbc/x/staking" 14 "github.com/stretchr/testify/require" 15 "github.com/stretchr/testify/suite" 16 ) 17 18 var ( 19 ctx sdk.Context 20 ak auth.AccountKeeper 21 dk Keeper 22 sk staking.Keeper 23 supplyKeeper types.SupplyKeeper 24 blockRewardValueTokens = sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(int64(100))}} 25 votes []abci.VoteInfo 26 depositCoin = sdk.NewCoin(sk.BondDenom(ctx), sdk.NewInt(100)) 27 ) 28 29 type testAllocationParam struct { 30 totalPower int64 31 isVote []bool 32 isJailed []bool 33 fee sdk.SysCoins 34 } 35 36 func allocateTokens(t *testing.T) { 37 feePoolBefore, _ := dk.GetFeePool(ctx).CommunityPool.TruncateDecimal() 38 setTestFees(t, ctx, ak, blockRewardValueTokens) 39 dk.AllocateTokens(ctx, 1, keeper.TestConsAddrs[0], votes) 40 feePoolAfter, _ := dk.GetFeePool(ctx).CommunityPool.TruncateDecimal() 41 require.Equal(t, feePoolBefore.Add2(getDecCoins("2")), feePoolAfter) 42 staking.EndBlocker(ctx, sk) 43 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 44 } 45 46 func initEnv(t *testing.T, validatorCount int64, newVersion bool) { 47 communityTax := sdk.NewDecWithPrec(2, 2) 48 ctx, ak, _, dk, sk, _, supplyKeeper = keeper.CreateTestInputAdvanced(t, false, 1000, communityTax) 49 if newVersion { 50 tmtypes.UnittestOnlySetMilestoneVenus2Height(-1) 51 dk.SetInitExistedValidatorFlag(ctx, true) 52 } 53 54 h := staking.NewHandler(sk) 55 valOpAddrs, valConsPks, _ := keeper.GetTestAddrs() 56 57 // create four validators 58 for i := int64(0); i < validatorCount; i++ { 59 msg := staking.NewMsgCreateValidator(valOpAddrs[i], valConsPks[i], 60 staking.Description{}, keeper.NewTestSysCoin(i+1, 0)) 61 _, e := h(ctx, msg) 62 require.Nil(t, e) 63 if newVersion { 64 require.True(t, dk.GetValidatorAccumulatedCommission(ctx, valOpAddrs[i]).IsZero()) 65 } else { 66 require.Panics(t, func() { 67 dk.GetValidatorOutstandingRewards(ctx, valOpAddrs[i]) 68 }) 69 } 70 } 71 staking.EndBlocker(ctx, sk) 72 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 73 74 testAllocationParam := testAllocationParam{ 75 10, 76 []bool{true, true, true, true}, []bool{false, false, false, false}, 77 nil, 78 } 79 votes = createTestVotes(ctx, sk, testAllocationParam) 80 } 81 82 func createTestVotes(ctx sdk.Context, sk staking.Keeper, test testAllocationParam) []abci.VoteInfo { 83 var votes []abci.VoteInfo 84 for i := int64(0); i < int64(len(test.isVote)); i++ { 85 if test.isJailed[i] { 86 sk.Jail(ctx, keeper.TestConsAddrs[i]) 87 } 88 abciVal := abci.Validator{Address: keeper.TestConsAddrs[i], Power: i + 1} 89 if test.isVote[i] { 90 votes = append(votes, abci.VoteInfo{Validator: abciVal, SignedLastBlock: true}) 91 } 92 } 93 return votes 94 } 95 96 type DistributionSuite struct { 97 suite.Suite 98 } 99 100 func TestDistributionSuit(t *testing.T) { 101 suite.Run(t, new(DistributionSuite)) 102 } 103 104 func getDecCoins(value string) sdk.SysCoins { 105 if value == "0" { 106 var decCoins sdk.SysCoins 107 return decCoins 108 } 109 110 dec, _ := sdk.NewDecFromStr(value) 111 return sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: dec}} 112 } 113 114 func (suite *DistributionSuite) TestNormal() { 115 testCases := []struct { 116 title string 117 valCount int64 118 beforeCommissionDec [4]string 119 beforeOutstandingDec [4]string 120 afterCommissionDec [4]string 121 afterOutstandingDec [4]string 122 decCommunity string 123 distrType uint32 124 remainReferenceCount uint64 125 }{ 126 { 127 "1 validator onchain", 128 int64(1), 129 [4]string{"98"}, 130 [4]string{"98"}, 131 [4]string{"0"}, 132 [4]string{"0"}, 133 "2", 134 1, 135 1, 136 }, 137 { 138 "2 validator onchain", 139 int64(2), 140 [4]string{"49", "49"}, 141 [4]string{"49", "49"}, 142 [4]string{"0", "0"}, 143 [4]string{"0", "0"}, 144 "2", 145 1, 146 2, 147 }, 148 { 149 "3 validator onchain", 150 int64(3), 151 [4]string{"32.666666666666666633", "32.666666666666666633", "32.666666666666666633"}, 152 [4]string{"32.666666666666666633", "32.666666666666666633", "32.666666666666666633"}, 153 [4]string{"0.666666666666666633", "0.666666666666666633", "0.666666666666666633"}, 154 [4]string{"0.666666666666666633", "0.666666666666666633", "0.666666666666666633"}, 155 "2.000000000000000101", 156 1, 157 3, 158 }, 159 { 160 "4 validator onchain", 161 int64(4), 162 [4]string{"24.5", "24.5", "24.5", "24.5"}, 163 [4]string{"24.5", "24.5", "24.5", "24.5"}, 164 [4]string{"0.5", "0.5", "0.5", "0.5"}, 165 [4]string{"0.5", "0.5", "0.5", "0.5"}, 166 "2", 167 1, 168 4, 169 }, 170 { 171 "1 validator offchain", 172 int64(1), 173 [4]string{"98"}, 174 [4]string{"98"}, 175 [4]string{"0"}, 176 [4]string{"0"}, 177 "2", 178 0, 179 1, 180 }, 181 { 182 "2 validator offchain", 183 int64(2), 184 [4]string{"49", "49"}, 185 [4]string{"49", "49"}, 186 [4]string{"0", "0"}, 187 [4]string{"0", "0"}, 188 "2", 189 0, 190 2, 191 }, 192 { 193 "3 validator offchain", 194 int64(3), 195 [4]string{"32.666666666666666633", "32.666666666666666633", "32.666666666666666633"}, 196 [4]string{"32.666666666666666633", "32.666666666666666633", "32.666666666666666633"}, 197 [4]string{"0.666666666666666633", "0.666666666666666633", "0.666666666666666633"}, 198 [4]string{"0.666666666666666633", "0.666666666666666633", "0.666666666666666633"}, 199 "2.000000000000000101", 200 0, 201 3, 202 }, 203 { 204 "4 validator offchain", 205 int64(4), 206 [4]string{"24.5", "24.5", "24.5", "24.5"}, 207 [4]string{"24.5", "24.5", "24.5", "24.5"}, 208 [4]string{"0.5", "0.5", "0.5", "0.5"}, 209 [4]string{"0.5", "0.5", "0.5", "0.5"}, 210 "2", 211 0, 212 4, 213 }, 214 } 215 216 for _, tc := range testCases { 217 suite.Run(tc.title, func() { 218 initEnv(suite.T(), tc.valCount, true) 219 dk.SetDistributionType(ctx, tc.distrType) 220 allocateTokens(suite.T()) 221 222 for i := int64(0); i < tc.valCount; i++ { 223 require.Equal(suite.T(), getDecCoins(tc.beforeCommissionDec[i]), dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i])) 224 require.Equal(suite.T(), getDecCoins(tc.beforeOutstandingDec[i]), dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i])) 225 require.Equal(suite.T(), getDecCoins(tc.decCommunity), dk.GetFeePoolCommunityCoins(ctx)) 226 227 dk.WithdrawValidatorCommission(ctx, keeper.TestValAddrs[i]) 228 229 require.Equal(suite.T(), getDecCoins(tc.afterCommissionDec[i]), dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i])) 230 require.Equal(suite.T(), getDecCoins(tc.afterOutstandingDec[i]), dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i])) 231 require.Equal(suite.T(), getDecCoins(tc.decCommunity), dk.GetFeePoolCommunityCoins(ctx)) 232 233 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 234 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 235 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 236 } 237 238 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 239 }) 240 } 241 } 242 243 func (suite *DistributionSuite) TestDelegator() { 244 testCases := []struct { 245 title string 246 valCount int64 247 delCount int64 248 decRewards [4][4]string 249 rate string 250 distrType uint32 251 remainReferenceCount uint64 252 }{ 253 { 254 "1 delegator,1 validator, onchain", 255 1, 256 1, 257 [4][4]string{{"48"}}, 258 "0.5", 259 1, 260 1, 261 }, 262 { 263 "1 delegator,1 validator, offchain", 264 1, 265 1, 266 [4][4]string{{"0"}}, 267 "0.5", 268 0, 269 1, 270 }, 271 { 272 "1 delegator,2 validator, onchain", 273 2, 274 1, 275 [4][4]string{{"24", "24"}}, 276 "0.5", 277 1, 278 2, 279 }, 280 { 281 "1 delegator,2 validator, offchain", 282 2, 283 1, 284 [4][4]string{{"0", "0"}}, 285 "0.5", 286 0, 287 2, 288 }, 289 { 290 "1 delegator,4 validator, onchain", 291 4, 292 1, 293 [4][4]string{{"12", "12", "12", "12"}}, 294 "0.5", 295 1, 296 4, 297 }, 298 { 299 "1 delegator,4 validator, offchain", 300 4, 301 1, 302 [4][4]string{{"0", "0", "0", "0"}}, 303 "0.5", 304 0, 305 4, 306 }, 307 { 308 "2 delegator,1 validator, onchain", 309 1, 310 2, 311 [4][4]string{{"24"}, {"24"}}, 312 "0.5", 313 1, 314 1, 315 }, 316 { 317 "2 delegator,1 validator, offchain", 318 1, 319 2, 320 [4][4]string{{"0"}, {"0"}}, 321 "0.5", 322 0, 323 1, 324 }, 325 { 326 "2 delegator,2 validator, onchain", 327 2, 328 2, 329 [4][4]string{{"12", "12"}, {"12", "12"}}, 330 "0.5", 331 1, 332 2, 333 }, 334 { 335 "2 delegator,2 validator, offchain", 336 2, 337 2, 338 [4][4]string{{"0", "0"}, {"0", "0"}}, 339 "0.5", 340 0, 341 2, 342 }, 343 { 344 "2 delegator,4 validator, onchain", 345 4, 346 2, 347 [4][4]string{{"6", "6", "6", "6"}, {"6", "6", "6", "6"}}, 348 "0.5", 349 1, 350 4, 351 }, 352 { 353 "2 delegator,4 validator, offchain", 354 4, 355 2, 356 [4][4]string{{"0", "0", "0", "0"}, {"0", "0", "0", "0"}}, 357 "0.5", 358 0, 359 4, 360 }, 361 { 362 "1 delegator,4 validator, onchain, rate 0", 363 4, 364 1, 365 [4][4]string{{"24", "24", "24", "24"}}, 366 "0", 367 1, 368 4, 369 }, 370 { 371 "1 delegator,4 validator, onchain, rate 1", 372 4, 373 1, 374 [4][4]string{{"0", "0", "0", "0"}}, 375 "1", 376 1, 377 4, 378 }, 379 } 380 381 for _, tc := range testCases { 382 suite.Run(tc.title, func() { 383 initEnv(suite.T(), tc.valCount, true) 384 dk.SetDistributionType(ctx, tc.distrType) 385 386 newRate, _ := sdk.NewDecFromStr(tc.rate) 387 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 388 for i := int64(0); i < tc.valCount; i++ { 389 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 390 } 391 392 for i := int64(0); i < tc.delCount; i++ { 393 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 394 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 395 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 396 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 397 } 398 399 allocateTokens(suite.T()) 400 401 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 402 for i := int64(0); i < tc.valCount; i++ { 403 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 404 } 405 406 for i := int64(0); i < tc.delCount; i++ { 407 for j := int64(0); j < tc.valCount; j++ { 408 queryRewards := keeper.GetQueriedDelegationRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 409 queryRewards, _ = queryRewards.TruncateWithPrec(int64(0)) 410 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 411 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 412 require.Nil(suite.T(), err) 413 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 414 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decRewards[i][j])) 415 require.Equal(suite.T(), queryRewards, getDecCoins(tc.decRewards[i][j])) 416 } 417 } 418 419 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 420 for i := int64(0); i < tc.valCount; i++ { 421 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 422 } 423 424 //withdraw again 425 staking.EndBlocker(ctx, sk) 426 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 427 for i := int64(0); i < tc.delCount; i++ { 428 for j := int64(0); j < tc.valCount; j++ { 429 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 430 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 431 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 432 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 433 434 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[j]).TruncateDecimal() 435 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[j]).TruncateDecimal() 436 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 437 } 438 } 439 require.Equal(suite.T(), beforeValCommission, afterValCommission) 440 441 //allocate and withdraw agagin 442 allocateTokens(suite.T()) 443 for i := int64(0); i < tc.delCount; i++ { 444 for j := int64(0); j < tc.valCount; j++ { 445 queryRewards := keeper.GetQueriedDelegationRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 446 queryRewards, _ = queryRewards.TruncateWithPrec(int64(0)) 447 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 448 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 449 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 450 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decRewards[i][j])) 451 require.Equal(suite.T(), queryRewards, getDecCoins(tc.decRewards[i][j])) 452 } 453 } 454 455 //withdraw token 456 allocateTokens(suite.T()) 457 for i := int64(0); i < tc.delCount; i++ { 458 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 459 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 460 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 461 rewards := sdk.SysCoins{} 462 for j := int64(0); j < tc.valCount; j++ { 463 rewards = rewards.Add2(getDecCoins(tc.decRewards[i][j])) 464 } 465 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), rewards) 466 for j := int64(0); j < tc.valCount; j++ { 467 require.False(suite.T(), dk.HasDelegatorStartingInfo(ctx, keeper.TestValAddrs[j], keeper.TestDelAddrs[i])) 468 } 469 } 470 471 //withdraw again 472 for i := int64(0); i < tc.delCount; i++ { 473 for j := int64(0); j < tc.valCount; j++ { 474 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 475 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 476 } 477 } 478 479 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 480 }) 481 } 482 } 483 484 func (suite *DistributionSuite) TestProxy() { 485 testCases := []struct { 486 title string 487 valCount int64 488 proxyCount int64 489 proxyRewards [4][4]string 490 rate string 491 distrType uint32 492 remainReferenceCount uint64 493 }{ 494 { 495 "1 proxy,1 validator, onchain", 496 1, 497 1, 498 [4][4]string{{"48"}}, 499 "0.5", 500 1, 501 1, 502 }, 503 { 504 "1 proxy,1 validator, offchain", 505 1, 506 1, 507 [4][4]string{{"0"}}, 508 "0.5", 509 0, 510 1, 511 }, 512 { 513 "1 proxy,2 validator, onchain", 514 2, 515 1, 516 [4][4]string{{"24", "24"}}, 517 "0.5", 518 1, 519 2, 520 }, 521 { 522 "1 proxy,2 validator, offchain", 523 2, 524 1, 525 [4][4]string{{"0", "0"}}, 526 "0.5", 527 0, 528 2, 529 }, 530 { 531 "1 proxy,4 validator, onchain", 532 4, 533 1, 534 [4][4]string{{"12", "12", "12", "12"}}, 535 "0.5", 536 1, 537 4, 538 }, 539 { 540 "1 proxy,4 validator, offchain", 541 4, 542 1, 543 [4][4]string{{"0", "0", "0", "0"}}, 544 "0.5", 545 0, 546 4, 547 }, 548 { 549 "2 proxy,1 validator, onchain", 550 1, 551 2, 552 [4][4]string{{"24"}, {"24"}}, 553 "0.5", 554 1, 555 1, 556 }, 557 { 558 "2 proxy,1 validator, offchain", 559 1, 560 2, 561 [4][4]string{{"0"}, {"0"}}, 562 "0.5", 563 0, 564 1, 565 }, 566 { 567 "2 proxy,2 validator, onchain", 568 2, 569 2, 570 [4][4]string{{"12", "12"}, {"12", "12"}}, 571 "0.5", 572 1, 573 2, 574 }, 575 { 576 "2 proxy,2 validator, offchain", 577 2, 578 2, 579 [4][4]string{{"0", "0"}, {"0", "0"}}, 580 "0.5", 581 0, 582 2, 583 }, 584 { 585 "2 proxy,4 validator, onchain", 586 4, 587 2, 588 [4][4]string{{"6", "6", "6", "6"}, {"6", "6", "6", "6"}}, 589 "0.5", 590 1, 591 4, 592 }, 593 { 594 "2 proxy,4 validator, offchain", 595 4, 596 2, 597 [4][4]string{{"0", "0", "0", "0"}, {"0", "0", "0", "0"}}, 598 "0.5", 599 0, 600 4, 601 }, 602 } 603 604 for _, tc := range testCases { 605 suite.Run(tc.title, func() { 606 initEnv(suite.T(), tc.valCount, true) 607 dk.SetDistributionType(ctx, tc.distrType) 608 609 newRate, _ := sdk.NewDecFromStr(tc.rate) 610 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 611 for i := int64(0); i < tc.valCount; i++ { 612 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 613 } 614 615 staking.EndBlocker(ctx, sk) 616 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 617 for i := int64(0); i < tc.proxyCount; i++ { 618 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], depositCoin) 619 keeper.DoRegProxy(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], true) 620 621 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 622 keeper.DoBindProxy(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestProxyAddrs[i]) 623 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 624 delegator := sk.Delegator(ctx, keeper.TestProxyAddrs[i]) 625 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 626 } 627 628 //test withdraw rewards 629 testProxyWithdrawRewards(suite, tc.valCount, tc.proxyCount, tc.proxyRewards) 630 631 //proxy withdraw rewards again, delegator withdraw reards again 632 testProxyWithdrawRewardsAgain(suite, tc.valCount, tc.proxyCount) 633 634 // UnBindProxy 635 for i := int64(0); i < tc.proxyCount; i++ { 636 keeper.DoUnBindProxy(suite.T(), ctx, sk, keeper.TestDelAddrs[i]) 637 } 638 639 allocateTokens(suite.T()) 640 641 for i := int64(0); i < tc.proxyCount; i++ { 642 for j := int64(0); j < tc.valCount; j++ { 643 queryRewards := keeper.GetQueriedDelegationRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 644 queryRewards, _ = queryRewards.TruncateWithPrec(int64(0)) 645 beforeAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 646 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 647 require.Nil(suite.T(), err) 648 afterAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 649 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.proxyRewards[i][j])) 650 require.Equal(suite.T(), queryRewards, getDecCoins(tc.proxyRewards[i][j])) 651 } 652 } 653 654 //proxy withdraw rewards again, delegator withdraw rewards again 655 testProxyWithdrawRewardsAgain(suite, tc.valCount, tc.proxyCount) 656 657 //bind proxy again 658 testProxyBindAgain(suite, tc.valCount, tc.proxyCount, tc.proxyRewards) 659 660 //delegator deposit to proxy 661 testProxyDelDepositAgain(suite, tc.valCount, tc.proxyCount, tc.proxyRewards) 662 663 //proxy deposit again 664 testProxyProxyDepositAgain(suite, tc.valCount, tc.proxyCount, tc.proxyRewards) 665 666 //withdraw token 667 allocateTokens(suite.T()) 668 for i := int64(0); i < tc.proxyCount; i++ { 669 beforeAccountCoins := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 670 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin.Add(depositCoin)) 671 keeper.DoRegProxy(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], false) 672 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], depositCoin.Add(depositCoin)) 673 afterAccountCoins := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 674 rewards := sdk.SysCoins{} 675 for j := int64(0); j < tc.valCount; j++ { 676 rewards = rewards.Add2(getDecCoins(tc.proxyRewards[i][j])) 677 } 678 require.Equal(suite.T(), afterAccountCoins.Sub(beforeAccountCoins), rewards) 679 for j := int64(0); j < tc.valCount; j++ { 680 require.False(suite.T(), dk.HasDelegatorStartingInfo(ctx, keeper.TestValAddrs[j], keeper.TestProxyAddrs[i])) 681 } 682 } 683 684 //proxy withdraw rewards again 685 for i := int64(0); i < tc.proxyCount; i++ { 686 for j := int64(0); j < tc.valCount; j++ { 687 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 688 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 689 } 690 } 691 692 //delegator withdraw rewards again 693 for i := int64(0); i < tc.proxyCount; i++ { 694 for j := int64(0); j < tc.valCount; j++ { 695 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 696 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 697 } 698 } 699 700 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 701 }) 702 } 703 } 704 705 func testProxyWithdrawRewards(suite *DistributionSuite, valCount int64, proxyCount int64, proxyRewards [4][4]string) { 706 allocateTokens(suite.T()) 707 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 708 for i := int64(0); i < valCount; i++ { 709 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 710 } 711 712 for i := int64(0); i < proxyCount; i++ { 713 for j := int64(0); j < valCount; j++ { 714 queryRewards := keeper.GetQueriedDelegationRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 715 queryRewards, _ = queryRewards.TruncateWithPrec(int64(0)) 716 beforeAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 717 dk.WithdrawDelegationRewards(ctx, keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 718 afterAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 719 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(proxyRewards[i][j])) 720 require.Equal(suite.T(), queryRewards, getDecCoins(proxyRewards[i][j])) 721 } 722 } 723 724 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 725 for i := int64(0); i < valCount; i++ { 726 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 727 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 728 truncatedCommission, _ := afterValCommission[i].TruncateDecimal() 729 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 730 } 731 require.Equal(suite.T(), beforeValCommission, afterValCommission) 732 } 733 734 func testProxyWithdrawRewardsAgain(suite *DistributionSuite, valCount int64, proxyCount int64) { 735 staking.EndBlocker(ctx, sk) 736 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 737 for i := int64(0); i < proxyCount; i++ { 738 for j := int64(0); j < valCount; j++ { 739 beforeAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 740 dk.WithdrawDelegationRewards(ctx, keeper.TestProxyAddrs[i], keeper.TestValAddrs[j]) 741 afterAccount := ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 742 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 743 } 744 } 745 746 //delegator withdraw 747 staking.EndBlocker(ctx, sk) 748 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 749 for i := int64(0); i < proxyCount; i++ { 750 for j := int64(0); j < valCount; j++ { 751 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 752 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 753 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 754 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 755 } 756 } 757 } 758 759 func testProxyBindAgain(suite *DistributionSuite, valCount int64, proxyCount int64, proxyRewards [4][4]string) { 760 allocateTokens(suite.T()) 761 beforeProxyAccountCoins := [4]sdk.SysCoins{} 762 for i := int64(0); i < proxyCount; i++ { 763 beforeProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 764 for j := int64(0); j < valCount; j++ { 765 beforeProxyAccountCoins[i] = beforeProxyAccountCoins[i].Add2(getDecCoins(proxyRewards[i][j])) 766 } 767 } 768 for i := int64(0); i < proxyCount; i++ { 769 keeper.DoBindProxy(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestProxyAddrs[i]) 770 } 771 afterProxyAccountCoins := [4]sdk.SysCoins{} 772 for i := int64(0); i < proxyCount; i++ { 773 afterProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 774 } 775 require.Equal(suite.T(), beforeProxyAccountCoins, afterProxyAccountCoins) 776 } 777 778 func testProxyDelDepositAgain(suite *DistributionSuite, valCount int64, proxyCount int64, proxyRewards [4][4]string) { 779 allocateTokens(suite.T()) 780 beforeProxyAccountCoins := [4]sdk.SysCoins{} 781 for i := int64(0); i < proxyCount; i++ { 782 beforeProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 783 for j := int64(0); j < valCount; j++ { 784 beforeProxyAccountCoins[i] = beforeProxyAccountCoins[i].Add2(getDecCoins(proxyRewards[i][j])) 785 } 786 } 787 for i := int64(0); i < proxyCount; i++ { 788 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 789 } 790 afterProxyAccountCoins := [4]sdk.SysCoins{} 791 for i := int64(0); i < proxyCount; i++ { 792 afterProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 793 } 794 require.Equal(suite.T(), beforeProxyAccountCoins, afterProxyAccountCoins) 795 } 796 797 func testProxyProxyDepositAgain(suite *DistributionSuite, valCount int64, proxyCount int64, proxyRewards [4][4]string) { 798 allocateTokens(suite.T()) 799 beforeProxyAccountCoins := [4]sdk.SysCoins{} 800 for i := int64(0); i < proxyCount; i++ { 801 beforeProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 802 for j := int64(0); j < valCount; j++ { 803 beforeProxyAccountCoins[i] = beforeProxyAccountCoins[i].Add2(getDecCoins(proxyRewards[i][j])) 804 } 805 } 806 for i := int64(0); i < proxyCount; i++ { 807 beforeProxyAccountCoins[i] = beforeProxyAccountCoins[i].Sub(sdk.NewCoins(depositCoin)) 808 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestProxyAddrs[i], depositCoin) 809 } 810 afterProxyAccountCoins := [4]sdk.SysCoins{} 811 for i := int64(0); i < proxyCount; i++ { 812 afterProxyAccountCoins[i] = ak.GetAccount(ctx, keeper.TestProxyAddrs[i]).GetCoins() 813 } 814 require.Equal(suite.T(), beforeProxyAccountCoins, afterProxyAccountCoins) 815 } 816 817 func (suite *DistributionSuite) TestWithdraw() { 818 testCases := []struct { 819 title string 820 valCount int64 821 delCount int64 822 decRewards [4][4]string 823 rate string 824 distrType uint32 825 remainReferenceCount uint64 826 }{ 827 { 828 "1 delegator,1 validator, onchain", 829 1, 830 1, 831 [4][4]string{{"48"}}, 832 "0.5", 833 1, 834 1, 835 }, 836 { 837 "1 delegator,1 validator, offchain", 838 1, 839 1, 840 [4][4]string{{"0"}}, 841 "0.5", 842 0, 843 1, 844 }, 845 { 846 "1 delegator,2 validator, onchain", 847 2, 848 1, 849 [4][4]string{{"24", "24"}}, 850 "0.5", 851 1, 852 2, 853 }, 854 { 855 "1 delegator,2 validator, offchain", 856 2, 857 1, 858 [4][4]string{{"0", "0"}}, 859 "0.5", 860 0, 861 2, 862 }, 863 { 864 "1 delegator,4 validator, onchain", 865 4, 866 1, 867 [4][4]string{{"12", "12", "12", "12"}}, 868 "0.5", 869 1, 870 4, 871 }, 872 { 873 "1 delegator,4 validator, offchain", 874 4, 875 1, 876 [4][4]string{{"0", "0", "0", "0"}}, 877 "0.5", 878 0, 879 4, 880 }, 881 { 882 "2 delegator,1 validator, onchain", 883 1, 884 2, 885 [4][4]string{{"24"}, {"24"}}, 886 "0.5", 887 1, 888 1, 889 }, 890 { 891 "2 delegator,1 validator, offchain", 892 1, 893 2, 894 [4][4]string{{"0"}, {"0"}}, 895 "0.5", 896 0, 897 1, 898 }, 899 { 900 "2 delegator,2 validator, onchain", 901 2, 902 2, 903 [4][4]string{{"12", "12"}, {"12", "12"}}, 904 "0.5", 905 1, 906 2, 907 }, 908 { 909 "2 delegator,2 validator, offchain", 910 2, 911 2, 912 [4][4]string{{"0", "0"}, {"0", "0"}}, 913 "0.5", 914 0, 915 2, 916 }, 917 { 918 "2 delegator,4 validator, onchain", 919 4, 920 2, 921 [4][4]string{{"6", "6", "6", "6"}, {"6", "6", "6", "6"}}, 922 "0.5", 923 1, 924 4, 925 }, 926 { 927 "2 delegator,4 validator, offchain", 928 4, 929 2, 930 [4][4]string{{"0", "0", "0", "0"}, {"0", "0", "0", "0"}}, 931 "0.5", 932 0, 933 4, 934 }, 935 } 936 937 for _, tc := range testCases { 938 suite.Run(tc.title, func() { 939 initEnv(suite.T(), tc.valCount, true) 940 dk.SetDistributionType(ctx, tc.distrType) 941 942 newRate, _ := sdk.NewDecFromStr(tc.rate) 943 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 944 for i := int64(0); i < tc.valCount; i++ { 945 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 946 } 947 948 for i := int64(0); i < tc.delCount; i++ { 949 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 950 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 951 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 952 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 953 } 954 955 allocateTokens(suite.T()) 956 957 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 958 for i := int64(0); i < tc.valCount; i++ { 959 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 960 } 961 962 for i := int64(0); i < tc.delCount; i++ { 963 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 964 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 965 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 966 rewards := sdk.SysCoins{} 967 for j := int64(0); j < tc.valCount; j++ { 968 rewards = rewards.Add2(getDecCoins(tc.decRewards[i][j])) 969 970 } 971 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), rewards) 972 } 973 974 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 975 for i := int64(0); i < tc.valCount; i++ { 976 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 977 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 978 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 979 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 980 } 981 require.Equal(suite.T(), beforeValCommission, afterValCommission) 982 983 //withdraw again 984 staking.EndBlocker(ctx, sk) 985 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 986 for i := int64(0); i < tc.delCount; i++ { 987 for j := int64(0); j < tc.valCount; j++ { 988 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 989 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 990 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 991 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 992 } 993 } 994 995 //allocate and withdraw again, do nothing 996 allocateTokens(suite.T()) 997 for i := int64(0); i < tc.delCount; i++ { 998 for j := int64(0); j < tc.valCount; j++ { 999 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1000 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1001 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 1002 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1003 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1004 } 1005 } 1006 1007 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 1008 }) 1009 } 1010 } 1011 1012 func (suite *DistributionSuite) TestWithdrawAllRewards() { 1013 testCases := []struct { 1014 title string 1015 valCount int64 1016 delCount int64 1017 decRewards [4]string 1018 rate string 1019 distrType uint32 1020 remainReferenceCount uint64 1021 addShares bool 1022 }{ 1023 { 1024 "1 delegator,1 validator, onchain", 1025 1, 1026 1, 1027 [4]string{"0"}, 1028 "0.5", 1029 1, 1030 1, 1031 false, 1032 }, 1033 { 1034 "1 delegator,1 validator, onchain", 1035 1, 1036 1, 1037 [4]string{"48"}, 1038 "0.5", 1039 1, 1040 1, 1041 true, 1042 }, 1043 { 1044 "1 delegator,1 validator, offchain", 1045 1, 1046 1, 1047 [4]string{"0"}, 1048 "0.5", 1049 0, 1050 1, 1051 true, 1052 }, 1053 { 1054 "1 delegator,2 validator, onchain", 1055 2, 1056 1, 1057 [4]string{"48"}, 1058 "0.5", 1059 1, 1060 2, 1061 true, 1062 }, 1063 { 1064 "1 delegator,2 validator, offchain", 1065 2, 1066 1, 1067 [4]string{"0"}, 1068 "0.5", 1069 0, 1070 2, 1071 true, 1072 }, 1073 { 1074 "1 delegator,4 validator, onchain", 1075 4, 1076 1, 1077 [4]string{"48"}, 1078 "0.5", 1079 1, 1080 4, 1081 true, 1082 }, 1083 { 1084 "1 delegator,4 validator, offchain", 1085 4, 1086 1, 1087 [4]string{"0"}, 1088 "0.5", 1089 0, 1090 4, 1091 true, 1092 }, 1093 { 1094 "2 delegator,1 validator, onchain", 1095 1, 1096 2, 1097 [4]string{"24", "24"}, 1098 "0.5", 1099 1, 1100 1, 1101 true, 1102 }, 1103 { 1104 "2 delegator,1 validator, offchain", 1105 1, 1106 2, 1107 [4]string{"0", "0"}, 1108 "0.5", 1109 0, 1110 1, 1111 true, 1112 }, 1113 { 1114 "2 delegator,2 validator, onchain", 1115 2, 1116 2, 1117 [4]string{"24", "24"}, 1118 "0.5", 1119 1, 1120 2, 1121 true, 1122 }, 1123 { 1124 "2 delegator,2 validator, offchain", 1125 2, 1126 2, 1127 [4]string{"0", "0"}, 1128 "0.5", 1129 0, 1130 2, 1131 true, 1132 }, 1133 { 1134 "2 delegator,4 validator, onchain", 1135 4, 1136 2, 1137 [4]string{"24", "24"}, 1138 "0.5", 1139 1, 1140 4, 1141 true, 1142 }, 1143 { 1144 "2 delegator,4 validator, offchain", 1145 4, 1146 2, 1147 [4]string{"0", "0"}, 1148 "0.5", 1149 0, 1150 4, 1151 true, 1152 }, 1153 { 1154 "1 delegator,4 validator, onchain, rate 0", 1155 4, 1156 1, 1157 [4]string{"96"}, 1158 "0", 1159 1, 1160 4, 1161 true, 1162 }, 1163 { 1164 "1 delegator,4 validator, onchain, rate 1", 1165 4, 1166 1, 1167 [4]string{"0"}, 1168 "1", 1169 1, 1170 4, 1171 true, 1172 }, 1173 } 1174 1175 for _, tc := range testCases { 1176 suite.Run(tc.title, func() { 1177 initEnv(suite.T(), tc.valCount, true) 1178 dk.SetDistributionType(ctx, tc.distrType) 1179 1180 newRate, _ := sdk.NewDecFromStr(tc.rate) 1181 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 1182 for i := int64(0); i < tc.valCount; i++ { 1183 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 1184 } 1185 1186 for i := int64(0); i < tc.delCount; i++ { 1187 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1188 if tc.addShares { 1189 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 1190 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 1191 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1192 } 1193 } 1194 1195 allocateTokens(suite.T()) 1196 1197 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 1198 for i := int64(0); i < tc.valCount; i++ { 1199 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1200 } 1201 1202 for i := int64(0); i < tc.delCount; i++ { 1203 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1204 response := keeper.GetQueriedDelegationTotalRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestDelAddrs[i]) 1205 var queryRewards sdk.SysCoins 1206 for _, v := range response.Rewards { 1207 coins, _ := v.Reward.TruncateWithPrec(int64(0)) 1208 queryRewards = queryRewards.Add2(coins) 1209 } 1210 err := dk.WithdrawDelegationAllRewards(ctx, keeper.TestDelAddrs[i]) 1211 if tc.addShares { 1212 require.Nil(suite.T(), err) 1213 } else { 1214 require.Equal(suite.T(), types.ErrCodeEmptyDelegationVoteValidator(), err) 1215 } 1216 1217 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1218 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decRewards[i])) 1219 require.Equal(suite.T(), queryRewards, getDecCoins(tc.decRewards[i])) 1220 } 1221 1222 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 1223 for i := int64(0); i < tc.valCount; i++ { 1224 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1225 } 1226 1227 //withdraw again 1228 staking.EndBlocker(ctx, sk) 1229 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1230 for i := int64(0); i < tc.delCount; i++ { 1231 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1232 err := dk.WithdrawDelegationAllRewards(ctx, keeper.TestDelAddrs[i]) 1233 if tc.addShares { 1234 require.Nil(suite.T(), err) 1235 } else { 1236 require.Equal(suite.T(), types.ErrCodeEmptyDelegationVoteValidator(), err) 1237 } 1238 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1239 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1240 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[0]).TruncateDecimal() 1241 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[0]).TruncateDecimal() 1242 if tc.addShares { 1243 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 1244 } else { 1245 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission.QuoDec(sdk.MustNewDecFromStr(tc.rate))) 1246 } 1247 } 1248 require.Equal(suite.T(), beforeValCommission, afterValCommission) 1249 1250 //allocate and withdraw agagin 1251 allocateTokens(suite.T()) 1252 for i := int64(0); i < tc.delCount; i++ { 1253 response := keeper.GetQueriedDelegationTotalRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestDelAddrs[i]) 1254 var queryRewards sdk.SysCoins 1255 for _, v := range response.Rewards { 1256 coins, _ := v.Reward.TruncateWithPrec(int64(0)) 1257 queryRewards = queryRewards.Add2(coins) 1258 } 1259 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1260 err := dk.WithdrawDelegationAllRewards(ctx, keeper.TestDelAddrs[i]) 1261 if tc.addShares { 1262 require.Nil(suite.T(), err) 1263 } else { 1264 require.Equal(suite.T(), types.ErrCodeEmptyDelegationVoteValidator(), err) 1265 } 1266 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1267 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decRewards[i])) 1268 require.Equal(suite.T(), queryRewards, getDecCoins(tc.decRewards[i])) 1269 } 1270 1271 //withdraw token 1272 allocateTokens(suite.T()) 1273 for i := int64(0); i < tc.delCount; i++ { 1274 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1275 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1276 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1277 rewards := getDecCoins(tc.decRewards[i]) 1278 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), rewards) 1279 for j := int64(0); j < tc.valCount; j++ { 1280 require.False(suite.T(), dk.HasDelegatorStartingInfo(ctx, keeper.TestValAddrs[j], keeper.TestDelAddrs[i])) 1281 } 1282 } 1283 1284 //withdraw again 1285 for i := int64(0); i < tc.delCount; i++ { 1286 err := dk.WithdrawDelegationAllRewards(ctx, keeper.TestDelAddrs[i]) 1287 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 1288 } 1289 1290 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 1291 }) 1292 } 1293 } 1294 1295 func (suite *DistributionSuite) TestDestroyValidator() { 1296 testCases := []struct { 1297 title string 1298 valCount int64 1299 delCount int64 1300 decRewards [4][4]string 1301 rate string 1302 distrType uint32 1303 remainReferenceCount uint64 1304 }{ 1305 { 1306 "1 delegator,1 validator, onchain", 1307 1, 1308 1, 1309 [4][4]string{{"24"}}, 1310 "0.5", 1311 1, 1312 0, 1313 }, 1314 { 1315 "1 delegator,1 validator, offchain", 1316 1, 1317 1, 1318 [4][4]string{{"0"}}, 1319 "0.5", 1320 0, 1321 0, 1322 }, 1323 } 1324 1325 for _, tc := range testCases { 1326 suite.Run(tc.title, func() { 1327 initEnv(suite.T(), tc.valCount, true) 1328 dk.SetDistributionType(ctx, tc.distrType) 1329 1330 newRate, _ := sdk.NewDecFromStr(tc.rate) 1331 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 1332 for i := int64(0); i < tc.valCount; i++ { 1333 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 1334 } 1335 1336 for i := int64(0); i < tc.delCount; i++ { 1337 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1338 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 1339 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 1340 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1341 } 1342 1343 for j := int64(0); j < tc.valCount; j++ { 1344 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestValAccAddrs[j], depositCoin) 1345 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestValAccAddrs[j], keeper.TestValAddrs[0:tc.valCount]) 1346 delegator := sk.Delegator(ctx, keeper.TestValAccAddrs[j]) 1347 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1348 } 1349 1350 allocateTokens(suite.T()) 1351 1352 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 1353 for i := int64(0); i < tc.valCount; i++ { 1354 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1355 } 1356 1357 //withdraw validator 1358 for j := int64(0); j < tc.valCount; j++ { 1359 keeper.DoDestroyValidator(suite.T(), ctx, sk, keeper.TestValAccAddrs[j]) 1360 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestValAccAddrs[j], depositCoin) 1361 } 1362 1363 staking.EndBlocker(ctx, sk) 1364 1365 for i := int64(0); i < tc.delCount; i++ { 1366 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1367 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1368 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1369 rewards := sdk.SysCoins{} 1370 for j := int64(0); j < tc.valCount; j++ { 1371 rewards = rewards.Add2(getDecCoins(tc.decRewards[i][j])) 1372 1373 } 1374 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), rewards) 1375 } 1376 1377 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 1378 for i := int64(0); i < tc.valCount; i++ { 1379 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1380 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 1381 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]).TruncateDecimal() 1382 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 1383 } 1384 require.Equal(suite.T(), beforeValCommission, afterValCommission) 1385 1386 //withdraw again 1387 staking.EndBlocker(ctx, sk) 1388 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1389 for i := int64(0); i < tc.delCount; i++ { 1390 for j := int64(0); j < tc.valCount; j++ { 1391 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1392 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1393 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1394 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1395 } 1396 } 1397 1398 //allocate and withdraw again, do nothing 1399 staking.EndBlocker(ctx, sk) 1400 for i := int64(0); i < tc.delCount; i++ { 1401 for j := int64(0); j < tc.valCount; j++ { 1402 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1403 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1404 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1405 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1406 } 1407 } 1408 1409 hook := dk.Hooks() 1410 for j := int64(0); j < tc.valCount; j++ { 1411 hook.AfterValidatorRemoved(ctx, nil, keeper.TestValAddrs[j]) 1412 require.True(suite.T(), dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[j]).IsZero()) 1413 require.Panics(suite.T(), func() { 1414 require.True(suite.T(), dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[j]).IsZero()) 1415 }) 1416 } 1417 1418 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 1419 }) 1420 } 1421 } 1422 1423 func setTestFees(t *testing.T, ctx sdk.Context, ak auth.AccountKeeper, fees sdk.SysCoins) { 1424 feeCollector := supplyKeeper.GetModuleAccount(ctx, auth.FeeCollectorName) 1425 require.NotNil(t, feeCollector) 1426 err := feeCollector.SetCoins(fees) 1427 require.NoError(t, err) 1428 ak.SetAccount(ctx, feeCollector) 1429 } 1430 1431 func (suite *DistributionSuite) TestUpgrade() { 1432 testCases := []struct { 1433 title string 1434 valCount int64 1435 delCount int64 1436 decBeforeUpgradeRewards [4][4]string 1437 decAfterUpgradeRewards [4][4]string 1438 rate string 1439 remainReferenceCount uint64 1440 }{ 1441 { 1442 "1 delegator,1 validator", 1443 1, 1444 1, 1445 [4][4]string{{"0"}}, 1446 [4][4]string{{"48"}}, 1447 "0.5", 1448 2, 1449 }, 1450 { 1451 "1 delegator,2 validator", 1452 2, 1453 1, 1454 [4][4]string{{"0", "0"}}, 1455 [4][4]string{{"24", "24"}}, 1456 "0.5", 1457 4, 1458 }, 1459 { 1460 "2 delegator,1 validator", 1461 1, 1462 2, 1463 [4][4]string{{"0"}, {"0"}}, 1464 [4][4]string{{"24"}, {"24"}}, 1465 "0.5", 1466 2, 1467 }, 1468 { 1469 "2 delegator,2 validator", 1470 2, 1471 2, 1472 [4][4]string{{"0", "0"}, {"0", "0"}}, 1473 [4][4]string{{"12", "12"}, {"12", "12"}}, 1474 "0.5", 1475 4, 1476 }, 1477 { 1478 "2 delegator,4 validator", 1479 4, 1480 2, 1481 [4][4]string{{"0", "0", "0", "0"}, {"0", "0", "0", "0"}}, 1482 [4][4]string{{"6", "6", "6", "6"}, {"6", "6", "6", "6"}}, 1483 "0.5", 1484 8, 1485 }, 1486 { 1487 "4 delegator,4 validator", 1488 4, 1489 4, 1490 [4][4]string{{"0", "0", "0", "0"}, {"0", "0", "0", "0"}, {"0", "0", "0", "0"}, {"0", "0", "0", "0"}}, 1491 [4][4]string{{"3", "3", "3", "3"}, {"3", "3", "3", "3"}, {"3", "3", "3", "3"}, {"3", "3", "3", "3"}}, 1492 "0.5", 1493 8, 1494 }, 1495 } 1496 1497 for _, tc := range testCases { 1498 suite.Run(tc.title, func() { 1499 initEnv(suite.T(), tc.valCount, false) 1500 ctx.SetBlockTime(time.Now()) 1501 for i := int64(0); i < tc.delCount; i++ { 1502 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1503 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:tc.valCount]) 1504 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 1505 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1506 } 1507 1508 allocateTokens(suite.T()) 1509 1510 beforeValCommission := [4]types.ValidatorAccumulatedCommission{} 1511 for i := int64(0); i < tc.valCount; i++ { 1512 beforeValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1513 } 1514 1515 for i := int64(0); i < tc.delCount; i++ { 1516 for j := int64(0); j < tc.valCount; j++ { 1517 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1518 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1519 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1520 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decBeforeUpgradeRewards[i][j])) 1521 } 1522 } 1523 1524 afterValCommission := [4]types.ValidatorAccumulatedCommission{} 1525 for i := int64(0); i < tc.valCount; i++ { 1526 afterValCommission[i] = dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[i]) 1527 require.Panics(suite.T(), func() { 1528 require.True(suite.T(), dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[i]).IsZero()) 1529 }) 1530 } 1531 1532 //withdraw again 1533 staking.EndBlocker(ctx, sk) 1534 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1535 for i := int64(0); i < tc.delCount; i++ { 1536 for j := int64(0); j < tc.valCount; j++ { 1537 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1538 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1539 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1540 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1541 } 1542 } 1543 require.Equal(suite.T(), beforeValCommission, afterValCommission) 1544 1545 //allocate and withdraw agagin 1546 allocateTokens(suite.T()) 1547 for i := int64(0); i < tc.delCount; i++ { 1548 for j := int64(0); j < tc.valCount; j++ { 1549 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1550 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1551 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1552 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decBeforeUpgradeRewards[i][j])) 1553 } 1554 } 1555 1556 // upgrade 1557 tmtypes.UnittestOnlySetMilestoneVenus2Height(-1) 1558 proposal := makeChangeDistributionTypeProposal(types.DistributionTypeOnChain) 1559 hdlr := NewDistributionProposalHandler(dk) 1560 require.NoError(suite.T(), hdlr(ctx, &proposal)) 1561 queryDistrType := dk.GetDistributionType(ctx) 1562 require.Equal(suite.T(), queryDistrType, types.DistributionTypeOnChain) 1563 staking.EndBlocker(ctx, sk) 1564 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1565 1566 //set rate 1567 newRate, _ := sdk.NewDecFromStr(tc.rate) 1568 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 1569 for i := int64(0); i < tc.valCount; i++ { 1570 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[i], newRate) 1571 } 1572 1573 allocateTokens(suite.T()) 1574 1575 //withdraw reward 1576 for i := int64(0); i < tc.delCount; i++ { 1577 for j := int64(0); j < tc.valCount; j++ { 1578 queryRewards := keeper.GetQueriedDelegationRewards(suite.T(), ctx, NewQuerier(dk), keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1579 queryRewards, _ = queryRewards.TruncateWithPrec(int64(0)) 1580 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1581 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1582 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1583 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins(tc.decAfterUpgradeRewards[i][j])) 1584 require.Equal(suite.T(), queryRewards, getDecCoins(tc.decAfterUpgradeRewards[i][j])) 1585 } 1586 } 1587 1588 //withdraw reward again 1589 staking.EndBlocker(ctx, sk) 1590 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1591 for i := int64(0); i < tc.delCount; i++ { 1592 for j := int64(0); j < tc.valCount; j++ { 1593 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1594 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1595 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1596 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), getDecCoins("0")) 1597 } 1598 } 1599 1600 allocateTokens(suite.T()) 1601 1602 //withdraw token 1603 for i := int64(0); i < tc.delCount; i++ { 1604 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1605 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1606 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1607 rewards := sdk.SysCoins{} 1608 for j := int64(0); j < tc.valCount; j++ { 1609 rewards = rewards.Add2(getDecCoins(tc.decAfterUpgradeRewards[i][j])) 1610 } 1611 require.Equal(suite.T(), afterAccount.Sub(beforeAccount), rewards) 1612 for j := int64(0); j < tc.valCount; j++ { 1613 require.False(suite.T(), dk.HasDelegatorStartingInfo(ctx, keeper.TestValAddrs[j], keeper.TestDelAddrs[i])) 1614 } 1615 } 1616 1617 //withdraw again 1618 for i := int64(0); i < tc.delCount; i++ { 1619 for j := int64(0); j < tc.valCount; j++ { 1620 _, err := dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[j]) 1621 require.Equal(suite.T(), types.ErrCodeEmptyDelegationDistInfo(), err) 1622 1623 truncatedOutstanding, _ := dk.GetValidatorOutstandingRewards(ctx, keeper.TestValAddrs[j]).TruncateDecimal() 1624 truncatedCommission, _ := dk.GetValidatorAccumulatedCommission(ctx, keeper.TestValAddrs[j]).TruncateDecimal() 1625 require.Equal(suite.T(), truncatedOutstanding, truncatedCommission) 1626 } 1627 } 1628 1629 require.Equal(suite.T(), tc.remainReferenceCount, dk.GetValidatorHistoricalReferenceCount(ctx)) 1630 }) 1631 } 1632 } 1633 1634 func allocateVariateTokens(t *testing.T, blockRewards string) { 1635 feePoolBefore, _ := dk.GetFeePool(ctx).CommunityPool.TruncateDecimal() 1636 VariateBlockRewards := sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.MustNewDecFromStr(blockRewards)}} 1637 setTestFees(t, ctx, ak, VariateBlockRewards) 1638 dk.SetCommunityTax(ctx, sdk.MustNewDecFromStr("0")) 1639 dk.AllocateTokens(ctx, 1, keeper.TestConsAddrs[0], votes[0:1]) 1640 feePoolAfter, _ := dk.GetFeePool(ctx).CommunityPool.TruncateDecimal() 1641 require.Equal(t, feePoolBefore, feePoolAfter) 1642 staking.EndBlocker(ctx, sk) 1643 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1644 } 1645 1646 func (suite *DistributionSuite) TestTruncateWithPrecWithdraw() { 1647 testCases := []struct { 1648 title string 1649 precision int64 1650 delCount int64 1651 depositCoins [4]string 1652 blockRewards string 1653 decRewards [4]string 1654 }{ 1655 { 1656 "1 delegator, precision 18, reward 1", 1657 18, 1658 1, 1659 [4]string{"100"}, 1660 "1", 1661 [4]string{"0.990099009900990000"}, 1662 }, 1663 { 1664 "2 delegator, precision 18, reward 1", 1665 18, 1666 2, 1667 [4]string{"100", "200"}, 1668 "1", 1669 [4]string{"0.332225913621262400", "0.664451827242524800"}, 1670 }, 1671 { 1672 "3 delegator, precision 18, reward 1", 1673 18, 1674 3, 1675 [4]string{"100", "200", "300"}, 1676 "1", 1677 [4]string{"0.166389351081530700", "0.332778702163061400", "0.499168053244592100"}, 1678 }, 1679 { 1680 "4 delegator, precision 18, reward 1", 1681 18, 1682 4, 1683 [4]string{"100", "200", "300", "400"}, 1684 "1", 1685 [4]string{"0.099900099900099900", "0.199800199800199800", "0.299700299700299700", "0.399600399600399600"}, 1686 }, 1687 { 1688 "1 delegator, precision 5, reward 1", 1689 5, 1690 1, 1691 [4]string{"100"}, 1692 "1", 1693 [4]string{"0.99009"}, 1694 }, 1695 { 1696 "2 delegator, precision 18, reward 1", 1697 5, 1698 2, 1699 [4]string{"100", "200"}, 1700 "1", 1701 [4]string{"0.33222", "0.66445"}, 1702 }, 1703 { 1704 "3 delegator, precision 18, reward 1", 1705 5, 1706 3, 1707 [4]string{"100", "200", "300"}, 1708 "1", 1709 [4]string{"0.16638", "0.33277", "0.49916"}, 1710 }, 1711 { 1712 "4 delegator, precision 18, reward 1", 1713 5, 1714 4, 1715 [4]string{"100", "200", "300", "400"}, 1716 "1", 1717 [4]string{"0.09990", "0.19980", "0.29970", "0.39960"}, 1718 }, 1719 { 1720 "4 delegator, precision 0, reward 1", 1721 0, 1722 4, 1723 [4]string{"100", "200", "300", "400"}, 1724 "1", 1725 [4]string{"0", "0", "0", "0"}, 1726 }, 1727 { 1728 "4 delegator, precision 18, reward 100", 1729 18, 1730 4, 1731 [4]string{"100", "200", "300", "400"}, 1732 "100", 1733 [4]string{"9.990009990009990000", "19.980019980019980000", "29.970029970029970000", "39.960039960039960000"}, 1734 }, 1735 { 1736 "4 delegator, precision 10, reward 100", 1737 10, 1738 4, 1739 [4]string{"100", "200", "300", "400"}, 1740 "100", 1741 [4]string{"9.9900099900", "19.9800199800", "29.9700299700", "39.9600399600"}, 1742 }, 1743 { 1744 "4 delegator, precision 1, reward 100", 1745 1, 1746 4, 1747 [4]string{"100", "200", "300", "400"}, 1748 "100", 1749 [4]string{"9.9", "19.9", "29.9", "39.9"}, 1750 }, 1751 { 1752 "4 delegator, precision 1, reward 100", 1753 0, 1754 4, 1755 [4]string{"100", "200", "300", "400"}, 1756 "100", 1757 [4]string{"9", "19", "29", "39"}, 1758 }, 1759 } 1760 1761 for _, tc := range testCases { 1762 suite.Run(tc.title, func() { 1763 initEnv(suite.T(), 1, true) 1764 dk.SetDistributionType(ctx, types.DistributionTypeOnChain) 1765 dk.SetRewardTruncatePrecision(ctx, tc.precision) 1766 ctx.SetBlockTime(time.Now().UTC().Add(48 * time.Hour)) 1767 keeper.DoEditValidator(suite.T(), ctx, sk, keeper.TestValAddrs[0], sdk.MustNewDecFromStr("0")) 1768 // UTC Time: 2000/1/1 00:00:00 1769 blockTimestampEpoch := int64(946684800) 1770 ctx.SetBlockTime(time.Unix(blockTimestampEpoch, 0)) 1771 1772 //deposit, add shares, withdraw msg in one block 1773 allocateVariateTokens(suite.T(), tc.blockRewards) 1774 staking.EndBlocker(ctx, sk) 1775 for i := int64(0); i < tc.delCount; i++ { 1776 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], getDecCoins(tc.depositCoins[i])[0]) 1777 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:1]) 1778 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 1779 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1780 1781 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1782 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[0]) 1783 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1784 require.Equal(suite.T(), getDecCoins("0"), afterAccount.Sub(beforeAccount)) 1785 1786 beforeAccount = ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1787 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], getDecCoins(tc.depositCoins[i])[0]) 1788 afterAccount = ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1789 require.Equal(suite.T(), getDecCoins("0"), afterAccount.Sub(beforeAccount)) 1790 } 1791 1792 allocateVariateTokens(suite.T(), tc.blockRewards) 1793 staking.EndBlocker(ctx, sk) 1794 //nomal 1795 for i := int64(0); i < tc.delCount; i++ { 1796 keeper.DoDeposit(suite.T(), ctx, sk, keeper.TestDelAddrs[i], getDecCoins(tc.depositCoins[i])[0]) 1797 keeper.DoAddShares(suite.T(), ctx, sk, keeper.TestDelAddrs[i], keeper.TestValAddrs[0:1]) 1798 delegator := sk.Delegator(ctx, keeper.TestDelAddrs[i]) 1799 require.False(suite.T(), delegator.GetLastAddedShares().IsZero()) 1800 } 1801 1802 allocateVariateTokens(suite.T(), tc.blockRewards) 1803 staking.EndBlocker(ctx, sk) 1804 //withdraw reward 1805 ctx.SetBlockHeight(ctx.BlockHeight() + 1) 1806 feePoolBefore := dk.GetFeePool(ctx).CommunityPool 1807 for i := int64(0); i < tc.delCount; i++ { 1808 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1809 dk.WithdrawDelegationRewards(ctx, keeper.TestDelAddrs[i], keeper.TestValAddrs[0]) 1810 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1811 require.Equal(suite.T(), getDecCoins(tc.decRewards[i]), afterAccount.Sub(beforeAccount)) 1812 } 1813 feePoolEnd := dk.GetFeePool(ctx).CommunityPool 1814 diff := feePoolEnd.Sub(feePoolBefore) 1815 if tc.precision == sdk.Precision { 1816 require.True(suite.T(), diff.IsZero()) 1817 } else { 1818 require.False(suite.T(), diff.IsZero()) 1819 } 1820 1821 // withdraw 1822 allocateVariateTokens(suite.T(), tc.blockRewards) 1823 staking.EndBlocker(ctx, sk) 1824 for i := int64(0); i < tc.delCount; i++ { 1825 beforeAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1826 keeper.DoWithdraw(suite.T(), ctx, sk, keeper.TestDelAddrs[i], depositCoin) 1827 afterAccount := ak.GetAccount(ctx, keeper.TestDelAddrs[i]).GetCoins() 1828 require.Equal(suite.T(), getDecCoins(tc.decRewards[i]), afterAccount.Sub(beforeAccount)) 1829 } 1830 }) 1831 } 1832 }