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::ChainSpec;
9use reth_engine_primitives::{EngineTypes, EngineValidator, PayloadValidator};
10use reth_ethereum_payload_builder::EthereumExecutionPayloadValidator;
11use reth_ethereum_primitives::Block;
12use reth_payload_primitives::{
13    validate_execution_requests, validate_version_specific_fields, EngineApiMessageVersion,
14    EngineObjectValidationError, NewPayloadError, PayloadOrAttributes,
15};
16use reth_primitives_traits::RecoveredBlock;
17use std::sync::Arc;
18
19/// Validator for the ethereum engine API.
20#[derive(Debug, Clone)]
21pub struct EthereumEngineValidator {
22    inner: EthereumExecutionPayloadValidator<ChainSpec>,
23}
24
25impl EthereumEngineValidator {
26    /// Instantiates a new validator.
27    pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
28        Self { inner: EthereumExecutionPayloadValidator::new(chain_spec) }
29    }
30
31    /// Returns the chain spec used by the validator.
32    #[inline]
33    fn chain_spec(&self) -> &ChainSpec {
34        self.inner.chain_spec()
35    }
36}
37
38impl PayloadValidator for EthereumEngineValidator {
39    type Block = Block;
40    type ExecutionData = ExecutionData;
41
42    fn ensure_well_formed_payload(
43        &self,
44        payload: ExecutionData,
45    ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError> {
46        let sealed_block = self.inner.ensure_well_formed_payload(payload)?;
47        sealed_block.try_recover().map_err(|e| NewPayloadError::Other(e.into()))
48    }
49}
50
51impl<Types> EngineValidator<Types> for EthereumEngineValidator
52where
53    Types: EngineTypes<PayloadAttributes = EthPayloadAttributes, ExecutionData = ExecutionData>,
54{
55    fn validate_version_specific_fields(
56        &self,
57        version: EngineApiMessageVersion,
58        payload_or_attrs: PayloadOrAttributes<'_, Self::ExecutionData, EthPayloadAttributes>,
59    ) -> Result<(), EngineObjectValidationError> {
60        payload_or_attrs
61            .execution_requests()
62            .map(|requests| validate_execution_requests(requests))
63            .transpose()?;
64
65        validate_version_specific_fields(self.chain_spec(), version, payload_or_attrs)
66    }
67
68    fn ensure_well_formed_attributes(
69        &self,
70        version: EngineApiMessageVersion,
71        attributes: &EthPayloadAttributes,
72    ) -> Result<(), EngineObjectValidationError> {
73        validate_version_specific_fields(
74            self.chain_spec(),
75            version,
76            PayloadOrAttributes::<Self::ExecutionData, EthPayloadAttributes>::PayloadAttributes(
77                attributes,
78            ),
79        )
80    }
81}