Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions beacon_node/store/src/hot_cold_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
}

/// Fetch a block from the store, ignoring which fork variant it *should* be for.
pub fn get_block_any_variant<Payload: ExecPayload<E>>(
pub fn get_block_any_variant<Payload: AbstractExecPayload<E>>(
&self,
block_root: &Hash256,
) -> Result<Option<SignedBeaconBlock<E, Payload>>, Error> {
Expand All @@ -439,7 +439,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
///
/// This is useful for e.g. ignoring the slot-indicated fork to forcefully load a block as if it
/// were for a different fork.
pub fn get_block_with<Payload: ExecPayload<E>>(
pub fn get_block_with<Payload: AbstractExecPayload<E>>(
&self,
block_root: &Hash256,
decoder: impl FnOnce(&[u8]) -> Result<SignedBeaconBlock<E, Payload>, ssz::DecodeError>,
Expand Down
39 changes: 37 additions & 2 deletions beacon_node/store/src/impls/execution_payload.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
use crate::{DBColumn, Error, StoreItem};
use ssz::{Decode, Encode};
use types::{EthSpec, ExecutionPayload};
use types::{
EthSpec, ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844,
ExecutionPayloadMerge,
};

macro_rules! impl_store_item {
($ty_name:ident) => {
impl<E: EthSpec> StoreItem for $ty_name<E> {
fn db_column() -> DBColumn {
DBColumn::ExecPayload
}

fn as_store_bytes(&self) -> Vec<u8> {
self.as_ssz_bytes()
}

fn from_store_bytes(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self::from_ssz_bytes(bytes)?)
}
}
};
}
impl_store_item!(ExecutionPayloadMerge);
impl_store_item!(ExecutionPayloadCapella);
impl_store_item!(ExecutionPayloadEip4844);

/// This fork-agnostic implementation should be only used for writing.
///
/// It is very inefficient at reading, and decoding the desired fork-specific variant is recommended
/// instead.
impl<E: EthSpec> StoreItem for ExecutionPayload<E> {
fn db_column() -> DBColumn {
DBColumn::ExecPayload
Expand All @@ -12,6 +40,13 @@ impl<E: EthSpec> StoreItem for ExecutionPayload<E> {
}

fn from_store_bytes(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self::from_ssz_bytes(bytes)?)
ExecutionPayloadEip4844::from_ssz_bytes(bytes)
.map(Self::Eip4844)
.or_else(|_| {
ExecutionPayloadCapella::from_ssz_bytes(bytes)
.map(Self::Capella)
.or_else(|_| ExecutionPayloadMerge::from_ssz_bytes(bytes).map(Self::Merge))
})
.map_err(Into::into)
}
}
80 changes: 70 additions & 10 deletions beacon_node/store/src/partial_beacon_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use types::*;
///
/// Utilises lazy-loading from separate storage for its vector fields.
#[superstruct(
variants(Base, Altair, Merge, Eip4844),
variants(Base, Altair, Merge, Capella, Eip4844),
variant_attributes(derive(Debug, PartialEq, Clone, Encode, Decode))
)]
#[derive(Debug, PartialEq, Clone, Encode)]
Expand Down Expand Up @@ -66,9 +66,9 @@ where
pub current_epoch_attestations: VariableList<PendingAttestation<T>, T::MaxPendingAttestations>,

// Participation (Altair and later)
#[superstruct(only(Altair, Merge, Eip4844))]
#[superstruct(only(Altair, Merge, Capella, Eip4844))]
pub previous_epoch_participation: VariableList<ParticipationFlags, T::ValidatorRegistryLimit>,
#[superstruct(only(Altair, Merge, Eip4844))]
#[superstruct(only(Altair, Merge, Capella, Eip4844))]
pub current_epoch_participation: VariableList<ParticipationFlags, T::ValidatorRegistryLimit>,

// Finality
Expand All @@ -78,18 +78,39 @@ where
pub finalized_checkpoint: Checkpoint,

// Inactivity
#[superstruct(only(Altair, Merge, Eip4844))]
#[superstruct(only(Altair, Merge, Capella, Eip4844))]
pub inactivity_scores: VariableList<u64, T::ValidatorRegistryLimit>,

// Light-client sync committees
#[superstruct(only(Altair, Merge, Eip4844))]
#[superstruct(only(Altair, Merge, Capella, Eip4844))]
pub current_sync_committee: Arc<SyncCommittee<T>>,
#[superstruct(only(Altair, Merge, Eip4844))]
#[superstruct(only(Altair, Merge, Capella, Eip4844))]
pub next_sync_committee: Arc<SyncCommittee<T>>,

// Execution
#[superstruct(only(Merge, Eip4844))]
pub latest_execution_payload_header: ExecutionPayloadHeader<T>,
#[superstruct(
only(Merge),
partial_getter(rename = "latest_execution_payload_header_merge")
)]
pub latest_execution_payload_header: ExecutionPayloadHeaderMerge<T>,
#[superstruct(
only(Capella),
partial_getter(rename = "latest_execution_payload_header_capella")
)]
pub latest_execution_payload_header: ExecutionPayloadHeaderCapella<T>,
#[superstruct(
only(Eip4844),
partial_getter(rename = "latest_execution_payload_header_eip4844")
)]
pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844<T>,

// Withdrawals
#[superstruct(only(Capella, Eip4844))]
pub withdrawal_queue: VariableList<Withdrawal, T::WithdrawalQueueLimit>,
#[superstruct(only(Capella, Eip4844))]
pub next_withdrawal_index: u64,
#[superstruct(only(Capella, Eip4844))]
pub next_partial_withdrawal_validator_index: u64,
}

/// Implement the conversion function from BeaconState -> PartialBeaconState.
Expand Down Expand Up @@ -178,6 +199,23 @@ impl<T: EthSpec> PartialBeaconState<T> {
latest_execution_payload_header
]
),
BeaconState::Capella(s) => impl_from_state_forgetful!(
s,
outer,
Capella,
PartialBeaconStateCapella,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index,
next_partial_withdrawal_validator_index
]
),
BeaconState::Eip4844(s) => impl_from_state_forgetful!(
s,
outer,
Expand All @@ -189,7 +227,10 @@ impl<T: EthSpec> PartialBeaconState<T> {
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index,
next_partial_withdrawal_validator_index
]
),
}
Expand Down Expand Up @@ -379,6 +420,22 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
latest_execution_payload_header
]
),
PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!(
inner,
Capella,
BeaconStateCapella,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index,
next_partial_withdrawal_validator_index
]
),
PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!(
inner,
Eip4844,
Expand All @@ -389,7 +446,10 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index,
next_partial_withdrawal_validator_index
]
),
};
Expand Down
12 changes: 8 additions & 4 deletions consensus/fork_choice/src/fork_choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ use std::collections::BTreeSet;
use std::marker::PhantomData;
use std::time::Duration;
use types::{
consts::merge::INTERVALS_PER_SLOT, AttestationShufflingId, AttesterSlashing, BeaconBlockRef,
BeaconState, BeaconStateError, ChainSpec, Checkpoint, Epoch, EthSpec, ExecPayload,
ExecutionBlockHash, Hash256, IndexedAttestation, RelativeEpoch, SignedBeaconBlock, Slot,
consts::merge::INTERVALS_PER_SLOT, AbstractExecPayload, AttestationShufflingId,
AttesterSlashing, BeaconBlockRef, BeaconState, BeaconStateError, ChainSpec, Checkpoint, Epoch,
EthSpec, ExecPayload, ExecutionBlockHash, Hash256, IndexedAttestation, RelativeEpoch,
SignedBeaconBlock, Slot,
};

#[derive(Debug)]
Expand Down Expand Up @@ -665,7 +666,7 @@ where
/// The supplied block **must** pass the `state_transition` function as it will not be run
/// here.
#[allow(clippy::too_many_arguments)]
pub fn on_block<Payload: ExecPayload<E>>(
pub fn on_block<Payload: AbstractExecPayload<E>>(
&mut self,
system_time_current_slot: Slot,
block: BeaconBlockRef<E, Payload>,
Expand Down Expand Up @@ -777,7 +778,10 @@ where
(parent_justified, parent_finalized)
} else {
let justification_and_finalization_state = match block {
// FIXME: verify this is correct for Capella/Eip4844 because
// epoch processing changes in Capella..
BeaconBlockRef::Eip4844(_)
| BeaconBlockRef::Capella(_)
| BeaconBlockRef::Merge(_)
| BeaconBlockRef::Altair(_) => {
let participation_cache =
Expand Down
4 changes: 2 additions & 2 deletions consensus/fork_choice/src/fork_choice_store.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeSet;
use std::fmt::Debug;
use types::{BeaconBlockRef, BeaconState, Checkpoint, EthSpec, ExecPayload, Hash256, Slot};
use types::{AbstractExecPayload, BeaconBlockRef, BeaconState, Checkpoint, EthSpec, Hash256, Slot};

/// Approximates the `Store` in "Ethereum 2.0 Phase 0 -- Beacon Chain Fork Choice":
///
Expand Down Expand Up @@ -33,7 +33,7 @@ pub trait ForkChoiceStore<T: EthSpec>: Sized {

/// Called whenever `ForkChoice::on_block` has verified a block, but not yet added it to fork
/// choice. Allows the implementer to performing caching or other housekeeping duties.
fn on_verified_block<Payload: ExecPayload<T>>(
fn on_verified_block<Payload: AbstractExecPayload<T>>(
&mut self,
block: BeaconBlockRef<T, Payload>,
block_root: Hash256,
Expand Down
11 changes: 6 additions & 5 deletions consensus/state_processing/src/common/slash_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,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::Eip4844(_) => {
whistleblower_reward
.safe_mul(PROPOSER_WEIGHT)?
.safe_div(WEIGHT_DENOMINATOR)?
}
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Eip4844(_) => whistleblower_reward
.safe_mul(PROPOSER_WEIGHT)?
.safe_div(WEIGHT_DENOMINATOR)?,
};

// Ensure the whistleblower index is in the validator registry.
Expand Down
44 changes: 41 additions & 3 deletions consensus/state_processing/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
use crate::upgrade::{
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844,
};
use safe_arith::{ArithError, SafeArith};
use tree_hash::TreeHash;
use types::DEPOSIT_TREE_DEPTH;
Expand Down Expand Up @@ -61,15 +63,51 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
.bellatrix_fork_epoch
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
{
// this will set state.latest_execution_payload_header = ExecutionPayloadHeaderMerge::default()
upgrade_to_bellatrix(&mut state, spec)?;

// Remove intermediate Altair fork from `state.fork`.
state.fork_mut().previous_version = spec.bellatrix_fork_version;

// Override latest execution payload header.
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing
*state.latest_execution_payload_header_mut()? =
execution_payload_header.unwrap_or_default();
if let Some(ExecutionPayloadHeader::Merge(ref header)) = execution_payload_header {
*state.latest_execution_payload_header_merge_mut()? = header.clone();
}
}

// Upgrade to capella if configured from genesis
if spec
.capella_fork_epoch
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
{
upgrade_to_capella(&mut state, spec)?;

// Remove intermediate Bellatrix fork from `state.fork`.
state.fork_mut().previous_version = spec.capella_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::Capella(ref header)) = execution_payload_header {
*state.latest_execution_payload_header_capella_mut()? = header.clone();
}
}

// Upgrade to eip4844 if configured from genesis
if spec
.eip4844_fork_epoch
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
{
upgrade_to_eip4844(&mut state, spec)?;

// Remove intermediate Capella fork from `state.fork`.
state.fork_mut().previous_version = spec.eip4844_fork_version;

// Override latest execution payload header.
// See https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#testing
if let Some(ExecutionPayloadHeader::Eip4844(header)) = execution_payload_header {
*state.latest_execution_payload_header_eip4844_mut()? = header;
}
}

// Now that we have our validators, initialize the caches (including the committees)
Expand Down
Loading