github.com/gravity-devs/liquidity@v1.5.3/x/liquidity/keeper/store_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  
     7  	sdk "github.com/cosmos/cosmos-sdk/types"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/gravity-devs/liquidity/app"
    11  	"github.com/gravity-devs/liquidity/x/liquidity"
    12  	"github.com/gravity-devs/liquidity/x/liquidity/types"
    13  )
    14  
    15  func TestGetAllLiquidityPoolBatchSwapMsgs(t *testing.T) {
    16  	for seed := int64(0); seed < 100; seed++ {
    17  		r := rand.New(rand.NewSource(seed))
    18  
    19  		simapp, ctx := createTestInput()
    20  		simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
    21  		params := simapp.LiquidityKeeper.GetParams(ctx)
    22  
    23  		// define test denom X, Y for Liquidity Pool
    24  		denomX := "denomX"
    25  		denomY := "denomY"
    26  		denomX, denomY = types.AlphabeticalDenomPair(denomX, denomY)
    27  
    28  		// get random X, Y amount for create pool
    29  		X, Y := app.GetRandPoolAmt(r, params.MinInitDepositAmount)
    30  		deposit := sdk.NewCoins(sdk.NewCoin(denomX, X), sdk.NewCoin(denomY, Y))
    31  
    32  		// set pool creator account, balance for deposit
    33  		addrs := app.AddTestAddrs(simapp, ctx, 3, params.PoolCreationFee)
    34  		app.SaveAccount(simapp, ctx, addrs[0], deposit) // pool creator
    35  		depositA := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomX)
    36  		depositB := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomY)
    37  		depositBalance := sdk.NewCoins(depositA, depositB)
    38  		require.Equal(t, deposit, depositBalance)
    39  
    40  		// create Liquidity pool
    41  		poolTypeID := types.DefaultPoolTypeID
    42  		msg := types.NewMsgCreatePool(addrs[0], poolTypeID, depositBalance)
    43  		_, err := simapp.LiquidityKeeper.CreatePool(ctx, msg)
    44  		require.NoError(t, err)
    45  
    46  		var xToY []*types.MsgSwapWithinBatch // buying Y from X
    47  		var yToX []*types.MsgSwapWithinBatch // selling Y for X
    48  
    49  		// make random orders, set buyer, seller accounts for the orders
    50  		xToY, yToX = app.GetRandomOrders(denomX, denomY, X, Y, r, 11, 11)
    51  		buyerAddrs := app.AddTestAddrsIncremental(simapp, ctx, len(xToY), sdk.ZeroInt())
    52  		sellerAddrs := app.AddTestAddrsIncremental(simapp, ctx, len(yToX), sdk.ZeroInt())
    53  
    54  		poolID := uint64(1)
    55  		pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
    56  		require.True(t, found)
    57  
    58  		poolBatch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
    59  		require.Equal(t, uint64(1), poolBatch.SwapMsgIndex)
    60  
    61  		for i, msg := range xToY {
    62  			app.SaveAccountWithFee(simapp, ctx, buyerAddrs[i], sdk.NewCoins(msg.OfferCoin), msg.OfferCoin)
    63  			msg.SwapRequesterAddress = buyerAddrs[i].String()
    64  			msg.PoolId = pool.Id
    65  			msg.OfferCoinFee = types.GetOfferCoinFee(msg.OfferCoin, params.SwapFeeRate)
    66  		}
    67  		for i, msg := range yToX {
    68  			app.SaveAccountWithFee(simapp, ctx, sellerAddrs[i], sdk.NewCoins(msg.OfferCoin), msg.OfferCoin)
    69  			msg.SwapRequesterAddress = sellerAddrs[i].String()
    70  			msg.PoolId = pool.Id
    71  			msg.OfferCoinFee = types.GetOfferCoinFee(msg.OfferCoin, params.SwapFeeRate)
    72  		}
    73  
    74  		// handle msgs, set order msgs to batch
    75  		for _, msg := range xToY[:10] {
    76  			_, err := simapp.LiquidityKeeper.SwapWithinBatch(ctx, msg, 0)
    77  			require.NoError(t, err)
    78  		}
    79  		for _, msg := range yToX[:10] {
    80  			_, err := simapp.LiquidityKeeper.SwapWithinBatch(ctx, msg, 0)
    81  			require.NoError(t, err)
    82  		}
    83  
    84  		msgs := simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStatesAsPointer(ctx, poolBatch)
    85  		require.Equal(t, 20, len(msgs))
    86  
    87  		simapp.LiquidityKeeper.IterateAllPoolBatchSwapMsgStates(ctx, poolBatch, func(msg types.SwapMsgState) bool {
    88  			if msg.MsgIndex%2 == 1 {
    89  				simapp.LiquidityKeeper.DeletePoolBatchSwapMsgState(ctx, msg.Msg.PoolId, msg.MsgIndex)
    90  			}
    91  			return false
    92  		})
    93  
    94  		msgs = simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStatesAsPointer(ctx, poolBatch)
    95  		require.Equal(t, 10, len(msgs))
    96  
    97  		poolBatch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
    98  		require.Equal(t, uint64(21), poolBatch.SwapMsgIndex)
    99  
   100  		poolBatch.SwapMsgIndex = uint64(18446744073709551610)
   101  		simapp.LiquidityKeeper.SetPoolBatch(ctx, poolBatch)
   102  
   103  		_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, xToY[10], 0)
   104  		require.NoError(t, err)
   105  		_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, yToX[10], 0)
   106  		require.NoError(t, err)
   107  
   108  		msgs = simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStatesAsPointer(ctx, poolBatch)
   109  		require.Equal(t, 12, len(msgs))
   110  		require.Equal(t, xToY[10], msgs[10].Msg)
   111  		require.Equal(t, yToX[10], msgs[11].Msg)
   112  	}
   113  }
   114  
   115  func TestGetAllNotProcessedPoolBatchSwapMsgs(t *testing.T) {
   116  	simapp, ctx := createTestInput()
   117  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   118  
   119  	// define test denom X, Y for Liquidity Pool
   120  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   121  
   122  	X := sdk.NewInt(1000000000)
   123  	Y := sdk.NewInt(1000000000)
   124  
   125  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   126  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   127  
   128  	// begin block, init
   129  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, true)
   130  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, true)
   131  
   132  	// next block
   133  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   134  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   135  
   136  	price, _ := sdk.NewDecFromStr("1.1")
   137  	offerCoins := []sdk.Coin{sdk.NewCoin(denomX, sdk.NewInt(10000)), sdk.NewCoin(denomX, sdk.NewInt(10000)), sdk.NewCoin(denomX, sdk.NewInt(10000))}
   138  	orderPrices := []sdk.Dec{price, price, price}
   139  	orderAddrs := addrs[1:4]
   140  	batchMsgs, _ := app.TestSwapPool(t, simapp, ctx, offerCoins, orderPrices, orderAddrs, poolID, false)
   141  	batchMsgs2, batch := app.TestSwapPool(t, simapp, ctx, offerCoins, orderPrices, orderAddrs, poolID, false)
   142  	require.Equal(t, 3, len(batchMsgs))
   143  	for _, msg := range batchMsgs2 {
   144  		msg.Executed = true
   145  		msg.Succeeded = true
   146  		msg.ToBeDeleted = true
   147  	}
   148  	require.Equal(t, 3, len(batchMsgs2))
   149  	simapp.LiquidityKeeper.SetPoolBatchSwapMsgStatesByPointer(ctx, poolID, batchMsgs2)
   150  
   151  	resultMsgs := simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStatesAsPointer(ctx, batch)
   152  	resultProcessedMsgs := simapp.LiquidityKeeper.GetAllNotProcessedPoolBatchSwapMsgStates(ctx, batch)
   153  	require.Equal(t, 6, len(resultMsgs))
   154  	require.Equal(t, 3, len(resultProcessedMsgs))
   155  
   156  }
   157  
   158  func TestIterateAllBatchMsgs(t *testing.T) {
   159  	simapp, ctx := createTestInput()
   160  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   161  
   162  	// define test denom X, Y for Liquidity Pool
   163  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   164  	denomA, denomB := types.AlphabeticalDenomPair("denomA", "denomB")
   165  
   166  	X := sdk.NewInt(1000000000)
   167  	Y := sdk.NewInt(500000000)
   168  	A := sdk.NewInt(500000000)
   169  	B := sdk.NewInt(1000000000)
   170  
   171  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   172  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   173  	poolId2 := app.TestCreatePool(t, simapp, ctx, A, B, denomA, denomB, addrs[4])
   174  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   175  	require.True(t, found)
   176  
   177  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   178  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   179  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   180  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   181  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   182  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   183  
   184  	price, _ := sdk.NewDecFromStr("1.1")
   185  	priceY, _ := sdk.NewDecFromStr("1.2")
   186  	xOfferCoins := []sdk.Coin{sdk.NewCoin(denomX, sdk.NewInt(10000))}
   187  	yOfferCoins := []sdk.Coin{sdk.NewCoin(denomY, sdk.NewInt(5000))}
   188  
   189  	xOrderPrices := []sdk.Dec{price}
   190  	yOrderPrices := []sdk.Dec{priceY}
   191  	xOrderAddrs := addrs[1:2]
   192  	yOrderAddrs := addrs[2:3]
   193  
   194  	offerCoins2 := []sdk.Coin{sdk.NewCoin(denomA, sdk.NewInt(5000))}
   195  
   196  	// next block
   197  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   198  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   199  
   200  	app.TestDepositPool(t, simapp, ctx, A, B.QuoRaw(10), addrs[4:5], poolId2, false)
   201  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(1000), addrs[4:5], poolId2, false)
   202  	app.TestSwapPool(t, simapp, ctx, offerCoins2, xOrderPrices, addrs[4:5], poolId2, true)
   203  
   204  	// next block
   205  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   206  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   207  
   208  	app.TestDepositPool(t, simapp, ctx, A, B.QuoRaw(10), addrs[4:5], poolId2, false)
   209  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(1000), addrs[4:5], poolId2, false)
   210  	app.TestSwapPool(t, simapp, ctx, offerCoins2, xOrderPrices, addrs[4:5], poolId2, true)
   211  
   212  	// next block,
   213  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   214  	// Reinitialize batch messages that were not executed in the previous batch and delete batch messages that were executed or ready to delete.
   215  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   216  
   217  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   218  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   219  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   220  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   221  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[1:2], poolID, false)
   222  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[1:2], poolID, false)
   223  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[2:3], poolID, false)
   224  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[2:3], poolID, false)
   225  
   226  	depositMsgsRemaining := simapp.LiquidityKeeper.GetAllRemainingPoolBatchDepositMsgStates(ctx, batch)
   227  	require.Equal(t, 0, len(depositMsgsRemaining))
   228  
   229  	var depositMsgs []types.DepositMsgState
   230  	simapp.LiquidityKeeper.IterateAllDepositMsgStates(ctx, func(msg types.DepositMsgState) bool {
   231  		depositMsgs = append(depositMsgs, msg)
   232  		return false
   233  	})
   234  	require.Equal(t, 4, len(depositMsgs))
   235  
   236  	depositMsgs[0].ToBeDeleted = true
   237  	simapp.LiquidityKeeper.SetPoolBatchDepositMsgStates(ctx, poolID, []types.DepositMsgState{depositMsgs[0]})
   238  	depositMsgsNotToDelete := simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgStatesNotToBeDeleted(ctx, batch)
   239  	require.Equal(t, 3, len(depositMsgsNotToDelete))
   240  
   241  	var withdrawMsgs []types.WithdrawMsgState
   242  	simapp.LiquidityKeeper.IterateAllWithdrawMsgStates(ctx, func(msg types.WithdrawMsgState) bool {
   243  		withdrawMsgs = append(withdrawMsgs, msg)
   244  		return false
   245  	})
   246  	withdrawMsgs[0].ToBeDeleted = true
   247  	simapp.LiquidityKeeper.SetPoolBatchWithdrawMsgStates(ctx, poolID, withdrawMsgs[0:1])
   248  
   249  	withdrawMsgsNotToDelete := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStatesNotToBeDeleted(ctx, batch)
   250  	require.Equal(t, 4, len(withdrawMsgs))
   251  	require.Equal(t, 3, len(withdrawMsgsNotToDelete))
   252  	require.NotEqual(t, withdrawMsgsNotToDelete, withdrawMsgs)
   253  
   254  	app.TestDepositPool(t, simapp, ctx, A, B.QuoRaw(10), addrs[4:5], poolId2, false)
   255  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(1000), addrs[4:5], poolId2, false)
   256  
   257  	depositMsgs = simapp.LiquidityKeeper.GetAllDepositMsgStates(ctx)
   258  	require.Equal(t, 5, len(depositMsgs))
   259  	withdrawMsgs = simapp.LiquidityKeeper.GetAllWithdrawMsgStates(ctx)
   260  	require.Equal(t, 5, len(depositMsgs))
   261  
   262  	var depositMsgs2 []types.DepositMsgState
   263  	simapp.LiquidityKeeper.IterateAllDepositMsgStates(ctx, func(msg types.DepositMsgState) bool {
   264  		depositMsgs2 = append(depositMsgs2, msg)
   265  		return false
   266  	})
   267  
   268  	var withdrawMsgs2 []types.WithdrawMsgState
   269  	simapp.LiquidityKeeper.IterateAllWithdrawMsgStates(ctx, func(msg types.WithdrawMsgState) bool {
   270  		withdrawMsgs2 = append(withdrawMsgs2, msg)
   271  		return false
   272  	})
   273  
   274  	require.Equal(t, 5, len(depositMsgs2))
   275  
   276  	require.Equal(t, 5, len(withdrawMsgs2))
   277  
   278  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   279  
   280  	depositMsgsRemaining = simapp.LiquidityKeeper.GetAllRemainingPoolBatchDepositMsgStates(ctx, batch)
   281  	require.Equal(t, 0, len(depositMsgsRemaining))
   282  
   283  	// next block,
   284  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   285  	// Reinitialize batch messages that were not executed in the previous batch and delete batch messages that were executed or ready to delete.
   286  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   287  
   288  	var depositMsgs3 []types.DepositMsgState
   289  	simapp.LiquidityKeeper.IterateAllDepositMsgStates(ctx, func(msg types.DepositMsgState) bool {
   290  		depositMsgs3 = append(depositMsgs3, msg)
   291  		return false
   292  	})
   293  	require.Equal(t, 0, len(depositMsgs3))
   294  
   295  	var withdrawMsgs3 []types.WithdrawMsgState
   296  	simapp.LiquidityKeeper.IterateAllWithdrawMsgStates(ctx, func(msg types.WithdrawMsgState) bool {
   297  		withdrawMsgs3 = append(withdrawMsgs3, msg)
   298  		return false
   299  	})
   300  	require.Equal(t, 0, len(withdrawMsgs3))
   301  
   302  	app.TestSwapPool(t, simapp, ctx, xOfferCoins, xOrderPrices, xOrderAddrs, poolID, false)
   303  	app.TestSwapPool(t, simapp, ctx, xOfferCoins, xOrderPrices, xOrderAddrs, poolID, false)
   304  	app.TestSwapPool(t, simapp, ctx, xOfferCoins, xOrderPrices, xOrderAddrs, poolID, false)
   305  	app.TestSwapPool(t, simapp, ctx, yOfferCoins, yOrderPrices, yOrderAddrs, poolID, false)
   306  	app.TestSwapPool(t, simapp, ctx, offerCoins2, xOrderPrices, addrs[4:5], poolId2, false)
   307  
   308  	swapMsgsPool1 := simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStates(ctx, batch)
   309  	require.Equal(t, 4, len(swapMsgsPool1))
   310  
   311  	swapMsg, found := simapp.LiquidityKeeper.GetPoolBatchSwapMsgState(ctx, batch.PoolId, 1)
   312  	require.True(t, found)
   313  	require.Equal(t, swapMsg, swapMsgsPool1[0])
   314  
   315  	var swapMsgsAllPool []types.SwapMsgState
   316  	simapp.LiquidityKeeper.IterateAllSwapMsgStates(ctx, func(msg types.SwapMsgState) bool {
   317  		swapMsgsAllPool = append(swapMsgsAllPool, msg)
   318  		return false
   319  	})
   320  	require.Equal(t, 5, len(swapMsgsAllPool))
   321  
   322  	swapMsgsAllPool = simapp.LiquidityKeeper.GetAllSwapMsgStates(ctx)
   323  	require.Equal(t, 5, len(swapMsgsAllPool))
   324  	require.Equal(t, swapMsgsPool1, swapMsgsAllPool[:len(swapMsgsPool1)])
   325  
   326  	swapMsgsAllPool[1].Executed = true
   327  	simapp.LiquidityKeeper.SetPoolBatchSwapMsgStates(ctx, poolID, swapMsgsAllPool[1:2])
   328  
   329  	remainingSwapMsgs := simapp.LiquidityKeeper.GetAllRemainingPoolBatchSwapMsgStates(ctx, batch)
   330  	require.Equal(t, 1, len(remainingSwapMsgs))
   331  
   332  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   333  	// next block,
   334  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   335  	// Reinitialize batch messages that were not executed in the previous batch and delete batch messages that were executed or ready to delete.
   336  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   337  
   338  	var swapMsg2 []types.SwapMsgState
   339  	simapp.LiquidityKeeper.IterateAllSwapMsgStates(ctx, func(msg types.SwapMsgState) bool {
   340  		swapMsg2 = append(swapMsg2, msg)
   341  		return false
   342  	})
   343  	require.Equal(t, 0, len(swapMsg2))
   344  
   345  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   346  
   347  	genesis := simapp.LiquidityKeeper.ExportGenesis(ctx)
   348  	simapp.LiquidityKeeper.InitGenesis(ctx, *genesis)
   349  	genesisNew := simapp.LiquidityKeeper.ExportGenesis(ctx)
   350  	require.Equal(t, genesis, genesisNew)
   351  
   352  	simapp.LiquidityKeeper.DeletePoolBatch(ctx, batch)
   353  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   354  	require.Equal(t, types.PoolBatch{}, batch)
   355  	require.False(t, found)
   356  }