mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-05 05:44:30 +00:00
Builder deposit requests
This commit is contained in:
@@ -844,8 +844,7 @@ impl HttpJsonRpc {
|
||||
),
|
||||
new_payload_request_electra.versioned_hashes,
|
||||
new_payload_request_electra.parent_beacon_block_root,
|
||||
new_payload_request_electra
|
||||
.execution_requests
|
||||
types::ExecutionRequestsRef::Electra(new_payload_request_electra.execution_requests)
|
||||
.get_execution_requests_list(),
|
||||
]);
|
||||
|
||||
@@ -873,8 +872,7 @@ impl HttpJsonRpc {
|
||||
),
|
||||
new_payload_request_fulu.versioned_hashes,
|
||||
new_payload_request_fulu.parent_beacon_block_root,
|
||||
new_payload_request_fulu
|
||||
.execution_requests
|
||||
types::ExecutionRequestsRef::Electra(new_payload_request_fulu.execution_requests)
|
||||
.get_execution_requests_list(),
|
||||
]);
|
||||
|
||||
@@ -902,8 +900,7 @@ impl HttpJsonRpc {
|
||||
),
|
||||
new_payload_request_gloas.versioned_hashes,
|
||||
new_payload_request_gloas.parent_beacon_block_root,
|
||||
new_payload_request_gloas
|
||||
.execution_requests
|
||||
types::ExecutionRequestsRef::Gloas(new_payload_request_gloas.execution_requests)
|
||||
.get_execution_requests_list(),
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
use super::*;
|
||||
use alloy_rlp::RlpEncodable;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, Encode, TryFromIter};
|
||||
use ssz::{Decode, TryFromIter};
|
||||
use ssz_types::{FixedVector, VariableList, typenum::Unsigned};
|
||||
use strum::EnumString;
|
||||
use superstruct::superstruct;
|
||||
use types::data::BlobsList;
|
||||
use types::execution::{ConsolidationRequests, DepositRequests, RequestType, WithdrawalRequests};
|
||||
use types::execution::{
|
||||
BuilderDepositRequests, BuilderExitRequests, ConsolidationRequests, DepositRequests,
|
||||
ExecutionRequestsElectra, ExecutionRequestsGloas, RequestType, WithdrawalRequests,
|
||||
};
|
||||
use types::kzg_ext::KzgCommitments;
|
||||
use types::{Blob, KzgProof};
|
||||
|
||||
@@ -483,28 +486,13 @@ pub struct JsonExecutionRequests(pub Vec<String>);
|
||||
|
||||
impl<E: EthSpec> From<ExecutionRequests<E>> for JsonExecutionRequests {
|
||||
fn from(requests: ExecutionRequests<E>) -> Self {
|
||||
let mut result = Vec::new();
|
||||
if !requests.deposits.is_empty() {
|
||||
result.push(format!(
|
||||
"0x{:02x}{}",
|
||||
RequestType::Deposit.to_u8(),
|
||||
hex::encode(requests.deposits.as_ssz_bytes())
|
||||
));
|
||||
}
|
||||
if !requests.withdrawals.is_empty() {
|
||||
result.push(format!(
|
||||
"0x{:02x}{}",
|
||||
RequestType::Withdrawal.to_u8(),
|
||||
hex::encode(requests.withdrawals.as_ssz_bytes())
|
||||
));
|
||||
}
|
||||
if !requests.consolidations.is_empty() {
|
||||
result.push(format!(
|
||||
"0x{:02x}{}",
|
||||
RequestType::Consolidation.to_u8(),
|
||||
hex::encode(requests.consolidations.as_ssz_bytes())
|
||||
));
|
||||
}
|
||||
// Each element is a `RequestType`-prefixed, SSZ-encoded request list (EIP-7685).
|
||||
// The Gloas variant additionally emits builder deposit/exit requests.
|
||||
let result = requests
|
||||
.get_execution_requests_list()
|
||||
.into_iter()
|
||||
.map(|bytes| format!("0x{}", hex::encode(bytes)))
|
||||
.collect();
|
||||
JsonExecutionRequests(result)
|
||||
}
|
||||
}
|
||||
@@ -513,7 +501,15 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
|
||||
type Error = RequestsError;
|
||||
|
||||
fn try_from(value: JsonExecutionRequests) -> Result<Self, Self::Error> {
|
||||
let mut requests = ExecutionRequests::default();
|
||||
let mut deposits = DepositRequests::<E>::default();
|
||||
let mut withdrawals = WithdrawalRequests::<E>::default();
|
||||
let mut consolidations = ConsolidationRequests::<E>::default();
|
||||
let mut builder_deposits = BuilderDepositRequests::<E>::default();
|
||||
let mut builder_exits = BuilderExitRequests::<E>::default();
|
||||
// [New in Gloas:EIP8282] The presence of builder requests determines the variant: the
|
||||
// EIP-7685 list is fork-agnostic, so we only know it is Gloas-shaped once a builder
|
||||
// request type appears.
|
||||
let mut has_builder_requests = false;
|
||||
let mut prev_prefix: Option<RequestType> = None;
|
||||
for (i, request) in value.0.into_iter().enumerate() {
|
||||
// hex string
|
||||
@@ -540,8 +536,8 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
|
||||
|
||||
match current_prefix {
|
||||
RequestType::Deposit => {
|
||||
requests.deposits = DepositRequests::<E>::from_ssz_bytes(request_bytes)
|
||||
.map_err(|e| {
|
||||
deposits =
|
||||
DepositRequests::<E>::from_ssz_bytes(request_bytes).map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode DepositRequest from EL: {:?}",
|
||||
e
|
||||
@@ -549,26 +545,64 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
|
||||
})?;
|
||||
}
|
||||
RequestType::Withdrawal => {
|
||||
requests.withdrawals = WithdrawalRequests::<E>::from_ssz_bytes(request_bytes)
|
||||
.map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode WithdrawalRequest from EL: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
withdrawals =
|
||||
WithdrawalRequests::<E>::from_ssz_bytes(request_bytes).map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode WithdrawalRequest from EL: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
}
|
||||
RequestType::Consolidation => {
|
||||
requests.consolidations =
|
||||
ConsolidationRequests::<E>::from_ssz_bytes(request_bytes).map_err(|e| {
|
||||
consolidations = ConsolidationRequests::<E>::from_ssz_bytes(request_bytes)
|
||||
.map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode ConsolidationRequest from EL: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
}
|
||||
RequestType::BuilderDeposit => {
|
||||
builder_deposits = BuilderDepositRequests::<E>::from_ssz_bytes(request_bytes)
|
||||
.map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode BuilderDepositRequest from EL: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
has_builder_requests = true;
|
||||
}
|
||||
RequestType::BuilderExit => {
|
||||
builder_exits = BuilderExitRequests::<E>::from_ssz_bytes(request_bytes)
|
||||
.map_err(|e| {
|
||||
RequestsError::DecodeError(format!(
|
||||
"Failed to decode BuilderExitRequest from EL: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
has_builder_requests = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(requests)
|
||||
|
||||
// Without any builder requests the list is indistinguishable from a pre-Gloas one, so we
|
||||
// produce the Electra-shaped variant. Consumers that require the Gloas variant lift it
|
||||
// (carrying empty builder lists) at their boundary.
|
||||
if has_builder_requests {
|
||||
Ok(ExecutionRequests::Gloas(ExecutionRequestsGloas {
|
||||
deposits,
|
||||
withdrawals,
|
||||
consolidations,
|
||||
builder_deposits,
|
||||
builder_exits,
|
||||
}))
|
||||
} else {
|
||||
Ok(ExecutionRequests::Electra(ExecutionRequestsElectra {
|
||||
deposits,
|
||||
withdrawals,
|
||||
consolidations,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ use types::{
|
||||
};
|
||||
use types::{
|
||||
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionRequests,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionRequestsElectra,
|
||||
ExecutionRequestsGloas, ExecutionRequestsRef,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
@@ -47,8 +48,13 @@ pub struct NewPayloadRequest<'block, E: EthSpec> {
|
||||
pub versioned_hashes: Vec<VersionedHash>,
|
||||
#[superstruct(only(Deneb, Electra, Fulu, Gloas))]
|
||||
pub parent_beacon_block_root: Hash256,
|
||||
#[superstruct(only(Electra, Fulu, Gloas))]
|
||||
pub execution_requests: &'block ExecutionRequests<E>,
|
||||
#[superstruct(
|
||||
only(Electra, Fulu),
|
||||
partial_getter(rename = "execution_requests_electra")
|
||||
)]
|
||||
pub execution_requests: &'block ExecutionRequestsElectra<E>,
|
||||
#[superstruct(only(Gloas), partial_getter(rename = "execution_requests_gloas"))]
|
||||
pub execution_requests: &'block ExecutionRequestsGloas<E>,
|
||||
}
|
||||
|
||||
impl<'block, E: EthSpec> NewPayloadRequest<'block, E> {
|
||||
@@ -123,6 +129,16 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the execution requests as a fork-tagged reference, if present.
|
||||
pub fn execution_requests_ref(&self) -> Option<ExecutionRequestsRef<'block, E>> {
|
||||
match self {
|
||||
Self::Bellatrix(_) | Self::Capella(_) | Self::Deneb(_) => None,
|
||||
Self::Electra(r) => Some(ExecutionRequestsRef::Electra(r.execution_requests)),
|
||||
Self::Fulu(r) => Some(ExecutionRequestsRef::Electra(r.execution_requests)),
|
||||
Self::Gloas(r) => Some(ExecutionRequestsRef::Gloas(r.execution_requests)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify the block hash is consistent locally within Lighthouse.
|
||||
///
|
||||
/// ## Specification
|
||||
@@ -143,7 +159,7 @@ impl<'block, E: EthSpec> NewPayloadRequest<'block, E> {
|
||||
let (header_hash, rlp_transactions_root) = calculate_execution_block_hash(
|
||||
payload,
|
||||
parent_beacon_block_root,
|
||||
self.execution_requests().ok().copied(),
|
||||
self.execution_requests_ref(),
|
||||
);
|
||||
|
||||
if header_hash != self.block_hash() {
|
||||
|
||||
Reference in New Issue
Block a user