mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 09:16:00 +00:00
checkpoint sync without alignment
This commit is contained in:
@@ -419,23 +419,14 @@ where
|
|||||||
let weak_subj_block_root = weak_subj_block.canonical_root();
|
let weak_subj_block_root = weak_subj_block.canonical_root();
|
||||||
let weak_subj_state_root = weak_subj_block.state_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
|
// full states on epoch boundaries and at restore points it would be difficult to support
|
||||||
// starting from a mid-epoch state.
|
// starting from a mid-epoch state.
|
||||||
if weak_subj_slot % TEthSpec::slots_per_epoch() != 0 {
|
if weak_subj_slot % TEthSpec::slots_per_epoch() != 0 {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Checkpoint block at slot {} is not aligned to epoch start. \
|
"Checkpoint state at slot {} is not aligned to epoch start. \
|
||||||
Please supply an aligned checkpoint with block.slot % 32 == 0",
|
Please supply an aligned checkpoint with state.slot % 32 == 0",
|
||||||
weak_subj_block.slot(),
|
weak_subj_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(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,13 +499,12 @@ where
|
|||||||
let fc_store = BeaconForkChoiceStore::get_forkchoice_store(store, &snapshot)
|
let fc_store = BeaconForkChoiceStore::get_forkchoice_store(store, &snapshot)
|
||||||
.map_err(|e| format!("Unable to initialize fork choice store: {e:?}"))?;
|
.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(
|
let fork_choice = ForkChoice::from_anchor(
|
||||||
fc_store,
|
fc_store,
|
||||||
snapshot.beacon_block_root,
|
snapshot.beacon_block_root,
|
||||||
&snapshot.beacon_block,
|
&snapshot.beacon_block,
|
||||||
&snapshot.beacon_state,
|
&snapshot.beacon_state,
|
||||||
current_slot,
|
Some(weak_subj_slot),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("Unable to initialize ForkChoice: {:?}", e))?;
|
.map_err(|e| format!("Unable to initialize ForkChoice: {:?}", e))?;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ use network::{NetworkConfig, NetworkSenders, NetworkService};
|
|||||||
use slasher::Slasher;
|
use slasher::Slasher;
|
||||||
use slasher_service::SlasherService;
|
use slasher_service::SlasherService;
|
||||||
use slog::{debug, info, warn, Logger};
|
use slog::{debug, info, warn, Logger};
|
||||||
|
use state_processing::per_slot_processing;
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -347,8 +348,8 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug!(context.log(), "Downloading finalized block");
|
debug!(context.log(), "Downloading finalized block");
|
||||||
// Find a suitable finalized block on an epoch boundary.
|
// Find a suitable finalized block.
|
||||||
let mut block = remote
|
let block = remote
|
||||||
.get_beacon_blocks_ssz::<TEthSpec>(BlockId::Finalized, &spec)
|
.get_beacon_blocks_ssz::<TEthSpec>(BlockId::Finalized, &spec)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
@@ -363,42 +364,13 @@ where
|
|||||||
|
|
||||||
debug!(context.log(), "Downloaded finalized block");
|
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();
|
let state_root = block.state_root();
|
||||||
debug!(
|
debug!(
|
||||||
context.log(),
|
context.log(),
|
||||||
"Downloading finalized state";
|
"Downloading finalized state";
|
||||||
"state_root" => ?state_root
|
"state_root" => ?state_root
|
||||||
);
|
);
|
||||||
let state = remote
|
let mut state = remote
|
||||||
.get_debug_beacon_states_ssz::<TEthSpec>(StateId::Root(state_root), &spec)
|
.get_debug_beacon_states_ssz::<TEthSpec>(StateId::Root(state_root), &spec)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
@@ -413,13 +385,19 @@ where
|
|||||||
|
|
||||||
debug!(context.log(), "Downloaded finalized state");
|
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)
|
let genesis_state = BeaconState::from_ssz_bytes(&genesis_state_bytes, &spec)
|
||||||
.map_err(|e| format!("Unable to parse genesis state SSZ: {:?}", e))?;
|
.map_err(|e| format!("Unable to parse genesis state SSZ: {:?}", e))?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
context.log(),
|
context.log(),
|
||||||
"Loaded checkpoint block and state";
|
"Loaded checkpoint block and state";
|
||||||
"slot" => block.slot(),
|
"block_slot" => block.slot(),
|
||||||
|
"state_slot" => state.slot(),
|
||||||
"block_root" => ?block.canonical_root(),
|
"block_root" => ?block.canonical_root(),
|
||||||
"state_root" => ?state_root,
|
"state_root" => ?state_root,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ where
|
|||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<Self, Error<T::Error>> {
|
) -> Result<Self, Error<T::Error>> {
|
||||||
// Sanity check: the anchor must lie on an epoch boundary.
|
// 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 {
|
return Err(Error::InvalidAnchor {
|
||||||
block_slot: anchor_block.slot(),
|
block_slot: anchor_block.slot(),
|
||||||
state_slot: anchor_state.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 current_slot = current_slot.unwrap_or_else(|| fc_store.get_current_slot());
|
||||||
|
|
||||||
let proto_array = ProtoArrayForkChoice::new::<E>(
|
let proto_array = ProtoArrayForkChoice::new::<E>(
|
||||||
|
current_slot,
|
||||||
finalized_block_slot,
|
finalized_block_slot,
|
||||||
finalized_block_state_root,
|
finalized_block_state_root,
|
||||||
*fc_store.justified_checkpoint(),
|
*fc_store.justified_checkpoint(),
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ impl ForkChoiceTestDefinition {
|
|||||||
let junk_shuffling_id =
|
let junk_shuffling_id =
|
||||||
AttestationShufflingId::from_components(Epoch::new(0), Hash256::zero());
|
AttestationShufflingId::from_components(Epoch::new(0), Hash256::zero());
|
||||||
let mut fork_choice = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
let mut fork_choice = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
||||||
|
self.finalized_block_slot,
|
||||||
self.finalized_block_slot,
|
self.finalized_block_slot,
|
||||||
Hash256::zero(),
|
Hash256::zero(),
|
||||||
self.justified_checkpoint,
|
self.justified_checkpoint,
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ pub struct ProtoArrayForkChoice {
|
|||||||
impl ProtoArrayForkChoice {
|
impl ProtoArrayForkChoice {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new<E: EthSpec>(
|
pub fn new<E: EthSpec>(
|
||||||
|
current_slot: Slot,
|
||||||
finalized_block_slot: Slot,
|
finalized_block_slot: Slot,
|
||||||
finalized_block_state_root: Hash256,
|
finalized_block_state_root: Hash256,
|
||||||
justified_checkpoint: Checkpoint,
|
justified_checkpoint: Checkpoint,
|
||||||
@@ -380,7 +381,7 @@ impl ProtoArrayForkChoice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
proto_array
|
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))?;
|
.map_err(|e| format!("Failed to add finalized block to proto_array: {:?}", e))?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -1108,6 +1109,7 @@ mod test_compute_deltas {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut fc = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
let mut fc = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
||||||
|
genesis_slot,
|
||||||
genesis_slot,
|
genesis_slot,
|
||||||
junk_state_root,
|
junk_state_root,
|
||||||
genesis_checkpoint,
|
genesis_checkpoint,
|
||||||
|
|||||||
Reference in New Issue
Block a user