fix: return UnsupportedFork on V2 endpoints (#4593)

This commit is contained in:
Dan Cline
2023-09-15 15:11:56 -04:00
committed by GitHub
parent 873b6f71d8
commit 357301cc29

View File

@ -188,6 +188,18 @@ where
&self,
payload_id: PayloadId,
) -> EngineApiResult<ExecutionPayloadEnvelopeV2> {
// First we fetch the payload attributes to check the timestamp
let attributes = self
.inner
.payload_store
.payload_attributes(payload_id)
.await
.ok_or(EngineApiError::UnknownPayload)??;
// validate timestamp according to engine rules
self.validate_payload_timestamp(EngineApiMessageVersion::V2, attributes.timestamp)?;
// Now resolve the payload
Ok(self
.inner
.payload_store
@ -216,14 +228,8 @@ where
.await
.ok_or(EngineApiError::UnknownPayload)??;
// From the Engine API spec:
// <https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/cancun.md#specification-2>
//
// 1. Client software **MUST** return `-38005: Unsupported fork` error if the `timestamp` of
// the built payload does not fall within the time frame of the Cancun fork.
if !self.inner.chain_spec.is_cancun_activated_at_timestamp(attributes.timestamp) {
return Err(EngineApiError::UnsupportedFork)
}
// validate timestamp according to engine rules
self.validate_payload_timestamp(EngineApiMessageVersion::V3, attributes.timestamp)?;
// Now resolve the payload
Ok(self
@ -376,6 +382,52 @@ where
}
}
/// Validates the timestamp depending on the version called:
///
/// * If V2, this ensure that the payload timestamp is pre-Cancun.
/// * If V3, this ensures that the payload timestamp is within the Cancun timestamp.
///
/// Otherwise, this will return [EngineApiError::UnsupportedFork].
fn validate_payload_timestamp(
&self,
version: EngineApiMessageVersion,
timestamp: u64,
) -> EngineApiResult<()> {
let is_cancun = self.inner.chain_spec.is_cancun_activated_at_timestamp(timestamp);
if version == EngineApiMessageVersion::V2 && is_cancun {
// From the Engine API spec:
//
// ### Update the methods of previous forks
//
// This document defines how Cancun payload should be handled by the [`Shanghai
// API`](https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/shanghai.md).
//
// For the following methods:
//
// - [`engine_forkchoiceUpdatedV2`](https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/shanghai.md#engine_forkchoiceupdatedv2)
// - [`engine_newPayloadV2`](https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/shanghai.md#engine_newpayloadV2)
// - [`engine_getPayloadV2`](https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/shanghai.md#engine_getpayloadv2)
//
// a validation **MUST** be added:
//
// 1. Client software **MUST** return `-38005: Unsupported fork` error if the
// `timestamp` of payload or payloadAttributes greater or equal to the Cancun
// activation timestamp.
return Err(EngineApiError::UnsupportedFork)
}
if version == EngineApiMessageVersion::V3 && !is_cancun {
// From the Engine API spec:
// <https://github.com/ethereum/execution-apis/blob/ff43500e653abde45aec0f545564abfb648317af/src/engine/cancun.md#specification-2>
//
// 1. Client software **MUST** return `-38005: Unsupported fork` error if the
// `timestamp` of the built payload does not fall within the time frame of the Cancun
// fork.
return Err(EngineApiError::UnsupportedFork)
}
Ok(())
}
/// Validates the presence of the `withdrawals` field according to the payload timestamp.
/// After Shanghai, withdrawals field must be [Some].
/// Before Shanghai, withdrawals field must be [None];
@ -417,14 +469,14 @@ where
/// Before Cancun, `parentBeaconBlockRoot` field must be [None].
///
/// If the engine API message version is V1 or V2, and the payload attribute's timestamp is
/// post-Cancun, then this will return [EngineApiError::NoParentBeaconBlockRootPostCancun].
///
/// If the engine API message version is V3, but the `parentBeaconBlockRoot` is [None], then
/// this will return [EngineApiError::NoParentBeaconBlockRootPostCancun].
/// post-Cancun, then this will return [EngineApiError::UnsupportedFork].
///
/// If the payload attribute's timestamp is before the Cancun fork and the engine API message
/// version is V3, then this will return [EngineApiError::UnsupportedFork].
///
/// If the engine API message version is V3, but the `parentBeaconBlockRoot` is [None], then
/// this will return [EngineApiError::NoParentBeaconBlockRootPostCancun].
///
/// This implements the following Engine API spec rules:
///
/// 1. Client software **MUST** check that provided set of parameters and their fields strictly
@ -440,26 +492,27 @@ where
timestamp: u64,
has_parent_beacon_block_root: bool,
) -> EngineApiResult<()> {
let is_cancun = self.inner.chain_spec.fork(Hardfork::Cancun).active_at_timestamp(timestamp);
// 1. Client software **MUST** check that provided set of parameters and their fields
// strictly matches the expected one and return `-32602: Invalid params` error if this
// check fails. Any field having `null` value **MUST** be considered as not provided.
match version {
EngineApiMessageVersion::V1 | EngineApiMessageVersion::V2 => {
if has_parent_beacon_block_root {
return Err(EngineApiError::ParentBeaconBlockRootNotSupportedBeforeV3)
}
if is_cancun {
return Err(EngineApiError::NoParentBeaconBlockRootPostCancun)
}
}
EngineApiMessageVersion::V3 => {
if !has_parent_beacon_block_root {
return Err(EngineApiError::NoParentBeaconBlockRootPostCancun)
} else if !is_cancun {
return Err(EngineApiError::UnsupportedFork)
}
}
};
// 2. Client software **MUST** return `-38005: Unsupported fork` error if the
// `payloadAttributes` is set and the `payloadAttributes.timestamp` does not fall within
// the time frame of the Cancun fork.
self.validate_payload_timestamp(version, timestamp)?;
Ok(())
}