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/SeismicSystems/seismic-reth/issues/"
7)]
8#![cfg_attr(not(test), warn(unused_crate_dependencies))]
9#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
10
11mod error;
12
13use core::fmt;
14
15use alloy_consensus::BlockHeader;
16use alloy_rpc_types_engine::{ExecutionPayload, ExecutionPayloadSidecar, PayloadError};
17pub use error::BeaconOnNewPayloadError;
18
19mod forkchoice;
20pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus};
21
22mod message;
23pub use message::{BeaconEngineMessage, OnForkChoiceUpdated};
24
25mod invalid_block_hook;
26pub use invalid_block_hook::InvalidBlockHook;
27
28pub use reth_payload_primitives::{
29    BuiltPayload, EngineApiMessageVersion, EngineObjectValidationError, PayloadOrAttributes,
30    PayloadTypes,
31};
32use reth_payload_primitives::{InvalidPayloadAttributesError, PayloadAttributes};
33use reth_primitives::SealedBlockFor;
34use reth_primitives_traits::Block;
35use serde::{de::DeserializeOwned, ser::Serialize};
36
37/// This type defines the versioned types of the engine API.
38///
39/// This includes the execution payload types and payload attributes that are used to trigger a
40/// payload job. Hence this trait is also [`PayloadTypes`].
41pub trait EngineTypes:
42    PayloadTypes<
43        BuiltPayload: TryInto<Self::ExecutionPayloadEnvelopeV1>
44                          + TryInto<Self::ExecutionPayloadEnvelopeV2>
45                          + TryInto<Self::ExecutionPayloadEnvelopeV3>
46                          + TryInto<Self::ExecutionPayloadEnvelopeV4>,
47    > + DeserializeOwned
48    + Serialize
49    + 'static
50{
51    /// Execution Payload V1 envelope type.
52    type ExecutionPayloadEnvelopeV1: DeserializeOwned
53        + Serialize
54        + Clone
55        + Unpin
56        + Send
57        + Sync
58        + 'static;
59    /// Execution Payload V2  envelope type.
60    type ExecutionPayloadEnvelopeV2: DeserializeOwned
61        + Serialize
62        + Clone
63        + Unpin
64        + Send
65        + Sync
66        + 'static;
67    /// Execution Payload V3 envelope type.
68    type ExecutionPayloadEnvelopeV3: DeserializeOwned
69        + Serialize
70        + Clone
71        + Unpin
72        + Send
73        + Sync
74        + 'static;
75    /// Execution Payload V4 envelope type.
76    type ExecutionPayloadEnvelopeV4: DeserializeOwned
77        + Serialize
78        + Clone
79        + Unpin
80        + Send
81        + Sync
82        + 'static;
83}
84
85/// Type that validates an [`ExecutionPayload`].
86pub trait PayloadValidator: fmt::Debug + Send + Sync + Unpin + 'static {
87    /// The block type used by the engine.
88    type Block: Block;
89
90    /// Ensures that the given payload does not violate any consensus rules that concern the block's
91    /// layout.
92    ///
93    /// This function must convert the payload into the executable block and pre-validate its
94    /// fields.
95    ///
96    /// Implementers should ensure that the checks are done in the order that conforms with the
97    /// engine-API specification.
98    fn ensure_well_formed_payload(
99        &self,
100        payload: ExecutionPayload,
101        sidecar: ExecutionPayloadSidecar,
102    ) -> Result<SealedBlockFor<Self::Block>, PayloadError>;
103}
104
105/// Type that validates the payloads processed by the engine.
106pub trait EngineValidator<Types: EngineTypes>: PayloadValidator {
107    /// Validates the presence or exclusion of fork-specific fields based on the payload attributes
108    /// and the message version.
109    fn validate_version_specific_fields(
110        &self,
111        version: EngineApiMessageVersion,
112        payload_or_attrs: PayloadOrAttributes<'_, <Types as PayloadTypes>::PayloadAttributes>,
113    ) -> Result<(), EngineObjectValidationError>;
114
115    /// Ensures that the payload attributes are valid for the given [`EngineApiMessageVersion`].
116    fn ensure_well_formed_attributes(
117        &self,
118        version: EngineApiMessageVersion,
119        attributes: &<Types as PayloadTypes>::PayloadAttributes,
120    ) -> Result<(), EngineObjectValidationError>;
121
122    /// Validates the payload attributes with respect to the header.
123    ///
124    /// By default, this enforces that the payload attributes timestamp is greater than the
125    /// timestamp according to:
126    ///   > 7. Client software MUST ensure that payloadAttributes.timestamp is greater than
127    ///   > timestamp
128    ///   > of a block referenced by forkchoiceState.headBlockHash.
129    ///
130    /// See also [engine api spec](https://github.com/ethereum/execution-apis/tree/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine)
131    fn validate_payload_attributes_against_header(
132        &self,
133        attr: &<Types as PayloadTypes>::PayloadAttributes,
134        header: &<Self::Block as Block>::Header,
135    ) -> Result<(), InvalidPayloadAttributesError> {
136        if attr.timestamp() <= header.timestamp() {
137            return Err(InvalidPayloadAttributesError::InvalidTimestamp);
138        }
139        Ok(())
140    }
141}