Allow manual checkpoint sync without blobs (#8470)

Since merging this PR, we don't need `--checkpoint-blobs`, even prior to Fulu:

- https://github.com/sigp/lighthouse/pull/8417

This PR removes the mandatory check for blobs prior to Fulu, enabling simpler manual checkpoint sync.


Co-Authored-By: Michael Sproul <michael@sigmaprime.io>

Co-Authored-By: Jimmy Chen <jimmy@sigmaprime.io>
This commit is contained in:
Michael Sproul
2025-11-27 10:00:21 +11:00
committed by GitHub
parent d6cec0ba50
commit e21a433748
2 changed files with 25 additions and 15 deletions

View File

@@ -2705,7 +2705,7 @@ async fn weak_subjectivity_sync_easy() {
let num_initial_slots = E::slots_per_epoch() * 11; let num_initial_slots = E::slots_per_epoch() * 11;
let checkpoint_slot = Slot::new(E::slots_per_epoch() * 9); let checkpoint_slot = Slot::new(E::slots_per_epoch() * 9);
let slots = (1..num_initial_slots).map(Slot::new).collect(); let slots = (1..num_initial_slots).map(Slot::new).collect();
weak_subjectivity_sync_test(slots, checkpoint_slot, None).await weak_subjectivity_sync_test(slots, checkpoint_slot, None, true).await
} }
#[tokio::test] #[tokio::test]
@@ -2713,7 +2713,7 @@ async fn weak_subjectivity_sync_single_block_batches() {
let num_initial_slots = E::slots_per_epoch() * 11; let num_initial_slots = E::slots_per_epoch() * 11;
let checkpoint_slot = Slot::new(E::slots_per_epoch() * 9); let checkpoint_slot = Slot::new(E::slots_per_epoch() * 9);
let slots = (1..num_initial_slots).map(Slot::new).collect(); let slots = (1..num_initial_slots).map(Slot::new).collect();
weak_subjectivity_sync_test(slots, checkpoint_slot, Some(1)).await weak_subjectivity_sync_test(slots, checkpoint_slot, Some(1), true).await
} }
#[tokio::test] #[tokio::test]
@@ -2727,7 +2727,7 @@ async fn weak_subjectivity_sync_unaligned_advanced_checkpoint() {
slot <= checkpoint_slot - 3 || slot > checkpoint_slot slot <= checkpoint_slot - 3 || slot > checkpoint_slot
}) })
.collect(); .collect();
weak_subjectivity_sync_test(slots, checkpoint_slot, None).await weak_subjectivity_sync_test(slots, checkpoint_slot, None, true).await
} }
#[tokio::test] #[tokio::test]
@@ -2741,7 +2741,7 @@ async fn weak_subjectivity_sync_unaligned_unadvanced_checkpoint() {
slot <= checkpoint_slot || slot > checkpoint_slot + 3 slot <= checkpoint_slot || slot > checkpoint_slot + 3
}) })
.collect(); .collect();
weak_subjectivity_sync_test(slots, checkpoint_slot, None).await weak_subjectivity_sync_test(slots, checkpoint_slot, None, true).await
} }
// Regression test for https://github.com/sigp/lighthouse/issues/4817 // Regression test for https://github.com/sigp/lighthouse/issues/4817
@@ -2753,7 +2753,7 @@ async fn weak_subjectivity_sync_skips_at_genesis() {
let end_slot = E::slots_per_epoch() * 4; let end_slot = E::slots_per_epoch() * 4;
let slots = (start_slot..end_slot).map(Slot::new).collect(); let slots = (start_slot..end_slot).map(Slot::new).collect();
let checkpoint_slot = Slot::new(E::slots_per_epoch() * 2); let checkpoint_slot = Slot::new(E::slots_per_epoch() * 2);
weak_subjectivity_sync_test(slots, checkpoint_slot, None).await weak_subjectivity_sync_test(slots, checkpoint_slot, None, true).await
} }
// Checkpoint sync from the genesis state. // Checkpoint sync from the genesis state.
@@ -2766,13 +2766,24 @@ async fn weak_subjectivity_sync_from_genesis() {
let end_slot = E::slots_per_epoch() * 2; let end_slot = E::slots_per_epoch() * 2;
let slots = (start_slot..end_slot).map(Slot::new).collect(); let slots = (start_slot..end_slot).map(Slot::new).collect();
let checkpoint_slot = Slot::new(0); let checkpoint_slot = Slot::new(0);
weak_subjectivity_sync_test(slots, checkpoint_slot, None).await weak_subjectivity_sync_test(slots, checkpoint_slot, None, true).await
}
// Test checkpoint sync without providing blobs - backfill should fetch them.
#[tokio::test]
async fn weak_subjectivity_sync_without_blobs() {
let start_slot = 4;
let end_slot = E::slots_per_epoch() * 4;
let slots = (start_slot..end_slot).map(Slot::new).collect();
let checkpoint_slot = Slot::new(E::slots_per_epoch() * 2);
weak_subjectivity_sync_test(slots, checkpoint_slot, None, false).await
} }
async fn weak_subjectivity_sync_test( async fn weak_subjectivity_sync_test(
slots: Vec<Slot>, slots: Vec<Slot>,
checkpoint_slot: Slot, checkpoint_slot: Slot,
backfill_batch_size: Option<usize>, backfill_batch_size: Option<usize>,
provide_blobs: bool,
) { ) {
// Build an initial chain on one harness, representing a synced node with full history. // Build an initial chain on one harness, representing a synced node with full history.
let num_final_blocks = E::slots_per_epoch() * 2; let num_final_blocks = E::slots_per_epoch() * 2;
@@ -2874,7 +2885,11 @@ async fn weak_subjectivity_sync_test(
.weak_subjectivity_state( .weak_subjectivity_state(
wss_state, wss_state,
wss_block.clone(), wss_block.clone(),
wss_blobs_opt.clone(), if provide_blobs {
wss_blobs_opt.clone()
} else {
None
},
genesis_state, genesis_state,
) )
.unwrap() .unwrap()

View File

@@ -354,15 +354,10 @@ where
let anchor_block = SignedBeaconBlock::from_ssz_bytes(&anchor_block_bytes, &spec) let anchor_block = SignedBeaconBlock::from_ssz_bytes(&anchor_block_bytes, &spec)
.map_err(|e| format!("Unable to parse weak subj block SSZ: {:?}", e))?; .map_err(|e| format!("Unable to parse weak subj block SSZ: {:?}", e))?;
// `BlobSidecar` is no longer used from Fulu onwards (superseded by `DataColumnSidecar`), // Providing blobs is optional now and not providing them is recommended.
// which will be fetched via rpc instead (unimplemented). // Backfill can handle downloading the blobs or columns for the checkpoint block.
let is_before_fulu = !spec let anchor_blobs = if let Some(anchor_blobs_bytes) = anchor_blobs_bytes {
.fork_name_at_slot::<E>(anchor_block.slot())
.fulu_enabled();
let anchor_blobs = if is_before_fulu && anchor_block.message().body().has_blobs() {
let max_blobs_len = spec.max_blobs_per_block(anchor_block.epoch()) as usize; let max_blobs_len = spec.max_blobs_per_block(anchor_block.epoch()) as usize;
let anchor_blobs_bytes = anchor_blobs_bytes
.ok_or("Blobs for checkpoint must be provided using --checkpoint-blobs")?;
Some( Some(
BlobSidecarList::from_ssz_bytes(&anchor_blobs_bytes, max_blobs_len) BlobSidecarList::from_ssz_bytes(&anchor_blobs_bytes, max_blobs_len)
.map_err(|e| format!("Unable to parse weak subj blobs SSZ: {e:?}"))?, .map_err(|e| format!("Unable to parse weak subj blobs SSZ: {e:?}"))?,