mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-01 20:04:41 +00:00
Builder deposit requests
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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,
|
||||
|
||||
74
consensus/types/src/builder/builder_deposit_request.rs
Normal file
74
consensus/types/src/builder/builder_deposit_request.rs
Normal 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);
|
||||
}
|
||||
35
consensus/types/src/builder/builder_exit_request.rs
Normal file
35
consensus/types/src/builder/builder_exit_request.rs
Normal 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);
|
||||
}
|
||||
@@ -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};
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user