github.com/prysmaticlabs/prysm@v1.4.4/slasher/db/kv/indexed_attestations_test.go (about) 1 package kv 2 3 import ( 4 "context" 5 "testing" 6 7 types "github.com/prysmaticlabs/eth2-types" 8 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 9 "github.com/prysmaticlabs/prysm/shared/testutil/require" 10 ) 11 12 type testStruct struct { 13 idxAtt *ethpb.IndexedAttestation 14 } 15 16 var tests []testStruct 17 18 func init() { 19 tests = []testStruct{ 20 { 21 idxAtt: ðpb.IndexedAttestation{ 22 AttestingIndices: []uint64{0}, 23 Data: ðpb.AttestationData{ 24 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 25 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 26 }, 27 Signature: []byte{1, 2}, 28 }, 29 }, 30 { 31 idxAtt: ðpb.IndexedAttestation{ 32 AttestingIndices: []uint64{1, 2}, 33 Data: ðpb.AttestationData{ 34 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 35 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 36 }, 37 Signature: []byte{3, 4}, 38 }, 39 }, 40 { 41 idxAtt: ðpb.IndexedAttestation{ 42 AttestingIndices: []uint64{0}, 43 Data: ðpb.AttestationData{ 44 Source: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 45 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 46 }, 47 Signature: []byte{5, 6}, 48 }, 49 }, 50 { 51 idxAtt: ðpb.IndexedAttestation{ 52 AttestingIndices: []uint64{0}, 53 Data: ðpb.AttestationData{ 54 Source: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 55 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 56 }, 57 Signature: []byte{5, 6}, 58 }, 59 }, 60 } 61 } 62 63 func TestHasIndexedAttestation_NilDB(t *testing.T) { 64 db := setupDB(t) 65 ctx := context.Background() 66 67 hasIdxAtt, err := db.HasIndexedAttestation(ctx, tests[0].idxAtt) 68 require.NoError(t, err) 69 require.Equal(t, false, hasIdxAtt) 70 } 71 72 func TestSaveIndexedAttestation(t *testing.T) { 73 db := setupDB(t) 74 ctx := context.Background() 75 76 for _, tt := range tests { 77 require.NoError(t, db.SaveIndexedAttestation(ctx, tt.idxAtt), "Save indexed attestation failed") 78 79 exists, err := db.HasIndexedAttestation(ctx, tt.idxAtt) 80 require.NoError(t, err, "Failed to get indexed attestation") 81 require.Equal(t, true, exists, "Expected to find saved attestation in DB") 82 } 83 } 84 85 func TestIndexedAttestationsWithPrefix(t *testing.T) { 86 type prefixTestStruct struct { 87 name string 88 attsInDB []*ethpb.IndexedAttestation 89 targetEpoch types.Epoch 90 searchPrefix []byte 91 expectedResult []*ethpb.IndexedAttestation 92 } 93 prefixTests := []prefixTestStruct{ 94 { 95 name: "single item, same sig, should find one", 96 attsInDB: []*ethpb.IndexedAttestation{ 97 { 98 AttestingIndices: []uint64{0}, 99 Data: ðpb.AttestationData{ 100 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 101 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 102 }, 103 Signature: []byte{1, 2}, 104 }, 105 }, 106 searchPrefix: []byte{1, 2}, 107 targetEpoch: 1, 108 expectedResult: []*ethpb.IndexedAttestation{ 109 { 110 AttestingIndices: []uint64{0}, 111 Data: ðpb.AttestationData{ 112 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 113 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 114 }, 115 Signature: []byte{1, 2}, 116 }, 117 }, 118 }, 119 { 120 name: "multiple item, same sig, should find 3", 121 attsInDB: []*ethpb.IndexedAttestation{ 122 { 123 AttestingIndices: []uint64{0}, 124 Data: ðpb.AttestationData{ 125 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 126 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 127 BeaconBlockRoot: []byte("hi there"), 128 }, 129 Signature: []byte{1, 2, 3}, 130 }, 131 { 132 AttestingIndices: []uint64{1}, 133 Data: ðpb.AttestationData{ 134 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 135 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 136 BeaconBlockRoot: []byte("hi there 2"), 137 }, 138 Signature: []byte{1, 2, 4}, 139 }, 140 { 141 AttestingIndices: []uint64{0}, 142 Data: ðpb.AttestationData{ 143 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 144 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 145 BeaconBlockRoot: []byte("hi there 3"), 146 }, 147 Signature: []byte{1, 2, 5}, 148 }, 149 }, 150 searchPrefix: []byte{1, 2}, 151 targetEpoch: 1, 152 expectedResult: []*ethpb.IndexedAttestation{ 153 { 154 AttestingIndices: []uint64{0}, 155 Data: ðpb.AttestationData{ 156 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 157 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 158 BeaconBlockRoot: []byte("hi there"), 159 }, 160 Signature: []byte{1, 2, 3}, 161 }, 162 { 163 AttestingIndices: []uint64{1}, 164 Data: ðpb.AttestationData{ 165 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 166 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 167 BeaconBlockRoot: []byte("hi there 2"), 168 }, 169 Signature: []byte{1, 2, 4}, 170 }, 171 { 172 AttestingIndices: []uint64{0}, 173 Data: ðpb.AttestationData{ 174 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 175 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 176 BeaconBlockRoot: []byte("hi there 3"), 177 }, 178 Signature: []byte{1, 2, 5}, 179 }, 180 }, 181 }, 182 { 183 name: "multiple items, different sig and epoch, should find 2", 184 attsInDB: []*ethpb.IndexedAttestation{ 185 { 186 AttestingIndices: []uint64{0}, 187 Data: ðpb.AttestationData{ 188 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 189 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 190 BeaconBlockRoot: []byte("hi there"), 191 }, 192 Signature: []byte{1, 2, 3}, 193 }, 194 { 195 AttestingIndices: []uint64{1}, 196 Data: ðpb.AttestationData{ 197 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 198 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 199 BeaconBlockRoot: []byte("hi there"), 200 }, 201 Signature: []byte{1, 2, 4}, 202 }, 203 { 204 AttestingIndices: []uint64{0}, 205 Data: ðpb.AttestationData{ 206 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 207 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 208 BeaconBlockRoot: []byte("hi there 3"), 209 }, 210 Signature: []byte{1, 2, 5}, 211 }, 212 { 213 AttestingIndices: []uint64{1}, 214 Data: ðpb.AttestationData{ 215 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 216 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 217 BeaconBlockRoot: []byte("hi there 2"), 218 }, 219 Signature: []byte{1, 3, 1}, 220 }, 221 { 222 AttestingIndices: []uint64{1}, 223 Data: ðpb.AttestationData{ 224 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 225 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 226 BeaconBlockRoot: []byte("hi there 2"), 227 }, 228 Signature: []byte{0, 2, 4}, 229 }, 230 { 231 AttestingIndices: []uint64{4}, 232 Data: ðpb.AttestationData{ 233 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 234 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 235 BeaconBlockRoot: []byte("hi there 2"), 236 }, 237 Signature: []byte{1, 2, 9}, 238 }, 239 }, 240 searchPrefix: []byte{1, 2}, 241 targetEpoch: 2, 242 expectedResult: []*ethpb.IndexedAttestation{ 243 { 244 AttestingIndices: []uint64{1}, 245 Data: ðpb.AttestationData{ 246 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 247 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 248 BeaconBlockRoot: []byte("hi there"), 249 }, 250 Signature: []byte{1, 2, 4}, 251 }, 252 { 253 AttestingIndices: []uint64{4}, 254 Data: ðpb.AttestationData{ 255 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 256 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 257 BeaconBlockRoot: []byte("hi there 2"), 258 }, 259 Signature: []byte{1, 2, 9}, 260 }, 261 }, 262 }, 263 { 264 name: "multiple items, different sigs, should not find any atts", 265 attsInDB: []*ethpb.IndexedAttestation{ 266 { 267 AttestingIndices: []uint64{0}, 268 Data: ðpb.AttestationData{ 269 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 270 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 271 BeaconBlockRoot: []byte("hi there"), 272 }, 273 Signature: []byte{3, 5, 3}, 274 }, 275 { 276 AttestingIndices: []uint64{0}, 277 Data: ðpb.AttestationData{ 278 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 279 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 280 BeaconBlockRoot: []byte("hi there"), 281 }, 282 Signature: []byte{3, 5, 3}, 283 }, 284 { 285 AttestingIndices: []uint64{1}, 286 Data: ðpb.AttestationData{ 287 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 288 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 289 BeaconBlockRoot: []byte("hi there 2"), 290 }, 291 Signature: []byte{1, 2, 4}, 292 }, 293 { 294 AttestingIndices: []uint64{0}, 295 Data: ðpb.AttestationData{ 296 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 297 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 298 BeaconBlockRoot: []byte("hi there 3"), 299 }, 300 Signature: []byte{1, 2, 5}, 301 }, 302 }, 303 searchPrefix: []byte{3, 5}, 304 targetEpoch: 1, 305 }, 306 } 307 for _, tt := range prefixTests { 308 t.Run(tt.name, func(t *testing.T) { 309 db := setupDB(t) 310 ctx := context.Background() 311 312 require.NoError(t, db.SaveIndexedAttestations(ctx, tt.attsInDB), "Save indexed attestation failed") 313 for _, att := range tt.attsInDB { 314 found, err := db.HasIndexedAttestation(ctx, att) 315 require.NoError(t, err) 316 require.Equal(t, true, found, "Expected to save %v", att) 317 } 318 319 idxAtts, err := db.IndexedAttestationsWithPrefix(ctx, tt.targetEpoch, tt.searchPrefix) 320 require.NoError(t, err, "Failed to get indexed attestation") 321 require.DeepSSZEqual(t, tt.expectedResult, idxAtts) 322 }) 323 } 324 } 325 326 func TestIndexedAttestationsForTarget(t *testing.T) { 327 type prefixTestStruct struct { 328 name string 329 attsInDB []*ethpb.IndexedAttestation 330 targetEpoch types.Epoch 331 expectedResult []*ethpb.IndexedAttestation 332 } 333 prefixTests := []prefixTestStruct{ 334 { 335 name: "single item, should find one", 336 attsInDB: []*ethpb.IndexedAttestation{ 337 { 338 AttestingIndices: []uint64{0}, 339 Data: ðpb.AttestationData{ 340 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 341 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 342 }, 343 Signature: []byte{1, 2}, 344 }, 345 }, 346 targetEpoch: 1, 347 expectedResult: []*ethpb.IndexedAttestation{ 348 { 349 AttestingIndices: []uint64{0}, 350 Data: ðpb.AttestationData{ 351 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 352 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 353 }, 354 Signature: []byte{1, 2}, 355 }, 356 }, 357 }, 358 { 359 name: "multiple items, same epoch, should find 3", 360 attsInDB: []*ethpb.IndexedAttestation{ 361 { 362 AttestingIndices: []uint64{0}, 363 Data: ðpb.AttestationData{ 364 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 365 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 366 BeaconBlockRoot: []byte("hi there"), 367 }, 368 Signature: []byte{1, 2, 3}, 369 }, 370 { 371 AttestingIndices: []uint64{1}, 372 Data: ðpb.AttestationData{ 373 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 374 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 375 BeaconBlockRoot: []byte("hi there 2"), 376 }, 377 Signature: []byte{1, 5, 4}, 378 }, 379 { 380 AttestingIndices: []uint64{0}, 381 Data: ðpb.AttestationData{ 382 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 383 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 384 BeaconBlockRoot: []byte("hi there 3"), 385 }, 386 Signature: []byte{8, 2, 5}, 387 }, 388 }, 389 targetEpoch: 3, 390 expectedResult: []*ethpb.IndexedAttestation{ 391 { 392 AttestingIndices: []uint64{0}, 393 Data: ðpb.AttestationData{ 394 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 395 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 396 BeaconBlockRoot: []byte("hi there"), 397 }, 398 Signature: []byte{1, 2, 3}, 399 }, 400 { 401 AttestingIndices: []uint64{1}, 402 Data: ðpb.AttestationData{ 403 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 404 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 405 BeaconBlockRoot: []byte("hi there 2"), 406 }, 407 Signature: []byte{1, 5, 4}, 408 }, 409 { 410 AttestingIndices: []uint64{0}, 411 Data: ðpb.AttestationData{ 412 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 413 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 414 BeaconBlockRoot: []byte("hi there 3"), 415 }, 416 Signature: []byte{8, 2, 5}, 417 }, 418 }, 419 }, 420 { 421 name: "multiple items, different epochs, should not find any atts", 422 attsInDB: []*ethpb.IndexedAttestation{ 423 { 424 AttestingIndices: []uint64{0}, 425 Data: ðpb.AttestationData{ 426 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 427 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 428 BeaconBlockRoot: []byte("hi there"), 429 }, 430 Signature: []byte{3, 5, 3}, 431 }, 432 { 433 AttestingIndices: []uint64{0}, 434 Data: ðpb.AttestationData{ 435 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 436 Target: ðpb.Checkpoint{Epoch: 2, Root: make([]byte, 32)}, 437 BeaconBlockRoot: []byte("hi there"), 438 }, 439 Signature: []byte{3, 5, 3}, 440 }, 441 { 442 AttestingIndices: []uint64{1}, 443 Data: ðpb.AttestationData{ 444 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 445 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 446 BeaconBlockRoot: []byte("hi there 2"), 447 }, 448 Signature: []byte{1, 2, 4}, 449 }, 450 { 451 AttestingIndices: []uint64{0}, 452 Data: ðpb.AttestationData{ 453 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 454 Target: ðpb.Checkpoint{Epoch: 5, Root: make([]byte, 32)}, 455 BeaconBlockRoot: []byte("hi there 3"), 456 }, 457 Signature: []byte{1, 2, 5}, 458 }, 459 }, 460 targetEpoch: 4, 461 }, 462 } 463 for _, tt := range prefixTests { 464 t.Run(tt.name, func(t *testing.T) { 465 db := setupDB(t) 466 ctx := context.Background() 467 468 require.NoError(t, db.SaveIndexedAttestations(ctx, tt.attsInDB), "Save indexed attestation failed") 469 for _, att := range tt.attsInDB { 470 found, err := db.HasIndexedAttestation(ctx, att) 471 require.NoError(t, err) 472 require.Equal(t, true, found, "Expected to save %v", att) 473 } 474 475 idxAtts, err := db.IndexedAttestationsForTarget(ctx, tt.targetEpoch) 476 require.NoError(t, err, "Failed to get indexed attestation: %v", err) 477 require.DeepSSZEqual(t, tt.expectedResult, idxAtts) 478 }) 479 } 480 } 481 482 func TestDeleteIndexedAttestation(t *testing.T) { 483 type deleteTestStruct struct { 484 name string 485 attsInDB []*ethpb.IndexedAttestation 486 deleteAtts []*ethpb.IndexedAttestation 487 foundArray []bool 488 } 489 deleteTests := []deleteTestStruct{ 490 { 491 name: "single item, should delete all", 492 attsInDB: []*ethpb.IndexedAttestation{ 493 { 494 AttestingIndices: []uint64{0}, 495 Data: ðpb.AttestationData{ 496 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 497 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 498 }, 499 Signature: []byte{1, 2}, 500 }, 501 }, 502 deleteAtts: []*ethpb.IndexedAttestation{ 503 { 504 AttestingIndices: []uint64{0}, 505 Data: ðpb.AttestationData{ 506 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 507 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 508 }, 509 Signature: []byte{1, 2}, 510 }, 511 }, 512 foundArray: []bool{false}, 513 }, 514 { 515 name: "multiple items, should delete 2", 516 attsInDB: []*ethpb.IndexedAttestation{ 517 { 518 AttestingIndices: []uint64{0}, 519 Data: ðpb.AttestationData{ 520 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 521 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 522 }, 523 Signature: []byte{1, 2}, 524 }, 525 { 526 AttestingIndices: []uint64{0}, 527 Data: ðpb.AttestationData{ 528 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 529 Target: ðpb.Checkpoint{Epoch: 3, Root: make([]byte, 32)}, 530 }, 531 Signature: []byte{2, 4}, 532 }, 533 { 534 AttestingIndices: []uint64{0}, 535 Data: ðpb.AttestationData{ 536 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 537 Target: ðpb.Checkpoint{Epoch: 4, Root: make([]byte, 32)}, 538 }, 539 Signature: []byte{3, 5}, 540 }, 541 }, 542 deleteAtts: []*ethpb.IndexedAttestation{ 543 { 544 AttestingIndices: []uint64{0}, 545 Data: ðpb.AttestationData{ 546 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 547 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 548 }, 549 Signature: []byte{1, 2}, 550 }, 551 { 552 AttestingIndices: []uint64{0}, 553 Data: ðpb.AttestationData{ 554 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 555 Target: ðpb.Checkpoint{Epoch: 4, Root: make([]byte, 32)}, 556 }, 557 Signature: []byte{3, 5}, 558 }, 559 }, 560 foundArray: []bool{false, true, false}, 561 }, 562 { 563 name: "multiple similar items, should delete 1", 564 attsInDB: []*ethpb.IndexedAttestation{ 565 { 566 AttestingIndices: []uint64{0}, 567 Data: ðpb.AttestationData{ 568 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 569 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 570 }, 571 Signature: []byte{1, 2, 2}, 572 }, 573 { 574 AttestingIndices: []uint64{0}, 575 Data: ðpb.AttestationData{ 576 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 577 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 578 }, 579 Signature: []byte{1, 2, 3}, 580 }, 581 { 582 AttestingIndices: []uint64{0}, 583 Data: ðpb.AttestationData{ 584 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 585 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 586 }, 587 Signature: []byte{1, 2, 4}, 588 }, 589 }, 590 deleteAtts: []*ethpb.IndexedAttestation{ 591 { 592 AttestingIndices: []uint64{0}, 593 Data: ðpb.AttestationData{ 594 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 595 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 596 }, 597 Signature: []byte{1, 2, 3}, 598 }, 599 }, 600 foundArray: []bool{true, false, true}, 601 }, 602 { 603 name: "should not delete any if not in list", 604 attsInDB: []*ethpb.IndexedAttestation{ 605 { 606 AttestingIndices: []uint64{0}, 607 Data: ðpb.AttestationData{ 608 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 609 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 610 }, 611 Signature: []byte{1, 2, 2}, 612 }, 613 { 614 AttestingIndices: []uint64{0}, 615 Data: ðpb.AttestationData{ 616 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 617 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 618 }, 619 Signature: []byte{1, 2, 3}, 620 }, 621 { 622 AttestingIndices: []uint64{0}, 623 Data: ðpb.AttestationData{ 624 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 625 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 626 }, 627 Signature: []byte{1, 2, 4}, 628 }, 629 }, 630 deleteAtts: []*ethpb.IndexedAttestation{ 631 { 632 AttestingIndices: []uint64{3}, 633 Data: ðpb.AttestationData{ 634 Source: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, 635 Target: ðpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)}, 636 }, 637 Signature: []byte{1, 2, 6}, 638 }, 639 }, 640 foundArray: []bool{true, true, true}, 641 }, 642 } 643 for _, tt := range deleteTests { 644 t.Run(tt.name, func(t *testing.T) { 645 db := setupDB(t) 646 ctx := context.Background() 647 648 require.NoError(t, db.SaveIndexedAttestations(ctx, tt.attsInDB), "Save indexed attestation failed") 649 650 for _, att := range tt.attsInDB { 651 found, err := db.HasIndexedAttestation(ctx, att) 652 require.NoError(t, err) 653 require.Equal(t, true, found, "Expected to save %v", att) 654 } 655 656 for _, att := range tt.deleteAtts { 657 require.NoError(t, db.DeleteIndexedAttestation(ctx, att)) 658 } 659 660 for i, att := range tt.attsInDB { 661 found, err := db.HasIndexedAttestation(ctx, att) 662 require.NoError(t, err) 663 require.Equal(t, tt.foundArray[i], found) 664 } 665 }) 666 } 667 } 668 669 func TestHasIndexedAttestation(t *testing.T) { 670 db := setupDB(t) 671 ctx := context.Background() 672 673 for _, tt := range tests { 674 exists, err := db.HasIndexedAttestation(ctx, tt.idxAtt) 675 require.NoError(t, err) 676 require.Equal(t, false, exists, "has indexed attestation should return false for indexed attestations that are not in db") 677 678 require.NoError(t, db.SaveIndexedAttestation(ctx, tt.idxAtt), "Save indexed attestation failed") 679 } 680 681 for _, tt := range tests { 682 exists, err := db.HasIndexedAttestation(ctx, tt.idxAtt) 683 require.NoError(t, err) 684 require.Equal(t, true, exists) 685 } 686 } 687 688 func TestPruneHistoryIndexedAttestation(t *testing.T) { 689 db := setupDB(t) 690 ctx := context.Background() 691 692 for _, tt := range tests { 693 require.NoError(t, db.SaveIndexedAttestation(ctx, tt.idxAtt), "Save indexed attestation failed") 694 695 found, err := db.HasIndexedAttestation(ctx, tt.idxAtt) 696 require.NoError(t, err, "Failed to get indexed attestation") 697 require.Equal(t, true, found, "Expected to find attestation in DB") 698 } 699 currentEpoch := types.Epoch(2) 700 historyToKeep := types.Epoch(1) 701 require.NoError(t, db.PruneAttHistory(ctx, currentEpoch, historyToKeep), "Failed to prune") 702 703 for _, tt := range tests { 704 exists, err := db.HasIndexedAttestation(ctx, tt.idxAtt) 705 require.NoError(t, err) 706 707 if tt.idxAtt.Data.Target.Epoch > currentEpoch-historyToKeep { 708 require.Equal(t, true, exists, "Expected to find attestation newer than prune age in DB") 709 } else { 710 require.Equal(t, false, exists, "Expected to not find attestation older than prune age in DB") 711 } 712 } 713 }