Disallow genesis sync outside blob pruning window (#5038)

* Disallow Syncing From Genesis By Default

* Fix CLI Tests

* Perform checks in the `ClientBuilder`

* Tidy, fix tests

* Return an error based on the Deneb fork

* Fix typos

* Fix failing test

* Add missing CLI flag

* Fix CLI flags

* Add suggestion from Sean

* Fix conflict with blob sidecars epochs

---------

Co-authored-by: Mark Mackey <mark@sigmaprime.io>
This commit is contained in:
Paul Hauner
2024-01-10 06:17:01 +11:00
committed by GitHub
parent b47e3f252e
commit 12d3d237cd
6 changed files with 79 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
use timer::spawn_timer;
use tokio::sync::oneshot;
use types::{
@@ -45,6 +46,11 @@ use types::{
/// Interval between polling the eth1 node for genesis information.
pub const ETH1_GENESIS_UPDATE_INTERVAL_MILLIS: u64 = 7_000;
/// Reduces the blob availability period by some epochs. Helps prevent the user
/// from starting a genesis sync so near to the blob pruning window that blobs
/// have been pruned before they can manage to sync the chain.
const BLOB_AVAILABILITY_REDUCTION_EPOCHS: u64 = 2;
/// Builds a `Client` instance.
///
/// ## Notes
@@ -252,6 +258,45 @@ where
let genesis_state = genesis_state(&runtime_context, &config, log).await?;
// If the user has not explicitly allowed genesis sync, prevent
// them from trying to sync from genesis if we're outside of the
// blob P2P availability window.
//
// It doesn't make sense to try and sync the chain if we can't
// verify blob availability by downloading blobs from the P2P
// network. The user should do a checkpoint sync instead.
if !config.allow_insecure_genesis_sync {
if let Some(deneb_fork_epoch) = spec.deneb_fork_epoch {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| format!("Unable to read system time: {e:}"))?
.as_secs();
let genesis_time = genesis_state.genesis_time();
let deneb_time =
genesis_time + (deneb_fork_epoch.as_u64() * spec.seconds_per_slot);
// Shrink the blob availability window so users don't start
// a sync right before blobs start to disappear from the P2P
// network.
let reduced_p2p_availability_epochs = spec
.min_epochs_for_blob_sidecars_requests
.saturating_sub(BLOB_AVAILABILITY_REDUCTION_EPOCHS);
let blob_availability_window = reduced_p2p_availability_epochs
* TEthSpec::slots_per_epoch()
* spec.seconds_per_slot;
if now > deneb_time + blob_availability_window {
return Err(
"Syncing from genesis is insecure and incompatible with data availability checks. \
You should instead perform a checkpoint sync from a trusted node using the --checkpoint-sync-url option. \
For a list of public endpoints, see: https://eth-clients.github.io/checkpoint-sync-endpoints/ \
Alternatively, use --allow-insecure-genesis-sync if the risks are understood."
.to_string(),
);
}
}
}
builder.genesis_state(genesis_state).map(|v| (v, None))?
}
ClientGenesis::WeakSubjSszBytes {

View File

@@ -78,6 +78,7 @@ pub struct Config {
pub beacon_processor: BeaconProcessorConfig,
pub genesis_state_url: Option<String>,
pub genesis_state_url_timeout: Duration,
pub allow_insecure_genesis_sync: bool,
}
impl Default for Config {
@@ -108,6 +109,7 @@ impl Default for Config {
genesis_state_url: <_>::default(),
// This default value should always be overwritten by the CLI default value.
genesis_state_url_timeout: Duration::from_secs(60),
allow_insecure_genesis_sync: false,
}
}
}