code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/trades_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package sqlstore_test 17 18 import ( 19 "context" 20 "encoding/hex" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/datanode/entities" 25 "code.vegaprotocol.io/vega/datanode/sqlstore" 26 "code.vegaprotocol.io/vega/libs/num" 27 types "code.vegaprotocol.io/vega/protos/vega" 28 29 "github.com/shopspring/decimal" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 ) 33 34 const ( 35 testMarket = "b4376d805a888548baabfae74ef6f4fa4680dc9718bab355fa7191715de4fafe" 36 testPartyA = "8cc0e020c0bc2f9eba77749d81ecec8283283b85941722c2cb88318aaf8b8cd8" 37 testPartyB = "521127F24B1FA40311BA2FB3F6977310346346604B275DB7B767B04240A5A5C3" 38 orderAId = "787B72CB5DD7A5EA869E49F361CF957DF747F849B4ACE88ABC6DA0F9C450AFDD" 39 orderBId = "83dc82be23c77daec384a239143f07f83c667acf60d734745b023c6567e7b57b" 40 41 tradeID1 = "0bd678723c33b059638953e0904d2ddbd78c2be72ab25a8753a622911c2d9c78" 42 tradeID2 = "af2bb48edd738353fcd7a2b6cea4821dd2382ec95497954535278dfbfff7b5b5" 43 tradeID3 = "3d4ed10064b7cedbc8a37316f7329f853c9588b6a55006ffb8bec3f1a4ccc88e" 44 tradeID4 = "8cc0e020c0bc2f9eba77749d81ecec8283283b85941722c2cb88318aaf8b8cd8" 45 tradeID5 = "8b6be1a03cc4d529f682887a78b66e6879d17f81e2b37356ca0acbc5d5886eb8" 46 tradeID6 = "8cc0e020c0bc2f9eba77749d81ecec8283283b85941722c2cb88318aaf8b8cd8" 47 ) 48 49 func TestStorageGetByTxHash(t *testing.T) { 50 ctx := tempTransaction(t) 51 52 tradeStore := sqlstore.NewTrades(connectionSource) 53 54 insertedTrades := insertTestData(t, ctx, tradeStore) 55 56 trades, err := tradeStore.GetByTxHash(ctx, insertedTrades[0].TxHash) 57 assert.Nil(t, err) 58 assert.Equal(t, 1, len(trades)) 59 assert.Equal(t, insertedTrades[0].ID.String(), trades[0].ID.String()) 60 assert.Equal(t, insertedTrades[0].TxHash, trades[0].TxHash) 61 62 trades, err = tradeStore.GetByTxHash(ctx, insertedTrades[2].TxHash) 63 assert.Nil(t, err) 64 assert.Equal(t, 1, len(trades)) 65 assert.Equal(t, insertedTrades[2].ID.String(), trades[0].ID.String()) 66 assert.Equal(t, insertedTrades[2].TxHash, trades[0].TxHash) 67 } 68 69 func insertTestData(t *testing.T, ctx context.Context, tradeStore *sqlstore.Trades) []entities.Trade { 70 t.Helper() 71 72 // Insert some trades 73 bs := sqlstore.NewBlocks(connectionSource) 74 now := time.Now() 75 block1 := addTestBlockForTime(t, ctx, bs, now) 76 block2 := addTestBlockForTime(t, ctx, bs, now.Add(time.Second)) 77 78 trade1 := &types.Trade{ 79 Type: types.Trade_TYPE_DEFAULT, 80 Id: tradeID1, 81 Price: "100", 82 Size: 100, 83 MarketId: testMarket, 84 Buyer: testPartyB, 85 Seller: testPartyA, 86 Aggressor: types.Side_SIDE_SELL, 87 Timestamp: 1, 88 BuyOrder: orderBId, 89 SellOrder: orderAId, 90 } 91 92 trade2 := &types.Trade{ 93 Type: types.Trade_TYPE_DEFAULT, 94 Id: tradeID2, 95 Price: "100", 96 Size: 100, 97 MarketId: testMarket, 98 Buyer: testPartyB, 99 Seller: testPartyA, 100 Aggressor: types.Side_SIDE_SELL, 101 Timestamp: 1, 102 BuyOrder: orderBId, 103 SellOrder: orderAId, 104 } 105 106 trade3 := &types.Trade{ 107 Type: types.Trade_TYPE_DEFAULT, 108 Id: tradeID3, 109 Price: "100", 110 Size: 100, 111 MarketId: testMarket, 112 Buyer: testPartyB, 113 Seller: testPartyA, 114 Aggressor: types.Side_SIDE_SELL, 115 Timestamp: 1, 116 BuyOrder: orderBId, 117 SellOrder: orderAId, 118 } 119 120 trade4 := &types.Trade{ 121 Type: types.Trade_TYPE_DEFAULT, 122 Id: tradeID4, 123 Price: "100", 124 Size: 100, 125 MarketId: testMarket, 126 Buyer: testPartyB, 127 Seller: testPartyA, 128 Aggressor: types.Side_SIDE_SELL, 129 Timestamp: 1, 130 BuyOrder: orderBId, 131 SellOrder: orderAId, 132 } 133 134 trade5 := &types.Trade{ 135 Type: types.Trade_TYPE_DEFAULT, 136 Id: tradeID5, 137 Price: "100", 138 Size: 100, 139 MarketId: testMarket, 140 Buyer: testPartyB, 141 Seller: testPartyA, 142 Aggressor: types.Side_SIDE_SELL, 143 Timestamp: 1, 144 BuyOrder: orderBId, 145 SellOrder: orderAId, 146 } 147 148 trade6 := &types.Trade{ 149 Type: types.Trade_TYPE_DEFAULT, 150 Id: tradeID6, 151 Price: "100", 152 Size: 100, 153 MarketId: testMarket, 154 Buyer: testPartyB, 155 Seller: testPartyA, 156 Aggressor: types.Side_SIDE_SELL, 157 Timestamp: 1, 158 BuyOrder: orderBId, 159 SellOrder: orderAId, 160 } 161 162 protos := []types.Trade{*trade1, *trade2, *trade3, *trade4, *trade5, *trade6} 163 164 inserted := []entities.Trade{} 165 var seqNum uint64 166 vegaTime := block1.VegaTime 167 for _, proto := range protos { 168 if seqNum == 3 { 169 seqNum = 0 170 vegaTime = block2.VegaTime 171 } 172 trade, err := entities.TradeFromProto(&proto, generateTxHash(), vegaTime, seqNum) 173 if err != nil { 174 t.Fatalf("failed to get trade from proto:%s", err) 175 } 176 err = tradeStore.Add(trade) 177 if err != nil { 178 t.Fatalf("failed to add trade:%s", err) 179 } 180 seqNum++ 181 182 inserted = append(inserted, *trade) 183 } 184 185 tradeStore.Flush(ctx) 186 return inserted 187 } 188 189 func TestTrades_CursorPagination(t *testing.T) { 190 t.Run("Should return all trades for a given market when no cursor is given", testTradesCursorPaginationByMarketNoCursor) 191 t.Run("Should return all trades for a given party when no market and no cursor is given", testTradesCursorPaginationByPartyNoMarketNoCursor) 192 t.Run("Should return all trades for a given party and market when market ID and no cursor is given", testTradesCursorPaginationByPartyAndMarketNoCursor) 193 t.Run("Should return the first page of trades for a given market when a first cursor is set", testTradesCursorPaginationByMarketWithCursorFirst) 194 t.Run("Should return the first page of trades for a given party when a first cursor is set but not market", testTradesCursorPaginationByPartyWithCursorNoMarketFirst) 195 t.Run("Should return the first page of trades for a given party and market when a first cursor is set", testTradesCursorPaginationByPartyAndMarketWithCursorFirst) 196 t.Run("Should return the last page of trades for a given market when a last cursor is set", testTradesCursorPaginationByMarketWithCursorLast) 197 t.Run("Should return the last page of trades for a given party when a last cursor is set but not market", testTradesCursorPaginationByPartyWithCursorNoMarketLast) 198 t.Run("Should return the last page of trades for a given party and market when a last cursor is set", testTradesCursorPaginationByPartyAndMarketWithCursorLast) 199 t.Run("Should return the page of trades for a given market when a first and after cursor is set", testTradesCursorPaginationByMarketWithCursorForward) 200 t.Run("Should return the page of trades for a given party when a first and after cursor is set but not market", testTradesCursorPaginationByPartyWithCursorNoMarketForward) 201 t.Run("Should return the page of trades for a given party and market when a first and after cursor is set", testTradesCursorPaginationByPartyAndMarketWithCursorForward) 202 t.Run("Should return the page of trades for a given market when a last and before cursor is set", testTradesCursorPaginationByMarketWithCursorBackward) 203 t.Run("Should return the page of trades for a given party when a last and before cursor is set but not market", testTradesCursorPaginationByPartyWithCursorNoMarketBackward) 204 t.Run("Should return the page of trades for a given party and market when a last and before cursor is set", testTradesCursorPaginationByPartyAndMarketWithCursorBackward) 205 206 t.Run("Should return all trades for a given market when no cursor is given - newest first", testTradesCursorPaginationByMarketNoCursorNewestFirst) 207 t.Run("Should return all trades for a given party when no market and no cursor is given - newest first", testTradesCursorPaginationByPartyNoMarketNoCursorNewestFirst) 208 t.Run("Should return all trades for a given party and market when market ID and no cursor is given - newest first", testTradesCursorPaginationByPartyAndMarketNoCursorNewestFirst) 209 t.Run("Should return the first page of trades for a given market when a first cursor is set - newest first", testTradesCursorPaginationByMarketWithCursorFirstNewestFirst) 210 t.Run("Should return the first page of trades for a given party when a first cursor is set but not market - newest first", testTradesCursorPaginationByPartyWithCursorNoMarketFirstNewestFirst) 211 t.Run("Should return the first page of trades for a given party and market when a first cursor is set - newest first", testTradesCursorPaginationByPartyAndMarketWithCursorFirstNewestFirst) 212 t.Run("Should return the last page of trades for a given market when a last cursor is set - newest first", testTradesCursorPaginationByMarketWithCursorLastNewestFirst) 213 t.Run("Should return the last page of trades for a given party when a last cursor is set but not market - newest first", testTradesCursorPaginationByPartyWithCursorNoMarketLastNewestFirst) 214 t.Run("Should return the last page of trades for a given party and market when a last cursor is set - newest first", testTradesCursorPaginationByPartyAndMarketWithCursorLastNewestFirst) 215 t.Run("Should return the page of trades for a given market when a first and after cursor is set - newest first", testTradesCursorPaginationByMarketWithCursorForwardNewestFirst) 216 t.Run("Should return the page of trades for a given party when a first and after cursor is set but not market - newest first", testTradesCursorPaginationByPartyWithCursorNoMarketForwardNewestFirst) 217 t.Run("Should return the page of trades for a given party and market when a first and after cursor is set - newest first", testTradesCursorPaginationByPartyAndMarketWithCursorForwardNewestFirst) 218 t.Run("Should return the page of trades for a given market when a last and before cursor is set - newest first", testTradesCursorPaginationByMarketWithCursorBackwardNewestFirst) 219 t.Run("Should return the page of trades for a given party when a last and before cursor is set but not market - newest first", testTradesCursorPaginationByPartyWithCursorNoMarketBackwardNewestFirst) 220 t.Run("Should return the page of trades for a given party and market when a last and before cursor is set - newest first", testTradesCursorPaginationByPartyAndMarketWithCursorBackwardNewestFirst) 221 222 t.Run("Should return all trades between dates for a given market when no cursor is given", testTradesCursorPaginationBetweenDatesByMarketNoCursor) 223 t.Run("Should return all trades between dates for a given market when no cursor is given - newest first", testTradesCursorPaginationBetweenDatesByMarketNoCursorNewestFirst) 224 t.Run("Should return the last page of trades between dates for a given market when a last cursor is set", testTradesCursorPaginationBetweenDatesByMarketWithCursorLast) 225 t.Run("Should return the page of trades between dates for a given market when a first and after cursor is set", testTradesCursorPaginationBetweenDatesByMarketWithCursorForward) 226 } 227 228 func TestTransferFeeDiscount(t *testing.T) { 229 t.Run("get current transfer fee discount", tesGetCurrentTransferFeeDiscount) 230 } 231 232 func setupTradesTest(t *testing.T) (*sqlstore.Blocks, *sqlstore.Trades) { 233 t.Helper() 234 bs := sqlstore.NewBlocks(connectionSource) 235 ts := sqlstore.NewTrades(connectionSource) 236 return bs, ts 237 } 238 239 func populateTestTrades(ctx context.Context, t *testing.T, bs *sqlstore.Blocks, ts *sqlstore.Trades, blockTimes map[string]time.Time) { 240 t.Helper() 241 242 trades := []entities.Trade{ 243 { 244 SeqNum: 1, 245 ID: entities.TradeID("02a16077"), 246 MarketID: entities.MarketID("deadbeef"), 247 Price: decimal.NewFromFloat(1.0), 248 Size: 1, 249 Buyer: entities.PartyID("dabbad00"), 250 Seller: entities.PartyID("facefeed"), 251 BuyOrder: entities.OrderID("02a16077"), 252 SellOrder: entities.OrderID("fb1528a5"), 253 Type: entities.TradeTypeDefault, 254 }, 255 { 256 SeqNum: 2, 257 ID: entities.TradeID("44eea1bc"), 258 MarketID: entities.MarketID("deadbeef"), 259 Price: decimal.NewFromFloat(2.0), 260 Size: 2, 261 Buyer: entities.PartyID("dabbad00"), 262 Seller: entities.PartyID("facefeed"), 263 BuyOrder: entities.OrderID("44eea1bc"), 264 SellOrder: entities.OrderID("da8d1803"), 265 Type: entities.TradeTypeDefault, 266 }, 267 { 268 SeqNum: 3, 269 ID: entities.TradeID("65be62cd"), 270 MarketID: entities.MarketID("deadbeef"), 271 Price: decimal.NewFromFloat(3.0), 272 Size: 3, 273 Buyer: entities.PartyID("dabbad00"), 274 Seller: entities.PartyID("facefeed"), 275 BuyOrder: entities.OrderID("65be62cd"), 276 SellOrder: entities.OrderID("c8744329"), 277 Type: entities.TradeTypeDefault, 278 }, 279 { 280 SeqNum: 4, 281 ID: entities.TradeID("7a797e0e"), 282 MarketID: entities.MarketID("deadbeef"), 283 Price: decimal.NewFromFloat(4.0), 284 Size: 4, 285 Buyer: entities.PartyID("dabbad00"), 286 Seller: entities.PartyID("facefeed"), 287 BuyOrder: entities.OrderID("7a797e0e"), 288 SellOrder: entities.OrderID("c612300d"), 289 Type: entities.TradeTypeDefault, 290 }, 291 { 292 SeqNum: 5, 293 ID: entities.TradeID("7bb2356e"), 294 MarketID: entities.MarketID("cafed00d"), 295 Price: decimal.NewFromFloat(5.0), 296 Size: 5, 297 Buyer: entities.PartyID("dabbad00"), 298 Seller: entities.PartyID("facefeed"), 299 BuyOrder: entities.OrderID("7bb2356e"), 300 SellOrder: entities.OrderID("b7c84b8e"), 301 Type: entities.TradeTypeDefault, 302 }, 303 { 304 SeqNum: 6, 305 ID: entities.TradeID("b7c84b8e"), 306 MarketID: entities.MarketID("cafed00d"), 307 Price: decimal.NewFromFloat(6.0), 308 Size: 6, 309 Buyer: entities.PartyID("d0d0caca"), 310 Seller: entities.PartyID("decafbad"), 311 BuyOrder: entities.OrderID("b7c84b8e"), 312 SellOrder: entities.OrderID("7bb2356e"), 313 Type: entities.TradeTypeDefault, 314 }, 315 { 316 SeqNum: 7, 317 ID: entities.TradeID("c612300d"), 318 MarketID: entities.MarketID("cafed00d"), 319 Price: decimal.NewFromFloat(7.0), 320 Size: 7, 321 Buyer: entities.PartyID("d0d0caca"), 322 Seller: entities.PartyID("decafbad"), 323 BuyOrder: entities.OrderID("c612300d"), 324 SellOrder: entities.OrderID("7a797e0e"), 325 Type: entities.TradeTypeDefault, 326 }, 327 { 328 SeqNum: 8, 329 ID: entities.TradeID("c8744329"), 330 MarketID: entities.MarketID("cafed00d"), 331 Price: decimal.NewFromFloat(8.0), 332 Size: 8, 333 Buyer: entities.PartyID("d0d0caca"), 334 Seller: entities.PartyID("decafbad"), 335 BuyOrder: entities.OrderID("c8744329"), 336 SellOrder: entities.OrderID("65be62cd"), 337 Type: entities.TradeTypeDefault, 338 }, 339 { 340 SeqNum: 9, 341 ID: entities.TradeID("da8d1803"), 342 MarketID: entities.MarketID("deadbaad"), 343 Price: decimal.NewFromFloat(9.0), 344 Size: 9, 345 Buyer: entities.PartyID("baadf00d"), 346 Seller: entities.PartyID("0d15ea5e"), 347 BuyOrder: entities.OrderID("da8d1803"), 348 SellOrder: entities.OrderID("44eea1bc"), 349 Type: entities.TradeTypeDefault, 350 }, 351 { 352 SeqNum: 10, 353 ID: entities.TradeID("fb1528a5"), 354 MarketID: entities.MarketID("deadbaad"), 355 Price: decimal.NewFromFloat(10.0), 356 Size: 10, 357 Buyer: entities.PartyID("baadf00d"), 358 Seller: entities.PartyID("0d15ea5e"), 359 BuyOrder: entities.OrderID("fb1528a5"), 360 SellOrder: entities.OrderID("02a16077"), 361 Type: entities.TradeTypeDefault, 362 }, 363 } 364 source := &testBlockSource{bs, time.Now()} 365 for _, td := range trades { 366 trade := td 367 block := source.getNextBlock(t, ctx) 368 trade.SyntheticTime = block.VegaTime 369 trade.VegaTime = block.VegaTime 370 blockTimes[trade.ID.String()] = block.VegaTime 371 err := ts.Add(&trade) 372 require.NoError(t, err) 373 } 374 375 _, err := ts.Flush(ctx) 376 require.NoError(t, err) 377 } 378 379 func testTradesCursorPaginationByMarketNoCursor(t *testing.T) { 380 ctx := tempTransaction(t) 381 382 bs, ts := setupTradesTest(t) 383 blockTimes := make(map[string]time.Time) 384 populateTestTrades(ctx, t, bs, ts, blockTimes) 385 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 386 require.NoError(t, err) 387 388 marketID := []entities.MarketID{"deadbeef"} 389 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 390 require.NoError(t, err) 391 392 assert.Len(t, got, 4) 393 assert.Equal(t, "02a16077", got[0].ID.String()) 394 assert.Equal(t, uint64(1), got[0].Size) 395 assert.Equal(t, "7a797e0e", got[3].ID.String()) 396 assert.Equal(t, uint64(4), got[3].Size) 397 assert.False(t, pageInfo.HasNextPage) 398 assert.False(t, pageInfo.HasPreviousPage) 399 assert.Equal(t, "02a16077", got[0].ID.String()) 400 assert.Equal(t, "7a797e0e", got[3].ID.String()) 401 } 402 403 func testTradesCursorPaginationByPartyNoMarketNoCursor(t *testing.T) { 404 ctx := tempTransaction(t) 405 406 bs, ts := setupTradesTest(t) 407 blockTimes := make(map[string]time.Time) 408 populateTestTrades(ctx, t, bs, ts, blockTimes) 409 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 410 require.NoError(t, err) 411 412 partyID := []entities.PartyID{"dabbad00"} 413 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 414 require.NoError(t, err) 415 assert.Len(t, got, 5) 416 417 assert.Equal(t, "02a16077", got[0].ID.String()) 418 assert.Equal(t, uint64(1), got[0].Size) 419 assert.Equal(t, "7bb2356e", got[4].ID.String()) 420 assert.Equal(t, uint64(5), got[4].Size) 421 422 assert.False(t, pageInfo.HasNextPage) 423 assert.False(t, pageInfo.HasPreviousPage) 424 assert.Equal(t, "02a16077", got[0].ID.String()) 425 assert.Equal(t, "7bb2356e", got[4].ID.String()) 426 } 427 428 func testTradesCursorPaginationByPartyAndMarketNoCursor(t *testing.T) { 429 ctx := tempTransaction(t) 430 431 bs, ts := setupTradesTest(t) 432 blockTimes := make(map[string]time.Time) 433 populateTestTrades(ctx, t, bs, ts, blockTimes) 434 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 435 require.NoError(t, err) 436 partyID := []entities.PartyID{"dabbad00"} 437 marketID := []entities.MarketID{"deadbeef"} 438 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 439 require.NoError(t, err) 440 assert.Len(t, got, 4) 441 assert.Equal(t, "02a16077", got[0].ID.String()) 442 assert.Equal(t, uint64(1), got[0].Size) 443 assert.Equal(t, "7a797e0e", got[3].ID.String()) 444 assert.Equal(t, uint64(4), got[3].Size) 445 assert.False(t, pageInfo.HasNextPage) 446 assert.False(t, pageInfo.HasPreviousPage) 447 assert.Equal(t, "02a16077", got[0].ID.String()) 448 assert.Equal(t, "7a797e0e", got[3].ID.String()) 449 } 450 451 func testTradesCursorPaginationByMarketWithCursorFirst(t *testing.T) { 452 ctx := tempTransaction(t) 453 454 bs, ts := setupTradesTest(t) 455 blockTimes := make(map[string]time.Time) 456 populateTestTrades(ctx, t, bs, ts, blockTimes) 457 first := int32(2) 458 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 459 require.NoError(t, err) 460 marketID := []entities.MarketID{"deadbeef"} 461 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 462 require.NoError(t, err) 463 464 assert.Len(t, got, 2) 465 assert.Equal(t, "02a16077", got[0].ID.String()) 466 assert.Equal(t, uint64(1), got[0].Size) 467 assert.Equal(t, "44eea1bc", got[1].ID.String()) 468 assert.Equal(t, uint64(2), got[1].Size) 469 assert.True(t, pageInfo.HasNextPage) 470 assert.False(t, pageInfo.HasPreviousPage) 471 assert.Equal(t, "02a16077", got[0].ID.String()) 472 assert.Equal(t, "44eea1bc", got[1].ID.String()) 473 } 474 475 func testTradesCursorPaginationByPartyWithCursorNoMarketFirst(t *testing.T) { 476 ctx := tempTransaction(t) 477 478 bs, ts := setupTradesTest(t) 479 blockTimes := make(map[string]time.Time) 480 populateTestTrades(ctx, t, bs, ts, blockTimes) 481 first := int32(2) 482 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 483 require.NoError(t, err) 484 partyID := []entities.PartyID{"dabbad00"} 485 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 486 require.NoError(t, err) 487 assert.Len(t, got, 2) 488 assert.Equal(t, "02a16077", got[0].ID.String()) 489 assert.Equal(t, uint64(1), got[0].Size) 490 assert.Equal(t, "44eea1bc", got[1].ID.String()) 491 assert.Equal(t, uint64(2), got[1].Size) 492 assert.True(t, pageInfo.HasNextPage) 493 assert.False(t, pageInfo.HasPreviousPage) 494 assert.Equal(t, "02a16077", got[0].ID.String()) 495 assert.Equal(t, "44eea1bc", got[1].ID.String()) 496 } 497 498 func testTradesCursorPaginationByPartyAndMarketWithCursorFirst(t *testing.T) { 499 ctx := tempTransaction(t) 500 501 bs, ts := setupTradesTest(t) 502 blockTimes := make(map[string]time.Time) 503 populateTestTrades(ctx, t, bs, ts, blockTimes) 504 first := int32(2) 505 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 506 require.NoError(t, err) 507 partyID := []entities.PartyID{"dabbad00"} 508 marketID := []entities.MarketID{"deadbeef"} 509 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 510 require.NoError(t, err) 511 assert.Len(t, got, 2) 512 assert.Equal(t, "02a16077", got[0].ID.String()) 513 assert.Equal(t, uint64(1), got[0].Size) 514 assert.Equal(t, "44eea1bc", got[1].ID.String()) 515 assert.Equal(t, uint64(2), got[1].Size) 516 assert.True(t, pageInfo.HasNextPage) 517 assert.False(t, pageInfo.HasPreviousPage) 518 assert.Equal(t, "02a16077", got[0].ID.String()) 519 assert.Equal(t, "44eea1bc", got[1].ID.String()) 520 } 521 522 func testTradesCursorPaginationByMarketWithCursorLast(t *testing.T) { 523 ctx := tempTransaction(t) 524 525 bs, ts := setupTradesTest(t) 526 blockTimes := make(map[string]time.Time) 527 populateTestTrades(ctx, t, bs, ts, blockTimes) 528 last := int32(2) 529 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 530 require.NoError(t, err) 531 marketID := []entities.MarketID{"deadbeef"} 532 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 533 require.NoError(t, err) 534 535 assert.Len(t, got, 2) 536 assert.Equal(t, "65be62cd", got[0].ID.String()) 537 assert.Equal(t, uint64(3), got[0].Size) 538 assert.Equal(t, "7a797e0e", got[1].ID.String()) 539 assert.Equal(t, uint64(4), got[1].Size) 540 assert.False(t, pageInfo.HasNextPage) 541 assert.True(t, pageInfo.HasPreviousPage) 542 assert.Equal(t, "65be62cd", got[0].ID.String()) 543 assert.Equal(t, "7a797e0e", got[1].ID.String()) 544 } 545 546 func testTradesCursorPaginationByPartyWithCursorNoMarketLast(t *testing.T) { 547 ctx := tempTransaction(t) 548 549 bs, ts := setupTradesTest(t) 550 blockTimes := make(map[string]time.Time) 551 populateTestTrades(ctx, t, bs, ts, blockTimes) 552 last := int32(2) 553 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 554 require.NoError(t, err) 555 partyID := []entities.PartyID{"dabbad00"} 556 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 557 require.NoError(t, err) 558 assert.Len(t, got, 2) 559 assert.Equal(t, "7a797e0e", got[0].ID.String()) 560 assert.Equal(t, uint64(4), got[0].Size) 561 assert.Equal(t, "7bb2356e", got[1].ID.String()) 562 assert.Equal(t, uint64(5), got[1].Size) 563 assert.False(t, pageInfo.HasNextPage) 564 assert.True(t, pageInfo.HasPreviousPage) 565 assert.Equal(t, "7a797e0e", got[0].ID.String()) 566 assert.Equal(t, "7bb2356e", got[1].ID.String()) 567 } 568 569 func testTradesCursorPaginationByPartyAndMarketWithCursorLast(t *testing.T) { 570 ctx := tempTransaction(t) 571 572 bs, ts := setupTradesTest(t) 573 blockTimes := make(map[string]time.Time) 574 last := int32(2) 575 populateTestTrades(ctx, t, bs, ts, blockTimes) 576 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 577 require.NoError(t, err) 578 partyID := []entities.PartyID{"dabbad00"} 579 marketID := []entities.MarketID{"deadbeef"} 580 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 581 require.NoError(t, err) 582 assert.Len(t, got, 2) 583 assert.Equal(t, "65be62cd", got[0].ID.String()) 584 assert.Equal(t, uint64(3), got[0].Size) 585 assert.Equal(t, "7a797e0e", got[1].ID.String()) 586 assert.Equal(t, uint64(4), got[1].Size) 587 assert.False(t, pageInfo.HasNextPage) 588 assert.True(t, pageInfo.HasPreviousPage) 589 assert.Equal(t, "65be62cd", got[0].ID.String()) 590 assert.Equal(t, "7a797e0e", got[1].ID.String()) 591 } 592 593 func testTradesCursorPaginationByMarketWithCursorForward(t *testing.T) { 594 ctx := tempTransaction(t) 595 596 bs, ts := setupTradesTest(t) 597 blockTimes := make(map[string]time.Time) 598 populateTestTrades(ctx, t, bs, ts, blockTimes) 599 first := int32(2) 600 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["02a16077"]}.String()).Encode() 601 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 602 require.NoError(t, err) 603 marketID := []entities.MarketID{"deadbeef"} 604 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 605 require.NoError(t, err) 606 607 assert.Len(t, got, 2) 608 assert.Equal(t, "44eea1bc", got[0].ID.String()) 609 assert.Equal(t, uint64(2), got[0].Size) 610 assert.Equal(t, "65be62cd", got[1].ID.String()) 611 assert.Equal(t, uint64(3), got[1].Size) 612 assert.True(t, pageInfo.HasNextPage) 613 assert.True(t, pageInfo.HasPreviousPage) 614 assert.Equal(t, "44eea1bc", got[0].ID.String()) 615 assert.Equal(t, "65be62cd", got[1].ID.String()) 616 } 617 618 func testTradesCursorPaginationByPartyWithCursorNoMarketForward(t *testing.T) { 619 ctx := tempTransaction(t) 620 621 bs, ts := setupTradesTest(t) 622 blockTimes := make(map[string]time.Time) 623 populateTestTrades(ctx, t, bs, ts, blockTimes) 624 first := int32(2) 625 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["44eea1bc"]}.String()).Encode() 626 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 627 require.NoError(t, err) 628 partyID := []entities.PartyID{"dabbad00"} 629 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 630 require.NoError(t, err) 631 assert.Len(t, got, 2) 632 assert.Equal(t, "65be62cd", got[0].ID.String()) 633 assert.Equal(t, uint64(3), got[0].Size) 634 assert.Equal(t, "7a797e0e", got[1].ID.String()) 635 assert.Equal(t, uint64(4), got[1].Size) 636 assert.True(t, pageInfo.HasNextPage) 637 assert.True(t, pageInfo.HasPreviousPage) 638 assert.Equal(t, "65be62cd", got[0].ID.String()) 639 assert.Equal(t, "7a797e0e", got[1].ID.String()) 640 } 641 642 func testTradesCursorPaginationByPartyAndMarketWithCursorForward(t *testing.T) { 643 ctx := tempTransaction(t) 644 645 bs, ts := setupTradesTest(t) 646 blockTimes := make(map[string]time.Time) 647 populateTestTrades(ctx, t, bs, ts, blockTimes) 648 first := int32(2) 649 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["02a16077"]}.String()).Encode() 650 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 651 require.NoError(t, err) 652 partyID := []entities.PartyID{"dabbad00"} 653 marketID := []entities.MarketID{"deadbeef"} 654 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 655 require.NoError(t, err) 656 assert.Len(t, got, 2) 657 assert.Equal(t, "44eea1bc", got[0].ID.String()) 658 assert.Equal(t, uint64(2), got[0].Size) 659 assert.Equal(t, "65be62cd", got[1].ID.String()) 660 assert.Equal(t, uint64(3), got[1].Size) 661 assert.True(t, pageInfo.HasNextPage) 662 assert.True(t, pageInfo.HasPreviousPage) 663 assert.Equal(t, "44eea1bc", got[0].ID.String()) 664 assert.Equal(t, "65be62cd", got[1].ID.String()) 665 } 666 667 func testTradesCursorPaginationByMarketWithCursorBackward(t *testing.T) { 668 ctx := tempTransaction(t) 669 670 bs, ts := setupTradesTest(t) 671 blockTimes := make(map[string]time.Time) 672 populateTestTrades(ctx, t, bs, ts, blockTimes) 673 last := int32(2) 674 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7a797e0e"]}.String()).Encode() 675 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 676 require.NoError(t, err) 677 marketID := []entities.MarketID{"deadbeef"} 678 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 679 require.NoError(t, err) 680 assert.Len(t, got, 2) 681 assert.Equal(t, "44eea1bc", got[0].ID.String()) 682 assert.Equal(t, uint64(2), got[0].Size) 683 assert.Equal(t, "65be62cd", got[1].ID.String()) 684 assert.Equal(t, uint64(3), got[1].Size) 685 assert.True(t, pageInfo.HasNextPage) 686 assert.True(t, pageInfo.HasPreviousPage) 687 assert.Equal(t, "44eea1bc", got[0].ID.String()) 688 assert.Equal(t, "65be62cd", got[1].ID.String()) 689 } 690 691 func testTradesCursorPaginationByPartyWithCursorNoMarketBackward(t *testing.T) { 692 ctx := tempTransaction(t) 693 694 bs, ts := setupTradesTest(t) 695 blockTimes := make(map[string]time.Time) 696 populateTestTrades(ctx, t, bs, ts, blockTimes) 697 last := int32(2) 698 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7bb2356e"]}.String()).Encode() 699 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 700 require.NoError(t, err) 701 partyID := []entities.PartyID{"dabbad00"} 702 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 703 require.NoError(t, err) 704 assert.Len(t, got, 2) 705 assert.Equal(t, "65be62cd", got[0].ID.String()) 706 assert.Equal(t, uint64(3), got[0].Size) 707 assert.Equal(t, "7a797e0e", got[1].ID.String()) 708 assert.Equal(t, uint64(4), got[1].Size) 709 assert.True(t, pageInfo.HasNextPage) 710 assert.True(t, pageInfo.HasPreviousPage) 711 assert.Equal(t, "65be62cd", got[0].ID.String()) 712 assert.Equal(t, "7a797e0e", got[1].ID.String()) 713 } 714 715 func testTradesCursorPaginationByPartyAndMarketWithCursorBackward(t *testing.T) { 716 ctx := tempTransaction(t) 717 718 bs, ts := setupTradesTest(t) 719 blockTimes := make(map[string]time.Time) 720 populateTestTrades(ctx, t, bs, ts, blockTimes) 721 last := int32(2) 722 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7a797e0e"]}.String()).Encode() 723 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 724 require.NoError(t, err) 725 partyID := []entities.PartyID{"dabbad00"} 726 marketID := []entities.MarketID{"deadbeef"} 727 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 728 require.NoError(t, err) 729 assert.Len(t, got, 2) 730 assert.Equal(t, "44eea1bc", got[0].ID.String()) 731 assert.Equal(t, uint64(2), got[0].Size) 732 assert.Equal(t, "65be62cd", got[1].ID.String()) 733 assert.Equal(t, uint64(3), got[1].Size) 734 assert.True(t, pageInfo.HasNextPage) 735 assert.True(t, pageInfo.HasPreviousPage) 736 assert.Equal(t, "44eea1bc", got[0].ID.String()) 737 assert.Equal(t, "65be62cd", got[1].ID.String()) 738 } 739 740 // Newest First. 741 func testTradesCursorPaginationByMarketNoCursorNewestFirst(t *testing.T) { 742 ctx := tempTransaction(t) 743 744 bs, ts := setupTradesTest(t) 745 blockTimes := make(map[string]time.Time) 746 populateTestTrades(ctx, t, bs, ts, blockTimes) 747 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 748 require.NoError(t, err) 749 750 marketID := []entities.MarketID{"deadbeef"} 751 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 752 require.NoError(t, err) 753 754 assert.Len(t, got, 4) 755 assert.Equal(t, "7a797e0e", got[0].ID.String()) 756 assert.Equal(t, uint64(4), got[0].Size) 757 assert.Equal(t, "02a16077", got[3].ID.String()) 758 assert.Equal(t, uint64(1), got[3].Size) 759 assert.False(t, pageInfo.HasNextPage) 760 assert.False(t, pageInfo.HasPreviousPage) 761 assert.Equal(t, "7a797e0e", got[0].ID.String()) 762 assert.Equal(t, "02a16077", got[3].ID.String()) 763 } 764 765 func testTradesCursorPaginationByPartyNoMarketNoCursorNewestFirst(t *testing.T) { 766 ctx := tempTransaction(t) 767 768 bs, ts := setupTradesTest(t) 769 blockTimes := make(map[string]time.Time) 770 populateTestTrades(ctx, t, bs, ts, blockTimes) 771 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 772 require.NoError(t, err) 773 774 partyID := []entities.PartyID{"dabbad00"} 775 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 776 require.NoError(t, err) 777 assert.Len(t, got, 5) 778 779 assert.Equal(t, "7bb2356e", got[0].ID.String()) 780 assert.Equal(t, uint64(5), got[0].Size) 781 assert.Equal(t, "02a16077", got[4].ID.String()) 782 assert.Equal(t, uint64(1), got[4].Size) 783 784 assert.False(t, pageInfo.HasNextPage) 785 assert.False(t, pageInfo.HasPreviousPage) 786 assert.Equal(t, "7bb2356e", got[0].ID.String()) 787 assert.Equal(t, "02a16077", got[4].ID.String()) 788 } 789 790 func testTradesCursorPaginationByPartyAndMarketNoCursorNewestFirst(t *testing.T) { 791 ctx := tempTransaction(t) 792 793 bs, ts := setupTradesTest(t) 794 blockTimes := make(map[string]time.Time) 795 populateTestTrades(ctx, t, bs, ts, blockTimes) 796 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 797 require.NoError(t, err) 798 partyID := []entities.PartyID{"dabbad00"} 799 marketID := []entities.MarketID{"deadbeef"} 800 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 801 require.NoError(t, err) 802 assert.Len(t, got, 4) 803 assert.Equal(t, "7a797e0e", got[0].ID.String()) 804 assert.Equal(t, uint64(4), got[0].Size) 805 assert.Equal(t, "02a16077", got[3].ID.String()) 806 assert.Equal(t, uint64(1), got[3].Size) 807 assert.False(t, pageInfo.HasNextPage) 808 assert.False(t, pageInfo.HasPreviousPage) 809 assert.Equal(t, "7a797e0e", got[0].ID.String()) 810 assert.Equal(t, "02a16077", got[3].ID.String()) 811 } 812 813 func testTradesCursorPaginationByMarketWithCursorFirstNewestFirst(t *testing.T) { 814 ctx := tempTransaction(t) 815 816 bs, ts := setupTradesTest(t) 817 blockTimes := make(map[string]time.Time) 818 populateTestTrades(ctx, t, bs, ts, blockTimes) 819 first := int32(2) 820 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 821 require.NoError(t, err) 822 marketID := []entities.MarketID{"deadbeef"} 823 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 824 require.NoError(t, err) 825 826 assert.Len(t, got, 2) 827 assert.Equal(t, "7a797e0e", got[0].ID.String()) 828 assert.Equal(t, uint64(4), got[0].Size) 829 assert.Equal(t, "65be62cd", got[1].ID.String()) 830 assert.Equal(t, uint64(3), got[1].Size) 831 assert.True(t, pageInfo.HasNextPage) 832 assert.False(t, pageInfo.HasPreviousPage) 833 assert.Equal(t, "7a797e0e", got[0].ID.String()) 834 assert.Equal(t, "65be62cd", got[1].ID.String()) 835 } 836 837 func testTradesCursorPaginationByPartyWithCursorNoMarketFirstNewestFirst(t *testing.T) { 838 ctx := tempTransaction(t) 839 840 bs, ts := setupTradesTest(t) 841 blockTimes := make(map[string]time.Time) 842 populateTestTrades(ctx, t, bs, ts, blockTimes) 843 first := int32(2) 844 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 845 require.NoError(t, err) 846 partyID := []entities.PartyID{"dabbad00"} 847 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 848 require.NoError(t, err) 849 assert.Len(t, got, 2) 850 assert.Equal(t, "7bb2356e", got[0].ID.String()) 851 assert.Equal(t, uint64(5), got[0].Size) 852 assert.Equal(t, "7a797e0e", got[1].ID.String()) 853 assert.Equal(t, uint64(4), got[1].Size) 854 assert.True(t, pageInfo.HasNextPage) 855 assert.False(t, pageInfo.HasPreviousPage) 856 assert.Equal(t, "7bb2356e", got[0].ID.String()) 857 assert.Equal(t, "7a797e0e", got[1].ID.String()) 858 } 859 860 func testTradesCursorPaginationByPartyAndMarketWithCursorFirstNewestFirst(t *testing.T) { 861 ctx := tempTransaction(t) 862 863 bs, ts := setupTradesTest(t) 864 blockTimes := make(map[string]time.Time) 865 first := int32(2) 866 populateTestTrades(ctx, t, bs, ts, blockTimes) 867 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 868 require.NoError(t, err) 869 partyID := []entities.PartyID{"dabbad00"} 870 marketID := []entities.MarketID{"deadbeef"} 871 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 872 require.NoError(t, err) 873 assert.Len(t, got, 2) 874 assert.Equal(t, "7a797e0e", got[0].ID.String()) 875 assert.Equal(t, uint64(4), got[0].Size) 876 assert.Equal(t, "65be62cd", got[1].ID.String()) 877 assert.Equal(t, uint64(3), got[1].Size) 878 assert.True(t, pageInfo.HasNextPage) 879 assert.False(t, pageInfo.HasPreviousPage) 880 assert.Equal(t, "7a797e0e", got[0].ID.String()) 881 assert.Equal(t, "65be62cd", got[1].ID.String()) 882 } 883 884 func testTradesCursorPaginationByMarketWithCursorLastNewestFirst(t *testing.T) { 885 ctx := tempTransaction(t) 886 887 bs, ts := setupTradesTest(t) 888 blockTimes := make(map[string]time.Time) 889 populateTestTrades(ctx, t, bs, ts, blockTimes) 890 last := int32(2) 891 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 892 require.NoError(t, err) 893 marketID := []entities.MarketID{"deadbeef"} 894 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 895 require.NoError(t, err) 896 897 assert.Len(t, got, 2) 898 assert.Equal(t, "44eea1bc", got[0].ID.String()) 899 assert.Equal(t, uint64(2), got[0].Size) 900 assert.Equal(t, "02a16077", got[1].ID.String()) 901 assert.Equal(t, uint64(1), got[1].Size) 902 assert.False(t, pageInfo.HasNextPage) 903 assert.True(t, pageInfo.HasPreviousPage) 904 assert.Equal(t, "44eea1bc", got[0].ID.String()) 905 assert.Equal(t, "02a16077", got[1].ID.String()) 906 } 907 908 func testTradesCursorPaginationByPartyWithCursorNoMarketLastNewestFirst(t *testing.T) { 909 ctx := tempTransaction(t) 910 911 bs, ts := setupTradesTest(t) 912 blockTimes := make(map[string]time.Time) 913 populateTestTrades(ctx, t, bs, ts, blockTimes) 914 last := int32(2) 915 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 916 require.NoError(t, err) 917 partyID := []entities.PartyID{"dabbad00"} 918 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 919 require.NoError(t, err) 920 assert.Len(t, got, 2) 921 assert.Equal(t, "44eea1bc", got[0].ID.String()) 922 assert.Equal(t, uint64(2), got[0].Size) 923 assert.Equal(t, "02a16077", got[1].ID.String()) 924 assert.Equal(t, uint64(1), got[1].Size) 925 assert.False(t, pageInfo.HasNextPage) 926 assert.True(t, pageInfo.HasPreviousPage) 927 assert.Equal(t, "44eea1bc", got[0].ID.String()) 928 assert.Equal(t, "02a16077", got[1].ID.String()) 929 } 930 931 func testTradesCursorPaginationByPartyAndMarketWithCursorLastNewestFirst(t *testing.T) { 932 ctx := tempTransaction(t) 933 934 bs, ts := setupTradesTest(t) 935 blockTimes := make(map[string]time.Time) 936 populateTestTrades(ctx, t, bs, ts, blockTimes) 937 last := int32(2) 938 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 939 require.NoError(t, err) 940 partyID := []entities.PartyID{"dabbad00"} 941 marketID := []entities.MarketID{"deadbeef"} 942 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 943 require.NoError(t, err) 944 assert.Len(t, got, 2) 945 assert.Equal(t, "44eea1bc", got[0].ID.String()) 946 assert.Equal(t, uint64(2), got[0].Size) 947 assert.Equal(t, "02a16077", got[1].ID.String()) 948 assert.Equal(t, uint64(1), got[1].Size) 949 assert.False(t, pageInfo.HasNextPage) 950 assert.True(t, pageInfo.HasPreviousPage) 951 assert.Equal(t, "44eea1bc", got[0].ID.String()) 952 assert.Equal(t, "02a16077", got[1].ID.String()) 953 } 954 955 func testTradesCursorPaginationByMarketWithCursorForwardNewestFirst(t *testing.T) { 956 ctx := tempTransaction(t) 957 958 bs, ts := setupTradesTest(t) 959 blockTimes := make(map[string]time.Time) 960 populateTestTrades(ctx, t, bs, ts, blockTimes) 961 first := int32(2) 962 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7a797e0e"]}.String()).Encode() 963 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 964 require.NoError(t, err) 965 marketID := []entities.MarketID{"deadbeef"} 966 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 967 require.NoError(t, err) 968 969 assert.Len(t, got, 2) 970 assert.Equal(t, "65be62cd", got[0].ID.String()) 971 assert.Equal(t, uint64(3), got[0].Size) 972 assert.Equal(t, "44eea1bc", got[1].ID.String()) 973 assert.Equal(t, uint64(2), got[1].Size) 974 assert.True(t, pageInfo.HasNextPage) 975 assert.True(t, pageInfo.HasPreviousPage) 976 assert.Equal(t, "65be62cd", got[0].ID.String()) 977 assert.Equal(t, "44eea1bc", got[1].ID.String()) 978 } 979 980 func testTradesCursorPaginationByPartyWithCursorNoMarketForwardNewestFirst(t *testing.T) { 981 ctx := tempTransaction(t) 982 983 bs, ts := setupTradesTest(t) 984 blockTimes := make(map[string]time.Time) 985 populateTestTrades(ctx, t, bs, ts, blockTimes) 986 first := int32(2) 987 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7a797e0e"]}.String()).Encode() 988 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 989 require.NoError(t, err) 990 partyID := []entities.PartyID{"dabbad00"} 991 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 992 require.NoError(t, err) 993 assert.Len(t, got, 2) 994 assert.Equal(t, "65be62cd", got[0].ID.String()) 995 assert.Equal(t, uint64(3), got[0].Size) 996 assert.Equal(t, "44eea1bc", got[1].ID.String()) 997 assert.Equal(t, uint64(2), got[1].Size) 998 assert.True(t, pageInfo.HasNextPage) 999 assert.True(t, pageInfo.HasPreviousPage) 1000 assert.Equal(t, "65be62cd", got[0].ID.String()) 1001 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1002 } 1003 1004 func testTradesCursorPaginationByPartyAndMarketWithCursorForwardNewestFirst(t *testing.T) { 1005 ctx := tempTransaction(t) 1006 1007 bs, ts := setupTradesTest(t) 1008 blockTimes := make(map[string]time.Time) 1009 populateTestTrades(ctx, t, bs, ts, blockTimes) 1010 first := int32(2) 1011 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["7a797e0e"]}.String()).Encode() 1012 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 1013 require.NoError(t, err) 1014 partyID := []entities.PartyID{"dabbad00"} 1015 marketID := []entities.MarketID{"deadbeef"} 1016 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 1017 require.NoError(t, err) 1018 assert.Len(t, got, 2) 1019 assert.Equal(t, "65be62cd", got[0].ID.String()) 1020 assert.Equal(t, uint64(3), got[0].Size) 1021 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1022 assert.Equal(t, uint64(2), got[1].Size) 1023 assert.True(t, pageInfo.HasNextPage) 1024 assert.True(t, pageInfo.HasPreviousPage) 1025 assert.Equal(t, "65be62cd", got[0].ID.String()) 1026 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1027 } 1028 1029 func testTradesCursorPaginationByMarketWithCursorBackwardNewestFirst(t *testing.T) { 1030 ctx := tempTransaction(t) 1031 1032 bs, ts := setupTradesTest(t) 1033 blockTimes := make(map[string]time.Time) 1034 populateTestTrades(ctx, t, bs, ts, blockTimes) 1035 last := int32(2) 1036 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["02a16077"]}.String()).Encode() 1037 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 1038 require.NoError(t, err) 1039 marketID := []entities.MarketID{"deadbeef"} 1040 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{}) 1041 require.NoError(t, err) 1042 assert.Len(t, got, 2) 1043 assert.Equal(t, "65be62cd", got[0].ID.String()) 1044 assert.Equal(t, uint64(3), got[0].Size) 1045 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1046 assert.Equal(t, uint64(2), got[1].Size) 1047 assert.True(t, pageInfo.HasNextPage) 1048 assert.True(t, pageInfo.HasPreviousPage) 1049 assert.Equal(t, "65be62cd", got[0].ID.String()) 1050 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1051 } 1052 1053 func testTradesCursorPaginationByPartyWithCursorNoMarketBackwardNewestFirst(t *testing.T) { 1054 ctx := tempTransaction(t) 1055 1056 bs, ts := setupTradesTest(t) 1057 blockTimes := make(map[string]time.Time) 1058 populateTestTrades(ctx, t, bs, ts, blockTimes) 1059 last := int32(2) 1060 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["44eea1bc"]}.String()).Encode() 1061 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 1062 require.NoError(t, err) 1063 partyID := []entities.PartyID{"dabbad00"} 1064 got, pageInfo, err := ts.List(ctx, nil, partyID, nil, pagination, entities.DateRange{}) 1065 require.NoError(t, err) 1066 assert.Len(t, got, 2) 1067 assert.Equal(t, "7a797e0e", got[0].ID.String()) 1068 assert.Equal(t, uint64(4), got[0].Size) 1069 assert.Equal(t, "65be62cd", got[1].ID.String()) 1070 assert.Equal(t, uint64(3), got[1].Size) 1071 assert.True(t, pageInfo.HasNextPage) 1072 assert.True(t, pageInfo.HasPreviousPage) 1073 assert.Equal(t, "7a797e0e", got[0].ID.String()) 1074 assert.Equal(t, "65be62cd", got[1].ID.String()) 1075 } 1076 1077 func testTradesCursorPaginationByPartyAndMarketWithCursorBackwardNewestFirst(t *testing.T) { 1078 ctx := tempTransaction(t) 1079 1080 bs, ts := setupTradesTest(t) 1081 blockTimes := make(map[string]time.Time) 1082 populateTestTrades(ctx, t, bs, ts, blockTimes) 1083 last := int32(2) 1084 before := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["02a16077"]}.String()).Encode() 1085 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 1086 require.NoError(t, err) 1087 partyID := []entities.PartyID{"dabbad00"} 1088 marketID := []entities.MarketID{"deadbeef"} 1089 got, pageInfo, err := ts.List(ctx, marketID, partyID, nil, pagination, entities.DateRange{}) 1090 require.NoError(t, err) 1091 assert.Len(t, got, 2) 1092 assert.Equal(t, "65be62cd", got[0].ID.String()) 1093 assert.Equal(t, uint64(3), got[0].Size) 1094 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1095 assert.Equal(t, uint64(2), got[1].Size) 1096 assert.True(t, pageInfo.HasNextPage) 1097 assert.True(t, pageInfo.HasPreviousPage) 1098 assert.Equal(t, "65be62cd", got[0].ID.String()) 1099 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1100 } 1101 1102 func testTradesCursorPaginationBetweenDatesByMarketNoCursor(t *testing.T) { 1103 ctx := tempTransaction(t) 1104 1105 bs, ts := setupTradesTest(t) 1106 blockTimes := make(map[string]time.Time) 1107 populateTestTrades(ctx, t, bs, ts, blockTimes) 1108 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 1109 require.NoError(t, err) 1110 1111 marketID := []entities.MarketID{"deadbeef"} 1112 startDate := blockTimes["44eea1bc"] 1113 endDate := blockTimes["7a797e0e"] 1114 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{ 1115 Start: &startDate, 1116 End: &endDate, 1117 }) 1118 require.NoError(t, err) 1119 1120 assert.Len(t, got, 2) 1121 assert.Equal(t, "44eea1bc", got[0].ID.String()) 1122 assert.Equal(t, uint64(2), got[0].Size) 1123 assert.Equal(t, "65be62cd", got[1].ID.String()) 1124 assert.Equal(t, uint64(3), got[1].Size) 1125 assert.False(t, pageInfo.HasNextPage) 1126 assert.False(t, pageInfo.HasPreviousPage) 1127 } 1128 1129 func testTradesCursorPaginationBetweenDatesByMarketNoCursorNewestFirst(t *testing.T) { 1130 ctx := tempTransaction(t) 1131 1132 bs, ts := setupTradesTest(t) 1133 blockTimes := make(map[string]time.Time) 1134 populateTestTrades(ctx, t, bs, ts, blockTimes) 1135 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 1136 require.NoError(t, err) 1137 1138 marketID := []entities.MarketID{"deadbeef"} 1139 startDate := blockTimes["44eea1bc"] 1140 endDate := blockTimes["7a797e0e"] 1141 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{ 1142 Start: &startDate, 1143 End: &endDate, 1144 }) 1145 require.NoError(t, err) 1146 1147 assert.Len(t, got, 2) 1148 assert.Equal(t, "65be62cd", got[0].ID.String()) 1149 assert.Equal(t, uint64(3), got[0].Size) 1150 assert.Equal(t, "44eea1bc", got[1].ID.String()) 1151 assert.Equal(t, uint64(2), got[1].Size) 1152 assert.False(t, pageInfo.HasNextPage) 1153 assert.False(t, pageInfo.HasPreviousPage) 1154 } 1155 1156 func testTradesCursorPaginationBetweenDatesByMarketWithCursorLast(t *testing.T) { 1157 ctx := tempTransaction(t) 1158 1159 bs, ts := setupTradesTest(t) 1160 blockTimes := make(map[string]time.Time) 1161 populateTestTrades(ctx, t, bs, ts, blockTimes) 1162 last := int32(2) 1163 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 1164 require.NoError(t, err) 1165 marketID := []entities.MarketID{"deadbeef"} 1166 startDate := blockTimes["02a16077"] 1167 endDate := blockTimes["7a797e0e"] 1168 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{ 1169 Start: &startDate, 1170 End: &endDate, 1171 }) 1172 require.NoError(t, err) 1173 1174 assert.Len(t, got, 2) 1175 assert.Equal(t, "44eea1bc", got[0].ID.String()) 1176 assert.Equal(t, uint64(2), got[0].Size) 1177 assert.Equal(t, "65be62cd", got[1].ID.String()) 1178 assert.Equal(t, uint64(3), got[1].Size) 1179 assert.False(t, pageInfo.HasNextPage) 1180 assert.True(t, pageInfo.HasPreviousPage) 1181 } 1182 1183 func testTradesCursorPaginationBetweenDatesByMarketWithCursorForward(t *testing.T) { 1184 ctx := tempTransaction(t) 1185 1186 bs, ts := setupTradesTest(t) 1187 blockTimes := make(map[string]time.Time) 1188 populateTestTrades(ctx, t, bs, ts, blockTimes) 1189 first := int32(2) 1190 after := entities.NewCursor(entities.TradeCursor{SyntheticTime: blockTimes["02a16077"]}.String()).Encode() 1191 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 1192 require.NoError(t, err) 1193 marketID := []entities.MarketID{"deadbeef"} 1194 startDate := blockTimes["02a16077"] 1195 endDate := blockTimes["7a797e0e"] 1196 got, pageInfo, err := ts.List(ctx, marketID, nil, nil, pagination, entities.DateRange{ 1197 Start: &startDate, 1198 End: &endDate, 1199 }) 1200 require.NoError(t, err) 1201 1202 assert.Len(t, got, 2) 1203 assert.Equal(t, "44eea1bc", got[0].ID.String()) 1204 assert.Equal(t, uint64(2), got[0].Size) 1205 assert.Equal(t, "65be62cd", got[1].ID.String()) 1206 assert.Equal(t, uint64(3), got[1].Size) 1207 assert.False(t, pageInfo.HasNextPage) 1208 assert.True(t, pageInfo.HasPreviousPage) 1209 } 1210 1211 func tesGetCurrentTransferFeeDiscount(t *testing.T) { 1212 ctx := tempTransaction(t) 1213 1214 transfers := sqlstore.NewTransfers(connectionSource) 1215 1216 vegaTime := time.Now().Truncate(time.Microsecond) 1217 1218 partyID := entities.PartyID(hex.EncodeToString([]byte("party-1"))) 1219 assetID := entities.AssetID(hex.EncodeToString([]byte("asset-1"))) 1220 secondAssetID := entities.AssetID(hex.EncodeToString([]byte("asset-2"))) 1221 1222 tfd := &entities.TransferFeesDiscount{ 1223 PartyID: partyID, 1224 AssetID: assetID, 1225 Amount: num.DecimalFromInt64(500), 1226 EpochSeq: 1, 1227 VegaTime: vegaTime, 1228 } 1229 assert.NoError(t, transfers.UpsertFeesDiscount(ctx, tfd)) 1230 discount, err := transfers.GetCurrentTransferFeeDiscount(ctx, partyID, assetID) 1231 assert.NoError(t, err) 1232 assert.Equal(t, tfd, discount) 1233 1234 secondTfd := &entities.TransferFeesDiscount{ 1235 PartyID: partyID, 1236 AssetID: secondAssetID, 1237 Amount: num.DecimalFromInt64(150), 1238 EpochSeq: 1, 1239 VegaTime: vegaTime, 1240 } 1241 assert.NoError(t, transfers.UpsertFeesDiscount(ctx, secondTfd)) 1242 discount, err = transfers.GetCurrentTransferFeeDiscount(ctx, partyID, secondAssetID) 1243 assert.NoError(t, err) 1244 assert.Equal(t, secondTfd, discount) 1245 1246 // update the amount for the same party and asset 1247 vegaTime = vegaTime.Add(time.Second) 1248 tfd.VegaTime = vegaTime 1249 tfd.Amount = num.DecimalFromInt64(400) 1250 assert.NoError(t, transfers.UpsertFeesDiscount(ctx, tfd)) 1251 1252 discount, err = transfers.GetCurrentTransferFeeDiscount(ctx, partyID, assetID) 1253 assert.NoError(t, err) 1254 assert.Equal(t, tfd, discount) 1255 }