reth_payload_primitives/
payload.rs
1use crate::{MessageValidationKind, PayloadAttributes};
2use alloc::vec::Vec;
3use alloy_eips::{eip4895::Withdrawal, eip7685::Requests};
4use alloy_primitives::B256;
5use alloy_rpc_types_engine::ExecutionData;
6use core::fmt::Debug;
7use serde::{de::DeserializeOwned, Serialize};
8
9pub trait ExecutionPayload:
11 Serialize + DeserializeOwned + Debug + Clone + Send + Sync + 'static
12{
13 fn parent_hash(&self) -> B256;
15
16 fn block_hash(&self) -> B256;
18
19 fn block_number(&self) -> u64;
21
22 fn withdrawals(&self) -> Option<&Vec<Withdrawal>>;
24
25 fn parent_beacon_block_root(&self) -> Option<B256>;
27
28 fn timestamp(&self) -> u64;
30
31 fn gas_used(&self) -> u64;
33}
34
35impl ExecutionPayload for ExecutionData {
36 fn parent_hash(&self) -> B256 {
37 self.payload.parent_hash()
38 }
39
40 fn block_hash(&self) -> B256 {
41 self.payload.block_hash()
42 }
43
44 fn block_number(&self) -> u64 {
45 self.payload.block_number()
46 }
47
48 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
49 self.payload.withdrawals()
50 }
51
52 fn parent_beacon_block_root(&self) -> Option<B256> {
53 self.sidecar.parent_beacon_block_root()
54 }
55
56 fn timestamp(&self) -> u64 {
57 self.payload.timestamp()
58 }
59
60 fn gas_used(&self) -> u64 {
61 self.payload.as_v1().gas_used
62 }
63}
64
65#[derive(Debug)]
70pub enum PayloadOrAttributes<'a, Payload, Attributes> {
71 ExecutionPayload(&'a Payload),
73 PayloadAttributes(&'a Attributes),
75}
76
77impl<'a, Payload, Attributes> PayloadOrAttributes<'a, Payload, Attributes> {
78 pub const fn from_execution_payload(payload: &'a Payload) -> Self {
80 Self::ExecutionPayload(payload)
81 }
82
83 pub const fn from_attributes(attributes: &'a Attributes) -> Self {
85 Self::PayloadAttributes(attributes)
86 }
87}
88
89impl<Payload, Attributes> PayloadOrAttributes<'_, Payload, Attributes>
90where
91 Payload: ExecutionPayload,
92 Attributes: PayloadAttributes,
93{
94 pub fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
96 match self {
97 Self::ExecutionPayload(payload) => payload.withdrawals(),
98 Self::PayloadAttributes(attributes) => attributes.withdrawals(),
99 }
100 }
101
102 pub fn timestamp(&self) -> u64 {
104 match self {
105 Self::ExecutionPayload(payload) => payload.timestamp(),
106 Self::PayloadAttributes(attributes) => attributes.timestamp(),
107 }
108 }
109
110 pub fn parent_beacon_block_root(&self) -> Option<B256> {
112 match self {
113 Self::ExecutionPayload(payload) => payload.parent_beacon_block_root(),
114 Self::PayloadAttributes(attributes) => attributes.parent_beacon_block_root(),
115 }
116 }
117
118 pub const fn message_validation_kind(&self) -> MessageValidationKind {
120 match self {
121 Self::ExecutionPayload { .. } => MessageValidationKind::Payload,
122 Self::PayloadAttributes(_) => MessageValidationKind::PayloadAttributes,
123 }
124 }
125}
126
127impl<'a, Payload, AttributesType> From<&'a AttributesType>
128 for PayloadOrAttributes<'a, Payload, AttributesType>
129where
130 AttributesType: PayloadAttributes,
131{
132 fn from(attributes: &'a AttributesType) -> Self {
133 Self::PayloadAttributes(attributes)
134 }
135}
136
137#[cfg(feature = "op")]
138impl ExecutionPayload for op_alloy_rpc_types_engine::OpExecutionData {
139 fn parent_hash(&self) -> B256 {
140 self.parent_hash()
141 }
142
143 fn block_hash(&self) -> B256 {
144 self.block_hash()
145 }
146
147 fn block_number(&self) -> u64 {
148 self.block_number()
149 }
150
151 fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
152 self.payload.as_v2().map(|p| &p.withdrawals)
153 }
154
155 fn parent_beacon_block_root(&self) -> Option<B256> {
156 self.sidecar.parent_beacon_block_root()
157 }
158
159 fn timestamp(&self) -> u64 {
160 self.payload.as_v1().timestamp
161 }
162
163 fn gas_used(&self) -> u64 {
164 self.payload.as_v1().gas_used
165 }
166}
167
168impl<'a, Attributes> PayloadOrAttributes<'a, ExecutionData, Attributes>
170where
171 Attributes: PayloadAttributes,
172{
173 pub fn execution_requests(&self) -> Option<&Requests> {
182 if let Self::ExecutionPayload(payload) = self {
183 payload.sidecar.requests()
184 } else {
185 None
186 }
187 }
188}