diff --git a/Cargo.lock b/Cargo.lock index ccdc8abdf..fc472c9a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7156,6 +7156,7 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", + "auto_impl", "futures", "reth-errors", "reth-execution-types", diff --git a/crates/engine/primitives/Cargo.toml b/crates/engine/primitives/Cargo.toml index 2e9e020a9..13ac36129 100644 --- a/crates/engine/primitives/Cargo.toml +++ b/crates/engine/primitives/Cargo.toml @@ -31,6 +31,7 @@ tokio = { workspace = true, features = ["sync"] } futures.workspace = true # misc +auto_impl.workspace = true serde.workspace = true thiserror.workspace = true diff --git a/crates/engine/primitives/src/lib.rs b/crates/engine/primitives/src/lib.rs index f8ddaf0ec..708c83d33 100644 --- a/crates/engine/primitives/src/lib.rs +++ b/crates/engine/primitives/src/lib.rs @@ -15,10 +15,10 @@ use alloy_primitives::B256; use reth_payload_primitives::{BuiltPayload, PayloadAttributes}; mod error; -use core::fmt; +use core::fmt::{self, Debug}; use alloy_consensus::BlockHeader; -use alloy_rpc_types_engine::{ExecutionPayload, ExecutionPayloadSidecar, PayloadError}; +use alloy_rpc_types_engine::{ExecutionPayloadSidecar, PayloadError}; pub use error::*; mod forkchoice; @@ -42,37 +42,25 @@ use reth_primitives::{NodePrimitives, SealedBlock}; use reth_primitives_traits::Block; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -/// Struct aggregating [`ExecutionPayload`] and [`ExecutionPayloadSidecar`] and encapsulating -/// complete payload supplied for execution. +/// Struct aggregating [`alloy_rpc_types_engine::ExecutionPayload`] and [`ExecutionPayloadSidecar`] +/// and encapsulating complete payload supplied for execution. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionData { /// Execution payload. - pub payload: ExecutionPayload, + pub payload: alloy_rpc_types_engine::ExecutionPayload, /// Additional fork-specific fields. pub sidecar: ExecutionPayloadSidecar, } impl ExecutionData { /// Creates new instance of [`ExecutionData`]. - pub const fn new(payload: ExecutionPayload, sidecar: ExecutionPayloadSidecar) -> Self { + pub const fn new( + payload: alloy_rpc_types_engine::ExecutionPayload, + sidecar: ExecutionPayloadSidecar, + ) -> Self { Self { payload, sidecar } } - /// Returns the parent hash of the block. - pub fn parent_hash(&self) -> B256 { - self.payload.parent_hash() - } - - /// Returns the hash of the block. - pub fn block_hash(&self) -> B256 { - self.payload.block_hash() - } - - /// Returns the number of the block. - pub fn block_number(&self) -> u64 { - self.payload.block_number() - } - /// Tries to create a new unsealed block from the given payload and payload sidecar. /// /// Performs additional validation of `extra_data` and `base_fee_per_gas` fields. @@ -89,6 +77,34 @@ impl ExecutionData { } } +/// An execution payload. +pub trait ExecutionPayload: + Serialize + DeserializeOwned + Debug + Clone + Send + Sync + 'static +{ + /// Returns the parent hash of the block. + fn parent_hash(&self) -> B256; + + /// Returns the hash of the block. + fn block_hash(&self) -> B256; + + /// Returns the number of the block. + fn block_number(&self) -> u64; +} + +impl ExecutionPayload for ExecutionData { + fn parent_hash(&self) -> B256 { + self.payload.parent_hash() + } + + fn block_hash(&self) -> B256 { + self.payload.block_hash() + } + + fn block_number(&self) -> u64 { + self.payload.block_number() + } +} + /// This type defines the versioned types of the engine API. /// /// This includes the execution payload types and payload attributes that are used to trigger a @@ -135,20 +151,26 @@ pub trait EngineTypes: + Send + Sync + 'static; + /// Execution data. + type ExecutionData: ExecutionPayload; /// Converts a [`BuiltPayload`] into an [`ExecutionPayload`] and [`ExecutionPayloadSidecar`]. fn block_to_payload( block: SealedBlock< <::Primitives as NodePrimitives>::Block, >, - ) -> ExecutionData; + ) -> Self::ExecutionData; } /// Type that validates an [`ExecutionPayload`]. +#[auto_impl::auto_impl(&, Arc)] pub trait PayloadValidator: fmt::Debug + Send + Sync + Unpin + 'static { /// The block type used by the engine. type Block: Block; + /// The execution payload type used by the engine. + type ExecutionData; + /// Ensures that the given payload does not violate any consensus rules that concern the block's /// layout. /// @@ -159,12 +181,14 @@ pub trait PayloadValidator: fmt::Debug + Send + Sync + Unpin + 'static { /// engine-API specification. fn ensure_well_formed_payload( &self, - payload: ExecutionData, + payload: Self::ExecutionData, ) -> Result, PayloadError>; } /// Type that validates the payloads processed by the engine. -pub trait EngineValidator: PayloadValidator { +pub trait EngineValidator: + PayloadValidator +{ /// Validates the execution requests according to [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685). fn validate_execution_requests( &self, diff --git a/crates/engine/primitives/src/message.rs b/crates/engine/primitives/src/message.rs index 9dbe01a1e..cc9073352 100644 --- a/crates/engine/primitives/src/message.rs +++ b/crates/engine/primitives/src/message.rs @@ -1,6 +1,6 @@ use crate::{ error::BeaconForkChoiceUpdateError, BeaconOnNewPayloadError, EngineApiMessageVersion, - EngineTypes, ExecutionData, ForkchoiceStatus, + EngineTypes, ExecutionPayload, ForkchoiceStatus, }; use alloy_rpc_types_engine::{ ForkChoiceUpdateResult, ForkchoiceState, ForkchoiceUpdateError, ForkchoiceUpdated, PayloadId, @@ -145,7 +145,7 @@ pub enum BeaconEngineMessage { /// Message with new payload. NewPayload { /// The execution payload received by Engine API. - payload: ExecutionData, + payload: Engine::ExecutionData, /// The sender for returning payload status result. tx: oneshot::Sender>, }, @@ -217,7 +217,7 @@ where /// See also pub async fn new_payload( &self, - payload: ExecutionData, + payload: Engine::ExecutionData, ) -> Result { let (tx, rx) = oneshot::channel(); let _ = self.to_engine.send(BeaconEngineMessage::NewPayload { payload, tx }); diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 9405c3ba5..8c80ed0ba 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -28,7 +28,7 @@ use reth_consensus::{Consensus, FullConsensus, PostExecutionInput}; pub use reth_engine_primitives::InvalidBlockHook; use reth_engine_primitives::{ BeaconConsensusEngineEvent, BeaconEngineMessage, BeaconOnNewPayloadError, EngineTypes, - EngineValidator, ExecutionData, ForkchoiceStateTracker, OnForkChoiceUpdated, + EngineValidator, ExecutionPayload, ForkchoiceStateTracker, OnForkChoiceUpdated, }; use reth_errors::{ConsensusError, ProviderResult}; use reth_ethereum_primitives::EthPrimitives; @@ -790,8 +790,8 @@ where /// When the Consensus layer receives a new block via the consensus gossip protocol, /// the transactions in the block are sent to the execution layer in the form of a - /// [`ExecutionData`]. The Execution layer executes the transactions and validates the - /// state in the block header, then passes validation data back to Consensus layer, that + /// [`EngineTypes::ExecutionData`]. The Execution layer executes the transactions and validates + /// the state in the block header, then passes validation data back to Consensus layer, that /// adds the block to the head of its own blockchain and attests to it. The block is then /// broadcast over the consensus p2p network in the form of a "Beacon block". /// @@ -803,7 +803,7 @@ where #[instrument(level = "trace", skip_all, fields(block_hash = %payload.block_hash(), block_num = %payload.block_number(),), target = "engine::tree")] fn on_new_payload( &mut self, - payload: ExecutionData, + payload: T::ExecutionData, ) -> Result, InsertBlockFatalError> { trace!(target: "engine::tree", "invoked new payload"); self.metrics.engine.new_payload_messages.increment(1); @@ -2920,7 +2920,7 @@ mod tests { use assert_matches::assert_matches; use reth_chain_state::{test_utils::TestBlockBuilder, BlockState}; use reth_chainspec::{ChainSpec, HOLESKY, MAINNET}; - use reth_engine_primitives::ForkchoiceStatus; + use reth_engine_primitives::{ExecutionData, ForkchoiceStatus}; use reth_ethereum_consensus::EthBeaconConsensus; use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator}; use reth_ethereum_primitives::{Block, EthPrimitives}; diff --git a/crates/engine/util/src/engine_store.rs b/crates/engine/util/src/engine_store.rs index 651414146..641994814 100644 --- a/crates/engine/util/src/engine_store.rs +++ b/crates/engine/util/src/engine_store.rs @@ -2,7 +2,7 @@ use alloy_rpc_types_engine::ForkchoiceState; use futures::{Stream, StreamExt}; -use reth_engine_primitives::{BeaconEngineMessage, EngineTypes, ExecutionData}; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes, ExecutionPayload}; use reth_fs_util as fs; use serde::{Deserialize, Serialize}; use std::{ @@ -17,19 +17,19 @@ use tracing::*; /// A message from the engine API that has been stored to disk. #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub enum StoredEngineApiMessage { +pub enum StoredEngineApiMessage { /// The on-disk representation of an `engine_forkchoiceUpdated` method call. ForkchoiceUpdated { /// The [`ForkchoiceState`] sent in the persisted call. state: ForkchoiceState, /// The payload attributes sent in the persisted call, if any. - payload_attrs: Option, + payload_attrs: Option, }, /// The on-disk representation of an `engine_newPayload` method call. NewPayload { - /// The [`ExecutionData`] sent in the persisted call. + /// The [`EngineTypes::ExecutionData`] sent in the persisted call. #[serde(flatten)] - payload: ExecutionData, + payload: EngineT::ExecutionData, }, } @@ -70,7 +70,7 @@ impl EngineMessageStore { let filename = format!("{}-fcu-{}.json", timestamp, state.head_block_hash); fs::write( self.path.join(filename), - serde_json::to_vec(&StoredEngineApiMessage::ForkchoiceUpdated { + serde_json::to_vec(&StoredEngineApiMessage::::ForkchoiceUpdated { state: *state, payload_attrs: payload_attrs.clone(), })?, @@ -80,11 +80,9 @@ impl EngineMessageStore { let filename = format!("{}-new_payload-{}.json", timestamp, payload.block_hash()); fs::write( self.path.join(filename), - serde_json::to_vec( - &StoredEngineApiMessage::::NewPayload { - payload: payload.clone(), - }, - )?, + serde_json::to_vec(&StoredEngineApiMessage::::NewPayload { + payload: payload.clone(), + })?, )?; } // noop diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index be862508e..4a521b1ab 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -8,7 +8,8 @@ use futures::{stream::FuturesUnordered, Stream, StreamExt, TryFutureExt}; use itertools::Either; use reth_chainspec::EthChainSpec; use reth_engine_primitives::{ - BeaconEngineMessage, BeaconOnNewPayloadError, EngineTypes, ExecutionData, OnForkChoiceUpdated, + BeaconEngineMessage, BeaconOnNewPayloadError, EngineTypes, ExecutionData, + ExecutionPayload as _, OnForkChoiceUpdated, }; use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult}; use reth_ethereum_forks::EthereumHardforks; @@ -104,7 +105,7 @@ impl EngineReorg Stream for EngineReorg where S: Stream>, - Engine: EngineTypes, + Engine: EngineTypes, Provider: BlockReader + StateProviderFactory, Evm: ConfigureEvm
, Spec: EthChainSpec + EthereumHardforks, diff --git a/crates/engine/util/src/skip_new_payload.rs b/crates/engine/util/src/skip_new_payload.rs index ce41a07e3..73b099f7b 100644 --- a/crates/engine/util/src/skip_new_payload.rs +++ b/crates/engine/util/src/skip_new_payload.rs @@ -2,7 +2,7 @@ use alloy_rpc_types_engine::{PayloadStatus, PayloadStatusEnum}; use futures::{Stream, StreamExt}; -use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes, ExecutionPayload}; use std::{ pin::Pin, task::{ready, Context, Poll}, diff --git a/crates/ethereum/engine-primitives/src/lib.rs b/crates/ethereum/engine-primitives/src/lib.rs index 39f4c462a..0a93f386e 100644 --- a/crates/ethereum/engine-primitives/src/lib.rs +++ b/crates/ethereum/engine-primitives/src/lib.rs @@ -50,6 +50,7 @@ where + TryInto + TryInto, { + type ExecutionData = ExecutionData; type ExecutionPayloadEnvelopeV1 = ExecutionPayloadV1; type ExecutionPayloadEnvelopeV2 = ExecutionPayloadEnvelopeV2; type ExecutionPayloadEnvelopeV3 = ExecutionPayloadEnvelopeV3; @@ -98,6 +99,7 @@ impl EthereumEngineValidator { impl PayloadValidator for EthereumEngineValidator { type Block = Block; + type ExecutionData = ExecutionData; fn ensure_well_formed_payload( &self, @@ -109,7 +111,7 @@ impl PayloadValidator for EthereumEngineValidator { impl EngineValidator for EthereumEngineValidator where - Types: EngineTypes, + Types: EngineTypes, { fn validate_version_specific_fields( &self, diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index cb1ac212c..7006a7d2c 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -10,8 +10,8 @@ use std::{ use alloy_rpc_types::engine::ClientVersionV1; use futures::TryFutureExt; use reth_node_api::{ - AddOnsContext, BlockTy, EngineValidator, FullNodeComponents, NodeAddOns, NodeTypes, - NodeTypesWithEngine, + AddOnsContext, BlockTy, EngineTypes, EngineValidator, ExecutionData, FullNodeComponents, + NodeAddOns, NodeTypes, NodeTypesWithEngine, }; use reth_node_core::{ node_config::NodeConfig, @@ -401,7 +401,9 @@ where impl RpcAddOns where - N: FullNodeComponents, + N: FullNodeComponents< + Types: NodeTypesWithEngine>, + >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners @@ -528,7 +530,9 @@ where impl NodeAddOns for RpcAddOns where - N: FullNodeComponents, + N: FullNodeComponents< + Types: NodeTypesWithEngine>, + >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index f16bfeb71..82ba137fc 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -47,6 +47,7 @@ where type ExecutionPayloadEnvelopeV2 = ExecutionPayloadEnvelopeV2; type ExecutionPayloadEnvelopeV3 = OpExecutionPayloadEnvelopeV3; type ExecutionPayloadEnvelopeV4 = OpExecutionPayloadEnvelopeV4; + type ExecutionData = ExecutionData; fn block_to_payload( block: SealedBlock< @@ -91,6 +92,7 @@ impl OpEngineValidator { impl PayloadValidator for OpEngineValidator { type Block = OpBlock; + type ExecutionData = ExecutionData; fn ensure_well_formed_payload( &self, @@ -102,7 +104,7 @@ impl PayloadValidator for OpEngineValidator { impl EngineValidator for OpEngineValidator where - Types: EngineTypes, + Types: EngineTypes, { fn validate_execution_requests( &self, diff --git a/crates/payload/validator/src/lib.rs b/crates/payload/validator/src/lib.rs index 100093b0c..6920de7fb 100644 --- a/crates/payload/validator/src/lib.rs +++ b/crates/payload/validator/src/lib.rs @@ -115,10 +115,10 @@ impl ExecutionPayloadValidator { &self, payload: ExecutionData, ) -> Result>, PayloadError> { - let expected_hash = payload.block_hash(); - let ExecutionData { payload, sidecar } = payload; + let expected_hash = payload.block_hash(); + // First parse the block let sealed_block = payload.try_into_block_with_sidecar(&sidecar)?.seal_slow(); diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 0b45b2431..68aeb1629 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -17,7 +17,7 @@ //! //! ``` //! use reth_consensus::{ConsensusError, FullConsensus}; -//! use reth_engine_primitives::PayloadValidator; +//! use reth_engine_primitives::{ExecutionData, PayloadValidator}; //! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; //! use reth_evm_ethereum::EthEvmConfig; //! use reth_network_api::{NetworkInfo, Peers}; @@ -58,7 +58,7 @@ //! Network: NetworkInfo + Peers + Clone + 'static, //! BlockExecutor: BlockExecutorProvider, //! Consensus: FullConsensus + Clone + 'static, -//! Validator: PayloadValidator, +//! Validator: PayloadValidator, //! { //! // configure the rpc module per transport //! let transports = TransportRpcModuleConfig::default().with_http(vec![ @@ -89,7 +89,7 @@ //! //! ``` //! use reth_consensus::{ConsensusError, FullConsensus}; -//! use reth_engine_primitives::{EngineTypes, PayloadValidator}; +//! use reth_engine_primitives::{EngineTypes, ExecutionData, PayloadValidator}; //! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; //! use reth_evm_ethereum::EthEvmConfig; //! use reth_network_api::{NetworkInfo, Peers}; @@ -146,7 +146,7 @@ //! EngineT: EngineTypes, //! BlockExecutor: BlockExecutorProvider, //! Consensus: FullConsensus + Clone + 'static, -//! Validator: PayloadValidator, +//! Validator: PayloadValidator, //! { //! // configure the rpc module per transport //! let transports = TransportRpcModuleConfig::default().with_http(vec![ @@ -213,7 +213,7 @@ use jsonrpsee::{ }; use reth_chainspec::EthereumHardforks; use reth_consensus::{ConsensusError, FullConsensus}; -use reth_engine_primitives::{EngineTypes, PayloadValidator}; +use reth_engine_primitives::{EngineTypes, ExecutionData, PayloadValidator}; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; use reth_primitives::NodePrimitives; @@ -284,7 +284,9 @@ pub async fn launch, block_executor: BlockExecutor, consensus: Arc>, - payload_validator: Arc>, + payload_validator: Arc< + dyn PayloadValidator, + >, ) -> Result where Provider: FullRpcProvider< @@ -614,7 +616,9 @@ where module_config: TransportRpcModuleConfig, engine: EngineApi, eth: DynEthApiBuilder, - payload_validator: Arc>, + payload_validator: Arc< + dyn PayloadValidator, + >, ) -> ( TransportRpcModules, AuthRpcModule, @@ -665,7 +669,7 @@ where /// /// ```no_run /// use reth_consensus::noop::NoopConsensus; - /// use reth_engine_primitives::PayloadValidator; + /// use reth_engine_primitives::{ExecutionData, PayloadValidator}; /// use reth_evm::ConfigureEvm; /// use reth_evm_ethereum::execute::EthExecutorProvider; /// use reth_network_api::noop::NoopNetwork; @@ -680,7 +684,8 @@ where /// fn init(evm: Evm, validator: Validator) /// where /// Evm: ConfigureEvm
+ 'static, - /// Validator: PayloadValidator + 'static, + /// Validator: PayloadValidator + /// + 'static, /// { /// let mut registry = RpcModuleBuilder::default() /// .with_provider(NoopProvider::default()) @@ -699,7 +704,9 @@ where self, config: RpcModuleConfig, eth: DynEthApiBuilder, - payload_validator: Arc>, + payload_validator: Arc< + dyn PayloadValidator, + >, ) -> RpcRegistryInner where EthApi: EthApiTypes + 'static, @@ -726,7 +733,9 @@ where self, module_config: TransportRpcModuleConfig, eth: DynEthApiBuilder, - payload_validator: Arc>, + payload_validator: Arc< + dyn PayloadValidator, + >, ) -> TransportRpcModules<()> where EthApi: FullEthApiServer< @@ -869,7 +878,8 @@ pub struct RpcRegistryInner< executor: Tasks, block_executor: BlockExecutor, consensus: Consensus, - payload_validator: Arc>, + payload_validator: + Arc>, /// Holds the configuration for the RPC modules config: RpcModuleConfig, /// Holds a all `eth_` namespace handlers @@ -910,7 +920,9 @@ where evm_config: EvmConfig, eth_api_builder: DynEthApiBuilder, block_executor: BlockExecutor, - payload_validator: Arc>, + payload_validator: Arc< + dyn PayloadValidator, + >, ) -> Self where EvmConfig: ConfigureEvm
, diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 26cf2ad2c..9a42aa3a4 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -79,7 +79,7 @@ impl EngineApi where Provider: HeaderProvider + BlockReader + StateProviderFactory + 'static, - EngineT: EngineTypes, + EngineT: EngineTypes, Pool: TransactionPool + 'static, Validator: EngineValidator, ChainSpec: EthereumHardforks + Send + Sync + 'static, @@ -748,7 +748,7 @@ impl EngineApiServer for EngineApi where Provider: HeaderProvider + BlockReader + StateProviderFactory + 'static, - EngineT: EngineTypes, + EngineT: EngineTypes, Pool: TransactionPool + 'static, Validator: EngineValidator, ChainSpec: EthereumHardforks + Send + Sync + 'static, diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index f493789c7..b92e1972c 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -51,7 +51,10 @@ where config: ValidationApiConfig, task_spawner: Box, payload_validator: Arc< - dyn PayloadValidator::Block>, + dyn PayloadValidator< + Block = ::Block, + ExecutionData = ExecutionData, + >, >, ) -> Self { let ValidationApiConfig { disallow, validation_window } = config; @@ -468,7 +471,12 @@ pub struct ValidationApiInner { /// Consensus implementation. consensus: Arc>, /// Execution payload validator. - payload_validator: Arc::Block>>, + payload_validator: Arc< + dyn PayloadValidator< + Block = ::Block, + ExecutionData = ExecutionData, + >, + >, /// Block executor factory. executor_provider: E, /// Set of disallowed addresses diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index 322791efc..30b9dc0e6 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -174,6 +174,7 @@ impl EngineTypes for CustomEngineTypes { type ExecutionPayloadEnvelopeV2 = ExecutionPayloadEnvelopeV2; type ExecutionPayloadEnvelopeV3 = ExecutionPayloadEnvelopeV3; type ExecutionPayloadEnvelopeV4 = ExecutionPayloadEnvelopeV4; + type ExecutionData = ExecutionData; fn block_to_payload( block: SealedBlock< @@ -207,6 +208,7 @@ impl CustomEngineValidator { impl PayloadValidator for CustomEngineValidator { type Block = Block; + type ExecutionData = ExecutionData; fn ensure_well_formed_payload( &self, @@ -218,7 +220,7 @@ impl PayloadValidator for CustomEngineValidator { impl EngineValidator for CustomEngineValidator where - T: EngineTypes, + T: EngineTypes, { fn validate_version_specific_fields( &self,