mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 18:04:18 +00:00
Merge remote-tracking branch 'upstream/unstable' into electra_attestation_changes
This commit is contained in:
@@ -47,7 +47,7 @@ pub fn get_attestation_participation_flag_indices<E: EthSpec>(
|
||||
match state {
|
||||
&BeaconState::Base(_)
|
||||
| &BeaconState::Altair(_)
|
||||
| &BeaconState::Merge(_)
|
||||
| &BeaconState::Bellatrix(_)
|
||||
| &BeaconState::Capella(_) => {
|
||||
if is_matching_target && inclusion_delay <= E::slots_per_epoch() {
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
|
||||
@@ -58,7 +58,7 @@ pub fn slash_validator<E: EthSpec>(
|
||||
let proposer_reward = match state {
|
||||
BeaconState::Base(_) => whistleblower_reward.safe_div(spec.proposer_reward_quotient)?,
|
||||
BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Bellatrix(_)
|
||||
| BeaconState::Capella(_)
|
||||
| BeaconState::Deneb(_)
|
||||
| BeaconState::Electra(_) => whistleblower_reward
|
||||
|
||||
@@ -63,7 +63,7 @@ pub fn initialize_beacon_state_from_eth1<E: EthSpec>(
|
||||
.bellatrix_fork_epoch
|
||||
.map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch())
|
||||
{
|
||||
// this will set state.latest_execution_payload_header = ExecutionPayloadHeaderMerge::default()
|
||||
// this will set state.latest_execution_payload_header = ExecutionPayloadHeaderBellatrix::default()
|
||||
upgrade_to_bellatrix(&mut state, spec)?;
|
||||
|
||||
// Remove intermediate Altair fork from `state.fork`.
|
||||
@@ -71,8 +71,8 @@ pub fn initialize_beacon_state_from_eth1<E: EthSpec>(
|
||||
|
||||
// Override latest execution payload header.
|
||||
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing
|
||||
if let Some(ExecutionPayloadHeader::Merge(ref header)) = execution_payload_header {
|
||||
*state.latest_execution_payload_header_merge_mut()? = header.clone();
|
||||
if let Some(ExecutionPayloadHeader::Bellatrix(ref header)) = execution_payload_header {
|
||||
*state.latest_execution_payload_header_bellatrix_mut()? = header.clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ lazy_static! {
|
||||
"beacon_participation_prev_epoch_source_attesting_gwei_total",
|
||||
"Total effective balance (gwei) of validators who attested to the source in the previous epoch"
|
||||
);
|
||||
pub static ref PARTICIPATION_CURRENT_EPOCH_TOTAL_ACTIVE_GWEI_TOTAL: Result<IntGauge> = try_create_int_gauge(
|
||||
"beacon_participation_current_epoch_active_gwei_total",
|
||||
"Total effective balance (gwei) of validators who are active in the current epoch"
|
||||
);
|
||||
/*
|
||||
* Processing metrics
|
||||
*/
|
||||
|
||||
@@ -418,9 +418,9 @@ pub fn process_execution_payload<E: EthSpec, Payload: AbstractExecPayload<E>>(
|
||||
partially_verify_execution_payload::<E, Payload>(state, state.slot(), body, spec)?;
|
||||
let payload = body.execution_payload()?;
|
||||
match state.latest_execution_payload_header_mut()? {
|
||||
ExecutionPayloadHeaderRefMut::Merge(header_mut) => {
|
||||
ExecutionPayloadHeaderRefMut::Bellatrix(header_mut) => {
|
||||
match payload.to_execution_payload_header() {
|
||||
ExecutionPayloadHeader::Merge(header) => *header_mut = header,
|
||||
ExecutionPayloadHeader::Bellatrix(header) => *header_mut = header,
|
||||
_ => return Err(BlockProcessingError::IncorrectStateType),
|
||||
}
|
||||
}
|
||||
@@ -449,14 +449,14 @@ pub fn process_execution_payload<E: EthSpec, Payload: AbstractExecPayload<E>>(
|
||||
|
||||
/// These functions will definitely be called before the merge. Their entire purpose is to check if
|
||||
/// the merge has happened or if we're on the transition block. Thus we don't want to propagate
|
||||
/// errors from the `BeaconState` being an earlier variant than `BeaconStateMerge` as we'd have to
|
||||
/// errors from the `BeaconState` being an earlier variant than `BeaconStateBellatrix` as we'd have to
|
||||
/// repeatedly write code to treat these errors as false.
|
||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#is_merge_transition_complete
|
||||
pub fn is_merge_transition_complete<E: EthSpec>(state: &BeaconState<E>) -> bool {
|
||||
match state {
|
||||
// We must check defaultness against the payload header with 0x0 roots, as that's what's meant
|
||||
// by `ExecutionPayloadHeader()` in the spec.
|
||||
BeaconState::Merge(_) => state
|
||||
BeaconState::Bellatrix(_) => state
|
||||
.latest_execution_payload_header()
|
||||
.map(|header| !header.is_default_with_zero_roots())
|
||||
.unwrap_or(false),
|
||||
@@ -557,7 +557,7 @@ pub fn process_withdrawals<E: EthSpec, Payload: AbstractExecPayload<E>>(
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
match state {
|
||||
BeaconState::Merge(_) => Ok(()),
|
||||
BeaconState::Bellatrix(_) => Ok(()),
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) | BeaconState::Electra(_) => {
|
||||
let expected_withdrawals = get_expected_withdrawals(state, spec)?;
|
||||
let expected_root = expected_withdrawals.tree_hash_root();
|
||||
|
||||
@@ -286,7 +286,7 @@ pub fn process_attestations<E: EthSpec, Payload: AbstractExecPayload<E>>(
|
||||
)?;
|
||||
}
|
||||
BeaconBlockBodyRef::Altair(_)
|
||||
| BeaconBlockBodyRef::Merge(_)
|
||||
| BeaconBlockBodyRef::Bellatrix(_)
|
||||
| BeaconBlockBodyRef::Capella(_)
|
||||
| BeaconBlockBodyRef::Deneb(_)
|
||||
| BeaconBlockBodyRef::Electra(_) => {
|
||||
|
||||
@@ -390,7 +390,7 @@ where
|
||||
let domain = match state {
|
||||
BeaconState::Base(_)
|
||||
| BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Bellatrix(_)
|
||||
| BeaconState::Capella(_) => spec.get_domain(
|
||||
exit.epoch,
|
||||
Domain::VoluntaryExit,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub fn verify_attestation_for_block_inclusion<'ctxt, E: EthSpec>(
|
||||
match state {
|
||||
BeaconState::Base(_)
|
||||
| BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Bellatrix(_)
|
||||
| BeaconState::Capella(_) => {
|
||||
verify!(
|
||||
state.slot() <= data.slot.safe_add(E::slots_per_epoch())?,
|
||||
|
||||
@@ -44,7 +44,7 @@ pub fn process_epoch<E: EthSpec>(
|
||||
match state {
|
||||
BeaconState::Base(_) => base::process_epoch(state, spec),
|
||||
BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Bellatrix(_)
|
||||
| BeaconState::Capella(_)
|
||||
| BeaconState::Deneb(_)
|
||||
| BeaconState::Electra(_) => altair::process_epoch(state, spec),
|
||||
|
||||
@@ -100,6 +100,10 @@ impl<E: EthSpec> EpochProcessingSummary<E> {
|
||||
&metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL,
|
||||
self.previous_epoch_source_attesting_balance()? as i64,
|
||||
);
|
||||
metrics::set_gauge(
|
||||
&metrics::PARTICIPATION_CURRENT_EPOCH_TOTAL_ACTIVE_GWEI_TOTAL,
|
||||
self.current_epoch_total_active_balance() as i64,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ pub fn per_slot_processing<E: EthSpec>(
|
||||
if spec.altair_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_altair(state, spec)?;
|
||||
}
|
||||
// If the Merge fork epoch is reached, perform an irregular state upgrade.
|
||||
// If the Bellatrix fork epoch is reached, perform an irregular state upgrade.
|
||||
if spec.bellatrix_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_bellatrix(state, spec)?;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
pub mod altair;
|
||||
pub mod bellatrix;
|
||||
pub mod capella;
|
||||
pub mod deneb;
|
||||
pub mod electra;
|
||||
pub mod merge;
|
||||
|
||||
pub use altair::upgrade_to_altair;
|
||||
pub use bellatrix::upgrade_to_bellatrix;
|
||||
pub use capella::upgrade_to_capella;
|
||||
pub use deneb::upgrade_to_deneb;
|
||||
pub use electra::upgrade_to_electra;
|
||||
pub use merge::upgrade_to_bellatrix;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::mem;
|
||||
use types::{
|
||||
BeaconState, BeaconStateError as Error, BeaconStateMerge, ChainSpec, EpochCache, EthSpec,
|
||||
ExecutionPayloadHeaderMerge, Fork,
|
||||
BeaconState, BeaconStateBellatrix, BeaconStateError as Error, ChainSpec, EpochCache, EthSpec,
|
||||
ExecutionPayloadHeaderBellatrix, Fork,
|
||||
};
|
||||
|
||||
/// Transform a `Altair` state into an `Merge` state.
|
||||
/// Transform a `Altair` state into an `Bellatrix` state.
|
||||
pub fn upgrade_to_bellatrix<E: EthSpec>(
|
||||
pre_state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
@@ -17,7 +17,7 @@ pub fn upgrade_to_bellatrix<E: EthSpec>(
|
||||
//
|
||||
// Fixed size vectors get cloned because replacing them would require the same size
|
||||
// allocation as cloning.
|
||||
let post = BeaconState::Merge(BeaconStateMerge {
|
||||
let post = BeaconState::Bellatrix(BeaconStateBellatrix {
|
||||
// Versioning
|
||||
genesis_time: pre.genesis_time,
|
||||
genesis_validators_root: pre.genesis_validators_root,
|
||||
@@ -57,7 +57,7 @@ pub fn upgrade_to_bellatrix<E: EthSpec>(
|
||||
current_sync_committee: pre.current_sync_committee.clone(),
|
||||
next_sync_committee: pre.next_sync_committee.clone(),
|
||||
// Execution
|
||||
latest_execution_payload_header: <ExecutionPayloadHeaderMerge<E>>::default(),
|
||||
latest_execution_payload_header: <ExecutionPayloadHeaderBellatrix<E>>::default(),
|
||||
// Caches
|
||||
total_active_balance: pre.total_active_balance,
|
||||
progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache),
|
||||
@@ -4,13 +4,13 @@ use types::{
|
||||
Fork, List,
|
||||
};
|
||||
|
||||
/// Transform a `Merge` state into an `Capella` state.
|
||||
/// Transform a `Bellatrix` state into an `Capella` state.
|
||||
pub fn upgrade_to_capella<E: EthSpec>(
|
||||
pre_state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let epoch = pre_state.current_epoch();
|
||||
let pre = pre_state.as_merge_mut()?;
|
||||
let pre = pre_state.as_bellatrix_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`.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use safe_arith::SafeArith;
|
||||
use std::mem;
|
||||
use types::{
|
||||
BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, EpochCache, EthSpec,
|
||||
@@ -10,14 +11,28 @@ pub fn upgrade_to_electra<E: EthSpec>(
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let epoch = pre_state.current_epoch();
|
||||
let pre = pre_state.as_deneb_mut()?;
|
||||
|
||||
let earliest_exit_epoch = pre_state
|
||||
.validators()
|
||||
.iter()
|
||||
.filter(|v| v.exit_epoch != spec.far_future_epoch)
|
||||
.map(|v| v.exit_epoch)
|
||||
.max()
|
||||
.unwrap_or(epoch)
|
||||
.safe_add(1)?;
|
||||
|
||||
// The total active balance cache must be built before the consolidation churn limit
|
||||
// is calculated.
|
||||
pre_state.build_total_active_balance_cache(spec)?;
|
||||
let earliest_consolidation_epoch = spec.compute_activation_exit_epoch(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 {
|
||||
let mut post = BeaconState::Electra(BeaconStateElectra {
|
||||
// Versioning
|
||||
genesis_time: pre.genesis_time,
|
||||
genesis_validators_root: pre.genesis_validators_root,
|
||||
@@ -62,6 +77,16 @@ pub fn upgrade_to_electra<E: EthSpec>(
|
||||
next_withdrawal_index: pre.next_withdrawal_index,
|
||||
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
|
||||
historical_summaries: pre.historical_summaries.clone(),
|
||||
// Electra
|
||||
deposit_receipts_start_index: spec.unset_deposit_receipts_start_index,
|
||||
deposit_balance_to_consume: 0,
|
||||
exit_balance_to_consume: 0,
|
||||
earliest_exit_epoch,
|
||||
consolidation_balance_to_consume: 0,
|
||||
earliest_consolidation_epoch,
|
||||
pending_balance_deposits: Default::default(),
|
||||
pending_partial_withdrawals: Default::default(),
|
||||
pending_consolidations: Default::default(),
|
||||
// Caches
|
||||
total_active_balance: pre.total_active_balance,
|
||||
progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache),
|
||||
@@ -71,6 +96,39 @@ pub fn upgrade_to_electra<E: EthSpec>(
|
||||
slashings_cache: mem::take(&mut pre.slashings_cache),
|
||||
epoch_cache: EpochCache::default(),
|
||||
});
|
||||
*post.exit_balance_to_consume_mut()? = post.get_activation_exit_churn_limit(spec)?;
|
||||
*post.consolidation_balance_to_consume_mut()? = post.get_consolidation_churn_limit(spec)?;
|
||||
|
||||
// Add validators that are not yet active to pending balance deposits
|
||||
let validators = post.validators().clone();
|
||||
let mut pre_activation = validators
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, validator)| validator.activation_epoch == spec.far_future_epoch)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Sort the indices by activation_eligibility_epoch and then by index
|
||||
pre_activation.sort_by(|(index_a, val_a), (index_b, val_b)| {
|
||||
if val_a.activation_eligibility_epoch == val_b.activation_eligibility_epoch {
|
||||
index_a.cmp(index_b)
|
||||
} else {
|
||||
val_a
|
||||
.activation_eligibility_epoch
|
||||
.cmp(&val_b.activation_eligibility_epoch)
|
||||
}
|
||||
});
|
||||
|
||||
// Process validators to queue entire balance and reset them
|
||||
for (index, _) in pre_activation {
|
||||
post.queue_entire_balance_and_reset_validator(index, spec)?;
|
||||
}
|
||||
|
||||
// Ensure early adopters of compounding credentials go through the activation churn
|
||||
for (index, validator) in validators.iter().enumerate() {
|
||||
if validator.has_compounding_withdrawal_credential(spec) {
|
||||
post.queue_excess_active_balance(index, spec)?;
|
||||
}
|
||||
}
|
||||
|
||||
*pre_state = post;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user