chore(payload): Custom PayloadError variant (#14607)

This commit is contained in:
Emilia Hane
2025-02-20 12:45:34 +01:00
committed by GitHub
parent 246a9ffb20
commit f03e7e02f7
7 changed files with 64 additions and 25 deletions

View File

@ -14,11 +14,11 @@ extern crate alloc;
use alloy_consensus::BlockHeader; use alloy_consensus::BlockHeader;
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use alloy_primitives::B256; use alloy_primitives::B256;
use alloy_rpc_types_engine::{ExecutionData, PayloadError}; use alloy_rpc_types_engine::ExecutionData;
use core::fmt::{self, Debug}; use core::fmt::{self, Debug};
use reth_payload_primitives::{ use reth_payload_primitives::{
validate_execution_requests, BuiltPayload, EngineApiMessageVersion, validate_execution_requests, BuiltPayload, EngineApiMessageVersion,
EngineObjectValidationError, InvalidPayloadAttributesError, PayloadAttributes, EngineObjectValidationError, InvalidPayloadAttributesError, NewPayloadError, PayloadAttributes,
PayloadOrAttributes, PayloadTypes, PayloadOrAttributes, PayloadTypes,
}; };
use reth_primitives::{NodePrimitives, SealedBlock}; use reth_primitives::{NodePrimitives, SealedBlock};
@ -145,7 +145,7 @@ pub trait PayloadValidator: fmt::Debug + Send + Sync + Unpin + 'static {
fn ensure_well_formed_payload( fn ensure_well_formed_payload(
&self, &self,
payload: Self::ExecutionData, payload: Self::ExecutionData,
) -> Result<SealedBlock<Self::Block>, PayloadError>; ) -> Result<SealedBlock<Self::Block>, NewPayloadError>;
} }
/// Type that validates the payloads processed by the engine. /// Type that validates the payloads processed by the engine.

View File

@ -13,7 +13,7 @@ extern crate alloc;
mod payload; mod payload;
use alloc::sync::Arc; use alloc::sync::Arc;
use alloy_rpc_types_engine::{ExecutionData, ExecutionPayload, PayloadError}; use alloy_rpc_types_engine::{ExecutionData, ExecutionPayload};
pub use alloy_rpc_types_engine::{ pub use alloy_rpc_types_engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4,
ExecutionPayloadV1, PayloadAttributes as EthPayloadAttributes, ExecutionPayloadV1, PayloadAttributes as EthPayloadAttributes,
@ -23,7 +23,7 @@ use reth_chainspec::ChainSpec;
use reth_engine_primitives::{EngineTypes, EngineValidator, PayloadValidator}; use reth_engine_primitives::{EngineTypes, EngineValidator, PayloadValidator};
use reth_payload_primitives::{ use reth_payload_primitives::{
validate_version_specific_fields, BuiltPayload, EngineApiMessageVersion, validate_version_specific_fields, BuiltPayload, EngineApiMessageVersion,
EngineObjectValidationError, PayloadOrAttributes, PayloadTypes, EngineObjectValidationError, NewPayloadError, PayloadOrAttributes, PayloadTypes,
}; };
use reth_payload_validator::ExecutionPayloadValidator; use reth_payload_validator::ExecutionPayloadValidator;
use reth_primitives::{Block, NodePrimitives, SealedBlock}; use reth_primitives::{Block, NodePrimitives, SealedBlock};
@ -104,8 +104,8 @@ impl PayloadValidator for EthereumEngineValidator {
fn ensure_well_formed_payload( fn ensure_well_formed_payload(
&self, &self,
payload: ExecutionData, payload: ExecutionData,
) -> Result<SealedBlock, PayloadError> { ) -> Result<SealedBlock, NewPayloadError> {
self.inner.ensure_well_formed_payload(payload) Ok(self.inner.ensure_well_formed_payload(payload)?)
} }
} }

View File

@ -1,5 +1,5 @@
use alloy_rpc_types_engine::{ use alloy_rpc_types_engine::{
ExecutionData, ExecutionPayload, ExecutionPayloadEnvelopeV2, ExecutionPayloadV1, PayloadError, ExecutionData, ExecutionPayload, ExecutionPayloadEnvelopeV2, ExecutionPayloadV1,
}; };
use op_alloy_rpc_types_engine::{ use op_alloy_rpc_types_engine::{
OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4, OpPayloadAttributes, OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4, OpPayloadAttributes,
@ -8,8 +8,8 @@ use reth_chainspec::ChainSpec;
use reth_node_api::{ use reth_node_api::{
payload::{ payload::{
validate_parent_beacon_block_root_presence, EngineApiMessageVersion, validate_parent_beacon_block_root_presence, EngineApiMessageVersion,
EngineObjectValidationError, MessageValidationKind, PayloadOrAttributes, PayloadTypes, EngineObjectValidationError, MessageValidationKind, NewPayloadError, PayloadOrAttributes,
VersionSpecificValidationError, PayloadTypes, VersionSpecificValidationError,
}, },
validate_version_specific_fields, BuiltPayload, EngineTypes, EngineValidator, NodePrimitives, validate_version_specific_fields, BuiltPayload, EngineTypes, EngineValidator, NodePrimitives,
PayloadValidator, PayloadValidator,
@ -97,8 +97,8 @@ impl PayloadValidator for OpEngineValidator {
fn ensure_well_formed_payload( fn ensure_well_formed_payload(
&self, &self,
payload: ExecutionData, payload: ExecutionData,
) -> Result<SealedBlock<Self::Block>, PayloadError> { ) -> Result<SealedBlock<Self::Block>, NewPayloadError> {
self.inner.ensure_well_formed_payload(payload) Ok(self.inner.ensure_well_formed_payload(payload)?)
} }
} }

View File

@ -1,8 +1,9 @@
//! Error types emitted by types or implementations of this crate. //! Error types emitted by types or implementations of this crate.
use alloc::boxed::Box; use alloc::{boxed::Box, string::ToString};
use alloy_primitives::B256; use alloy_primitives::B256;
use alloy_rpc_types_engine::ForkchoiceUpdateError; use alloy_rpc_types_engine::{ForkchoiceUpdateError, PayloadError, PayloadStatusEnum};
use core::error;
use reth_errors::{ProviderError, RethError}; use reth_errors::{ProviderError, RethError};
use tokio::sync::oneshot; use tokio::sync::oneshot;
@ -115,6 +116,45 @@ pub enum VersionSpecificValidationError {
NoParentBeaconBlockRootPostCancun, NoParentBeaconBlockRootPostCancun,
} }
/// Error validating payload received over `newPayload` API.
#[derive(thiserror::Error, Debug)]
pub enum NewPayloadError {
/// Payload validation error.
#[error(transparent)]
Eth(#[from] PayloadError),
/// Custom payload validation error.
#[error(transparent)]
Other(Box<dyn error::Error + Send + Sync>),
}
impl NewPayloadError {
/// Creates instance of variant [`NewPayloadError::Other`].
#[inline]
pub const fn other(err: Box<dyn error::Error + Send + Sync>) -> Self {
Self::Other(err)
}
}
impl NewPayloadError {
/// Returns `true` if the error is caused by a block hash mismatch.
#[inline]
pub const fn is_block_hash_mismatch(&self) -> bool {
matches!(self, Self::Eth(PayloadError::BlockHash { .. }))
}
/// Returns `true` if the error is caused by invalid block hashes (Cancun).
#[inline]
pub const fn is_invalid_versioned_hashes(&self) -> bool {
matches!(self, Self::Eth(PayloadError::InvalidVersionedHashes))
}
}
impl From<NewPayloadError> for PayloadStatusEnum {
fn from(error: NewPayloadError) -> Self {
Self::Invalid { validation_error: error.to_string() }
}
}
impl EngineObjectValidationError { impl EngineObjectValidationError {
/// Creates an instance of the `InvalidParams` variant with the given error. /// Creates an instance of the `InvalidParams` variant with the given error.
pub fn invalid_params<E>(error: E) -> Self pub fn invalid_params<E>(error: E) -> Self

View File

@ -17,8 +17,8 @@ use reth_chainspec::EthereumHardforks;
mod error; mod error;
pub use error::{ pub use error::{
EngineObjectValidationError, InvalidPayloadAttributesError, PayloadBuilderError, EngineObjectValidationError, InvalidPayloadAttributesError, NewPayloadError,
VersionSpecificValidationError, PayloadBuilderError, VersionSpecificValidationError,
}; };
/// Contains traits to abstract over payload attributes types and default implementations of the /// Contains traits to abstract over payload attributes types and default implementations of the

View File

@ -8,7 +8,7 @@ use alloy_rpc_types_beacon::relay::{
}; };
use alloy_rpc_types_engine::{ use alloy_rpc_types_engine::{
BlobsBundleV1, CancunPayloadFields, ExecutionData, ExecutionPayload, ExecutionPayloadSidecar, BlobsBundleV1, CancunPayloadFields, ExecutionData, ExecutionPayload, ExecutionPayloadSidecar,
PayloadError, PraguePayloadFields, PraguePayloadFields,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use jsonrpsee::core::RpcResult; use jsonrpsee::core::RpcResult;
@ -18,6 +18,7 @@ use reth_engine_primitives::PayloadValidator;
use reth_errors::{BlockExecutionError, ConsensusError, ProviderError}; use reth_errors::{BlockExecutionError, ConsensusError, ProviderError};
use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_evm::execute::{BlockExecutorProvider, Executor};
use reth_metrics::{metrics, metrics::Gauge, Metrics}; use reth_metrics::{metrics, metrics::Gauge, Metrics};
use reth_node_api::NewPayloadError;
use reth_primitives::{GotExpected, NodePrimitives, RecoveredBlock}; use reth_primitives::{GotExpected, NodePrimitives, RecoveredBlock};
use reth_primitives_traits::{ use reth_primitives_traits::{
constants::GAS_LIMIT_BOUND_DIVISOR, BlockBody, SealedBlock, SealedHeaderFor, constants::GAS_LIMIT_BOUND_DIVISOR, BlockBody, SealedBlock, SealedHeaderFor,
@ -555,7 +556,7 @@ pub enum ValidationApiError {
#[error(transparent)] #[error(transparent)]
Execution(#[from] BlockExecutionError), Execution(#[from] BlockExecutionError),
#[error(transparent)] #[error(transparent)]
Payload(#[from] PayloadError), Payload(#[from] NewPayloadError),
} }
/// Metrics for the validation endpoint. /// Metrics for the validation endpoint.

View File

@ -40,10 +40,7 @@ use reth::{
payload::ExecutionPayloadValidator, payload::ExecutionPayloadValidator,
primitives::{Block, EthPrimitives, SealedBlock, TransactionSigned}, primitives::{Block, EthPrimitives, SealedBlock, TransactionSigned},
providers::{EthStorage, StateProviderFactory}, providers::{EthStorage, StateProviderFactory},
rpc::{ rpc::{eth::EthApi, types::engine::ExecutionPayload},
eth::EthApi,
types::engine::{ExecutionPayload, PayloadError},
},
tasks::TaskManager, tasks::TaskManager,
transaction_pool::{PoolTransaction, TransactionPool}, transaction_pool::{PoolTransaction, TransactionPool},
version::default_extra_data_bytes, version::default_extra_data_bytes,
@ -55,7 +52,8 @@ use reth_ethereum_payload_builder::EthereumBuilderConfig;
use reth_node_api::{ use reth_node_api::{
payload::{EngineApiMessageVersion, EngineObjectValidationError, PayloadOrAttributes}, payload::{EngineApiMessageVersion, EngineObjectValidationError, PayloadOrAttributes},
validate_version_specific_fields, AddOnsContext, EngineTypes, EngineValidator, validate_version_specific_fields, AddOnsContext, EngineTypes, EngineValidator,
FullNodeComponents, PayloadAttributes, PayloadBuilderAttributes, PayloadValidator, FullNodeComponents, NewPayloadError, PayloadAttributes, PayloadBuilderAttributes,
PayloadValidator,
}; };
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::{ use reth_node_ethereum::{
@ -207,8 +205,8 @@ impl PayloadValidator for CustomEngineValidator {
fn ensure_well_formed_payload( fn ensure_well_formed_payload(
&self, &self,
payload: ExecutionData, payload: ExecutionData,
) -> Result<SealedBlock<Self::Block>, PayloadError> { ) -> Result<SealedBlock<Self::Block>, NewPayloadError> {
self.inner.ensure_well_formed_payload(payload) Ok(self.inner.ensure_well_formed_payload(payload)?)
} }
} }