@@ -339,23 +339,64 @@ func (c *Conns) Nodes() []*enode.Node {
339339}
340340
341341// AddTx adds a transaction to the shared cache for duplicate detection and serving.
342- // Stores actual tx if broadcasting enabled, nil otherwise to mark as seen.
343342func (c * Conns ) AddTx (hash common.Hash , tx * types.Transaction ) {
344- if c .shouldBroadcastTx || c .shouldBroadcastTxHashes {
345- c .txs .Add (hash , tx )
346- } else {
347- c .txs .Add (hash , nil )
348- }
343+ c .txs .Add (hash , tx )
349344}
350345
351346// AddBlock adds a block to the shared cache for duplicate detection and serving.
352- // Stores actual block if broadcasting enabled, nil otherwise to mark as seen.
353347func (c * Conns ) AddBlock (hash common.Hash , block * types.Block ) {
354- if c .shouldBroadcastBlocks || c .shouldBroadcastBlockHashes {
355- c .blocks .Add (hash , block )
356- } else {
357- c .blocks .Add (hash , nil )
348+ c .blocks .Add (hash , block )
349+ }
350+
351+ // AddBlockHeader adds a block header to the cache. If a block already exists with a real header, does nothing.
352+ // If a block exists with an empty header (body received first), replaces it with the real header.
353+ // Otherwise creates a new block with just the header.
354+ func (c * Conns ) AddBlockHeader (header * types.Header ) {
355+ hash := header .Hash ()
356+
357+ // Check if block already exists in cache
358+ block , ok := c .blocks .Get (hash )
359+ if ! ok {
360+ // No block exists, create new one with header only
361+ c .AddBlock (hash , types .NewBlockWithHeader (header ))
362+ return
363+ }
364+
365+ // Check if existing block has a real header already
366+ if block .Number () != nil && block .Number ().Uint64 () > 0 {
367+ // Block already has a real header, don't overwrite
368+ return
369+ }
370+
371+ // Block has empty header (body came first), replace with real header + keep body
372+ b := types .NewBlockWithHeader (header ).WithBody (types.Body {
373+ Transactions : block .Transactions (),
374+ Uncles : block .Uncles (),
375+ Withdrawals : block .Withdrawals (),
376+ })
377+ c .AddBlock (hash , b )
378+ }
379+
380+ // AddBlockBody adds a body to an existing block in the cache. If no block exists for this hash,
381+ // creates a block with an empty header and the body. If a block exists with only a header, updates it with the body.
382+ func (c * Conns ) AddBlockBody (hash common.Hash , body * eth.BlockBody ) {
383+ // Get existing block from cache
384+ block , ok := c .blocks .Get (hash )
385+ if ! ok {
386+ // No header yet, create block with empty header and body
387+ blockWithBody := types .NewBlockWithHeader (& types.Header {}).WithBody (types .Body (* body ))
388+ c .AddBlock (hash , blockWithBody )
389+ return
390+ }
391+
392+ // Check if block already has a body
393+ if len (block .Transactions ()) > 0 || len (block .Uncles ()) > 0 || len (block .Withdrawals ()) > 0 {
394+ // Block already has a body, no need to update
395+ return
358396 }
397+
398+ // Reconstruct full block with existing header and body
399+ c .AddBlock (hash , block .WithBody (types .Body (* body )))
359400}
360401
361402// GetTx retrieves a transaction from the shared cache.
@@ -368,6 +409,18 @@ func (c *Conns) GetBlock(hash common.Hash) (*types.Block, bool) {
368409 return c .blocks .Get (hash )
369410}
370411
412+ // HasBlockHeader checks if we have at least a header for a block in the cache.
413+ // Returns true if we have a block with a real header (number > 0).
414+ func (c * Conns ) HasBlockHeader (hash common.Hash ) bool {
415+ block , ok := c .blocks .Get (hash )
416+ if ! ok {
417+ return false
418+ }
419+
420+ // Check if block has a real header (not empty)
421+ return block .Number () != nil && block .Number ().Uint64 () > 0
422+ }
423+
371424// GetPeerConnectedAt returns the time when a peer connected, or zero time if not found.
372425func (c * Conns ) GetPeerConnectedAt (url string ) time.Time {
373426 c .mu .RLock ()
0 commit comments