From 75d4333776c25f7bdf7d975504fe24c37e1500fc Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 4 May 2026 15:46:48 +0300 Subject: [PATCH] Hack for checkpoint sync --- beacon_node/beacon_chain/src/beacon_chain.rs | 24 ++++++++++++++++++- .../beacon_chain/src/block_verification.rs | 9 +++---- .../network_beacon_processor/sync_methods.rs | 10 ++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index d5920928aa..190988589e 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -3041,7 +3041,29 @@ impl BeaconChain { // In the case of (2), skipping the block is valid since we should never import it. // However, we will potentially get a `ParentUnknown` on a later block. The sync // protocol will need to ensure this is handled gracefully. - Err(BlockError::WouldRevertFinalizedSlot { .. }) => continue, + Err(BlockError::WouldRevertFinalizedSlot { .. }) => { + // For Gloas blocks, persist the envelope even though we're skipping + // the block. This is needed after checkpoint sync: the checkpoint + // block's envelope must be in the store so that `load_parent` can + // verify it when importing the first post-checkpoint block. + if let RangeSyncBlock::Gloas { + envelope: Some(ref available_envelope), + .. + } = block + { + let (signed_envelope, _columns) = available_envelope.clone().deconstruct(); + if let Err(e) = self + .store + .put_payload_envelope(&block_root, &signed_envelope) + { + return Err(Box::new(ChainSegmentResult::Failed { + imported_blocks, + error: BlockError::BeaconChainError(Box::new(e.into())), + })); + } + } + continue; + } // The block has a known parent that does not descend from the finalized block. // There is no need to process this block or any children. Err(BlockError::NotFinalizedDescendant { block_parent_root }) => { diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 7a81a4465e..9b6e71ccbf 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -2017,10 +2017,11 @@ fn load_parent>( // If the parent's execution payload envelope hasn't arrived yet, // return an unknown parent error so the block gets sent to the // reprocess queue. - if chain - .spec - .fork_name_at_slot::(parent_block.slot()) - .gloas_enabled() + if parent_block.slot() != 0 + && chain + .spec + .fork_name_at_slot::(parent_block.slot()) + .gloas_enabled() { let _envelope = chain .store diff --git a/beacon_node/network/src/network_beacon_processor/sync_methods.rs b/beacon_node/network/src/network_beacon_processor/sync_methods.rs index 8f89b66948..968120b4bf 100644 --- a/beacon_node/network/src/network_beacon_processor/sync_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/sync_methods.rs @@ -864,6 +864,16 @@ impl NetworkBeaconProcessor { peer_action: Some(PeerAction::LowToleranceError), }) } + BlockError::ParentEnvelopeUnknown { parent_root } => { + Err(ChainSegmentFailed { + message: format!( + "Block's parent envelope has not been received: {}", + parent_root + ), + // Don't penalize the peer, the envelope may arrive later. + peer_action: None, + }) + } BlockError::DuplicateFullyImported(_) | BlockError::DuplicateImportStatusUnknown(..) => { // This can happen for many reasons. Head sync's can download multiples and parent