mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 21:34:46 +00:00
Altair consensus changes and refactors (#2279)
## Proposed Changes Implement the consensus changes necessary for the upcoming Altair hard fork. ## Additional Info This is quite a heavy refactor, with pivotal types like the `BeaconState` and `BeaconBlock` changing from structs to enums. This ripples through the whole codebase with field accesses changing to methods, e.g. `state.slot` => `state.slot()`. Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
use super::*;
|
||||
use crate::bls_setting::BlsSetting;
|
||||
use crate::case_result::compare_beacon_state_results_without_caches;
|
||||
use crate::decode::{ssz_decode_file, yaml_decode_file};
|
||||
use crate::decode::{ssz_decode_state, yaml_decode_file};
|
||||
use crate::type_name;
|
||||
use crate::type_name::TypeName;
|
||||
use serde_derive::Deserialize;
|
||||
use state_processing::per_epoch_processing::validator_statuses::ValidatorStatuses;
|
||||
use state_processing::per_epoch_processing::{
|
||||
errors::EpochProcessingError, process_final_updates, process_justification_and_finalization,
|
||||
process_registry_updates, process_rewards_and_penalties, process_slashings,
|
||||
validator_statuses::ValidatorStatuses,
|
||||
altair, base,
|
||||
effective_balance_updates::process_effective_balance_updates,
|
||||
historical_roots_update::process_historical_roots_update,
|
||||
process_registry_updates, process_slashings,
|
||||
resets::{process_eth1_data_reset, process_randao_mixes_reset, process_slashings_reset},
|
||||
};
|
||||
use state_processing::EpochProcessingError;
|
||||
use std::marker::PhantomData;
|
||||
use std::path::{Path, PathBuf};
|
||||
use types::{BeaconState, ChainSpec, EthSpec};
|
||||
use types::{BeaconState, ChainSpec, EthSpec, ForkName};
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
pub struct Metadata {
|
||||
@@ -44,7 +48,23 @@ pub struct RegistryUpdates;
|
||||
#[derive(Debug)]
|
||||
pub struct Slashings;
|
||||
#[derive(Debug)]
|
||||
pub struct FinalUpdates;
|
||||
pub struct Eth1DataReset;
|
||||
#[derive(Debug)]
|
||||
pub struct EffectiveBalanceUpdates;
|
||||
#[derive(Debug)]
|
||||
pub struct SlashingsReset;
|
||||
#[derive(Debug)]
|
||||
pub struct RandaoMixesReset;
|
||||
#[derive(Debug)]
|
||||
pub struct HistoricalRootsUpdate;
|
||||
#[derive(Debug)]
|
||||
pub struct ParticipationRecordUpdates;
|
||||
#[derive(Debug)]
|
||||
pub struct SyncCommitteeUpdates;
|
||||
#[derive(Debug)]
|
||||
pub struct InactivityUpdates;
|
||||
#[derive(Debug)]
|
||||
pub struct ParticipationFlagUpdates;
|
||||
|
||||
type_name!(
|
||||
JustificationAndFinalization,
|
||||
@@ -53,21 +73,43 @@ type_name!(
|
||||
type_name!(RewardsAndPenalties, "rewards_and_penalties");
|
||||
type_name!(RegistryUpdates, "registry_updates");
|
||||
type_name!(Slashings, "slashings");
|
||||
type_name!(FinalUpdates, "final_updates");
|
||||
type_name!(Eth1DataReset, "eth1_data_reset");
|
||||
type_name!(EffectiveBalanceUpdates, "effective_balance_updates");
|
||||
type_name!(SlashingsReset, "slashings_reset");
|
||||
type_name!(RandaoMixesReset, "randao_mixes_reset");
|
||||
type_name!(HistoricalRootsUpdate, "historical_roots_update");
|
||||
type_name!(ParticipationRecordUpdates, "participation_record_updates");
|
||||
type_name!(SyncCommitteeUpdates, "sync_committee_updates");
|
||||
type_name!(InactivityUpdates, "inactivity_updates");
|
||||
type_name!(ParticipationFlagUpdates, "participation_flag_updates");
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for JustificationAndFinalization {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
let mut validator_statuses = ValidatorStatuses::new(state, spec)?;
|
||||
validator_statuses.process_attestations(state, spec)?;
|
||||
process_justification_and_finalization(state, &validator_statuses.total_balances)
|
||||
match state {
|
||||
BeaconState::Base(_) => {
|
||||
let mut validator_statuses = ValidatorStatuses::new(state, spec)?;
|
||||
validator_statuses.process_attestations(state)?;
|
||||
base::process_justification_and_finalization(
|
||||
state,
|
||||
&validator_statuses.total_balances,
|
||||
spec,
|
||||
)
|
||||
}
|
||||
BeaconState::Altair(_) => altair::process_justification_and_finalization(state, spec),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for RewardsAndPenalties {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
let mut validator_statuses = ValidatorStatuses::new(state, spec)?;
|
||||
validator_statuses.process_attestations(state, spec)?;
|
||||
process_rewards_and_penalties(state, &mut validator_statuses, spec)
|
||||
match state {
|
||||
BeaconState::Base(_) => {
|
||||
let mut validator_statuses = ValidatorStatuses::new(state, spec)?;
|
||||
validator_statuses.process_attestations(state)?;
|
||||
base::process_rewards_and_penalties(state, &mut validator_statuses, spec)
|
||||
}
|
||||
BeaconState::Altair(_) => altair::process_rewards_and_penalties(state, spec),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,35 +121,110 @@ impl<E: EthSpec> EpochTransition<E> for RegistryUpdates {
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for Slashings {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
let mut validator_statuses = ValidatorStatuses::new(&state, spec)?;
|
||||
validator_statuses.process_attestations(&state, spec)?;
|
||||
process_slashings(
|
||||
state,
|
||||
validator_statuses.total_balances.current_epoch(),
|
||||
spec,
|
||||
)?;
|
||||
match state {
|
||||
BeaconState::Base(_) => {
|
||||
let mut validator_statuses = ValidatorStatuses::new(&state, spec)?;
|
||||
validator_statuses.process_attestations(&state)?;
|
||||
process_slashings(
|
||||
state,
|
||||
validator_statuses.total_balances.current_epoch(),
|
||||
spec.proportional_slashing_multiplier,
|
||||
spec,
|
||||
)?;
|
||||
}
|
||||
BeaconState::Altair(_) => {
|
||||
process_slashings(
|
||||
state,
|
||||
state.get_total_active_balance(spec)?,
|
||||
spec.proportional_slashing_multiplier_altair,
|
||||
spec,
|
||||
)?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for FinalUpdates {
|
||||
impl<E: EthSpec> EpochTransition<E> for Eth1DataReset {
|
||||
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
process_eth1_data_reset(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for EffectiveBalanceUpdates {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
process_final_updates(state, spec)
|
||||
process_effective_balance_updates(state, spec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for SlashingsReset {
|
||||
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
process_slashings_reset(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for RandaoMixesReset {
|
||||
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
process_randao_mixes_reset(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for HistoricalRootsUpdate {
|
||||
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
process_historical_roots_update(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for ParticipationRecordUpdates {
|
||||
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
if let BeaconState::Base(_) = state {
|
||||
base::process_participation_record_updates(state)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for SyncCommitteeUpdates {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
match state {
|
||||
BeaconState::Base(_) => Ok(()),
|
||||
BeaconState::Altair(_) => altair::process_sync_committee_updates(state, spec),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for InactivityUpdates {
|
||||
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
match state {
|
||||
BeaconState::Base(_) => Ok(()),
|
||||
BeaconState::Altair(_) => altair::process_inactivity_updates(state, spec),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> EpochTransition<E> for ParticipationFlagUpdates {
|
||||
fn run(state: &mut BeaconState<E>, _: &ChainSpec) -> Result<(), EpochProcessingError> {
|
||||
match state {
|
||||
BeaconState::Base(_) => Ok(()),
|
||||
BeaconState::Altair(_) => altair::process_participation_flag_updates(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec, T: EpochTransition<E>> LoadCase for EpochProcessing<E, T> {
|
||||
fn load_from_dir(path: &Path) -> Result<Self, Error> {
|
||||
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
let metadata_path = path.join("meta.yaml");
|
||||
let metadata: Metadata = if metadata_path.is_file() {
|
||||
yaml_decode_file(&metadata_path)?
|
||||
} else {
|
||||
Metadata::default()
|
||||
};
|
||||
let pre = ssz_decode_file(&path.join("pre.ssz"))?;
|
||||
let post_file = path.join("post.ssz");
|
||||
let pre = ssz_decode_state(&path.join("pre.ssz_snappy"), spec)?;
|
||||
let post_file = path.join("post.ssz_snappy");
|
||||
let post = if post_file.is_file() {
|
||||
Some(ssz_decode_file(&post_file)?)
|
||||
Some(ssz_decode_state(&post_file, spec)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -130,11 +247,25 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
|
||||
.unwrap_or_else(String::new)
|
||||
}
|
||||
|
||||
fn result(&self, _case_index: usize) -> Result<(), Error> {
|
||||
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||
match fork_name {
|
||||
// No Altair tests for genesis fork.
|
||||
ForkName::Base => {
|
||||
T::name() != "sync_committee_updates"
|
||||
&& T::name() != "inactivity_updates"
|
||||
&& T::name() != "participation_flag_updates"
|
||||
}
|
||||
ForkName::Altair => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
|
||||
self.metadata.bls_setting.unwrap_or_default().check()?;
|
||||
|
||||
let mut state = self.pre.clone();
|
||||
let mut expected = self.post.clone();
|
||||
|
||||
let spec = &E::default_spec();
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
|
||||
let mut result = (|| {
|
||||
// Processing requires the committee caches.
|
||||
|
||||
Reference in New Issue
Block a user