reth_engine_primitives/
lib.rs

1//! Traits, validation methods, and helper types used to abstract over engine types.
2
3#![doc(
4    html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
5    html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
6    issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
7)]
8#![cfg_attr(not(test), warn(unused_crate_dependencies))]
9#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
10#![cfg_attr(not(feature = "std"), no_std)]
11
12extern crate alloc;
13
14use alloy_consensus::BlockHeader;
15use reth_errors::ConsensusError;
16use reth_payload_primitives::{
17    EngineApiMessageVersion, EngineObjectValidationError, InvalidPayloadAttributesError,
18    NewPayloadError, PayloadAttributes, PayloadOrAttributes, PayloadTypes,
19};
20use reth_primitives_traits::{Block, RecoveredBlock};
21use reth_trie_common::HashedPostState;
22use serde::{de::DeserializeOwned, Serialize};
23
24// Re-export [`ExecutionPayload`] moved to `reth_payload_primitives`
25pub use reth_evm::{ConfigureEngineEvm, ExecutableTxIterator};
26pub use reth_payload_primitives::ExecutionPayload;
27
28mod error;
29pub use error::*;
30
31mod forkchoice;
32pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus};
33
34#[cfg(feature = "std")]
35mod message;
36#[cfg(feature = "std")]
37pub use message::*;
38
39mod event;
40pub use event::*;
41
42mod invalid_block_hook;
43pub use invalid_block_hook::{InvalidBlockHook, InvalidBlockHooks, NoopInvalidBlockHook};
44
45pub mod config;
46pub use config::*;
47
48/// This type defines the versioned types of the engine API based on the [ethereum engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine).
49///
50/// This includes the execution payload types and payload attributes that are used to trigger a
51/// payload job. Hence this trait is also [`PayloadTypes`].
52///
53/// Implementations of this type are intended to be stateless and just define the types as
54/// associated types.
55/// This type is intended for non-ethereum chains that closely mirror the ethereum engine API spec,
56/// but may have different payload, for example opstack, but structurally equivalent otherwise (same
57/// engine API RPC endpoints for example).
58pub trait EngineTypes:
59    PayloadTypes<
60        BuiltPayload: TryInto<Self::ExecutionPayloadEnvelopeV1>
61                          + TryInto<Self::ExecutionPayloadEnvelopeV2>
62                          + TryInto<Self::ExecutionPayloadEnvelopeV3>
63                          + TryInto<Self::ExecutionPayloadEnvelopeV4>
64                          + TryInto<Self::ExecutionPayloadEnvelopeV5>,
65    > + DeserializeOwned
66    + Serialize
67{
68    /// Execution Payload V1 envelope type.
69    type ExecutionPayloadEnvelopeV1: DeserializeOwned
70        + Serialize
71        + Clone
72        + Unpin
73        + Send
74        + Sync
75        + 'static;
76    /// Execution Payload V2  envelope type.
77    type ExecutionPayloadEnvelopeV2: DeserializeOwned
78        + Serialize
79        + Clone
80        + Unpin
81        + Send
82        + Sync
83        + 'static;
84    /// Execution Payload V3 envelope type.
85    type ExecutionPayloadEnvelopeV3: DeserializeOwned
86        + Serialize
87        + Clone
88        + Unpin
89        + Send
90        + Sync
91        + 'static;
92    /// Execution Payload V4 envelope type.
93    type ExecutionPayloadEnvelopeV4: DeserializeOwned
94        + Serialize
95        + Clone
96        + Unpin
97        + Send
98        + Sync
99        + 'static;
100    /// Execution Payload V5 envelope type.
101    type ExecutionPayloadEnvelopeV5: DeserializeOwned
102        + Serialize
103        + Clone
104        + Unpin
105        + Send
106        + Sync
107        + 'static;
108}
109
110/// Type that validates the payloads processed by the engine API.
111pub trait EngineApiValidator<Types: PayloadTypes>: Send + Sync + Unpin + 'static {
112    /// Validates the presence or exclusion of fork-specific fields based on the payload attributes
113    /// and the message version.
114    fn validate_version_specific_fields(
115        &self,
116        version: EngineApiMessageVersion,
117        payload_or_attrs: PayloadOrAttributes<'_, Types::ExecutionData, Types::PayloadAttributes>,
118    ) -> Result<(), EngineObjectValidationError>;
119
120    /// Ensures that the payload attributes are valid for the given [`EngineApiMessageVersion`].
121    fn ensure_well_formed_attributes(
122        &self,
123        version: EngineApiMessageVersion,
124        attributes: &Types::PayloadAttributes,
125    ) -> Result<(), EngineObjectValidationError>;
126}
127
128/// Type that validates an [`ExecutionPayload`].
129#[auto_impl::auto_impl(&, Arc)]
130pub trait PayloadValidator<Types: PayloadTypes>: Send + Sync + Unpin + 'static {
131    /// The block type used by the engine.
132    type Block: Block;
133
134    /// Ensures that the given payload does not violate any consensus rules that concern the block's
135    /// layout.
136    ///
137    /// This function must convert the payload into the executable block and pre-validate its
138    /// fields.
139    ///
140    /// Implementers should ensure that the checks are done in the order that conforms with the
141    /// engine-API specification.
142    fn ensure_well_formed_payload(
143        &self,
144        payload: Types::ExecutionData,
145    ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError>;
146
147    /// Verifies payload post-execution w.r.t. hashed state updates.
148    fn validate_block_post_execution_with_hashed_state(
149        &self,
150        _state_updates: &HashedPostState,
151        _block: &RecoveredBlock<Self::Block>,
152    ) -> Result<(), ConsensusError> {
153        // method not used by l1
154        Ok(())
155    }
156
157    /// Validates the payload attributes with respect to the header.
158    ///
159    /// By default, this enforces that the payload attributes timestamp is greater than the
160    /// timestamp according to:
161    ///   > 7. Client software MUST ensure that payloadAttributes.timestamp is greater than
162    ///   > timestamp
163    ///   > of a block referenced by forkchoiceState.headBlockHash.
164    ///
165    /// See also: <https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md#specification-1>
166    fn validate_payload_attributes_against_header(
167        &self,
168        attr: &Types::PayloadAttributes,
169        header: &<Self::Block as Block>::Header,
170    ) -> Result<(), InvalidPayloadAttributesError> {
171        if attr.timestamp() <= header.timestamp() {
172            return Err(InvalidPayloadAttributesError::InvalidTimestamp);
173        }
174        Ok(())
175    }
176}