Builder deposit requests

This commit is contained in:
Eitan Seri-Levi
2026-06-22 12:55:40 +03:00
parent d610407820
commit edf34c5575
33 changed files with 675 additions and 265 deletions

View File

@@ -21,3 +21,10 @@ BUILDER_PENDING_WITHDRAWALS_LIMIT: 1048576
# ---------------------------------------------------------------
# 2**14 (= 16,384) builders
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP: 16384
# Execution
# ---------------------------------------------------------------
# 2**8 (= 256) builder deposit requests
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD: 256
# 2**4 (= 16) builder exit requests
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD: 16

View File

@@ -20,4 +20,11 @@ BUILDER_PENDING_WITHDRAWALS_LIMIT: 1048576
# Withdrawals processing
# ---------------------------------------------------------------
# 2**14 (= 16,384) builders
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP: 16384
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP: 16384
# Execution
# ---------------------------------------------------------------
# 2**8 (= 256) builder deposit requests
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD: 256
# 2**4 (= 16) builder exit requests
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD: 16

View File

@@ -21,3 +21,10 @@ BUILDER_PENDING_WITHDRAWALS_LIMIT: 1048576
# ---------------------------------------------------------------
# [customized] 2**4 (= 16) builders
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP: 16
# Execution
# ---------------------------------------------------------------
# 2**8 (= 256) builder deposit requests
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD: 256
# 2**4 (= 16) builder exit requests
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD: 16

View File

@@ -25,8 +25,8 @@ use crate::{
core::{ChainSpec, Domain, Epoch, EthSpec, Graffiti, Hash256, SignedRoot, Slot},
deposit::{Deposit, DepositData},
execution::{
AbstractExecPayload, BlindedPayload, Eth1Data, ExecutionPayload, ExecutionRequests,
FullPayload,
AbstractExecPayload, BlindedPayload, Eth1Data, ExecutionPayload, ExecutionRequestsElectra,
ExecutionRequestsGloas, FullPayload,
},
exit::{SignedVoluntaryExit, VoluntaryExit},
fork::{Fork, ForkName, InconsistentFork, map_fork_name},
@@ -650,7 +650,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockElec
execution_payload: Payload::Electra::default(),
bls_to_execution_changes: VariableList::empty(),
blob_kzg_commitments: VariableList::empty(),
execution_requests: ExecutionRequests::default(),
execution_requests: ExecutionRequestsElectra::default(),
},
}
}
@@ -684,7 +684,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockFulu
execution_payload: Payload::Fulu::default(),
bls_to_execution_changes: VariableList::empty(),
blob_kzg_commitments: VariableList::empty(),
execution_requests: ExecutionRequests::default(),
execution_requests: ExecutionRequestsElectra::default(),
},
}
}
@@ -713,7 +713,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockGloa
voluntary_exits: VariableList::empty(),
sync_aggregate: SyncAggregate::empty(),
bls_to_execution_changes: VariableList::empty(),
parent_execution_requests: ExecutionRequests::default(),
parent_execution_requests: ExecutionRequestsGloas::default(),
signed_execution_payload_bid: SignedExecutionPayloadBid::empty(),
payload_attestations: VariableList::empty(),
_phantom: PhantomData,

View File

@@ -24,9 +24,10 @@ use crate::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, Eth1Data, ExecutionPayload,
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionRequests,
FullPayload, FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb,
FullPayloadElectra, FullPayloadFulu, SignedBlsToExecutionChange,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas,
ExecutionRequestsElectra, ExecutionRequestsGloas, FullPayload, FullPayloadBellatrix,
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu,
SignedBlsToExecutionChange,
},
exit::SignedVoluntaryExit,
fork::{ForkName, map_fork_name},
@@ -163,13 +164,13 @@ pub struct BeaconBlockBody<E: EthSpec, Payload: AbstractExecPayload<E> = FullPay
#[superstruct(only(Deneb, Electra, Fulu))]
pub blob_kzg_commitments: KzgCommitments<E>,
#[superstruct(only(Electra, Fulu))]
pub execution_requests: ExecutionRequests<E>,
pub execution_requests: ExecutionRequestsElectra<E>,
#[superstruct(only(Gloas))]
pub signed_execution_payload_bid: SignedExecutionPayloadBid<E>,
#[superstruct(only(Gloas))]
pub payload_attestations: VariableList<PayloadAttestation<E>, E::MaxPayloadAttestations>,
#[superstruct(only(Gloas))]
pub parent_execution_requests: ExecutionRequests<E>,
pub parent_execution_requests: ExecutionRequestsGloas<E>,
#[superstruct(only(Base, Altair, Gloas))]
#[metastruct(exclude_from(fields))]
#[ssz(skip_serializing, skip_deserializing)]

View File

@@ -12,7 +12,7 @@ use crate::{
execution::{
ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, ExecutionRequests,
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, ExecutionRequestsElectra,
},
fork::{ForkName, ForkVersionDecode},
kzg_ext::KzgCommitments,
@@ -59,7 +59,7 @@ pub struct BuilderBid<E: EthSpec> {
#[superstruct(only(Deneb, Electra, Fulu))]
pub blob_kzg_commitments: KzgCommitments<E>,
#[superstruct(only(Electra, Fulu))]
pub execution_requests: ExecutionRequests<E>,
pub execution_requests: ExecutionRequestsElectra<E>,
#[serde(with = "serde_utils::quoted_u256")]
pub value: Uint256,
pub pubkey: PublicKeyBytes,

View File

@@ -0,0 +1,74 @@
use bls::{PublicKeyBytes, SignatureBytes};
use context_deserialize::context_deserialize;
use serde::{Deserialize, Serialize};
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use tree_hash_derive::TreeHash;
use crate::{
Address, BeaconStateError, ChainSpec, DepositMessage, Domain, SignedRoot, core::Hash256,
fork::ForkName,
};
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)]
#[context_deserialize(ForkName)]
pub struct BuilderDepositRequest {
pub pubkey: PublicKeyBytes,
pub withdrawal_credentials: Hash256,
#[serde(with = "serde_utils::quoted_u64")]
pub amount: u64,
pub signature: SignatureBytes,
}
impl BuilderDepositRequest {
fn as_deposit_message(&self) -> DepositMessage {
DepositMessage {
pubkey: self.pubkey,
withdrawal_credentials: self.withdrawal_credentials,
amount: self.amount,
}
}
pub fn version(&self) -> Option<u8> {
self.withdrawal_credentials.as_slice().first().cloned()
}
pub fn is_valid_builder_deposit_signature(&self, spec: &ChainSpec) -> bool {
let Ok(pubkey) = self.pubkey.decompress() else {
return false;
};
let Ok(signature) = self.signature.decompress() else {
return false;
};
let domain = spec.compute_domain(
Domain::BuilderDeposit,
spec.genesis_fork_version,
Hash256::ZERO,
);
let signing_root = self.as_deposit_message().signing_root(domain);
signature.verify(&pubkey, signing_root)
}
}
impl BuilderDepositRequest {
pub fn max_size() -> usize {
Self {
pubkey: PublicKeyBytes::empty(),
withdrawal_credentials: Hash256::ZERO,
amount: 0,
signature: SignatureBytes::empty(),
}
.as_ssz_bytes()
.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(BuilderDepositRequest);
}

View File

@@ -0,0 +1,35 @@
use bls::PublicKeyBytes;
use context_deserialize::context_deserialize;
use serde::{Deserialize, Serialize};
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use tree_hash_derive::TreeHash;
use crate::{core::Address, fork::ForkName};
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)]
#[context_deserialize(ForkName)]
pub struct BuilderExitRequest {
#[serde(with = "serde_utils::address_hex")]
pub source_address: Address,
pub pubkey: PublicKeyBytes,
}
impl BuilderExitRequest {
pub fn max_size() -> usize {
Self {
source_address: Address::repeat_byte(0),
pubkey: PublicKeyBytes::empty(),
}
.as_ssz_bytes()
.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(BuilderExitRequest);
}

View File

@@ -1,5 +1,7 @@
mod builder;
mod builder_bid;
mod builder_deposit_request;
mod builder_exit_request;
mod builder_pending_payment;
mod builder_pending_withdrawal;
mod proposer_preferences;
@@ -9,6 +11,8 @@ pub use builder_bid::{
BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidElectra,
BuilderBidFulu, SignedBuilderBid,
};
pub use builder_deposit_request::BuilderDepositRequest;
pub use builder_exit_request::BuilderExitRequest;
pub use builder_pending_payment::BuilderPendingPayment;
pub use builder_pending_withdrawal::BuilderPendingWithdrawal;
pub use proposer_preferences::{ProposerPreferences, SignedProposerPreferences};

View File

@@ -37,6 +37,7 @@ pub enum Domain {
BeaconBuilder,
PTCAttester,
ProposerPreferences,
BuilderDeposit,
ApplicationMask(ApplicationDomain),
}
@@ -147,6 +148,7 @@ pub struct ChainSpec {
pub(crate) domain_beacon_builder: u32,
pub(crate) domain_ptc_attester: u32,
pub(crate) domain_proposer_preferences: u32,
pub(crate) domain_builder_deposit: u32,
/*
* Fork choice
@@ -525,6 +527,7 @@ impl ChainSpec {
Domain::BeaconBuilder => self.domain_beacon_builder,
Domain::PTCAttester => self.domain_ptc_attester,
Domain::ProposerPreferences => self.domain_proposer_preferences,
Domain::BuilderDeposit => self.domain_builder_deposit,
Domain::SyncCommittee => self.domain_sync_committee,
Domain::ContributionAndProof => self.domain_contribution_and_proof,
Domain::SyncCommitteeSelectionProof => self.domain_sync_committee_selection_proof,
@@ -1158,6 +1161,7 @@ impl ChainSpec {
domain_beacon_builder: 0x0B,
domain_ptc_attester: 0x0C,
domain_proposer_preferences: 0x0D,
domain_builder_deposit: 0x0E,
/*
* Fork choice
@@ -1583,6 +1587,7 @@ impl ChainSpec {
domain_beacon_builder: 0x0B,
domain_ptc_attester: 0x0C,
domain_proposer_preferences: 0x0D,
domain_builder_deposit: 0x0E,
/*
* Fork choice
@@ -2982,6 +2987,12 @@ mod tests {
test_domain(Domain::SyncCommittee, spec.domain_sync_committee, &spec);
test_domain(Domain::BeaconBuilder, spec.domain_beacon_builder, &spec);
test_domain(Domain::PTCAttester, spec.domain_ptc_attester, &spec);
test_domain(
Domain::ProposerPreferences,
spec.domain_proposer_preferences,
&spec,
);
test_domain(Domain::BuilderDeposit, spec.domain_builder_deposit, &spec);
// The builder domain index is zero
let builder_domain_pre_mask = [0; 4];

View File

@@ -181,6 +181,8 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
type BuilderPendingPaymentsLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type BuilderPendingWithdrawalsLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxBuildersPerWithdrawalsSweep: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxBuilderDepositRequestsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxBuilderExitRequestsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
fn default_spec() -> ChainSpec;
@@ -444,6 +446,16 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
Self::MaxBuildersPerWithdrawalsSweep::to_usize()
}
/// Returns the `MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD` constant for this specification.
fn max_builder_deposit_requests_per_payload() -> usize {
Self::MaxBuilderDepositRequestsPerPayload::to_usize()
}
/// Returns the `MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD` constant for this specification.
fn max_builder_exit_requests_per_payload() -> usize {
Self::MaxBuilderExitRequestsPerPayload::to_usize()
}
/// Returns the `PAYLOAD_TIMELY_THRESHOLD` constant (PTC_SIZE / 2).
fn payload_timely_threshold() -> usize {
Self::PTCSize::to_usize() / 2
@@ -529,6 +541,8 @@ impl EthSpec for MainnetEthSpec {
type PtcWindowLength = U96; // (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH
type MaxPayloadAttestations = U4;
type MaxBuildersPerWithdrawalsSweep = U16384;
type MaxBuilderDepositRequestsPerPayload = U256;
type MaxBuilderExitRequestsPerPayload = U16;
fn default_spec() -> ChainSpec {
ChainSpec::mainnet()
@@ -606,6 +620,8 @@ impl EthSpec for MinimalEthSpec {
MaxDepositRequestsPerPayload,
MaxWithdrawalRequestsPerPayload,
MaxPayloadAttestations,
MaxBuilderDepositRequestsPerPayload,
MaxBuilderExitRequestsPerPayload,
BuilderRegistryLimit
});
@@ -684,6 +700,8 @@ impl EthSpec for GnosisEthSpec {
type PtcWindowLength = U48; // (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH
type MaxPayloadAttestations = U2;
type MaxBuildersPerWithdrawalsSweep = U16384;
type MaxBuilderDepositRequestsPerPayload = U256;
type MaxBuilderExitRequestsPerPayload = U16;
fn default_spec() -> ChainSpec {
ChainSpec::gnosis()

View File

@@ -342,6 +342,10 @@ pub struct GloasPreset {
pub builder_pending_withdrawals_limit: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub max_builders_per_withdrawals_sweep: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub max_builder_deposit_requests_per_payload: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub max_builder_exit_requests_per_payload: u64,
}
impl GloasPreset {
@@ -352,6 +356,10 @@ impl GloasPreset {
builder_registry_limit: E::BuilderRegistryLimit::to_u64(),
builder_pending_withdrawals_limit: E::builder_pending_withdrawals_limit() as u64,
max_builders_per_withdrawals_sweep: E::max_builders_per_withdrawals_sweep() as u64,
max_builder_deposit_requests_per_payload: E::max_builder_deposit_requests_per_payload()
as u64,
max_builder_exit_requests_per_payload: E::max_builder_exit_requests_per_payload()
as u64,
}
}
}

View File

@@ -1,4 +1,4 @@
use crate::execution::{ExecutionPayloadGloas, ExecutionRequests};
use crate::execution::{ExecutionPayloadGloas, ExecutionRequestsGloas};
use crate::{EthSpec, ForkName, Hash256, SignedRoot, Slot};
use context_deserialize::context_deserialize;
use educe::Educe;
@@ -19,7 +19,7 @@ use tree_hash_derive::TreeHash;
#[serde(bound = "E: EthSpec")]
pub struct ExecutionPayloadEnvelope<E: EthSpec> {
pub payload: ExecutionPayloadGloas<E>,
pub execution_requests: ExecutionRequests<E>,
pub execution_requests: ExecutionRequestsGloas<E>,
#[serde(with = "serde_utils::quoted_u64")]
pub builder_index: u64,
pub beacon_block_root: Hash256,
@@ -31,7 +31,7 @@ impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
pub fn empty() -> Self {
Self {
payload: ExecutionPayloadGloas::default(),
execution_requests: ExecutionRequests::default(),
execution_requests: ExecutionRequestsGloas::default(),
builder_index: 0,
beacon_block_root: Hash256::zero(),
parent_beacon_block_root: Hash256::zero(),

View File

@@ -6,15 +6,19 @@ use serde::{Deserialize, Serialize};
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use ssz_types::VariableList;
use superstruct::superstruct;
use tree_hash_derive::TreeHash;
use crate::{
builder::{BuilderDepositRequest, BuilderExitRequest},
consolidation::ConsolidationRequest,
core::{EthSpec, Hash256},
deposit::DepositRequest,
fork::ForkName,
fork::{ForkName, ForkVersionDecode},
state::BeaconStateError,
withdrawal::WithdrawalRequest,
};
use ssz::Decode;
pub type DepositRequests<E> =
VariableList<DepositRequest, <E as EthSpec>::MaxDepositRequestsPerPayload>;
@@ -22,46 +26,106 @@ pub type WithdrawalRequests<E> =
VariableList<WithdrawalRequest, <E as EthSpec>::MaxWithdrawalRequestsPerPayload>;
pub type ConsolidationRequests<E> =
VariableList<ConsolidationRequest, <E as EthSpec>::MaxConsolidationRequestsPerPayload>;
pub type BuilderDepositRequests<E> =
VariableList<BuilderDepositRequest, <E as EthSpec>::MaxBuilderDepositRequestsPerPayload>;
pub type BuilderExitRequests<E> =
VariableList<BuilderExitRequest, <E as EthSpec>::MaxBuilderExitRequestsPerPayload>;
#[superstruct(
variants(Electra, Gloas),
variant_attributes(
derive(
Default,
Debug,
Clone,
Serialize,
Deserialize,
Encode,
Decode,
TreeHash,
Educe,
),
context_deserialize(ForkName),
educe(PartialEq, Eq, Hash(bound(E: EthSpec))),
serde(bound = "E: EthSpec"),
cfg_attr(
feature = "arbitrary",
derive(arbitrary::Arbitrary),
arbitrary(bound = "E: EthSpec"),
),
),
cast_error(
ty = "BeaconStateError",
expr = "BeaconStateError::IncorrectStateVariant"
),
partial_getter_error(
ty = "BeaconStateError",
expr = "BeaconStateError::IncorrectStateVariant"
)
)]
#[cfg_attr(
feature = "arbitrary",
derive(arbitrary::Arbitrary),
arbitrary(bound = "E: EthSpec")
)]
#[derive(Debug, Educe, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)]
#[serde(bound = "E: EthSpec")]
#[derive(Debug, Educe, Clone, Serialize, Deserialize, Encode, TreeHash)]
#[serde(bound = "E: EthSpec", untagged)]
#[educe(PartialEq, Eq, Hash(bound(E: EthSpec)))]
#[context_deserialize(ForkName)]
#[tree_hash(enum_behaviour = "transparent")]
#[ssz(enum_behaviour = "transparent")]
pub struct ExecutionRequests<E: EthSpec> {
pub deposits: DepositRequests<E>,
pub withdrawals: WithdrawalRequests<E>,
pub consolidations: ConsolidationRequests<E>,
#[superstruct(only(Gloas))]
pub builder_deposits: BuilderDepositRequests<E>,
#[superstruct(only(Gloas))]
pub builder_exits: BuilderExitRequests<E>,
}
impl<E: EthSpec> ExecutionRequests<E> {
impl<'a, E: EthSpec> ExecutionRequestsRef<'a, E> {
/// Returns the encoding according to EIP-7685 to send
/// to the execution layer over the engine api.
pub fn get_execution_requests_list(&self) -> Vec<Bytes> {
let mut requests_list = Vec::new();
if !self.deposits.is_empty() {
if !self.deposits().is_empty() {
requests_list.push(Bytes::from_iter(
[RequestType::Deposit.to_u8()]
.into_iter()
.chain(self.deposits.as_ssz_bytes()),
.chain(self.deposits().as_ssz_bytes()),
));
}
if !self.withdrawals.is_empty() {
if !self.withdrawals().is_empty() {
requests_list.push(Bytes::from_iter(
[RequestType::Withdrawal.to_u8()]
.into_iter()
.chain(self.withdrawals.as_ssz_bytes()),
.chain(self.withdrawals().as_ssz_bytes()),
));
}
if !self.consolidations.is_empty() {
if !self.consolidations().is_empty() {
requests_list.push(Bytes::from_iter(
[RequestType::Consolidation.to_u8()]
.into_iter()
.chain(self.consolidations.as_ssz_bytes()),
.chain(self.consolidations().as_ssz_bytes()),
));
}
// [New in Gloas:EIP8282] The builder request lists are only present on the Gloas variant.
if let Ok(builder_deposits) = self.builder_deposits()
&& !builder_deposits.is_empty()
{
requests_list.push(Bytes::from_iter(
[RequestType::BuilderDeposit.to_u8()]
.into_iter()
.chain(builder_deposits.as_ssz_bytes()),
));
}
if let Ok(builder_exits) = self.builder_exits()
&& !builder_exits.is_empty()
{
requests_list.push(Bytes::from_iter(
[RequestType::BuilderExit.to_u8()]
.into_iter()
.chain(builder_exits.as_ssz_bytes()),
));
}
requests_list
@@ -85,12 +149,46 @@ impl<E: EthSpec> ExecutionRequests<E> {
}
}
impl<E: EthSpec> ExecutionRequests<E> {
/// Returns the encoding according to EIP-7685 to send
/// to the execution layer over the engine api.
pub fn get_execution_requests_list(&self) -> Vec<Bytes> {
self.to_ref().get_execution_requests_list()
}
/// Generate the execution layer `requests_hash` based on EIP-7685.
pub fn requests_hash(&self) -> Hash256 {
self.to_ref().requests_hash()
}
}
impl<E: EthSpec> ForkVersionDecode for ExecutionRequests<E> {
/// SSZ decode with explicit fork variant.
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError> {
match fork_name {
ForkName::Base
| ForkName::Altair
| ForkName::Bellatrix
| ForkName::Capella
| ForkName::Deneb => Err(ssz::DecodeError::BytesInvalid(format!(
"unsupported fork for ExecutionRequests: {fork_name}",
))),
ForkName::Electra | ForkName::Fulu => {
ExecutionRequestsElectra::from_ssz_bytes(bytes).map(Self::Electra)
}
ForkName::Gloas => ExecutionRequestsGloas::from_ssz_bytes(bytes).map(Self::Gloas),
}
}
}
/// The prefix types for `ExecutionRequest` objects.
#[derive(Debug, Copy, Clone)]
pub enum RequestType {
Deposit,
Withdrawal,
Consolidation,
BuilderDeposit,
BuilderExit,
}
impl RequestType {
@@ -99,6 +197,8 @@ impl RequestType {
0 => Some(Self::Deposit),
1 => Some(Self::Withdrawal),
2 => Some(Self::Consolidation),
3 => Some(Self::BuilderDeposit),
4 => Some(Self::BuilderExit),
_ => None,
}
}
@@ -107,15 +207,24 @@ impl RequestType {
Self::Deposit => 0,
Self::Withdrawal => 1,
Self::Consolidation => 2,
Self::BuilderDeposit => 3,
Self::BuilderExit => 4,
}
}
}
#[cfg(test)]
mod tests {
mod electra_tests {
use super::*;
use crate::MainnetEthSpec;
use super::*;
ssz_and_tree_hash_tests!(ExecutionRequests<MainnetEthSpec>);
ssz_and_tree_hash_tests!(ExecutionRequestsElectra<MainnetEthSpec>);
}
#[cfg(test)]
mod gloas_tests {
use super::*;
use crate::MainnetEthSpec;
ssz_and_tree_hash_tests!(ExecutionRequestsGloas<MainnetEthSpec>);
}

View File

@@ -29,7 +29,9 @@ pub use execution_payload_header::{
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
};
pub use execution_requests::{
ConsolidationRequests, DepositRequests, ExecutionRequests, RequestType, WithdrawalRequests,
BuilderDepositRequests, BuilderExitRequests, ConsolidationRequests, DepositRequests,
ExecutionRequests, ExecutionRequestsElectra, ExecutionRequestsGloas, ExecutionRequestsRef,
RequestType, WithdrawalRequests,
};
pub use payload::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,