checkpoint sync without alignment

This commit is contained in:
realbigsean
2023-06-09 12:03:59 -04:00
parent 8da95ac9c6
commit 9fa67ccb88
5 changed files with 22 additions and 50 deletions

View File

@@ -419,23 +419,14 @@ where
let weak_subj_block_root = weak_subj_block.canonical_root();
let weak_subj_state_root = weak_subj_block.state_root();
// Check that the given block lies on an epoch boundary. Due to the database only storing
// Check that the given state lies on an epoch boundary. Due to the database only storing
// full states on epoch boundaries and at restore points it would be difficult to support
// starting from a mid-epoch state.
if weak_subj_slot % TEthSpec::slots_per_epoch() != 0 {
return Err(format!(
"Checkpoint block at slot {} is not aligned to epoch start. \
Please supply an aligned checkpoint with block.slot % 32 == 0",
weak_subj_block.slot(),
));
}
// Check that the block and state have consistent slots and state roots.
if weak_subj_state.slot() != weak_subj_block.slot() {
return Err(format!(
"Slot of snapshot block ({}) does not match snapshot state ({})",
weak_subj_block.slot(),
weak_subj_state.slot(),
"Checkpoint state at slot {} is not aligned to epoch start. \
Please supply an aligned checkpoint with state.slot % 32 == 0",
weak_subj_slot,
));
}
@@ -508,13 +499,12 @@ where
let fc_store = BeaconForkChoiceStore::get_forkchoice_store(store, &snapshot)
.map_err(|e| format!("Unable to initialize fork choice store: {e:?}"))?;
let current_slot = Some(snapshot.beacon_block.slot());
let fork_choice = ForkChoice::from_anchor(
fc_store,
snapshot.beacon_block_root,
&snapshot.beacon_block,
&snapshot.beacon_state,
current_slot,
Some(weak_subj_slot),
&self.spec,
)
.map_err(|e| format!("Unable to initialize ForkChoice: {:?}", e))?;

View File

@@ -28,6 +28,7 @@ use network::{NetworkConfig, NetworkSenders, NetworkService};
use slasher::Slasher;
use slasher_service::SlasherService;
use slog::{debug, info, warn, Logger};
use state_processing::per_slot_processing;
use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::sync::Arc;
@@ -347,8 +348,8 @@ where
};
debug!(context.log(), "Downloading finalized block");
// Find a suitable finalized block on an epoch boundary.
let mut block = remote
// Find a suitable finalized block.
let block = remote
.get_beacon_blocks_ssz::<TEthSpec>(BlockId::Finalized, &spec)
.await
.map_err(|e| match e {
@@ -363,42 +364,13 @@ where
debug!(context.log(), "Downloaded finalized block");
let mut block_slot = block.slot();
while block.slot() % slots_per_epoch != 0 {
block_slot = (block_slot / slots_per_epoch - 1) * slots_per_epoch;
debug!(
context.log(),
"Searching for aligned checkpoint block";
"block_slot" => block_slot
);
if let Some(found_block) = remote
.get_beacon_blocks_ssz::<TEthSpec>(BlockId::Slot(block_slot), &spec)
.await
.map_err(|e| {
format!("Error fetching block at slot {}: {:?}", block_slot, e)
})?
{
block = found_block;
}
}
debug!(
context.log(),
"Downloaded aligned finalized block";
"block_root" => ?block.canonical_root(),
"block_slot" => block.slot(),
);
let state_root = block.state_root();
debug!(
context.log(),
"Downloading finalized state";
"state_root" => ?state_root
);
let state = remote
let mut state = remote
.get_debug_beacon_states_ssz::<TEthSpec>(StateId::Root(state_root), &spec)
.await
.map_err(|e| {
@@ -413,13 +385,19 @@ where
debug!(context.log(), "Downloaded finalized state");
while state.slot() % slots_per_epoch != 0 {
per_slot_processing(&mut state, Some(state_root), &spec)
.map_err(|e| format!("Error advancing state: {:?}", e))?;
}
let genesis_state = BeaconState::from_ssz_bytes(&genesis_state_bytes, &spec)
.map_err(|e| format!("Unable to parse genesis state SSZ: {:?}", e))?;
info!(
context.log(),
"Loaded checkpoint block and state";
"slot" => block.slot(),
"block_slot" => block.slot(),
"state_slot" => state.slot(),
"block_root" => ?block.canonical_root(),
"state_root" => ?state_root,
);

View File

@@ -352,7 +352,7 @@ where
spec: &ChainSpec,
) -> Result<Self, Error<T::Error>> {
// Sanity check: the anchor must lie on an epoch boundary.
if anchor_block.slot() % E::slots_per_epoch() != 0 {
if anchor_state.slot() % E::slots_per_epoch() != 0 {
return Err(Error::InvalidAnchor {
block_slot: anchor_block.slot(),
state_slot: anchor_state.slot(),
@@ -388,6 +388,7 @@ where
let current_slot = current_slot.unwrap_or_else(|| fc_store.get_current_slot());
let proto_array = ProtoArrayForkChoice::new::<E>(
current_slot,
finalized_block_slot,
finalized_block_state_root,
*fc_store.justified_checkpoint(),

View File

@@ -80,6 +80,7 @@ impl ForkChoiceTestDefinition {
let junk_shuffling_id =
AttestationShufflingId::from_components(Epoch::new(0), Hash256::zero());
let mut fork_choice = ProtoArrayForkChoice::new::<MainnetEthSpec>(
self.finalized_block_slot,
self.finalized_block_slot,
Hash256::zero(),
self.justified_checkpoint,

View File

@@ -345,6 +345,7 @@ pub struct ProtoArrayForkChoice {
impl ProtoArrayForkChoice {
#[allow(clippy::too_many_arguments)]
pub fn new<E: EthSpec>(
current_slot: Slot,
finalized_block_slot: Slot,
finalized_block_state_root: Hash256,
justified_checkpoint: Checkpoint,
@@ -380,7 +381,7 @@ impl ProtoArrayForkChoice {
};
proto_array
.on_block::<E>(block, finalized_block_slot)
.on_block::<E>(block, current_slot)
.map_err(|e| format!("Failed to add finalized block to proto_array: {:?}", e))?;
Ok(Self {
@@ -1108,6 +1109,7 @@ mod test_compute_deltas {
};
let mut fc = ProtoArrayForkChoice::new::<MainnetEthSpec>(
genesis_slot,
genesis_slot,
junk_state_root,
genesis_checkpoint,