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 }