Fix execution payload request block prod code path

This commit is contained in:
Eitan Seri-Levi
2026-06-23 11:38:35 +03:00
parent 84407b3033
commit d685ba1e4a
4 changed files with 39 additions and 44 deletions

View File

@@ -31,11 +31,10 @@ use types::{
Address, Attestation, AttestationElectra, AttesterSlashing, AttesterSlashingElectra, Address, Attestation, AttestationElectra, AttesterSlashing, AttesterSlashingElectra,
BeaconBlock, BeaconBlockBodyGloas, BeaconBlockGloas, BeaconState, BeaconStateError, BeaconBlock, BeaconBlockBodyGloas, BeaconBlockGloas, BeaconState, BeaconStateError,
BuilderIndex, ChainSpec, Deposit, Eth1Data, EthSpec, ExecutionBlockHash, ExecutionPayloadBid, BuilderIndex, ChainSpec, Deposit, Eth1Data, EthSpec, ExecutionBlockHash, ExecutionPayloadBid,
ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequests, ExecutionRequestsGloas, ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequestsGloas, FullPayload, Graffiti,
FullPayload, Graffiti, Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, SignedBeaconBlock,
SignedBeaconBlock, SignedBlsToExecutionChange, SignedExecutionPayloadBid, SignedBlsToExecutionChange, SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope,
SignedExecutionPayloadEnvelope, SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal, SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal, Withdrawals,
Withdrawals,
}; };
use crate::pending_payload_envelopes::PendingEnvelopeData; use crate::pending_payload_envelopes::PendingEnvelopeData;
@@ -810,11 +809,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
should_override_builder, should_override_builder,
} = block_proposal_contents; } = block_proposal_contents;
// The EL get_payload response carries the standard (Electra-shaped) requests; lift them
// into the Gloas variant carried by the envelope and committed to by the bid.
// TODO(gloas): plumb builder deposit/exit requests from the EL.
let execution_requests = to_gloas_execution_requests(execution_requests);
// TODO(gloas) since we are defaulting to local building, execution payment is 0 // TODO(gloas) since we are defaulting to local building, execution payment is 0
// execution payment should only be set to > 0 for trusted building. // execution payment should only be set to > 0 for trusted building.
let bid = ExecutionPayloadBid::<T::EthSpec> { let bid = ExecutionPayloadBid::<T::EthSpec> {
@@ -1106,33 +1100,6 @@ where
Ok(block_contents) Ok(block_contents)
} }
/// Drop voluntary exits whose target validators will be exited by the parent envelope's
/// execution requests.
///
/// In Gloas the parent execution payload is processed before voluntary exits during block
/// processing. EL-triggered withdrawal-full-exit requests (EIP-7002) and cross-pubkey
/// consolidation requests (EIP-7251) call `initiate_validator_exit`, setting the target's
/// `exit_epoch`. A voluntary exit for the same validator would then fail with `AlreadyExited`.
/// Lift a fork-agnostic `ExecutionRequests` (as received from the EL) into the Gloas variant.
///
/// The standard request types are carried over; the Gloas-only builder deposit/exit lists are
/// left empty.
/// TODO(gloas): plumb builder deposit/exit requests from the EL.
fn to_gloas_execution_requests<E: EthSpec>(
requests: ExecutionRequests<E>,
) -> ExecutionRequestsGloas<E> {
match requests {
ExecutionRequests::Gloas(requests) => requests,
other => ExecutionRequestsGloas {
deposits: other.deposits().clone(),
withdrawals: other.withdrawals().clone(),
consolidations: other.consolidations().clone(),
builder_deposits: <_>::default(),
builder_exits: <_>::default(),
},
}
}
fn filter_voluntary_exits_for_parent_execution_requests<E: EthSpec>( fn filter_voluntary_exits_for_parent_execution_requests<E: EthSpec>(
voluntary_exits: &mut Vec<SignedVoluntaryExit>, voluntary_exits: &mut Vec<SignedVoluntaryExit>,
parent_execution_requests: &ExecutionRequestsGloas<E>, parent_execution_requests: &ExecutionRequestsGloas<E>,

View File

@@ -341,8 +341,13 @@ pub struct GetPayloadResponse<E: EthSpec> {
pub blobs_bundle: BlobsBundle<E>, pub blobs_bundle: BlobsBundle<E>,
#[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))] #[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))]
pub should_override_builder: bool, pub should_override_builder: bool,
#[superstruct(only(Electra, Fulu, Gloas))] #[superstruct(
pub requests: ExecutionRequests<E>, only(Electra, Fulu),
partial_getter(rename = "execution_requests_electra")
)]
pub requests: types::ExecutionRequestsElectra<E>,
#[superstruct(only(Gloas), partial_getter(rename = "execution_requests_gloas"))]
pub requests: types::ExecutionRequestsGloas<E>,
} }
impl<E: EthSpec> GetPayloadResponse<E> { impl<E: EthSpec> GetPayloadResponse<E> {
@@ -407,19 +412,19 @@ impl<E: EthSpec> From<GetPayloadResponse<E>>
ExecutionPayload::Electra(inner.execution_payload), ExecutionPayload::Electra(inner.execution_payload),
inner.block_value, inner.block_value,
Some(inner.blobs_bundle), Some(inner.blobs_bundle),
Some(inner.requests), Some(ExecutionRequests::Electra(inner.requests)),
), ),
GetPayloadResponse::Fulu(inner) => ( GetPayloadResponse::Fulu(inner) => (
ExecutionPayload::Fulu(inner.execution_payload), ExecutionPayload::Fulu(inner.execution_payload),
inner.block_value, inner.block_value,
Some(inner.blobs_bundle), Some(inner.blobs_bundle),
Some(inner.requests), Some(ExecutionRequests::Electra(inner.requests)),
), ),
GetPayloadResponse::Gloas(inner) => ( GetPayloadResponse::Gloas(inner) => (
ExecutionPayload::Gloas(inner.execution_payload), ExecutionPayload::Gloas(inner.execution_payload),
inner.block_value, inner.block_value,
Some(inner.blobs_bundle), Some(inner.blobs_bundle),
Some(inner.requests), Some(ExecutionRequests::Gloas(inner.requests)),
), ),
} }
} }

View File

@@ -474,6 +474,7 @@ pub enum RequestsError {
InvalidOrdering, InvalidOrdering,
InvalidPrefix(u8), InvalidPrefix(u8),
DecodeError(String), DecodeError(String),
VariantMismatch,
} }
/// Format of `ExecutionRequests` received over the engine api. /// Format of `ExecutionRequests` received over the engine api.
@@ -606,6 +607,28 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
} }
} }
impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequestsElectra<E> {
type Error = RequestsError;
fn try_from(value: JsonExecutionRequests) -> Result<Self, Self::Error> {
match ExecutionRequests::<E>::try_from(value)? {
ExecutionRequests::Electra(requests) => Ok(requests),
ExecutionRequests::Gloas(_) => Err(RequestsError::VariantMismatch),
}
}
}
impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequestsGloas<E> {
type Error = RequestsError;
fn try_from(value: JsonExecutionRequests) -> Result<Self, Self::Error> {
match ExecutionRequests::<E>::try_from(value)? {
ExecutionRequests::Gloas(requests) => Ok(requests),
ExecutionRequests::Electra(_) => Err(RequestsError::VariantMismatch),
}
}
}
#[superstruct( #[superstruct(
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas), variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
variant_attributes( variant_attributes(

View File

@@ -43,7 +43,6 @@ use tokio::{
use tokio_stream::wrappers::WatchStream; use tokio_stream::wrappers::WatchStream;
use tracing::{Instrument, debug, debug_span, error, info, instrument, warn}; use tracing::{Instrument, debug, debug_span, error, info, instrument, warn};
use tree_hash::TreeHash; use tree_hash::TreeHash;
use types::ExecutionPayloadGloas;
use types::builder::BuilderBid; use types::builder::BuilderBid;
use types::execution::BlockProductionVersion; use types::execution::BlockProductionVersion;
use types::kzg_ext::KzgCommitments; use types::kzg_ext::KzgCommitments;
@@ -56,6 +55,7 @@ use types::{
ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload, ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload,
ProposerPreparationData, Slot, ProposerPreparationData, Slot,
}; };
use types::{ExecutionPayloadGloas, ExecutionRequestsGloas};
mod block_hash; mod block_hash;
mod engine_api; mod engine_api;
@@ -206,7 +206,7 @@ pub struct BlockProposalContentsGloas<E: EthSpec> {
pub payload_value: Uint256, pub payload_value: Uint256,
pub blob_kzg_commitments: KzgCommitments<E>, pub blob_kzg_commitments: KzgCommitments<E>,
pub blobs_and_proofs: (BlobsList<E>, KzgProofs<E>), pub blobs_and_proofs: (BlobsList<E>, KzgProofs<E>),
pub execution_requests: ExecutionRequests<E>, pub execution_requests: ExecutionRequestsGloas<E>,
pub should_override_builder: bool, pub should_override_builder: bool,
} }