reth_payload_primitives/
payload.rs1use crate::{MessageValidationKind, PayloadAttributes};
4use alloc::vec::Vec;
5use alloy_eips::{eip1898::BlockWithParent, eip4895::Withdrawal, eip7685::Requests, BlockNumHash};
6use alloy_primitives::{Bytes, B256};
7use alloy_rpc_types_engine::ExecutionData;
8use core::fmt::Debug;
9use serde::{de::DeserializeOwned, Serialize};
10
11pub trait ExecutionPayload:
17 Serialize + DeserializeOwned + Debug + Clone + Send + Sync + 'static
18{
19 fn parent_hash(&self) -> B256;
21
22 fn block_hash(&self) -> B256;
24
25 fn block_number(&self) -> u64;
27
28 fn num_hash(&self) -> BlockNumHash {
30 BlockNumHash::new(self.block_number(), self.block_hash())
31 }
32
33 fn block_with_parent(&self) -> BlockWithParent {
35 BlockWithParent::new(self.parent_hash(), self.num_hash())
36 }
37
38 fn withdrawals(&self) -> Option<&Vec<Withdrawal>>;
42
43 fn block_access_list(&self) -> Option<&Bytes>;
47
48 fn parent_beacon_block_root(&self) -> Option<B256>;
52
53 fn timestamp(&self) -> u64;
55
56 fn gas_used(&self) -> u64;
58}
59
60impl ExecutionPayload for ExecutionData {
61 fn parent_hash(&self) -> B256 {
62 self.payload.parent_hash()
63 }
64
65 fn block_hash(&self) -> B256 {
66 self.payload.block_hash()
67 }
68
69 fn block_number(&self) -> u64 {
70 self.payload.block_number()
71 }
72
73 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
74 self.payload.withdrawals()
75 }
76
77 fn block_access_list(&self) -> Option<&Bytes> {
78 None
79 }
80
81 fn parent_beacon_block_root(&self) -> Option<B256> {
82 self.sidecar.parent_beacon_block_root()
83 }
84
85 fn timestamp(&self) -> u64 {
86 self.payload.timestamp()
87 }
88
89 fn gas_used(&self) -> u64 {
90 self.payload.as_v1().gas_used
91 }
92}
93
94#[derive(Debug)]
99pub enum PayloadOrAttributes<'a, Payload, Attributes> {
100 ExecutionPayload(&'a Payload),
102 PayloadAttributes(&'a Attributes),
104}
105
106impl<'a, Payload, Attributes> PayloadOrAttributes<'a, Payload, Attributes> {
107 pub const fn from_execution_payload(payload: &'a Payload) -> Self {
109 Self::ExecutionPayload(payload)
110 }
111
112 pub const fn from_attributes(attributes: &'a Attributes) -> Self {
114 Self::PayloadAttributes(attributes)
115 }
116}
117
118impl<Payload, Attributes> PayloadOrAttributes<'_, Payload, Attributes>
119where
120 Payload: ExecutionPayload,
121 Attributes: PayloadAttributes,
122{
123 pub fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
125 match self {
126 Self::ExecutionPayload(payload) => payload.withdrawals(),
127 Self::PayloadAttributes(attributes) => attributes.withdrawals(),
128 }
129 }
130
131 pub fn timestamp(&self) -> u64 {
133 match self {
134 Self::ExecutionPayload(payload) => payload.timestamp(),
135 Self::PayloadAttributes(attributes) => attributes.timestamp(),
136 }
137 }
138
139 pub fn parent_beacon_block_root(&self) -> Option<B256> {
141 match self {
142 Self::ExecutionPayload(payload) => payload.parent_beacon_block_root(),
143 Self::PayloadAttributes(attributes) => attributes.parent_beacon_block_root(),
144 }
145 }
146
147 pub const fn message_validation_kind(&self) -> MessageValidationKind {
149 match self {
150 Self::ExecutionPayload { .. } => MessageValidationKind::Payload,
151 Self::PayloadAttributes(_) => MessageValidationKind::PayloadAttributes,
152 }
153 }
154}
155
156impl<'a, Payload, AttributesType> From<&'a AttributesType>
157 for PayloadOrAttributes<'a, Payload, AttributesType>
158where
159 AttributesType: PayloadAttributes,
160{
161 fn from(attributes: &'a AttributesType) -> Self {
162 Self::PayloadAttributes(attributes)
163 }
164}
165
166#[cfg(feature = "op")]
167impl ExecutionPayload for op_alloy_rpc_types_engine::OpExecutionData {
168 fn parent_hash(&self) -> B256 {
169 self.parent_hash()
170 }
171
172 fn block_hash(&self) -> B256 {
173 self.block_hash()
174 }
175
176 fn block_number(&self) -> u64 {
177 self.block_number()
178 }
179
180 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
181 self.payload.as_v2().map(|p| &p.withdrawals)
182 }
183
184 fn block_access_list(&self) -> Option<&Bytes> {
185 None
186 }
187
188 fn parent_beacon_block_root(&self) -> Option<B256> {
189 self.sidecar.parent_beacon_block_root()
190 }
191
192 fn timestamp(&self) -> u64 {
193 self.payload.as_v1().timestamp
194 }
195
196 fn gas_used(&self) -> u64 {
197 self.payload.as_v1().gas_used
198 }
199}
200
201impl<Attributes> PayloadOrAttributes<'_, ExecutionData, Attributes>
203where
204 Attributes: PayloadAttributes,
205{
206 pub fn execution_requests(&self) -> Option<&Requests> {
211 if let Self::ExecutionPayload(payload) = self {
212 payload.sidecar.requests()
213 } else {
214 None
215 }
216 }
217}