mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 03:12:41 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user