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 fn transaction_count(&self) -> usize;
61}
62
63impl ExecutionPayload for ExecutionData {
64 fn parent_hash(&self) -> B256 {
65 self.payload.parent_hash()
66 }
67
68 fn block_hash(&self) -> B256 {
69 self.payload.block_hash()
70 }
71
72 fn block_number(&self) -> u64 {
73 self.payload.block_number()
74 }
75
76 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
77 self.payload.withdrawals()
78 }
79
80 fn block_access_list(&self) -> Option<&Bytes> {
81 None
82 }
83
84 fn parent_beacon_block_root(&self) -> Option<B256> {
85 self.sidecar.parent_beacon_block_root()
86 }
87
88 fn timestamp(&self) -> u64 {
89 self.payload.timestamp()
90 }
91
92 fn gas_used(&self) -> u64 {
93 self.payload.as_v1().gas_used
94 }
95
96 fn transaction_count(&self) -> usize {
97 self.payload.as_v1().transactions.len()
98 }
99}
100
101#[derive(Debug)]
106pub enum PayloadOrAttributes<'a, Payload, Attributes> {
107 ExecutionPayload(&'a Payload),
109 PayloadAttributes(&'a Attributes),
111}
112
113impl<'a, Payload, Attributes> PayloadOrAttributes<'a, Payload, Attributes> {
114 pub const fn from_execution_payload(payload: &'a Payload) -> Self {
116 Self::ExecutionPayload(payload)
117 }
118
119 pub const fn from_attributes(attributes: &'a Attributes) -> Self {
121 Self::PayloadAttributes(attributes)
122 }
123}
124
125impl<Payload, Attributes> PayloadOrAttributes<'_, Payload, Attributes>
126where
127 Payload: ExecutionPayload,
128 Attributes: PayloadAttributes,
129{
130 pub fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
132 match self {
133 Self::ExecutionPayload(payload) => payload.withdrawals(),
134 Self::PayloadAttributes(attributes) => attributes.withdrawals(),
135 }
136 }
137
138 pub fn timestamp(&self) -> u64 {
140 match self {
141 Self::ExecutionPayload(payload) => payload.timestamp(),
142 Self::PayloadAttributes(attributes) => attributes.timestamp(),
143 }
144 }
145
146 pub fn parent_beacon_block_root(&self) -> Option<B256> {
148 match self {
149 Self::ExecutionPayload(payload) => payload.parent_beacon_block_root(),
150 Self::PayloadAttributes(attributes) => attributes.parent_beacon_block_root(),
151 }
152 }
153
154 pub const fn message_validation_kind(&self) -> MessageValidationKind {
156 match self {
157 Self::ExecutionPayload { .. } => MessageValidationKind::Payload,
158 Self::PayloadAttributes(_) => MessageValidationKind::PayloadAttributes,
159 }
160 }
161}
162
163impl<'a, Payload, AttributesType> From<&'a AttributesType>
164 for PayloadOrAttributes<'a, Payload, AttributesType>
165where
166 AttributesType: PayloadAttributes,
167{
168 fn from(attributes: &'a AttributesType) -> Self {
169 Self::PayloadAttributes(attributes)
170 }
171}
172
173#[cfg(feature = "op")]
174impl ExecutionPayload for op_alloy_rpc_types_engine::OpExecutionData {
175 fn parent_hash(&self) -> B256 {
176 self.parent_hash()
177 }
178
179 fn block_hash(&self) -> B256 {
180 self.block_hash()
181 }
182
183 fn block_number(&self) -> u64 {
184 self.block_number()
185 }
186
187 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
188 self.payload.as_v2().map(|p| &p.withdrawals)
189 }
190
191 fn block_access_list(&self) -> Option<&Bytes> {
192 None
193 }
194
195 fn parent_beacon_block_root(&self) -> Option<B256> {
196 self.sidecar.parent_beacon_block_root()
197 }
198
199 fn timestamp(&self) -> u64 {
200 self.payload.as_v1().timestamp
201 }
202
203 fn gas_used(&self) -> u64 {
204 self.payload.as_v1().gas_used
205 }
206
207 fn transaction_count(&self) -> usize {
208 self.payload.as_v1().transactions.len()
209 }
210}
211
212impl<Attributes> PayloadOrAttributes<'_, ExecutionData, Attributes>
214where
215 Attributes: PayloadAttributes,
216{
217 pub fn execution_requests(&self) -> Option<&Requests> {
222 if let Self::ExecutionPayload(payload) = self {
223 payload.sidecar.requests()
224 } else {
225 None
226 }
227 }
228}