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 = &param.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(&parammodel.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  }