Add experimental complete-blob-backfill flag (#7751)

A different (and complementary) approach for:

- https://github.com/sigp/lighthouse/issues/5391


  This PR adds a flag to set the DA boundary to the Deneb fork. The effect of this change is that Lighthouse will try to backfill _all_ blobs.

Most peers do not have this data, but I'm thinking that combined with `trusted-peers` this could be quite effective.


Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
Michael Sproul
2025-09-18 15:17:03 +10:00
committed by GitHub
parent 684632df73
commit 3543a20192
6 changed files with 76 additions and 5 deletions

View File

@@ -899,6 +899,7 @@ where
let genesis_time = head_snapshot.beacon_state.genesis_time();
let canonical_head = CanonicalHead::new(fork_choice, Arc::new(head_snapshot));
let shuffling_cache_size = self.chain_config.shuffling_cache_size;
let complete_blob_backfill = self.chain_config.complete_blob_backfill;
// Calculate the weak subjectivity point in which to backfill blocks to.
let genesis_backfill_slot = if self.chain_config.genesis_backfill {
@@ -1013,6 +1014,7 @@ where
genesis_backfill_slot,
data_availability_checker: Arc::new(
DataAvailabilityChecker::new(
complete_blob_backfill,
slot_clock,
self.kzg.clone(),
store,

View File

@@ -86,6 +86,8 @@ pub struct ChainConfig {
/// If using a weak-subjectivity sync, whether we should download blocks all the way back to
/// genesis.
pub genesis_backfill: bool,
/// EXPERIMENTAL: backfill blobs and data columns beyond the data availability window.
pub complete_blob_backfill: bool,
/// Whether to send payload attributes every slot, regardless of connected proposers.
///
/// This is useful for block builders and testing.
@@ -144,6 +146,7 @@ impl Default for ChainConfig {
optimistic_finalized_sync: true,
shuffling_cache_size: crate::shuffling_cache::DEFAULT_CACHE_SIZE,
genesis_backfill: false,
complete_blob_backfill: false,
always_prepare_payload: false,
epochs_per_migration: crate::migrate::DEFAULT_EPOCHS_PER_MIGRATION,
enable_light_client_server: true,

View File

@@ -78,6 +78,7 @@ pub const STATE_LRU_CAPACITY: usize = STATE_LRU_CAPACITY_NON_ZERO.get();
/// proposer. Having a capacity > 1 is an optimization to prevent sync lookup from having re-fetch
/// data during moments of unstable network conditions.
pub struct DataAvailabilityChecker<T: BeaconChainTypes> {
complete_blob_backfill: bool,
availability_cache: Arc<DataAvailabilityCheckerInner<T>>,
slot_clock: T::SlotClock,
kzg: Arc<Kzg>,
@@ -116,6 +117,7 @@ impl<E: EthSpec> Debug for Availability<E> {
impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
pub fn new(
complete_blob_backfill: bool,
slot_clock: T::SlotClock,
kzg: Arc<Kzg>,
store: BeaconStore<T>,
@@ -129,6 +131,7 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
spec.clone(),
)?;
Ok(Self {
complete_blob_backfill,
availability_cache: Arc::new(inner),
slot_clock,
kzg,
@@ -518,9 +521,15 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
/// The epoch at which we require a data availability check in block processing.
/// `None` if the `Deneb` fork is disabled.
pub fn data_availability_boundary(&self) -> Option<Epoch> {
let current_epoch = self.slot_clock.now()?.epoch(T::EthSpec::slots_per_epoch());
self.spec
.min_epoch_data_availability_boundary(current_epoch)
let fork_epoch = self.spec.deneb_fork_epoch?;
if self.complete_blob_backfill {
Some(fork_epoch)
} else {
let current_epoch = self.slot_clock.now()?.epoch(T::EthSpec::slots_per_epoch());
self.spec
.min_epoch_data_availability_boundary(current_epoch)
}
}
/// Returns true if the given epoch lies within the da boundary and false otherwise.
@@ -1076,7 +1085,15 @@ mod test {
let kzg = get_kzg(&spec);
let store = Arc::new(HotColdDB::open_ephemeral(<_>::default(), spec.clone()).unwrap());
let custody_context = Arc::new(CustodyContext::new(false));
DataAvailabilityChecker::new(slot_clock, kzg, store, custody_context, spec)
.expect("should initialise data availability checker")
let complete_blob_backfill = false;
DataAvailabilityChecker::new(
complete_blob_backfill,
slot_clock,
kzg,
store,
custody_context,
spec,
)
.expect("should initialise data availability checker")
}
}