Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
491b69f
proto node versioning
hopinheimer Feb 20, 2026
3e3ccba
adding michael commits
michaelsproul Dec 11, 2025
d5c5077
implement scoring mechanisms and plumbing
hopinheimer Feb 24, 2026
e04a8c3
adding tests and payload changes
hopinheimer Feb 26, 2026
6d74723
Merge branch 'unstable' of github.com:sigp/lighthouse into gloas-fc-p…
hopinheimer Feb 26, 2026
eb1b810
fixing test
hopinheimer Feb 26, 2026
59033a5
lint
hopinheimer Feb 26, 2026
e68cc03
vote sanity and genesis epoch fix
hopinheimer Mar 2, 2026
6f6da5b
lint
hopinheimer Mar 2, 2026
275ac11
test fixes
hopinheimer Mar 2, 2026
9c6f25c
fix migration `SszContainer` scripts
hopinheimer Mar 9, 2026
ca1b3eb
Merge branch 'unstable' into gloas-fc-proto
hopinheimer Mar 9, 2026
6fbb931
Merge branch 'unstable' of https://github.com/sigp/lighthouse into gl…
eserilev Mar 13, 2026
5679994
addressing comments
hopinheimer Mar 13, 2026
d89e7f7
Merge branch 'gloas-fc-proto' of github.com:hopinheimer/lighthouse in…
hopinheimer Mar 13, 2026
cf9e463
Merge branch 'unstable' into gloas-fc-proto
hopinheimer Mar 16, 2026
f747696
bitfield for `PTC` votes
hopinheimer Mar 16, 2026
97d1b7b
Merge branch 'gloas-fc-proto' of github.com:hopinheimer/lighthouse in…
hopinheimer Mar 16, 2026
0df749f
completing `should_extend_payload` implementation
hopinheimer Mar 16, 2026
916d9fb
changes
hopinheimer Mar 16, 2026
9ce88ea
addressing comments:
hopinheimer Mar 16, 2026
a7bcf0f
enable ef tests @brech1 commit
hopinheimer Mar 17, 2026
ffec1a1
enable ef tests @brech1 commit
hopinheimer Mar 17, 2026
5aa1192
unstable merge
hopinheimer Mar 17, 2026
46a909b
changes
hopinheimer Mar 17, 2026
ab1305d
Propagate weight to parent's full/empty variants
michaelsproul Mar 19, 2026
cc8466d
fixing recursive calls with caching
hopinheimer Mar 20, 2026
cb35ba6
Merge branch 'unstable' of github.com:sigp/lighthouse into fix-gloas-…
hopinheimer Mar 23, 2026
ce71471
passing ef tests ft. @dapplion
hopinheimer Mar 23, 2026
52e397f
Refactoring fork choice to look more like the spec
michaelsproul Mar 24, 2026
81b96a5
More spec compliance
michaelsproul Mar 25, 2026
c841603
Fix compilation issues
michaelsproul Mar 25, 2026
8b44886
Re-do head_payload_status
michaelsproul Mar 25, 2026
cec5ce1
Undo botched optimisation
michaelsproul Mar 25, 2026
845831c
Align GLOAS fork choice with spec
dapplion Mar 25, 2026
9f56fd0
Review fixes: cache should_apply_proposer_boost, improve error context
dapplion Mar 25, 2026
e943888
Fix test_03: update weight assertions for spec-parity boost
dapplion Mar 25, 2026
93ef1e3
Include head_payload_status in ForkChoiceView comparison
dapplion Mar 25, 2026
324c61d
Implement get_filtered_block_tree and fix remaining test failures
dapplion Mar 25, 2026
66f71b3
Remove unused params
michaelsproul Mar 25, 2026
2323b86
Merge remote-tracking branch 'origin/unstable' into gloas-walk-always
michaelsproul Mar 25, 2026
84679b1
Remove redundant invalid-node check from filter_block_tree
dapplion Mar 25, 2026
c7c82f8
Merge remote-tracking branch 'origin/gloas-walk-always' into gloas-wa…
michaelsproul Mar 25, 2026
e77651a
Revert changes in load_parent
michaelsproul Mar 25, 2026
fdf2fd2
Simplify reorg weight logic, TODO(gloas) for payload-aware version
dapplion Mar 25, 2026
9f1f68c
Add back AttestationFromBlock
michaelsproul Mar 25, 2026
a69a848
Remove expect
michaelsproul Mar 25, 2026
f1b261f
Safeguard attestation index check
michaelsproul Mar 25, 2026
d58df3a
Make proposer_index mandatory in on_block
michaelsproul Mar 26, 2026
e7f027b
O(n) children index, fix load_parent for gloas blocks
dapplion Mar 26, 2026
f31a936
Fix test review issues
dapplion Mar 26, 2026
a34b7c9
Fix CI: collapse nested if, ignore payload attestation test
dapplion Mar 26, 2026
bb3e9e1
Fix arithmetic lint in committee_cache (saturating_sub)
dapplion Mar 26, 2026
bc28e63
Revert "Fix arithmetic lint in committee_cache (saturating_sub)"
dapplion Mar 26, 2026
93f987f
Remove head_payload_status from ForkchoiceUpdateParameters
dapplion Mar 26, 2026
e676c33
Merge sigp/unstable into gloas-walk-always
dapplion Mar 26, 2026
c7670ed
Cleanup and spec parity fixes
dapplion Mar 26, 2026
ea1e99b
Add TODO for head_payload_status initialization (re: #8998)
dapplion Mar 26, 2026
ac53575
Source head_payload_status from get_head, not hardcoded Pending
dapplion Mar 26, 2026
12f5ab0
Load the state corresponding to head payload status yay
michaelsproul Mar 26, 2026
09e9a54
When a block comes in whose parent is unkown, queue the block for pro…
eserilev Mar 27, 2026
4c3fd70
Merge remote-tracking branch 'origin/unstable' into gloas-walk-always
michaelsproul Mar 30, 2026
419645c
Update CURRENT_SCHEMA_VERSION to 29
michaelsproul Mar 31, 2026
5c6e171
Add schema v29 migration
michaelsproul Mar 31, 2026
e1dcd9e
Update schema test
michaelsproul Mar 31, 2026
3bc1d88
Clarify load_parent genesis behaviour
michaelsproul Mar 31, 2026
517d16f
Revert parent->child optimisation
michaelsproul Mar 31, 2026
b6728c2
Start removing more best_child/best_descend
michaelsproul Mar 31, 2026
5353710
Fix compilation, clear best_child/best_descendant in migration
dapplion Mar 31, 2026
9f08f48
import envelope status into fc
eserilev Mar 31, 2026
a1534bb
Check `ChainSpec` consistency with upstream `config.yaml` (#9008)
michaelsproul Mar 30, 2026
6044d79
Fix local testnet Tempo and Prometheus/Grafana config (#9054)
jimmygchen Mar 31, 2026
6f480e4
Add range sync tests (#8989)
dapplion Mar 31, 2026
cd60ea8
Update to spec v1.7.0-alpha.4 (#9046)
michaelsproul Mar 31, 2026
7fe9da0
Add Gloas SSE event boilerplate (#9053)
dknopik Mar 31, 2026
e1cabb8
Merge branch 'unstable' into gloas-walk-always
eserilev Mar 31, 2026
367972b
Default to full payload status if the payload has been received
eserilev Mar 31, 2026
95a5839
Smol fix
eserilev Mar 31, 2026
7645064
Fix fc
eserilev Mar 31, 2026
77382da
Rvert
eserilev Mar 31, 2026
1eefef6
Resolve merge conflicts
eserilev Mar 31, 2026
a538d7b
resolve merge conflicts
eserilev Mar 31, 2026
0f996dd
sse stuff
eserilev Mar 31, 2026
4ca10e9
Add range sync machinery on sync side
pawanjay176 Mar 31, 2026
2a26474
Process envelopes correctly
pawanjay176 Mar 26, 2026
93d3343
Apply envelopes even if block is duplicate
pawanjay176 Mar 30, 2026
aa5292d
Fix replayer
pawanjay176 Mar 30, 2026
993cece
Clear best_child/best_descendant during V28->V29 conversion
dapplion Mar 31, 2026
1ee2ce4
Fix schema migrations
michaelsproul Mar 31, 2026
bc6cf0f
Remove payload attestation queueing and more cleanups
michaelsproul Apr 1, 2026
4684d97
Remove TOCTOU early return
michaelsproul Apr 1, 2026
51e78fd
Fix queued attestation decoding from disk
michaelsproul Apr 1, 2026
f6f9eae
More cleanup
michaelsproul Apr 1, 2026
ad0f3cf
Use None for post-Gloas payload hashes pre-Gloas
michaelsproul Apr 1, 2026
9ef73d0
Add new cross-boundary test
michaelsproul Apr 1, 2026
afb1f0a
Fix VoteTracker decoding
michaelsproul Apr 1, 2026
edae39c
Fix fork transition case
michaelsproul Apr 1, 2026
4e44cec
Fix markdown lint
michaelsproul Apr 1, 2026
ab023a7
Fix the VoteTrackerV28 definition
michaelsproul Apr 1, 2026
3cf19e7
Fix Gloas check in on_block
michaelsproul Apr 1, 2026
8716972
Add checkpoint sync
pawanjay176 Mar 31, 2026
08c5ec4
Fix fork choice bug
pawanjay176 Apr 1, 2026
ddff03d
Store parent_payload_hash in ProtoNode
michaelsproul Apr 1, 2026
f5b2445
Remove stupid GLOAS comments
michaelsproul Apr 1, 2026
39f0710
revert
eserilev Apr 1, 2026
dc5489d
Merge branch 'gloas-walk-always' of https://github.com/sigp/lighthous…
eserilev Apr 1, 2026
f6baea4
revert
eserilev Apr 1, 2026
5aae563
Remove proposer boost weight during upgrade
michaelsproul Apr 1, 2026
12e6595
revcert
eserilev Apr 1, 2026
d978e3d
revbert
eserilev Apr 1, 2026
2660856
Merge branch 'gloas-fork-choice-fixes' into epbs-devnet-1
eserilev Apr 1, 2026
a5bdd0c
Smol revert
eserilev Apr 1, 2026
5f8605f
Disable optimistic sync for Gloas
michaelsproul Apr 1, 2026
1c5a7be
Clarify name of `on_valid_payload_envelope_received`
michaelsproul Apr 1, 2026
958c8ca
Rename fork choice test def for clarity
michaelsproul Apr 2, 2026
69d7250
Tidy up payload attestation verification
michaelsproul Apr 2, 2026
bc7864b
Split out InvalidPayloadAttestation error
michaelsproul Apr 2, 2026
cc7e727
Tidy latest_message
michaelsproul Apr 2, 2026
727535b
Remove spurious payload attestation condition
michaelsproul Apr 2, 2026
d7f67da
Remove incorrect comment
michaelsproul Apr 2, 2026
6cc6584
Remove dead code
michaelsproul Apr 2, 2026
85934b4
Remove some noisy TODOs
michaelsproul Apr 2, 2026
5284486
Break out of invalidation loop on Gloas block
michaelsproul Apr 2, 2026
7570fd1
Remove comment
michaelsproul Apr 2, 2026
eceedaf
Revert parent->child optimisation AGAIN
michaelsproul Mar 31, 2026
6df5597
Simplify find_head_walk
michaelsproul Apr 2, 2026
f5413c6
Remove useless let _
michaelsproul Apr 2, 2026
a1296fc
Fix block_timeliness_ptc_threshold hardcoded constants
michaelsproul Apr 2, 2026
9db37b8
Document is_head_weak spec divergence and impact
dapplion Apr 2, 2026
6763862
Add attestation_due_bps_gloas and payload_attestation_due_bps to Chai…
dapplion Apr 2, 2026
68f18ef
Fix minimal spec
michaelsproul Apr 2, 2026
93cfa0f
Merge branch 'unstable' into gloas-parent-envelope-unknown-lookup
eserilev Apr 2, 2026
86ddd0d
Add EnvelopeRequestState logic
eserilev Apr 3, 2026
3523804
cleanup
eserilev Apr 3, 2026
1cd4d57
Fixes
eserilev Apr 3, 2026
214e3ce
Cleanup
eserilev Apr 3, 2026
f897215
refactor awaiting_parent field and some metrics
eserilev Apr 3, 2026
b333841
update
eserilev Apr 3, 2026
e7dd951
Resolve merge conflicts
eserilev Apr 3, 2026
a42444d
Merge branch 'gloas-walk-always' into epbs-devnet-1
eserilev Apr 3, 2026
5472c30
Relax requirements that a checkpoint state must be epoch aligned post…
eserilev Apr 4, 2026
9306767
add test
eserilev Apr 4, 2026
a12969a
Clean up
eserilev Apr 4, 2026
9c825cf
Fmt
eserilev Apr 4, 2026
818a83e
Resolve merge confclits from unstable
eserilev Apr 5, 2026
6419e60
Merge branch 'epbs-devnet-1' of https://github.com/sigp/lighthouse in…
eserilev Apr 5, 2026
2002651
merge conflicts
eserilev Apr 5, 2026
81262ad
Resolve merge conflicts
eserilev Apr 5, 2026
286b4dc
Resolve merge conflicts
eserilev Apr 5, 2026
0d36ee0
testing
eserilev Apr 5, 2026
c8f69b5
Temp dart throws
eserilev Apr 5, 2026
f7cf8fc
Temp fixes
eserilev Apr 6, 2026
4e8415f
Enable optimistic sync and change rate limitis
eserilev Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 115 additions & 8 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,28 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
)?
}

/// Returns the Pending (pre-payload) state root at the given slot in the canonical chain.
///
/// In ePBS (Gloas+), if the canonical state at `slot` is Full (post-payload), this resolves
/// to the same-slot Pending state root. For skipped slots or pre-Gloas, returns the canonical
/// state root unchanged.
pub fn pending_state_root_at_slot(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> {
let Some(root) = self.state_root_at_slot(request_slot)? else {
return Ok(None);
};

// Pre-Gloas: all states are inherently Pending.
if !self
.spec
.fork_name_at_slot::<T::EthSpec>(request_slot)
.gloas_enabled()
{
return Ok(Some(root));
}

Ok(Some(self.store.resolve_pending_state_root(&root)?))
}

/// Returns the block root at the given slot, if any. Only returns roots in the canonical chain.
///
/// ## Notes
Expand Down Expand Up @@ -2820,7 +2842,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
//
// Note that `check_block_relevancy` is incapable of returning
// `DuplicateImportStatusUnknown` so we don't need to handle that case here.
Err(BlockError::DuplicateFullyImported(_)) => continue,
//
// Gloas: keep duplicate blocks so their envelopes can still be processed
// in `process_chain_segment`. This handles the case where a node restarts
// before an envelope was persisted to the DB.
Err(BlockError::DuplicateFullyImported(_)) => {
if block.as_block().fork_name_unchecked().gloas_enabled() {
filtered_chain_segment.push((block_root, block));
}
}
// If the block is the genesis block, simply ignore this block.
Err(BlockError::GenesisBlock) => continue,
// If the block is is for a finalized slot, simply ignore this block.
Expand All @@ -2836,7 +2866,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// 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 { .. }) => {
// Gloas: keep blocks at finalized slots so their envelopes can
// still be processed. This handles the checkpoint sync case where
// the checkpoint block is already finalized but its envelope hasn't
// been stored yet.
if block.as_block().fork_name_unchecked().gloas_enabled() {
filtered_chain_segment.push((block_root, block));
}
}
// 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 }) => {
Expand Down Expand Up @@ -2905,6 +2943,39 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
};

// Strip already-known blocks (e.g. the checkpoint sync anchor) from the
// front of the segment and process only their envelopes. These blocks
// can't go through signature_verify_chain_segment because their parents
// may not be available.
while let Some((root, _)) = filtered_chain_segment.first() {
if !self
.canonical_head
.fork_choice_read_lock()
.contains_block(root)
{
break;
}
let (block_root, block) = filtered_chain_segment.remove(0);
let maybe_envelope = match block {
RangeSyncBlock::Gloas { envelope, .. } => envelope,
_ => None,
};
if let Some(envelope) = maybe_envelope
&& let Err(error) = self
.process_range_sync_envelope(
block_root,
envelope,
notify_execution_layer,
)
.await
{
return ChainSegmentResult::Failed {
imported_blocks,
error: BlockError::EnvelopeError(Box::new(error)),
};
}
}

while let Some((_root, block)) = filtered_chain_segment.first() {
// Determine the epoch of the first block in the remaining segment.
let start_epoch = block.epoch();
Expand Down Expand Up @@ -2944,12 +3015,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
};

// Import the blocks into the chain.
for signature_verified_block in signature_verified_blocks {
// Import the blocks (and envelopes for Gloas) into the chain.
for (signature_verified_block, maybe_envelope) in signature_verified_blocks {
let block_root = signature_verified_block.block_root();
let block_slot = signature_verified_block.slot();

match self
.process_block(
signature_verified_block.block_root(),
block_root,
signature_verified_block,
notify_execution_layer,
BlockImportSource::RangeSync,
Expand All @@ -2962,6 +3035,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
AvailabilityProcessingStatus::Imported(block_root) => {
// The block was imported successfully.
imported_blocks.push((block_root, block_slot));

// Gloas: process the envelope now that the block is in fork choice.
if let Some(envelope) = maybe_envelope
&& let Err(error) = self
.process_range_sync_envelope(
block_root,
envelope,
notify_execution_layer,
)
.await
{
return ChainSegmentResult::Failed {
imported_blocks,
error: BlockError::EnvelopeError(Box::new(error)),
};
}
}
AvailabilityProcessingStatus::MissingComponents(slot, block_root) => {
warn!(
Expand All @@ -2978,11 +3067,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
}
}
Err(BlockError::DuplicateFullyImported(block_root)) => {
Err(BlockError::DuplicateFullyImported(_))
| Err(BlockError::WouldRevertFinalizedSlot { .. }) => {
debug!(
?block_root,
"Ignoring already known blocks while processing chain segment"
"Ignoring already known block while processing chain segment"
);
// Gloas: still process the envelope for duplicate blocks. The envelope
// may not have been persisted before a restart, or the block may be the
// checkpoint sync anchor whose envelope was never stored.
if let Some(envelope) = maybe_envelope
&& let Err(error) = self
.process_range_sync_envelope(
block_root,
envelope,
notify_execution_layer,
)
.await
{
return ChainSegmentResult::Failed {
imported_blocks,
error: BlockError::EnvelopeError(Box::new(error)),
};
}
continue;
}
Err(error) => {
Expand Down Expand Up @@ -7185,7 +7292,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
block_data: AvailableBlockData<T::EthSpec>,
) -> Option<StoreOp<'_, T::EthSpec>> {
match block_data {
AvailableBlockData::NoData => None,
AvailableBlockData::NoData | AvailableBlockData::DataInEnvelope => None,
AvailableBlockData::Blobs(blobs) => {
debug!(
%block_root,
Expand Down
12 changes: 7 additions & 5 deletions beacon_node/beacon_chain/src/beacon_fork_choice_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ where
let mut anchor_state = anchor.beacon_state;
let mut anchor_block_header = anchor_state.latest_block_header().clone();

// The anchor state MUST be on an epoch boundary (it should be advanced by the caller).
if !anchor_state
.slot()
.as_u64()
.is_multiple_of(E::slots_per_epoch())
// Pre-gloas the anchor state MUST be on an epoch boundary (it should be advanced by the caller).
// Post-gloas this requirement is relaxed.
if !anchor_state.fork_name_unchecked().gloas_enabled()
&& !anchor_state
.slot()
.as_u64()
.is_multiple_of(E::slots_per_epoch())
{
return Err(Error::UnalignedCheckpoint {
block_slot: anchor_block_header.slot,
Expand Down
107 changes: 87 additions & 20 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ use crate::execution_payload::{
};
use crate::kzg_utils::blobs_to_data_column_sidecars;
use crate::observed_block_producers::SeenBlock;
use crate::payload_envelope_verification::{AvailableEnvelope, EnvelopeError};
use crate::validator_monitor::HISTORIC_EPOCHS as VALIDATOR_MONITOR_HISTORIC_EPOCHS;
use crate::validator_pubkey_cache::ValidatorPubkeyCache;
use crate::{
Expand Down Expand Up @@ -321,6 +322,20 @@ pub enum BlockError {
bid_parent_root: Hash256,
block_parent_root: Hash256,
},
/// The child block is known but its parent execution payload envelope has not been received yet.
///
/// ## Peer scoring
///
/// It's unclear if this block is valid, but it cannot be fully verified without the parent's
/// execution payload envelope.
ParentEnvelopeUnknown { parent_root: Hash256 },
/// An error occurred while processing the execution payload envelope during range sync.
EnvelopeError(Box<EnvelopeError>),

PayloadEnvelopeError {
e: Box<EnvelopeError>,
penalize_peer: bool,
},
}

/// Which specific signature(s) are invalid in a SignedBeaconBlock
Expand Down Expand Up @@ -487,6 +502,36 @@ impl From<ArithError> for BlockError {
}
}

impl From<EnvelopeError> for BlockError {
fn from(e: EnvelopeError) -> Self {
let penalize_peer = match &e {
// REJECT per spec: peer sent invalid envelope data
EnvelopeError::BadSignature
| EnvelopeError::BuilderIndexMismatch { .. }
| EnvelopeError::BlockHashMismatch { .. }
| EnvelopeError::SlotMismatch { .. }
| EnvelopeError::IncorrectBlockProposer { .. } => true,
// IGNORE per spec: not the peer's fault
EnvelopeError::BlockRootUnknown { .. }
| EnvelopeError::PriorToFinalization { .. }
| EnvelopeError::UnknownValidator { .. } => false,
// Internal errors: not the peer's fault
EnvelopeError::BeaconChainError(_)
| EnvelopeError::BeaconStateError(_)
| EnvelopeError::BlockProcessingError(_)
| EnvelopeError::EnvelopeProcessingError(_)
| EnvelopeError::ExecutionPayloadError(_)
| EnvelopeError::BlockError(_)
| EnvelopeError::InternalError(_)
| EnvelopeError::OptimisticSyncNotSupported { .. } => false,
};
BlockError::PayloadEnvelopeError {
e: Box::new(e),
penalize_peer,
}
}
}

/// Stores information about verifying a payload against an execution engine.
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
pub struct PayloadVerificationOutcome {
Expand Down Expand Up @@ -584,10 +629,17 @@ pub(crate) fn process_block_slash_info<T: BeaconChainTypes, TErr: BlockBlobError
/// The given `chain_segment` must contain only blocks from the same epoch, otherwise an error
/// will be returned.
#[instrument(skip_all)]
#[allow(clippy::type_complexity)]
pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
mut chain_segment: Vec<(Hash256, RangeSyncBlock<T::EthSpec>)>,
chain: &BeaconChain<T>,
) -> Result<Vec<SignatureVerifiedBlock<T>>, BlockError> {
) -> Result<
Vec<(
SignatureVerifiedBlock<T>,
Option<Box<AvailableEnvelope<T::EthSpec>>>,
)>,
BlockError,
> {
if chain_segment.is_empty() {
return Ok(vec![]);
}
Expand Down Expand Up @@ -616,14 +668,30 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
let consensus_context =
ConsensusContext::new(block.slot()).set_current_block_root(block_root);

let available_block = block.into_available_block();
let (available_block, envelope) = match block {
RangeSyncBlock::Base(ab) => (ab, None),
RangeSyncBlock::Gloas { block, envelope } => {
let ab = AvailableBlock::new(
block,
AvailableBlockData::DataInEnvelope,
&chain.data_availability_checker,
chain.spec.clone(),
)
.map_err(BlockError::AvailabilityCheck)?;
(ab, envelope)
}
};

available_blocks.push(available_block.clone());
signature_verified_blocks.push(SignatureVerifiedBlock {
block: MaybeAvailableBlock::Available(available_block),
block_root,
parent: None,
consensus_context,
});
signature_verified_blocks.push((
SignatureVerifiedBlock {
block: MaybeAvailableBlock::Available(available_block),
block_root,
parent: None,
consensus_context,
},
envelope,
));
}

chain
Expand All @@ -633,7 +701,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
// verify signatures
let pubkey_cache = get_validator_pubkey_cache(chain)?;
let mut signature_verifier = get_signature_verifier(&state, &pubkey_cache, &chain.spec);
for svb in &mut signature_verified_blocks {
for (svb, _) in &mut signature_verified_blocks {
signature_verifier
.include_all_signatures(svb.block.as_block(), &mut svb.consensus_context)?;
}
Expand All @@ -644,7 +712,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(

drop(pubkey_cache);

if let Some(signature_verified_block) = signature_verified_blocks.first_mut() {
if let Some((signature_verified_block, _)) = signature_verified_blocks.first_mut() {
signature_verified_block.parent = Some(parent);
}

Expand Down Expand Up @@ -1192,7 +1260,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
let result = info_span!("signature_verify").in_scope(|| signature_verifier.verify());
match result {
Ok(_) => {
// gloas blocks are always available.
// Gloas blocks are always available — data arrives via the envelope.
let maybe_available = if chain
.spec
.fork_name_at_slot::<T::EthSpec>(block.slot())
Expand All @@ -1201,7 +1269,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
MaybeAvailableBlock::Available(
AvailableBlock::new(
block,
AvailableBlockData::NoData,
AvailableBlockData::DataInEnvelope,
&chain.data_availability_checker,
chain.spec.clone(),
)
Expand Down Expand Up @@ -1971,14 +2039,13 @@ fn load_parent<T: BeaconChainTypes, B: AsBlock<T::EthSpec>>(
} else if let Ok(parent_bid_block_hash) = parent_block.payload_bid_block_hash()
&& block.as_block().is_parent_block_full(parent_bid_block_hash)
{
// Post-Gloas Full block case.
// TODO(gloas): loading the envelope here is not very efficient
let Some(envelope) = chain.store.get_payload_envelope(&root)? else {
return Err(BeaconChainError::DBInconsistent(format!(
"Missing envelope for parent block {root:?}",
))
.into());
};
// 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.
let envelope = chain
.store
.get_payload_envelope(&root)?
.ok_or(BlockError::ParentEnvelopeUnknown { parent_root: root })?;
let state_root = envelope.message.state_root;
(StatePayloadStatus::Full, state_root)
} else {
Expand Down
Loading
Loading