@@ -54,6 +54,7 @@ impl BlockChain {
5454 p2p_tx,
5555 key_manager,
5656 pending_blocks : HashMap :: new ( ) ,
57+ pending_block_parents : HashMap :: new ( ) ,
5758 }
5859 . start ( ) ;
5960 let time_until_genesis = ( SystemTime :: UNIX_EPOCH + Duration :: from_secs ( genesis_time) )
@@ -93,6 +94,10 @@ struct BlockChainServer {
9394
9495 // Pending blocks waiting for their parent
9596 pending_blocks : HashMap < H256 , Vec < SignedBlockWithAttestation > > ,
97+ // Maps pending block_root → the oldest missing ancestor in its chain.
98+ // Single lookup replaces walking the chain, safe because processing is synchronous:
99+ // once the missing ancestor arrives, the entire chain is processed and all entries removed.
100+ pending_block_parents : HashMap < H256 , H256 > ,
96101}
97102
98103impl BlockChainServer {
@@ -283,14 +288,24 @@ impl BlockChainServer {
283288 if !self . store . has_state ( & parent_root) {
284289 info ! ( %slot, %parent_root, %block_root, "Block parent missing, storing as pending" ) ;
285290
291+ // Resolve the actual missing ancestor: if the parent is itself pending,
292+ // reuse its cached missing ancestor. Otherwise the parent IS the missing block.
293+ let missing_root = self
294+ . pending_block_parents
295+ . get ( & parent_root)
296+ . copied ( )
297+ . unwrap_or ( parent_root) ;
298+
299+ self . pending_block_parents . insert ( block_root, missing_root) ;
300+
286301 // Store block for later processing
287302 self . pending_blocks
288303 . entry ( parent_root)
289304 . or_default ( )
290305 . push ( signed_block) ;
291306
292- // Request missing parent from network
293- self . request_missing_block ( parent_root ) ;
307+ // Request the actual missing block from network
308+ self . request_missing_block ( missing_root ) ;
294309 return ;
295310 }
296311
@@ -339,9 +354,13 @@ impl BlockChainServer {
339354 "Processing pending blocks after parent arrival" ) ;
340355
341356 for child_block in children {
357+ let block_root = child_block. message . block . tree_hash_root ( ) ;
342358 let slot = child_block. message . block . slot ;
343359 trace ! ( %parent_root, %slot, "Processing pending child block" ) ;
344360
361+ // Clean up lineage tracking
362+ self . pending_block_parents . remove ( & block_root) ;
363+
345364 // Process recursively - might unblock more descendants
346365 self . on_block ( child_block) ;
347366 }
0 commit comments