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:
Mac L
2024-04-02 23:35:02 +11:00
committed by GitHub
parent 3058b96f25
commit f8fdb71f50
105 changed files with 2079 additions and 405 deletions

View File

@@ -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);

View File

@@ -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)?,
};

View File

@@ -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();
}
}

View File

@@ -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()?;

View File

@@ -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(),

View File

@@ -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(),

View File

@@ -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)

View File

@@ -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)
}
}
}

View File

@@ -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)

View File

@@ -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;

View 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(())
}