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:
Michael Sproul
2024-02-19 13:22:23 +11:00
committed by GitHub
parent e22c9eed8f
commit c9702cb0a1
10 changed files with 122 additions and 11 deletions

View File

@@ -36,6 +36,7 @@ use network::{NetworkConfig, NetworkSenders, NetworkService};
use slasher::Slasher;
use slasher_service::SlasherService;
use slog::{debug, info, warn, Logger};
use ssz::Decode;
use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::sync::Arc;
@@ -44,7 +45,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use timer::spawn_timer;
use tokio::sync::oneshot;
use types::{
test_utils::generate_deterministic_keypairs, BeaconState, ChainSpec, EthSpec,
test_utils::generate_deterministic_keypairs, BeaconState, BlobSidecarList, ChainSpec, EthSpec,
ExecutionBlockHash, Hash256, SignedBeaconBlock,
};
@@ -319,6 +320,7 @@ where
ClientGenesis::WeakSubjSszBytes {
anchor_state_bytes,
anchor_block_bytes,
anchor_blobs_bytes,
} => {
info!(context.log(), "Starting checkpoint sync");
if config.chain.genesis_backfill {
@@ -332,10 +334,25 @@ where
.map_err(|e| format!("Unable to parse weak subj state SSZ: {:?}", e))?;
let anchor_block = SignedBeaconBlock::from_ssz_bytes(&anchor_block_bytes, &spec)
.map_err(|e| format!("Unable to parse weak subj block SSZ: {:?}", e))?;
let anchor_blobs = if anchor_block.message().body().has_blobs() {
let anchor_blobs_bytes = anchor_blobs_bytes
.ok_or("Blobs for checkpoint must be provided using --checkpoint-blobs")?;
Some(
BlobSidecarList::from_ssz_bytes(&anchor_blobs_bytes)
.map_err(|e| format!("Unable to parse weak subj blobs SSZ: {e:?}"))?,
)
} else {
None
};
let genesis_state = genesis_state(&runtime_context, &config, log).await?;
builder
.weak_subjectivity_state(anchor_state, anchor_block, genesis_state)
.weak_subjectivity_state(
anchor_state,
anchor_block,
anchor_blobs,
genesis_state,
)
.map(|v| (v, None))?
}
ClientGenesis::CheckpointSyncUrl { url } => {
@@ -430,9 +447,33 @@ where
e => format!("Error fetching finalized block from remote: {:?}", e),
})?
.ok_or("Finalized block missing from remote, it returned 404")?;
let block_root = block.canonical_root();
debug!(context.log(), "Downloaded finalized block");
let blobs = if block.message().body().has_blobs() {
debug!(context.log(), "Downloading finalized blobs");
if let Some(response) = remote
.get_blobs::<TEthSpec>(BlockId::Root(block_root), None)
.await
.map_err(|e| format!("Error fetching finalized blobs from remote: {e:?}"))?
{
debug!(context.log(), "Downloaded finalized blobs");
Some(response.data)
} else {
warn!(
context.log(),
"Checkpoint server is missing blobs";
"block_root" => %block_root,
"hint" => "use a different URL or ask the provider to update",
"impact" => "db will be slightly corrupt until these blobs are pruned",
);
None
}
} else {
None
};
let genesis_state = genesis_state(&runtime_context, &config, log).await?;
info!(
@@ -440,7 +481,7 @@ where
"Loaded checkpoint block and state";
"block_slot" => block.slot(),
"state_slot" => state.slot(),
"block_root" => ?block.canonical_root(),
"block_root" => ?block_root,
);
let service =
@@ -468,7 +509,7 @@ where
});
builder
.weak_subjectivity_state(state, block, genesis_state)
.weak_subjectivity_state(state, block, blobs, genesis_state)
.map(|v| (v, service))?
}
ClientGenesis::DepositContract => {