This commit is contained in:
Eitan Seri-Levi
2026-05-01 22:18:15 +02:00
parent 7e502a5e65
commit d6e3b006ea
3 changed files with 76 additions and 2 deletions

View File

@@ -3185,11 +3185,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}; };
// Import the blocks into the chain. // Import the blocks into the chain.
for (signature_verified_block, _envelope) in signature_verified_blocks { for (signature_verified_block, envelope) in signature_verified_blocks {
let block_slot = signature_verified_block.slot(); let block_slot = signature_verified_block.slot();
let block_root = signature_verified_block.block_root();
match self match self
.process_block( .process_block(
signature_verified_block.block_root(), block_root,
signature_verified_block, signature_verified_block,
notify_execution_layer, notify_execution_layer,
BlockImportSource::RangeSync, BlockImportSource::RangeSync,
@@ -3200,6 +3201,17 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(status) => { Ok(status) => {
match status { match status {
AvailabilityProcessingStatus::Imported(block_root) => { AvailabilityProcessingStatus::Imported(block_root) => {
// Import the envelope if one was provided (Gloas+).
if let Some(envelope) = envelope
&& let Err(e) = self.import_envelope_from_range_sync(
*envelope, block_root,
)
{
return ChainSegmentResult::Failed {
imported_blocks,
error: e,
};
}
// The block was imported successfully. // The block was imported successfully.
imported_blocks.push((block_root, block_slot)); imported_blocks.push((block_root, block_slot));
} }

View File

@@ -2019,10 +2019,20 @@ fn load_parent<T: BeaconChainTypes, B: AsBlock<T::EthSpec>>(
// If the parent's execution payload envelope hasn't arrived yet, // If the parent's execution payload envelope hasn't arrived yet,
// return an unknown parent error so the block gets sent to the // return an unknown parent error so the block gets sent to the
// reprocess queue. // reprocess queue.
//
// Skip this check if the parent is at or before the finalized slot (e.g. after
// checkpoint sync the finalized block won't have a stored envelope).
let finalized_slot = chain
.canonical_head
.cached_head()
.finalized_checkpoint()
.epoch
.start_slot(T::EthSpec::slots_per_epoch());
if chain if chain
.spec .spec
.fork_name_at_slot::<T::EthSpec>(parent_block.slot()) .fork_name_at_slot::<T::EthSpec>(parent_block.slot())
.gloas_enabled() .gloas_enabled()
&& parent_block.slot() > finalized_slot
{ {
let _envelope = chain let _envelope = chain
.store .store

View File

@@ -392,4 +392,56 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
)); ));
} }
} }
/// Import an execution payload envelope received via range sync.
///
/// This is a simplified import path that trusts the envelope since it was fetched alongside
/// a valid block during range sync. It stores the envelope to the database and marks it as
/// received in fork choice.
pub fn import_envelope_from_range_sync(
&self,
envelope: AvailableEnvelope<T::EthSpec>,
block_root: Hash256,
) -> Result<(), BlockError> {
let fork_choice_reader = self.canonical_head.fork_choice_upgradable_read_lock();
if !fork_choice_reader.contains_block(&block_root) {
return Err(BlockError::EnvelopeBlockRootUnknown(block_root));
}
let mut fork_choice = parking_lot::RwLockUpgradableReadGuard::upgrade(fork_choice_reader);
fork_choice
.on_valid_payload_envelope_received(block_root)
.map_err(|e| BlockError::InternalError(format!("{e:?}")))?;
let (signed_envelope, columns) = envelope.deconstruct();
let mut ops = vec![];
if let Some(blobs_or_columns_store_op) = self.get_blobs_or_columns_store_op(
block_root,
signed_envelope.slot(),
AvailableBlockData::DataColumns(columns),
) {
ops.push(blobs_or_columns_store_op);
}
ops.push(StoreOp::PutPayloadEnvelope(
block_root,
signed_envelope,
));
drop(fork_choice);
if let Err(e) = self.store.do_atomically_with_block_and_blobs_cache(ops) {
error!(
msg = "Failed to store range sync envelope",
error = ?e,
"Database write failed!"
);
return Err(e.into());
}
Ok(())
}
} }