Add support for electra fields in getPayloadBodies

This commit is contained in:
Pawan Dhananjay
2024-05-08 16:22:01 -07:00
parent 683de56f6e
commit dd5c9a8c81
4 changed files with 64 additions and 27 deletions

View File

@@ -20,6 +20,7 @@ use reqwest::StatusCode;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::IntoStaticStr; use strum::IntoStaticStr;
use superstruct::superstruct; use superstruct::superstruct;
use types::execution_payload::{DepositReceipts, WithdrawalRequests};
pub use types::{ pub use types::{
Address, BeaconBlockRef, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, Address, BeaconBlockRef, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList, ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList,
@@ -545,6 +546,8 @@ impl<E: EthSpec> GetPayloadResponse<E> {
pub struct ExecutionPayloadBodyV1<E: EthSpec> { pub struct ExecutionPayloadBodyV1<E: EthSpec> {
pub transactions: Transactions<E>, pub transactions: Transactions<E>,
pub withdrawals: Option<Withdrawals<E>>, pub withdrawals: Option<Withdrawals<E>>,
pub deposit_receipts: Option<DepositReceipts<E>>,
pub withdrawal_requests: Option<WithdrawalRequests<E>>,
} }
impl<E: EthSpec> ExecutionPayloadBodyV1<E> { impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
@@ -632,7 +635,17 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
} }
} }
ExecutionPayloadHeader::Electra(header) => { ExecutionPayloadHeader::Electra(header) => {
if let Some(withdrawals) = self.withdrawals { let (Some(withdrawals), Some(deposit_receipts), Some(withdrawal_requests)) = (
self.withdrawals,
self.deposit_receipts,
self.withdrawal_requests,
) else {
return Err(format!(
"block {} is post-electra but payload body doesn't have withdrawals/deposit_receipts/withdrawal_requests \
Check that ELs are returning receipts and withdrawal_requests in getPayloadBody requests",
header.block_hash
))
};
Ok(ExecutionPayload::Electra(ExecutionPayloadElectra { Ok(ExecutionPayload::Electra(ExecutionPayloadElectra {
parent_hash: header.parent_hash, parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient, fee_recipient: header.fee_recipient,
@@ -651,16 +664,9 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
withdrawals, withdrawals,
blob_gas_used: header.blob_gas_used, blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas, excess_blob_gas: header.excess_blob_gas,
// TODO(electra) deposit_receipts,
deposit_receipts: <_>::default(), withdrawal_requests,
withdrawal_requests: <_>::default(),
})) }))
} else {
Err(format!(
"block {} is post-capella but payload body doesn't have withdrawals",
header.block_hash
))
}
} }
} }
} }

View File

@@ -724,6 +724,9 @@ pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
pub transactions: Transactions<E>, pub transactions: Transactions<E>,
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>, pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
pub deposit_receipts: Option<VariableList<JsonDepositRequest, E::MaxDepositReceiptsPerPayload>>,
pub withdrawal_requests:
Option<VariableList<JsonWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>>,
} }
impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> { impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
@@ -738,6 +741,22 @@ impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
) )
}), }),
deposit_receipts: value.deposit_receipts.map(|json_receipts| {
DepositReceipts::<E>::from(
json_receipts
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
withdrawal_requests: value.withdrawal_requests.map(|json_withdrawal_requests| {
WithdrawalRequests::<E>::from(
json_withdrawal_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
} }
} }
} }

View File

@@ -580,6 +580,14 @@ pub async fn handle_rpc<E: EthSpec>(
.withdrawals() .withdrawals()
.ok() .ok()
.map(|withdrawals| VariableList::from(withdrawals.clone())), .map(|withdrawals| VariableList::from(withdrawals.clone())),
deposit_receipts: block.deposit_receipts().ok().map(
|deposit_receipts| VariableList::from(deposit_receipts.clone()),
),
withdrawal_requests: block.withdrawal_requests().ok().map(
|withdrawal_requests| {
VariableList::from(withdrawal_requests.clone())
},
),
})); }));
} }
None => response.push(None), None => response.push(None),

View File

@@ -13,6 +13,10 @@ pub type Transactions<E> = VariableList<
>; >;
pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>; pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>;
pub type DepositReceipts<E> =
VariableList<DepositReceipt, <E as EthSpec>::MaxDepositReceiptsPerPayload>;
pub type WithdrawalRequests<E> =
VariableList<ExecutionLayerWithdrawalRequest, <E as EthSpec>::MaxWithdrawalRequestsPerPayload>;
#[superstruct( #[superstruct(
variants(Bellatrix, Capella, Deneb, Electra), variants(Bellatrix, Capella, Deneb, Electra),