il inclusion list inclusive

This commit is contained in:
Eitan Seri-Levi
2026-04-30 12:53:51 +02:00
parent 8559bf0e10
commit b4ac2eefda
2 changed files with 64 additions and 7 deletions

View File

@@ -545,11 +545,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
| BeaconState::Deneb(_) | BeaconState::Deneb(_)
| BeaconState::Electra(_) | BeaconState::Electra(_)
| BeaconState::Fulu(_) | BeaconState::Fulu(_)
| BeaconState::Heze(_) => {
return Err(BlockProductionError::InvalidBlockVariant(
"Cannot construct a block pre-Gloas".to_owned(),
));
}
BeaconState::Gloas(_) => BeaconBlock::Gloas(BeaconBlockGloas { BeaconState::Gloas(_) => BeaconBlock::Gloas(BeaconBlockGloas {
slot, slot,
proposer_index, proposer_index,
@@ -588,6 +583,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}), }),
BeaconState::Heze(_) => { BeaconState::Heze(_) => {
let gloas_bid = signed_execution_payload_bid; let gloas_bid = signed_execution_payload_bid;
// Compute inclusion_list_bits for the previous slot's ILs
let il_slot = slot.saturating_sub(1_u64);
let inclusion_list_bits = state
.get_inclusion_list_committee(il_slot, &self.spec)
.map(|committee| {
self.inclusion_list_cache
.read()
.get_inclusion_list_bits(il_slot, &committee, false)
})
.unwrap_or_default();
let heze_bid = SignedExecutionPayloadBidHeze { let heze_bid = SignedExecutionPayloadBidHeze {
message: ExecutionPayloadBidHeze { message: ExecutionPayloadBidHeze {
parent_block_hash: gloas_bid.message.parent_block_hash, parent_block_hash: gloas_bid.message.parent_block_hash,
@@ -602,7 +607,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
execution_payment: gloas_bid.message.execution_payment, execution_payment: gloas_bid.message.execution_payment,
blob_kzg_commitments: gloas_bid.message.blob_kzg_commitments, blob_kzg_commitments: gloas_bid.message.blob_kzg_commitments,
execution_requests_root: gloas_bid.message.execution_requests_root, execution_requests_root: gloas_bid.message.execution_requests_root,
inclusion_list_bits: Default::default(), inclusion_list_bits,
}, },
signature: gloas_bid.signature, signature: gloas_bid.signature,
}; };

View File

@@ -1,4 +1,5 @@
use crate::{EthSpec, SignedInclusionList, Slot, Transaction, Transactions}; use crate::{EthSpec, InclusionListCommittee, SignedInclusionList, Slot, Transaction, Transactions};
use ssz_types::BitVector;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use tracing::info; use tracing::info;
@@ -123,4 +124,55 @@ impl<E: EthSpec> InclusionListCache<E> {
let il: Vec<_> = txs.iter().cloned().collect(); let il: Vec<_> = txs.iter().cloned().collect();
il.try_into().ok() il.try_into().ok()
} }
/// Returns a bitvector with bits set for each committee member who submitted a valid,
/// non-equivocating inclusion list.
pub fn get_inclusion_list_bits(
&self,
slot: Slot,
committee: &InclusionListCommittee<E>,
only_timely: bool,
) -> BitVector<E::InclusionListCommitteeSize> {
let mut bits = BitVector::new();
let Some(inner) = self.inner_map.get(&slot) else {
return bits;
};
for (i, validator_index) in committee.iter().enumerate() {
if inner.inclusion_list_equivocators.contains(validator_index) {
continue;
}
if !inner.inclusion_lists_seen.contains(validator_index) {
continue;
}
if only_timely {
if inner.inclusion_list_timeliness.get(validator_index) == Some(&true) {
bits.set(i, true).ok();
}
} else {
bits.set(i, true).ok();
}
}
bits
}
/// Checks that `inclusion_list_bits` is a superset of the locally observed bits.
pub fn is_inclusion_list_bits_inclusive(
&self,
slot: Slot,
committee: &InclusionListCommittee<E>,
inclusion_list_bits: &BitVector<E::InclusionListCommitteeSize>,
only_timely: bool,
) -> bool {
let local_bits = self.get_inclusion_list_bits(slot, committee, only_timely);
// Check that inclusion_list_bits is a superset of local_bits:
// every bit set in local_bits must also be set in inclusion_list_bits.
for i in 0..local_bits.len() {
if local_bits.get(i).unwrap_or(false) && !inclusion_list_bits.get(i).unwrap_or(false) {
return false;
}
}
true
}
} }