code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/withdrawals_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 "fmt" 21 "strconv" 22 "testing" 23 "time" 24 25 "code.vegaprotocol.io/vega/datanode/entities" 26 "code.vegaprotocol.io/vega/datanode/sqlstore" 27 "code.vegaprotocol.io/vega/protos/vega" 28 29 "github.com/georgysavva/scany/pgxscan" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 ) 33 34 func TestWithdrawals(t *testing.T) { 35 t.Run("Upsert should insert withdrawals if one doesn't exist for the block", testAddWithdrawalForNewBlock) 36 t.Run("Upsert should update withdrawals if one already exists for the block", testUpdateWithdrawalForBlockIfExists) 37 t.Run("Upsert should insert withdrawal updates if the same withdrawal id is inserted in a different block", testInsertWithdrawalUpdatesIfNewBlock) 38 t.Run("GetByID should retrieve the latest state of the withdrawal with the given ID", testWithdrawalsGetByID) 39 t.Run("GetByParty should retrieve the latest state of all withdrawals for a given party", testWithdrawalsGetByParty) 40 t.Run("GetByTxHash", testWithdrawalsGetByTxHash) 41 } 42 43 func TestWithdrawalsPagination(t *testing.T) { 44 t.Run("should return all withdrawals if no pagination is specified", testWithdrawalsPaginationNoPagination) 45 t.Run("should return the first page of results if first is provided", testWithdrawalsPaginationFirst) 46 t.Run("should return the last page of results if last is provided", testWithdrawalsPaginationLast) 47 t.Run("should return the specified page of results if first and after are provided", testWithdrawalsPaginationFirstAfter) 48 t.Run("should return the specified page of results if last and before are provided", testWithdrawalsPaginationLastBefore) 49 50 t.Run("should return all withdrawals if no pagination is specified - newest first", testWithdrawalsPaginationNoPaginationNewestFirst) 51 t.Run("should return the first page of results if first is provided - newest first", testWithdrawalsPaginationFirstNewestFirst) 52 t.Run("should return the last page of results if last is provided - newest first", testWithdrawalsPaginationLastNewestFirst) 53 t.Run("should return the specified page of results if first and after are provided - newest first", testWithdrawalsPaginationFirstAfterNewestFirst) 54 t.Run("should return the specified page of results if last and before are provided - newest first", testWithdrawalsPaginationLastBeforeNewestFirst) 55 56 t.Run("should return all withdrawals between dates if no pagination is specified", testWithdrawalsPaginationBetweenDatesNoPagination) 57 t.Run("should return the first page of results between dates if first is provided", testWithdrawalsPaginationBetweenDatesFirst) 58 t.Run("should return the last page of results between dates if last is provided", testWithdrawalsPaginationBetweenDatesLast) 59 t.Run("should return the specified page of results between dates if first and after are provided", testWithdrawalsPaginationBetweenDatesFirstAfter) 60 t.Run("should return the specified page of results between dates if last and before are provided", testWithdrawalsPaginationBetweenDatesLastBefore) 61 62 t.Run("should return all withdrawals between dates if no pagination is specified - newest first", testWithdrawalsPaginationBetweenDatesNoPaginationNewestFirst) 63 t.Run("should return the first page of results between dates if first is provided - newest first", testWithdrawalsPaginationBetweenDatesFirstNewestFirst) 64 t.Run("should return the last page of results between dates if last is provided - newest first", testWithdrawalsPaginationBetweenDatesLastNewestFirst) 65 t.Run("should return the specified page of results between dates if first and after are provided - newest first", testWithdrawalsPaginationBetweenDatesFirstAfterNewestFirst) 66 t.Run("should return the specified page of results between dates if last and before are provided - newest first", testWithdrawalsPaginationBetweenDatesLastBeforeNewestFirst) 67 } 68 69 func setupWithdrawalStoreTests(t *testing.T) (*sqlstore.Blocks, *sqlstore.Withdrawals, sqlstore.Connection) { 70 t.Helper() 71 bs := sqlstore.NewBlocks(connectionSource) 72 ws := sqlstore.NewWithdrawals(connectionSource) 73 return bs, ws, connectionSource 74 } 75 76 func testAddWithdrawalForNewBlock(t *testing.T) { 77 ctx := tempTransaction(t) 78 79 bs, ws, conn := setupWithdrawalStoreTests(t) 80 81 var rowCount int 82 83 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 84 require.NoError(t, err) 85 assert.Equal(t, 0, rowCount) 86 87 block := addTestBlock(t, ctx, bs) 88 withdrawalProto := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 89 90 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 91 require.NoError(t, err, "Converting withdrawal proto to database entity") 92 err = ws.Upsert(ctx, withdrawal) 93 require.NoError(t, err) 94 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 95 assert.NoError(t, err) 96 assert.Equal(t, 1, rowCount) 97 } 98 99 func testUpdateWithdrawalForBlockIfExists(t *testing.T) { 100 ctx := tempTransaction(t) 101 102 bs, ws, conn := setupWithdrawalStoreTests(t) 103 104 var rowCount int 105 106 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 107 require.NoError(t, err) 108 assert.Equal(t, 0, rowCount) 109 110 block := addTestBlock(t, ctx, bs) 111 withdrawalProto := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 112 113 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 114 require.NoError(t, err, "Converting withdrawal proto to database entity") 115 116 err = ws.Upsert(ctx, withdrawal) 117 require.NoError(t, err) 118 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 119 assert.NoError(t, err) 120 assert.Equal(t, 1, rowCount) 121 122 withdrawal.Status = entities.WithdrawalStatus(vega.Withdrawal_STATUS_FINALIZED) 123 124 err = ws.Upsert(ctx, withdrawal) 125 require.NoError(t, err) 126 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 127 assert.NoError(t, err) 128 var status entities.WithdrawalStatus 129 err = pgxscan.Get(ctx, conn, &status, `select status from withdrawals where id = $1 and vega_time = $2`, withdrawal.ID, withdrawal.VegaTime) 130 assert.NoError(t, err) 131 assert.Equal(t, entities.WithdrawalStatusFinalized, status) 132 } 133 134 func testInsertWithdrawalUpdatesIfNewBlock(t *testing.T) { 135 ctx := tempTransaction(t) 136 137 bs, ws, conn := setupWithdrawalStoreTests(t) 138 139 var rowCount int 140 141 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 142 require.NoError(t, err) 143 assert.Equal(t, 0, rowCount) 144 145 source := &testBlockSource{bs, time.Now()} 146 block := source.getNextBlock(t, ctx) 147 withdrawalProto := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 148 149 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 150 require.NoError(t, err, "Converting withdrawal proto to database entity") 151 152 err = ws.Upsert(ctx, withdrawal) 153 require.NoError(t, err) 154 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 155 assert.NoError(t, err) 156 assert.Equal(t, 1, rowCount) 157 158 block = source.getNextBlock(t, ctx) 159 withdrawalProto.Status = vega.Withdrawal_STATUS_FINALIZED 160 withdrawal, err = entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 161 require.NoError(t, err, "Converting withdrawal proto to database entity") 162 163 err = ws.Upsert(ctx, withdrawal) 164 require.NoError(t, err) 165 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 166 assert.NoError(t, err) 167 var status entities.WithdrawalStatus 168 err = pgxscan.Get(ctx, conn, &status, `select status from withdrawals where id = $1 and vega_time = $2`, withdrawal.ID, withdrawal.VegaTime) 169 assert.NoError(t, err) 170 assert.Equal(t, entities.WithdrawalStatusFinalized, status) 171 } 172 173 func testWithdrawalsGetByID(t *testing.T) { 174 ctx := tempTransaction(t) 175 176 bs, ws, conn := setupWithdrawalStoreTests(t) 177 178 var rowCount int 179 180 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 181 require.NoError(t, err) 182 assert.Equal(t, 0, rowCount) 183 184 source := &testBlockSource{bs, time.Now()} 185 block := source.getNextBlock(t, ctx) 186 withdrawalProto := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 187 188 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 189 require.NoError(t, err, "Converting withdrawal proto to database entity") 190 191 err = ws.Upsert(ctx, withdrawal) 192 require.NoError(t, err) 193 err = conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 194 assert.NoError(t, err) 195 assert.Equal(t, 1, rowCount) 196 197 block = source.getNextBlock(t, ctx) 198 withdrawalProto.Status = vega.Withdrawal_STATUS_FINALIZED 199 withdrawal, err = entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 200 require.NoError(t, err, "Converting withdrawal proto to database entity") 201 202 err = ws.Upsert(ctx, withdrawal) 203 require.NoError(t, err) 204 205 got, err := ws.GetByID(ctx, withdrawalProto.Id) 206 assert.NoError(t, err) 207 withdrawal.CreatedTimestamp = withdrawal.CreatedTimestamp.Truncate(time.Microsecond) 208 withdrawal.WithdrawnTimestamp = withdrawal.WithdrawnTimestamp.Truncate(time.Microsecond) 209 assert.Equal(t, *withdrawal, got) 210 } 211 212 func testWithdrawalsGetByParty(t *testing.T) { 213 ctx := tempTransaction(t) 214 215 bs, ws, conn := setupWithdrawalStoreTests(t) 216 217 var rowCount int 218 219 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 220 require.NoError(t, err) 221 assert.Equal(t, 0, rowCount) 222 223 source := &testBlockSource{bs, time.Now()} 224 block := source.getNextBlock(t, ctx) 225 withdrawalProto1 := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 226 withdrawalProto1.Id = "deadbeef01" 227 228 withdrawalProto2 := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 229 withdrawalProto2.Id = "deadbeef02" 230 231 want := make([]entities.Withdrawal, 0) 232 233 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto1, generateTxHash(), block.VegaTime) 234 require.NoError(t, err, "Converting withdrawal proto to database entity") 235 236 err = ws.Upsert(ctx, withdrawal) 237 require.NoError(t, err) 238 239 block = source.getNextBlock(t, ctx) 240 withdrawalProto1.Status = vega.Withdrawal_STATUS_FINALIZED 241 withdrawal, err = entities.WithdrawalFromProto(withdrawalProto1, generateTxHash(), block.VegaTime) 242 require.NoError(t, err, "Converting withdrawal proto to database entity") 243 244 err = ws.Upsert(ctx, withdrawal) 245 require.NoError(t, err) 246 247 withdrawal.CreatedTimestamp = withdrawal.CreatedTimestamp.Truncate(time.Microsecond) 248 withdrawal.WithdrawnTimestamp = withdrawal.WithdrawnTimestamp.Truncate(time.Microsecond) 249 250 want = append(want, *withdrawal) 251 252 block = source.getNextBlock(t, ctx) 253 withdrawal, err = entities.WithdrawalFromProto(withdrawalProto2, generateTxHash(), block.VegaTime) 254 require.NoError(t, err, "Converting withdrawal proto to database entity") 255 256 err = ws.Upsert(ctx, withdrawal) 257 require.NoError(t, err) 258 259 block = source.getNextBlock(t, ctx) 260 withdrawal, err = entities.WithdrawalFromProto(withdrawalProto2, generateTxHash(), block.VegaTime) 261 withdrawalProto2.Status = vega.Withdrawal_STATUS_FINALIZED 262 require.NoError(t, err, "Converting withdrawal proto to database entity") 263 264 err = ws.Upsert(ctx, withdrawal) 265 require.NoError(t, err) 266 267 withdrawal.CreatedTimestamp = withdrawal.CreatedTimestamp.Truncate(time.Microsecond) 268 withdrawal.WithdrawnTimestamp = withdrawal.WithdrawnTimestamp.Truncate(time.Microsecond) 269 270 want = append(want, *withdrawal) 271 272 got, _, _ := ws.GetByParty(ctx, withdrawalProto1.PartyId, false, entities.CursorPagination{}, entities.DateRange{}) 273 274 assert.Equal(t, want, got) 275 } 276 277 func testWithdrawalsGetByTxHash(t *testing.T) { 278 ctx := tempTransaction(t) 279 280 bs, ws, conn := setupWithdrawalStoreTests(t) 281 282 var rowCount int 283 284 err := conn.QueryRow(ctx, `select count(*) from withdrawals`).Scan(&rowCount) 285 require.NoError(t, err) 286 assert.Equal(t, 0, rowCount) 287 288 block := addTestBlock(t, ctx, bs) 289 withdrawalProto1 := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 290 withdrawalProto1.Id = "deadbeef01" 291 292 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto1, generateTxHash(), block.VegaTime) 293 require.NoError(t, err, "Converting withdrawal proto to database entity") 294 295 err = ws.Upsert(ctx, withdrawal) 296 require.NoError(t, err) 297 298 withdrawals, err := ws.GetByTxHash(ctx, withdrawal.TxHash) 299 require.NoError(t, err) 300 require.Equal(t, *withdrawal, withdrawals[0]) 301 } 302 303 func getTestWithdrawal(id, party, asset, amount, txHash string, ts time.Time) *vega.Withdrawal { 304 return &vega.Withdrawal{ 305 Id: id, 306 PartyId: party, 307 Amount: amount, 308 Asset: asset, 309 Status: vega.Withdrawal_STATUS_OPEN, 310 Ref: "deadbeef", 311 TxHash: txHash, 312 CreatedTimestamp: ts.UnixNano(), 313 WithdrawnTimestamp: ts.UnixNano(), 314 Ext: &vega.WithdrawExt{ 315 Ext: &vega.WithdrawExt_Erc20{ 316 Erc20: &vega.Erc20WithdrawExt{ 317 ReceiverAddress: "0x1234", 318 }, 319 }, 320 }, 321 } 322 } 323 324 func addWithdrawals(ctx context.Context, t *testing.T, bs *sqlstore.Blocks, ws *sqlstore.Withdrawals) []entities.Withdrawal { 325 t.Helper() 326 vegaTime := time.Now().Truncate(time.Microsecond) 327 amount := int64(1000) 328 withdrawals := make([]entities.Withdrawal, 0, 10) 329 for i := 0; i < 10; i++ { 330 addTestBlockForTime(t, ctx, bs, vegaTime) 331 332 withdrawalProto := getTestWithdrawal(fmt.Sprintf("deadbeef%02d", i+1), testID, testID, 333 strconv.FormatInt(amount, 10), GenerateID(), vegaTime) 334 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), vegaTime) 335 require.NoError(t, err, "Converting withdrawal proto to database entity") 336 err = ws.Upsert(ctx, withdrawal) 337 withdrawals = append(withdrawals, *withdrawal) 338 require.NoError(t, err) 339 340 vegaTime = vegaTime.Add(time.Second) 341 amount += 100 342 } 343 344 return withdrawals 345 } 346 347 func testWithdrawalsPaginationNoPagination(t *testing.T) { 348 ctx := tempTransaction(t) 349 350 bs, ws, _ := setupWithdrawalStoreTests(t) 351 352 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 353 354 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 355 require.NoError(t, err) 356 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 357 358 require.NoError(t, err) 359 assert.Equal(t, testWithdrawals, got) 360 assert.Equal(t, entities.PageInfo{ 361 HasNextPage: false, 362 HasPreviousPage: false, 363 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 364 VegaTime: testWithdrawals[0].VegaTime, 365 ID: testWithdrawals[0].ID, 366 }.String()).Encode(), 367 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 368 VegaTime: testWithdrawals[9].VegaTime, 369 ID: testWithdrawals[9].ID, 370 }.String()).Encode(), 371 }, pageInfo) 372 } 373 374 func testWithdrawalsPaginationFirst(t *testing.T) { 375 ctx := tempTransaction(t) 376 377 bs, ws, _ := setupWithdrawalStoreTests(t) 378 379 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 380 381 first := int32(3) 382 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 383 require.NoError(t, err) 384 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 385 386 require.NoError(t, err) 387 want := testWithdrawals[:3] 388 assert.Equal(t, want, got) 389 assert.Equal(t, entities.PageInfo{ 390 HasNextPage: true, 391 HasPreviousPage: false, 392 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 393 VegaTime: testWithdrawals[0].VegaTime, 394 ID: testWithdrawals[0].ID, 395 }.String()).Encode(), 396 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 397 VegaTime: testWithdrawals[2].VegaTime, 398 ID: testWithdrawals[2].ID, 399 }.String()).Encode(), 400 }, pageInfo) 401 } 402 403 func testWithdrawalsPaginationLast(t *testing.T) { 404 ctx := tempTransaction(t) 405 406 bs, ws, _ := setupWithdrawalStoreTests(t) 407 408 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 409 410 last := int32(3) 411 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 412 require.NoError(t, err) 413 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 414 415 require.NoError(t, err) 416 want := testWithdrawals[7:] 417 assert.Equal(t, want, got) 418 assert.Equal(t, entities.PageInfo{ 419 HasNextPage: false, 420 HasPreviousPage: true, 421 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 422 VegaTime: testWithdrawals[7].VegaTime, 423 ID: testWithdrawals[7].ID, 424 }.String()).Encode(), 425 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 426 VegaTime: testWithdrawals[9].VegaTime, 427 ID: testWithdrawals[9].ID, 428 }.String()).Encode(), 429 }, pageInfo) 430 } 431 432 func testWithdrawalsPaginationFirstAfter(t *testing.T) { 433 ctx := tempTransaction(t) 434 435 bs, ws, _ := setupWithdrawalStoreTests(t) 436 437 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 438 439 first := int32(3) 440 after := testWithdrawals[2].Cursor().Encode() 441 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 442 require.NoError(t, err) 443 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 444 445 require.NoError(t, err) 446 want := testWithdrawals[3:6] 447 assert.Equal(t, want, got) 448 assert.Equal(t, entities.PageInfo{ 449 HasNextPage: true, 450 HasPreviousPage: true, 451 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 452 VegaTime: testWithdrawals[3].VegaTime, 453 ID: testWithdrawals[3].ID, 454 }.String()).Encode(), 455 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 456 VegaTime: testWithdrawals[5].VegaTime, 457 ID: testWithdrawals[5].ID, 458 }.String()).Encode(), 459 }, pageInfo) 460 } 461 462 func testWithdrawalsPaginationLastBefore(t *testing.T) { 463 ctx := tempTransaction(t) 464 465 bs, ws, _ := setupWithdrawalStoreTests(t) 466 467 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 468 469 last := int32(3) 470 before := entities.NewCursor(entities.WithdrawalCursor{ 471 VegaTime: testWithdrawals[7].VegaTime, 472 ID: testWithdrawals[7].ID, 473 }.String()).Encode() 474 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 475 require.NoError(t, err) 476 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 477 478 require.NoError(t, err) 479 want := testWithdrawals[4:7] 480 assert.Equal(t, want, got) 481 assert.Equal(t, entities.PageInfo{ 482 HasNextPage: true, 483 HasPreviousPage: true, 484 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 485 VegaTime: testWithdrawals[4].VegaTime, 486 ID: testWithdrawals[4].ID, 487 }.String()).Encode(), 488 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 489 VegaTime: testWithdrawals[6].VegaTime, 490 ID: testWithdrawals[6].ID, 491 }.String()).Encode(), 492 }, pageInfo) 493 } 494 495 func testWithdrawalsPaginationNoPaginationNewestFirst(t *testing.T) { 496 ctx := tempTransaction(t) 497 498 bs, ws, _ := setupWithdrawalStoreTests(t) 499 500 testWithdrawals := entities.ReverseSlice(addWithdrawals(ctx, t, bs, ws)) 501 502 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 503 require.NoError(t, err) 504 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 505 506 require.NoError(t, err) 507 assert.Equal(t, testWithdrawals, got) 508 assert.Equal(t, entities.PageInfo{ 509 HasNextPage: false, 510 HasPreviousPage: false, 511 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 512 VegaTime: testWithdrawals[0].VegaTime, 513 ID: testWithdrawals[0].ID, 514 }.String()).Encode(), 515 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 516 VegaTime: testWithdrawals[9].VegaTime, 517 ID: testWithdrawals[9].ID, 518 }.String()).Encode(), 519 }, pageInfo) 520 } 521 522 func testWithdrawalsPaginationFirstNewestFirst(t *testing.T) { 523 ctx := tempTransaction(t) 524 525 bs, ws, _ := setupWithdrawalStoreTests(t) 526 527 testWithdrawals := entities.ReverseSlice(addWithdrawals(ctx, t, bs, ws)) 528 529 first := int32(3) 530 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 531 require.NoError(t, err) 532 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 533 534 require.NoError(t, err) 535 want := testWithdrawals[:3] 536 assert.Equal(t, want, got) 537 assert.Equal(t, entities.PageInfo{ 538 HasNextPage: true, 539 HasPreviousPage: false, 540 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 541 VegaTime: testWithdrawals[0].VegaTime, 542 ID: testWithdrawals[0].ID, 543 }.String()).Encode(), 544 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 545 VegaTime: testWithdrawals[2].VegaTime, 546 ID: testWithdrawals[2].ID, 547 }.String()).Encode(), 548 }, pageInfo) 549 } 550 551 func testWithdrawalsPaginationLastNewestFirst(t *testing.T) { 552 ctx := tempTransaction(t) 553 554 bs, ws, _ := setupWithdrawalStoreTests(t) 555 556 testWithdrawals := entities.ReverseSlice(addWithdrawals(ctx, t, bs, ws)) 557 558 last := int32(3) 559 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 560 require.NoError(t, err) 561 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 562 563 require.NoError(t, err) 564 want := testWithdrawals[7:] 565 assert.Equal(t, want, got) 566 assert.Equal(t, entities.PageInfo{ 567 HasNextPage: false, 568 HasPreviousPage: true, 569 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 570 VegaTime: testWithdrawals[7].VegaTime, 571 ID: testWithdrawals[7].ID, 572 }.String()).Encode(), 573 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 574 VegaTime: testWithdrawals[9].VegaTime, 575 ID: testWithdrawals[9].ID, 576 }.String()).Encode(), 577 }, pageInfo) 578 } 579 580 func testWithdrawalsPaginationFirstAfterNewestFirst(t *testing.T) { 581 ctx := tempTransaction(t) 582 583 bs, ws, _ := setupWithdrawalStoreTests(t) 584 585 testWithdrawals := entities.ReverseSlice(addWithdrawals(ctx, t, bs, ws)) 586 587 first := int32(3) 588 after := testWithdrawals[2].Cursor().Encode() 589 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 590 require.NoError(t, err) 591 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 592 593 require.NoError(t, err) 594 want := testWithdrawals[3:6] 595 assert.Equal(t, want, got) 596 assert.Equal(t, entities.PageInfo{ 597 HasNextPage: true, 598 HasPreviousPage: true, 599 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 600 VegaTime: testWithdrawals[3].VegaTime, 601 ID: testWithdrawals[3].ID, 602 }.String()).Encode(), 603 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 604 VegaTime: testWithdrawals[5].VegaTime, 605 ID: testWithdrawals[5].ID, 606 }.String()).Encode(), 607 }, pageInfo) 608 } 609 610 func testWithdrawalsPaginationLastBeforeNewestFirst(t *testing.T) { 611 ctx := tempTransaction(t) 612 613 bs, ws, _ := setupWithdrawalStoreTests(t) 614 615 testWithdrawals := entities.ReverseSlice(addWithdrawals(ctx, t, bs, ws)) 616 617 last := int32(3) 618 before := entities.NewCursor(entities.WithdrawalCursor{ 619 VegaTime: testWithdrawals[7].VegaTime, 620 ID: testWithdrawals[7].ID, 621 }.String()).Encode() 622 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 623 require.NoError(t, err) 624 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{}) 625 626 require.NoError(t, err) 627 want := testWithdrawals[4:7] 628 assert.Equal(t, want, got) 629 assert.Equal(t, entities.PageInfo{ 630 HasNextPage: true, 631 HasPreviousPage: true, 632 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 633 VegaTime: testWithdrawals[4].VegaTime, 634 ID: testWithdrawals[4].ID, 635 }.String()).Encode(), 636 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 637 VegaTime: testWithdrawals[6].VegaTime, 638 ID: testWithdrawals[6].ID, 639 }.String()).Encode(), 640 }, pageInfo) 641 } 642 643 func testWithdrawalsPaginationBetweenDatesNoPagination(t *testing.T) { 644 ctx := tempTransaction(t) 645 646 bs, ws, _ := setupWithdrawalStoreTests(t) 647 648 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 649 want := testWithdrawals[2:8] 650 651 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 652 require.NoError(t, err) 653 startDate := testWithdrawals[2].VegaTime 654 endDate := testWithdrawals[8].VegaTime 655 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 656 Start: &startDate, 657 End: &endDate, 658 }) 659 660 require.NoError(t, err) 661 assert.Equal(t, want, got) 662 assert.Equal(t, entities.PageInfo{ 663 HasNextPage: false, 664 HasPreviousPage: false, 665 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 666 VegaTime: want[0].VegaTime, 667 ID: want[0].ID, 668 }.String()).Encode(), 669 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 670 VegaTime: want[5].VegaTime, 671 ID: want[5].ID, 672 }.String()).Encode(), 673 }, pageInfo) 674 } 675 676 func testWithdrawalsPaginationBetweenDatesFirst(t *testing.T) { 677 ctx := tempTransaction(t) 678 679 bs, ws, _ := setupWithdrawalStoreTests(t) 680 681 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 682 want := testWithdrawals[2:8] 683 684 first := int32(3) 685 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 686 require.NoError(t, err) 687 startDate := testWithdrawals[2].VegaTime 688 endDate := testWithdrawals[8].VegaTime 689 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 690 Start: &startDate, 691 End: &endDate, 692 }) 693 694 require.NoError(t, err) 695 want = want[:3] 696 assert.Equal(t, want, got) 697 assert.Equal(t, entities.PageInfo{ 698 HasNextPage: true, 699 HasPreviousPage: false, 700 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 701 VegaTime: want[0].VegaTime, 702 ID: want[0].ID, 703 }.String()).Encode(), 704 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 705 VegaTime: want[2].VegaTime, 706 ID: want[2].ID, 707 }.String()).Encode(), 708 }, pageInfo) 709 } 710 711 func testWithdrawalsPaginationBetweenDatesLast(t *testing.T) { 712 ctx := tempTransaction(t) 713 714 bs, ws, _ := setupWithdrawalStoreTests(t) 715 716 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 717 want := testWithdrawals[2:8] 718 719 last := int32(3) 720 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 721 require.NoError(t, err) 722 startDate := testWithdrawals[2].VegaTime 723 endDate := testWithdrawals[8].VegaTime 724 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 725 Start: &startDate, 726 End: &endDate, 727 }) 728 729 require.NoError(t, err) 730 want = want[3:] 731 assert.Equal(t, want, got) 732 assert.Equal(t, entities.PageInfo{ 733 HasNextPage: false, 734 HasPreviousPage: true, 735 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 736 VegaTime: want[0].VegaTime, 737 ID: want[0].ID, 738 }.String()).Encode(), 739 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 740 VegaTime: want[2].VegaTime, 741 ID: want[2].ID, 742 }.String()).Encode(), 743 }, pageInfo) 744 } 745 746 func testWithdrawalsPaginationBetweenDatesFirstAfter(t *testing.T) { 747 ctx := tempTransaction(t) 748 749 bs, ws, _ := setupWithdrawalStoreTests(t) 750 751 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 752 want := testWithdrawals[2:8] 753 754 first := int32(3) 755 after := want[1].Cursor().Encode() 756 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 757 require.NoError(t, err) 758 startDate := testWithdrawals[2].VegaTime 759 endDate := testWithdrawals[8].VegaTime 760 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 761 Start: &startDate, 762 End: &endDate, 763 }) 764 765 require.NoError(t, err) 766 want = want[2:5] 767 assert.Equal(t, want, got) 768 assert.Equal(t, entities.PageInfo{ 769 HasNextPage: true, 770 HasPreviousPage: true, 771 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 772 VegaTime: want[0].VegaTime, 773 ID: want[0].ID, 774 }.String()).Encode(), 775 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 776 VegaTime: want[2].VegaTime, 777 ID: want[2].ID, 778 }.String()).Encode(), 779 }, pageInfo) 780 } 781 782 func testWithdrawalsPaginationBetweenDatesLastBefore(t *testing.T) { 783 ctx := tempTransaction(t) 784 785 bs, ws, _ := setupWithdrawalStoreTests(t) 786 787 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 788 want := testWithdrawals[2:8] 789 790 last := int32(3) 791 before := entities.NewCursor(entities.WithdrawalCursor{ 792 VegaTime: want[4].VegaTime, 793 ID: want[4].ID, 794 }.String()).Encode() 795 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 796 require.NoError(t, err) 797 startDate := testWithdrawals[2].VegaTime 798 endDate := testWithdrawals[8].VegaTime 799 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 800 Start: &startDate, 801 End: &endDate, 802 }) 803 804 require.NoError(t, err) 805 want = want[1:4] 806 assert.Equal(t, want, got) 807 assert.Equal(t, entities.PageInfo{ 808 HasNextPage: true, 809 HasPreviousPage: true, 810 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 811 VegaTime: want[0].VegaTime, 812 ID: want[0].ID, 813 }.String()).Encode(), 814 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 815 VegaTime: want[2].VegaTime, 816 ID: want[2].ID, 817 }.String()).Encode(), 818 }, pageInfo) 819 } 820 821 func testWithdrawalsPaginationBetweenDatesNoPaginationNewestFirst(t *testing.T) { 822 ctx := tempTransaction(t) 823 824 bs, ws, _ := setupWithdrawalStoreTests(t) 825 826 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 827 828 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 829 require.NoError(t, err) 830 startDate := testWithdrawals[2].VegaTime 831 endDate := testWithdrawals[8].VegaTime 832 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 833 Start: &startDate, 834 End: &endDate, 835 }) 836 837 want := entities.ReverseSlice(testWithdrawals[2:8]) 838 839 require.NoError(t, err) 840 assert.Equal(t, want, got) 841 assert.Equal(t, entities.PageInfo{ 842 HasNextPage: false, 843 HasPreviousPage: false, 844 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 845 VegaTime: want[0].VegaTime, 846 ID: want[0].ID, 847 }.String()).Encode(), 848 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 849 VegaTime: want[5].VegaTime, 850 ID: want[5].ID, 851 }.String()).Encode(), 852 }, pageInfo) 853 } 854 855 func testWithdrawalsPaginationBetweenDatesFirstNewestFirst(t *testing.T) { 856 ctx := tempTransaction(t) 857 858 bs, ws, _ := setupWithdrawalStoreTests(t) 859 860 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 861 want := entities.ReverseSlice(testWithdrawals[2:8]) 862 863 first := int32(3) 864 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 865 require.NoError(t, err) 866 startDate := testWithdrawals[2].VegaTime 867 endDate := testWithdrawals[8].VegaTime 868 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 869 Start: &startDate, 870 End: &endDate, 871 }) 872 873 require.NoError(t, err) 874 want = want[:3] 875 assert.Equal(t, want, got) 876 assert.Equal(t, entities.PageInfo{ 877 HasNextPage: true, 878 HasPreviousPage: false, 879 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 880 VegaTime: want[0].VegaTime, 881 ID: want[0].ID, 882 }.String()).Encode(), 883 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 884 VegaTime: want[2].VegaTime, 885 ID: want[2].ID, 886 }.String()).Encode(), 887 }, pageInfo) 888 } 889 890 func testWithdrawalsPaginationBetweenDatesLastNewestFirst(t *testing.T) { 891 ctx := tempTransaction(t) 892 893 bs, ws, _ := setupWithdrawalStoreTests(t) 894 895 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 896 want := entities.ReverseSlice(testWithdrawals[2:8]) 897 898 last := int32(3) 899 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 900 require.NoError(t, err) 901 startDate := testWithdrawals[2].VegaTime 902 endDate := testWithdrawals[8].VegaTime 903 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 904 Start: &startDate, 905 End: &endDate, 906 }) 907 908 require.NoError(t, err) 909 want = want[3:] 910 assert.Equal(t, want, got) 911 assert.Equal(t, entities.PageInfo{ 912 HasNextPage: false, 913 HasPreviousPage: true, 914 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 915 VegaTime: want[0].VegaTime, 916 ID: want[0].ID, 917 }.String()).Encode(), 918 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 919 VegaTime: want[2].VegaTime, 920 ID: want[2].ID, 921 }.String()).Encode(), 922 }, pageInfo) 923 } 924 925 func testWithdrawalsPaginationBetweenDatesFirstAfterNewestFirst(t *testing.T) { 926 ctx := tempTransaction(t) 927 928 bs, ws, _ := setupWithdrawalStoreTests(t) 929 930 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 931 want := entities.ReverseSlice(testWithdrawals[2:8]) 932 933 first := int32(3) 934 after := want[1].Cursor().Encode() 935 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 936 require.NoError(t, err) 937 startDate := testWithdrawals[2].VegaTime 938 endDate := testWithdrawals[8].VegaTime 939 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 940 Start: &startDate, 941 End: &endDate, 942 }) 943 944 require.NoError(t, err) 945 want = want[2:5] 946 assert.Equal(t, want, got) 947 assert.Equal(t, entities.PageInfo{ 948 HasNextPage: true, 949 HasPreviousPage: true, 950 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 951 VegaTime: want[0].VegaTime, 952 ID: want[0].ID, 953 }.String()).Encode(), 954 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 955 VegaTime: want[2].VegaTime, 956 ID: want[2].ID, 957 }.String()).Encode(), 958 }, pageInfo) 959 } 960 961 func testWithdrawalsPaginationBetweenDatesLastBeforeNewestFirst(t *testing.T) { 962 ctx := tempTransaction(t) 963 964 bs, ws, _ := setupWithdrawalStoreTests(t) 965 966 testWithdrawals := addWithdrawals(ctx, t, bs, ws) 967 want := entities.ReverseSlice(testWithdrawals[2:8]) 968 969 last := int32(3) 970 before := entities.NewCursor(entities.WithdrawalCursor{ 971 VegaTime: want[4].VegaTime, 972 ID: want[4].ID, 973 }.String()).Encode() 974 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 975 require.NoError(t, err) 976 startDate := testWithdrawals[2].VegaTime 977 endDate := testWithdrawals[8].VegaTime 978 got, pageInfo, err := ws.GetByParty(ctx, testID, false, pagination, entities.DateRange{ 979 Start: &startDate, 980 End: &endDate, 981 }) 982 983 require.NoError(t, err) 984 want = want[1:4] 985 assert.Equal(t, want, got) 986 assert.Equal(t, entities.PageInfo{ 987 HasNextPage: true, 988 HasPreviousPage: true, 989 StartCursor: entities.NewCursor(entities.WithdrawalCursor{ 990 VegaTime: want[0].VegaTime, 991 ID: want[0].ID, 992 }.String()).Encode(), 993 EndCursor: entities.NewCursor(entities.WithdrawalCursor{ 994 VegaTime: want[2].VegaTime, 995 ID: want[2].ID, 996 }.String()).Encode(), 997 }, pageInfo) 998 } 999 1000 func TestWithdrawalStatusEnum(t *testing.T) { 1001 var withdrawalStatus vega.Withdrawal_Status 1002 states := getEnums(t, withdrawalStatus) 1003 assert.Len(t, states, 4) 1004 for s, state := range states { 1005 t.Run(state, func(t *testing.T) { 1006 ctx := tempTransaction(t) 1007 1008 bs, ws, _ := setupWithdrawalStoreTests(t) 1009 1010 block := addTestBlock(t, ctx, bs) 1011 withdrawalProto := getTestWithdrawal(testID, testID, testID, testAmount, testID, block.VegaTime) 1012 withdrawalProto.Status = vega.Withdrawal_Status(s) 1013 1014 withdrawal, err := entities.WithdrawalFromProto(withdrawalProto, generateTxHash(), block.VegaTime) 1015 require.NoError(t, err, "Converting withdrawal proto to database entity") 1016 require.NoError(t, ws.Upsert(ctx, withdrawal)) 1017 got, err := ws.GetByTxHash(ctx, withdrawal.TxHash) 1018 require.NoError(t, err) 1019 assert.Len(t, got, 1) 1020 assert.Equal(t, withdrawal.Status, got[0].Status) 1021 }) 1022 } 1023 }