reth_node_ethereum/
engine.rs

1//! Validates execution payload wrt Ethereum Execution Engine API version.
2
3use alloy_rpc_types_engine::ExecutionData;
4pub use alloy_rpc_types_engine::{
5    ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4,
6    ExecutionPayloadV1, PayloadAttributes as EthPayloadAttributes,
7};
8use reth_chainspec::{EthChainSpec, EthereumHardforks};
9use reth_engine_primitives::{EngineApiValidator, PayloadValidator};
10use reth_ethereum_payload_builder::EthereumExecutionPayloadValidator;
11use reth_ethereum_primitives::Block;
12use reth_node_api::PayloadTypes;
13use reth_payload_primitives::{
14    validate_execution_requests, validate_version_specific_fields, EngineApiMessageVersion,
15    EngineObjectValidationError, NewPayloadError, PayloadOrAttributes,
16};
17use reth_primitives_traits::SealedBlock;
18use std::sync::Arc;
19
20/// Validator for the ethereum engine API.
21#[derive(Debug, Clone)]
22pub struct EthereumEngineValidator<ChainSpec = reth_chainspec::ChainSpec> {
23    inner: EthereumExecutionPayloadValidator<ChainSpec>,
24}
25
26impl<ChainSpec> EthereumEngineValidator<ChainSpec> {
27    /// Instantiates a new validator.
28    pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
29        Self { inner: EthereumExecutionPayloadValidator::new(chain_spec) }
30    }
31
32    /// Returns the chain spec used by the validator.
33    #[inline]
34    fn chain_spec(&self) -> &ChainSpec {
35        self.inner.chain_spec()
36    }
37}
38
39impl<ChainSpec, Types> PayloadValidator<Types> for EthereumEngineValidator<ChainSpec>
40where
41    ChainSpec: EthChainSpec + EthereumHardforks + 'static,
42    Types: PayloadTypes<ExecutionData = ExecutionData>,
43{
44    type Block = Block;
45
46    fn convert_payload_to_block(
47        &self,
48        payload: ExecutionData,
49    ) -> Result<SealedBlock<Self::Block>, NewPayloadError> {
50        self.inner.ensure_well_formed_payload(payload).map_err(Into::into)
51    }
52}
53
54impl<ChainSpec, Types> EngineApiValidator<Types> for EthereumEngineValidator<ChainSpec>
55where
56    ChainSpec: EthChainSpec + EthereumHardforks + 'static,
57    Types: PayloadTypes<PayloadAttributes = EthPayloadAttributes, ExecutionData = ExecutionData>,
58{
59    fn validate_version_specific_fields(
60        &self,
61        version: EngineApiMessageVersion,
62        payload_or_attrs: PayloadOrAttributes<'_, Types::ExecutionData, EthPayloadAttributes>,
63    ) -> Result<(), EngineObjectValidationError> {
64        payload_or_attrs
65            .execution_requests()
66            .map(|requests| validate_execution_requests(requests))
67            .transpose()?;
68
69        validate_version_specific_fields(self.chain_spec(), version, payload_or_attrs)
70    }
71
72    fn ensure_well_formed_attributes(
73        &self,
74        version: EngineApiMessageVersion,
75        attributes: &EthPayloadAttributes,
76    ) -> Result<(), EngineObjectValidationError> {
77        validate_version_specific_fields(
78            self.chain_spec(),
79            version,
80            PayloadOrAttributes::<Types::ExecutionData, EthPayloadAttributes>::PayloadAttributes(
81                attributes,
82            ),
83        )
84    }
85}