mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 05:14:35 +00:00
Remove equivocating validators from fork choice (#3371)
## Issue Addressed Closes https://github.com/sigp/lighthouse/issues/3241 Closes https://github.com/sigp/lighthouse/issues/3242 ## Proposed Changes * [x] Implement logic to remove equivocating validators from fork choice per https://github.com/ethereum/consensus-specs/pull/2845 * [x] Update tests to v1.2.0-rc.1. The new test which exercises `equivocating_indices` is passing. * [x] Pull in some SSZ abstractions from the `tree-states` branch that make implementing Vec-compatible encoding for types like `BTreeSet` and `BTreeMap`. * [x] Implement schema upgrades and downgrades for the database (new schema version is V11). * [x] Apply attester slashings from blocks to fork choice ## Additional Info * This PR doesn't need the `BTreeMap` impl, but `tree-states` does, and I don't think there's any harm in keeping it. But I could also be convinced to drop it. Blocked on #3322.
This commit is contained in:
@@ -276,7 +276,8 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
|
||||
&& T::name() != "inactivity_updates"
|
||||
&& T::name() != "participation_flag_updates"
|
||||
}
|
||||
ForkName::Altair | ForkName::Merge => true, // TODO: revisit when tests are out
|
||||
// No phase0 tests for Altair and later.
|
||||
ForkName::Altair | ForkName::Merge => T::name() != "participation_record_updates",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,13 +52,13 @@ pub struct Checks {
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
pub enum Step<B, A, P, S> {
|
||||
pub enum Step<B, A, AS, P> {
|
||||
Tick { tick: u64 },
|
||||
ValidBlock { block: B },
|
||||
MaybeValidBlock { block: B, valid: bool },
|
||||
Attestation { attestation: A },
|
||||
AttesterSlashing { attester_slashing: AS },
|
||||
PowBlock { pow_block: P },
|
||||
AttesterSlashing { attester_slashing: S },
|
||||
Checks { checks: Box<Checks> },
|
||||
}
|
||||
|
||||
@@ -75,12 +75,7 @@ pub struct ForkChoiceTest<E: EthSpec> {
|
||||
pub anchor_state: BeaconState<E>,
|
||||
pub anchor_block: BeaconBlock<E>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub steps: Vec<Step<SignedBeaconBlock<E>, Attestation<E>, PowBlock, AttesterSlashing<E>>>,
|
||||
}
|
||||
|
||||
/// Spec to be used for fork choice tests.
|
||||
pub fn fork_choice_spec<E: EthSpec>(fork_name: ForkName) -> ChainSpec {
|
||||
testing_spec::<E>(fork_name)
|
||||
pub steps: Vec<Step<SignedBeaconBlock<E>, Attestation<E>, AttesterSlashing<E>, PowBlock>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
@@ -92,7 +87,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
.to_str()
|
||||
.expect("path must be valid OsStr")
|
||||
.to_string();
|
||||
let spec = &fork_choice_spec::<E>(fork_name);
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
let steps: Vec<Step<String, String, String, String>> =
|
||||
yaml_decode_file(&path.join("steps.yaml"))?;
|
||||
// Resolve the object names in `steps.yaml` into actual decoded block/attestation objects.
|
||||
@@ -116,14 +111,14 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attestation)))
|
||||
.map(|attestation| Step::Attestation { attestation })
|
||||
}
|
||||
Step::PowBlock { pow_block } => {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", pow_block)))
|
||||
.map(|pow_block| Step::PowBlock { pow_block })
|
||||
}
|
||||
Step::AttesterSlashing { attester_slashing } => {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attester_slashing)))
|
||||
.map(|attester_slashing| Step::AttesterSlashing { attester_slashing })
|
||||
}
|
||||
Step::PowBlock { pow_block } => {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", pow_block)))
|
||||
.map(|pow_block| Step::PowBlock { pow_block })
|
||||
}
|
||||
Step::Checks { checks } => Ok(Step::Checks { checks }),
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
@@ -159,15 +154,12 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
}
|
||||
|
||||
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
|
||||
let tester = Tester::new(self, fork_choice_spec::<E>(fork_name))?;
|
||||
let tester = Tester::new(self, testing_spec::<E>(fork_name))?;
|
||||
|
||||
// TODO(merge): re-enable this test before production.
|
||||
// This test is skipped until we can do retrospective confirmations of the terminal
|
||||
// block after an optimistic sync.
|
||||
if self.description == "block_lookup_failed"
|
||||
//TODO(sean): enable once we implement equivocation logic (https://github.com/sigp/lighthouse/issues/3241)
|
||||
|| self.description == "discard_equivocations"
|
||||
{
|
||||
if self.description == "block_lookup_failed" {
|
||||
return Err(Error::SkippedKnownFailure);
|
||||
};
|
||||
|
||||
@@ -179,11 +171,10 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
tester.process_block(block.clone(), *valid)?
|
||||
}
|
||||
Step::Attestation { attestation } => tester.process_attestation(attestation)?,
|
||||
Step::AttesterSlashing { attester_slashing } => {
|
||||
tester.process_attester_slashing(attester_slashing)
|
||||
}
|
||||
Step::PowBlock { pow_block } => tester.process_pow_block(pow_block),
|
||||
//TODO(sean): enable once we implement equivocation logic (https://github.com/sigp/lighthouse/issues/3241)
|
||||
Step::AttesterSlashing {
|
||||
attester_slashing: _,
|
||||
} => (),
|
||||
Step::Checks { checks } => {
|
||||
let Checks {
|
||||
head,
|
||||
@@ -443,6 +434,14 @@ impl<E: EthSpec> Tester<E> {
|
||||
.map_err(|e| Error::InternalError(format!("attestation import failed with {:?}", e)))
|
||||
}
|
||||
|
||||
pub fn process_attester_slashing(&self, attester_slashing: &AttesterSlashing<E>) {
|
||||
self.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_write_lock()
|
||||
.on_attester_slashing(attester_slashing)
|
||||
}
|
||||
|
||||
pub fn process_pow_block(&self, pow_block: &PowBlock) {
|
||||
let el = self.harness.mock_execution_layer.as_ref().unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user