mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 14:28:37 +00:00
Add fork choice EF tests (#2737)
## Issue Addressed Resolves #2545 ## Proposed Changes Adds the long-overdue EF tests for fork choice. Although we had pretty good coverage via other implementations that closely followed our approach, it is nonetheless important for us to implement these tests too. During testing I found that we were using a hard-coded `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` value rather than one from the `ChainSpec`. This caused a failure during a minimal preset test. This doesn't represent a risk to mainnet or testnets, since the hard-coded value matched the mainnet preset. ## Failing Cases There is one failing case which is presently marked as `SkippedKnownFailure`: ``` case 4 ("new_finalized_slot_is_justified_checkpoint_ancestor") from /home/paul/development/lighthouse/testing/ef_tests/consensus-spec-tests/tests/minimal/phase0/fork_choice/on_block/pyspec_tests/new_finalized_slot_is_justified_checkpoint_ancestor failed with NotEqual: head check failed: Got Head { slot: Slot(40), root: 0x9183dbaed4191a862bd307d476e687277fc08469fc38618699863333487703e7 } | Expected Head { slot: Slot(24), root: 0x105b49b51bf7103c182aa58860b039550a89c05a4675992e2af703bd02c84570 } ``` This failure is due to #2741. It's not a particularly high priority issue at the moment, so we fix it after merging this PR.
This commit is contained in:
@@ -3,18 +3,13 @@ use std::marker::PhantomData;
|
||||
use proto_array::{Block as ProtoBlock, ProtoArrayForkChoice};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use types::{
|
||||
AttestationShufflingId, BeaconBlock, BeaconState, BeaconStateError, Checkpoint, Epoch, EthSpec,
|
||||
Hash256, IndexedAttestation, RelativeEpoch, SignedBeaconBlock, Slot,
|
||||
AttestationShufflingId, BeaconBlock, BeaconState, BeaconStateError, ChainSpec, Checkpoint,
|
||||
Epoch, EthSpec, Hash256, IndexedAttestation, RelativeEpoch, SignedBeaconBlock, Slot,
|
||||
};
|
||||
|
||||
use crate::ForkChoiceStore;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// Defined here:
|
||||
///
|
||||
/// https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/fork-choice.md#configuration
|
||||
pub const SAFE_SLOTS_TO_UPDATE_JUSTIFIED: u64 = 8;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error<T> {
|
||||
InvalidAttestation(InvalidAttestation),
|
||||
@@ -379,13 +374,14 @@ where
|
||||
&mut self,
|
||||
current_slot: Slot,
|
||||
state: &BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<bool, Error<T::Error>> {
|
||||
self.update_time(current_slot)?;
|
||||
|
||||
let new_justified_checkpoint = &state.current_justified_checkpoint();
|
||||
|
||||
if compute_slots_since_epoch_start::<E>(self.fc_store.get_current_slot())
|
||||
< SAFE_SLOTS_TO_UPDATE_JUSTIFIED
|
||||
< spec.safe_slots_to_update_justified
|
||||
{
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -442,6 +438,7 @@ where
|
||||
block: &BeaconBlock<E>,
|
||||
block_root: Hash256,
|
||||
state: &BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error<T::Error>> {
|
||||
let current_slot = self.update_time(current_slot)?;
|
||||
|
||||
@@ -500,7 +497,7 @@ where
|
||||
self.fc_store
|
||||
.set_best_justified_checkpoint(state.current_justified_checkpoint());
|
||||
}
|
||||
if self.should_update_justified_checkpoint(current_slot, state)? {
|
||||
if self.should_update_justified_checkpoint(current_slot, state, spec)? {
|
||||
self.fc_store
|
||||
.set_justified_checkpoint(state.current_justified_checkpoint())
|
||||
.map_err(Error::UnableToSetJustifiedCheckpoint)?;
|
||||
@@ -797,6 +794,21 @@ where
|
||||
*self.fc_store.finalized_checkpoint()
|
||||
}
|
||||
|
||||
/// Return the justified checkpoint.
|
||||
pub fn justified_checkpoint(&self) -> Checkpoint {
|
||||
*self.fc_store.justified_checkpoint()
|
||||
}
|
||||
|
||||
/// Return the best justified checkpoint.
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// This is distinct to the "justified checkpoint" or the "current justified checkpoint". This
|
||||
/// "best justified checkpoint" value should only be used internally or for testing.
|
||||
pub fn best_justified_checkpoint(&self) -> Checkpoint {
|
||||
*self.fc_store.best_justified_checkpoint()
|
||||
}
|
||||
|
||||
/// Returns the latest message for a given validator, if any.
|
||||
///
|
||||
/// Returns `(block_root, block_slot)`.
|
||||
|
||||
@@ -3,7 +3,6 @@ mod fork_choice_store;
|
||||
|
||||
pub use crate::fork_choice::{
|
||||
Error, ForkChoice, InvalidAttestation, InvalidBlock, PersistedForkChoice, QueuedAttestation,
|
||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED,
|
||||
};
|
||||
pub use fork_choice_store::ForkChoiceStore;
|
||||
pub use proto_array::Block as ProtoBlock;
|
||||
|
||||
Reference in New Issue
Block a user