reth_payload_primitives/
traits.rs

1//! Core traits for working with execution payloads.
2
3use crate::PayloadBuilderError;
4use alloc::{boxed::Box, vec::Vec};
5use alloy_eips::{
6    eip4895::{Withdrawal, Withdrawals},
7    eip7685::Requests,
8};
9use alloy_primitives::{Address, B256, U256};
10use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId};
11use core::fmt;
12use reth_chain_state::ExecutedBlockWithTrieUpdates;
13use reth_primitives_traits::{NodePrimitives, SealedBlock, SealedHeader};
14
15/// Represents a successfully built execution payload (block).
16///
17/// Provides access to the underlying block data, execution results, and associated metadata
18/// for payloads ready for execution or propagation.
19#[auto_impl::auto_impl(&, Arc)]
20pub trait BuiltPayload: Send + Sync + fmt::Debug {
21    /// The node's primitive types
22    type Primitives: NodePrimitives;
23
24    /// Returns the built block in its sealed (hash-verified) form.
25    fn block(&self) -> &SealedBlock<<Self::Primitives as NodePrimitives>::Block>;
26
27    /// Returns the total fees collected from all transactions in this block.
28    fn fees(&self) -> U256;
29
30    /// Returns the complete execution result including state updates.
31    ///
32    /// Returns `None` if execution data is not available or not tracked.
33    fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates<Self::Primitives>> {
34        None
35    }
36
37    /// Returns the EIP-7685 execution layer requests included in this block.
38    ///
39    /// These are requests generated by the execution layer that need to be
40    /// processed by the consensus layer (e.g., validator deposits, withdrawals).
41    fn requests(&self) -> Option<Requests>;
42}
43
44/// Attributes used to guide the construction of a new execution payload.
45///
46/// Extends basic payload attributes with additional context needed during the
47/// building process, tracking in-progress payload jobs and their parameters.
48pub trait PayloadBuilderAttributes: Send + Sync + Unpin + fmt::Debug + 'static {
49    /// The external payload attributes format this type can be constructed from.
50    type RpcPayloadAttributes: Send + Sync + 'static;
51    /// The error type used in [`PayloadBuilderAttributes::try_new`].
52    type Error: core::error::Error + Send + Sync + 'static;
53
54    /// Constructs new builder attributes from external payload attributes.
55    ///
56    /// Validates attributes and generates a unique [`PayloadId`] based on the
57    /// parent block, attributes, and version.
58    fn try_new(
59        parent: B256,
60        rpc_payload_attributes: Self::RpcPayloadAttributes,
61        version: u8,
62    ) -> Result<Self, Self::Error>
63    where
64        Self: Sized;
65
66    /// Returns the unique identifier for this payload build job.
67    fn payload_id(&self) -> PayloadId;
68
69    /// Returns the hash of the parent block this payload builds on.
70    fn parent(&self) -> B256;
71
72    /// Returns the timestamp to be used in the payload's header.
73    fn timestamp(&self) -> u64;
74
75    /// Returns the beacon chain block root from the parent block.
76    ///
77    /// Returns `None` for pre-merge blocks or non-beacon contexts.
78    fn parent_beacon_block_root(&self) -> Option<B256>;
79
80    /// Returns the address that should receive transaction fees.
81    fn suggested_fee_recipient(&self) -> Address;
82
83    /// Returns the randomness value for this block.
84    fn prev_randao(&self) -> B256;
85
86    /// Returns the list of withdrawals to be processed in this block.
87    fn withdrawals(&self) -> &Withdrawals;
88}
89
90/// Basic attributes required to initiate payload construction.
91///
92/// Defines minimal parameters needed to build a new execution payload.
93/// Implementations must be serializable for transmission.
94pub trait PayloadAttributes:
95    serde::de::DeserializeOwned + serde::Serialize + fmt::Debug + Clone + Send + Sync + 'static
96{
97    /// Returns the timestamp for the new payload.
98    fn timestamp(&self) -> u64;
99
100    /// Returns the withdrawals to be included in the payload.
101    ///
102    /// `Some` for post-Shanghai blocks, `None` for earlier blocks.
103    fn withdrawals(&self) -> Option<&Vec<Withdrawal>>;
104
105    /// Returns the parent beacon block root.
106    ///
107    /// `Some` for post-merge blocks, `None` for pre-merge blocks.
108    fn parent_beacon_block_root(&self) -> Option<B256>;
109}
110
111impl PayloadAttributes for EthPayloadAttributes {
112    fn timestamp(&self) -> u64 {
113        self.timestamp
114    }
115
116    fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
117        self.withdrawals.as_ref()
118    }
119
120    fn parent_beacon_block_root(&self) -> Option<B256> {
121        self.parent_beacon_block_root
122    }
123}
124
125#[cfg(feature = "op")]
126impl PayloadAttributes for op_alloy_rpc_types_engine::OpPayloadAttributes {
127    fn timestamp(&self) -> u64 {
128        self.payload_attributes.timestamp
129    }
130
131    fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
132        self.payload_attributes.withdrawals.as_ref()
133    }
134
135    fn parent_beacon_block_root(&self) -> Option<B256> {
136        self.payload_attributes.parent_beacon_block_root
137    }
138}
139
140/// Factory trait for creating payload attributes.
141///
142/// Enables different strategies for generating payload attributes based on
143/// contextual information. Useful for testing and specialized building.
144pub trait PayloadAttributesBuilder<Attributes>: Send + Sync + 'static {
145    /// Constructs new payload attributes for the given timestamp.
146    fn build(&self, timestamp: u64) -> Attributes;
147}
148
149impl<Attributes, F> PayloadAttributesBuilder<Attributes> for F
150where
151    F: Fn(u64) -> Attributes + Send + Sync + 'static,
152{
153    fn build(&self, timestamp: u64) -> Attributes {
154        self(timestamp)
155    }
156}
157
158impl<Attributes, L, R> PayloadAttributesBuilder<Attributes> for either::Either<L, R>
159where
160    L: PayloadAttributesBuilder<Attributes>,
161    R: PayloadAttributesBuilder<Attributes>,
162{
163    fn build(&self, timestamp: u64) -> Attributes {
164        match self {
165            Self::Left(l) => l.build(timestamp),
166            Self::Right(r) => r.build(timestamp),
167        }
168    }
169}
170
171impl<Attributes> PayloadAttributesBuilder<Attributes>
172    for Box<dyn PayloadAttributesBuilder<Attributes>>
173where
174    Attributes: 'static,
175{
176    fn build(&self, timestamp: u64) -> Attributes {
177        self.as_ref().build(timestamp)
178    }
179}
180
181/// Trait to build the EVM environment for the next block from the given payload attributes.
182///
183/// Accepts payload attributes from CL, parent header and additional payload builder context.
184pub trait BuildNextEnv<Attributes, Header, Ctx>: Sized {
185    /// Builds the EVM environment for the next block from the given payload attributes.
186    fn build_next_env(
187        attributes: &Attributes,
188        parent: &SealedHeader<Header>,
189        ctx: &Ctx,
190    ) -> Result<Self, PayloadBuilderError>;
191}