mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-29 10:54:24 +00:00
Remove checkpoint alignment requirements and enable historic state pruning (#4610)
## Issue Addressed Closes #3210 Closes #3211 ## Proposed Changes - Checkpoint sync from the latest finalized state regardless of its alignment. - Add the `block_root` to the database's split point. This is _only_ added to the in-memory split in order to avoid a schema migration. See `load_split`. - Add a new method to the DB called `get_advanced_state`, which looks up a state _by block root_, with a `state_root` as fallback. Using this method prevents accidental accesses of the split's unadvanced state, which does not exist in the hot DB and is not guaranteed to exist in the freezer DB at all. Previously Lighthouse would look up this state _from the freezer DB_, even if it was required for block/attestation processing, which was suboptimal. - Replace several state look-ups in block and attestation processing with `get_advanced_state` so that they can't hit the split block's unadvanced state. - Do not store any states in the freezer database by default. All states will be deleted upon being evicted from the hot database unless `--reconstruct-historic-states` is set. The anchor info which was previously used for checkpoint sync is used to implement this, including when syncing from genesis. ## Additional Info Needs further testing. I want to stress-test the pruned database under Hydra. The `get_advanced_state` method is intended to become more relevant over time: `tree-states` includes an identically named method that returns advanced states from its in-memory cache. Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
@@ -355,7 +355,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(),
|
||||
@@ -391,6 +391,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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
@@ -983,6 +984,7 @@ mod test_compute_deltas {
|
||||
};
|
||||
|
||||
let mut fc = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
||||
genesis_slot,
|
||||
genesis_slot,
|
||||
state_root,
|
||||
genesis_checkpoint,
|
||||
@@ -1108,6 +1110,7 @@ mod test_compute_deltas {
|
||||
};
|
||||
|
||||
let mut fc = ProtoArrayForkChoice::new::<MainnetEthSpec>(
|
||||
genesis_slot,
|
||||
genesis_slot,
|
||||
junk_state_root,
|
||||
genesis_checkpoint,
|
||||
|
||||
@@ -21,7 +21,7 @@ impl From<ArithError> for Error {
|
||||
///
|
||||
/// If the root of the supplied `state` is known, then it can be passed as `state_root`. If
|
||||
/// `state_root` is `None`, the root of `state` will be computed using a cached tree hash.
|
||||
/// Providing the `state_root` makes this function several orders of magniude faster.
|
||||
/// Providing the `state_root` makes this function several orders of magnitude faster.
|
||||
pub fn per_slot_processing<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
state_root: Option<Hash256>,
|
||||
|
||||
Reference in New Issue
Block a user