mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 09:16:00 +00:00
fix genesis from eth1 for electra
This commit is contained in:
@@ -2,9 +2,9 @@ use super::per_block_processing::{
|
|||||||
errors::BlockProcessingError, process_operations::apply_deposit,
|
errors::BlockProcessingError, process_operations::apply_deposit,
|
||||||
};
|
};
|
||||||
use crate::common::DepositDataTree;
|
use crate::common::DepositDataTree;
|
||||||
|
use crate::upgrade::electra::upgrade_state_to_electra;
|
||||||
use crate::upgrade::{
|
use crate::upgrade::{
|
||||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||||
upgrade_to_electra,
|
|
||||||
};
|
};
|
||||||
use safe_arith::{ArithError, SafeArith};
|
use safe_arith::{ArithError, SafeArith};
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
@@ -116,7 +116,8 @@ pub fn initialize_beacon_state_from_eth1<E: EthSpec>(
|
|||||||
.electra_fork_epoch
|
.electra_fork_epoch
|
||||||
.map_or(false, |fork_epoch| fork_epoch == E::genesis_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`.
|
// Remove intermediate Deneb fork from `state.fork`.
|
||||||
state.fork_mut().previous_version = spec.electra_fork_version;
|
state.fork_mut().previous_version = spec.electra_fork_version;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use types::{
|
use types::{
|
||||||
BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, EpochCache, EthSpec,
|
BeaconState, BeaconStateElectra, BeaconStateError as Error, ChainSpec, Epoch, EpochCache,
|
||||||
Fork,
|
EthSpec, Fork,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Transform a `Deneb` state into an `Electra` state.
|
/// 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)?;
|
pre_state.build_total_active_balance_cache(spec)?;
|
||||||
let earliest_consolidation_epoch = spec.compute_activation_exit_epoch(epoch)?;
|
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()?;
|
let pre = pre_state.as_deneb_mut()?;
|
||||||
// Where possible, use something like `mem::take` to move fields from behind the &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`.
|
// 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
|
// Fixed size vectors get cloned because replacing them would require the same size
|
||||||
// allocation as cloning.
|
// allocation as cloning.
|
||||||
let mut post = BeaconState::Electra(BeaconStateElectra {
|
let post = BeaconState::Electra(BeaconStateElectra {
|
||||||
// Versioning
|
// Versioning
|
||||||
genesis_time: pre.genesis_time,
|
genesis_time: pre.genesis_time,
|
||||||
genesis_validators_root: pre.genesis_validators_root,
|
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),
|
slashings_cache: mem::take(&mut pre.slashings_cache),
|
||||||
epoch_cache: EpochCache::default(),
|
epoch_cache: EpochCache::default(),
|
||||||
});
|
});
|
||||||
*post.exit_balance_to_consume_mut()? = post.get_activation_exit_churn_limit(spec)?;
|
Ok(post)
|
||||||
*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(())
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user