@@ -40,8 +40,8 @@ use store::{Error as StoreError, HotColdDB, ItemStore, KeyValueStoreOp};
40
40
use task_executor:: { ShutdownReason , TaskExecutor } ;
41
41
use tracing:: { debug, error, info} ;
42
42
use types:: {
43
- BeaconBlock , BeaconState , BlobSidecarList , ChainSpec , Checkpoint , DataColumnSidecarList , Epoch ,
44
- EthSpec , FixedBytesExtended , Hash256 , Signature , SignedBeaconBlock , Slot ,
43
+ BeaconBlock , BeaconState , BlobSidecarList , ChainSpec , DataColumnSidecarList , Epoch , EthSpec ,
44
+ FixedBytesExtended , Hash256 , Signature , SignedBeaconBlock , Slot ,
45
45
} ;
46
46
47
47
/// An empty struct used to "witness" all the `BeaconChainTypes` traits. It has no user-facing
@@ -360,21 +360,29 @@ where
360
360
}
361
361
362
362
/// Starts a new chain from a genesis state.
363
- pub fn genesis_state ( mut self , beacon_state : BeaconState < E > ) -> Result < Self , String > {
363
+ pub fn genesis_state ( mut self , mut beacon_state : BeaconState < E > ) -> Result < Self , String > {
364
364
let store = self . store . clone ( ) . ok_or ( "genesis_state requires a store" ) ?;
365
365
366
- let ( genesis, updated_builder) = self . set_genesis_state ( beacon_state) ?;
367
- self = updated_builder;
368
-
369
- // Stage the database's metadata fields for atomic storage when `build` is called.
366
+ // Initialize anchor info before attempting to write the genesis state.
370
367
// Since v4.4.0 we will set the anchor with a dummy state upper limit in order to prevent
371
368
// historic states from being retained (unless `--reconstruct-historic-states` is set).
372
369
let retain_historic_states = self . chain_config . reconstruct_historic_states ;
370
+ let genesis_beacon_block = genesis_block ( & mut beacon_state, & self . spec ) ?;
373
371
self . pending_io_batch . push (
374
372
store
375
- . init_anchor_info ( genesis. beacon_block . message ( ) , retain_historic_states)
373
+ . init_anchor_info (
374
+ genesis_beacon_block. parent_root ( ) ,
375
+ genesis_beacon_block. slot ( ) ,
376
+ Slot :: new ( 0 ) ,
377
+ retain_historic_states,
378
+ )
376
379
. map_err ( |e| format ! ( "Failed to initialize genesis anchor: {:?}" , e) ) ?,
377
380
) ;
381
+
382
+ let ( genesis, updated_builder) = self . set_genesis_state ( beacon_state) ?;
383
+ self = updated_builder;
384
+
385
+ // Stage the database's metadata fields for atomic storage when `build` is called.
378
386
self . pending_io_batch . push (
379
387
store
380
388
. init_blob_info ( genesis. beacon_block . slot ( ) )
@@ -499,6 +507,13 @@ where
499
507
}
500
508
}
501
509
510
+ debug ! (
511
+ slot = %weak_subj_slot,
512
+ state_root = ?weak_subj_state_root,
513
+ block_root = ?weak_subj_block_root,
514
+ "Storing split from weak subjectivity state"
515
+ ) ;
516
+
502
517
// Set the store's split point *before* storing genesis so that genesis is stored
503
518
// immediately in the freezer DB.
504
519
store. set_split ( weak_subj_slot, weak_subj_state_root, weak_subj_block_root) ;
@@ -519,6 +534,26 @@ where
519
534
. cold_db
520
535
. do_atomically ( block_root_batch)
521
536
. map_err ( |e| format ! ( "Error writing frozen block roots: {e:?}" ) ) ?;
537
+ debug ! (
538
+ from = %weak_subj_block. slot( ) ,
539
+ to_excl = %weak_subj_state. slot( ) ,
540
+ block_root = ?weak_subj_block_root,
541
+ "Stored frozen block roots at skipped slots"
542
+ ) ;
543
+
544
+ // Write the anchor to memory before calling `put_state` otherwise hot hdiff can't store
545
+ // states that do not align with the `start_slot` grid.
546
+ let retain_historic_states = self . chain_config . reconstruct_historic_states ;
547
+ self . pending_io_batch . push (
548
+ store
549
+ . init_anchor_info (
550
+ weak_subj_block. parent_root ( ) ,
551
+ weak_subj_block. slot ( ) ,
552
+ weak_subj_slot,
553
+ retain_historic_states,
554
+ )
555
+ . map_err ( |e| format ! ( "Failed to initialize anchor info: {:?}" , e) ) ?,
556
+ ) ;
522
557
523
558
// Write the state, block and blobs non-atomically, it doesn't matter if they're forgotten
524
559
// about on a crash restart.
@@ -529,6 +564,8 @@ where
529
564
weak_subj_state. clone ( ) ,
530
565
)
531
566
. map_err ( |e| format ! ( "Failed to set checkpoint state as finalized state: {:?}" , e) ) ?;
567
+ // Note: post hot hdiff must update the anchor info before attempting to put_state otherwise
568
+ // the write will fail if the weak_subj_slot is not aligned with the snapshot moduli.
532
569
store
533
570
. put_state ( & weak_subj_state_root, & weak_subj_state)
534
571
. map_err ( |e| format ! ( "Failed to store weak subjectivity state: {e:?}" ) ) ?;
@@ -558,13 +595,7 @@ where
558
595
// Stage the database's metadata fields for atomic storage when `build` is called.
559
596
// This prevents the database from restarting in an inconsistent state if the anchor
560
597
// info or split point is written before the `PersistedBeaconChain`.
561
- let retain_historic_states = self . chain_config . reconstruct_historic_states ;
562
598
self . pending_io_batch . push ( store. store_split_in_batch ( ) ) ;
563
- self . pending_io_batch . push (
564
- store
565
- . init_anchor_info ( weak_subj_block. message ( ) , retain_historic_states)
566
- . map_err ( |e| format ! ( "Failed to initialize anchor info: {:?}" , e) ) ?,
567
- ) ;
568
599
self . pending_io_batch . push (
569
600
store
570
601
. init_blob_info ( weak_subj_block. slot ( ) )
@@ -576,13 +607,6 @@ where
576
607
. map_err ( |e| format ! ( "Failed to initialize data column info: {:?}" , e) ) ?,
577
608
) ;
578
609
579
- // Store pruning checkpoint to prevent attempting to prune before the anchor state.
580
- self . pending_io_batch
581
- . push ( store. pruning_checkpoint_store_op ( Checkpoint {
582
- root : weak_subj_block_root,
583
- epoch : weak_subj_state. slot ( ) . epoch ( E :: slots_per_epoch ( ) ) ,
584
- } ) ) ;
585
-
586
610
let snapshot = BeaconSnapshot {
587
611
beacon_block_root : weak_subj_block_root,
588
612
beacon_block : Arc :: new ( weak_subj_block) ,
0 commit comments