mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 20:57:10 +00:00
Merge remote-tracking branch 'origin/deneb-free-blobs' into tree-states
This commit is contained in:
@@ -44,8 +44,21 @@ pub fn get_attestation_participation_flag_indices<T: EthSpec>(
|
||||
if is_matching_source && inclusion_delay <= T::slots_per_epoch().integer_sqrt() {
|
||||
participation_flag_indices.push(TIMELY_SOURCE_FLAG_INDEX);
|
||||
}
|
||||
if is_matching_target && inclusion_delay <= T::slots_per_epoch() {
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
match state {
|
||||
&BeaconState::Base(_)
|
||||
| &BeaconState::Altair(_)
|
||||
| &BeaconState::Merge(_)
|
||||
| &BeaconState::Capella(_) => {
|
||||
if is_matching_target && inclusion_delay <= T::slots_per_epoch() {
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
}
|
||||
}
|
||||
&BeaconState::Deneb(_) => {
|
||||
if is_matching_target {
|
||||
// [Modified in Deneb:EIP7045]
|
||||
participation_flag_indices.push(TIMELY_TARGET_FLAG_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_matching_head && inclusion_delay == spec.min_attestation_inclusion_delay {
|
||||
participation_flag_indices.push(TIMELY_HEAD_FLAG_INDEX);
|
||||
|
||||
@@ -57,11 +57,12 @@ pub fn slash_validator<T: EthSpec>(
|
||||
validator_effective_balance.safe_div(spec.whistleblower_reward_quotient)?;
|
||||
let proposer_reward = match state {
|
||||
BeaconState::Base(_) => whistleblower_reward.safe_div(spec.proposer_reward_quotient)?,
|
||||
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
|
||||
whistleblower_reward
|
||||
.safe_mul(PROPOSER_WEIGHT)?
|
||||
.safe_div(WEIGHT_DENOMINATOR)?
|
||||
}
|
||||
BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Capella(_)
|
||||
| BeaconState::Deneb(_) => whistleblower_reward
|
||||
.safe_mul(PROPOSER_WEIGHT)?
|
||||
.safe_div(WEIGHT_DENOMINATOR)?,
|
||||
};
|
||||
|
||||
// Ensure the whistleblower index is in the validator registry.
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use crate::common::get_indexed_attestation;
|
||||
use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError};
|
||||
use crate::EpochCacheError;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::collections::{hash_map::Entry, HashMap};
|
||||
use std::marker::PhantomData;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{
|
||||
AbstractExecPayload, Attestation, AttestationData, BeaconState, BeaconStateError, BitList,
|
||||
ChainSpec, Epoch, EthSpec, Hash256, IndexedAttestation, SignedBeaconBlock, Slot,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
|
||||
pub struct ConsensusContext<T: EthSpec> {
|
||||
/// Slot to act as an identifier/safeguard
|
||||
slot: Slot,
|
||||
@@ -22,9 +22,10 @@ pub struct ConsensusContext<T: EthSpec> {
|
||||
/// Block root of the block at `slot`.
|
||||
current_block_root: Option<Hash256>,
|
||||
/// Cache of indexed attestations constructed during block processing.
|
||||
/// We can skip serializing / deserializing this as the cache will just be rebuilt
|
||||
#[ssz(skip_serializing, skip_deserializing)]
|
||||
indexed_attestations:
|
||||
HashMap<(AttestationData, BitList<T::MaxValidatorsPerCommittee>), IndexedAttestation<T>>,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
@@ -58,7 +59,6 @@ impl<T: EthSpec> ConsensusContext<T> {
|
||||
proposer_index: None,
|
||||
current_block_root: None,
|
||||
indexed_attestations: HashMap::new(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ use super::per_block_processing::{
|
||||
errors::BlockProcessingError, process_operations::process_deposit,
|
||||
};
|
||||
use crate::common::DepositDataTree;
|
||||
use crate::upgrade::{upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella};
|
||||
use crate::upgrade::{
|
||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||
};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use tree_hash::TreeHash;
|
||||
use types::DEPOSIT_TREE_DEPTH;
|
||||
@@ -91,6 +93,23 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade to deneb if configured from genesis
|
||||
if spec
|
||||
.deneb_fork_epoch
|
||||
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
|
||||
{
|
||||
upgrade_to_deneb(&mut state, spec)?;
|
||||
|
||||
// Remove intermediate Capella fork from `state.fork`.
|
||||
state.fork_mut().previous_version = spec.deneb_fork_version;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have our validators, initialize the caches (including the committees)
|
||||
state.build_caches(spec)?;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ pub use verify_exit::verify_exit;
|
||||
|
||||
pub mod altair;
|
||||
pub mod block_signature_verifier;
|
||||
pub mod deneb;
|
||||
pub mod errors;
|
||||
mod is_valid_indexed_attestation;
|
||||
pub mod process_operations;
|
||||
@@ -170,11 +171,11 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
// `process_randao` as the former depends on the `randao_mix` computed with the reveal of the
|
||||
// previous block.
|
||||
if is_execution_enabled(state, block.body()) {
|
||||
let payload = block.body().execution_payload()?;
|
||||
let body = block.body();
|
||||
if state_processing_strategy == StateProcessingStrategy::Accurate {
|
||||
process_withdrawals::<T, Payload>(state, payload, spec)?;
|
||||
process_withdrawals::<T, Payload>(state, body.execution_payload()?, spec)?;
|
||||
}
|
||||
process_execution_payload::<T, Payload>(state, payload, spec)?;
|
||||
process_execution_payload::<T, Payload>(state, body, spec)?;
|
||||
}
|
||||
|
||||
process_randao(state, block, verify_randao, ctxt, spec)?;
|
||||
@@ -362,9 +363,10 @@ pub fn get_new_eth1_data<T: EthSpec>(
|
||||
pub fn partially_verify_execution_payload<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
state: &BeaconState<T>,
|
||||
block_slot: Slot,
|
||||
payload: Payload::Ref<'_>,
|
||||
body: BeaconBlockBodyRef<T, Payload>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
let payload = body.execution_payload()?;
|
||||
if is_merge_transition_complete(state) {
|
||||
block_verify!(
|
||||
payload.parent_hash() == state.latest_execution_payload_header()?.block_hash(),
|
||||
@@ -391,6 +393,17 @@ pub fn partially_verify_execution_payload<T: EthSpec, Payload: AbstractExecPaylo
|
||||
}
|
||||
);
|
||||
|
||||
if let Ok(blob_commitments) = body.blob_kzg_commitments() {
|
||||
// Verify commitments are under the limit.
|
||||
block_verify!(
|
||||
blob_commitments.len() <= T::max_blobs_per_block(),
|
||||
BlockProcessingError::ExecutionInvalidBlobsLen {
|
||||
max: T::max_blobs_per_block(),
|
||||
actual: blob_commitments.len(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -403,11 +416,11 @@ pub fn partially_verify_execution_payload<T: EthSpec, Payload: AbstractExecPaylo
|
||||
/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/beacon-chain.md#process_execution_payload
|
||||
pub fn process_execution_payload<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
state: &mut BeaconState<T>,
|
||||
payload: Payload::Ref<'_>,
|
||||
body: BeaconBlockBodyRef<T, Payload>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
partially_verify_execution_payload::<T, Payload>(state, state.slot(), payload, spec)?;
|
||||
|
||||
partially_verify_execution_payload::<T, Payload>(state, state.slot(), body, spec)?;
|
||||
let payload = body.execution_payload()?;
|
||||
match state.latest_execution_payload_header_mut()? {
|
||||
ExecutionPayloadHeaderRefMut::Merge(header_mut) => {
|
||||
match payload.to_execution_payload_header() {
|
||||
@@ -421,6 +434,12 @@ pub fn process_execution_payload<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
_ => return Err(BlockProcessingError::IncorrectStateType),
|
||||
}
|
||||
}
|
||||
ExecutionPayloadHeaderRefMut::Deneb(header_mut) => {
|
||||
match payload.to_execution_payload_header() {
|
||||
ExecutionPayloadHeader::Deneb(header) => *header_mut = header,
|
||||
_ => return Err(BlockProcessingError::IncorrectStateType),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -429,15 +448,19 @@ pub fn process_execution_payload<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
/// 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
|
||||
/// repeaetedly write code to treat these errors as false.
|
||||
/// 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<T: EthSpec>(state: &BeaconState<T>) -> bool {
|
||||
// We must check defaultness against the payload header with 0x0 roots, as that's what's meant
|
||||
// by `ExecutionPayloadHeader()` in the spec.
|
||||
state
|
||||
.latest_execution_payload_header()
|
||||
.map(|header| !header.is_default_with_zero_roots())
|
||||
.unwrap_or(false)
|
||||
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
|
||||
.latest_execution_payload_header()
|
||||
.map(|header| !header.is_default_with_zero_roots())
|
||||
.unwrap_or(false),
|
||||
BeaconState::Deneb(_) | BeaconState::Capella(_) => true,
|
||||
BeaconState::Base(_) | BeaconState::Altair(_) => false,
|
||||
}
|
||||
}
|
||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#is_merge_transition_block
|
||||
pub fn is_merge_transition_block<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
@@ -533,7 +556,7 @@ pub fn process_withdrawals<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
match state {
|
||||
BeaconState::Merge(_) => Ok(()),
|
||||
BeaconState::Capella(_) => {
|
||||
BeaconState::Capella(_) | BeaconState::Deneb(_) => {
|
||||
let expected_withdrawals = get_expected_withdrawals(state, spec)?;
|
||||
let expected_root = expected_withdrawals.tree_hash_root();
|
||||
let withdrawals_root = payload.withdrawals_root()?;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
use ethereum_hashing::hash_fixed;
|
||||
use types::consts::deneb::VERSIONED_HASH_VERSION_KZG;
|
||||
use types::{KzgCommitment, VersionedHash};
|
||||
|
||||
pub fn kzg_commitment_to_versioned_hash(kzg_commitment: &KzgCommitment) -> VersionedHash {
|
||||
let mut hashed_commitment = hash_fixed(&kzg_commitment.0);
|
||||
hashed_commitment[0] = VERSIONED_HASH_VERSION_KZG;
|
||||
VersionedHash::from(hashed_commitment)
|
||||
}
|
||||
@@ -78,6 +78,10 @@ pub enum BlockProcessingError {
|
||||
expected: u64,
|
||||
found: u64,
|
||||
},
|
||||
ExecutionInvalidBlobsLen {
|
||||
max: usize,
|
||||
actual: usize,
|
||||
},
|
||||
ExecutionInvalid,
|
||||
ConsensusContext(ContextError),
|
||||
MilhouseError(milhouse::Error),
|
||||
|
||||
@@ -95,7 +95,7 @@ pub mod base {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod altair {
|
||||
pub mod altair_deneb {
|
||||
use super::*;
|
||||
use crate::common::update_progressive_balances_cache::update_progressive_balances_on_attestation;
|
||||
|
||||
@@ -276,8 +276,9 @@ pub fn process_attestations<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
}
|
||||
BeaconBlockBodyRef::Altair(_)
|
||||
| BeaconBlockBodyRef::Merge(_)
|
||||
| BeaconBlockBodyRef::Capella(_) => {
|
||||
altair::process_attestations(
|
||||
| BeaconBlockBodyRef::Capella(_)
|
||||
| BeaconBlockBodyRef::Deneb(_) => {
|
||||
altair_deneb::process_attestations(
|
||||
state,
|
||||
block_body.attestations(),
|
||||
verify_signatures,
|
||||
|
||||
@@ -387,12 +387,23 @@ where
|
||||
let exit = &signed_exit.message;
|
||||
let proposer_index = exit.validator_index as usize;
|
||||
|
||||
let domain = spec.get_domain(
|
||||
exit.epoch,
|
||||
Domain::VoluntaryExit,
|
||||
&state.fork(),
|
||||
state.genesis_validators_root(),
|
||||
);
|
||||
let domain = match state {
|
||||
BeaconState::Base(_)
|
||||
| BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Capella(_) => spec.get_domain(
|
||||
exit.epoch,
|
||||
Domain::VoluntaryExit,
|
||||
&state.fork(),
|
||||
state.genesis_validators_root(),
|
||||
),
|
||||
// EIP-7044
|
||||
BeaconState::Deneb(_) => spec.compute_domain(
|
||||
Domain::VoluntaryExit,
|
||||
spec.capella_fork_version,
|
||||
state.genesis_validators_root(),
|
||||
),
|
||||
};
|
||||
|
||||
let message = exit.signing_root(domain);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ async fn get_harness<E: EthSpec>(
|
||||
// Set the state and block to be in the last slot of the `epoch_offset`th epoch.
|
||||
let last_slot_of_epoch =
|
||||
(MainnetEthSpec::genesis_epoch() + epoch_offset).end_slot(E::slots_per_epoch());
|
||||
let harness = BeaconChainHarness::builder(E::default())
|
||||
let harness = BeaconChainHarness::<EphemeralHarnessType<E>>::builder(E::default())
|
||||
.default_spec()
|
||||
.keypairs(KEYPAIRS[0..num_validators].to_vec())
|
||||
.fresh_ephemeral_store()
|
||||
@@ -63,7 +63,7 @@ async fn valid_block_ok() {
|
||||
let state = harness.get_current_state();
|
||||
|
||||
let slot = state.slot();
|
||||
let (block, mut state) = harness
|
||||
let ((block, _), mut state) = harness
|
||||
.make_block_return_pre_state(state, slot + Slot::new(1))
|
||||
.await;
|
||||
|
||||
@@ -89,7 +89,7 @@ async fn invalid_block_header_state_slot() {
|
||||
let state = harness.get_current_state();
|
||||
let slot = state.slot() + Slot::new(1);
|
||||
|
||||
let (signed_block, mut state) = harness.make_block_return_pre_state(state, slot).await;
|
||||
let ((signed_block, _), mut state) = harness.make_block_return_pre_state(state, slot).await;
|
||||
let (mut block, signature) = signed_block.deconstruct();
|
||||
*block.slot_mut() = slot + Slot::new(1);
|
||||
|
||||
@@ -120,7 +120,7 @@ async fn invalid_parent_block_root() {
|
||||
let state = harness.get_current_state();
|
||||
let slot = state.slot();
|
||||
|
||||
let (signed_block, mut state) = harness
|
||||
let ((signed_block, _), mut state) = harness
|
||||
.make_block_return_pre_state(state, slot + Slot::new(1))
|
||||
.await;
|
||||
let (mut block, signature) = signed_block.deconstruct();
|
||||
@@ -155,7 +155,7 @@ async fn invalid_block_signature() {
|
||||
|
||||
let state = harness.get_current_state();
|
||||
let slot = state.slot();
|
||||
let (signed_block, mut state) = harness
|
||||
let ((signed_block, _), mut state) = harness
|
||||
.make_block_return_pre_state(state, slot + Slot::new(1))
|
||||
.await;
|
||||
let (block, _) = signed_block.deconstruct();
|
||||
@@ -188,7 +188,7 @@ async fn invalid_randao_reveal_signature() {
|
||||
let state = harness.get_current_state();
|
||||
let slot = state.slot();
|
||||
|
||||
let (signed_block, mut state) = harness
|
||||
let ((signed_block, _), mut state) = harness
|
||||
.make_block_with_modifier(state, slot + 1, |block| {
|
||||
*block.body_mut().randao_reveal_mut() = Signature::empty();
|
||||
})
|
||||
|
||||
@@ -32,13 +32,22 @@ pub fn verify_attestation_for_block_inclusion<'ctxt, T: EthSpec>(
|
||||
attestation: data.slot,
|
||||
}
|
||||
);
|
||||
verify!(
|
||||
state.slot() <= data.slot.safe_add(T::slots_per_epoch())?,
|
||||
Invalid::IncludedTooLate {
|
||||
state: state.slot(),
|
||||
attestation: data.slot,
|
||||
match state {
|
||||
BeaconState::Base(_)
|
||||
| BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Capella(_) => {
|
||||
verify!(
|
||||
state.slot() <= data.slot.safe_add(T::slots_per_epoch())?,
|
||||
Invalid::IncludedTooLate {
|
||||
state: state.slot(),
|
||||
attestation: data.slot,
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
// [Modified in Deneb:EIP7045]
|
||||
BeaconState::Deneb(_) => {}
|
||||
}
|
||||
|
||||
verify_attestation_for_state(state, attestation, ctxt, verify_signatures, spec)
|
||||
}
|
||||
|
||||
@@ -43,9 +43,10 @@ pub fn process_epoch<T: EthSpec>(
|
||||
|
||||
match state {
|
||||
BeaconState::Base(_) => base::process_epoch(state, spec),
|
||||
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
|
||||
altair::process_epoch(state, spec)
|
||||
}
|
||||
BeaconState::Altair(_)
|
||||
| BeaconState::Merge(_)
|
||||
| BeaconState::Capella(_)
|
||||
| BeaconState::Deneb(_) => altair::process_epoch(state, spec),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ pub fn process_registry_updates<T: EthSpec>(
|
||||
|
||||
// Queue validators eligible for activation and not dequeued for activation prior to finalized epoch
|
||||
// Dequeue validators for activation up to churn limit
|
||||
let churn_limit = state.get_churn_limit(spec)? as usize;
|
||||
let churn_limit = state.get_activation_churn_limit(spec)? as usize;
|
||||
|
||||
let epoch_cache = state.epoch_cache().clone();
|
||||
let activation_queue = epoch_cache
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::upgrade::{upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella};
|
||||
use crate::upgrade::{
|
||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||
};
|
||||
use crate::{per_epoch_processing::EpochProcessingSummary, *};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use types::*;
|
||||
@@ -59,6 +61,10 @@ pub fn per_slot_processing<T: EthSpec>(
|
||||
if spec.capella_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_capella(state, spec)?;
|
||||
}
|
||||
// Deneb
|
||||
if spec.deneb_fork_epoch == Some(state.current_epoch()) {
|
||||
upgrade_to_deneb(state, spec)?;
|
||||
}
|
||||
|
||||
// Additionally build all caches so that all valid states that are advanced always have
|
||||
// committee caches built, and we don't have to worry about initialising them at higher
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
pub mod altair;
|
||||
pub mod capella;
|
||||
pub mod deneb;
|
||||
pub mod merge;
|
||||
|
||||
pub use altair::upgrade_to_altair;
|
||||
pub use capella::upgrade_to_capella;
|
||||
pub use deneb::upgrade_to_deneb;
|
||||
pub use merge::upgrade_to_bellatrix;
|
||||
|
||||
76
consensus/state_processing/src/upgrade/deneb.rs
Normal file
76
consensus/state_processing/src/upgrade/deneb.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::mem;
|
||||
use types::{BeaconState, BeaconStateDeneb, BeaconStateError as Error, ChainSpec, EthSpec, Fork};
|
||||
|
||||
/// Transform a `Capella` state into an `Deneb` state.
|
||||
pub fn upgrade_to_deneb<E: EthSpec>(
|
||||
pre_state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let epoch = pre_state.current_epoch();
|
||||
let pre = pre_state.as_capella_mut()?;
|
||||
|
||||
let previous_fork_version = pre.fork.current_version;
|
||||
|
||||
// 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::Deneb(BeaconStateDeneb {
|
||||
// Versioning
|
||||
genesis_time: pre.genesis_time,
|
||||
genesis_validators_root: pre.genesis_validators_root,
|
||||
slot: pre.slot,
|
||||
fork: Fork {
|
||||
previous_version: previous_fork_version,
|
||||
current_version: spec.deneb_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_deneb(),
|
||||
// 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