@@ -371,7 +371,7 @@ type ReqRespPreImportCache<E> = HashMap<Hash256, Arc<SignedBeaconBlock<E>>>;
371371/// Represents the "Beacon Chain" component of Ethereum 2.0. Allows import of blocks and block
372372/// operations and chooses a canonical head.
373373pub struct BeaconChain < T : BeaconChainTypes > {
374- pub spec : ChainSpec ,
374+ pub spec : Arc < ChainSpec > ,
375375 /// Configuration for `BeaconChain` runtime behaviour.
376376 pub config : ChainConfig ,
377377 /// Persistent storage for blocks, states, etc. Typically an on-disk store, such as LevelDB.
@@ -497,7 +497,7 @@ pub struct BeaconChain<T: BeaconChainTypes> {
497497 /// they are collected and combined.
498498 pub data_availability_checker : Arc < DataAvailabilityChecker < T > > ,
499499 /// The KZG trusted setup used by this chain.
500- pub kzg : Option < Arc < Kzg > > ,
500+ pub kzg : Arc < Kzg > ,
501501}
502502
503503pub enum BeaconBlockResponseWrapper < E : EthSpec > {
@@ -2740,7 +2740,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
27402740 // If the block is relevant, add it to the filtered chain segment.
27412741 Ok ( _) => filtered_chain_segment. push ( ( block_root, block) ) ,
27422742 // If the block is already known, simply ignore this block.
2743- Err ( BlockError :: BlockIsAlreadyKnown ( _) ) => continue ,
2743+ //
2744+ // Note that `check_block_relevancy` is incapable of returning
2745+ // `DuplicateImportStatusUnknown` so we don't need to handle that case here.
2746+ Err ( BlockError :: DuplicateFullyImported ( _) ) => continue ,
27442747 // If the block is the genesis block, simply ignore this block.
27452748 Err ( BlockError :: GenesisBlock ) => continue ,
27462749 // If the block is is for a finalized slot, simply ignore this block.
@@ -2886,7 +2889,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
28862889 }
28872890 }
28882891 }
2889- Err ( BlockError :: BlockIsAlreadyKnown ( block_root) ) => {
2892+ Err ( BlockError :: DuplicateFullyImported ( block_root) ) => {
28902893 debug ! ( self . log,
28912894 "Ignoring already known blocks while processing chain segment" ;
28922895 "block_root" => ?block_root) ;
@@ -2977,6 +2980,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
29772980 pub async fn process_gossip_blob (
29782981 self : & Arc < Self > ,
29792982 blob : GossipVerifiedBlob < T > ,
2983+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
29802984 ) -> Result < AvailabilityProcessingStatus , BlockError > {
29812985 let block_root = blob. block_root ( ) ;
29822986
@@ -2987,7 +2991,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
29872991 . fork_choice_read_lock ( )
29882992 . contains_block ( & block_root)
29892993 {
2990- return Err ( BlockError :: BlockIsAlreadyKnown ( blob. block_root ( ) ) ) ;
2994+ return Err ( BlockError :: DuplicateFullyImported ( blob. block_root ( ) ) ) ;
29912995 }
29922996
29932997 // No need to process and import blobs beyond the PeerDAS epoch.
@@ -3003,7 +3007,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30033007 }
30043008 }
30053009
3006- let r = self . check_gossip_blob_availability_and_import ( blob) . await ;
3010+ let r = self
3011+ . check_gossip_blob_availability_and_import ( blob, publish_fn)
3012+ . await ;
30073013 self . remove_notified ( & block_root, r)
30083014 }
30093015
@@ -3012,6 +3018,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30123018 pub async fn process_gossip_data_columns (
30133019 self : & Arc < Self > ,
30143020 data_columns : Vec < GossipVerifiedDataColumn < T > > ,
3021+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
30153022 ) -> Result <
30163023 (
30173024 AvailabilityProcessingStatus ,
@@ -3037,11 +3044,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30373044 . fork_choice_read_lock ( )
30383045 . contains_block ( & block_root)
30393046 {
3040- return Err ( BlockError :: BlockIsAlreadyKnown ( block_root) ) ;
3047+ return Err ( BlockError :: DuplicateFullyImported ( block_root) ) ;
30413048 }
30423049
30433050 let r = self
3044- . check_gossip_data_columns_availability_and_import ( slot, block_root, data_columns)
3051+ . check_gossip_data_columns_availability_and_import (
3052+ slot,
3053+ block_root,
3054+ data_columns,
3055+ publish_fn,
3056+ )
30453057 . await ;
30463058 self . remove_notified_custody_columns ( & block_root, r)
30473059 }
@@ -3061,7 +3073,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30613073 . fork_choice_read_lock ( )
30623074 . contains_block ( & block_root)
30633075 {
3064- return Err ( BlockError :: BlockIsAlreadyKnown ( block_root) ) ;
3076+ return Err ( BlockError :: DuplicateFullyImported ( block_root) ) ;
30653077 }
30663078
30673079 // Reject RPC blobs referencing unknown parents. Otherwise we allow potentially invalid data
@@ -3127,7 +3139,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
31273139 . fork_choice_read_lock ( )
31283140 . contains_block ( & block_root)
31293141 {
3130- return Err ( BlockError :: BlockIsAlreadyKnown ( block_root) ) ;
3142+ return Err ( BlockError :: DuplicateFullyImported ( block_root) ) ;
31313143 }
31323144
31333145 // Reject RPC columns referencing unknown parents. Otherwise we allow potentially invalid data
@@ -3225,7 +3237,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
32253237 unverified_block : B ,
32263238 notify_execution_layer : NotifyExecutionLayer ,
32273239 block_source : BlockImportSource ,
3228- publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > + Send + ' static ,
3240+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
32293241 ) -> Result < AvailabilityProcessingStatus , BlockError > {
32303242 // Start the Prometheus timer.
32313243 let _full_timer = metrics:: start_timer ( & metrics:: BLOCK_PROCESSING_TIMES ) ;
@@ -3407,22 +3419,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
34073419 let availability = self
34083420 . data_availability_checker
34093421 . put_pending_executed_block ( block) ?;
3410- self . process_availability ( slot, availability) . await
3422+ self . process_availability ( slot, availability, || Ok ( ( ) ) )
3423+ . await
34113424 }
34123425
34133426 /// Checks if the provided blob can make any cached blocks available, and imports immediately
34143427 /// if so, otherwise caches the blob in the data availability checker.
34153428 async fn check_gossip_blob_availability_and_import (
34163429 self : & Arc < Self > ,
34173430 blob : GossipVerifiedBlob < T > ,
3431+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
34183432 ) -> Result < AvailabilityProcessingStatus , BlockError > {
34193433 let slot = blob. slot ( ) ;
34203434 if let Some ( slasher) = self . slasher . as_ref ( ) {
34213435 slasher. accept_block_header ( blob. signed_block_header ( ) ) ;
34223436 }
34233437 let availability = self . data_availability_checker . put_gossip_blob ( blob) ?;
34243438
3425- self . process_availability ( slot, availability) . await
3439+ self . process_availability ( slot, availability, publish_fn)
3440+ . await
34263441 }
34273442
34283443 /// Checks if the provided data column can make any cached blocks available, and imports immediately
@@ -3432,6 +3447,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
34323447 slot : Slot ,
34333448 block_root : Hash256 ,
34343449 data_columns : Vec < GossipVerifiedDataColumn < T > > ,
3450+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
34353451 ) -> Result <
34363452 (
34373453 AvailabilityProcessingStatus ,
@@ -3449,7 +3465,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
34493465 . data_availability_checker
34503466 . put_gossip_data_columns ( slot, block_root, data_columns) ?;
34513467
3452- self . process_availability ( slot, availability)
3468+ self . process_availability ( slot, availability, publish_fn )
34533469 . await
34543470 . map ( |result| ( result, data_columns_to_publish) )
34553471 }
@@ -3490,7 +3506,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
34903506 . data_availability_checker
34913507 . put_rpc_blobs ( block_root, epoch, blobs) ?;
34923508
3493- self . process_availability ( slot, availability) . await
3509+ self . process_availability ( slot, availability, || Ok ( ( ) ) )
3510+ . await
34943511 }
34953512
34963513 /// Checks if the provided columns can make any cached blocks available, and imports immediately
@@ -3538,7 +3555,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
35383555 custody_columns,
35393556 ) ?;
35403557
3541- self . process_availability ( slot, availability)
3558+ self . process_availability ( slot, availability, || Ok ( ( ) ) )
35423559 . await
35433560 . map ( |result| ( result, data_columns_to_publish) )
35443561 }
@@ -3551,9 +3568,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
35513568 self : & Arc < Self > ,
35523569 slot : Slot ,
35533570 availability : Availability < T :: EthSpec > ,
3571+ publish_fn : impl FnOnce ( ) -> Result < ( ) , BlockError > ,
35543572 ) -> Result < AvailabilityProcessingStatus , BlockError > {
35553573 match availability {
35563574 Availability :: Available ( block) => {
3575+ publish_fn ( ) ?;
35573576 // Block is fully available, import into fork choice
35583577 self . import_available_block ( block) . await
35593578 }
@@ -5684,10 +5703,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
56845703
56855704 let kzg_proofs = Vec :: from ( proofs) ;
56865705
5687- let kzg = self
5688- . kzg
5689- . as_ref ( )
5690- . ok_or ( BlockProductionError :: TrustedSetupNotInitialized ) ?;
5706+ let kzg = self . kzg . as_ref ( ) ;
5707+
56915708 kzg_utils:: validate_blobs :: < T :: EthSpec > (
56925709 kzg,
56935710 expected_kzg_commitments,
0 commit comments