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::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 parent_beacon_block_root(&self) -> Option<B256>;
47
48 fn timestamp(&self) -> u64;
50
51 fn gas_used(&self) -> u64;
53}
54
55impl ExecutionPayload for ExecutionData {
56 fn parent_hash(&self) -> B256 {
57 self.payload.parent_hash()
58 }
59
60 fn block_hash(&self) -> B256 {
61 self.payload.block_hash()
62 }
63
64 fn block_number(&self) -> u64 {
65 self.payload.block_number()
66 }
67
68 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
69 self.payload.withdrawals()
70 }
71
72 fn parent_beacon_block_root(&self) -> Option<B256> {
73 self.sidecar.parent_beacon_block_root()
74 }
75
76 fn timestamp(&self) -> u64 {
77 self.payload.timestamp()
78 }
79
80 fn gas_used(&self) -> u64 {
81 self.payload.as_v1().gas_used
82 }
83}
84
85#[derive(Debug)]
90pub enum PayloadOrAttributes<'a, Payload, Attributes> {
91 ExecutionPayload(&'a Payload),
93 PayloadAttributes(&'a Attributes),
95}
96
97impl<'a, Payload, Attributes> PayloadOrAttributes<'a, Payload, Attributes> {
98 pub const fn from_execution_payload(payload: &'a Payload) -> Self {
100 Self::ExecutionPayload(payload)
101 }
102
103 pub const fn from_attributes(attributes: &'a Attributes) -> Self {
105 Self::PayloadAttributes(attributes)
106 }
107}
108
109impl<Payload, Attributes> PayloadOrAttributes<'_, Payload, Attributes>
110where
111 Payload: ExecutionPayload,
112 Attributes: PayloadAttributes,
113{
114 pub fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
116 match self {
117 Self::ExecutionPayload(payload) => payload.withdrawals(),
118 Self::PayloadAttributes(attributes) => attributes.withdrawals(),
119 }
120 }
121
122 pub fn timestamp(&self) -> u64 {
124 match self {
125 Self::ExecutionPayload(payload) => payload.timestamp(),
126 Self::PayloadAttributes(attributes) => attributes.timestamp(),
127 }
128 }
129
130 pub fn parent_beacon_block_root(&self) -> Option<B256> {
132 match self {
133 Self::ExecutionPayload(payload) => payload.parent_beacon_block_root(),
134 Self::PayloadAttributes(attributes) => attributes.parent_beacon_block_root(),
135 }
136 }
137
138 pub const fn message_validation_kind(&self) -> MessageValidationKind {
140 match self {
141 Self::ExecutionPayload { .. } => MessageValidationKind::Payload,
142 Self::PayloadAttributes(_) => MessageValidationKind::PayloadAttributes,
143 }
144 }
145}
146
147impl<'a, Payload, AttributesType> From<&'a AttributesType>
148 for PayloadOrAttributes<'a, Payload, AttributesType>
149where
150 AttributesType: PayloadAttributes,
151{
152 fn from(attributes: &'a AttributesType) -> Self {
153 Self::PayloadAttributes(attributes)
154 }
155}
156
157#[cfg(feature = "op")]
158impl ExecutionPayload for op_alloy_rpc_types_engine::OpExecutionData {
159 fn parent_hash(&self) -> B256 {
160 self.parent_hash()
161 }
162
163 fn block_hash(&self) -> B256 {
164 self.block_hash()
165 }
166
167 fn block_number(&self) -> u64 {
168 self.block_number()
169 }
170
171 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
172 self.payload.as_v2().map(|p| &p.withdrawals)
173 }
174
175 fn parent_beacon_block_root(&self) -> Option<B256> {
176 self.sidecar.parent_beacon_block_root()
177 }
178
179 fn timestamp(&self) -> u64 {
180 self.payload.as_v1().timestamp
181 }
182
183 fn gas_used(&self) -> u64 {
184 self.payload.as_v1().gas_used
185 }
186}
187
188impl<Attributes> PayloadOrAttributes<'_, ExecutionData, Attributes>
190where
191 Attributes: PayloadAttributes,
192{
193 pub fn execution_requests(&self) -> Option<&Requests> {
198 if let Self::ExecutionPayload(payload) = self {
199 payload.sidecar.requests()
200 } else {
201 None
202 }
203 }
204}