fix genesis from eth1 for electra

This commit is contained in:
realbigsean
2024-05-12 04:53:12 -04:00
parent 7a0057b707
commit d7cc47ccc3
2 changed files with 60 additions and 42 deletions

View File

@@ -2,9 +2,9 @@ use super::per_block_processing::{
errors::BlockProcessingError, process_operations::apply_deposit,
};
use crate::common::DepositDataTree;
use crate::upgrade::electra::upgrade_state_to_electra;
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;
@@ -116,7 +116,8 @@ pub fn initialize_beacon_state_from_eth1<E: EthSpec>(
.electra_fork_epoch
.map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch())
{
upgrade_to_electra(&mut state, spec)?;
let post = upgrade_state_to_electra(&mut state, Epoch::new(0), Epoch::new(0), spec)?;
state = post;
// Remove intermediate Deneb fork from `state.fork`.
state.fork_mut().previous_version = spec.electra_fork_version;

View File

@@ -1,8 +1,8 @@
use safe_arith::SafeArith;
use std::mem;
use types::{
BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, EpochCache, EthSpec,
Fork,
BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, Epoch, EpochCache,
EthSpec, Fork,
};
/// Transform a `Deneb` state into an `Electra` state.
@@ -26,13 +26,66 @@ pub fn upgrade_to_electra<E: EthSpec>(
pre_state.build_total_active_balance_cache(spec)?;
let earliest_consolidation_epoch = spec.compute_activation_exit_epoch(epoch)?;
let mut post = upgrade_state_to_electra(
pre_state,
earliest_exit_epoch,
earliest_consolidation_epoch,
spec,
)?;
*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;
Ok(())
}
pub fn upgrade_state_to_electra<E: EthSpec>(
pre_state: &mut BeaconState<E>,
earliest_exit_epoch: Epoch,
earliest_consolidation_epoch: Epoch,
spec: &ChainSpec,
) -> Result<BeaconState<E>, 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 mut post = BeaconState::Electra(BeaconStateElectra {
let post = BeaconState::Electra(BeaconStateElectra {
// Versioning
genesis_time: pre.genesis_time,
genesis_validators_root: pre.genesis_validators_root,
@@ -96,41 +149,5 @@ 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;
Ok(())
Ok(post)
}