github.com/lino-network/lino@v0.6.11/x/bandwidth/manager/manager_test.go (about) 1 package manager 2 3 import ( 4 "testing" 5 "time" 6 7 sdk "github.com/cosmos/cosmos-sdk/types" 8 "github.com/cosmos/cosmos-sdk/x/auth" 9 "github.com/stretchr/testify/mock" 10 "github.com/stretchr/testify/suite" 11 abci "github.com/tendermint/tendermint/abci/types" 12 13 parammodel "github.com/lino-network/lino/param" 14 param "github.com/lino-network/lino/param/mocks" 15 "github.com/lino-network/lino/testsuites" 16 linotypes "github.com/lino-network/lino/types" 17 account "github.com/lino-network/lino/x/account/mocks" 18 accmodel "github.com/lino-network/lino/x/account/model" 19 acctypes "github.com/lino-network/lino/x/account/types" 20 "github.com/lino-network/lino/x/bandwidth/model" 21 "github.com/lino-network/lino/x/bandwidth/types" 22 developer "github.com/lino-network/lino/x/developer/mocks" 23 devModel "github.com/lino-network/lino/x/developer/model" 24 global "github.com/lino-network/lino/x/global/mocks" 25 vote "github.com/lino-network/lino/x/vote/mocks" 26 ) 27 28 type BandwidthManagerTestSuite struct { 29 testsuites.CtxTestSuite 30 bm BandwidthManager 31 ph *param.ParamKeeper 32 baseTime time.Time 33 // deps 34 global *global.GlobalKeeper 35 vm *vote.VoteKeeper 36 dm *developer.DeveloperKeeper 37 am *account.AccountKeeper 38 } 39 40 func TestBandwidthManagerTestSuite(t *testing.T) { 41 suite.Run(t, new(BandwidthManagerTestSuite)) 42 } 43 44 func (suite *BandwidthManagerTestSuite) SetupTest() { 45 suite.baseTime = time.Now() 46 testBandwidthKey := sdk.NewKVStoreKey("bandwidth") 47 suite.SetupCtx(0, suite.baseTime.Add(3*time.Second), testBandwidthKey) 48 suite.global = &global.GlobalKeeper{} 49 suite.ph = ¶m.ParamKeeper{} 50 suite.vm = &vote.VoteKeeper{} 51 suite.dm = &developer.DeveloperKeeper{} 52 suite.am = &account.AccountKeeper{} 53 suite.bm = *NewBandwidthManager(testBandwidthKey, suite.ph, suite.global, suite.vm, suite.dm, suite.am) 54 err := suite.bm.InitGenesis(suite.Ctx) 55 suite.NoError(err) 56 suite.ph.On("GetBandwidthParam", mock.Anything).Return(¶mmodel.BandwidthParam{ 57 SecondsToRecoverBandwidth: int64(7 * 24 * 3600), 58 CapacityUsagePerTransaction: linotypes.NewCoinFromInt64(1 * linotypes.Decimals), 59 VirtualCoin: linotypes.NewCoinFromInt64(1 * linotypes.Decimals), 60 GeneralMsgQuotaRatio: linotypes.NewDecFromRat(20, 100), 61 GeneralMsgEMAFactor: linotypes.NewDecFromRat(1, 10), 62 AppMsgQuotaRatio: linotypes.NewDecFromRat(80, 100), 63 AppMsgEMAFactor: linotypes.NewDecFromRat(1, 10), 64 ExpectedMaxMPS: linotypes.NewDecFromRat(1000, 1), 65 MsgFeeFactorA: linotypes.NewDecFromRat(6, 1), 66 MsgFeeFactorB: linotypes.NewDecFromRat(10, 1), 67 MaxMPSDecayRate: linotypes.NewDecFromRat(99, 100), 68 AppBandwidthPoolSize: linotypes.NewDecFromRat(10, 1), 69 AppVacancyFactor: linotypes.NewDecFromRat(69, 100), 70 AppPunishmentFactor: linotypes.NewDecFromRat(14, 5), 71 }, nil).Maybe() 72 73 suite.vm.On("GetLinoStake", suite.Ctx, linotypes.AccountKey("AppX")).Return(linotypes.NewCoinFromInt64(10), nil).Maybe() 74 suite.vm.On("GetLinoStake", suite.Ctx, linotypes.AccountKey("AppY")).Return(linotypes.NewCoinFromInt64(90), nil).Maybe() 75 suite.dm.On("GetLiveDevelopers", mock.Anything).Return([]devModel.Developer{ 76 { 77 Username: "AppX", 78 }, 79 { 80 Username: "AppY", 81 }, 82 }, nil).Maybe() 83 suite.dm.On("GetAffiliatingApp", suite.Ctx, linotypes.AccountKey("AppY")).Return(linotypes.AccountKey("AppY"), nil).Maybe() 84 suite.dm.On("GetAffiliatingApp", suite.Ctx, linotypes.AccountKey("UserX")).Return(linotypes.AccountKey("dummy"), types.ErrUserMsgFeeNotEnough()).Maybe() 85 suite.global.On("GetLastBlockTime", mock.Anything).Return(suite.baseTime.Unix()).Maybe() 86 suite.am.On("MoveToPool", mock.Anything, linotypes.InflationValidatorPool, 87 mock.Anything, mock.Anything).Return(nil).Maybe() 88 suite.am.On("GetBankByAddress", mock.Anything, sdk.AccAddress("appYAddr")).Return(&accmodel.AccountBank{ 89 Username: "AppY", 90 }, nil).Maybe() 91 suite.am.On("GetBankByAddress", mock.Anything, sdk.AccAddress("userXAddr")).Return(&accmodel.AccountBank{ 92 Username: "UserX", 93 }, nil).Maybe() 94 suite.am.On("GetBankByAddress", mock.Anything, sdk.AccAddress("emptyAddr")).Return( 95 nil, acctypes.ErrAccountBankNotFound(sdk.AccAddress("emptyAddr"))).Maybe() 96 } 97 98 func (suite *BandwidthManagerTestSuite) TestAddMsgSignedByUser() { 99 testCases := []struct { 100 testName string 101 amount int64 102 expectBlockInfo model.BlockInfo 103 }{ 104 { 105 testName: "add user signed message", 106 amount: 1, 107 expectBlockInfo: model.BlockInfo{ 108 TotalMsgSignedByApp: 0, 109 TotalMsgSignedByUser: 1, 110 CurMsgFee: linotypes.NewCoinFromInt64(int64(0)), 111 CurU: sdk.NewDec(1), 112 }, 113 }, 114 } 115 116 for _, tc := range testCases { 117 err := suite.bm.AddMsgSignedByUser(suite.Ctx, tc.amount) 118 suite.NoError(err) 119 info, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 120 suite.Require().Nil(err) 121 suite.Equal(tc.expectBlockInfo, *info, "%s", tc.testName) 122 } 123 } 124 125 func (suite *BandwidthManagerTestSuite) TestAddMsgSignedByApp() { 126 testCases := []struct { 127 testName string 128 amount int64 129 expectBlockInfo model.BlockInfo 130 expectAppInfo model.AppBandwidthInfo 131 }{ 132 { 133 testName: "add user signed message", 134 amount: 1, 135 expectBlockInfo: model.BlockInfo{ 136 TotalMsgSignedByApp: 1, 137 TotalMsgSignedByUser: 0, 138 CurMsgFee: linotypes.NewCoinFromInt64(int64(0)), 139 CurU: sdk.NewDec(1), 140 }, 141 expectAppInfo: model.AppBandwidthInfo{ 142 MessagesInCurBlock: 1, 143 MaxBandwidthCredit: sdk.NewDec(0), 144 CurBandwidthCredit: sdk.NewDec(0), 145 ExpectedMPS: sdk.NewDec(0), 146 LastRefilledAt: 0, 147 }, 148 }, 149 } 150 151 for _, tc := range testCases { 152 appName := linotypes.AccountKey("test") 153 appBandwidthInfo := model.AppBandwidthInfo{} 154 155 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appName, &appBandwidthInfo) 156 suite.Require().Nil(err) 157 158 err = suite.bm.AddMsgSignedByApp(suite.Ctx, appName, tc.amount) 159 suite.NoError(err) 160 info, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 161 suite.Require().Nil(err) 162 suite.Equal(tc.expectBlockInfo, *info, "%s", tc.testName) 163 164 appInfo, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appName) 165 suite.Require().Nil(err) 166 suite.Equal(tc.expectAppInfo, *appInfo, "%s", tc.testName) 167 } 168 } 169 170 func (suite *BandwidthManagerTestSuite) TestApproximateExp() { 171 testCases := []struct { 172 testName string 173 x sdk.Dec 174 expectedRes string 175 }{ 176 { 177 testName: "test1", 178 x: sdk.NewDec(0), 179 expectedRes: "1", 180 }, 181 { 182 testName: "test2", 183 x: sdk.NewDec(-6), 184 expectedRes: "0.002522536744331140", // truth: 0.00247875217 185 }, 186 { 187 testName: "test3", 188 x: sdk.NewDec(10), 189 expectedRes: "20983.411084513772091023", // truth: 22026.4657948 190 }, 191 { 192 testName: "test4", 193 x: sdk.NewDec(30), 194 expectedRes: "6944323407751.788994887415441546", // truth: 1.0686475e+13 195 }, 196 } 197 198 for _, tc := range testCases { 199 res := suite.bm.approximateExp(tc.x) 200 expectedFee, err := sdk.NewDecFromStr(tc.expectedRes) 201 suite.Require().Nil(err) 202 suite.Equal(expectedFee, res, "%s", tc.testName) 203 } 204 } 205 206 func (suite *BandwidthManagerTestSuite) TestCalculateCurMsgFee() { 207 testCases := []struct { 208 testName string 209 bandwidthInfo model.BandwidthInfo 210 expectMessageFeeCoin int64 211 }{ 212 { 213 testName: "test1", 214 bandwidthInfo: model.BandwidthInfo{ 215 GeneralMsgEMA: sdk.NewDec(0), 216 AppMsgEMA: sdk.NewDec(0), 217 MaxMPS: sdk.NewDec(1000), 218 }, 219 expectMessageFeeCoin: int64(2523), 220 }, 221 { 222 testName: "test2", 223 bandwidthInfo: model.BandwidthInfo{ 224 GeneralMsgEMA: sdk.NewDec(100), 225 AppMsgEMA: sdk.NewDec(0), 226 MaxMPS: sdk.NewDec(1000), 227 }, 228 expectMessageFeeCoin: int64(50006), 229 }, 230 { 231 testName: "test3", 232 bandwidthInfo: model.BandwidthInfo{ 233 GeneralMsgEMA: sdk.NewDec(200), 234 AppMsgEMA: sdk.NewDec(0), 235 MaxMPS: sdk.NewDec(1000), 236 }, 237 expectMessageFeeCoin: int64(1000000), 238 }, 239 { 240 testName: "test4", 241 bandwidthInfo: model.BandwidthInfo{ 242 GeneralMsgEMA: sdk.NewDec(300), 243 AppMsgEMA: sdk.NewDec(0), 244 MaxMPS: sdk.NewDec(1000), 245 }, 246 expectMessageFeeCoin: int64(19997635), 247 }, 248 { 249 testName: "test5", 250 bandwidthInfo: model.BandwidthInfo{ 251 GeneralMsgEMA: sdk.NewDec(300), 252 AppMsgEMA: sdk.NewDec(0), 253 MaxMPS: sdk.NewDec(500), 254 }, 255 expectMessageFeeCoin: int64(19997635), 256 }, 257 } 258 259 for _, tc := range testCases { 260 err := suite.bm.storage.SetBandwidthInfo(suite.Ctx, &tc.bandwidthInfo) 261 suite.NoError(err) 262 err = suite.bm.CalculateCurMsgFee(suite.Ctx) 263 suite.Require().Nil(err) 264 265 info, getErr := suite.bm.storage.GetBlockInfo(suite.Ctx) 266 suite.Require().Nil(getErr) 267 suite.Equal(linotypes.NewCoinFromInt64(tc.expectMessageFeeCoin), info.CurMsgFee, "%s", tc.testName) 268 } 269 } 270 271 // only one step 272 func (suite *BandwidthManagerTestSuite) TestUpdateMaxMPSAndEMA() { 273 testCases := []struct { 274 testName string 275 blockInfo model.BlockInfo 276 bandwidthInfo model.BandwidthInfo 277 expectGeneralEMA string 278 expectAppEMA string 279 expectMaxMPS sdk.Dec 280 }{ 281 { 282 testName: "test general message ema", 283 bandwidthInfo: model.BandwidthInfo{ 284 GeneralMsgEMA: sdk.NewDec(10), 285 AppMsgEMA: sdk.NewDec(0), 286 MaxMPS: sdk.NewDec(1000), 287 }, 288 blockInfo: model.BlockInfo{ 289 TotalMsgSignedByApp: 0, 290 TotalMsgSignedByUser: 60, 291 }, 292 293 expectGeneralEMA: "11", 294 expectAppEMA: "0", 295 expectMaxMPS: sdk.NewDec(1000), 296 }, 297 { 298 testName: "test app message ema", 299 bandwidthInfo: model.BandwidthInfo{ 300 GeneralMsgEMA: sdk.NewDec(0), 301 AppMsgEMA: sdk.NewDec(50), 302 MaxMPS: sdk.NewDec(1000), 303 }, 304 blockInfo: model.BlockInfo{ 305 TotalMsgSignedByApp: 270, 306 TotalMsgSignedByUser: 0, 307 }, 308 expectGeneralEMA: "0", 309 expectAppEMA: "54", 310 expectMaxMPS: sdk.NewDec(1000), 311 }, 312 { 313 testName: "test update max MPS", 314 bandwidthInfo: model.BandwidthInfo{ 315 GeneralMsgEMA: sdk.NewDec(0), 316 AppMsgEMA: sdk.NewDec(0), 317 MaxMPS: sdk.NewDec(1000), 318 }, 319 blockInfo: model.BlockInfo{ 320 TotalMsgSignedByApp: 15000, 321 TotalMsgSignedByUser: 15000, 322 }, 323 expectGeneralEMA: "500", 324 expectAppEMA: "500", 325 expectMaxMPS: sdk.NewDec(10000), 326 }, 327 } 328 329 for _, tc := range testCases { 330 err := suite.bm.storage.SetBandwidthInfo(suite.Ctx, &tc.bandwidthInfo) 331 suite.NoError(err) 332 err = suite.bm.storage.SetBlockInfo(suite.Ctx, &tc.blockInfo) 333 suite.NoError(err) 334 335 err = suite.bm.UpdateMaxMPSAndEMA(suite.Ctx) 336 suite.Nil(err, "%s", tc.testName) 337 338 expectedGeneralEMA, err := sdk.NewDecFromStr(tc.expectGeneralEMA) 339 suite.Nil(err, "%s", tc.testName) 340 341 expectedAppEMA, err := sdk.NewDecFromStr(tc.expectAppEMA) 342 suite.Nil(err, "%s", tc.testName) 343 344 info, err := suite.bm.storage.GetBandwidthInfo(suite.Ctx) 345 suite.Nil(err, "%s", tc.testName) 346 suite.Equal(expectedGeneralEMA, info.GeneralMsgEMA, "%s", tc.testName) 347 suite.Equal(expectedAppEMA, info.AppMsgEMA, "%s", tc.testName) 348 suite.Equal(tc.expectMaxMPS, info.MaxMPS, "%s", tc.testName) 349 350 } 351 } 352 353 func (suite *BandwidthManagerTestSuite) TestDecayMaxMPS() { 354 testCases := []struct { 355 testName string 356 info model.BandwidthInfo 357 expectedInfo model.BandwidthInfo 358 }{ 359 { 360 testName: "test1", 361 info: model.BandwidthInfo{ 362 GeneralMsgEMA: sdk.NewDec(0), 363 AppMsgEMA: sdk.NewDec(0), 364 MaxMPS: sdk.NewDec(100), 365 }, 366 expectedInfo: model.BandwidthInfo{ 367 GeneralMsgEMA: sdk.NewDec(0), 368 AppMsgEMA: sdk.NewDec(0), 369 MaxMPS: sdk.NewDec(99), 370 }, 371 }, 372 } 373 374 for _, tc := range testCases { 375 err := suite.bm.storage.SetBandwidthInfo(suite.Ctx, &tc.info) 376 suite.Require().Nil(err) 377 err = suite.bm.DecayMaxMPS(suite.Ctx) 378 suite.Require().Nil(err) 379 info, err := suite.bm.storage.GetBandwidthInfo(suite.Ctx) 380 suite.Nil(err, "%s", tc.testName) 381 suite.Equal(tc.expectedInfo, *info, "%s", tc.testName) 382 } 383 } 384 385 func (suite *BandwidthManagerTestSuite) TestCalculateEMA() { 386 testCases := []struct { 387 testName string 388 prevEMA sdk.Dec 389 k sdk.Dec 390 curMPS sdk.Dec 391 expectedEMA sdk.Dec 392 }{ 393 { 394 testName: "test1", 395 prevEMA: linotypes.NewDecFromRat(100, 1), 396 k: linotypes.NewDecFromRat(1, 10), 397 curMPS: linotypes.NewDecFromRat(200, 1), 398 expectedEMA: linotypes.NewDecFromRat(110, 1), 399 }, 400 } 401 402 for _, tc := range testCases { 403 res := suite.bm.calculateEMA(tc.prevEMA, tc.k, tc.curMPS) 404 suite.Equal(tc.expectedEMA, res, "%s", tc.testName) 405 } 406 } 407 408 func (suite *BandwidthManagerTestSuite) TestIsUserMsgFeeEnough() { 409 testCases := []struct { 410 testName string 411 providedFee auth.StdFee 412 curMsgFee linotypes.Coin 413 expectedRes bool 414 }{ 415 { 416 testName: "test1", 417 providedFee: auth.StdFee{ 418 Amount: sdk.NewCoins(sdk.NewCoin(linotypes.LinoCoinDenom, sdk.NewInt(12))), 419 }, 420 curMsgFee: linotypes.NewCoinFromInt64(int64(10)), 421 expectedRes: true, 422 }, 423 { 424 testName: "test2", 425 providedFee: auth.StdFee{ 426 Amount: sdk.NewCoins(sdk.NewCoin(linotypes.LinoCoinDenom, sdk.NewInt(2))), 427 }, 428 curMsgFee: linotypes.NewCoinFromInt64(int64(10)), 429 expectedRes: false, 430 }, 431 { 432 testName: "test3", 433 providedFee: auth.StdFee{ 434 Amount: sdk.NewCoins(sdk.NewCoin("dummy", sdk.NewInt(12))), 435 }, 436 curMsgFee: linotypes.NewCoinFromInt64(int64(10)), 437 expectedRes: false, 438 }, 439 } 440 441 for _, tc := range testCases { 442 info := model.BlockInfo{ 443 CurMsgFee: tc.curMsgFee, 444 } 445 err := suite.bm.storage.SetBlockInfo(suite.Ctx, &info) 446 suite.NoError(err) 447 res := suite.bm.IsUserMsgFeeEnough(suite.Ctx, tc.providedFee) 448 suite.Equal(tc.expectedRes, res, "%s", tc.testName) 449 } 450 } 451 452 func (suite *BandwidthManagerTestSuite) TestClearBlockInfo() { 453 testCases := []struct { 454 testName string 455 curBlockInfo model.BlockInfo 456 expectedBlockInfo model.BlockInfo 457 }{ 458 { 459 testName: "test1", 460 curBlockInfo: model.BlockInfo{ 461 TotalMsgSignedByApp: 1, 462 TotalMsgSignedByUser: 2, 463 CurMsgFee: linotypes.NewCoinFromInt64(int64(32)), 464 CurU: sdk.NewDec(2), 465 }, 466 expectedBlockInfo: model.BlockInfo{ 467 TotalMsgSignedByApp: 0, 468 TotalMsgSignedByUser: 0, 469 CurMsgFee: linotypes.NewCoinFromInt64(int64(32)), 470 CurU: sdk.NewDec(2), 471 }, 472 }, 473 } 474 475 for _, tc := range testCases { 476 err := suite.bm.storage.SetBlockInfo(suite.Ctx, &tc.curBlockInfo) 477 suite.Nil(err, "%s", tc.testName) 478 479 err = suite.bm.ClearBlockInfo(suite.Ctx) 480 suite.Nil(err, "%s", tc.testName) 481 482 res, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 483 suite.Nil(err, "%s", tc.testName) 484 suite.Equal(tc.expectedBlockInfo, *res, "%s", tc.testName) 485 } 486 } 487 488 func (suite *BandwidthManagerTestSuite) TestGetBandwidthCostPerMsg() { 489 testCases := []struct { 490 testName string 491 u sdk.Dec 492 p sdk.Dec 493 expectedCost sdk.Dec 494 }{ 495 { 496 testName: "test1", 497 u: sdk.NewDec(5), 498 p: sdk.NewDec(2), 499 expectedCost: sdk.NewDec(10), 500 }, 501 } 502 503 for _, tc := range testCases { 504 res := suite.bm.GetBandwidthCostPerMsg(suite.Ctx, tc.u, tc.p) 505 suite.Equal(tc.expectedCost, res, "%s", tc.testName) 506 } 507 } 508 509 func (suite *BandwidthManagerTestSuite) TestGetPunishmentCoeff() { 510 testCases := []struct { 511 testName string 512 appBandwidthInfo model.AppBandwidthInfo 513 expectedP string 514 }{ 515 { 516 testName: "test1", 517 appBandwidthInfo: model.AppBandwidthInfo{ 518 ExpectedMPS: sdk.NewDec(100), 519 MessagesInCurBlock: 300, 520 }, 521 expectedP: "1", 522 }, 523 { 524 testName: "test2", 525 appBandwidthInfo: model.AppBandwidthInfo{ 526 ExpectedMPS: sdk.NewDec(100), 527 MessagesInCurBlock: 375, 528 }, 529 expectedP: "2.013271178444183139", 530 }, 531 } 532 533 for _, tc := range testCases { 534 appName := linotypes.AccountKey("test") 535 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appName, &tc.appBandwidthInfo) 536 suite.Nil(err, "%s", tc.testName) 537 538 res, getErr := suite.bm.GetPunishmentCoeff(suite.Ctx, appName) 539 suite.Nil(getErr, "%s", tc.testName) 540 541 expectedRes, err := sdk.NewDecFromStr(tc.expectedP) 542 suite.Nil(err, "%s", tc.testName) 543 suite.Equal(expectedRes, res, "%s", tc.testName) 544 } 545 } 546 547 func (suite *BandwidthManagerTestSuite) TestGetVacancyCoeff() { 548 testCases := []struct { 549 testName string 550 bandwidthInfo model.BandwidthInfo 551 expectedU string 552 }{ 553 { 554 testName: "test1", 555 bandwidthInfo: model.BandwidthInfo{ 556 MaxMPS: sdk.NewDec(1000), 557 AppMsgEMA: sdk.NewDec(0), 558 }, 559 expectedU: "0.501692631996395802", 560 }, 561 { 562 testName: "test2", 563 bandwidthInfo: model.BandwidthInfo{ 564 MaxMPS: sdk.NewDec(800), 565 AppMsgEMA: sdk.NewDec(800), 566 }, 567 expectedU: "1", 568 }, 569 } 570 571 for _, tc := range testCases { 572 err := suite.bm.storage.SetBandwidthInfo(suite.Ctx, &tc.bandwidthInfo) 573 suite.Nil(err, "%s", tc.testName) 574 575 err = suite.bm.CalculateCurU(suite.Ctx) 576 suite.Nil(err, "%s", tc.testName) 577 578 expectedRes, err := sdk.NewDecFromStr(tc.expectedU) 579 suite.Nil(err, "%s", tc.testName) 580 581 blockInfo, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 582 suite.Nil(err, "%s", tc.testName) 583 suite.Equal(expectedRes, blockInfo.CurU, "%s", tc.testName) 584 } 585 } 586 587 func (suite *BandwidthManagerTestSuite) TestRefillAppBandwidthCredit() { 588 testCases := []struct { 589 testName string 590 appBandwidthInfo model.AppBandwidthInfo 591 curTime time.Time 592 expectedInfo model.AppBandwidthInfo 593 }{ 594 { 595 testName: "test1", 596 appBandwidthInfo: model.AppBandwidthInfo{ 597 MaxBandwidthCredit: sdk.NewDec(3000), 598 ExpectedMPS: sdk.NewDec(200), 599 CurBandwidthCredit: sdk.NewDec(0), 600 LastRefilledAt: suite.baseTime.Unix(), 601 }, 602 curTime: suite.baseTime.Add(3 * time.Second), 603 expectedInfo: model.AppBandwidthInfo{ 604 MaxBandwidthCredit: sdk.NewDec(3000), 605 ExpectedMPS: sdk.NewDec(200), 606 CurBandwidthCredit: sdk.NewDec(600), 607 LastRefilledAt: suite.baseTime.Add(3 * time.Second).Unix(), 608 }, 609 }, 610 { 611 testName: "test2", 612 appBandwidthInfo: model.AppBandwidthInfo{ 613 MaxBandwidthCredit: sdk.NewDec(3000), 614 ExpectedMPS: sdk.NewDec(200), 615 CurBandwidthCredit: sdk.NewDec(0), 616 LastRefilledAt: suite.baseTime.Unix(), 617 }, 618 curTime: suite.baseTime.Add(1000 * time.Second), 619 expectedInfo: model.AppBandwidthInfo{ 620 MaxBandwidthCredit: sdk.NewDec(3000), 621 ExpectedMPS: sdk.NewDec(200), 622 CurBandwidthCredit: sdk.NewDec(3000), 623 LastRefilledAt: suite.baseTime.Add(1000 * time.Second).Unix(), 624 }, 625 }, 626 { 627 testName: "test3", 628 appBandwidthInfo: model.AppBandwidthInfo{ 629 MaxBandwidthCredit: sdk.NewDec(3000), 630 ExpectedMPS: sdk.NewDec(200), 631 CurBandwidthCredit: sdk.NewDec(0), 632 LastRefilledAt: suite.baseTime.Add(3 * time.Second).Unix(), 633 }, 634 curTime: suite.baseTime, 635 expectedInfo: model.AppBandwidthInfo{ 636 MaxBandwidthCredit: sdk.NewDec(3000), 637 ExpectedMPS: sdk.NewDec(200), 638 CurBandwidthCredit: sdk.NewDec(0), 639 LastRefilledAt: suite.baseTime.Add(3 * time.Second).Unix(), 640 }, 641 }, 642 } 643 644 for _, tc := range testCases { 645 suite.Ctx = suite.Ctx.WithBlockHeader(abci.Header{Time: tc.curTime}) 646 appName := linotypes.AccountKey("test") 647 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appName, &tc.appBandwidthInfo) 648 suite.Nil(err, "%s", tc.testName) 649 650 err = suite.bm.RefillAppBandwidthCredit(suite.Ctx, appName) 651 suite.Nil(err, "%s", tc.testName) 652 653 res, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appName) 654 suite.Nil(err, "%s", tc.testName) 655 suite.Equal(tc.expectedInfo, *res, "%s", tc.testName) 656 } 657 } 658 659 func (suite *BandwidthManagerTestSuite) TestConsumeBandwidthCredit() { 660 testCases := []struct { 661 testName string 662 appInfo model.AppBandwidthInfo 663 u sdk.Dec 664 p sdk.Dec 665 expectedInfo model.AppBandwidthInfo 666 }{ 667 { 668 testName: "test1", 669 u: linotypes.NewDecFromRat(5, 10), 670 p: linotypes.NewDecFromRat(5, 10), 671 appInfo: model.AppBandwidthInfo{ 672 Username: linotypes.AccountKey("test"), 673 MaxBandwidthCredit: sdk.NewDec(1000), 674 CurBandwidthCredit: sdk.NewDec(500), 675 MessagesInCurBlock: 100, 676 ExpectedMPS: sdk.NewDec(50), 677 LastRefilledAt: 0, 678 }, 679 expectedInfo: model.AppBandwidthInfo{ 680 Username: linotypes.AccountKey("test"), 681 MaxBandwidthCredit: sdk.NewDec(1000), 682 CurBandwidthCredit: sdk.NewDec(525), 683 MessagesInCurBlock: 0, 684 ExpectedMPS: sdk.NewDec(50), 685 LastRefilledAt: 0, 686 }, 687 }, 688 { 689 testName: "test2", 690 u: linotypes.NewDecFromRat(1, 1), 691 p: linotypes.NewDecFromRat(200, 1), 692 appInfo: model.AppBandwidthInfo{ 693 Username: linotypes.AccountKey("test"), 694 MaxBandwidthCredit: sdk.NewDec(1000), 695 CurBandwidthCredit: sdk.NewDec(500), 696 MessagesInCurBlock: 20, 697 ExpectedMPS: sdk.NewDec(50), 698 LastRefilledAt: 0, 699 }, 700 expectedInfo: model.AppBandwidthInfo{ 701 Username: linotypes.AccountKey("test"), 702 MaxBandwidthCredit: sdk.NewDec(1000), 703 CurBandwidthCredit: sdk.NewDec(-3480), 704 MessagesInCurBlock: 0, 705 ExpectedMPS: sdk.NewDec(50), 706 LastRefilledAt: 0, 707 }, 708 }, 709 } 710 711 for _, tc := range testCases { 712 appName := linotypes.AccountKey("test") 713 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appName, &tc.appInfo) 714 suite.Nil(err, "%s", tc.testName) 715 716 err = suite.bm.ConsumeBandwidthCredit(suite.Ctx, tc.u, tc.p, appName) 717 suite.Nil(err, "%s", tc.testName) 718 719 res, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appName) 720 suite.Nil(err, "%s", tc.testName) 721 suite.Equal(tc.expectedInfo, *res, "%s", tc.testName) 722 } 723 } 724 725 func (suite *BandwidthManagerTestSuite) TestPrecheckAndConsumeBandwidthCredit() { 726 testCases := []struct { 727 testName string 728 appInfo model.AppBandwidthInfo 729 blockInfo model.BlockInfo 730 expectedAppInfo model.AppBandwidthInfo 731 expectedErr sdk.Error 732 }{ 733 { 734 testName: "test1", 735 blockInfo: model.BlockInfo{ 736 CurU: sdk.NewDec(1), 737 }, 738 appInfo: model.AppBandwidthInfo{ 739 Username: linotypes.AccountKey("test"), 740 MaxBandwidthCredit: sdk.NewDec(1000), 741 CurBandwidthCredit: sdk.NewDec(500), 742 MessagesInCurBlock: 100, 743 ExpectedMPS: sdk.NewDec(50), 744 LastRefilledAt: 0, 745 }, 746 expectedAppInfo: model.AppBandwidthInfo{ 747 Username: linotypes.AccountKey("test"), 748 MaxBandwidthCredit: sdk.NewDec(1000), 749 CurBandwidthCredit: sdk.NewDec(499), 750 MessagesInCurBlock: 100, 751 ExpectedMPS: sdk.NewDec(50), 752 LastRefilledAt: 0, 753 }, 754 expectedErr: nil, 755 }, 756 { 757 testName: "test2", 758 blockInfo: model.BlockInfo{ 759 CurU: sdk.NewDec(2), 760 }, 761 appInfo: model.AppBandwidthInfo{ 762 Username: linotypes.AccountKey("test"), 763 MaxBandwidthCredit: sdk.NewDec(1000), 764 CurBandwidthCredit: sdk.NewDec(1), 765 MessagesInCurBlock: 100, 766 ExpectedMPS: sdk.NewDec(50), 767 LastRefilledAt: 0, 768 }, 769 expectedAppInfo: model.AppBandwidthInfo{ 770 Username: linotypes.AccountKey("test"), 771 MaxBandwidthCredit: sdk.NewDec(1000), 772 CurBandwidthCredit: sdk.NewDec(1), 773 MessagesInCurBlock: 100, 774 ExpectedMPS: sdk.NewDec(50), 775 LastRefilledAt: 0, 776 }, 777 expectedErr: types.ErrAppBandwidthNotEnough(), 778 }, 779 } 780 781 for _, tc := range testCases { 782 appName := linotypes.AccountKey("test") 783 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appName, &tc.appInfo) 784 suite.Nil(err, "%s", tc.testName) 785 786 err = suite.bm.storage.SetBlockInfo(suite.Ctx, &tc.blockInfo) 787 suite.Nil(err, "%s", tc.testName) 788 789 err = suite.bm.PrecheckAndConsumeBandwidthCredit(suite.Ctx, appName) 790 suite.Equal(tc.expectedErr, err, "%s", tc.testName) 791 792 appInfo, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appName) 793 suite.Nil(err, "%s", tc.testName) 794 suite.Equal(tc.expectedAppInfo, *appInfo, "%s", tc.testName) 795 } 796 } 797 798 func (suite *BandwidthManagerTestSuite) TestReCalculateAppBandwidthInfo() { 799 testCases := []struct { 800 testName string 801 prevAppYInfo model.AppBandwidthInfo 802 expectedAppXInfo model.AppBandwidthInfo 803 expectedAppYInfo model.AppBandwidthInfo 804 }{ 805 { 806 testName: "test1", 807 prevAppYInfo: model.AppBandwidthInfo{ 808 Username: linotypes.AccountKey("AppY"), 809 MaxBandwidthCredit: sdk.NewDec(800 * 10), 810 CurBandwidthCredit: sdk.NewDec(0), 811 MessagesInCurBlock: 0, 812 ExpectedMPS: sdk.NewDec(800), 813 LastRefilledAt: suite.baseTime.Unix(), 814 }, 815 expectedAppXInfo: model.AppBandwidthInfo{ 816 Username: linotypes.AccountKey("AppX"), 817 MaxBandwidthCredit: sdk.NewDec(80 * 10), 818 CurBandwidthCredit: sdk.NewDec(80 * 10), 819 MessagesInCurBlock: 0, 820 ExpectedMPS: sdk.NewDec(80), 821 LastRefilledAt: suite.Ctx.BlockHeader().Time.Unix(), 822 }, 823 expectedAppYInfo: model.AppBandwidthInfo{ 824 Username: linotypes.AccountKey("AppY"), 825 MaxBandwidthCredit: sdk.NewDec(720 * 10), 826 CurBandwidthCredit: sdk.NewDec(2400), 827 MessagesInCurBlock: 0, 828 ExpectedMPS: sdk.NewDec(720), 829 LastRefilledAt: suite.Ctx.BlockHeader().Time.Unix(), 830 }, 831 }, 832 } 833 834 for _, tc := range testCases { 835 appX := linotypes.AccountKey("AppX") 836 appY := linotypes.AccountKey("AppY") 837 838 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appY, &tc.prevAppYInfo) 839 suite.Nil(err, "%s", tc.testName) 840 841 err = suite.bm.ReCalculateAppBandwidthInfo(suite.Ctx) 842 suite.Nil(err, "%s", tc.testName) 843 844 appXInfo, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appX) 845 suite.Nil(err, "%s", tc.testName) 846 suite.Equal(tc.expectedAppXInfo, *appXInfo, "%s", tc.testName) 847 848 appYInfo, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appY) 849 suite.Nil(err, "%s", tc.testName) 850 suite.Equal(tc.expectedAppYInfo, *appYInfo, "%s", tc.testName) 851 } 852 } 853 854 func (suite *BandwidthManagerTestSuite) TestCheckAppBandwidth() { 855 testCases := []struct { 856 testName string 857 fee auth.StdFee 858 prevAppYInfo model.AppBandwidthInfo 859 expectedAppYInfo model.AppBandwidthInfo 860 expectedBlockInfo model.BlockInfo 861 expectedErr sdk.Error 862 }{ 863 { 864 testName: "test1", 865 fee: auth.StdFee{}, 866 prevAppYInfo: model.AppBandwidthInfo{ 867 Username: linotypes.AccountKey("AppY"), 868 MaxBandwidthCredit: sdk.NewDec(800 * 10), 869 CurBandwidthCredit: sdk.NewDec(4000), 870 MessagesInCurBlock: 0, 871 ExpectedMPS: sdk.NewDec(800), 872 LastRefilledAt: 0, 873 }, 874 expectedAppYInfo: model.AppBandwidthInfo{ 875 Username: linotypes.AccountKey("AppY"), 876 MaxBandwidthCredit: sdk.NewDec(800 * 10), 877 CurBandwidthCredit: sdk.NewDec(7999), 878 MessagesInCurBlock: 1, 879 ExpectedMPS: sdk.NewDec(800), 880 LastRefilledAt: suite.Ctx.BlockHeader().Time.Unix(), 881 }, 882 expectedBlockInfo: model.BlockInfo{ 883 TotalMsgSignedByApp: 1, 884 TotalMsgSignedByUser: 0, 885 CurMsgFee: linotypes.NewCoinFromInt64(0), 886 CurU: sdk.NewDec(1), 887 }, 888 expectedErr: nil, 889 }, 890 { 891 testName: "test2", 892 fee: auth.StdFee{}, 893 prevAppYInfo: model.AppBandwidthInfo{ 894 Username: linotypes.AccountKey("AppY"), 895 MaxBandwidthCredit: sdk.NewDec(800 * 10), 896 CurBandwidthCredit: sdk.NewDec(0), 897 MessagesInCurBlock: 0, 898 ExpectedMPS: sdk.NewDec(800), 899 LastRefilledAt: suite.Ctx.BlockHeader().Time.Unix(), 900 }, 901 expectedAppYInfo: model.AppBandwidthInfo{ 902 Username: linotypes.AccountKey("AppY"), 903 MaxBandwidthCredit: sdk.NewDec(800 * 10), 904 CurBandwidthCredit: sdk.NewDec(0), 905 MessagesInCurBlock: 0, 906 ExpectedMPS: sdk.NewDec(800), 907 LastRefilledAt: suite.Ctx.BlockHeader().Time.Unix(), 908 }, 909 expectedBlockInfo: model.BlockInfo{ 910 TotalMsgSignedByApp: 1, 911 TotalMsgSignedByUser: 0, 912 CurMsgFee: linotypes.NewCoinFromInt64(0), 913 CurU: sdk.NewDec(1), 914 }, 915 expectedErr: types.ErrAppBandwidthNotEnough(), 916 }, 917 } 918 919 for _, tc := range testCases { 920 appYAddr := sdk.AccAddress("appYAddr") 921 appY := linotypes.AccountKey("AppY") 922 err := suite.bm.storage.SetAppBandwidthInfo(suite.Ctx, appY, &tc.prevAppYInfo) 923 suite.Nil(err, "%s", tc.testName) 924 925 err = suite.bm.CheckBandwidth(suite.Ctx, appYAddr, tc.fee) 926 suite.Equal(tc.expectedErr, err, "%s", tc.testName) 927 928 appYInfo, err := suite.bm.storage.GetAppBandwidthInfo(suite.Ctx, appY) 929 suite.Nil(err, "%s", tc.testName) 930 suite.Equal(tc.expectedAppYInfo, *appYInfo, "%s", tc.testName) 931 932 blockInfo, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 933 suite.Nil(err, "%s", tc.testName) 934 suite.Equal(tc.expectedBlockInfo, *blockInfo, "%s", tc.testName) 935 } 936 } 937 938 func (suite *BandwidthManagerTestSuite) TestCheckMsgFee() { 939 testCases := []struct { 940 testName string 941 address sdk.AccAddress 942 fee auth.StdFee 943 blockInfo model.BlockInfo 944 expectedBlockInfo model.BlockInfo 945 expectedErr sdk.Error 946 }{ 947 { 948 testName: "test1", 949 fee: auth.StdFee{Amount: sdk.NewCoins(sdk.NewCoin(linotypes.LinoCoinDenom, sdk.NewInt(1000)))}, 950 address: sdk.AccAddress("userXAddr"), 951 blockInfo: model.BlockInfo{ 952 TotalMsgSignedByApp: 0, 953 TotalMsgSignedByUser: 0, 954 CurMsgFee: linotypes.NewCoinFromInt64(100), 955 CurU: sdk.NewDec(1), 956 }, 957 expectedBlockInfo: model.BlockInfo{ 958 TotalMsgSignedByApp: 0, 959 TotalMsgSignedByUser: 1, 960 CurMsgFee: linotypes.NewCoinFromInt64(100), 961 CurU: sdk.NewDec(1), 962 }, 963 expectedErr: nil, 964 }, 965 { 966 testName: "test2", 967 fee: auth.StdFee{Amount: sdk.NewCoins(sdk.NewCoin(linotypes.LinoCoinDenom, sdk.NewInt(10)))}, 968 address: sdk.AccAddress("userXAddr"), 969 blockInfo: model.BlockInfo{ 970 TotalMsgSignedByApp: 0, 971 TotalMsgSignedByUser: 0, 972 CurMsgFee: linotypes.NewCoinFromInt64(100), 973 CurU: sdk.NewDec(1), 974 }, 975 expectedBlockInfo: model.BlockInfo{ 976 TotalMsgSignedByApp: 0, 977 TotalMsgSignedByUser: 0, 978 CurMsgFee: linotypes.NewCoinFromInt64(100), 979 CurU: sdk.NewDec(1), 980 }, 981 expectedErr: types.ErrUserMsgFeeNotEnough(), 982 }, 983 { 984 testName: "test3", 985 fee: auth.StdFee{Amount: sdk.NewCoins(sdk.NewCoin(linotypes.LinoCoinDenom, sdk.NewInt(10)))}, 986 address: sdk.AccAddress("emptyAddr"), 987 blockInfo: model.BlockInfo{ 988 TotalMsgSignedByApp: 0, 989 TotalMsgSignedByUser: 0, 990 CurMsgFee: linotypes.NewCoinFromInt64(100), 991 CurU: sdk.NewDec(1), 992 }, 993 expectedBlockInfo: model.BlockInfo{ 994 TotalMsgSignedByApp: 0, 995 TotalMsgSignedByUser: 0, 996 CurMsgFee: linotypes.NewCoinFromInt64(100), 997 CurU: sdk.NewDec(1), 998 }, 999 expectedErr: acctypes.ErrAccountBankNotFound(sdk.AccAddress("emptyAddr")), 1000 }, 1001 } 1002 1003 for _, tc := range testCases { 1004 err := suite.bm.storage.SetBlockInfo(suite.Ctx, &tc.blockInfo) 1005 suite.Nil(err, "%s", tc.testName) 1006 1007 err = suite.bm.CheckBandwidth(suite.Ctx, tc.address, tc.fee) 1008 suite.Equal(tc.expectedErr, err, "%s", tc.testName) 1009 1010 blockInfo, err := suite.bm.storage.GetBlockInfo(suite.Ctx) 1011 suite.Nil(err, "%s", tc.testName) 1012 suite.Equal(tc.expectedBlockInfo, *blockInfo, "%s", tc.testName) 1013 } 1014 }