code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/parties_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 "testing" 21 "time" 22 23 "code.vegaprotocol.io/vega/datanode/entities" 24 "code.vegaprotocol.io/vega/datanode/sqlstore" 25 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func addTestParty(t *testing.T, ctx context.Context, ps *sqlstore.Parties, block entities.Block) entities.Party { 31 t.Helper() 32 party := entities.Party{ 33 ID: entities.PartyID(GenerateID()), 34 VegaTime: &block.VegaTime, 35 TxHash: generateTxHash(), 36 } 37 38 err := ps.Add(ctx, party) 39 require.NoError(t, err) 40 return party 41 } 42 43 func TestParty(t *testing.T) { 44 ctx := tempTransaction(t) 45 46 ps := sqlstore.NewParties(connectionSource) 47 ps.Initialise(ctx) 48 bs := sqlstore.NewBlocks(connectionSource) 49 block := addTestBlock(t, ctx, bs) 50 51 // Make sure we're starting with an empty set of parties (except network party) 52 parties, err := ps.GetAll(ctx) 53 require.NoError(t, err) 54 assert.Len(t, parties, 1) 55 assert.Equal(t, "network", parties[0].ID.String()) 56 57 // Make a new party 58 party := addTestParty(t, ctx, ps, block) 59 60 // Add it again, we shouldn't get a primary key violation (we just ignore) 61 err = ps.Add(ctx, party) 62 require.NoError(t, err) 63 64 // Query and check we've got back a party the same as the one we put in 65 fetchedParty, err := ps.GetByID(ctx, party.ID.String()) 66 require.NoError(t, err) 67 assert.Equal(t, party, fetchedParty) 68 69 // Get all assets and make sure ours is in there (along with built in network party) 70 parties, err = ps.GetAll(ctx) 71 require.NoError(t, err) 72 assert.Len(t, parties, 2) 73 74 // Check we get the right error if we ask for a non-existent party 75 _, err = ps.GetByID(ctx, "beef") 76 assert.ErrorIs(t, err, entities.ErrNotFound) 77 78 partiesByHash, err := ps.GetByTxHash(ctx, party.TxHash) 79 assert.NoError(t, err) 80 assert.Len(t, partiesByHash, 1) 81 assert.Equal(t, party, partiesByHash[0]) 82 } 83 84 func setupPartyTest(t *testing.T) (*sqlstore.Blocks, *sqlstore.Parties) { 85 t.Helper() 86 bs := sqlstore.NewBlocks(connectionSource) 87 pt := sqlstore.NewParties(connectionSource) 88 89 return bs, pt 90 } 91 92 func populateTestParties(ctx context.Context, t *testing.T, bs *sqlstore.Blocks, ps *sqlstore.Parties, blockTimes map[string]time.Time) { 93 t.Helper() 94 parties := []entities.Party{ 95 { 96 ID: entities.PartyID("02a16077"), 97 }, 98 { 99 ID: entities.PartyID("44eea1bc"), 100 }, 101 { 102 ID: entities.PartyID("65be62cd"), 103 }, 104 { 105 ID: entities.PartyID("7a797e0e"), 106 }, 107 { 108 ID: entities.PartyID("7bb2356e"), 109 }, 110 { 111 ID: entities.PartyID("b7c84b8e"), 112 }, 113 { 114 ID: entities.PartyID("c612300d"), 115 }, 116 { 117 ID: entities.PartyID("c8744329"), 118 }, 119 { 120 ID: entities.PartyID("da8d1803"), 121 }, 122 { 123 ID: entities.PartyID("fb1528a5"), 124 }, 125 } 126 127 source := &testBlockSource{bs, time.Now()} 128 for _, party := range parties { 129 block := source.getNextBlock(t, ctx) 130 party.VegaTime = &block.VegaTime 131 blockTimes[party.ID.String()] = block.VegaTime 132 err := ps.Add(ctx, party) 133 require.NoError(t, err) 134 } 135 } 136 137 func TestPartyPagination(t *testing.T) { 138 t.Run("CursorPagination should return the party if Party ID is provided", testPartyPaginationReturnsTheSpecifiedParty) 139 t.Run("CursorPagination should return all parties if no party ID and no cursor is provided", testPartyPaginationReturnAllParties) 140 t.Run("CursorPagination should return the first page when first limit is provided with no after cursor", testPartyPaginationReturnsFirstPage) 141 t.Run("CursorPagination should return the last page when last limit is provided with no before cursor", testPartyPaginationReturnsLastPage) 142 t.Run("CursorPagination should return the page specified by the first limit and after cursor", testPartyPaginationReturnsPageTraversingForward) 143 t.Run("CursorPagination should return the page specified by the last limit and before cursor", testPartyPaginationReturnsPageTraversingBackward) 144 145 t.Run("CursorPagination should return the party if Party ID is provided - newest first", testPartyPaginationReturnsTheSpecifiedPartyNewestFirst) 146 t.Run("CursorPagination should return all parties if no party ID and no cursor is provided - newest first", testPartyPaginationReturnAllPartiesNewestFirst) 147 t.Run("CursorPagination should return the first page when first limit is provided with no after cursor - newest first", testPartyPaginationReturnsFirstPageNewestFirst) 148 t.Run("CursorPagination should return the last page when last limit is provided with no before cursor - newest first", testPartyPaginationReturnsLastPageNewestFirst) 149 t.Run("CursorPagination should return the page specified by the first limit and after cursor - newest first", testPartyPaginationReturnsPageTraversingForwardNewestFirst) 150 t.Run("CursorPagination should return the page specified by the last limit and before cursor - newest first", testPartyPaginationReturnsPageTraversingBackwardNewestFirst) 151 } 152 153 func testPartyPaginationReturnsTheSpecifiedParty(t *testing.T) { 154 bs, pt := setupPartyTest(t) 155 ctx := tempTransaction(t) 156 157 blockTimes := make(map[string]time.Time) 158 populateTestParties(ctx, t, bs, pt, blockTimes) 159 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 160 require.NoError(t, err) 161 got, pageInfo, err := pt.GetAllPaged(ctx, "c612300d", pagination) 162 require.NoError(t, err) 163 assert.Len(t, got, 1) 164 assert.Equal(t, "c612300d", got[0].ID.String()) 165 166 vegaTime := blockTimes["c612300d"] 167 party := entities.Party{ 168 ID: "c612300d", 169 VegaTime: &vegaTime, 170 }.String() 171 wantStartCursor := entities.NewCursor(party).Encode() 172 wantEndCursor := entities.NewCursor(party).Encode() 173 assert.Equal(t, entities.PageInfo{ 174 HasNextPage: false, 175 HasPreviousPage: false, 176 StartCursor: wantStartCursor, 177 EndCursor: wantEndCursor, 178 }, pageInfo) 179 } 180 181 func testPartyPaginationReturnAllParties(t *testing.T) { 182 bs, pt := setupPartyTest(t) 183 ctx := tempTransaction(t) 184 185 blockTimes := make(map[string]time.Time) 186 populateTestParties(ctx, t, bs, pt, blockTimes) 187 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 188 require.NoError(t, err) 189 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 190 require.NoError(t, err) 191 assert.Len(t, got, 10) 192 assert.Equal(t, "02a16077", got[0].ID.String()) 193 assert.Equal(t, "fb1528a5", got[9].ID.String()) 194 195 startVegaTime := blockTimes["02a16077"] 196 startParty := entities.Party{ 197 ID: "02a16077", 198 VegaTime: &startVegaTime, 199 }.String() 200 endVegaTime := blockTimes["fb1528a5"] 201 endParty := entities.Party{ 202 ID: "fb1528a5", 203 VegaTime: &endVegaTime, 204 }.String() 205 wantStartCursor := entities.NewCursor(startParty).Encode() 206 wantEndCursor := entities.NewCursor(endParty).Encode() 207 assert.Equal(t, entities.PageInfo{ 208 HasNextPage: false, 209 HasPreviousPage: false, 210 StartCursor: wantStartCursor, 211 EndCursor: wantEndCursor, 212 }, pageInfo) 213 } 214 215 func testPartyPaginationReturnsFirstPage(t *testing.T) { 216 bs, pt := setupPartyTest(t) 217 ctx := tempTransaction(t) 218 219 blockTimes := make(map[string]time.Time) 220 populateTestParties(ctx, t, bs, pt, blockTimes) 221 first := int32(3) 222 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 223 require.NoError(t, err) 224 225 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 226 require.NoError(t, err) 227 assert.Len(t, got, 3) 228 assert.Equal(t, "02a16077", got[0].ID.String()) 229 assert.Equal(t, "65be62cd", got[2].ID.String()) 230 231 startVegaTime := blockTimes["02a16077"] 232 startParty := entities.Party{ 233 ID: "02a16077", 234 VegaTime: &startVegaTime, 235 }.String() 236 endVegaTime := blockTimes["65be62cd"] 237 endParty := entities.Party{ 238 ID: "65be62cd", 239 VegaTime: &endVegaTime, 240 }.String() 241 wantStartCursor := entities.NewCursor(startParty).Encode() 242 wantEndCursor := entities.NewCursor(endParty).Encode() 243 assert.Equal(t, entities.PageInfo{ 244 HasNextPage: true, 245 HasPreviousPage: false, 246 StartCursor: wantStartCursor, 247 EndCursor: wantEndCursor, 248 }, pageInfo) 249 } 250 251 func testPartyPaginationReturnsLastPage(t *testing.T) { 252 bs, pt := setupPartyTest(t) 253 ctx := tempTransaction(t) 254 255 blockTimes := make(map[string]time.Time) 256 populateTestParties(ctx, t, bs, pt, blockTimes) 257 last := int32(3) 258 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 259 require.NoError(t, err) 260 261 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 262 require.NoError(t, err) 263 assert.Len(t, got, 3) 264 assert.Equal(t, "c8744329", got[0].ID.String()) 265 assert.Equal(t, "fb1528a5", got[2].ID.String()) 266 267 startVegaTime := blockTimes["c8744329"] 268 startParty := entities.Party{ 269 ID: "c8744329", 270 VegaTime: &startVegaTime, 271 }.String() 272 endVegaTime := blockTimes["fb1528a5"] 273 endParty := entities.Party{ 274 ID: "fb1528a5", 275 VegaTime: &endVegaTime, 276 }.String() 277 wantStartCursor := entities.NewCursor(startParty).Encode() 278 wantEndCursor := entities.NewCursor(endParty).Encode() 279 assert.Equal(t, entities.PageInfo{ 280 HasNextPage: false, 281 HasPreviousPage: true, 282 StartCursor: wantStartCursor, 283 EndCursor: wantEndCursor, 284 }, pageInfo) 285 } 286 287 func testPartyPaginationReturnsPageTraversingForward(t *testing.T) { 288 bs, pt := setupPartyTest(t) 289 ctx := tempTransaction(t) 290 291 blockTimes := make(map[string]time.Time) 292 populateTestParties(ctx, t, bs, pt, blockTimes) 293 first := int32(3) 294 afterVegaTime := blockTimes["65be62cd"] 295 afterParty := entities.Party{ 296 ID: "65be62cd", 297 VegaTime: &afterVegaTime, 298 }.String() 299 after := entities.NewCursor(afterParty).Encode() 300 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 301 require.NoError(t, err) 302 303 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 304 require.NoError(t, err) 305 assert.Len(t, got, 3) 306 assert.Equal(t, "7a797e0e", got[0].ID.String()) 307 assert.Equal(t, "b7c84b8e", got[2].ID.String()) 308 309 startVegaTime := blockTimes["7a797e0e"] 310 startParty := entities.Party{ 311 ID: "7a797e0e", 312 VegaTime: &startVegaTime, 313 }.String() 314 endVegaTime := blockTimes["b7c84b8e"] 315 endParty := entities.Party{ 316 ID: "b7c84b8e", 317 VegaTime: &endVegaTime, 318 }.String() 319 wantStartCursor := entities.NewCursor(startParty).Encode() 320 wantEndCursor := entities.NewCursor(endParty).Encode() 321 assert.Equal(t, entities.PageInfo{ 322 HasNextPage: true, 323 HasPreviousPage: true, 324 StartCursor: wantStartCursor, 325 EndCursor: wantEndCursor, 326 }, pageInfo) 327 } 328 329 func testPartyPaginationReturnsPageTraversingBackward(t *testing.T) { 330 bs, pt := setupPartyTest(t) 331 ctx := tempTransaction(t) 332 333 blockTimes := make(map[string]time.Time) 334 populateTestParties(ctx, t, bs, pt, blockTimes) 335 last := int32(3) 336 beforeVegaTime := blockTimes["c8744329"] 337 beforeParty := entities.Party{ 338 ID: "c8744329", 339 VegaTime: &beforeVegaTime, 340 }.String() 341 before := entities.NewCursor(beforeParty).Encode() 342 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 343 require.NoError(t, err) 344 345 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 346 require.NoError(t, err) 347 assert.Len(t, got, 3) 348 assert.Equal(t, "7bb2356e", got[0].ID.String()) 349 assert.Equal(t, "c612300d", got[2].ID.String()) 350 351 startVegaTime := blockTimes["7bb2356e"] 352 startParty := entities.Party{ 353 ID: "7bb2356e", 354 VegaTime: &startVegaTime, 355 }.String() 356 endVegaTime := blockTimes["c612300d"] 357 endParty := entities.Party{ 358 ID: "c612300d", 359 VegaTime: &endVegaTime, 360 }.String() 361 wantStartCursor := entities.NewCursor(startParty).Encode() 362 wantEndCursor := entities.NewCursor(endParty).Encode() 363 assert.Equal(t, entities.PageInfo{ 364 HasNextPage: true, 365 HasPreviousPage: true, 366 StartCursor: wantStartCursor, 367 EndCursor: wantEndCursor, 368 }, pageInfo) 369 } 370 371 func testPartyPaginationReturnsTheSpecifiedPartyNewestFirst(t *testing.T) { 372 bs, pt := setupPartyTest(t) 373 ctx := tempTransaction(t) 374 375 blockTimes := make(map[string]time.Time) 376 populateTestParties(ctx, t, bs, pt, blockTimes) 377 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 378 require.NoError(t, err) 379 got, pageInfo, err := pt.GetAllPaged(ctx, "c612300d", pagination) 380 require.NoError(t, err) 381 assert.Len(t, got, 1) 382 assert.Equal(t, "c612300d", got[0].ID.String()) 383 384 startVegaTime := blockTimes["c612300d"] 385 startParty := entities.Party{ 386 ID: "c612300d", 387 VegaTime: &startVegaTime, 388 }.String() 389 endVegaTime := blockTimes["c612300d"] 390 endParty := entities.Party{ 391 ID: "c612300d", 392 VegaTime: &endVegaTime, 393 }.String() 394 wantStartCursor := entities.NewCursor(startParty).Encode() 395 wantEndCursor := entities.NewCursor(endParty).Encode() 396 assert.Equal(t, entities.PageInfo{ 397 HasNextPage: false, 398 HasPreviousPage: false, 399 StartCursor: wantStartCursor, 400 EndCursor: wantEndCursor, 401 }, pageInfo) 402 } 403 404 func testPartyPaginationReturnAllPartiesNewestFirst(t *testing.T) { 405 bs, pt := setupPartyTest(t) 406 ctx := tempTransaction(t) 407 408 blockTimes := make(map[string]time.Time) 409 populateTestParties(ctx, t, bs, pt, blockTimes) 410 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 411 require.NoError(t, err) 412 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 413 require.NoError(t, err) 414 assert.Len(t, got, 10) 415 assert.Equal(t, "fb1528a5", got[0].ID.String()) 416 assert.Equal(t, "02a16077", got[9].ID.String()) 417 418 startVegaTime := blockTimes["fb1528a5"] 419 startParty := entities.Party{ 420 ID: "fb1528a5", 421 VegaTime: &startVegaTime, 422 }.String() 423 endVegaTime := blockTimes["02a16077"] 424 endParty := entities.Party{ 425 ID: "02a16077", 426 VegaTime: &endVegaTime, 427 }.String() 428 wantStartCursor := entities.NewCursor(startParty).Encode() 429 wantEndCursor := entities.NewCursor(endParty).Encode() 430 assert.Equal(t, entities.PageInfo{ 431 HasNextPage: false, 432 HasPreviousPage: false, 433 StartCursor: wantStartCursor, 434 EndCursor: wantEndCursor, 435 }, pageInfo) 436 } 437 438 func testPartyPaginationReturnsFirstPageNewestFirst(t *testing.T) { 439 bs, pt := setupPartyTest(t) 440 ctx := tempTransaction(t) 441 442 blockTimes := make(map[string]time.Time) 443 populateTestParties(ctx, t, bs, pt, blockTimes) 444 first := int32(3) 445 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 446 require.NoError(t, err) 447 448 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 449 require.NoError(t, err) 450 assert.Len(t, got, 3) 451 assert.Equal(t, "fb1528a5", got[0].ID.String()) 452 assert.Equal(t, "c8744329", got[2].ID.String()) 453 454 startVegaTime := blockTimes["fb1528a5"] 455 startParty := entities.Party{ 456 ID: "fb1528a5", 457 VegaTime: &startVegaTime, 458 }.String() 459 endVegaTime := blockTimes["c8744329"] 460 endParty := entities.Party{ 461 ID: "c8744329", 462 VegaTime: &endVegaTime, 463 }.String() 464 wantStartCursor := entities.NewCursor(startParty).Encode() 465 wantEndCursor := entities.NewCursor(endParty).Encode() 466 assert.Equal(t, entities.PageInfo{ 467 HasNextPage: true, 468 HasPreviousPage: false, 469 StartCursor: wantStartCursor, 470 EndCursor: wantEndCursor, 471 }, pageInfo) 472 } 473 474 func testPartyPaginationReturnsLastPageNewestFirst(t *testing.T) { 475 bs, pt := setupPartyTest(t) 476 ctx := tempTransaction(t) 477 478 blockTimes := make(map[string]time.Time) 479 populateTestParties(ctx, t, bs, pt, blockTimes) 480 last := int32(3) 481 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 482 require.NoError(t, err) 483 484 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 485 require.NoError(t, err) 486 assert.Len(t, got, 3) 487 assert.Equal(t, "65be62cd", got[0].ID.String()) 488 assert.Equal(t, "02a16077", got[2].ID.String()) 489 490 startVegaTime := blockTimes["65be62cd"] 491 startParty := entities.Party{ 492 ID: "65be62cd", 493 VegaTime: &startVegaTime, 494 }.String() 495 endVegaTime := blockTimes["02a16077"] 496 endParty := entities.Party{ 497 ID: "02a16077", 498 VegaTime: &endVegaTime, 499 }.String() 500 wantStartCursor := entities.NewCursor(startParty).Encode() 501 wantEndCursor := entities.NewCursor(endParty).Encode() 502 assert.Equal(t, entities.PageInfo{ 503 HasNextPage: false, 504 HasPreviousPage: true, 505 StartCursor: wantStartCursor, 506 EndCursor: wantEndCursor, 507 }, pageInfo) 508 } 509 510 func testPartyPaginationReturnsPageTraversingForwardNewestFirst(t *testing.T) { 511 bs, pt := setupPartyTest(t) 512 ctx := tempTransaction(t) 513 514 blockTimes := make(map[string]time.Time) 515 populateTestParties(ctx, t, bs, pt, blockTimes) 516 first := int32(3) 517 afterVegaTime := blockTimes["c8744329"] 518 afterParty := entities.Party{ 519 ID: "c8744329", 520 VegaTime: &afterVegaTime, 521 }.String() 522 after := entities.NewCursor(afterParty).Encode() 523 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 524 require.NoError(t, err) 525 526 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 527 require.NoError(t, err) 528 assert.Len(t, got, 3) 529 assert.Equal(t, "c612300d", got[0].ID.String()) 530 assert.Equal(t, "7bb2356e", got[2].ID.String()) 531 532 startVegaTime := blockTimes["c612300d"] 533 startParty := entities.Party{ 534 ID: "c612300d", 535 VegaTime: &startVegaTime, 536 }.String() 537 endVegaTime := blockTimes["7bb2356e"] 538 endParty := entities.Party{ 539 ID: "7bb2356e", 540 VegaTime: &endVegaTime, 541 }.String() 542 wantStartCursor := entities.NewCursor(startParty).Encode() 543 wantEndCursor := entities.NewCursor(endParty).Encode() 544 assert.Equal(t, entities.PageInfo{ 545 HasNextPage: true, 546 HasPreviousPage: true, 547 StartCursor: wantStartCursor, 548 EndCursor: wantEndCursor, 549 }, pageInfo) 550 } 551 552 func testPartyPaginationReturnsPageTraversingBackwardNewestFirst(t *testing.T) { 553 bs, pt := setupPartyTest(t) 554 ctx := tempTransaction(t) 555 556 blockTimes := make(map[string]time.Time) 557 populateTestParties(ctx, t, bs, pt, blockTimes) 558 last := int32(3) 559 beforeVegaTime := blockTimes["65be62cd"] 560 beforeParty := entities.Party{ 561 ID: "65be62cd", 562 VegaTime: &beforeVegaTime, 563 }.String() 564 before := entities.NewCursor(beforeParty).Encode() 565 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 566 require.NoError(t, err) 567 568 got, pageInfo, err := pt.GetAllPaged(ctx, "", pagination) 569 require.NoError(t, err) 570 assert.Len(t, got, 3) 571 assert.Equal(t, "b7c84b8e", got[0].ID.String()) 572 assert.Equal(t, "7a797e0e", got[2].ID.String()) 573 574 startVegaTime := blockTimes["b7c84b8e"] 575 startParty := entities.Party{ 576 ID: "b7c84b8e", 577 VegaTime: &startVegaTime, 578 }.String() 579 endVegaTime := blockTimes["7a797e0e"] 580 endParty := entities.Party{ 581 ID: "7a797e0e", 582 VegaTime: &endVegaTime, 583 }.String() 584 wantStartCursor := entities.NewCursor(startParty).Encode() 585 wantEndCursor := entities.NewCursor(endParty).Encode() 586 assert.Equal(t, entities.PageInfo{ 587 HasNextPage: true, 588 HasPreviousPage: true, 589 StartCursor: wantStartCursor, 590 EndCursor: wantEndCursor, 591 }, pageInfo) 592 }