1//! Traits, validation methods, and helper types used to abstract over engine types.
23#![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)]
1112extern crate alloc;
1314use 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};
2324// Re-export [`ExecutionPayload`] moved to `reth_payload_primitives`
25pub use reth_payload_primitives::ExecutionPayload;
2627mod error;
28pub use error::*;
2930mod forkchoice;
31pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus};
3233mod message;
34pub use message::*;
3536mod event;
37pub use event::*;
3839mod invalid_block_hook;
40pub use invalid_block_hook::InvalidBlockHook;
4142pub mod config;
43pub use config::*;
4445/// 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 > + DeserializeOwned56 + Serialize57{
58/// Execution Payload V1 envelope type.
59type ExecutionPayloadEnvelopeV1: DeserializeOwned60 + Serialize61 + Clone62 + Unpin63 + Send64 + Sync65 + 'static;
66/// Execution Payload V2 envelope type.
67type ExecutionPayloadEnvelopeV2: DeserializeOwned68 + Serialize69 + Clone70 + Unpin71 + Send72 + Sync73 + 'static;
74/// Execution Payload V3 envelope type.
75type ExecutionPayloadEnvelopeV3: DeserializeOwned76 + Serialize77 + Clone78 + Unpin79 + Send80 + Sync81 + 'static;
82/// Execution Payload V4 envelope type.
83type ExecutionPayloadEnvelopeV4: DeserializeOwned84 + Serialize85 + Clone86 + Unpin87 + Send88 + Sync89 + 'static;
90}
9192/// 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.
96type Block: Block;
9798/// The execution payload type used by the engine.
99type ExecutionData;
100101/// 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.
109fn ensure_well_formed_payload(
110&self,
111 payload: Self::ExecutionData,
112 ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError>;
113114/// Verifies payload post-execution w.r.t. hashed state updates.
115fn 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
121Ok(())
122 }
123}
124125/// Type that validates the payloads processed by the engine.
126pub trait EngineValidator<Types: PayloadTypes>:
127PayloadValidator<ExecutionData = Types::ExecutionData>
128{
129/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
130 /// and the message version.
131fn 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>;
140141/// Ensures that the payload attributes are valid for the given [`EngineApiMessageVersion`].
142fn ensure_well_formed_attributes(
143&self,
144 version: EngineApiMessageVersion,
145 attributes: &<Types as PayloadTypes>::PayloadAttributes,
146 ) -> Result<(), EngineObjectValidationError>;
147148/// 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)
157fn validate_payload_attributes_against_header(
158&self,
159 attr: &<Types as PayloadTypes>::PayloadAttributes,
160 header: &<Self::Block as Block>::Header,
161 ) -> Result<(), InvalidPayloadAttributesError> {
162if attr.timestamp() <= header.timestamp() {
163return Err(InvalidPayloadAttributesError::InvalidTimestamp);
164 }
165Ok(())
166 }
167}