Add bal support, remove epbs stuff

This commit is contained in:
Pawan Dhananjay
2026-01-16 12:40:57 -08:00
parent d099ad56fb
commit 47094d592c
15 changed files with 336 additions and 208 deletions

View File

@@ -456,6 +456,12 @@ pub fn process_execution_payload<E: EthSpec, Payload: AbstractExecPayload<E>>(
_ => return Err(BlockProcessingError::IncorrectStateType),
}
}
ExecutionPayloadHeaderRefMut::Gloas(header_mut) => {
match payload.to_execution_payload_header() {
ExecutionPayloadHeader::Gloas(header) => *header_mut = header,
_ => return Err(BlockProcessingError::IncorrectStateType),
}
}
}
Ok(())

View File

@@ -1,11 +1,5 @@
use bls::Hash256;
use milhouse::{List, Vector};
use ssz_types::BitVector;
use std::mem;
use types::{
BeaconState, BeaconStateError as Error, BeaconStateGloas, BuilderPendingPayment, ChainSpec,
EthSpec, ExecutionPayloadBid, Fork,
};
use types::{BeaconState, BeaconStateError as Error, BeaconStateGloas, ChainSpec, EthSpec, Fork};
/// Transform a `Fulu` state into a `Gloas` state.
pub fn upgrade_to_gloas<E: EthSpec>(
@@ -69,11 +63,8 @@ pub fn upgrade_state_to_gloas<E: EthSpec>(
// Sync committees
current_sync_committee: pre.current_sync_committee.clone(),
next_sync_committee: pre.next_sync_committee.clone(),
// Execution Bid
latest_execution_payload_bid: ExecutionPayloadBid {
block_hash: pre.latest_execution_payload_header.block_hash,
..Default::default()
},
// Execution - upgrade header from Fulu to Gloas
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_gloas(),
// Capella
next_withdrawal_index: pre.next_withdrawal_index,
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
@@ -88,15 +79,6 @@ pub fn upgrade_state_to_gloas<E: EthSpec>(
pending_deposits: pre.pending_deposits.clone(),
pending_partial_withdrawals: pre.pending_partial_withdrawals.clone(),
pending_consolidations: pre.pending_consolidations.clone(),
// Gloas
execution_payload_availability: BitVector::default(), // All bits set to false initially
builder_pending_payments: Vector::new(vec![
BuilderPendingPayment::default();
E::builder_pending_payments_limit()
])?,
builder_pending_withdrawals: List::default(), // Empty list initially,
latest_block_hash: pre.latest_execution_payload_header.block_hash,
latest_withdrawals_root: Hash256::default(),
// Caches
total_active_balance: pre.total_active_balance,
progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache),

View File

@@ -15,7 +15,6 @@ use tree_hash_derive::TreeHash;
use typenum::Unsigned;
use crate::{
SignedExecutionPayloadBid,
attestation::{AttestationBase, AttestationData, IndexedAttestationBase},
block::{
BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyBellatrix,
@@ -695,41 +694,15 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockGloa
deposits: VariableList::empty(),
voluntary_exits: VariableList::empty(),
sync_aggregate: SyncAggregate::empty(),
execution_payload: Payload::Gloas::default(),
bls_to_execution_changes: VariableList::empty(),
signed_execution_payload_bid: SignedExecutionPayloadBid::empty(),
payload_attestations: VariableList::empty(),
_phantom: PhantomData,
blob_kzg_commitments: VariableList::empty(),
execution_requests: ExecutionRequests::default(),
},
}
}
}
// TODO(EIP-7732) Mark's branch had the following implementation but not sure if it's needed so will just add header below for reference
// impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockEIP7732<E, Payload> {
// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas
impl<E: EthSpec> From<BeaconBlockGloas<E, BlindedPayload<E>>>
for BeaconBlockGloas<E, FullPayload<E>>
{
fn from(block: BeaconBlockGloas<E, BlindedPayload<E>>) -> Self {
let BeaconBlockGloas {
slot,
proposer_index,
parent_root,
state_root,
body,
} = block;
BeaconBlockGloas {
slot,
proposer_index,
parent_root,
state_root,
body: body.into(),
}
}
}
// We can convert pre-Bellatrix blocks without payloads into blocks "with" payloads.
impl<E: EthSpec> From<BeaconBlockBase<E, BlindedPayload<E>>>
for BeaconBlockBase<E, FullPayload<E>>

View File

@@ -14,19 +14,17 @@ use tree_hash::{BYTES_PER_CHUNK, TreeHash};
use tree_hash_derive::TreeHash;
use crate::{
SignedExecutionPayloadBid,
attestation::{
AttestationBase, AttestationElectra, AttestationRef, AttestationRefMut, PayloadAttestation,
},
attestation::{AttestationBase, AttestationElectra, AttestationRef, AttestationRefMut},
core::{EthSpec, Graffiti, Hash256},
deposit::Deposit,
execution::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, Eth1Data, ExecutionPayload,
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionRequests,
FullPayload, FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb,
FullPayloadElectra, FullPayloadFulu, SignedBlsToExecutionChange,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
Eth1Data, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
ExecutionPayloadGloas, ExecutionRequests, FullPayload, FullPayloadBellatrix,
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu,
FullPayloadGloas, SignedBlsToExecutionChange,
},
exit::SignedVoluntaryExit,
fork::{ForkName, map_fork_name},
@@ -159,18 +157,17 @@ pub struct BeaconBlockBody<E: EthSpec, Payload: AbstractExecPayload<E> = FullPay
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
#[serde(flatten)]
pub execution_payload: Payload::Fulu,
#[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))]
#[serde(flatten)]
pub execution_payload: Payload::Gloas,
#[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas))]
pub bls_to_execution_changes:
VariableList<SignedBlsToExecutionChange, E::MaxBlsToExecutionChanges>,
#[superstruct(only(Deneb, Electra, Fulu))]
#[superstruct(only(Deneb, Electra, Fulu, Gloas))]
pub blob_kzg_commitments: KzgCommitments<E>,
#[superstruct(only(Electra, Fulu))]
#[superstruct(only(Electra, Fulu, Gloas))]
pub execution_requests: ExecutionRequests<E>,
#[superstruct(only(Gloas))]
pub signed_execution_payload_bid: SignedExecutionPayloadBid,
#[superstruct(only(Gloas))]
pub payload_attestations: VariableList<PayloadAttestation<E>, E::MaxPayloadAttestations>,
#[superstruct(only(Base, Altair, Gloas))]
#[superstruct(only(Base, Altair))]
#[metastruct(exclude_from(fields))]
#[ssz(skip_serializing, skip_deserializing)]
#[tree_hash(skip_hashing)]
@@ -199,7 +196,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
Self::Deneb(body) => Ok(Payload::Ref::from(&body.execution_payload)),
Self::Electra(body) => Ok(Payload::Ref::from(&body.execution_payload)),
Self::Fulu(body) => Ok(Payload::Ref::from(&body.execution_payload)),
Self::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant),
Self::Gloas(body) => Ok(Payload::Ref::from(&body.execution_payload)),
}
}
@@ -257,19 +254,16 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
/// Produces the proof of inclusion for a `KzgCommitment` in `self.blob_kzg_commitments`
/// at `index` using an existing proof for the `blob_kzg_commitments` field.
/// TODO(EIP7732) Investigate calling functions since this will no longer work for glas since no block_kzg_commitments in the body anymore
pub fn complete_kzg_commitment_merkle_proof(
&self,
index: usize,
kzg_commitments_proof: &[Hash256],
) -> Result<FixedVector<Hash256, E::KzgCommitmentInclusionProofDepth>, BeaconStateError> {
match self {
Self::Base(_)
| Self::Altair(_)
| Self::Bellatrix(_)
| Self::Capella(_)
| Self::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant),
Self::Deneb(_) | Self::Electra(_) | Self::Fulu(_) => {
Self::Base(_) | Self::Altair(_) | Self::Bellatrix(_) | Self::Capella(_) => {
Err(BeaconStateError::IncorrectStateVariant)
}
Self::Deneb(_) | Self::Electra(_) | Self::Fulu(_) | Self::Gloas(_) => {
// We compute the branches by generating 2 merkle trees:
// 1. Merkle tree for the `blob_kzg_commitments` List object
// 2. Merkle tree for the `BeaconBlockBody` container
@@ -547,46 +541,6 @@ impl<E: EthSpec> From<BeaconBlockBodyAltair<E, BlindedPayload<E>>>
}
}
// Post-Fulu block bodies without payloads can be converted into block bodies with payloads
// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas
impl<E: EthSpec> From<BeaconBlockBodyGloas<E, BlindedPayload<E>>>
for BeaconBlockBodyGloas<E, FullPayload<E>>
{
fn from(body: BeaconBlockBodyGloas<E, BlindedPayload<E>>) -> Self {
let BeaconBlockBodyGloas {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
bls_to_execution_changes,
signed_execution_payload_bid,
payload_attestations,
_phantom,
} = body;
BeaconBlockBodyGloas {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
bls_to_execution_changes,
signed_execution_payload_bid,
payload_attestations,
_phantom: PhantomData,
}
}
}
// Likewise bodies with payloads can be transformed into bodies without.
impl<E: EthSpec> From<BeaconBlockBodyBase<E, FullPayload<E>>>
for (
@@ -897,10 +851,10 @@ impl<E: EthSpec> From<BeaconBlockBodyGloas<E, FullPayload<E>>>
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadGloas { execution_payload },
bls_to_execution_changes,
signed_execution_payload_bid,
payload_attestations,
_phantom,
blob_kzg_commitments,
execution_requests,
} = body;
(
@@ -914,12 +868,14 @@ impl<E: EthSpec> From<BeaconBlockBodyGloas<E, FullPayload<E>>>
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadGloas {
execution_payload_header: From::from(&execution_payload),
},
bls_to_execution_changes,
signed_execution_payload_bid,
payload_attestations,
_phantom: PhantomData,
blob_kzg_commitments: blob_kzg_commitments.clone(),
execution_requests,
},
None,
Some(execution_payload),
)
}
}

View File

@@ -17,17 +17,19 @@ use crate::{
block::{
BLOB_KZG_COMMITMENTS_INDEX, BeaconBlock, BeaconBlockAltair, BeaconBlockBase,
BeaconBlockBellatrix, BeaconBlockBodyBellatrix, BeaconBlockBodyCapella,
BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockCapella,
BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, BeaconBlockHeader,
BeaconBlockRef, BeaconBlockRefMut, SignedBeaconBlockHeader,
BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas,
BeaconBlockCapella, BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu,
BeaconBlockGloas, BeaconBlockHeader, BeaconBlockRef, BeaconBlockRefMut,
SignedBeaconBlockHeader,
},
core::{ChainSpec, Domain, Epoch, EthSpec, Hash256, SignedRoot, SigningData, Slot},
execution::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, ExecutionPayload,
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload, FullPayloadBellatrix,
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
ExecutionPayloadGloas, FullPayload, FullPayloadBellatrix, FullPayloadCapella,
FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu, FullPayloadGloas,
},
fork::{Fork, ForkName, ForkVersionDecode, InconsistentFork, map_fork_name},
kzg_ext::format_kzg_commitments,
@@ -673,15 +675,59 @@ impl<E: EthSpec> SignedBeaconBlockFulu<E, BlindedPayload<E>> {
}
}
// We can convert gloas blocks without payloads into blocks "with" payloads.
// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas
impl<E: EthSpec> From<SignedBeaconBlockGloas<E, BlindedPayload<E>>>
for SignedBeaconBlockGloas<E, FullPayload<E>>
{
fn from(signed_block: SignedBeaconBlockGloas<E, BlindedPayload<E>>) -> Self {
let SignedBeaconBlockGloas { message, signature } = signed_block;
impl<E: EthSpec> SignedBeaconBlockGloas<E, BlindedPayload<E>> {
pub fn into_full_block(
self,
execution_payload: ExecutionPayloadGloas<E>,
) -> SignedBeaconBlockGloas<E, FullPayload<E>> {
let SignedBeaconBlockGloas {
message:
BeaconBlockGloas {
slot,
proposer_index,
parent_root,
state_root,
body:
BeaconBlockBodyGloas {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadGloas { .. },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
} = self;
SignedBeaconBlockGloas {
message: message.into(),
message: BeaconBlockGloas {
slot,
proposer_index,
parent_root,
state_root,
body: BeaconBlockBodyGloas {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadGloas { execution_payload },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
}
}
@@ -710,7 +756,9 @@ impl<E: EthSpec> SignedBeaconBlock<E, BlindedPayload<E>> {
(SignedBeaconBlock::Fulu(block), Some(ExecutionPayload::Fulu(payload))) => {
SignedBeaconBlock::Fulu(block.into_full_block(payload))
}
(SignedBeaconBlock::Gloas(block), _) => SignedBeaconBlock::Gloas(block.into()),
(SignedBeaconBlock::Gloas(block), Some(ExecutionPayload::Gloas(payload))) => {
SignedBeaconBlock::Gloas(block.into_full_block(payload))
}
// avoid wildcard matching forks so that compiler will
// direct us here when a new fork has been added
(SignedBeaconBlock::Bellatrix(_), _) => return None,
@@ -718,7 +766,7 @@ impl<E: EthSpec> SignedBeaconBlock<E, BlindedPayload<E>> {
(SignedBeaconBlock::Deneb(_), _) => return None,
(SignedBeaconBlock::Electra(_), _) => return None,
(SignedBeaconBlock::Fulu(_), _) => return None,
// TODO(EIP-7732) Determine if need a match arm for gloas here
(SignedBeaconBlock::Gloas(_), _) => return None,
};
Some(full_block)
}

View File

@@ -3,7 +3,6 @@
// - ExecutionPayloadHeader
// - FullPayload
// - BlindedPayload
// TODO(EIP-7732): get rid of this whole file and panics once the engine_api is refactored for ePBS
#[macro_export]
macro_rules! map_execution_payload_into_full_payload {
@@ -29,7 +28,10 @@ macro_rules! map_execution_payload_into_full_payload {
let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f;
f(inner, FullPayload::Fulu)
}
ExecutionPayload::Gloas(_) => panic!("FullPayload::Gloas does not exist!"),
ExecutionPayload::Gloas(inner) => {
let f: fn(ExecutionPayloadGloas<_>, fn(_) -> _) -> _ = $f;
f(inner, FullPayload::Gloas)
}
}
};
}
@@ -58,7 +60,10 @@ macro_rules! map_execution_payload_into_blinded_payload {
let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f;
f(inner, BlindedPayload::Fulu)
}
ExecutionPayload::Gloas(_) => panic!("BlindedPayload::Gloas does not exist!"),
ExecutionPayload::Gloas(inner) => {
let f: fn(ExecutionPayloadGloas<_>, fn(_) -> _) -> _ = $f;
f(inner, BlindedPayload::Gloas)
}
}
};
}
@@ -102,7 +107,13 @@ macro_rules! map_execution_payload_ref_into_execution_payload_header {
) -> _ = $f;
f(inner, ExecutionPayloadHeader::Fulu)
}
ExecutionPayloadRef::Gloas(_) => panic!("ExecutionPayloadHeader::Gloas does not exist!"),
ExecutionPayloadRef::Gloas(inner) => {
let f: fn(
&$lifetime ExecutionPayloadGloas<_>,
fn(_) -> _,
) -> _ = $f;
f(inner, ExecutionPayloadHeader::Gloas)
}
}
}
}

View File

@@ -109,6 +109,10 @@ pub struct ExecutionPayload<E: EthSpec> {
#[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
pub excess_blob_gas: u64,
/// EIP-7928: Block access list
#[superstruct(only(Gloas))]
#[serde(with = "ssz_types::serde_utils::hex_var_list")]
pub block_access_list: VariableList<u8, E::MaxBytesPerTransaction>,
}
impl<'a, E: EthSpec> ExecutionPayloadRef<'a, E> {

View File

@@ -14,7 +14,8 @@ use crate::{
core::{Address, EthSpec, ExecutionBlockHash, Hash256, Uint256},
execution::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadRef, Transactions,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadRef,
Transactions,
},
fork::ForkName,
map_execution_payload_ref_into_execution_payload_header,
@@ -23,7 +24,7 @@ use crate::{
};
#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
variant_attributes(
derive(
Default,
@@ -105,14 +106,17 @@ pub struct ExecutionPayloadHeader<E: EthSpec> {
pub block_hash: ExecutionBlockHash,
#[superstruct(getter(copy))]
pub transactions_root: Hash256,
#[superstruct(only(Capella, Deneb, Electra, Fulu), partial_getter(copy))]
#[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
pub withdrawals_root: Hash256,
#[superstruct(only(Deneb, Electra, Fulu), partial_getter(copy))]
#[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
pub blob_gas_used: u64,
#[superstruct(only(Deneb, Electra, Fulu), partial_getter(copy))]
#[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
pub excess_blob_gas: u64,
/// EIP-7928: Block access list root
#[superstruct(only(Gloas), partial_getter(copy))]
pub block_access_list_root: Hash256,
}
impl<E: EthSpec> ExecutionPayloadHeader<E> {
@@ -136,19 +140,14 @@ impl<E: EthSpec> ExecutionPayloadHeader<E> {
ExecutionPayloadHeaderElectra::from_ssz_bytes(bytes).map(Self::Electra)
}
ForkName::Fulu => ExecutionPayloadHeaderFulu::from_ssz_bytes(bytes).map(Self::Fulu),
ForkName::Gloas => Err(ssz::DecodeError::BytesInvalid(format!(
"unsupported fork for ExecutionPayloadHeader: {fork_name}",
))),
ForkName::Gloas => ExecutionPayloadHeaderGloas::from_ssz_bytes(bytes).map(Self::Gloas),
}
}
#[allow(clippy::arithmetic_side_effects)]
pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize {
// TODO(newfork): Add a new case here if there are new variable fields
if fork_name.gloas_enabled() {
// TODO(EIP7732): check this
0
} else if fork_name.bellatrix_enabled() {
if fork_name.bellatrix_enabled() {
// Max size of variable length `extra_data` field
E::max_extra_data_bytes() * <u8 as Encode>::ssz_fixed_len()
} else {
@@ -163,6 +162,7 @@ impl<E: EthSpec> ExecutionPayloadHeader<E> {
ExecutionPayloadHeader::Deneb(_) => ForkName::Deneb,
ExecutionPayloadHeader::Electra(_) => ForkName::Electra,
ExecutionPayloadHeader::Fulu(_) => ForkName::Fulu,
ExecutionPayloadHeader::Gloas(_) => ForkName::Gloas,
}
}
}
@@ -270,6 +270,31 @@ impl<E: EthSpec> ExecutionPayloadHeaderElectra<E> {
}
}
impl<E: EthSpec> ExecutionPayloadHeaderFulu<E> {
pub fn upgrade_to_gloas(&self) -> ExecutionPayloadHeaderGloas<E> {
ExecutionPayloadHeaderGloas {
parent_hash: self.parent_hash,
fee_recipient: self.fee_recipient,
state_root: self.state_root,
receipts_root: self.receipts_root,
logs_bloom: self.logs_bloom.clone(),
prev_randao: self.prev_randao,
block_number: self.block_number,
gas_limit: self.gas_limit,
gas_used: self.gas_used,
timestamp: self.timestamp,
extra_data: self.extra_data.clone(),
base_fee_per_gas: self.base_fee_per_gas,
block_hash: self.block_hash,
transactions_root: self.transactions_root,
withdrawals_root: self.withdrawals_root,
blob_gas_used: self.blob_gas_used,
excess_blob_gas: self.excess_blob_gas,
block_access_list_root: Hash256::zero(),
}
}
}
impl<'a, E: EthSpec> From<&'a ExecutionPayloadBellatrix<E>> for ExecutionPayloadHeaderBellatrix<E> {
fn from(payload: &'a ExecutionPayloadBellatrix<E>) -> Self {
Self {
@@ -385,6 +410,31 @@ impl<'a, E: EthSpec> From<&'a ExecutionPayloadFulu<E>> for ExecutionPayloadHeade
}
}
impl<'a, E: EthSpec> From<&'a ExecutionPayloadGloas<E>> for ExecutionPayloadHeaderGloas<E> {
fn from(payload: &'a ExecutionPayloadGloas<E>) -> Self {
Self {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
receipts_root: payload.receipts_root,
logs_bloom: payload.logs_bloom.clone(),
prev_randao: payload.prev_randao,
block_number: payload.block_number,
gas_limit: payload.gas_limit,
gas_used: payload.gas_used,
timestamp: payload.timestamp,
extra_data: payload.extra_data.clone(),
base_fee_per_gas: payload.base_fee_per_gas,
block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(),
withdrawals_root: payload.withdrawals.tree_hash_root(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
block_access_list_root: payload.block_access_list.tree_hash_root(),
}
}
}
// These impls are required to work around an inelegance in `to_execution_payload_header`.
// They only clone headers so they should be relatively cheap.
impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderBellatrix<E> {
@@ -417,6 +467,12 @@ impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderFulu<E> {
}
}
impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderGloas<E> {
fn from(payload: &'a Self) -> Self {
payload.clone()
}
}
impl<'a, E: EthSpec> From<ExecutionPayloadRef<'a, E>> for ExecutionPayloadHeader<E> {
fn from(payload: ExecutionPayloadRef<'a, E>) -> Self {
map_execution_payload_ref_into_execution_payload_header!(
@@ -478,6 +534,9 @@ impl<E: EthSpec> ExecutionPayloadHeaderRefMut<'_, E> {
ExecutionPayloadHeaderRefMut::Fulu(mut_ref) => {
*mut_ref = header.try_into()?;
}
ExecutionPayloadHeaderRefMut::Gloas(mut_ref) => {
*mut_ref = header.try_into()?;
}
}
Ok(())
}
@@ -505,6 +564,16 @@ impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for ExecutionPayloadHeaderFu
}
}
impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for ExecutionPayloadHeaderGloas<E> {
type Error = BeaconStateError;
fn try_from(header: ExecutionPayloadHeader<E>) -> Result<Self, Self::Error> {
match header {
ExecutionPayloadHeader::Gloas(execution_payload_header) => Ok(execution_payload_header),
_ => Err(BeaconStateError::IncorrectStateVariant),
}
}
}
impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for ExecutionPayloadHeader<E> {
fn context_deserialize<D>(deserializer: D, context: ForkName) -> Result<Self, D::Error>
where
@@ -532,8 +601,11 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for ExecutionPayloadHead
ForkName::Fulu => {
Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?)
}
ForkName::Gloas => {
Self::Gloas(Deserialize::deserialize(deserializer).map_err(convert_err)?)
}
ForkName::Base | ForkName::Altair | ForkName::Gloas => {
ForkName::Base | ForkName::Altair => {
return Err(serde::de::Error::custom(format!(
"ExecutionPayloadHeader failed to deserialize: unsupported fork '{}'",
context

View File

@@ -26,17 +26,17 @@ pub use execution_payload_envelope::ExecutionPayloadEnvelope;
pub use execution_payload_header::{
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
};
pub use execution_requests::{
ConsolidationRequests, DepositRequests, ExecutionRequests, RequestType, WithdrawalRequests,
};
pub use payload::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadRef,
BlockProductionVersion, BlockType, ExecPayload, FullPayload, FullPayloadBellatrix,
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu, FullPayloadRef,
OwnedExecPayload,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
BlindedPayloadRef, BlockProductionVersion, BlockType, ExecPayload, FullPayload,
FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra,
FullPayloadFulu, FullPayloadGloas, FullPayloadRef, OwnedExecPayload,
};
pub use signed_bls_to_execution_change::SignedBlsToExecutionChange;
pub use signed_execution_payload_bid::SignedExecutionPayloadBid;

View File

@@ -15,9 +15,9 @@ use crate::{
execution::{
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
ExecutionPayloadRef, Transactions,
ExecutionPayloadGloas, ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix,
ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra,
ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderGloas, ExecutionPayloadRef, Transactions,
},
fork::ForkName,
map_execution_payload_into_blinded_payload, map_execution_payload_into_full_payload,
@@ -119,6 +119,7 @@ pub trait AbstractExecPayload<E: EthSpec>:
+ TryInto<Self::Deneb>
+ TryInto<Self::Electra>
+ TryInto<Self::Fulu>
+ TryInto<Self::Gloas>
+ Sync
{
type Ref<'a>: ExecPayload<E>
@@ -127,7 +128,8 @@ pub trait AbstractExecPayload<E: EthSpec>:
+ From<&'a Self::Capella>
+ From<&'a Self::Deneb>
+ From<&'a Self::Electra>
+ From<&'a Self::Fulu>;
+ From<&'a Self::Fulu>
+ From<&'a Self::Gloas>;
type Bellatrix: OwnedExecPayload<E>
+ Into<Self>
@@ -154,10 +156,15 @@ pub trait AbstractExecPayload<E: EthSpec>:
+ for<'a> From<Cow<'a, ExecutionPayloadFulu<E>>>
+ TryFrom<ExecutionPayloadHeaderFulu<E>>
+ Sync;
type Gloas: OwnedExecPayload<E>
+ Into<Self>
+ for<'a> From<Cow<'a, ExecutionPayloadGloas<E>>>
+ TryFrom<ExecutionPayloadHeaderGloas<E>>
+ Sync;
}
#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
variant_attributes(
derive(
Debug,
@@ -218,6 +225,8 @@ pub struct FullPayload<E: EthSpec> {
pub execution_payload: ExecutionPayloadElectra<E>,
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
pub execution_payload: ExecutionPayloadFulu<E>,
#[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))]
pub execution_payload: ExecutionPayloadGloas<E>,
}
impl<E: EthSpec> From<FullPayload<E>> for ExecutionPayload<E> {
@@ -329,6 +338,7 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
FullPayload::Deneb(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
FullPayload::Electra(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
FullPayload::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
FullPayload::Gloas(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
}
}
@@ -340,6 +350,7 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
FullPayload::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayload::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayload::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayload::Gloas(inner) => Ok(inner.execution_payload.blob_gas_used),
}
}
@@ -371,7 +382,7 @@ impl<E: EthSpec> FullPayload<E> {
ForkName::Deneb => Ok(FullPayloadDeneb::default().into()),
ForkName::Electra => Ok(FullPayloadElectra::default().into()),
ForkName::Fulu => Ok(FullPayloadFulu::default().into()),
ForkName::Gloas => Err(BeaconStateError::IncorrectStateVariant),
ForkName::Gloas => Ok(FullPayloadGloas::default().into()),
}
}
}
@@ -472,6 +483,9 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
Ok(inner.execution_payload.withdrawals.tree_hash_root())
}
FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
FullPayloadRef::Gloas(inner) => {
Ok(inner.execution_payload.withdrawals.tree_hash_root())
}
}
}
@@ -483,6 +497,7 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
FullPayloadRef::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayloadRef::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used),
FullPayloadRef::Gloas(inner) => Ok(inner.execution_payload.blob_gas_used),
}
}
@@ -506,6 +521,7 @@ impl<E: EthSpec> AbstractExecPayload<E> for FullPayload<E> {
type Deneb = FullPayloadDeneb<E>;
type Electra = FullPayloadElectra<E>;
type Fulu = FullPayloadFulu<E>;
type Gloas = FullPayloadGloas<E>;
}
impl<E: EthSpec> From<ExecutionPayload<E>> for FullPayload<E> {
@@ -524,7 +540,7 @@ impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for FullPayload<E> {
}
#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
variant_attributes(
derive(
Debug,
@@ -584,6 +600,8 @@ pub struct BlindedPayload<E: EthSpec> {
pub execution_payload_header: ExecutionPayloadHeaderElectra<E>,
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
pub execution_payload_header: ExecutionPayloadHeaderFulu<E>,
#[superstruct(only(Gloas), partial_getter(rename = "execution_payload_gloas"))]
pub execution_payload_header: ExecutionPayloadHeaderGloas<E>,
}
impl<'a, E: EthSpec> From<BlindedPayloadRef<'a, E>> for BlindedPayload<E> {
@@ -673,6 +691,7 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.withdrawals_root),
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.withdrawals_root),
BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root),
BlindedPayload::Gloas(inner) => Ok(inner.execution_payload_header.withdrawals_root),
}
}
@@ -684,6 +703,7 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayload::Gloas(inner) => Ok(inner.execution_payload_header.blob_gas_used),
}
}
@@ -783,6 +803,7 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
Ok(inner.execution_payload_header.withdrawals_root)
}
BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root),
BlindedPayloadRef::Gloas(inner) => Ok(inner.execution_payload_header.withdrawals_root),
}
}
@@ -794,6 +815,7 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
BlindedPayloadRef::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayloadRef::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used),
BlindedPayloadRef::Gloas(inner) => Ok(inner.execution_payload_header.blob_gas_used),
}
}
@@ -1105,6 +1127,13 @@ impl_exec_payload_for_fork!(
ExecutionPayloadFulu,
Fulu
);
impl_exec_payload_for_fork!(
BlindedPayloadGloas,
FullPayloadGloas,
ExecutionPayloadHeaderGloas,
ExecutionPayloadGloas,
Gloas
);
impl<E: EthSpec> AbstractExecPayload<E> for BlindedPayload<E> {
type Ref<'a> = BlindedPayloadRef<'a, E>;
@@ -1113,6 +1142,7 @@ impl<E: EthSpec> AbstractExecPayload<E> for BlindedPayload<E> {
type Deneb = BlindedPayloadDeneb<E>;
type Electra = BlindedPayloadElectra<E>;
type Fulu = BlindedPayloadFulu<E>;
type Gloas = BlindedPayloadGloas<E>;
}
impl<E: EthSpec> From<ExecutionPayload<E>> for BlindedPayload<E> {
@@ -1154,6 +1184,11 @@ impl<E: EthSpec> From<ExecutionPayloadHeader<E>> for BlindedPayload<E> {
execution_payload_header,
})
}
ExecutionPayloadHeader::Gloas(execution_payload_header) => {
Self::Gloas(BlindedPayloadGloas {
execution_payload_header,
})
}
}
}
}
@@ -1176,6 +1211,9 @@ impl<E: EthSpec> From<BlindedPayload<E>> for ExecutionPayloadHeader<E> {
BlindedPayload::Fulu(blinded_payload) => {
ExecutionPayloadHeader::Fulu(blinded_payload.execution_payload_header)
}
BlindedPayload::Gloas(blinded_payload) => {
ExecutionPayloadHeader::Gloas(blinded_payload.execution_payload_header)
}
}
}
}

View File

@@ -23,7 +23,6 @@ use tree_hash_derive::TreeHash;
use typenum::Unsigned;
use crate::{
BuilderPendingPayment, BuilderPendingWithdrawal, ExecutionBlockHash, ExecutionPayloadBid,
attestation::{
AttestationDuty, BeaconCommittee, Checkpoint, CommitteeIndex, ParticipationFlags,
PendingAttestation,
@@ -35,7 +34,7 @@ use crate::{
execution::{
Eth1Data, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
},
fork::{Fork, ForkName, ForkVersionDecode, InconsistentFork, map_fork_name},
light_client::consts::{
@@ -543,9 +542,12 @@ where
)]
#[metastruct(exclude_from(tree_lists))]
pub latest_execution_payload_header: ExecutionPayloadHeaderFulu<E>,
#[superstruct(only(Gloas))]
#[superstruct(
only(Gloas),
partial_getter(rename = "latest_execution_payload_header_gloas")
)]
#[metastruct(exclude_from(tree_lists))]
pub latest_execution_payload_bid: ExecutionPayloadBid,
pub latest_execution_payload_header: ExecutionPayloadHeaderGloas<E>,
#[superstruct(only(Capella, Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
#[metastruct(exclude_from(tree_lists))]
@@ -603,33 +605,6 @@ where
#[serde(with = "ssz_types::serde_utils::quoted_u64_fixed_vec")]
pub proposer_lookahead: Vector<u64, E::ProposerLookaheadSlots>,
// Gloas
#[test_random(default)]
#[superstruct(only(Gloas))]
#[metastruct(exclude_from(tree_lists))]
pub execution_payload_availability: BitVector<E::SlotsPerHistoricalRoot>,
#[compare_fields(as_iter)]
#[test_random(default)]
#[superstruct(only(Gloas))]
pub builder_pending_payments: Vector<BuilderPendingPayment, E::BuilderPendingPaymentsLimit>,
#[compare_fields(as_iter)]
#[test_random(default)]
#[superstruct(only(Gloas))]
pub builder_pending_withdrawals:
List<BuilderPendingWithdrawal, E::BuilderPendingWithdrawalsLimit>,
#[test_random(default)]
#[superstruct(only(Gloas))]
#[metastruct(exclude_from(tree_lists))]
pub latest_block_hash: ExecutionBlockHash,
#[test_random(default)]
#[superstruct(only(Gloas))]
#[metastruct(exclude_from(tree_lists))]
pub latest_withdrawals_root: Hash256,
// Caching (not in the spec)
#[serde(skip_serializing, skip_deserializing)]
#[ssz(skip_serializing, skip_deserializing)]
@@ -1190,8 +1165,9 @@ impl<E: EthSpec> BeaconState<E> {
BeaconState::Fulu(state) => Ok(ExecutionPayloadHeaderRef::Fulu(
&state.latest_execution_payload_header,
)),
// TODO(EIP-7732): investigate calling functions
BeaconState::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant),
BeaconState::Gloas(state) => Ok(ExecutionPayloadHeaderRef::Gloas(
&state.latest_execution_payload_header,
)),
}
}
@@ -1217,8 +1193,9 @@ impl<E: EthSpec> BeaconState<E> {
BeaconState::Fulu(state) => Ok(ExecutionPayloadHeaderRefMut::Fulu(
&mut state.latest_execution_payload_header,
)),
// TODO(EIP-7732): investigate calling functions
BeaconState::Gloas(_) => Err(BeaconStateError::IncorrectStateVariant),
BeaconState::Gloas(state) => Ok(ExecutionPayloadHeaderRefMut::Gloas(
&mut state.latest_execution_payload_header,
)),
}
}
@@ -2295,15 +2272,12 @@ impl<E: EthSpec> BeaconState<E> {
pub fn is_parent_block_full(&self) -> bool {
match self {
BeaconState::Base(_) | BeaconState::Altair(_) => false,
// TODO(EIP-7732): check the implications of this when we get to forkchoice modifications
BeaconState::Bellatrix(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_)
| BeaconState::Electra(_)
| BeaconState::Fulu(_) => true,
BeaconState::Gloas(state) => {
state.latest_execution_payload_bid.block_hash == state.latest_block_hash
}
| BeaconState::Fulu(_)
| BeaconState::Gloas(_) => true,
}
}