github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/order/match/periodicauction/match_test.go (about) 1 //go:build ignore 2 3 package periodicauction 4 5 import ( 6 "math/rand" 7 "strconv" 8 "testing" 9 10 "github.com/fibonacci-chain/fbc/x/dex" 11 orderkeeper "github.com/fibonacci-chain/fbc/x/order/keeper" 12 13 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 14 "github.com/stretchr/testify/require" 15 16 "github.com/fibonacci-chain/fbc/x/order/types" 17 ) 18 19 type BookItemTestData struct { 20 Price string 21 BuyQuantity string 22 SellQuantity string 23 } 24 25 type MatchTestData struct { 26 items []BookItemTestData 27 pricePrecision int64 28 refPrice string 29 output string 30 } 31 32 func runPeriodicAuctionMatchPriceTest(t *testing.T, testData *MatchTestData, check bool) { 33 book := types.DepthBook{} 34 for _, input := range testData.items { 35 price, err := sdk.NewDecFromStr(input.Price) 36 require.Nil(t, err) 37 buy, err := sdk.NewDecFromStr(input.BuyQuantity) 38 require.Nil(t, err) 39 sell, err := sdk.NewDecFromStr(input.SellQuantity) 40 require.Nil(t, err) 41 book.Items = append(book.Items, types.DepthBookItem{ 42 Price: price, 43 BuyQuantity: buy, 44 SellQuantity: sell, 45 }) 46 } 47 refPrice, err := sdk.NewDecFromStr(testData.refPrice) 48 require.Nil(t, err) 49 needres, err := sdk.NewDecFromStr(testData.output) 50 require.Nil(t, err) 51 bestPrice, _ := periodicAuctionMatchPrice(&book, testData.pricePrecision, refPrice) 52 if check { 53 if !needres.Equal(bestPrice) { 54 t.Fatalf("need:%s calc:%s\n", needres.String(), bestPrice.String()) 55 } 56 } 57 58 } 59 60 func TestPeriodicAuctionMatchPriceRandomData(t *testing.T) { 61 for i := 0; i < 10000; i++ { 62 n := rand.Int()%200 + 2 63 data := MatchTestData{ 64 pricePrecision: 1, 65 refPrice: "1", 66 output: "98", 67 } 68 for j := 0; j < n; j++ { 69 data.items = append(data.items, BookItemTestData{ 70 Price: strconv.Itoa(100 - j), 71 BuyQuantity: strconv.Itoa(rand.Intn(2) * rand.Intn(10)), 72 SellQuantity: strconv.Itoa(rand.Intn(2) * rand.Intn(10)), 73 }) 74 } 75 runPeriodicAuctionMatchPriceTest(t, &data, false) 76 } 77 } 78 79 func TestPeriodicAuctionMatchPrice(t *testing.T) { 80 data := MatchTestData{ 81 items: []BookItemTestData{{ 82 "100", "150", "0", 83 }, { 84 "99", "10", "0", 85 }, { 86 "98", "0", "250", 87 }, { 88 "97", "0", "50", 89 }, 90 }, 91 pricePrecision: 1, 92 refPrice: "1", 93 output: "98", 94 } 95 runPeriodicAuctionMatchPriceTest(t, &data, true) 96 } 97 98 func TestPeriodicAuctionMatchPriceRule0(t *testing.T) { 99 data := MatchTestData{ 100 items: []BookItemTestData{{ 101 "100", "0", "40", 102 }, { 103 "99", "0", "30", 104 }, { 105 "98", "80", "0", 106 }, { 107 "97", "70", "0", 108 }, 109 }, 110 pricePrecision: 1, 111 refPrice: "1", 112 output: "1", 113 } 114 runPeriodicAuctionMatchPriceTest(t, &data, true) 115 } 116 117 func TestPeriodicAuctionMatchPriceRule1(t *testing.T) { 118 data := MatchTestData{ 119 items: []BookItemTestData{{ 120 "100", "150", "0", 121 }, { 122 "98", "150", "250", 123 }, { 124 "97", "0", "50", 125 }, 126 }, 127 pricePrecision: 1, 128 refPrice: "1", 129 output: "98", 130 } 131 runPeriodicAuctionMatchPriceTest(t, &data, true) 132 } 133 134 func TestPeriodicAuctionMatchPriceRule2(t *testing.T) { 135 data := MatchTestData{ 136 items: []BookItemTestData{{ 137 "102", "30", "0", 138 }, { 139 "101", "10", "0", 140 }, { 141 "99", "50", "0", 142 }, { 143 "98", "0", "10", 144 }, { 145 "97", "0", "50", 146 }, { 147 "96", "15", "0", 148 }, { 149 "95", "0", "50", 150 }, 151 }, 152 pricePrecision: 1, 153 refPrice: "1", 154 output: "97", 155 } 156 runPeriodicAuctionMatchPriceTest(t, &data, true) 157 } 158 159 func TestPeriodicAuctionMatchPriceRule3A(t *testing.T) { 160 data := MatchTestData{ 161 items: []BookItemTestData{{ 162 "102", "60", "0", 163 }, { 164 "100", "0", "20", 165 }, { 166 "95", "0", "30", 167 }, 168 }, 169 pricePrecision: 1, 170 refPrice: "100", 171 output: "102", 172 } 173 runPeriodicAuctionMatchPriceTest(t, &data, true) 174 } 175 176 func TestPeriodicAuctionMatchPriceRule3B(t *testing.T) { 177 data := MatchTestData{ 178 items: []BookItemTestData{{ 179 "102", "30", "0", 180 }, { 181 "97", "20", "0", 182 }, { 183 "95", "0", "60", 184 }, 185 }, 186 pricePrecision: 1, 187 refPrice: "96", 188 output: "95", 189 } 190 runPeriodicAuctionMatchPriceTest(t, &data, true) 191 } 192 193 func TestPeriodicAuctionMatchPriceRule3C(t *testing.T) { 194 data := MatchTestData{ 195 items: []BookItemTestData{{ 196 "100", "25", "0", 197 }, { 198 "98", "0", "35", 199 }, { 200 "97", "35", "0", 201 }, { 202 "95", "0", "25", 203 }, 204 }, 205 pricePrecision: 1, 206 refPrice: "99", 207 output: "99", 208 } 209 runPeriodicAuctionMatchPriceTest(t, &data, true) 210 } 211 212 func TestPeriodicAuctionMatchPriceByEmptyDepthBook(t *testing.T) { 213 depthBook := &types.DepthBook{} 214 bestPrice, maxExecution := periodicAuctionMatchPrice(depthBook, 10, sdk.MustNewDecFromStr("10.0")) 215 216 require.EqualValues(t, sdk.ZeroDec(), bestPrice) 217 require.EqualValues(t, sdk.ZeroDec(), maxExecution) 218 } 219 220 func TestPreMatchProcessing(t *testing.T) { 221 testInput := orderkeeper.CreateTestInput(t) 222 223 // mock orders, DepthBook, and orderIDsMap 224 orders := []*types.Order{ 225 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 226 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 227 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 228 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 229 } 230 orders[0].Sender = testInput.TestAddrs[0] 231 orders[1].Sender = testInput.TestAddrs[0] 232 orders[2].Sender = testInput.TestAddrs[1] 233 orders[3].Sender = testInput.TestAddrs[1] 234 235 depthBook := &types.DepthBook{} 236 for i := 0; i < 4; i++ { 237 depthBook.InsertOrder(orders[i]) 238 } 239 240 buyAmountSum, sellAmountSum := preMatchProcessing(depthBook) 241 require.Equal(t, sdk.NewDec(3), buyAmountSum[1]) 242 require.Equal(t, sdk.NewDec(4), sellAmountSum[0]) 243 } 244 245 func TestExecRule0(t *testing.T) { 246 buyAmountSum := []sdk.Dec{sdk.NewDec(0.0), sdk.NewDec(3.0), sdk.NewDec(3.0)} 247 sellAmountSum := []sdk.Dec{sdk.NewDec(4.0), sdk.NewDec(3.0), sdk.NewDec(3.0)} 248 249 maxExecution, execution := execRule0(buyAmountSum, sellAmountSum) 250 require.EqualValues(t, sdk.NewDec(3), maxExecution) 251 require.EqualValues(t, sdk.NewDec(3), execution[1]) 252 } 253 254 func TestExecRule1(t *testing.T) { 255 maxExecution := sdk.NewDec(3.0) 256 execution := []sdk.Dec{sdk.NewDec(0.0), sdk.NewDec(3.0), sdk.NewDec(3.0)} 257 258 indexesRule1 := execRule1(maxExecution, execution) 259 require.EqualValues(t, []int{1, 2}, indexesRule1) 260 } 261 262 func TestExecRule2(t *testing.T) { 263 buyAmountSum := []sdk.Dec{sdk.NewDec(0.0), sdk.NewDec(3.0), sdk.NewDec(3.0)} 264 sellAmountSum := []sdk.Dec{sdk.NewDec(4.0), sdk.NewDec(3.0), sdk.NewDec(3.0)} 265 indexesRule1 := []int{1, 2} 266 267 indexesRule2, _ := execRule2(buyAmountSum, sellAmountSum, indexesRule1) 268 require.EqualValues(t, []int{1, 2}, indexesRule2) 269 } 270 271 func TestExecRule3(t *testing.T) { 272 testInput := orderkeeper.CreateTestInput(t) 273 keeper := testInput.OrderKeeper 274 ctx := testInput.Ctx 275 tokenPair := dex.GetBuiltInTokenPair() 276 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 277 require.Nil(t, err) 278 279 // mock orders, DepthBook, and orderIDsMap 280 orders := []*types.Order{ 281 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 282 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 283 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 284 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 285 } 286 orders[0].Sender = testInput.TestAddrs[0] 287 orders[1].Sender = testInput.TestAddrs[0] 288 orders[2].Sender = testInput.TestAddrs[1] 289 orders[3].Sender = testInput.TestAddrs[1] 290 depthBook := &types.DepthBook{} 291 292 for i := 0; i < 4; i++ { 293 err := keeper.PlaceOrder(ctx, orders[i]) 294 require.NoError(t, err) 295 depthBook.InsertOrder(orders[i]) 296 } 297 298 indexesRule1 := []int{1, 2} 299 refPrice := sdk.NewDec(10.0) 300 pricePrecision := tokenPair.MaxPriceDigit 301 indexesRule2 := []int{1, 2} 302 imbalance := []sdk.Dec{sdk.NewDec(0.0), sdk.NewDec(0.0)} 303 304 bestPrice := execRule3(depthBook, indexesRule1[0], refPrice, pricePrecision, indexesRule2, imbalance) 305 require.EqualValues(t, sdk.NewDec(10), bestPrice) 306 } 307 308 func TestBestPriceFromRefPrice(t *testing.T) { 309 minPrice, err := sdk.NewDecFromStr("10.1") 310 require.EqualValues(t, nil, err) 311 maxPrice, err := sdk.NewDecFromStr("9.9") 312 require.EqualValues(t, nil, err) 313 refPrice, err := sdk.NewDecFromStr("10.0") 314 require.EqualValues(t, nil, err) 315 316 bestPrice := bestPriceFromRefPrice(minPrice, maxPrice, refPrice) 317 require.EqualValues(t, sdk.NewDec(10), bestPrice) 318 } 319 320 func TestExpireOrdersInExpiredBlock(t *testing.T) { 321 testInput := orderkeeper.CreateTestInput(t) 322 keeper := testInput.OrderKeeper 323 ctx := testInput.Ctx 324 tokenPair := dex.GetBuiltInTokenPair() 325 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 326 require.Nil(t, err) 327 328 orders := []*types.Order{ 329 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 330 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 331 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 332 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 333 } 334 orders[0].Sender = testInput.TestAddrs[0] 335 orders[1].Sender = testInput.TestAddrs[0] 336 orders[2].Sender = testInput.TestAddrs[1] 337 orders[3].Sender = testInput.TestAddrs[1] 338 339 for i := 0; i < 4; i++ { 340 err := keeper.PlaceOrder(ctx, orders[i]) 341 require.EqualValues(t, nil, err) 342 } 343 344 keeper.DropExpiredOrdersByBlockHeight(ctx, ctx.BlockHeight()) 345 346 order := keeper.GetOrder(ctx, "ID0000000000-1") 347 require.NotEqual(t, nil, order) 348 require.EqualValues(t, int64(types.OrderStatusExpired), order.Status) 349 } 350 351 func TestMarkCurBlockToFeatureExpireBlockList(t *testing.T) { 352 testInput := orderkeeper.CreateTestInput(t) 353 keeper := testInput.OrderKeeper 354 ctx := testInput.Ctx 355 feeParams := types.DefaultTestParams() 356 357 markCurBlockToFutureExpireBlockList(ctx, keeper) 358 expiredBlocks := keeper.GetExpireBlockHeight(ctx, ctx.BlockHeight()+feeParams.OrderExpireBlocks) 359 require.EqualValues(t, 0, expiredBlocks[0]) 360 } 361 362 func TestCleanLastBlockClosedOrders(t *testing.T) { 363 testInput := orderkeeper.CreateTestInput(t) 364 keeper := testInput.OrderKeeper 365 ctx := testInput.Ctx 366 367 orders := []*types.Order{ 368 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 369 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 370 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 371 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 372 } 373 orders[0].Sender = testInput.TestAddrs[0] 374 orders[1].Sender = testInput.TestAddrs[0] 375 orders[2].Sender = testInput.TestAddrs[1] 376 orders[3].Sender = testInput.TestAddrs[1] 377 378 for i := 0; i < 4; i++ { 379 err := keeper.PlaceOrder(ctx, orders[i]) 380 require.EqualValues(t, nil, err) 381 } 382 383 keeper.SetLastClosedOrderIDs(ctx, []string{orders[0].OrderID}) 384 385 cleanLastBlockClosedOrders(ctx, keeper) 386 387 order := keeper.GetOrder(ctx, orders[0].OrderID) 388 require.EqualValues(t, (*types.Order)(nil), order) 389 } 390 391 func TestCacheExpiredBlockToCurrentHeight(t *testing.T) { 392 testInput := orderkeeper.CreateTestInput(t) 393 keeper := testInput.OrderKeeper 394 ctx := testInput.Ctx 395 396 orders := []*types.Order{ 397 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 398 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 399 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 400 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 401 } 402 orders[0].Sender = testInput.TestAddrs[0] 403 orders[1].Sender = testInput.TestAddrs[0] 404 orders[2].Sender = testInput.TestAddrs[1] 405 orders[3].Sender = testInput.TestAddrs[1] 406 407 for i := 0; i < 4; i++ { 408 err := keeper.PlaceOrder(ctx, orders[i]) 409 require.EqualValues(t, nil, err) 410 } 411 412 keeper.DropExpiredOrdersByBlockHeight(ctx, ctx.BlockHeight()) 413 keeper.SetExpireBlockHeight(ctx, ctx.BlockHeight(), []int64{ctx.BlockHeight()}) 414 415 cacheExpiredBlockToCurrentHeight(ctx, keeper) 416 417 num := keeper.GetCache().GetExpireNum() 418 require.EqualValues(t, len(orders), int(num)) 419 } 420 421 func TestCleanupExpiredOrders(t *testing.T) { 422 testInput := orderkeeper.CreateTestInput(t) 423 keeper := testInput.OrderKeeper 424 ctx := testInput.Ctx 425 feeParams := types.DefaultTestParams() 426 427 orders := []*types.Order{ 428 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 429 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 430 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 431 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 432 } 433 orders[0].Sender = testInput.TestAddrs[0] 434 orders[1].Sender = testInput.TestAddrs[0] 435 orders[2].Sender = testInput.TestAddrs[1] 436 orders[3].Sender = testInput.TestAddrs[1] 437 438 for i := 0; i < 4; i++ { 439 err := keeper.PlaceOrder(ctx, orders[i]) 440 require.EqualValues(t, nil, err) 441 } 442 443 keeper.SetLastClosedOrderIDs(ctx, []string{orders[0].OrderID}) 444 keeper.ExpireOrder(ctx, orders[1], ctx.Logger()) 445 446 cleanupExpiredOrders(ctx, keeper) 447 448 expiredBlocks := keeper.GetExpireBlockHeight(ctx, ctx.BlockHeight()+ 449 feeParams.OrderExpireBlocks) 450 require.EqualValues(t, true, expiredBlocks[0] == ctx.BlockHeight()) 451 452 lastClosedOrderIDs := keeper.GetLastClosedOrderIDs(ctx) 453 require.EqualValues(t, true, lastClosedOrderIDs[0] == orders[0].OrderID) 454 455 num := keeper.GetCache().GetExpireNum() 456 require.EqualValues(t, 1, int(num)) 457 } 458 459 func TestMatchOrders(t *testing.T) { 460 testInput := orderkeeper.CreateTestInput(t) 461 keeper := testInput.OrderKeeper 462 ctx := testInput.Ctx 463 tokenPair := dex.GetBuiltInTokenPair() 464 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 465 require.Nil(t, err) 466 467 // mock orders, DepthBook, and orderIDsMap 468 orders := []*types.Order{ 469 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 470 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 471 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 472 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 473 } 474 orders[0].Sender = testInput.TestAddrs[0] 475 orders[1].Sender = testInput.TestAddrs[0] 476 orders[2].Sender = testInput.TestAddrs[1] 477 orders[3].Sender = testInput.TestAddrs[1] 478 depthBook := &types.DepthBook{} 479 480 for i := 0; i < 4; i++ { 481 err := keeper.PlaceOrder(ctx, orders[i]) 482 require.EqualValues(t, nil, err) 483 depthBook.InsertOrder(orders[i]) 484 } 485 486 matchOrders(ctx, keeper) 487 488 depthBook = keeper.GetDepthBookCopy(types.TestTokenPair) 489 require.EqualValues(t, 1, len(depthBook.Items)) 490 require.EqualValues(t, sdk.MustNewDecFromStr("10.2"), depthBook.Items[0].Price) 491 require.EqualValues(t, sdk.ZeroDec(), depthBook.Items[0].BuyQuantity) 492 require.EqualValues(t, sdk.MustNewDecFromStr("1"), depthBook.Items[0].SellQuantity) 493 494 orders = []*types.Order{ 495 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 496 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 497 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 498 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 499 } 500 orders[0].Sender = testInput.TestAddrs[0] 501 orders[1].Sender = testInput.TestAddrs[0] 502 orders[2].Sender = testInput.TestAddrs[1] 503 orders[3].Sender = testInput.TestAddrs[1] 504 505 for i := 0; i < 4; i++ { 506 err := keeper.PlaceOrder(ctx, orders[i]) 507 require.EqualValues(t, nil, err) 508 depthBook.InsertOrder(orders[i]) 509 } 510 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 511 lockProduct(ctx, keeper, ctx.Logger(), types.TestTokenPair, updatedProductsBasePrice[types.TestTokenPair], 512 sdk.ZeroDec(), sdk.ZeroDec()) 513 514 matchOrders(ctx, keeper) 515 516 depthBook = keeper.GetDepthBookCopy(types.TestTokenPair) 517 require.EqualValues(t, 1, len(depthBook.Items)) 518 require.EqualValues(t, sdk.MustNewDecFromStr("10.2"), depthBook.Items[0].Price) 519 require.EqualValues(t, sdk.ZeroDec(), depthBook.Items[0].BuyQuantity) 520 require.EqualValues(t, sdk.MustNewDecFromStr("2"), depthBook.Items[0].SellQuantity) 521 } 522 523 func TestMatchOrdersByEmptyBlock(t *testing.T) { 524 testInput := orderkeeper.CreateTestInput(t) 525 keeper := testInput.OrderKeeper 526 ctx := testInput.Ctx 527 tokenPair := dex.GetBuiltInTokenPair() 528 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 529 require.Nil(t, err) 530 531 matchOrders(ctx, keeper) 532 require.EqualValues(t, int64(0), keeper.GetBlockOrderNum(ctx, ctx.BlockHeight())) 533 require.EqualValues(t, false, keeper.AnyProductLocked(ctx)) 534 } 535 536 func TestCalcMatchPriceAndExecution(t *testing.T) { 537 testInput := orderkeeper.CreateTestInput(t) 538 keeper := testInput.OrderKeeper 539 ctx := testInput.Ctx 540 tokenPair := dex.GetBuiltInTokenPair() 541 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 542 require.Nil(t, err) 543 544 // mock orders, DepthBook, and orderIDsMap 545 orders := []*types.Order{ 546 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 547 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 548 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 549 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 550 } 551 orders[0].Sender = testInput.TestAddrs[0] 552 orders[1].Sender = testInput.TestAddrs[0] 553 orders[2].Sender = testInput.TestAddrs[1] 554 orders[3].Sender = testInput.TestAddrs[1] 555 depthBook := &types.DepthBook{} 556 557 for i := 0; i < 4; i++ { 558 err := keeper.PlaceOrder(ctx, orders[i]) 559 require.EqualValues(t, nil, err) 560 depthBook.InsertOrder(orders[i]) 561 } 562 563 products := keeper.GetDiskCache().GetUpdatedDepthbookKeys() 564 keeper.GetDexKeeper().SortProducts(ctx, products) // sort products 565 566 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, products) 567 matchResult, ok := updatedProductsBasePrice[types.TestTokenPair] 568 require.EqualValues(t, ok, true) 569 require.EqualValues(t, matchResult.BlockHeight, ctx.BlockHeight()) 570 require.EqualValues(t, sdk.MustNewDecFromStr("10.0"), matchResult.Price) 571 require.EqualValues(t, sdk.MustNewDecFromStr("3.0"), matchResult.Quantity) 572 } 573 574 func TestLockProduct(t *testing.T) { 575 testInput := orderkeeper.CreateTestInput(t) 576 keeper := testInput.OrderKeeper 577 ctx := testInput.Ctx 578 tokenPair := dex.GetBuiltInTokenPair() 579 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 580 require.Nil(t, err) 581 582 // mock orders, DepthBook, and orderIDsMap 583 orders := []*types.Order{ 584 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 585 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 586 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 587 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 588 } 589 orders[0].Sender = testInput.TestAddrs[0] 590 orders[1].Sender = testInput.TestAddrs[0] 591 orders[2].Sender = testInput.TestAddrs[1] 592 orders[3].Sender = testInput.TestAddrs[1] 593 depthBook := &types.DepthBook{} 594 595 for i := 0; i < 4; i++ { 596 err := keeper.PlaceOrder(ctx, orders[i]) 597 require.EqualValues(t, nil, err) 598 depthBook.InsertOrder(orders[i]) 599 } 600 601 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 602 603 lockProduct(ctx, keeper, ctx.Logger(), types.TestTokenPair, updatedProductsBasePrice[types.TestTokenPair], 604 sdk.ZeroDec(), sdk.ZeroDec()) 605 606 require.EqualValues(t, true, keeper.IsProductLocked(ctx, types.TestTokenPair)) 607 } 608 609 func TestExecuteMatchedUpdatedProduct(t *testing.T) { 610 testInput := orderkeeper.CreateTestInput(t) 611 keeper := testInput.OrderKeeper 612 ctx := testInput.Ctx 613 feeParams := types.DefaultTestParams() 614 tokenPair := dex.GetBuiltInTokenPair() 615 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 616 require.Nil(t, err) 617 618 // mock orders, DepthBook, and orderIDsMap 619 orders := []*types.Order{ 620 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 621 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 622 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 623 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 624 } 625 orders[0].Sender = testInput.TestAddrs[0] 626 orders[1].Sender = testInput.TestAddrs[0] 627 orders[2].Sender = testInput.TestAddrs[1] 628 orders[3].Sender = testInput.TestAddrs[1] 629 depthBook := &types.DepthBook{} 630 631 for i := 0; i < 4; i++ { 632 err := keeper.PlaceOrder(ctx, orders[i]) 633 require.EqualValues(t, nil, err) 634 depthBook.InsertOrder(orders[i]) 635 } 636 637 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 638 639 blockRemainDeals := executeMatchedUpdatedProduct(ctx, keeper, updatedProductsBasePrice, &feeParams, 640 1000, types.TestTokenPair, ctx.Logger()) 641 642 require.EqualValues(t, 997, int(blockRemainDeals)) 643 } 644 645 func TestExecuteMatchedUpdatedProductByLimitedBlockDeals(t *testing.T) { 646 testInput := orderkeeper.CreateTestInput(t) 647 keeper := testInput.OrderKeeper 648 ctx := testInput.Ctx 649 feeParams := types.DefaultTestParams() 650 tokenPair := dex.GetBuiltInTokenPair() 651 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 652 require.Nil(t, err) 653 654 // mock orders, DepthBook, and orderIDsMap 655 orders := []*types.Order{ 656 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 657 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 658 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 659 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 660 } 661 orders[0].Sender = testInput.TestAddrs[0] 662 orders[1].Sender = testInput.TestAddrs[0] 663 orders[2].Sender = testInput.TestAddrs[1] 664 orders[3].Sender = testInput.TestAddrs[1] 665 depthBook := &types.DepthBook{} 666 667 for i := 0; i < 4; i++ { 668 err := keeper.PlaceOrder(ctx, orders[i]) 669 require.EqualValues(t, nil, err) 670 depthBook.InsertOrder(orders[i]) 671 } 672 673 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 674 675 blockRemainDeals := executeMatchedUpdatedProduct(ctx, keeper, updatedProductsBasePrice, &feeParams, 676 0, types.TestTokenPair, ctx.Logger()) 677 678 require.EqualValues(t, 0, int(blockRemainDeals)) 679 require.EqualValues(t, true, keeper.IsProductLocked(ctx, types.TestTokenPair)) 680 } 681 682 func TestExecuteLockedProduct(t *testing.T) { 683 testInput := orderkeeper.CreateTestInput(t) 684 keeper := testInput.OrderKeeper 685 ctx := testInput.Ctx 686 feeParams := types.DefaultTestParams() 687 tokenPair := dex.GetBuiltInTokenPair() 688 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 689 require.Nil(t, err) 690 691 // mock orders, DepthBook, and orderIDsMap 692 orders := []*types.Order{ 693 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 694 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 695 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 696 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 697 } 698 orders[0].Sender = testInput.TestAddrs[0] 699 orders[1].Sender = testInput.TestAddrs[0] 700 orders[2].Sender = testInput.TestAddrs[1] 701 orders[3].Sender = testInput.TestAddrs[1] 702 depthBook := &types.DepthBook{} 703 704 for i := 0; i < 4; i++ { 705 err := keeper.PlaceOrder(ctx, orders[i]) 706 require.EqualValues(t, nil, err) 707 depthBook.InsertOrder(orders[i]) 708 } 709 710 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 711 lockProduct(ctx, keeper, ctx.Logger(), types.TestTokenPair, updatedProductsBasePrice[types.TestTokenPair], 712 sdk.ZeroDec(), sdk.ZeroDec()) 713 714 lockMap := keeper.GetDexKeeper().GetLockedProductsCopy(ctx) 715 716 blockRemainDeals := executeLockedProduct(ctx, keeper, updatedProductsBasePrice, lockMap, &feeParams, 717 1000, types.TestTokenPair, ctx.Logger()) 718 719 require.EqualValues(t, 997, int(blockRemainDeals)) 720 } 721 722 func TestExecuteLockedProductByLimitedBlockDeals(t *testing.T) { 723 testInput := orderkeeper.CreateTestInput(t) 724 keeper := testInput.OrderKeeper 725 ctx := testInput.Ctx 726 feeParams := types.DefaultTestParams() 727 tokenPair := dex.GetBuiltInTokenPair() 728 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 729 require.Nil(t, err) 730 731 // mock orders, DepthBook, and orderIDsMap 732 orders := []*types.Order{ 733 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 734 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 735 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 736 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 737 } 738 orders[0].Sender = testInput.TestAddrs[0] 739 orders[1].Sender = testInput.TestAddrs[0] 740 orders[2].Sender = testInput.TestAddrs[1] 741 orders[3].Sender = testInput.TestAddrs[1] 742 depthBook := &types.DepthBook{} 743 744 for i := 0; i < 4; i++ { 745 err := keeper.PlaceOrder(ctx, orders[i]) 746 require.EqualValues(t, nil, err) 747 depthBook.InsertOrder(orders[i]) 748 } 749 750 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 751 lockProduct(ctx, keeper, ctx.Logger(), types.TestTokenPair, updatedProductsBasePrice[types.TestTokenPair], 752 sdk.ZeroDec(), sdk.ZeroDec()) 753 754 lockMap := keeper.GetDexKeeper().GetLockedProductsCopy(ctx) 755 756 blockRemainDeals := executeLockedProduct(ctx, keeper, updatedProductsBasePrice, lockMap, &feeParams, 757 0, types.TestTokenPair, ctx.Logger()) 758 759 require.EqualValues(t, 0, int(blockRemainDeals)) 760 } 761 762 func TestExecuteLockedProductByLargeLockQuantity(t *testing.T) { 763 testInput := orderkeeper.CreateTestInput(t) 764 keeper := testInput.OrderKeeper 765 ctx := testInput.Ctx 766 feeParams := types.DefaultTestParams() 767 tokenPair := dex.GetBuiltInTokenPair() 768 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 769 require.Nil(t, err) 770 771 // mock orders, DepthBook, and orderIDsMap 772 orders := []*types.Order{ 773 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 774 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 775 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 776 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 777 } 778 orders[0].Sender = testInput.TestAddrs[0] 779 orders[1].Sender = testInput.TestAddrs[0] 780 orders[2].Sender = testInput.TestAddrs[1] 781 orders[3].Sender = testInput.TestAddrs[1] 782 depthBook := &types.DepthBook{} 783 784 for i := 0; i < 4; i++ { 785 err := keeper.PlaceOrder(ctx, orders[i]) 786 require.EqualValues(t, nil, err) 787 depthBook.InsertOrder(orders[i]) 788 } 789 790 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, []string{types.TestTokenPair}) 791 lockProduct(ctx, keeper, ctx.Logger(), types.TestTokenPair, updatedProductsBasePrice[types.TestTokenPair], 792 sdk.ZeroDec(), sdk.ZeroDec()) 793 794 lockMap := keeper.GetDexKeeper().GetLockedProductsCopy(ctx) 795 lock := lockMap.Data[types.TestTokenPair] 796 lock.Quantity = lock.Quantity.Add(sdk.NewDec(100)) 797 798 blockRemainDeals := executeLockedProduct(ctx, keeper, updatedProductsBasePrice, lockMap, &feeParams, 799 1000, types.TestTokenPair, ctx.Logger()) 800 801 require.EqualValues(t, 997, int(blockRemainDeals)) 802 } 803 804 func TestExecuteMatch(t *testing.T) { 805 testInput := orderkeeper.CreateTestInput(t) 806 keeper := testInput.OrderKeeper 807 ctx := testInput.Ctx 808 tokenPair := dex.GetBuiltInTokenPair() 809 err := testInput.DexKeeper.SaveTokenPair(ctx, tokenPair) 810 require.Nil(t, err) 811 812 // mock orders, DepthBook, and orderIDsMap 813 orders := []*types.Order{ 814 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 815 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 816 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 817 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 818 } 819 orders[0].Sender = testInput.TestAddrs[0] 820 orders[1].Sender = testInput.TestAddrs[0] 821 orders[2].Sender = testInput.TestAddrs[1] 822 orders[3].Sender = testInput.TestAddrs[1] 823 depthBook := &types.DepthBook{} 824 825 for i := 0; i < 4; i++ { 826 err := keeper.PlaceOrder(ctx, orders[i]) 827 require.EqualValues(t, nil, err) 828 depthBook.InsertOrder(orders[i]) 829 } 830 831 products := keeper.GetDiskCache().GetUpdatedDepthbookKeys() 832 keeper.GetDexKeeper().SortProducts(ctx, products) // sort products 833 updatedProductsBasePrice := calcMatchPriceAndExecution(ctx, keeper, products) 834 lockMap := keeper.GetDexKeeper().GetLockedProductsCopy(ctx) 835 for product := range lockMap.Data { 836 products = append(products, product) 837 } 838 keeper.GetDexKeeper().SortProducts(ctx, products) // sort products 839 840 executeMatch(ctx, keeper, products, updatedProductsBasePrice, lockMap) 841 842 depthBook = keeper.GetDepthBookCopy(types.TestTokenPair) 843 require.EqualValues(t, 1, len(depthBook.Items)) 844 require.EqualValues(t, sdk.MustNewDecFromStr("10.2"), depthBook.Items[0].Price) 845 require.EqualValues(t, sdk.ZeroDec(), depthBook.Items[0].BuyQuantity) 846 require.EqualValues(t, sdk.MustNewDecFromStr("1"), depthBook.Items[0].SellQuantity) 847 } 848 849 func TestCleanupOrdersWhoseTokenPairHaveBeenDelisted(t *testing.T) { 850 testInput := orderkeeper.CreateTestInput(t) 851 keeper := testInput.OrderKeeper 852 ctx := testInput.Ctx 853 854 // mock orders, DepthBook, and orderIDsMap 855 orders := []*types.Order{ 856 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "1.0"), 857 mockOrder("", types.TestTokenPair, types.BuyOrder, "10.1", "2.0"), 858 mockOrder("", types.TestTokenPair, types.SellOrder, "9.9", "3.0"), 859 mockOrder("", types.TestTokenPair, types.SellOrder, "10.2", "1.0"), 860 } 861 orders[0].Sender = testInput.TestAddrs[0] 862 orders[1].Sender = testInput.TestAddrs[0] 863 orders[2].Sender = testInput.TestAddrs[1] 864 orders[3].Sender = testInput.TestAddrs[1] 865 depthBook := &types.DepthBook{} 866 867 for i := 0; i < 4; i++ { 868 err := keeper.PlaceOrder(ctx, orders[i]) 869 require.EqualValues(t, nil, err) 870 depthBook.InsertOrder(orders[i]) 871 } 872 873 cleanupOrdersWhoseTokenPairHaveBeenDelisted(ctx, keeper) 874 875 depthBook = keeper.GetDepthBookCopy(types.TestTokenPair) 876 require.EqualValues(t, 0, len(depthBook.Items)) 877 878 }