mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 18:21:45 +00:00
Add Electra fork boilerplate (#5122)
* Add Electra fork boilerplate * Remove electra from spec tests * Fix tests * Remove sneaky log file * Fix more tests * Fix even more tests and add suggestions * Remove unrelated lcli addition * Update more tests * Merge branch 'unstable' into electra * Add comment for test-suite lcli override * Merge branch 'unstable' into electra * Cleanup * Merge branch 'unstable' into electra * Apply suggestions * Merge branch 'unstable' into electra * Merge sigp/unstable into electra * Merge branch 'unstable' into electra
This commit is contained in:
@@ -53,7 +53,7 @@ pub fn get_attestation_participation_flag_indices<T: EthSpec>(
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
}
|
||||
}
|
||||
&BeaconState::Deneb(_) => {
|
||||
&BeaconState::Deneb(_) | &BeaconState::Electra(_) => {
|
||||
if is_matching_target {
|
||||
// [Modified in Deneb:EIP7045]
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
|
||||
@@ -56,7 +56,8 @@ pub fn slash_validator<T: EthSpec>(
|
||||
BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Capella(_)
|
||||
| BeaconState::Deneb(_) => whistleblower_reward
|
||||
| BeaconState::Deneb(_)
|
||||
| BeaconState::Electra(_) => whistleblower_reward
|
||||
.safe_mul(PROPOSER_WEIGHT)?
|
||||
.safe_div(WEIGHT_DENOMINATOR)?,
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ use super::per_block_processing::{
|
||||
use crate::common::DepositDataTree;
|
||||
use crate::upgrade::{
|
||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||
upgrade_to_electra,
|
||||
};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use tree_hash::TreeHash;
|
||||
@@ -104,8 +105,25 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
|
||||
|
||||
// Override latest execution payload header.
|
||||
// See https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#testing
|
||||
if let Some(ExecutionPayloadHeader::Deneb(header)) = execution_payload_header {
|
||||
*state.latest_execution_payload_header_deneb_mut()? = header;
|
||||
if let Some(ExecutionPayloadHeader::Deneb(ref header)) = execution_payload_header {
|
||||
*state.latest_execution_payload_header_deneb_mut()? = header.clone();
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade to electra if configured from genesis.
|
||||
if spec
|
||||
.electra_fork_epoch
|
||||
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
|
||||
{
|
||||
upgrade_to_electra(&mut state, spec)?;
|
||||
|
||||
// Remove intermediate Deneb fork from `state.fork`.
|
||||
state.fork_mut().previous_version = spec.electra_fork_version;
|
||||
|
||||
// Override latest execution payload header.
|
||||
// See https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#testing
|
||||
if let Some(ExecutionPayloadHeader::Electra(header)) = execution_payload_header {
|
||||
*state.latest_execution_payload_header_electra_mut()? = header.clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -433,6 +433,12 @@ pub fn process_execution_payload<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
_ => return Err(BlockProcessingError::IncorrectStateType),
|
||||
}
|
||||
}
|
||||
ExecutionPayloadHeaderRefMut::Electra(header_mut) => {
|
||||
match payload.to_execution_payload_header() {
|
||||
ExecutionPayloadHeader::Electra(header) => *header_mut = header,
|
||||
_ => return Err(BlockProcessingError::IncorrectStateType),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -451,7 +457,7 @@ pub fn is_merge_transition_complete<T: EthSpec>(state: &BeaconState<T>) -> bool
|
||||
.latest_execution_payload_header()
|
||||
.map(|header| !header.is_default_with_zero_roots())
|
||||
.unwrap_or(false),
|
||||
BeaconState::Deneb(_) | BeaconState::Capella(_) => true,
|
||||
BeaconState::Electra(_) | BeaconState::Deneb(_) | BeaconState::Capella(_) => true,
|
||||
BeaconState::Base(_) | BeaconState::Altair(_) => false,
|
||||
}
|
||||
}
|
||||
@@ -549,7 +555,7 @@ pub fn process_withdrawals<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
match state {
|
||||
BeaconState::Merge(_) => Ok(()),
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) => {
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) | BeaconState::Electra(_) => {
|
||||
let expected_withdrawals = get_expected_withdrawals(state, spec)?;
|
||||
let expected_root = expected_withdrawals.tree_hash_root();
|
||||
let withdrawals_root = payload.withdrawals_root()?;
|
||||
|
||||
@@ -265,7 +265,8 @@ pub fn process_attestations<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
BeaconBlockBodyRef::Altair(_)
|
||||
| BeaconBlockBodyRef::Merge(_)
|
||||
| BeaconBlockBodyRef::Capella(_)
|
||||
| BeaconBlockBodyRef::Deneb(_) => {
|
||||
| BeaconBlockBodyRef::Deneb(_)
|
||||
| BeaconBlockBodyRef::Electra(_) => {
|
||||
altair_deneb::process_attestations(
|
||||
state,
|
||||
block_body.attestations(),
|
||||
|
||||
@@ -398,7 +398,7 @@ where
|
||||
state.genesis_validators_root(),
|
||||
),
|
||||
// EIP-7044
|
||||
BeaconState::Deneb(_) => spec.compute_domain(
|
||||
BeaconState::Deneb(_) | BeaconState::Electra(_) => spec.compute_domain(
|
||||
Domain::VoluntaryExit,
|
||||
spec.capella_fork_version,
|
||||
state.genesis_validators_root(),
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn verify_attestation_for_block_inclusion<'ctxt, T: EthSpec>(
|
||||
);
|
||||
}
|
||||
// [Modified in Deneb:EIP7045]
|
||||
BeaconState::Deneb(_) => {}
|
||||
BeaconState::Deneb(_) | BeaconState::Electra(_) => {}
|
||||
}
|
||||
|
||||
verify_attestation_for_state(state, attestation, ctxt, verify_signatures, spec)
|
||||
|
||||
@@ -40,7 +40,9 @@ pub fn process_epoch<T: EthSpec>(
|
||||
match state {
|
||||
BeaconState::Base(_) => base::process_epoch(state, spec),
|
||||
BeaconState::Altair(_) | BeaconState::Merge(_) => altair::process_epoch(state, spec),
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) => capella::process_epoch(state, spec),
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) | BeaconState::Electra(_) => {
|
||||
capella::process_epoch(state, spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::upgrade::{
|
||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||
upgrade_to_electra,
|
||||
};
|
||||
use crate::{per_epoch_processing::EpochProcessingSummary, *};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
@@ -61,10 +62,14 @@ pub fn per_slot_processing<T: EthSpec>(
|
||||
if spec.capella_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_capella(state, spec)?;
|
||||
}
|
||||
// Deneb
|
||||
// Deneb.
|
||||
if spec.deneb_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_deneb(state, spec)?;
|
||||
}
|
||||
// Electra.
|
||||
if spec.electra_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_electra(state, spec)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(summary)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
pub mod altair;
|
||||
pub mod capella;
|
||||
pub mod deneb;
|
||||
pub mod electra;
|
||||
pub mod merge;
|
||||
|
||||
pub use altair::upgrade_to_altair;
|
||||
pub use capella::upgrade_to_capella;
|
||||
pub use deneb::upgrade_to_deneb;
|
||||
pub use electra::upgrade_to_electra;
|
||||
pub use merge::upgrade_to_bellatrix;
|
||||
|
||||
74
consensus/state_processing/src/upgrade/electra.rs
Normal file
74
consensus/state_processing/src/upgrade/electra.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use std::mem;
|
||||
use types::{BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, EthSpec, Fork};
|
||||
|
||||
/// Transform a `Deneb` state into an `Electra` state.
|
||||
pub fn upgrade_to_electra<E: EthSpec>(
|
||||
pre_state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let epoch = pre_state.current_epoch();
|
||||
let pre = pre_state.as_deneb_mut()?;
|
||||
|
||||
// Where possible, use something like `mem::take` to move fields from behind the &mut
|
||||
// reference. For other fields that don't have a good default value, use `clone`.
|
||||
//
|
||||
// Fixed size vectors get cloned because replacing them would require the same size
|
||||
// allocation as cloning.
|
||||
let post = BeaconState::Electra(BeaconStateElectra {
|
||||
// Versioning
|
||||
genesis_time: pre.genesis_time,
|
||||
genesis_validators_root: pre.genesis_validators_root,
|
||||
slot: pre.slot,
|
||||
fork: Fork {
|
||||
previous_version: pre.fork.current_version,
|
||||
current_version: spec.electra_fork_version,
|
||||
epoch,
|
||||
},
|
||||
// History
|
||||
latest_block_header: pre.latest_block_header.clone(),
|
||||
block_roots: pre.block_roots.clone(),
|
||||
state_roots: pre.state_roots.clone(),
|
||||
historical_roots: mem::take(&mut pre.historical_roots),
|
||||
// Eth1
|
||||
eth1_data: pre.eth1_data.clone(),
|
||||
eth1_data_votes: mem::take(&mut pre.eth1_data_votes),
|
||||
eth1_deposit_index: pre.eth1_deposit_index,
|
||||
// Registry
|
||||
validators: mem::take(&mut pre.validators),
|
||||
balances: mem::take(&mut pre.balances),
|
||||
// Randomness
|
||||
randao_mixes: pre.randao_mixes.clone(),
|
||||
// Slashings
|
||||
slashings: pre.slashings.clone(),
|
||||
// `Participation
|
||||
previous_epoch_participation: mem::take(&mut pre.previous_epoch_participation),
|
||||
current_epoch_participation: mem::take(&mut pre.current_epoch_participation),
|
||||
// Finality
|
||||
justification_bits: pre.justification_bits.clone(),
|
||||
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
||||
current_justified_checkpoint: pre.current_justified_checkpoint,
|
||||
finalized_checkpoint: pre.finalized_checkpoint,
|
||||
// Inactivity
|
||||
inactivity_scores: mem::take(&mut pre.inactivity_scores),
|
||||
// Sync committees
|
||||
current_sync_committee: pre.current_sync_committee.clone(),
|
||||
next_sync_committee: pre.next_sync_committee.clone(),
|
||||
// Execution
|
||||
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_electra(),
|
||||
// Capella
|
||||
next_withdrawal_index: pre.next_withdrawal_index,
|
||||
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
|
||||
historical_summaries: pre.historical_summaries.clone(),
|
||||
// Caches
|
||||
total_active_balance: pre.total_active_balance,
|
||||
progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache),
|
||||
committee_caches: mem::take(&mut pre.committee_caches),
|
||||
pubkey_cache: mem::take(&mut pre.pubkey_cache),
|
||||
exit_cache: mem::take(&mut pre.exit_cache),
|
||||
tree_hash_cache: mem::take(&mut pre.tree_hash_cache),
|
||||
});
|
||||
|
||||
*pre_state = post;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user