Use Fork variants instead of version for JsonPayload types (#7909)

With Fulu, we increment the engine API version for `get_payload` but we do not also increment `new_payload`.
In Lighthouse, we have a tight coupling between these version numbers and the Fork variants.
For example, both `get_payload_v3` and `new_payload_v3` correspond to Deneb, `v4` to Electra, etc.

However this coupling breaks with Fulu where only `get_payload_v5` is related to Fulu and `new_payload_v4` now also corresponds to Fulu (new_payload_v5 does not exist). While we can work around this, it creates a confusing situation where the versions and Fork variants are out of sync.

See the following code snippet where we are using the v4 endpoint, and yet passing a `V5` payload variant: 522bd9e9c6/beacon_node/execution_layer/src/engine_api/http.rs (L849-L870)


  1. Remove `new_payload_v5` as it is unused in Fulu.
2. Rename the `JsonExecutionPayload` and `JsonGetExecutionPayloadResponse` types to use Fork variants instead of version variants. This clarifies the relationship between them.
This commit is contained in:
Mac L
2025-08-22 19:22:41 +10:00
committed by GitHub
parent 884f30094a
commit c41d1181d2
5 changed files with 116 additions and 159 deletions

View File

@@ -5,7 +5,7 @@ use crate::http::{
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V4,
ENGINE_GET_PAYLOAD_V5, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3,
ENGINE_NEW_PAYLOAD_V4, ENGINE_NEW_PAYLOAD_V5,
ENGINE_NEW_PAYLOAD_V4,
};
use eth2::types::{
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
@@ -541,7 +541,6 @@ pub struct EngineCapabilities {
pub new_payload_v2: bool,
pub new_payload_v3: bool,
pub new_payload_v4: bool,
pub new_payload_v5: bool,
pub forkchoice_updated_v1: bool,
pub forkchoice_updated_v2: bool,
pub forkchoice_updated_v3: bool,
@@ -572,9 +571,6 @@ impl EngineCapabilities {
if self.new_payload_v4 {
response.push(ENGINE_NEW_PAYLOAD_V4);
}
if self.new_payload_v5 {
response.push(ENGINE_NEW_PAYLOAD_V5);
}
if self.forkchoice_updated_v1 {
response.push(ENGINE_FORKCHOICE_UPDATED_V1);
}

View File

@@ -35,7 +35,6 @@ pub const ENGINE_NEW_PAYLOAD_V1: &str = "engine_newPayloadV1";
pub const ENGINE_NEW_PAYLOAD_V2: &str = "engine_newPayloadV2";
pub const ENGINE_NEW_PAYLOAD_V3: &str = "engine_newPayloadV3";
pub const ENGINE_NEW_PAYLOAD_V4: &str = "engine_newPayloadV4";
pub const ENGINE_NEW_PAYLOAD_V5: &str = "engine_newPayloadV5";
pub const ENGINE_NEW_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(8);
pub const ENGINE_GET_PAYLOAD_V1: &str = "engine_getPayloadV1";
@@ -75,7 +74,6 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[
ENGINE_NEW_PAYLOAD_V2,
ENGINE_NEW_PAYLOAD_V3,
ENGINE_NEW_PAYLOAD_V4,
ENGINE_NEW_PAYLOAD_V5,
ENGINE_GET_PAYLOAD_V1,
ENGINE_GET_PAYLOAD_V2,
ENGINE_GET_PAYLOAD_V3,
@@ -805,7 +803,7 @@ impl HttpJsonRpc {
new_payload_request_deneb: NewPayloadRequestDeneb<'_, E>,
) -> Result<PayloadStatusV1, Error> {
let params = json!([
JsonExecutionPayload::V3(new_payload_request_deneb.execution_payload.clone().into()),
JsonExecutionPayload::Deneb(new_payload_request_deneb.execution_payload.clone().into()),
new_payload_request_deneb.versioned_hashes,
new_payload_request_deneb.parent_beacon_block_root,
]);
@@ -826,7 +824,9 @@ impl HttpJsonRpc {
new_payload_request_electra: NewPayloadRequestElectra<'_, E>,
) -> Result<PayloadStatusV1, Error> {
let params = json!([
JsonExecutionPayload::V4(new_payload_request_electra.execution_payload.clone().into()),
JsonExecutionPayload::Electra(
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
@@ -850,7 +850,7 @@ impl HttpJsonRpc {
new_payload_request_fulu: NewPayloadRequestFulu<'_, E>,
) -> Result<PayloadStatusV1, Error> {
let params = json!([
JsonExecutionPayload::V5(new_payload_request_fulu.execution_payload.clone().into()),
JsonExecutionPayload::Fulu(new_payload_request_fulu.execution_payload.clone().into()),
new_payload_request_fulu.versioned_hashes,
new_payload_request_fulu.parent_beacon_block_root,
new_payload_request_fulu
@@ -875,7 +875,7 @@ impl HttpJsonRpc {
) -> Result<GetPayloadResponse<E>, Error> {
let params = json!([JsonPayloadIdRequest::from(payload_id)]);
let payload_v1: JsonExecutionPayloadV1<E> = self
let payload_v1: JsonExecutionPayloadBellatrix<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V1,
params,
@@ -901,26 +901,26 @@ impl HttpJsonRpc {
match fork_name {
ForkName::Bellatrix => {
let response: JsonGetPayloadResponseV1<E> = self
let response: JsonGetPayloadResponseBellatrix<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V2,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
JsonGetPayloadResponse::V1(response)
JsonGetPayloadResponse::Bellatrix(response)
.try_into()
.map_err(Error::BadResponse)
}
ForkName::Capella => {
let response: JsonGetPayloadResponseV2<E> = self
let response: JsonGetPayloadResponseCapella<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V2,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
JsonGetPayloadResponse::V2(response)
JsonGetPayloadResponse::Capella(response)
.try_into()
.map_err(Error::BadResponse)
}
@@ -940,14 +940,14 @@ impl HttpJsonRpc {
match fork_name {
ForkName::Deneb => {
let response: JsonGetPayloadResponseV3<E> = self
let response: JsonGetPayloadResponseDeneb<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V3,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
JsonGetPayloadResponse::V3(response)
JsonGetPayloadResponse::Deneb(response)
.try_into()
.map_err(Error::BadResponse)
}
@@ -967,14 +967,14 @@ impl HttpJsonRpc {
match fork_name {
ForkName::Electra => {
let response: JsonGetPayloadResponseV4<E> = self
let response: JsonGetPayloadResponseElectra<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V4,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
JsonGetPayloadResponse::V4(response)
JsonGetPayloadResponse::Electra(response)
.try_into()
.map_err(Error::BadResponse)
}
@@ -994,14 +994,14 @@ impl HttpJsonRpc {
match fork_name {
ForkName::Fulu => {
let response: JsonGetPayloadResponseV5<E> = self
let response: JsonGetPayloadResponseFulu<E> = self
.rpc_request(
ENGINE_GET_PAYLOAD_V5,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
JsonGetPayloadResponse::V5(response)
JsonGetPayloadResponse::Fulu(response)
.try_into()
.map_err(Error::BadResponse)
}
@@ -1135,7 +1135,6 @@ impl HttpJsonRpc {
new_payload_v2: capabilities.contains(ENGINE_NEW_PAYLOAD_V2),
new_payload_v3: capabilities.contains(ENGINE_NEW_PAYLOAD_V3),
new_payload_v4: capabilities.contains(ENGINE_NEW_PAYLOAD_V4),
new_payload_v5: capabilities.contains(ENGINE_NEW_PAYLOAD_V5),
forkchoice_updated_v1: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V1),
forkchoice_updated_v2: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V2),
forkchoice_updated_v3: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V3),
@@ -1501,10 +1500,11 @@ mod test {
fn encode_transactions<E: EthSpec>(
transactions: Transactions<E>,
) -> Result<serde_json::Value, serde_json::Error> {
let ep: JsonExecutionPayload<E> = JsonExecutionPayload::V1(JsonExecutionPayloadV1 {
transactions,
..<_>::default()
});
let ep: JsonExecutionPayload<E> =
JsonExecutionPayload::Bellatrix(JsonExecutionPayloadBellatrix {
transactions,
..<_>::default()
});
let json = serde_json::to_value(ep)?;
Ok(json.get("transactions").unwrap().clone())
}

View File

@@ -65,7 +65,7 @@ pub struct JsonPayloadIdResponse {
}
#[superstruct(
variants(V1, V2, V3, V4, V5),
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
variant_attributes(
derive(Debug, PartialEq, Default, Serialize, Deserialize,),
serde(bound = "E: EthSpec", rename_all = "camelCase"),
@@ -100,19 +100,19 @@ pub struct JsonExecutionPayload<E: EthSpec> {
pub block_hash: ExecutionBlockHash,
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
pub transactions: Transactions<E>,
#[superstruct(only(V2, V3, V4, V5))]
#[superstruct(only(Capella, Deneb, Electra, Fulu))]
pub withdrawals: VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>,
#[superstruct(only(V3, V4, V5))]
#[superstruct(only(Deneb, Electra, Fulu))]
#[serde(with = "serde_utils::u64_hex_be")]
pub blob_gas_used: u64,
#[superstruct(only(V3, V4, V5))]
#[superstruct(only(Deneb, Electra, Fulu))]
#[serde(with = "serde_utils::u64_hex_be")]
pub excess_blob_gas: u64,
}
impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadV1<E> {
impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadBellatrix<E> {
fn from(payload: ExecutionPayloadBellatrix<E>) -> Self {
JsonExecutionPayloadV1 {
JsonExecutionPayloadBellatrix {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
@@ -130,9 +130,9 @@ impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadV1<E
}
}
}
impl<E: EthSpec> From<ExecutionPayloadCapella<E>> for JsonExecutionPayloadV2<E> {
impl<E: EthSpec> From<ExecutionPayloadCapella<E>> for JsonExecutionPayloadCapella<E> {
fn from(payload: ExecutionPayloadCapella<E>) -> Self {
JsonExecutionPayloadV2 {
JsonExecutionPayloadCapella {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
@@ -156,9 +156,9 @@ impl<E: EthSpec> From<ExecutionPayloadCapella<E>> for JsonExecutionPayloadV2<E>
}
}
}
impl<E: EthSpec> From<ExecutionPayloadDeneb<E>> for JsonExecutionPayloadV3<E> {
impl<E: EthSpec> From<ExecutionPayloadDeneb<E>> for JsonExecutionPayloadDeneb<E> {
fn from(payload: ExecutionPayloadDeneb<E>) -> Self {
JsonExecutionPayloadV3 {
JsonExecutionPayloadDeneb {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
@@ -185,9 +185,9 @@ impl<E: EthSpec> From<ExecutionPayloadDeneb<E>> for JsonExecutionPayloadV3<E> {
}
}
impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E> {
impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadElectra<E> {
fn from(payload: ExecutionPayloadElectra<E>) -> Self {
JsonExecutionPayloadV4 {
JsonExecutionPayloadElectra {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
@@ -214,9 +214,9 @@ impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E>
}
}
impl<E: EthSpec> From<ExecutionPayloadFulu<E>> for JsonExecutionPayloadV5<E> {
impl<E: EthSpec> From<ExecutionPayloadFulu<E>> for JsonExecutionPayloadFulu<E> {
fn from(payload: ExecutionPayloadFulu<E>) -> Self {
JsonExecutionPayloadV5 {
JsonExecutionPayloadFulu {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
@@ -246,17 +246,17 @@ impl<E: EthSpec> From<ExecutionPayloadFulu<E>> for JsonExecutionPayloadV5<E> {
impl<E: EthSpec> From<ExecutionPayload<E>> for JsonExecutionPayload<E> {
fn from(execution_payload: ExecutionPayload<E>) -> Self {
match execution_payload {
ExecutionPayload::Bellatrix(payload) => JsonExecutionPayload::V1(payload.into()),
ExecutionPayload::Capella(payload) => JsonExecutionPayload::V2(payload.into()),
ExecutionPayload::Deneb(payload) => JsonExecutionPayload::V3(payload.into()),
ExecutionPayload::Electra(payload) => JsonExecutionPayload::V4(payload.into()),
ExecutionPayload::Fulu(payload) => JsonExecutionPayload::V5(payload.into()),
ExecutionPayload::Bellatrix(payload) => JsonExecutionPayload::Bellatrix(payload.into()),
ExecutionPayload::Capella(payload) => JsonExecutionPayload::Capella(payload.into()),
ExecutionPayload::Deneb(payload) => JsonExecutionPayload::Deneb(payload.into()),
ExecutionPayload::Electra(payload) => JsonExecutionPayload::Electra(payload.into()),
ExecutionPayload::Fulu(payload) => JsonExecutionPayload::Fulu(payload.into()),
}
}
}
impl<E: EthSpec> From<JsonExecutionPayloadV1<E>> for ExecutionPayloadBellatrix<E> {
fn from(payload: JsonExecutionPayloadV1<E>) -> Self {
impl<E: EthSpec> From<JsonExecutionPayloadBellatrix<E>> for ExecutionPayloadBellatrix<E> {
fn from(payload: JsonExecutionPayloadBellatrix<E>) -> Self {
ExecutionPayloadBellatrix {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
@@ -275,8 +275,8 @@ impl<E: EthSpec> From<JsonExecutionPayloadV1<E>> for ExecutionPayloadBellatrix<E
}
}
}
impl<E: EthSpec> From<JsonExecutionPayloadV2<E>> for ExecutionPayloadCapella<E> {
fn from(payload: JsonExecutionPayloadV2<E>) -> Self {
impl<E: EthSpec> From<JsonExecutionPayloadCapella<E>> for ExecutionPayloadCapella<E> {
fn from(payload: JsonExecutionPayloadCapella<E>) -> Self {
ExecutionPayloadCapella {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
@@ -302,8 +302,8 @@ impl<E: EthSpec> From<JsonExecutionPayloadV2<E>> for ExecutionPayloadCapella<E>
}
}
impl<E: EthSpec> From<JsonExecutionPayloadV3<E>> for ExecutionPayloadDeneb<E> {
fn from(payload: JsonExecutionPayloadV3<E>) -> Self {
impl<E: EthSpec> From<JsonExecutionPayloadDeneb<E>> for ExecutionPayloadDeneb<E> {
fn from(payload: JsonExecutionPayloadDeneb<E>) -> Self {
ExecutionPayloadDeneb {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
@@ -331,8 +331,8 @@ impl<E: EthSpec> From<JsonExecutionPayloadV3<E>> for ExecutionPayloadDeneb<E> {
}
}
impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E> {
fn from(payload: JsonExecutionPayloadV4<E>) -> Self {
impl<E: EthSpec> From<JsonExecutionPayloadElectra<E>> for ExecutionPayloadElectra<E> {
fn from(payload: JsonExecutionPayloadElectra<E>) -> Self {
ExecutionPayloadElectra {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
@@ -360,8 +360,8 @@ impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E>
}
}
impl<E: EthSpec> From<JsonExecutionPayloadV5<E>> for ExecutionPayloadFulu<E> {
fn from(payload: JsonExecutionPayloadV5<E>) -> Self {
impl<E: EthSpec> From<JsonExecutionPayloadFulu<E>> for ExecutionPayloadFulu<E> {
fn from(payload: JsonExecutionPayloadFulu<E>) -> Self {
ExecutionPayloadFulu {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
@@ -392,11 +392,11 @@ impl<E: EthSpec> From<JsonExecutionPayloadV5<E>> for ExecutionPayloadFulu<E> {
impl<E: EthSpec> From<JsonExecutionPayload<E>> for ExecutionPayload<E> {
fn from(json_execution_payload: JsonExecutionPayload<E>) -> Self {
match json_execution_payload {
JsonExecutionPayload::V1(payload) => ExecutionPayload::Bellatrix(payload.into()),
JsonExecutionPayload::V2(payload) => ExecutionPayload::Capella(payload.into()),
JsonExecutionPayload::V3(payload) => ExecutionPayload::Deneb(payload.into()),
JsonExecutionPayload::V4(payload) => ExecutionPayload::Electra(payload.into()),
JsonExecutionPayload::V5(payload) => ExecutionPayload::Fulu(payload.into()),
JsonExecutionPayload::Bellatrix(payload) => ExecutionPayload::Bellatrix(payload.into()),
JsonExecutionPayload::Capella(payload) => ExecutionPayload::Capella(payload.into()),
JsonExecutionPayload::Deneb(payload) => ExecutionPayload::Deneb(payload.into()),
JsonExecutionPayload::Electra(payload) => ExecutionPayload::Electra(payload.into()),
JsonExecutionPayload::Fulu(payload) => ExecutionPayload::Fulu(payload.into()),
}
}
}
@@ -482,7 +482,7 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
}
#[superstruct(
variants(V1, V2, V3, V4, V5),
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
variant_attributes(
derive(Debug, PartialEq, Serialize, Deserialize),
serde(bound = "E: EthSpec", rename_all = "camelCase")
@@ -493,23 +493,26 @@ impl<E: EthSpec> TryFrom<JsonExecutionRequests> for ExecutionRequests<E> {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub struct JsonGetPayloadResponse<E: EthSpec> {
#[superstruct(only(V1), partial_getter(rename = "execution_payload_v1"))]
pub execution_payload: JsonExecutionPayloadV1<E>,
#[superstruct(only(V2), partial_getter(rename = "execution_payload_v2"))]
pub execution_payload: JsonExecutionPayloadV2<E>,
#[superstruct(only(V3), partial_getter(rename = "execution_payload_v3"))]
pub execution_payload: JsonExecutionPayloadV3<E>,
#[superstruct(only(V4), partial_getter(rename = "execution_payload_v4"))]
pub execution_payload: JsonExecutionPayloadV4<E>,
#[superstruct(only(V5), partial_getter(rename = "execution_payload_v5"))]
pub execution_payload: JsonExecutionPayloadV5<E>,
#[superstruct(
only(Bellatrix),
partial_getter(rename = "execution_payload_bellatrix")
)]
pub execution_payload: JsonExecutionPayloadBellatrix<E>,
#[superstruct(only(Capella), partial_getter(rename = "execution_payload_capella"))]
pub execution_payload: JsonExecutionPayloadCapella<E>,
#[superstruct(only(Deneb), partial_getter(rename = "execution_payload_deneb"))]
pub execution_payload: JsonExecutionPayloadDeneb<E>,
#[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))]
pub execution_payload: JsonExecutionPayloadElectra<E>,
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
pub execution_payload: JsonExecutionPayloadFulu<E>,
#[serde(with = "serde_utils::u256_hex_be")]
pub block_value: Uint256,
#[superstruct(only(V3, V4, V5))]
#[superstruct(only(Deneb, Electra, Fulu))]
pub blobs_bundle: JsonBlobsBundleV1<E>,
#[superstruct(only(V3, V4, V5))]
#[superstruct(only(Deneb, Electra, Fulu))]
pub should_override_builder: bool,
#[superstruct(only(V4, V5))]
#[superstruct(only(Electra, Fulu))]
pub execution_requests: JsonExecutionRequests,
}
@@ -517,19 +520,19 @@ 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) => {
JsonGetPayloadResponse::Bellatrix(response) => {
Ok(GetPayloadResponse::Bellatrix(GetPayloadResponseBellatrix {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
}))
}
JsonGetPayloadResponse::V2(response) => {
JsonGetPayloadResponse::Capella(response) => {
Ok(GetPayloadResponse::Capella(GetPayloadResponseCapella {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
}))
}
JsonGetPayloadResponse::V3(response) => {
JsonGetPayloadResponse::Deneb(response) => {
Ok(GetPayloadResponse::Deneb(GetPayloadResponseDeneb {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
@@ -537,7 +540,7 @@ impl<E: EthSpec> TryFrom<JsonGetPayloadResponse<E>> for GetPayloadResponse<E> {
should_override_builder: response.should_override_builder,
}))
}
JsonGetPayloadResponse::V4(response) => {
JsonGetPayloadResponse::Electra(response) => {
Ok(GetPayloadResponse::Electra(GetPayloadResponseElectra {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,
@@ -548,7 +551,7 @@ impl<E: EthSpec> TryFrom<JsonGetPayloadResponse<E>> for GetPayloadResponse<E> {
})?,
}))
}
JsonGetPayloadResponse::V5(response) => {
JsonGetPayloadResponse::Fulu(response) => {
Ok(GetPayloadResponse::Fulu(GetPayloadResponseFulu {
execution_payload: response.execution_payload.into(),
block_value: response.block_value,

View File

@@ -99,31 +99,28 @@ pub async fn handle_rpc<E: EthSpec>(
ENGINE_NEW_PAYLOAD_V1
| ENGINE_NEW_PAYLOAD_V2
| ENGINE_NEW_PAYLOAD_V3
| ENGINE_NEW_PAYLOAD_V4
| ENGINE_NEW_PAYLOAD_V5 => {
| ENGINE_NEW_PAYLOAD_V4 => {
let request = match method {
ENGINE_NEW_PAYLOAD_V1 => JsonExecutionPayload::V1(
get_param::<JsonExecutionPayloadV1<E>>(params, 0)
ENGINE_NEW_PAYLOAD_V1 => JsonExecutionPayload::Bellatrix(
get_param::<JsonExecutionPayloadBellatrix<E>>(params, 0)
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
),
ENGINE_NEW_PAYLOAD_V2 => get_param::<JsonExecutionPayloadV2<E>>(params, 0)
.map(|jep| JsonExecutionPayload::V2(jep))
ENGINE_NEW_PAYLOAD_V2 => get_param::<JsonExecutionPayloadCapella<E>>(params, 0)
.map(|jep| JsonExecutionPayload::Capella(jep))
.or_else(|_| {
get_param::<JsonExecutionPayloadV1<E>>(params, 0)
.map(|jep| JsonExecutionPayload::V1(jep))
get_param::<JsonExecutionPayloadBellatrix<E>>(params, 0)
.map(|jep| JsonExecutionPayload::Bellatrix(jep))
})
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
// From v3 onwards, we use the newPayload version only for the corresponding
// ExecutionPayload version. So we return an error instead of falling back to
// older versions of newPayload
ENGINE_NEW_PAYLOAD_V3 => get_param::<JsonExecutionPayloadV3<E>>(params, 0)
.map(|jep| JsonExecutionPayload::V3(jep))
ENGINE_NEW_PAYLOAD_V3 => get_param::<JsonExecutionPayloadDeneb<E>>(params, 0)
.map(|jep| JsonExecutionPayload::Deneb(jep))
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
ENGINE_NEW_PAYLOAD_V4 => get_param::<JsonExecutionPayloadV4<E>>(params, 0)
.map(|jep| JsonExecutionPayload::V4(jep))
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
ENGINE_NEW_PAYLOAD_V5 => get_param::<JsonExecutionPayloadV5<E>>(params, 0)
.map(|jep| JsonExecutionPayload::V5(jep))
ENGINE_NEW_PAYLOAD_V4 => get_param::<JsonExecutionPayloadFulu<E>>(params, 0)
.map(|jep| JsonExecutionPayload::Fulu(jep))
.or_else(|_| {
get_param::<JsonExecutionPayloadElectra<E>>(params, 0)
.map(|jep| JsonExecutionPayload::Electra(jep))
})
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
_ => unreachable!(),
};
@@ -135,10 +132,10 @@ pub async fn handle_rpc<E: EthSpec>(
// validate method called correctly according to fork time
match fork {
ForkName::Bellatrix => {
if matches!(request, JsonExecutionPayload::V2(_)) {
if matches!(request, JsonExecutionPayload::Capella(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV2` before Capella fork!",
"{} called with `ExecutionPayloadCapella` before Capella fork!",
method
),
GENERIC_ERROR_CODE,
@@ -152,10 +149,10 @@ pub async fn handle_rpc<E: EthSpec>(
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V1(_)) {
if matches!(request, JsonExecutionPayload::Bellatrix(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV1` after Capella fork!",
"{} called with `ExecutionPayloadBellatrix` after Capella fork!",
method
),
GENERIC_ERROR_CODE,
@@ -169,7 +166,7 @@ pub async fn handle_rpc<E: EthSpec>(
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V1(_)) {
if matches!(request, JsonExecutionPayload::Bellatrix(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV1` after Deneb fork!",
@@ -178,7 +175,7 @@ pub async fn handle_rpc<E: EthSpec>(
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V2(_)) {
if matches!(request, JsonExecutionPayload::Capella(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV2` after Deneb fork!",
@@ -188,7 +185,7 @@ pub async fn handle_rpc<E: EthSpec>(
));
}
}
ForkName::Electra => {
ForkName::Electra | ForkName::Fulu => {
if method == ENGINE_NEW_PAYLOAD_V1
|| method == ENGINE_NEW_PAYLOAD_V2
|| method == ENGINE_NEW_PAYLOAD_V3
@@ -198,66 +195,28 @@ pub async fn handle_rpc<E: EthSpec>(
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V1(_)) {
if matches!(request, JsonExecutionPayload::Bellatrix(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV1` after Electra fork!",
"{} called with `ExecutionPayloadBellatrix after Electra fork!",
method
),
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V2(_)) {
if matches!(request, JsonExecutionPayload::Capella(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV2` after Electra fork!",
"{} called with `ExecutionPayloadCapella` after Electra fork!",
method
),
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V3(_)) {
if matches!(request, JsonExecutionPayload::Deneb(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV3` after Electra fork!",
method
),
GENERIC_ERROR_CODE,
));
}
}
ForkName::Fulu => {
if method == ENGINE_NEW_PAYLOAD_V1
|| method == ENGINE_NEW_PAYLOAD_V2
|| method == ENGINE_NEW_PAYLOAD_V3
{
return Err((
format!("{} called after Fulu fork!", method),
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V1(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV1` after Fulu fork!",
method
),
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V2(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV2` after Fulu fork!",
method
),
GENERIC_ERROR_CODE,
));
}
if matches!(request, JsonExecutionPayload::V3(_)) {
return Err((
format!(
"{} called with `ExecutionPayloadV3` after Fulu fork!",
"{} called with `ExecutionPayloadDeneb` after Electra fork!",
method
),
GENERIC_ERROR_CODE,
@@ -385,15 +344,15 @@ pub async fn handle_rpc<E: EthSpec>(
Ok(serde_json::to_value(JsonExecutionPayload::from(response)).unwrap())
}
ENGINE_GET_PAYLOAD_V2 => Ok(match JsonExecutionPayload::from(response) {
JsonExecutionPayload::V1(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseV1 {
JsonExecutionPayload::Bellatrix(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseBellatrix {
execution_payload,
block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI),
})
.unwrap()
}
JsonExecutionPayload::V2(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseV2 {
JsonExecutionPayload::Capella(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseCapella {
execution_payload,
block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI),
})
@@ -405,8 +364,8 @@ pub async fn handle_rpc<E: EthSpec>(
// ExecutionPayload version. So we return an error if the ExecutionPayload version
// we get does not correspond to the getPayload version.
ENGINE_GET_PAYLOAD_V3 => Ok(match JsonExecutionPayload::from(response) {
JsonExecutionPayload::V3(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseV3 {
JsonExecutionPayload::Deneb(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseDeneb {
execution_payload,
block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI),
blobs_bundle: maybe_blobs
@@ -422,8 +381,8 @@ pub async fn handle_rpc<E: EthSpec>(
_ => unreachable!(),
}),
ENGINE_GET_PAYLOAD_V4 => Ok(match JsonExecutionPayload::from(response) {
JsonExecutionPayload::V4(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseV4 {
JsonExecutionPayload::Electra(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseElectra {
execution_payload,
block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI),
blobs_bundle: maybe_blobs
@@ -441,8 +400,8 @@ pub async fn handle_rpc<E: EthSpec>(
_ => unreachable!(),
}),
ENGINE_GET_PAYLOAD_V5 => Ok(match JsonExecutionPayload::from(response) {
JsonExecutionPayload::V5(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseV5 {
JsonExecutionPayload::Fulu(execution_payload) => {
serde_json::to_value(JsonGetPayloadResponseFulu {
execution_payload,
block_value: Uint256::from(DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI),
blobs_bundle: maybe_blobs

View File

@@ -45,7 +45,6 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
new_payload_v2: true,
new_payload_v3: true,
new_payload_v4: true,
new_payload_v5: true,
forkchoice_updated_v1: true,
forkchoice_updated_v2: true,
forkchoice_updated_v3: true,