mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-23 23:04:53 +00:00
Download checkpoint blobs during checkpoint sync (#5252)
* MVP implementation (untested) * update store checkpoint sync test * update cli help * Merge pull request #5253 from realbigsean/checkpoint-blobs-sean Checkpoint blobs sean * Warn only if blobs are missing from server * Merge remote-tracking branch 'origin/unstable' into checkpoint-blobs * Verify checkpoint blobs * Move blob verification earlier
This commit is contained in:
@@ -39,8 +39,8 @@ use std::time::Duration;
|
||||
use store::{Error as StoreError, HotColdDB, ItemStore, KeyValueStoreOp};
|
||||
use task_executor::{ShutdownReason, TaskExecutor};
|
||||
use types::{
|
||||
BeaconBlock, BeaconState, ChainSpec, Checkpoint, Epoch, EthSpec, Graffiti, Hash256, Signature,
|
||||
SignedBeaconBlock, Slot,
|
||||
BeaconBlock, BeaconState, BlobSidecarList, ChainSpec, Checkpoint, Epoch, EthSpec, Graffiti,
|
||||
Hash256, Signature, SignedBeaconBlock, Slot,
|
||||
};
|
||||
|
||||
/// An empty struct used to "witness" all the `BeaconChainTypes` traits. It has no user-facing
|
||||
@@ -432,6 +432,7 @@ where
|
||||
mut self,
|
||||
mut weak_subj_state: BeaconState<TEthSpec>,
|
||||
weak_subj_block: SignedBeaconBlock<TEthSpec>,
|
||||
weak_subj_blobs: Option<BlobSidecarList<TEthSpec>>,
|
||||
genesis_state: BeaconState<TEthSpec>,
|
||||
) -> Result<Self, String> {
|
||||
let store = self
|
||||
@@ -490,6 +491,29 @@ where
|
||||
));
|
||||
}
|
||||
|
||||
// Verify that blobs (if provided) match the block.
|
||||
if let Some(blobs) = &weak_subj_blobs {
|
||||
let commitments = weak_subj_block
|
||||
.message()
|
||||
.body()
|
||||
.blob_kzg_commitments()
|
||||
.map_err(|e| format!("Blobs provided but block does not reference them: {e:?}"))?;
|
||||
if blobs.len() != commitments.len() {
|
||||
return Err(format!(
|
||||
"Wrong number of blobs, expected: {}, got: {}",
|
||||
commitments.len(),
|
||||
blobs.len()
|
||||
));
|
||||
}
|
||||
if commitments
|
||||
.iter()
|
||||
.zip(blobs.iter())
|
||||
.any(|(commitment, blob)| *commitment != blob.kzg_commitment)
|
||||
{
|
||||
return Err("Checkpoint blob does not match block commitment".into());
|
||||
}
|
||||
}
|
||||
|
||||
// Set the store's split point *before* storing genesis so that genesis is stored
|
||||
// immediately in the freezer DB.
|
||||
store.set_split(weak_subj_slot, weak_subj_state_root, weak_subj_block_root);
|
||||
@@ -511,14 +535,19 @@ where
|
||||
.do_atomically(block_root_batch)
|
||||
.map_err(|e| format!("Error writing frozen block roots: {e:?}"))?;
|
||||
|
||||
// Write the state and block non-atomically, it doesn't matter if they're forgotten
|
||||
// Write the state, block and blobs non-atomically, it doesn't matter if they're forgotten
|
||||
// about on a crash restart.
|
||||
store
|
||||
.put_state(&weak_subj_state_root, &weak_subj_state)
|
||||
.map_err(|e| format!("Failed to store weak subjectivity state: {:?}", e))?;
|
||||
.map_err(|e| format!("Failed to store weak subjectivity state: {e:?}"))?;
|
||||
store
|
||||
.put_block(&weak_subj_block_root, weak_subj_block.clone())
|
||||
.map_err(|e| format!("Failed to store weak subjectivity block: {:?}", e))?;
|
||||
.map_err(|e| format!("Failed to store weak subjectivity block: {e:?}"))?;
|
||||
if let Some(blobs) = weak_subj_blobs {
|
||||
store
|
||||
.put_blobs(&weak_subj_block_root, blobs)
|
||||
.map_err(|e| format!("Failed to store weak subjectivity blobs: {e:?}"))?;
|
||||
}
|
||||
|
||||
// Stage the database's metadata fields for atomic storage when `build` is called.
|
||||
// This prevents the database from restarting in an inconsistent state if the anchor
|
||||
|
||||
@@ -2396,6 +2396,7 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
|
||||
.get_full_block(&wss_block_root)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let wss_blobs_opt = harness.chain.store.get_blobs(&wss_block_root).unwrap();
|
||||
let wss_state = full_store
|
||||
.get_state(&wss_state_root, Some(checkpoint_slot))
|
||||
.unwrap()
|
||||
@@ -2438,7 +2439,12 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
|
||||
.custom_spec(test_spec::<E>())
|
||||
.task_executor(harness.chain.task_executor.clone())
|
||||
.logger(log.clone())
|
||||
.weak_subjectivity_state(wss_state, wss_block.clone(), genesis_state)
|
||||
.weak_subjectivity_state(
|
||||
wss_state,
|
||||
wss_block.clone(),
|
||||
wss_blobs_opt.clone(),
|
||||
genesis_state,
|
||||
)
|
||||
.unwrap()
|
||||
.store_migrator_config(MigratorConfig::default().blocking())
|
||||
.dummy_eth1_backend()
|
||||
@@ -2456,6 +2462,17 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
|
||||
.expect("should build");
|
||||
|
||||
let beacon_chain = Arc::new(beacon_chain);
|
||||
let wss_block_root = wss_block.canonical_root();
|
||||
let store_wss_block = harness
|
||||
.chain
|
||||
.get_block(&wss_block_root)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let store_wss_blobs_opt = beacon_chain.store.get_blobs(&wss_block_root).unwrap();
|
||||
|
||||
assert_eq!(store_wss_block, wss_block);
|
||||
assert_eq!(store_wss_blobs_opt, wss_blobs_opt);
|
||||
|
||||
// Apply blocks forward to reach head.
|
||||
let chain_dump = harness.chain.chain_dump().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user