Electra updates for v1.5.0-alpha.6 (#6445)

* Update process_slashing

* Update test vectors version

* Delete Domain::Consolidation

* Rename to get_max_effective_balance

* Fix unused; lint

* Add the pre-electra slashing processing

* lint

* Change request json types

* Move requests from payload to beacon block body

* Refactor engine api

* Fix warnings

* Update engine api to latest

* engine api changed..again

* yet again

* Merge branch 'engine-requests' into electra-updates

* Fix tests

* Store reference instead of bytes in NewPayloadRequest

* Merge branch 'unstable' into electra-updates

* Update beacon_node/execution_layer/src/engine_api/json_structures.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>

* Update beacon_node/execution_layer/src/lib.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>

* Update beacon_node/execution_layer/src/test_utils/handle_rpc.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>
This commit is contained in:
Pawan Dhananjay
2024-10-15 10:38:43 -07:00
committed by GitHub
parent 2e440df4f1
commit 83d5c521d7
35 changed files with 445 additions and 913 deletions

View File

@@ -2,8 +2,7 @@ use crate::engines::ForkchoiceState;
use crate::http::{
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
ENGINE_GET_CLIENT_VERSION_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V4, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
ENGINE_NEW_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V4,
};
@@ -18,7 +17,6 @@ use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use strum::IntoStaticStr;
use superstruct::superstruct;
use types::execution_payload::{ConsolidationRequests, DepositRequests, WithdrawalRequests};
pub use types::{
Address, BeaconBlockRef, ConsolidationRequest, EthSpec, ExecutionBlockHash, ExecutionPayload,
ExecutionPayloadHeader, ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions,
@@ -26,7 +24,7 @@ pub use types::{
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, KzgProofs,
ExecutionPayloadElectra, ExecutionRequests, KzgProofs,
};
use types::{Graffiti, GRAFFITI_BYTES_LEN};
@@ -288,6 +286,8 @@ pub struct GetPayloadResponse<E: EthSpec> {
pub blobs_bundle: BlobsBundle<E>,
#[superstruct(only(Deneb, Electra), partial_getter(copy))]
pub should_override_builder: bool,
#[superstruct(only(Electra))]
pub requests: ExecutionRequests<E>,
}
impl<E: EthSpec> GetPayloadResponse<E> {
@@ -321,7 +321,12 @@ impl<E: EthSpec> From<GetPayloadResponse<E>> for ExecutionPayload<E> {
}
impl<E: EthSpec> From<GetPayloadResponse<E>>
for (ExecutionPayload<E>, Uint256, Option<BlobsBundle<E>>)
for (
ExecutionPayload<E>,
Uint256,
Option<BlobsBundle<E>>,
Option<ExecutionRequests<E>>,
)
{
fn from(response: GetPayloadResponse<E>) -> Self {
match response {
@@ -329,21 +334,25 @@ impl<E: EthSpec> From<GetPayloadResponse<E>>
ExecutionPayload::Bellatrix(inner.execution_payload),
inner.block_value,
None,
None,
),
GetPayloadResponse::Capella(inner) => (
ExecutionPayload::Capella(inner.execution_payload),
inner.block_value,
None,
None,
),
GetPayloadResponse::Deneb(inner) => (
ExecutionPayload::Deneb(inner.execution_payload),
inner.block_value,
Some(inner.blobs_bundle),
None,
),
GetPayloadResponse::Electra(inner) => (
ExecutionPayload::Electra(inner.execution_payload),
inner.block_value,
Some(inner.blobs_bundle),
Some(inner.requests),
),
}
}
@@ -360,106 +369,25 @@ impl<E: EthSpec> GetPayloadResponse<E> {
}
}
#[superstruct(
variants(V1, V2),
variant_attributes(derive(Clone, Debug),),
partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant")
)]
#[derive(Clone, Debug)]
pub struct ExecutionPayloadBody<E: EthSpec> {
pub struct ExecutionPayloadBodyV1<E: EthSpec> {
pub transactions: Transactions<E>,
pub withdrawals: Option<Withdrawals<E>>,
#[superstruct(only(V2))]
pub deposit_requests: Option<DepositRequests<E>>,
#[superstruct(only(V2))]
pub withdrawal_requests: Option<WithdrawalRequests<E>>,
#[superstruct(only(V2))]
pub consolidation_requests: Option<ConsolidationRequests<E>>,
}
impl<E: EthSpec> ExecutionPayloadBody<E> {
#[allow(clippy::type_complexity)]
pub fn deconstruct(
self,
) -> (
Transactions<E>,
Option<Withdrawals<E>>,
Option<DepositRequests<E>>,
Option<WithdrawalRequests<E>>,
Option<ConsolidationRequests<E>>,
) {
match self {
ExecutionPayloadBody::V1(body) => {
(body.transactions, body.withdrawals, None, None, None)
}
ExecutionPayloadBody::V2(body) => (
body.transactions,
body.withdrawals,
body.deposit_requests,
body.withdrawal_requests,
body.consolidation_requests,
),
}
}
impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
pub fn to_payload(
self,
header: ExecutionPayloadHeader<E>,
) -> Result<ExecutionPayload<E>, String> {
let header_fork = header.fork_name_unchecked();
match &self {
Self::V1(_) => {
if header_fork.electra_enabled() {
return Err(format!(
"block {} is {} but response is ExecutionPayloadBodyV1. Does the EL support {}?",
header.block_hash(),
header_fork,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2,
));
}
}
Self::V2(_) => {}
}
let (
transactions,
withdrawals,
deposit_requests,
withdrawal_requests,
consolidation_requests,
) = self.deconstruct();
if !header_fork.capella_enabled() && withdrawals.is_some() {
return Err(format!(
"block {} is {} but payload body has withdrawals",
header.block_hash(),
header_fork
));
}
if !header_fork.electra_enabled() {
if deposit_requests.is_some() {
return Err(format!(
"block {} is {} but payload body has deposit_requests",
header.block_hash(),
header_fork
));
}
if withdrawal_requests.is_some() {
return Err(format!(
"block {} is {} but payload body has withdrawal_requests",
header.block_hash(),
header_fork
));
}
if consolidation_requests.is_some() {
return Err(format!(
"block {} is {} but payload body has consolidation_requests",
header.block_hash(),
header_fork
));
}
}
match header {
ExecutionPayloadHeader::Bellatrix(header) => {
if self.withdrawals.is_some() {
return Err(format!(
"block {} is bellatrix but payload body has withdrawals",
header.block_hash
));
}
Ok(ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
@@ -474,108 +402,90 @@ impl<E: EthSpec> ExecutionPayloadBody<E> {
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions,
transactions: self.transactions,
}))
}
ExecutionPayloadHeader::Capella(header) => {
let withdrawals = withdrawals.ok_or_else(|| {
format!(
"block {} is {} but payload body has withdrawals set to null",
header.block_hash, header_fork
)
})?;
Ok(ExecutionPayload::Capella(ExecutionPayloadCapella {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions,
withdrawals,
}))
if let Some(withdrawals) = self.withdrawals {
Ok(ExecutionPayload::Capella(ExecutionPayloadCapella {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions: self.transactions,
withdrawals,
}))
} else {
Err(format!(
"block {} is capella but payload body doesn't have withdrawals",
header.block_hash
))
}
}
ExecutionPayloadHeader::Deneb(header) => {
let withdrawals = withdrawals.ok_or_else(|| {
format!(
"block {} is {} but payload body has withdrawals set to null",
header.block_hash, header_fork
)
})?;
Ok(ExecutionPayload::Deneb(ExecutionPayloadDeneb {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions,
withdrawals,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
}))
if let Some(withdrawals) = self.withdrawals {
Ok(ExecutionPayload::Deneb(ExecutionPayloadDeneb {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions: self.transactions,
withdrawals,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
}))
} else {
Err(format!(
"block {} is post capella but payload body doesn't have withdrawals",
header.block_hash
))
}
}
ExecutionPayloadHeader::Electra(header) => {
let withdrawals = withdrawals.ok_or_else(|| {
format!(
"block {} is {} but payload body has withdrawals set to null",
header.block_hash, header_fork
)
})?;
let deposit_requests = deposit_requests.ok_or_else(|| {
format!(
"block {} is {} but payload body has deposit_requests set to null",
header.block_hash, header_fork
)
})?;
let withdrawal_requests = withdrawal_requests.ok_or_else(|| {
format!(
"block {} is {} but payload body has withdrawal_requests set to null",
header.block_hash, header_fork
)
})?;
let consolidation_requests = consolidation_requests.ok_or_else(|| {
format!(
"block {} is {} but payload body has consolidation_requests set to null",
header.block_hash, header_fork
)
})?;
Ok(ExecutionPayload::Electra(ExecutionPayloadElectra {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions,
withdrawals,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
deposit_requests,
withdrawal_requests,
consolidation_requests,
}))
if let Some(withdrawals) = self.withdrawals {
Ok(ExecutionPayload::Electra(ExecutionPayloadElectra {
parent_hash: header.parent_hash,
fee_recipient: header.fee_recipient,
state_root: header.state_root,
receipts_root: header.receipts_root,
logs_bloom: header.logs_bloom,
prev_randao: header.prev_randao,
block_number: header.block_number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
extra_data: header.extra_data,
base_fee_per_gas: header.base_fee_per_gas,
block_hash: header.block_hash,
transactions: self.transactions,
withdrawals,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
}))
} else {
Err(format!(
"block {} is post capella but payload body doesn't have withdrawals",
header.block_hash
))
}
}
}
}
@@ -592,8 +502,6 @@ pub struct EngineCapabilities {
pub forkchoice_updated_v3: bool,
pub get_payload_bodies_by_hash_v1: bool,
pub get_payload_bodies_by_range_v1: bool,
pub get_payload_bodies_by_hash_v2: bool,
pub get_payload_bodies_by_range_v2: bool,
pub get_payload_v1: bool,
pub get_payload_v2: bool,
pub get_payload_v3: bool,
@@ -631,12 +539,6 @@ impl EngineCapabilities {
if self.get_payload_bodies_by_range_v1 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1);
}
if self.get_payload_bodies_by_hash_v2 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2);
}
if self.get_payload_bodies_by_range_v2 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2);
}
if self.get_payload_v1 {
response.push(ENGINE_GET_PAYLOAD_V1);
}

View File

@@ -50,8 +50,6 @@ pub const ENGINE_FORKCHOICE_UPDATED_TIMEOUT: Duration = Duration::from_secs(8);
pub const ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1: &str = "engine_getPayloadBodiesByHashV1";
pub const ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1: &str = "engine_getPayloadBodiesByRangeV1";
pub const ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2: &str = "engine_getPayloadBodiesByHashV2";
pub const ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2: &str = "engine_getPayloadBodiesByRangeV2";
pub const ENGINE_GET_PAYLOAD_BODIES_TIMEOUT: Duration = Duration::from_secs(10);
pub const ENGINE_EXCHANGE_CAPABILITIES: &str = "engine_exchangeCapabilities";
@@ -80,8 +78,6 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[
ENGINE_FORKCHOICE_UPDATED_V3,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2,
ENGINE_GET_CLIENT_VERSION_V1,
];
@@ -797,6 +793,9 @@ impl HttpJsonRpc {
JsonExecutionPayload::V4(new_payload_request_electra.execution_payload.clone().into()),
new_payload_request_electra.versioned_hashes,
new_payload_request_electra.parent_beacon_block_root,
new_payload_request_electra
.execution_requests_list
.get_execution_requests_list(),
]);
let response: JsonPayloadStatusV1 = self
@@ -849,7 +848,9 @@ impl HttpJsonRpc {
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(JsonGetPayloadResponse::V1(response).into())
JsonGetPayloadResponse::V1(response)
.try_into()
.map_err(Error::BadResponse)
}
ForkName::Capella => {
let response: JsonGetPayloadResponseV2<E> = self
@@ -859,7 +860,9 @@ impl HttpJsonRpc {
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(JsonGetPayloadResponse::V2(response).into())
JsonGetPayloadResponse::V2(response)
.try_into()
.map_err(Error::BadResponse)
}
ForkName::Base | ForkName::Altair | ForkName::Deneb | ForkName::Electra => Err(
Error::UnsupportedForkVariant(format!("called get_payload_v2 with {}", fork_name)),
@@ -883,7 +886,9 @@ impl HttpJsonRpc {
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(JsonGetPayloadResponse::V3(response).into())
JsonGetPayloadResponse::V3(response)
.try_into()
.map_err(Error::BadResponse)
}
ForkName::Base
| ForkName::Altair
@@ -912,7 +917,9 @@ impl HttpJsonRpc {
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(JsonGetPayloadResponse::V4(response).into())
JsonGetPayloadResponse::V4(response)
.try_into()
.map_err(Error::BadResponse)
}
ForkName::Base
| ForkName::Altair
@@ -991,7 +998,7 @@ impl HttpJsonRpc {
pub async fn get_payload_bodies_by_hash_v1<E: EthSpec>(
&self,
block_hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
) -> Result<Vec<Option<ExecutionPayloadBodyV1<E>>>, Error> {
let params = json!([block_hashes]);
let response: Vec<Option<JsonExecutionPayloadBodyV1<E>>> = self
@@ -1004,27 +1011,7 @@ impl HttpJsonRpc {
Ok(response
.into_iter()
.map(|opt_json| opt_json.map(|v1| JsonExecutionPayloadBody::V1(v1).into()))
.collect())
}
pub async fn get_payload_bodies_by_hash_v2<E: EthSpec>(
&self,
block_hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
let params = json!([block_hashes]);
let response: Vec<Option<JsonExecutionPayloadBodyV2<E>>> = self
.rpc_request(
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2,
params,
ENGINE_GET_PAYLOAD_BODIES_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(response
.into_iter()
.map(|opt_json| opt_json.map(|v2| JsonExecutionPayloadBody::V2(v2).into()))
.map(|opt_json| opt_json.map(From::from))
.collect())
}
@@ -1032,7 +1019,7 @@ impl HttpJsonRpc {
&self,
start: u64,
count: u64,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
) -> Result<Vec<Option<ExecutionPayloadBodyV1<E>>>, Error> {
#[derive(Serialize)]
#[serde(transparent)]
struct Quantity(#[serde(with = "serde_utils::u64_hex_be")] u64);
@@ -1048,31 +1035,7 @@ impl HttpJsonRpc {
Ok(response
.into_iter()
.map(|opt_json| opt_json.map(|v1| JsonExecutionPayloadBody::V1(v1).into()))
.collect())
}
pub async fn get_payload_bodies_by_range_v2<E: EthSpec>(
&self,
start: u64,
count: u64,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
#[derive(Serialize)]
#[serde(transparent)]
struct Quantity(#[serde(with = "serde_utils::u64_hex_be")] u64);
let params = json!([Quantity(start), Quantity(count)]);
let response: Vec<Option<JsonExecutionPayloadBodyV2<E>>> = self
.rpc_request(
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2,
params,
ENGINE_GET_PAYLOAD_BODIES_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(response
.into_iter()
.map(|opt_json| opt_json.map(|v2| JsonExecutionPayloadBody::V2(v2).into()))
.map(|opt_json| opt_json.map(From::from))
.collect())
}
@@ -1099,10 +1062,6 @@ impl HttpJsonRpc {
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1),
get_payload_bodies_by_range_v1: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1),
get_payload_bodies_by_hash_v2: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2),
get_payload_bodies_by_range_v2: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2),
get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1),
get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2),
get_payload_v3: capabilities.contains(ENGINE_GET_PAYLOAD_V3),
@@ -1278,39 +1237,6 @@ impl HttpJsonRpc {
}
}
pub async fn get_payload_bodies_by_hash<E: EthSpec>(
&self,
block_hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
let engine_capabilities = self.get_engine_capabilities(None).await?;
if engine_capabilities.get_payload_bodies_by_hash_v2 {
self.get_payload_bodies_by_hash_v2(block_hashes).await
} else if engine_capabilities.get_payload_bodies_by_hash_v1 {
self.get_payload_bodies_by_hash_v1(block_hashes).await
} else {
Err(Error::RequiredMethodUnsupported(
"engine_getPayloadBodiesByHash",
))
}
}
pub async fn get_payload_bodies_by_range<E: EthSpec>(
&self,
start: u64,
count: u64,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
let engine_capabilities = self.get_engine_capabilities(None).await?;
if engine_capabilities.get_payload_bodies_by_range_v2 {
self.get_payload_bodies_by_range_v2(start, count).await
} else if engine_capabilities.get_payload_bodies_by_range_v1 {
self.get_payload_bodies_by_range_v1(start, count).await
} else {
Err(Error::RequiredMethodUnsupported(
"engine_getPayloadBodiesByRange",
))
}
}
// automatically selects the latest version of
// forkchoice_updated that the execution engine supports
pub async fn forkchoice_updated(

View File

@@ -1,11 +1,13 @@
use super::*;
use alloy_rlp::RlpEncodable;
use serde::{Deserialize, Serialize};
use ssz::Decode;
use strum::EnumString;
use superstruct::superstruct;
use types::beacon_block_body::KzgCommitments;
use types::blob_sidecar::BlobsList;
use types::{DepositRequest, FixedVector, PublicKeyBytes, Signature, Unsigned, WithdrawalRequest};
use types::execution_requests::{ConsolidationRequests, DepositRequests, WithdrawalRequests};
use types::{FixedVector, Unsigned};
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -104,14 +106,6 @@ pub struct JsonExecutionPayload<E: EthSpec> {
#[superstruct(only(V3, V4))]
#[serde(with = "serde_utils::u64_hex_be")]
pub excess_blob_gas: u64,
#[superstruct(only(V4))]
pub deposit_requests: VariableList<JsonDepositRequest, E::MaxDepositRequestsPerPayload>,
#[superstruct(only(V4))]
pub withdrawal_requests:
VariableList<JsonWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>,
#[superstruct(only(V4))]
pub consolidation_requests:
VariableList<JsonConsolidationRequest, E::MaxConsolidationRequestsPerPayload>,
}
impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadV1<E> {
@@ -214,24 +208,6 @@ impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E>
.into(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
deposit_requests: payload
.deposit_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
withdrawal_requests: payload
.withdrawal_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
consolidation_requests: payload
.consolidation_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}
@@ -348,24 +324,6 @@ impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E>
.into(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
deposit_requests: payload
.deposit_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
withdrawal_requests: payload
.withdrawal_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
consolidation_requests: payload
.consolidation_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}
@@ -381,6 +339,71 @@ impl<E: EthSpec> From<JsonExecutionPayload<E>> for ExecutionPayload<E> {
}
}
/// This is used to index into the `execution_requests` array.
#[derive(Debug, Copy, Clone)]
enum RequestPrefix {
Deposit,
Withdrawal,
Consolidation,
}
impl RequestPrefix {
pub fn from_prefix(prefix: u8) -> Option<Self> {
match prefix {
0 => Some(Self::Deposit),
1 => Some(Self::Withdrawal),
2 => Some(Self::Consolidation),
_ => None,
}
}
}
/// Format of `ExecutionRequests` received over the engine api.
///
/// Array of ssz-encoded requests list encoded as hex bytes.
/// The prefix of the request type is used to index into the array.
///
/// For e.g. [0xab, 0xcd, 0xef]
/// Here, 0xab are the deposits bytes (prefix and index == 0)
/// 0xcd are the withdrawals bytes (prefix and index == 1)
/// 0xef are the consolidations bytes (prefix and index == 2)
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct JsonExecutionRequests(pub Vec<String>);
impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
type Error = String;
fn try_from(value: JsonExecutionRequests) -> Result<Self, Self::Error> {
let mut requests = ExecutionRequests::default();
for (i, request) in value.0.into_iter().enumerate() {
// hex string
let decoded_bytes = hex::decode(request).map_err(|e| format!("Invalid hex {:?}", e))?;
match RequestPrefix::from_prefix(i as u8) {
Some(RequestPrefix::Deposit) => {
requests.deposits = DepositRequests::<E>::from_ssz_bytes(&decoded_bytes)
.map_err(|e| format!("Failed to decode DepositRequest from EL: {:?}", e))?;
}
Some(RequestPrefix::Withdrawal) => {
requests.withdrawals = WithdrawalRequests::<E>::from_ssz_bytes(&decoded_bytes)
.map_err(|e| {
format!("Failed to decode WithdrawalRequest from EL: {:?}", e)
})?;
}
Some(RequestPrefix::Consolidation) => {
requests.consolidations =
ConsolidationRequests::<E>::from_ssz_bytes(&decoded_bytes).map_err(
|e| format!("Failed to decode ConsolidationRequest from EL: {:?}", e),
)?;
}
None => return Err("Empty requests string".to_string()),
}
}
Ok(requests)
}
}
#[superstruct(
variants(V1, V2, V3, V4),
variant_attributes(
@@ -407,38 +430,42 @@ pub struct JsonGetPayloadResponse<E: EthSpec> {
pub blobs_bundle: JsonBlobsBundleV1<E>,
#[superstruct(only(V3, V4))]
pub should_override_builder: bool,
#[superstruct(only(V4))]
pub requests: JsonExecutionRequests,
}
impl<E: EthSpec> From<JsonGetPayloadResponse<E>> for GetPayloadResponse<E> {
fn from(json_get_payload_response: JsonGetPayloadResponse<E>) -> Self {
impl<E: EthSpec> TryFrom<JsonGetPayloadResponse<E>> for GetPayloadResponse<E> {
type Error = String;
fn try_from(json_get_payload_response: JsonGetPayloadResponse<E>) -> Result<Self, Self::Error> {
match json_get_payload_response {
JsonGetPayloadResponse::V1(response) => {
GetPayloadResponse::Bellatrix(GetPayloadResponseBellatrix {
Ok(GetPayloadResponse::Bellatrix(GetPayloadResponseBellatrix {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
})
}))
}
JsonGetPayloadResponse::V2(response) => {
GetPayloadResponse::Capella(GetPayloadResponseCapella {
Ok(GetPayloadResponse::Capella(GetPayloadResponseCapella {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
})
}))
}
JsonGetPayloadResponse::V3(response) => {
GetPayloadResponse::Deneb(GetPayloadResponseDeneb {
Ok(GetPayloadResponse::Deneb(GetPayloadResponseDeneb {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
blobs_bundle: response.blobs_bundle.into(),
should_override_builder: response.should_override_builder,
})
}))
}
JsonGetPayloadResponse::V4(response) => {
GetPayloadResponse::Electra(GetPayloadResponseElectra {
Ok(GetPayloadResponse::Electra(GetPayloadResponseElectra {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
blobs_bundle: response.blobs_bundle.into(),
should_override_builder: response.should_override_builder,
})
requests: response.requests.try_into()?,
}))
}
}
}
@@ -754,122 +781,36 @@ impl From<ForkchoiceUpdatedResponse> for JsonForkchoiceUpdatedV1Response {
}
}
#[superstruct(
variants(V1, V2),
variant_attributes(
derive(Clone, Debug, Serialize, Deserialize),
serde(bound = "E: EthSpec", rename_all = "camelCase"),
),
partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant")
)]
#[derive(Clone, Debug, Serialize)]
#[serde(bound = "E: EthSpec", rename_all = "camelCase", untagged)]
pub struct JsonExecutionPayloadBody<E: EthSpec> {
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "E: EthSpec")]
pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
pub transactions: Transactions<E>,
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
#[superstruct(only(V2))]
pub deposit_requests: Option<VariableList<JsonDepositRequest, E::MaxDepositRequestsPerPayload>>,
#[superstruct(only(V2))]
pub withdrawal_requests:
Option<VariableList<JsonWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>>,
#[superstruct(only(V2))]
pub consolidation_requests:
Option<VariableList<ConsolidationRequest, E::MaxConsolidationRequestsPerPayload>>,
}
impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
fn from(value: JsonExecutionPayloadBodyV1<E>) -> Self {
Self {
transactions: value.transactions,
withdrawals: value.withdrawals.map(|json_withdrawals| {
Withdrawals::<E>::from(
json_withdrawals
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
}
}
}
impl<E: EthSpec> From<ExecutionPayloadBodyV1<E>> for JsonExecutionPayloadBodyV1<E> {
fn from(value: ExecutionPayloadBodyV1<E>) -> Self {
Self {
transactions: value.transactions,
withdrawals: value.withdrawals.map(|json_withdrawals| {
VariableList::from(
json_withdrawals
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
}
}
}
impl<E: EthSpec> From<ExecutionPayloadBodyV2<E>> for JsonExecutionPayloadBodyV2<E> {
fn from(value: ExecutionPayloadBodyV2<E>) -> Self {
Self {
transactions: value.transactions,
withdrawals: value.withdrawals.map(|json_withdrawals| {
VariableList::from(
json_withdrawals
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
deposit_requests: value.deposit_requests.map(|receipts| {
VariableList::from(receipts.into_iter().map(Into::into).collect::<Vec<_>>())
}),
withdrawal_requests: value.withdrawal_requests.map(|withdrawal_requests| {
VariableList::from(
withdrawal_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
consolidation_requests: value.consolidation_requests.map(|consolidation_requests| {
VariableList::from(
consolidation_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
}
}
}
impl<E: EthSpec> From<JsonExecutionPayloadBody<E>> for ExecutionPayloadBody<E> {
fn from(value: JsonExecutionPayloadBody<E>) -> Self {
match value {
JsonExecutionPayloadBody::V1(body_v1) => Self::V1(ExecutionPayloadBodyV1 {
transactions: body_v1.transactions,
withdrawals: body_v1.withdrawals.map(|json_withdrawals| {
Withdrawals::<E>::from(
json_withdrawals
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
}),
JsonExecutionPayloadBody::V2(body_v2) => Self::V2(ExecutionPayloadBodyV2 {
transactions: body_v2.transactions,
withdrawals: body_v2.withdrawals.map(|json_withdrawals| {
Withdrawals::<E>::from(
json_withdrawals
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
deposit_requests: body_v2.deposit_requests.map(|json_receipts| {
DepositRequests::<E>::from(
json_receipts
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
withdrawal_requests: body_v2.withdrawal_requests.map(|json_withdrawal_requests| {
WithdrawalRequests::<E>::from(
json_withdrawal_requests
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
)
}),
consolidation_requests: body_v2.consolidation_requests,
withdrawals: value.withdrawals.map(|withdrawals| {
VariableList::from(withdrawals.into_iter().map(Into::into).collect::<Vec<_>>())
}),
}
}
@@ -950,96 +891,3 @@ impl TryFrom<JsonClientVersionV1> for ClientVersionV1 {
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct JsonDepositRequest {
pub pubkey: PublicKeyBytes,
pub withdrawal_credentials: Hash256,
#[serde(with = "serde_utils::u64_hex_be")]
pub amount: u64,
pub signature: Signature,
#[serde(with = "serde_utils::u64_hex_be")]
pub index: u64,
}
impl From<DepositRequest> for JsonDepositRequest {
fn from(deposit: DepositRequest) -> Self {
Self {
pubkey: deposit.pubkey,
withdrawal_credentials: deposit.withdrawal_credentials,
amount: deposit.amount,
signature: deposit.signature,
index: deposit.index,
}
}
}
impl From<JsonDepositRequest> for DepositRequest {
fn from(json_deposit: JsonDepositRequest) -> Self {
Self {
pubkey: json_deposit.pubkey,
withdrawal_credentials: json_deposit.withdrawal_credentials,
amount: json_deposit.amount,
signature: json_deposit.signature,
index: json_deposit.index,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct JsonWithdrawalRequest {
pub source_address: Address,
pub validator_pubkey: PublicKeyBytes,
#[serde(with = "serde_utils::u64_hex_be")]
pub amount: u64,
}
impl From<WithdrawalRequest> for JsonWithdrawalRequest {
fn from(withdrawal_request: WithdrawalRequest) -> Self {
Self {
source_address: withdrawal_request.source_address,
validator_pubkey: withdrawal_request.validator_pubkey,
amount: withdrawal_request.amount,
}
}
}
impl From<JsonWithdrawalRequest> for WithdrawalRequest {
fn from(json_withdrawal_request: JsonWithdrawalRequest) -> Self {
Self {
source_address: json_withdrawal_request.source_address,
validator_pubkey: json_withdrawal_request.validator_pubkey,
amount: json_withdrawal_request.amount,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct JsonConsolidationRequest {
pub source_address: Address,
pub source_pubkey: PublicKeyBytes,
pub target_pubkey: PublicKeyBytes,
}
impl From<ConsolidationRequest> for JsonConsolidationRequest {
fn from(consolidation_request: ConsolidationRequest) -> Self {
Self {
source_address: consolidation_request.source_address,
source_pubkey: consolidation_request.source_pubkey,
target_pubkey: consolidation_request.target_pubkey,
}
}
}
impl From<JsonConsolidationRequest> for ConsolidationRequest {
fn from(json_consolidation_request: JsonConsolidationRequest) -> Self {
Self {
source_address: json_consolidation_request.source_address,
source_pubkey: json_consolidation_request.source_pubkey,
target_pubkey: json_consolidation_request.target_pubkey,
}
}
}

View File

@@ -9,7 +9,7 @@ use types::{
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra,
ExecutionPayloadElectra, ExecutionRequests,
};
#[superstruct(
@@ -43,6 +43,8 @@ pub struct NewPayloadRequest<'block, E: EthSpec> {
pub versioned_hashes: Vec<VersionedHash>,
#[superstruct(only(Deneb, Electra))]
pub parent_beacon_block_root: Hash256,
#[superstruct(only(Electra))]
pub execution_requests_list: &'block ExecutionRequests<E>,
}
impl<'block, E: EthSpec> NewPayloadRequest<'block, E> {
@@ -183,6 +185,7 @@ impl<'a, E: EthSpec> TryFrom<BeaconBlockRef<'a, E>> for NewPayloadRequest<'a, E>
.map(kzg_commitment_to_versioned_hash)
.collect(),
parent_beacon_block_root: block_ref.parent_root,
execution_requests_list: &block_ref.body.execution_requests,
})),
}
}

View File

@@ -48,7 +48,8 @@ use types::builder_bid::BuilderBid;
use types::non_zero_usize::new_non_zero_usize;
use types::payload::BlockProductionVersion;
use types::{
AbstractExecPayload, BlobsList, ExecutionPayloadDeneb, KzgProofs, SignedBlindedBeaconBlock,
AbstractExecPayload, BlobsList, ExecutionPayloadDeneb, ExecutionRequests, KzgProofs,
SignedBlindedBeaconBlock,
};
use types::{
BeaconStateError, BlindedPayload, ChainSpec, Epoch, ExecPayload, ExecutionPayloadBellatrix,
@@ -112,12 +113,15 @@ impl<E: EthSpec> TryFrom<BuilderBid<E>> for ProvenancedPayload<BlockProposalCont
block_value: builder_bid.value,
kzg_commitments: builder_bid.blob_kzg_commitments,
blobs_and_proofs: None,
requests: None,
},
BuilderBid::Electra(builder_bid) => BlockProposalContents::PayloadAndBlobs {
payload: ExecutionPayloadHeader::Electra(builder_bid.header).into(),
block_value: builder_bid.value,
kzg_commitments: builder_bid.blob_kzg_commitments,
blobs_and_proofs: None,
// TODO(electra): update this with builder api returning the requests
requests: None,
},
};
Ok(ProvenancedPayload::Builder(
@@ -194,6 +198,8 @@ pub enum BlockProposalContents<E: EthSpec, Payload: AbstractExecPayload<E>> {
kzg_commitments: KzgCommitments<E>,
/// `None` for blinded `PayloadAndBlobs`.
blobs_and_proofs: Option<(BlobsList<E>, KzgProofs<E>)>,
// TODO(electra): this should probably be a separate variant/superstruct
requests: Option<ExecutionRequests<E>>,
},
}
@@ -214,11 +220,13 @@ impl<E: EthSpec> From<BlockProposalContents<E, FullPayload<E>>>
block_value,
kzg_commitments,
blobs_and_proofs: _,
requests,
} => BlockProposalContents::PayloadAndBlobs {
payload: payload.execution_payload().into(),
block_value,
kzg_commitments,
blobs_and_proofs: None,
requests,
},
}
}
@@ -230,13 +238,14 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> TryFrom<GetPayloadResponse<E>>
type Error = Error;
fn try_from(response: GetPayloadResponse<E>) -> Result<Self, Error> {
let (execution_payload, block_value, maybe_bundle) = response.into();
let (execution_payload, block_value, maybe_bundle, maybe_requests) = response.into();
match maybe_bundle {
Some(bundle) => Ok(Self::PayloadAndBlobs {
payload: execution_payload.into(),
block_value,
kzg_commitments: bundle.commitments,
blobs_and_proofs: Some((bundle.blobs, bundle.proofs)),
requests: maybe_requests,
}),
None => Ok(Self::Payload {
payload: execution_payload.into(),
@@ -265,22 +274,25 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BlockProposalContents<E, Paylo
Payload,
Option<KzgCommitments<E>>,
Option<(BlobsList<E>, KzgProofs<E>)>,
Option<ExecutionRequests<E>>,
Uint256,
) {
match self {
Self::Payload {
payload,
block_value,
} => (payload, None, None, block_value),
} => (payload, None, None, None, block_value),
Self::PayloadAndBlobs {
payload,
block_value,
kzg_commitments,
blobs_and_proofs,
requests,
} => (
payload,
Some(kzg_commitments),
blobs_and_proofs,
requests,
block_value,
),
}
@@ -1772,10 +1784,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
pub async fn get_payload_bodies_by_hash(
&self,
hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
) -> Result<Vec<Option<ExecutionPayloadBodyV1<E>>>, Error> {
self.engine()
.request(|engine: &Engine| async move {
engine.api.get_payload_bodies_by_hash(hashes).await
engine.api.get_payload_bodies_by_hash_v1(hashes).await
})
.await
.map_err(Box::new)
@@ -1786,11 +1798,14 @@ impl<E: EthSpec> ExecutionLayer<E> {
&self,
start: u64,
count: u64,
) -> Result<Vec<Option<ExecutionPayloadBody<E>>>, Error> {
) -> Result<Vec<Option<ExecutionPayloadBodyV1<E>>>, Error> {
let _timer = metrics::start_timer(&metrics::EXECUTION_LAYER_GET_PAYLOAD_BODIES_BY_RANGE);
self.engine()
.request(|engine: &Engine| async move {
engine.api.get_payload_bodies_by_range(start, count).await
engine
.api
.get_payload_bodies_by_range_v1(start, count)
.await
})
.await
.map_err(Box::new)
@@ -1823,9 +1838,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
// Use efficient payload bodies by range method if supported.
let capabilities = self.get_engine_capabilities(None).await?;
if capabilities.get_payload_bodies_by_range_v1
|| capabilities.get_payload_bodies_by_range_v2
{
if capabilities.get_payload_bodies_by_range_v1 {
let mut payload_bodies = self.get_payload_bodies_by_range(block_number, 1).await?;
if payload_bodies.len() != 1 {

View File

@@ -652,10 +652,6 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
withdrawals: pa.withdrawals.clone().into(),
blob_gas_used: 0,
excess_blob_gas: 0,
// TODO(electra): consider how to test these fields below
deposit_requests: vec![].into(),
withdrawal_requests: vec![].into(),
consolidation_requests: vec![].into(),
}),
_ => unreachable!(),
},

View File

@@ -373,6 +373,8 @@ pub async fn handle_rpc<E: EthSpec>(
))?
.into(),
should_override_builder: false,
// TODO(electra): add EL requests in mock el
requests: Default::default(),
})
.unwrap()
}
@@ -561,60 +563,11 @@ pub async fn handle_rpc<E: EthSpec>(
match maybe_payload {
Some(payload) => {
assert!(
!payload.fork_name().electra_enabled(),
"payload bodies V1 is not supported for Electra blocks"
);
let payload_body = ExecutionPayloadBodyV1 {
let payload_body: ExecutionPayloadBodyV1<E> = ExecutionPayloadBodyV1 {
transactions: payload.transactions().clone(),
withdrawals: payload.withdrawals().ok().cloned(),
};
let json_payload_body = JsonExecutionPayloadBody::V1(
JsonExecutionPayloadBodyV1::<E>::from(payload_body),
);
response.push(Some(json_payload_body));
}
None => response.push(None),
}
}
Ok(serde_json::to_value(response).unwrap())
}
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V2 => {
#[derive(Deserialize)]
#[serde(transparent)]
struct Quantity(#[serde(with = "serde_utils::u64_hex_be")] pub u64);
let start = get_param::<Quantity>(params, 0)
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?
.0;
let count = get_param::<Quantity>(params, 1)
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?
.0;
let mut response = vec![];
for block_num in start..(start + count) {
let maybe_payload = ctx
.execution_block_generator
.read()
.execution_payload_by_number(block_num);
match maybe_payload {
Some(payload) => {
// TODO(electra): add testing for:
// deposit_requests
// withdrawal_requests
// consolidation_requests
let payload_body = ExecutionPayloadBodyV2 {
transactions: payload.transactions().clone(),
withdrawals: payload.withdrawals().ok().cloned(),
deposit_requests: payload.deposit_requests().ok().cloned(),
withdrawal_requests: payload.withdrawal_requests().ok().cloned(),
consolidation_requests: payload.consolidation_requests().ok().cloned(),
};
let json_payload_body = JsonExecutionPayloadBody::V2(
JsonExecutionPayloadBodyV2::<E>::from(payload_body),
);
let json_payload_body = JsonExecutionPayloadBodyV1::from(payload_body);
response.push(Some(json_payload_body));
}
None => response.push(None),

View File

@@ -20,9 +20,9 @@ use types::builder_bid::{
};
use types::{
Address, BeaconState, ChainSpec, EthSpec, ExecPayload, ExecutionPayload,
ExecutionPayloadHeaderRefMut, FixedBytesExtended, ForkName, ForkVersionedResponse, Hash256,
PublicKeyBytes, Signature, SignedBlindedBeaconBlock, SignedRoot,
SignedValidatorRegistrationData, Slot, Uint256,
ExecutionPayloadHeaderRefMut, ExecutionRequests, FixedBytesExtended, ForkName,
ForkVersionedResponse, Hash256, PublicKeyBytes, Signature, SignedBlindedBeaconBlock,
SignedRoot, SignedValidatorRegistrationData, Slot, Uint256,
};
use types::{ExecutionBlockHash, SecretKey};
use warp::{Filter, Rejection};
@@ -542,10 +542,12 @@ pub fn serve<E: EthSpec>(
let mut message = match payload_response_type {
crate::GetPayloadResponseType::Full(payload_response) => {
let (payload, _block_value, maybe_blobs_bundle): (
#[allow(clippy::type_complexity)]
let (payload, _block_value, maybe_blobs_bundle, _maybe_requests): (
ExecutionPayload<E>,
Uint256,
Option<BlobsBundle<E>>,
Option<ExecutionRequests<E>>,
) = payload_response.into();
match fork {
@@ -593,10 +595,12 @@ pub fn serve<E: EthSpec>(
}
}
crate::GetPayloadResponseType::Blinded(payload_response) => {
let (payload, _block_value, maybe_blobs_bundle): (
#[allow(clippy::type_complexity)]
let (payload, _block_value, maybe_blobs_bundle, _maybe_requests): (
ExecutionPayload<E>,
Uint256,
Option<BlobsBundle<E>>,
Option<ExecutionRequests<E>>,
) = payload_response.into();
match fork {
ForkName::Electra => BuilderBid::Electra(BuilderBidElectra {

View File

@@ -47,9 +47,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
forkchoice_updated_v2: true,
forkchoice_updated_v3: true,
get_payload_bodies_by_hash_v1: true,
get_payload_bodies_by_hash_v2: true,
get_payload_bodies_by_range_v1: true,
get_payload_bodies_by_range_v2: true,
get_payload_v1: true,
get_payload_v2: true,
get_payload_v3: true,