github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stategen/replay_test.go (about) 1 package stategen 2 3 import ( 4 "context" 5 "testing" 6 7 types "github.com/prysmaticlabs/eth2-types" 8 "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" 9 "github.com/prysmaticlabs/prysm/beacon-chain/db" 10 testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing" 11 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 12 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 13 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper" 14 "github.com/prysmaticlabs/prysm/proto/interfaces" 15 "github.com/prysmaticlabs/prysm/shared/bytesutil" 16 "github.com/prysmaticlabs/prysm/shared/params" 17 "github.com/prysmaticlabs/prysm/shared/testutil" 18 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 19 "github.com/prysmaticlabs/prysm/shared/testutil/require" 20 "google.golang.org/protobuf/proto" 21 ) 22 23 func TestReplayBlocks_AllSkipSlots(t *testing.T) { 24 beaconDB := testDB.SetupDB(t) 25 26 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 27 genesisBlock := blocks.NewGenesisBlock([]byte{}) 28 bodyRoot, err := genesisBlock.Block.HashTreeRoot() 29 require.NoError(t, err) 30 err = beaconState.SetLatestBlockHeader(ðpb.BeaconBlockHeader{ 31 Slot: genesisBlock.Block.Slot, 32 ParentRoot: genesisBlock.Block.ParentRoot, 33 StateRoot: params.BeaconConfig().ZeroHash[:], 34 BodyRoot: bodyRoot[:], 35 }) 36 require.NoError(t, err) 37 require.NoError(t, beaconState.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector))) 38 cp := beaconState.CurrentJustifiedCheckpoint() 39 mockRoot := [32]byte{} 40 copy(mockRoot[:], "hello-world") 41 cp.Root = mockRoot[:] 42 require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp)) 43 require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{})) 44 45 service := New(beaconDB) 46 targetSlot := params.BeaconConfig().SlotsPerEpoch - 1 47 newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot) 48 require.NoError(t, err) 49 assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots") 50 } 51 52 func TestReplayBlocks_SameSlot(t *testing.T) { 53 beaconDB := testDB.SetupDB(t) 54 55 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 56 genesisBlock := blocks.NewGenesisBlock([]byte{}) 57 bodyRoot, err := genesisBlock.Block.HashTreeRoot() 58 require.NoError(t, err) 59 err = beaconState.SetLatestBlockHeader(ðpb.BeaconBlockHeader{ 60 Slot: genesisBlock.Block.Slot, 61 ParentRoot: genesisBlock.Block.ParentRoot, 62 StateRoot: params.BeaconConfig().ZeroHash[:], 63 BodyRoot: bodyRoot[:], 64 }) 65 require.NoError(t, err) 66 require.NoError(t, beaconState.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector))) 67 cp := beaconState.CurrentJustifiedCheckpoint() 68 mockRoot := [32]byte{} 69 copy(mockRoot[:], "hello-world") 70 cp.Root = mockRoot[:] 71 require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp)) 72 require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{})) 73 74 service := New(beaconDB) 75 targetSlot := beaconState.Slot() 76 newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot) 77 require.NoError(t, err) 78 assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots") 79 } 80 81 func TestReplayBlocks_LowerSlotBlock(t *testing.T) { 82 beaconDB := testDB.SetupDB(t) 83 84 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 85 require.NoError(t, beaconState.SetSlot(1)) 86 genesisBlock := blocks.NewGenesisBlock([]byte{}) 87 bodyRoot, err := genesisBlock.Block.HashTreeRoot() 88 require.NoError(t, err) 89 err = beaconState.SetLatestBlockHeader(ðpb.BeaconBlockHeader{ 90 Slot: genesisBlock.Block.Slot, 91 ParentRoot: genesisBlock.Block.ParentRoot, 92 StateRoot: params.BeaconConfig().ZeroHash[:], 93 BodyRoot: bodyRoot[:], 94 }) 95 require.NoError(t, err) 96 require.NoError(t, beaconState.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector))) 97 cp := beaconState.CurrentJustifiedCheckpoint() 98 mockRoot := [32]byte{} 99 copy(mockRoot[:], "hello-world") 100 cp.Root = mockRoot[:] 101 require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp)) 102 require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{})) 103 104 service := New(beaconDB) 105 targetSlot := beaconState.Slot() 106 b := testutil.NewBeaconBlock() 107 b.Block.Slot = beaconState.Slot() - 1 108 newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{wrapper.WrappedPhase0SignedBeaconBlock(b)}, targetSlot) 109 require.NoError(t, err) 110 assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots") 111 } 112 113 func TestLoadBlocks_FirstBranch(t *testing.T) { 114 beaconDB := testDB.SetupDB(t) 115 ctx := context.Background() 116 s := &State{ 117 beaconDB: beaconDB, 118 } 119 120 roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 121 require.NoError(t, err) 122 123 filteredBlocks, err := s.LoadBlocks(ctx, 0, 8, roots[len(roots)-1]) 124 require.NoError(t, err) 125 126 wanted := []*ethpb.SignedBeaconBlock{ 127 savedBlocks[8], 128 savedBlocks[6], 129 savedBlocks[4], 130 savedBlocks[2], 131 savedBlocks[1], 132 savedBlocks[0], 133 } 134 135 for i, block := range wanted { 136 if !proto.Equal(block, filteredBlocks[i].Proto()) { 137 t.Error("Did not get wanted blocks") 138 } 139 } 140 } 141 142 func TestLoadBlocks_SecondBranch(t *testing.T) { 143 beaconDB := testDB.SetupDB(t) 144 ctx := context.Background() 145 s := &State{ 146 beaconDB: beaconDB, 147 } 148 149 roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 150 require.NoError(t, err) 151 152 filteredBlocks, err := s.LoadBlocks(ctx, 0, 5, roots[5]) 153 require.NoError(t, err) 154 155 wanted := []*ethpb.SignedBeaconBlock{ 156 savedBlocks[5], 157 savedBlocks[3], 158 savedBlocks[1], 159 savedBlocks[0], 160 } 161 162 for i, block := range wanted { 163 if !proto.Equal(block, filteredBlocks[i].Proto()) { 164 t.Error("Did not get wanted blocks") 165 } 166 } 167 } 168 169 func TestLoadBlocks_ThirdBranch(t *testing.T) { 170 beaconDB := testDB.SetupDB(t) 171 ctx := context.Background() 172 s := &State{ 173 beaconDB: beaconDB, 174 } 175 176 roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 177 require.NoError(t, err) 178 179 filteredBlocks, err := s.LoadBlocks(ctx, 0, 7, roots[7]) 180 require.NoError(t, err) 181 182 wanted := []*ethpb.SignedBeaconBlock{ 183 savedBlocks[7], 184 savedBlocks[6], 185 savedBlocks[4], 186 savedBlocks[2], 187 savedBlocks[1], 188 savedBlocks[0], 189 } 190 191 for i, block := range wanted { 192 if !proto.Equal(block, filteredBlocks[i].Proto()) { 193 t.Error("Did not get wanted blocks") 194 } 195 } 196 } 197 198 func TestLoadBlocks_SameSlots(t *testing.T) { 199 beaconDB := testDB.SetupDB(t) 200 ctx := context.Background() 201 s := &State{ 202 beaconDB: beaconDB, 203 } 204 205 roots, savedBlocks, err := tree2(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 206 require.NoError(t, err) 207 208 filteredBlocks, err := s.LoadBlocks(ctx, 0, 3, roots[6]) 209 require.NoError(t, err) 210 211 wanted := []*ethpb.SignedBeaconBlock{ 212 savedBlocks[6], 213 savedBlocks[5], 214 savedBlocks[1], 215 savedBlocks[0], 216 } 217 218 for i, block := range wanted { 219 if !proto.Equal(block, filteredBlocks[i].Proto()) { 220 t.Error("Did not get wanted blocks") 221 } 222 } 223 } 224 225 func TestLoadBlocks_SameEndSlots(t *testing.T) { 226 beaconDB := testDB.SetupDB(t) 227 ctx := context.Background() 228 s := &State{ 229 beaconDB: beaconDB, 230 } 231 232 roots, savedBlocks, err := tree3(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 233 require.NoError(t, err) 234 235 filteredBlocks, err := s.LoadBlocks(ctx, 0, 2, roots[2]) 236 require.NoError(t, err) 237 238 wanted := []*ethpb.SignedBeaconBlock{ 239 savedBlocks[2], 240 savedBlocks[1], 241 savedBlocks[0], 242 } 243 244 for i, block := range wanted { 245 if !proto.Equal(block, filteredBlocks[i].Proto()) { 246 t.Error("Did not get wanted blocks") 247 } 248 } 249 } 250 251 func TestLoadBlocks_SameEndSlotsWith2blocks(t *testing.T) { 252 beaconDB := testDB.SetupDB(t) 253 ctx := context.Background() 254 s := &State{ 255 beaconDB: beaconDB, 256 } 257 258 roots, savedBlocks, err := tree4(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 259 require.NoError(t, err) 260 261 filteredBlocks, err := s.LoadBlocks(ctx, 0, 2, roots[1]) 262 require.NoError(t, err) 263 264 wanted := []*ethpb.SignedBeaconBlock{ 265 savedBlocks[1], 266 savedBlocks[0], 267 } 268 269 for i, block := range wanted { 270 if !proto.Equal(block, filteredBlocks[i].Proto()) { 271 t.Error("Did not get wanted blocks") 272 } 273 } 274 } 275 276 func TestLoadBlocks_BadStart(t *testing.T) { 277 beaconDB := testDB.SetupDB(t) 278 ctx := context.Background() 279 s := &State{ 280 beaconDB: beaconDB, 281 } 282 283 roots, _, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32)) 284 require.NoError(t, err) 285 _, err = s.LoadBlocks(ctx, 0, 5, roots[8]) 286 assert.ErrorContains(t, "end block roots don't match", err) 287 } 288 289 func TestLastSavedBlock_Genesis(t *testing.T) { 290 beaconDB := testDB.SetupDB(t) 291 ctx := context.Background() 292 s := &State{ 293 beaconDB: beaconDB, 294 finalizedInfo: &finalizedInfo{slot: 128}, 295 } 296 297 gBlk := testutil.NewBeaconBlock() 298 gRoot, err := gBlk.Block.HashTreeRoot() 299 require.NoError(t, err) 300 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(gBlk))) 301 require.NoError(t, s.beaconDB.SaveGenesisBlockRoot(ctx, gRoot)) 302 303 savedRoot, savedSlot, err := s.lastSavedBlock(ctx, 0) 304 require.NoError(t, err) 305 assert.Equal(t, types.Slot(0), savedSlot, "Did not save genesis slot") 306 assert.Equal(t, savedRoot, savedRoot, "Did not save genesis root") 307 } 308 309 func TestLastSavedBlock_CanGet(t *testing.T) { 310 beaconDB := testDB.SetupDB(t) 311 ctx := context.Background() 312 s := &State{ 313 beaconDB: beaconDB, 314 finalizedInfo: &finalizedInfo{slot: 128}, 315 } 316 317 b1 := testutil.NewBeaconBlock() 318 b1.Block.Slot = s.finalizedInfo.slot + 5 319 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1))) 320 b2 := testutil.NewBeaconBlock() 321 b2.Block.Slot = s.finalizedInfo.slot + 10 322 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2))) 323 b3 := testutil.NewBeaconBlock() 324 b3.Block.Slot = s.finalizedInfo.slot + 20 325 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3))) 326 327 savedRoot, savedSlot, err := s.lastSavedBlock(ctx, s.finalizedInfo.slot+100) 328 require.NoError(t, err) 329 assert.Equal(t, s.finalizedInfo.slot+20, savedSlot) 330 wantedRoot, err := b3.Block.HashTreeRoot() 331 require.NoError(t, err) 332 assert.Equal(t, wantedRoot, savedRoot, "Did not save correct root") 333 } 334 335 func TestLastSavedBlock_NoSavedBlock(t *testing.T) { 336 beaconDB := testDB.SetupDB(t) 337 ctx := context.Background() 338 s := &State{ 339 beaconDB: beaconDB, 340 finalizedInfo: &finalizedInfo{slot: 128}, 341 } 342 343 root, slot, err := s.lastSavedBlock(ctx, s.finalizedInfo.slot+1) 344 require.NoError(t, err) 345 if slot != 0 && root != [32]byte{} { 346 t.Error("Did not get wanted block") 347 } 348 } 349 350 func TestLastSavedState_Genesis(t *testing.T) { 351 beaconDB := testDB.SetupDB(t) 352 ctx := context.Background() 353 s := &State{ 354 beaconDB: beaconDB, 355 finalizedInfo: &finalizedInfo{slot: 128}, 356 } 357 358 gBlk := testutil.NewBeaconBlock() 359 gState, err := testutil.NewBeaconState() 360 require.NoError(t, err) 361 gRoot, err := gBlk.Block.HashTreeRoot() 362 require.NoError(t, err) 363 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(gBlk))) 364 require.NoError(t, s.beaconDB.SaveGenesisBlockRoot(ctx, gRoot)) 365 require.NoError(t, s.beaconDB.SaveState(ctx, gState, gRoot)) 366 367 savedState, err := s.lastSavedState(ctx, 0) 368 require.NoError(t, err) 369 require.DeepSSZEqual(t, gState.InnerStateUnsafe(), savedState.InnerStateUnsafe()) 370 } 371 372 func TestLastSavedState_CanGet(t *testing.T) { 373 beaconDB := testDB.SetupDB(t) 374 ctx := context.Background() 375 s := &State{ 376 beaconDB: beaconDB, 377 finalizedInfo: &finalizedInfo{slot: 128}, 378 } 379 380 b1 := testutil.NewBeaconBlock() 381 b1.Block.Slot = s.finalizedInfo.slot + 5 382 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1))) 383 b2 := testutil.NewBeaconBlock() 384 b2.Block.Slot = s.finalizedInfo.slot + 10 385 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2))) 386 b2Root, err := b2.Block.HashTreeRoot() 387 require.NoError(t, err) 388 st, err := testutil.NewBeaconState() 389 require.NoError(t, err) 390 require.NoError(t, st.SetSlot(s.finalizedInfo.slot+10)) 391 392 require.NoError(t, s.beaconDB.SaveState(ctx, st, b2Root)) 393 b3 := testutil.NewBeaconBlock() 394 b3.Block.Slot = s.finalizedInfo.slot + 20 395 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3))) 396 397 savedState, err := s.lastSavedState(ctx, s.finalizedInfo.slot+100) 398 require.NoError(t, err) 399 require.DeepSSZEqual(t, st.InnerStateUnsafe(), savedState.InnerStateUnsafe()) 400 } 401 402 func TestLastSavedState_NoSavedBlockState(t *testing.T) { 403 beaconDB := testDB.SetupDB(t) 404 ctx := context.Background() 405 s := &State{ 406 beaconDB: beaconDB, 407 finalizedInfo: &finalizedInfo{slot: 128}, 408 } 409 410 b1 := testutil.NewBeaconBlock() 411 b1.Block.Slot = 127 412 require.NoError(t, s.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1))) 413 414 _, err := s.lastSavedState(ctx, s.finalizedInfo.slot+1) 415 assert.ErrorContains(t, errUnknownState.Error(), err) 416 } 417 418 // tree1 constructs the following tree: 419 // B0 - B1 - - B3 -- B5 420 // \- B2 -- B4 -- B6 ----- B8 421 // \- B7 422 func tree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte, []*ethpb.SignedBeaconBlock, error) { 423 b0 := testutil.NewBeaconBlock() 424 b0.Block.Slot = 0 425 b0.Block.ParentRoot = genesisRoot 426 r0, err := b0.Block.HashTreeRoot() 427 if err != nil { 428 return nil, nil, err 429 } 430 b1 := testutil.NewBeaconBlock() 431 b1.Block.Slot = 1 432 b1.Block.ParentRoot = r0[:] 433 r1, err := b1.Block.HashTreeRoot() 434 if err != nil { 435 return nil, nil, err 436 } 437 b2 := testutil.NewBeaconBlock() 438 b2.Block.Slot = 2 439 b2.Block.ParentRoot = r1[:] 440 r2, err := b2.Block.HashTreeRoot() 441 if err != nil { 442 return nil, nil, err 443 } 444 b3 := testutil.NewBeaconBlock() 445 b3.Block.Slot = 3 446 b3.Block.ParentRoot = r1[:] 447 r3, err := b3.Block.HashTreeRoot() 448 if err != nil { 449 return nil, nil, err 450 } 451 b4 := testutil.NewBeaconBlock() 452 b4.Block.Slot = 4 453 b4.Block.ParentRoot = r2[:] 454 r4, err := b4.Block.HashTreeRoot() 455 if err != nil { 456 return nil, nil, err 457 } 458 b5 := testutil.NewBeaconBlock() 459 b5.Block.Slot = 5 460 b5.Block.ParentRoot = r3[:] 461 r5, err := b5.Block.HashTreeRoot() 462 if err != nil { 463 return nil, nil, err 464 } 465 b6 := testutil.NewBeaconBlock() 466 b6.Block.Slot = 6 467 b6.Block.ParentRoot = r4[:] 468 r6, err := b6.Block.HashTreeRoot() 469 if err != nil { 470 return nil, nil, err 471 } 472 b7 := testutil.NewBeaconBlock() 473 b7.Block.Slot = 7 474 b7.Block.ParentRoot = r6[:] 475 r7, err := b7.Block.HashTreeRoot() 476 if err != nil { 477 return nil, nil, err 478 } 479 b8 := testutil.NewBeaconBlock() 480 b8.Block.Slot = 8 481 b8.Block.ParentRoot = r6[:] 482 r8, err := b8.Block.HashTreeRoot() 483 if err != nil { 484 return nil, nil, err 485 } 486 st, err := testutil.NewBeaconState() 487 require.NoError(t, err) 488 489 returnedBlocks := make([]*ethpb.SignedBeaconBlock, 0) 490 for _, b := range []*ethpb.SignedBeaconBlock{b0, b1, b2, b3, b4, b5, b6, b7, b8} { 491 beaconBlock := testutil.NewBeaconBlock() 492 beaconBlock.Block.Slot = b.Block.Slot 493 beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32) 494 if err := beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil { 495 return nil, nil, err 496 } 497 if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { 498 return nil, nil, err 499 } 500 returnedBlocks = append(returnedBlocks, beaconBlock) 501 } 502 return [][32]byte{r0, r1, r2, r3, r4, r5, r6, r7, r8}, returnedBlocks, nil 503 } 504 505 // tree2 constructs the following tree: 506 // B0 - B1 507 // \- B2 508 // \- B2 509 // \- B2 510 // \- B2 -- B3 511 func tree2(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte, []*ethpb.SignedBeaconBlock, error) { 512 b0 := testutil.NewBeaconBlock() 513 b0.Block.Slot = 0 514 b0.Block.ParentRoot = genesisRoot 515 r0, err := b0.Block.HashTreeRoot() 516 if err != nil { 517 return nil, nil, err 518 } 519 b1 := testutil.NewBeaconBlock() 520 b1.Block.Slot = 1 521 b1.Block.ParentRoot = r0[:] 522 r1, err := b1.Block.HashTreeRoot() 523 if err != nil { 524 return nil, nil, err 525 } 526 b21 := testutil.NewBeaconBlock() 527 b21.Block.Slot = 2 528 b21.Block.ParentRoot = r1[:] 529 b21.Block.StateRoot = bytesutil.PadTo([]byte{'A'}, 32) 530 r21, err := b21.Block.HashTreeRoot() 531 if err != nil { 532 return nil, nil, err 533 } 534 b22 := testutil.NewBeaconBlock() 535 b22.Block.Slot = 2 536 b22.Block.ParentRoot = r1[:] 537 b22.Block.StateRoot = bytesutil.PadTo([]byte{'B'}, 32) 538 r22, err := b22.Block.HashTreeRoot() 539 if err != nil { 540 return nil, nil, err 541 } 542 b23 := testutil.NewBeaconBlock() 543 b23.Block.Slot = 2 544 b23.Block.ParentRoot = r1[:] 545 b23.Block.StateRoot = bytesutil.PadTo([]byte{'C'}, 32) 546 r23, err := b23.Block.HashTreeRoot() 547 if err != nil { 548 return nil, nil, err 549 } 550 b24 := testutil.NewBeaconBlock() 551 b24.Block.Slot = 2 552 b24.Block.ParentRoot = r1[:] 553 b24.Block.StateRoot = bytesutil.PadTo([]byte{'D'}, 32) 554 r24, err := b24.Block.HashTreeRoot() 555 if err != nil { 556 return nil, nil, err 557 } 558 b3 := testutil.NewBeaconBlock() 559 b3.Block.Slot = 3 560 b3.Block.ParentRoot = r24[:] 561 r3, err := b3.Block.HashTreeRoot() 562 if err != nil { 563 return nil, nil, err 564 } 565 st, err := testutil.NewBeaconState() 566 require.NoError(t, err) 567 568 returnedBlocks := make([]*ethpb.SignedBeaconBlock, 0) 569 for _, b := range []*ethpb.SignedBeaconBlock{b0, b1, b21, b22, b23, b24, b3} { 570 beaconBlock := testutil.NewBeaconBlock() 571 beaconBlock.Block.Slot = b.Block.Slot 572 beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32) 573 beaconBlock.Block.StateRoot = bytesutil.PadTo(b.Block.StateRoot, 32) 574 if err := beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil { 575 return nil, nil, err 576 } 577 if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { 578 return nil, nil, err 579 } 580 returnedBlocks = append(returnedBlocks, beaconBlock) 581 } 582 return [][32]byte{r0, r1, r21, r22, r23, r24, r3}, returnedBlocks, nil 583 } 584 585 // tree3 constructs the following tree: 586 // B0 - B1 587 // \- B2 588 // \- B2 589 // \- B2 590 // \- B2 591 func tree3(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte, []*ethpb.SignedBeaconBlock, error) { 592 b0 := testutil.NewBeaconBlock() 593 b0.Block.Slot = 0 594 b0.Block.ParentRoot = genesisRoot 595 r0, err := b0.Block.HashTreeRoot() 596 if err != nil { 597 return nil, nil, err 598 } 599 b1 := testutil.NewBeaconBlock() 600 b1.Block.Slot = 1 601 b1.Block.ParentRoot = r0[:] 602 r1, err := b1.Block.HashTreeRoot() 603 if err != nil { 604 return nil, nil, err 605 } 606 b21 := testutil.NewBeaconBlock() 607 b21.Block.Slot = 2 608 b21.Block.ParentRoot = r1[:] 609 b21.Block.StateRoot = bytesutil.PadTo([]byte{'A'}, 32) 610 r21, err := b21.Block.HashTreeRoot() 611 if err != nil { 612 return nil, nil, err 613 } 614 b22 := testutil.NewBeaconBlock() 615 b22.Block.Slot = 2 616 b22.Block.ParentRoot = r1[:] 617 b22.Block.StateRoot = bytesutil.PadTo([]byte{'B'}, 32) 618 r22, err := b22.Block.HashTreeRoot() 619 if err != nil { 620 return nil, nil, err 621 } 622 b23 := testutil.NewBeaconBlock() 623 b23.Block.Slot = 2 624 b23.Block.ParentRoot = r1[:] 625 b23.Block.StateRoot = bytesutil.PadTo([]byte{'C'}, 32) 626 r23, err := b23.Block.HashTreeRoot() 627 if err != nil { 628 return nil, nil, err 629 } 630 b24 := testutil.NewBeaconBlock() 631 b24.Block.Slot = 2 632 b24.Block.ParentRoot = r1[:] 633 b24.Block.StateRoot = bytesutil.PadTo([]byte{'D'}, 32) 634 r24, err := b24.Block.HashTreeRoot() 635 if err != nil { 636 return nil, nil, err 637 } 638 st, err := testutil.NewBeaconState() 639 require.NoError(t, err) 640 641 returnedBlocks := make([]*ethpb.SignedBeaconBlock, 0) 642 for _, b := range []*ethpb.SignedBeaconBlock{b0, b1, b21, b22, b23, b24} { 643 beaconBlock := testutil.NewBeaconBlock() 644 beaconBlock.Block.Slot = b.Block.Slot 645 beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32) 646 beaconBlock.Block.StateRoot = bytesutil.PadTo(b.Block.StateRoot, 32) 647 if err := beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil { 648 return nil, nil, err 649 } 650 if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { 651 return nil, nil, err 652 } 653 returnedBlocks = append(returnedBlocks, beaconBlock) 654 } 655 656 return [][32]byte{r0, r1, r21, r22, r23, r24}, returnedBlocks, nil 657 } 658 659 // tree4 constructs the following tree: 660 // B0 661 // \- B2 662 // \- B2 663 // \- B2 664 // \- B2 665 func tree4(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte, []*ethpb.SignedBeaconBlock, error) { 666 b0 := testutil.NewBeaconBlock() 667 b0.Block.Slot = 0 668 b0.Block.ParentRoot = genesisRoot 669 r0, err := b0.Block.HashTreeRoot() 670 if err != nil { 671 return nil, nil, err 672 } 673 b21 := testutil.NewBeaconBlock() 674 b21.Block.Slot = 2 675 b21.Block.ParentRoot = r0[:] 676 b21.Block.StateRoot = bytesutil.PadTo([]byte{'A'}, 32) 677 r21, err := b21.Block.HashTreeRoot() 678 if err != nil { 679 return nil, nil, err 680 } 681 b22 := testutil.NewBeaconBlock() 682 b22.Block.Slot = 2 683 b22.Block.ParentRoot = r0[:] 684 b22.Block.StateRoot = bytesutil.PadTo([]byte{'B'}, 32) 685 r22, err := b22.Block.HashTreeRoot() 686 if err != nil { 687 return nil, nil, err 688 } 689 b23 := testutil.NewBeaconBlock() 690 b23.Block.Slot = 2 691 b23.Block.ParentRoot = r0[:] 692 b23.Block.StateRoot = bytesutil.PadTo([]byte{'C'}, 32) 693 r23, err := b23.Block.HashTreeRoot() 694 if err != nil { 695 return nil, nil, err 696 } 697 b24 := testutil.NewBeaconBlock() 698 b24.Block.Slot = 2 699 b24.Block.ParentRoot = r0[:] 700 b24.Block.StateRoot = bytesutil.PadTo([]byte{'D'}, 32) 701 r24, err := b24.Block.HashTreeRoot() 702 if err != nil { 703 return nil, nil, err 704 } 705 st, err := testutil.NewBeaconState() 706 require.NoError(t, err) 707 708 returnedBlocks := make([]*ethpb.SignedBeaconBlock, 0) 709 for _, b := range []*ethpb.SignedBeaconBlock{b0, b21, b22, b23, b24} { 710 beaconBlock := testutil.NewBeaconBlock() 711 beaconBlock.Block.Slot = b.Block.Slot 712 beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32) 713 beaconBlock.Block.StateRoot = bytesutil.PadTo(b.Block.StateRoot, 32) 714 if err := beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil { 715 return nil, nil, err 716 } 717 if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { 718 return nil, nil, err 719 } 720 returnedBlocks = append(returnedBlocks, beaconBlock) 721 } 722 723 return [][32]byte{r0, r21, r22, r23, r24}, returnedBlocks, nil 724 } 725 726 func TestLoadFinalizedBlocks(t *testing.T) { 727 beaconDB := testDB.SetupDB(t) 728 ctx := context.Background() 729 s := &State{ 730 beaconDB: beaconDB, 731 } 732 gBlock := testutil.NewBeaconBlock() 733 gRoot, err := gBlock.Block.HashTreeRoot() 734 require.NoError(t, err) 735 require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(gBlock))) 736 require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, [32]byte{})) 737 roots, _, err := tree1(t, beaconDB, gRoot[:]) 738 require.NoError(t, err) 739 740 filteredBlocks, err := s.loadFinalizedBlocks(ctx, 0, 8) 741 require.NoError(t, err) 742 require.Equal(t, 0, len(filteredBlocks)) 743 require.NoError(t, beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: roots[8][:]})) 744 745 require.NoError(t, s.beaconDB.SaveFinalizedCheckpoint(ctx, ðpb.Checkpoint{Root: roots[8][:]})) 746 filteredBlocks, err = s.loadFinalizedBlocks(ctx, 0, 8) 747 require.NoError(t, err) 748 require.Equal(t, 10, len(filteredBlocks)) 749 }