mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 02:42:38 +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,3 +1,4 @@
|
||||
use crate::upgrade::upgrade_to_altair;
|
||||
use crate::{per_epoch_processing::EpochProcessingSummary, *};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use types::*;
|
||||
@@ -7,6 +8,7 @@ pub enum Error {
|
||||
BeaconStateError(BeaconStateError),
|
||||
EpochProcessingError(EpochProcessingError),
|
||||
ArithError(ArithError),
|
||||
InconsistentStateFork(InconsistentFork),
|
||||
}
|
||||
|
||||
impl From<ArithError> for Error {
|
||||
@@ -20,24 +22,34 @@ 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.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
pub fn per_slot_processing<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
state_root: Option<Hash256>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<EpochProcessingSummary>, Error> {
|
||||
// Verify that the `BeaconState` instantiation matches the fork at `state.slot()`.
|
||||
state
|
||||
.fork_name(spec)
|
||||
.map_err(Error::InconsistentStateFork)?;
|
||||
|
||||
cache_state(state, state_root)?;
|
||||
|
||||
let summary = if state.slot > spec.genesis_slot
|
||||
&& state.slot.safe_add(1)?.safe_rem(T::slots_per_epoch())? == 0
|
||||
let summary = if state.slot() > spec.genesis_slot
|
||||
&& state.slot().safe_add(1)?.safe_rem(T::slots_per_epoch())? == 0
|
||||
{
|
||||
Some(per_epoch_processing(state, spec)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
state.slot.safe_add_assign(1)?;
|
||||
state.slot_mut().safe_add_assign(1)?;
|
||||
|
||||
// If the Altair fork epoch is reached, perform an irregular state upgrade.
|
||||
if state.slot().safe_rem(T::slots_per_epoch())? == 0
|
||||
&& spec.altair_fork_epoch == Some(state.current_epoch())
|
||||
{
|
||||
upgrade_to_altair(state, spec)?;
|
||||
}
|
||||
|
||||
Ok(summary)
|
||||
}
|
||||
@@ -56,23 +68,23 @@ fn cache_state<T: EthSpec>(
|
||||
// getter/setter functions.
|
||||
//
|
||||
// This is a bit hacky, however it gets the job done safely without lots of code.
|
||||
let previous_slot = state.slot;
|
||||
state.slot.safe_add_assign(1)?;
|
||||
let previous_slot = state.slot();
|
||||
state.slot_mut().safe_add_assign(1)?;
|
||||
|
||||
// Store the previous slot's post state transition root.
|
||||
state.set_state_root(previous_slot, previous_state_root)?;
|
||||
|
||||
// Cache latest block header state root
|
||||
if state.latest_block_header.state_root == Hash256::zero() {
|
||||
state.latest_block_header.state_root = previous_state_root;
|
||||
if state.latest_block_header().state_root == Hash256::zero() {
|
||||
state.latest_block_header_mut().state_root = previous_state_root;
|
||||
}
|
||||
|
||||
// Cache block root
|
||||
let latest_block_root = state.latest_block_header.canonical_root();
|
||||
let latest_block_root = state.latest_block_header().canonical_root();
|
||||
state.set_block_root(previous_slot, latest_block_root)?;
|
||||
|
||||
// Set the state slot back to what it should be.
|
||||
state.slot.safe_sub_assign(1)?;
|
||||
state.slot_mut().safe_sub_assign(1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user