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_payload_primitives::ExecutionPayload;
26
27mod error;
28pub use error::*;
29
30mod forkchoice;
31pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus};
32
33mod message;
34pub use message::*;
35
36mod event;
37pub use event::*;
38
39mod invalid_block_hook;
40pub use invalid_block_hook::InvalidBlockHook;
41
42pub mod config;
43pub use config::*;
44
45/// This type defines the versioned types of the engine API.
46///
47/// This includes the execution payload types and payload attributes that are used to trigger a
48/// payload job. Hence this trait is also [`PayloadTypes`].
49pub trait EngineTypes:
50    PayloadTypes<
51        BuiltPayload: TryInto<Self::ExecutionPayloadEnvelopeV1>
52                          + TryInto<Self::ExecutionPayloadEnvelopeV2>
53                          + TryInto<Self::ExecutionPayloadEnvelopeV3>
54                          + TryInto<Self::ExecutionPayloadEnvelopeV4>,
55    > + DeserializeOwned
56    + Serialize
57{
58    /// Execution Payload V1 envelope type.
59    type ExecutionPayloadEnvelopeV1: DeserializeOwned
60        + Serialize
61        + Clone
62        + Unpin
63        + Send
64        + Sync
65        + 'static;
66    /// Execution Payload V2  envelope type.
67    type ExecutionPayloadEnvelopeV2: DeserializeOwned
68        + Serialize
69        + Clone
70        + Unpin
71        + Send
72        + Sync
73        + 'static;
74    /// Execution Payload V3 envelope type.
75    type ExecutionPayloadEnvelopeV3: DeserializeOwned
76        + Serialize
77        + Clone
78        + Unpin
79        + Send
80        + Sync
81        + 'static;
82    /// Execution Payload V4 envelope type.
83    type ExecutionPayloadEnvelopeV4: DeserializeOwned
84        + Serialize
85        + Clone
86        + Unpin
87        + Send
88        + Sync
89        + 'static;
90}
91
92/// Type that validates an [`ExecutionPayload`].
93#[auto_impl::auto_impl(&, Arc)]
94pub trait PayloadValidator: Send + Sync + Unpin + 'static {
95    /// The block type used by the engine.
96    type Block: Block;
97
98    /// The execution payload type used by the engine.
99    type ExecutionData;
100
101    /// Ensures that the given payload does not violate any consensus rules that concern the block's
102    /// layout.
103    ///
104    /// This function must convert the payload into the executable block and pre-validate its
105    /// fields.
106    ///
107    /// Implementers should ensure that the checks are done in the order that conforms with the
108    /// engine-API specification.
109    fn ensure_well_formed_payload(
110        &self,
111        payload: Self::ExecutionData,
112    ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError>;
113
114    /// Verifies payload post-execution w.r.t. hashed state updates.
115    fn validate_block_post_execution_with_hashed_state(
116        &self,
117        _state_updates: &HashedPostState,
118        _block: &RecoveredBlock<Self::Block>,
119    ) -> Result<(), ConsensusError> {
120        // method not used by l1
121        Ok(())
122    }
123}
124
125/// Type that validates the payloads processed by the engine.
126pub trait EngineValidator<Types: PayloadTypes>:
127    PayloadValidator<ExecutionData = Types::ExecutionData>
128{
129    /// Validates the presence or exclusion of fork-specific fields based on the payload attributes
130    /// and the message version.
131    fn validate_version_specific_fields(
132        &self,
133        version: EngineApiMessageVersion,
134        payload_or_attrs: PayloadOrAttributes<
135            '_,
136            Types::ExecutionData,
137            <Types as PayloadTypes>::PayloadAttributes,
138        >,
139    ) -> Result<(), EngineObjectValidationError>;
140
141    /// Ensures that the payload attributes are valid for the given [`EngineApiMessageVersion`].
142    fn ensure_well_formed_attributes(
143        &self,
144        version: EngineApiMessageVersion,
145        attributes: &<Types as PayloadTypes>::PayloadAttributes,
146    ) -> Result<(), EngineObjectValidationError>;
147
148    /// Validates the payload attributes with respect to the header.
149    ///
150    /// By default, this enforces that the payload attributes timestamp is greater than the
151    /// timestamp according to:
152    ///   > 7. Client software MUST ensure that payloadAttributes.timestamp is greater than
153    ///   > timestamp
154    ///   > of a block referenced by forkchoiceState.headBlockHash.
155    ///
156    /// See also [engine api spec](https://github.com/ethereum/execution-apis/tree/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine)
157    fn validate_payload_attributes_against_header(
158        &self,
159        attr: &<Types as PayloadTypes>::PayloadAttributes,
160        header: &<Self::Block as Block>::Header,
161    ) -> Result<(), InvalidPayloadAttributesError> {
162        if attr.timestamp() <= header.timestamp() {
163            return Err(InvalidPayloadAttributesError::InvalidTimestamp);
164        }
165        Ok(())
166    }
167}