package keeper_test import ( "math/rand" "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/simulation" "github.com/kava-labs/kava/app" "github.com/kava-labs/kava/x/cdp/keeper" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" tmtime "github.com/tendermint/tendermint/types/time" ) type FeeTestSuite struct { suite.Suite keeper keeper.Keeper app app.TestApp ctx sdk.Context } func (suite *FeeTestSuite) SetupTest() { tApp := app.NewTestApp() ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()}) tApp.InitializeFromGenesisStates( NewPricefeedGenStateMulti(), NewCDPGenStateMulti(), ) keeper := tApp.GetCDPKeeper() suite.app = tApp suite.ctx = ctx suite.keeper = keeper } func (suite *FeeTestSuite) TestCalculateFeesPrecisionLoss() { // Calculates the difference between fees calculated on the total amount of debt, // versus iterating over all the 1000 randomly generated cdps. // Assumes 7 second block times, runs simulations for 100, 1000, 10000, 100000, and 1000000 // blocks, where the bulk debt is updated each block, and the cdps are updated once. coins := []sdk.Coins{} total := sdk.NewCoins() for i := 0; i < 1000; i++ { ri, err := simulation.RandPositiveInt(rand.New(rand.NewSource(int64(i))), sdk.NewInt(100000000000)) suite.NoError(err) c := sdk.NewCoins(sdk.NewCoin("usdx", ri)) coins = append(coins, c) total = total.Add(cs(sdk.NewCoin("usdx", ri))) } numBlocks := []int{100, 1000, 10000, 100000} for _, nb := range numBlocks { bulkFees := sdk.NewCoins() individualFees := sdk.NewCoins() for x := 0; x < nb; x++ { fee := suite.keeper.CalculateFees(suite.ctx, total.Add(bulkFees), i(7), "xrp") bulkFees = bulkFees.Add(fee) } for _, cns := range coins { fee := suite.keeper.CalculateFees(suite.ctx, cns, i(int64(nb*7)), "xrp") individualFees = individualFees.Add(fee) } absError := (sdk.OneDec().Sub(sdk.NewDecFromInt(bulkFees[0].Amount).Quo(sdk.NewDecFromInt(individualFees[0].Amount)))).Abs() suite.T().Log(bulkFees) suite.T().Log(individualFees) suite.T().Log(absError) suite.True(d("0.00001").GTE(absError)) } } func (suite *FeeTestSuite) TestGetSetPreviousBlockTime() { now := tmtime.Now() _, f := suite.keeper.GetPreviousBlockTime(suite.ctx) suite.False(f) suite.NotPanics(func() { suite.keeper.SetPreviousBlockTime(suite.ctx, now) }) bpt, f := suite.keeper.GetPreviousBlockTime(suite.ctx) suite.True(f) suite.Equal(now, bpt) } func TestFeeTestSuite(t *testing.T) { suite.Run(t, new(FeeTestSuite)) }