Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
9947031
Add InclusionList and SignedInclusionList types
conache Jul 13, 2026
3bc8458
Add IL committee size to the EthSpec trait
conache Jul 13, 2026
4d5751f
Add Heze presets
conache Jul 13, 2026
1a98507
Add IL committee domain constant
conache Jul 13, 2026
175191d
Add il due bps and IL p2p limits constants
conache Jul 13, 2026
7e1f9ff
Add il deadline bps validation
conache Jul 13, 2026
b7da74e
Add min_slots_for_inclusion_lists_requests constant
conache Jul 28, 2026
035a281
Convert ExecutionPayloadBid to a fork-aware superstruct and propagate…
conache Jul 14, 2026
aafc704
Remove unused imports
conache Jul 14, 2026
bd850f9
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 1, 2026
a9c1355
Merge branch 'unstable' of https://github.com/sigp/lighthouse into fo…
conache Aug 4, 2026
9e934e4
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 5, 2026
4e52244
Fix tests after merge
conache Aug 5, 2026
db3bfb7
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 6, 2026
04b3841
Fix tests after merge
conache Aug 6, 2026
106e947
Add test ensuring il bits are covered in Heze bid signing_root
conache Aug 6, 2026
d47295f
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 10, 2026
37186d0
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 10, 2026
8f3af57
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 12, 2026
469c65c
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 13, 2026
320ad2c
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 16, 2026
21c78e2
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 18, 2026
3645ddc
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 18, 2026
932cd19
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Aug 24, 2026
81251c2
Fix types in test files
conache Aug 24, 2026
cbe0a48
Merge remote-tracking branch 'sigp/unstable' into focil-add-il-bits-t…
conache Aug 30, 2026
14a153c
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 4, 2026
0a5f7f0
Fix beacon state initialization from genesis data for Heze
conache Sep 4, 2026
0fbc86c
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 8, 2026
b23ca44
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 10, 2026
7b03c92
Explicitly handle each fork variant when generating unsigned genesis …
conache Sep 15, 2026
078bad1
Decode execution payload bids based on the consensus version header
conache Sep 15, 2026
b402621
Make the execution payload bid size check fork-aware
conache Sep 15, 2026
16992ef
Avoid cloning the bid when constructing an AvailableEnvelope
conache Sep 16, 2026
2e52066
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 16, 2026
853a0a4
Fix: produce Heze execution payload bids
conache Sep 16, 2026
0f76601
Ensure BN execution payload bids endpoints are tested against Heze va…
conache Sep 16, 2026
11d330a
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 17, 2026
d8fa811
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 18, 2026
9ca662c
Fix compilation error
conache Sep 18, 2026
b6f849a
Add gossip il bits inclusivity check for execution payload bids
conache Sep 18, 2026
acb18a0
Add bid il bits inclusivity checks tests
conache Sep 19, 2026
be945a4
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 19, 2026
6067991
Ensure IL dependent root is determined based on the bid's parent bloc…
conache Sep 20, 2026
68fd607
Use clearer comment for InclusionListBitsNotInclusive error
conache Sep 20, 2026
2e6c4fa
Umprove gloas bid check
conache Sep 20, 2026
62d2f8a
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 23, 2026
6505b5f
Add inclusion list bits check helper
conache Sep 24, 2026
3cdb993
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 26, 2026
4bd592d
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Sep 28, 2026
7cb32a0
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 29, 2026
c01be14
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Sep 29, 2026
c883699
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Sep 30, 2026
aea0759
Use Box for the process_block future in the weak_subjectivity_sync_te…
conache Sep 30, 2026
f6fd3b1
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Sep 30, 2026
d383fa3
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 1, 2026
7178d6c
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Oct 1, 2026
e9463c4
Remove redundant TODO
conache Oct 6, 2026
3a64770
Check the bid variant matches the fork at its slot
conache Oct 6, 2026
38f3e1b
Ensure bids are pushed to the correct topic at the fork boundary
conache Oct 6, 2026
e6373b6
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 6, 2026
f265250
Publish bids through publish_fork_digest
conache Oct 6, 2026
ff4746e
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Oct 6, 2026
2509c91
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 7, 2026
e5e704b
List fork variants explicitly and require ContextDeserialize for bids
conache Oct 7, 2026
dc3547b
Add bid variant check for the direct path bids
conache Oct 7, 2026
59db449
Skip bids whose variant doesn't match the fork at their slot on block…
conache Oct 7, 2026
abb6630
Check the builder bid variant matches the requested fork
conache Oct 7, 2026
7f3ea1f
Move gossip bounds in eth spec and add heze variant
conache Oct 7, 2026
b8da456
Test bid variant mismatches on the direct path
conache Oct 7, 2026
805f754
Add test for Gloas bid at the Heze fork boundary on the gossip path
conache Oct 7, 2026
4969cc1
Re-add deny_unknown_fields on the bid variants
conache Oct 7, 2026
5769b3e
Box block production and import futures in the test harness
conache Oct 7, 2026
9b3425f
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 7, 2026
ccb2317
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 7, 2026
3022a0f
Fix bid commitments access after merging unstable
eserilev Oct 7, 2026
4a914b2
Merge branch 'unstable' into focil-add-il-bits-to-bid
conache Oct 8, 2026
72c4587
Merge branch 'focil-add-il-bits-to-bid' into focil-payload-bid-il-bit…
conache Oct 8, 2026
2816df4
Fix tests
conache Oct 8, 2026
7e274ae
Add Heze fork boundary test
conache Oct 8, 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
33 changes: 22 additions & 11 deletions beacon_node/beacon_chain/src/inclusion_list_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
//! keyed by `(slot, dependent_root)`, which pins an inclusion list to the committee it was produced
//! against.

use ssz_types::{BitVector, ProgressiveVariableList};
use ssz_types::ProgressiveVariableList;
use std::collections::{HashMap, HashSet};
use std::marker::PhantomData;
use tree_hash::TreeHash;
use types::{ChainSpec, EthSpec, Hash256, InclusionListCommittee, SignedInclusionList, Slot};
use types::{
ChainSpec, EthSpec, Hash256, InclusionListBits, InclusionListCommittee, SignedInclusionList,
Slot,
};

/// The shuffling `dependent_root` an inclusion list was produced against.
pub type DependentRoot = Hash256;
Expand Down Expand Up @@ -63,6 +66,19 @@ pub struct InclusionListStore<E: EthSpec> {
_phantom: PhantomData<E>,
}

/// Returns whether `bits` is inclusive of `local`: every bit set in `local` is also set in `bits`.
pub fn inclusion_list_bits_are_inclusive<E: EthSpec>(
local: &InclusionListBits<E>,
bits: &InclusionListBits<E>,
) -> Result<bool, Error> {
for i in 0..local.len() {
if local.get(i)? && !bits.get(i)? {
return Ok(false);
}
}
Ok(true)
}

impl<E: EthSpec> InclusionListStore<E> {
pub fn new(spec: &ChainSpec) -> Self {
// `heze_fork_epoch` holds the far future sentinel when Heze is unscheduled.
Expand Down Expand Up @@ -211,10 +227,10 @@ impl<E: EthSpec> InclusionListStore<E> {
dependent_root: DependentRoot,
il_committee: &InclusionListCommittee<E>,
only_timely: bool,
) -> Result<BitVector<E::InclusionListCommitteeSize>, Error> {
) -> Result<InclusionListBits<E>, Error> {
let submitted = self.submitted_validators(slot, dependent_root, only_timely);

let mut bits = BitVector::new();
let mut bits = InclusionListBits::<E>::new();
for (i, validator) in il_committee.iter().enumerate() {
if submitted.contains(validator) {
bits.set(i, true)?;
Expand All @@ -230,17 +246,12 @@ impl<E: EthSpec> InclusionListStore<E> {
slot: Slot,
dependent_root: DependentRoot,
il_committee: &InclusionListCommittee<E>,
bits: &BitVector<E::InclusionListCommitteeSize>,
bits: &InclusionListBits<E>,
only_timely: bool,
) -> Result<bool, Error> {
let local =
self.get_inclusion_list_bits(slot, dependent_root, il_committee, only_timely)?;
for i in 0..local.len() {
if local.get(i)? && !bits.get(i)? {
return Ok(false);
}
}
Ok(true)
inclusion_list_bits_are_inclusive::<E>(&local, bits)
}

/// The stored signed inclusion lists for the given `validators`, used to serve
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::Arc;

use crate::inclusion_list_store::{InclusionListStore, inclusion_list_bits_are_inclusive};
use crate::{
BeaconChain, BeaconChainTypes, BeaconStore, CachedHead, CanonicalHead,
canonical_head::ForkChoiceReadGuard,
Expand All @@ -12,6 +13,7 @@ use crate::{
};
use educe::Educe;
use eth2::types::{EventKind, ForkVersionedResponse};
use parking_lot::RwLock;
use proto_array::{Block as ProtoBlock, PayloadBlockHash};
use slot_clock::SlotClock;
use state_processing::signature_sets::{
Expand All @@ -20,7 +22,7 @@ use state_processing::signature_sets::{
use tracing::debug;
use types::{
BeaconState, Builder, ChainSpec, EthSpec, ExecutionPayloadBidRef, ExecutionRequestsGloas,
SignedExecutionPayloadBid, SignedProposerPreferences, Slot,
InclusionListBits, RelativeEpoch, SignedExecutionPayloadBid, SignedProposerPreferences, Slot,
consts::gloas::PAYLOAD_BUILDER_VERSION,
};

Expand Down Expand Up @@ -83,6 +85,34 @@ fn verify_bid_blobs<E: EthSpec>(
Ok(())
}

/// Reject a bid whose `inclusion_list_bits` do not cover `local_inclusion_list_bits`, the node's
/// own view of the inclusion lists for the slot before the bid's. Pre-Heze bids carry no bits and pass.
///
/// Callers resolve `local_inclusion_list_bits` under their own timeliness rule.
/// On gossip only timely inclusion lists count, while for the proposer's block production path
/// both timely and untimely inclusion lists count.
pub(crate) fn verify_bid_inclusion_list_bits<E: EthSpec>(
bid: ExecutionPayloadBidRef<E>,
local_inclusion_list_bits: &InclusionListBits<E>,
) -> Result<(), PayloadBidError> {
let ExecutionPayloadBidRef::Heze(bid) = bid else {
return Ok(());
};

let inclusion_list_inclusive =
inclusion_list_bits_are_inclusive::<E>(local_inclusion_list_bits, &bid.inclusion_list_bits)
.map_err(|e| {
PayloadBidError::InternalError(format!(
"inclusion list bits inclusivity check error: {e:?}"
))
})?;

if !inclusion_list_inclusive {
return Err(PayloadBidError::InclusionListBitsNotInclusive { slot: bid.slot });
}
Ok(())
}

/// Verify that a direct (builder-API) bid is consistent with the current chain state
/// and proposer preferences: the direct path's bundle of the shared bid checks.
///
Expand Down Expand Up @@ -265,6 +295,7 @@ pub struct GossipVerificationContext<'a, T: BeaconChainTypes> {
pub observed_execution_payloads: &'a ObservedExecutionPayloads,
pub gossip_verified_payload_bid_cache: &'a GossipVerifiedPayloadBidCache<T::EthSpec>,
pub gossip_verified_proposer_preferences_cache: &'a GossipVerifiedProposerPreferenceCache,
pub inclusion_list_store: &'a RwLock<InclusionListStore<T::EthSpec>>,
pub slot_clock: &'a T::SlotClock,
pub spec: &'a ChainSpec,
pub store: &'a BeaconStore<T>,
Expand Down Expand Up @@ -459,6 +490,48 @@ impl<E: EthSpec> GossipVerifiedPayloadBid<E> {
});
}

// [IGNORE] `bid.inclusion_list_bits` is inclusive of the node's view of the inclusion
// lists for the slot preceding the bid's slot.
if ctx
.spec
.fork_name_at_slot::<T::EthSpec>(bid_slot)
.heze_enabled()
{
let inclusion_list_slot = bid_slot.saturating_sub(1u64);
let inclusion_list_epoch = inclusion_list_slot.epoch(T::EthSpec::slots_per_epoch());
let relative_epoch =
RelativeEpoch::from_epoch(head_state.current_epoch(), inclusion_list_epoch)
.map_err(|e| {
PayloadBidError::InternalError(format!(
"inclusion list epoch {inclusion_list_epoch} out of range: {e:?}"
))
})?;

// determine inclusion list dependent root and committee necessary for determining
// the inclusion list bits for the inclusivity check
let inclusion_list_dependent_root = head_state.attester_shuffling_decision_root(
signed_bid.message().parent_block_root(),
relative_epoch,
)?;
let inclusion_list_committee =
head_state.get_inclusion_list_committee(inclusion_list_slot)?;

// Only the timely inclusion lists count on gossip
let local_inclusion_list_bits = ctx
.inclusion_list_store
.read()
.get_inclusion_list_bits(
inclusion_list_slot,
inclusion_list_dependent_root,
&inclusion_list_committee,
true,
)
.map_err(|e| {
PayloadBidError::InternalError(format!("inclusion list store: {e:?}"))
})?;
verify_bid_inclusion_list_bits(signed_bid.message(), &local_inclusion_list_bits)?;
}

execution_payload_bid_signature_set(
head_state,
|i| get_builder_pubkey_from_state(head_state, i),
Expand Down Expand Up @@ -489,6 +562,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
gossip_verified_payload_bid_cache: &self.gossip_verified_payload_bid_cache,
gossip_verified_proposer_preferences_cache: &self
.gossip_verified_proposer_preferences_cache,
inclusion_list_store: &self.inclusion_list_store,
slot_clock: &self.slot_clock,
spec: &self.spec,
store: &self.store,
Expand Down
3 changes: 3 additions & 0 deletions beacon_node/beacon_chain/src/payload_bid_verification/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ pub enum PayloadBidError {
},
/// The bids prev randao value is invalid
InvalidPrevRandao { slot: Slot },
/// The bid's `inclusion_list_bits` do not cover every timely inclusion list
/// the node holds for `slot - 1`
InclusionListBitsNotInclusive { slot: Slot },
/// Some Beacon State error
BeaconStateError(BeaconStateError),
/// The bid's variant does not match the fork at its slot.
Expand Down
Loading
Loading