reth_payload_primitives/
error.rs1use alloc::{boxed::Box, string::ToString};
4use alloy_primitives::B256;
5use alloy_rpc_types_engine::{ForkchoiceUpdateError, PayloadError, PayloadStatusEnum};
6use core::error;
7use reth_errors::{BlockExecutionError, ProviderError, RethError};
8use tokio::sync::{mpsc, oneshot};
9
10#[derive(Debug, thiserror::Error)]
12pub enum PayloadBuilderError {
13 #[error("missing parent header: {0}")]
15 MissingParentHeader(B256),
16 #[error("missing parent block {0}")]
18 MissingParentBlock(B256),
19 #[error("sender has been dropped")]
21 ChannelClosed,
22 #[error("missing payload")]
24 MissingPayload,
25 #[error(transparent)]
27 Internal(#[from] RethError),
28 #[error("evm execution error: {0}")]
30 EvmExecutionError(Box<dyn core::error::Error + Send + Sync>),
31 #[error(transparent)]
33 Other(Box<dyn core::error::Error + Send + Sync>),
34 #[error("invalid payload attributes: {0}")]
42 InvalidAttributes(Box<dyn core::error::Error + Send + Sync>),
43}
44
45impl PayloadBuilderError {
46 pub fn evm<E>(error: E) -> Self
48 where
49 E: core::error::Error + Send + Sync + 'static,
50 {
51 Self::EvmExecutionError(Box::new(error))
52 }
53
54 pub fn other<E>(error: E) -> Self
56 where
57 E: core::error::Error + Send + Sync + 'static,
58 {
59 Self::Other(Box::new(error))
60 }
61
62 pub fn invalid_attributes<E>(error: E) -> Self
64 where
65 E: core::error::Error + Send + Sync + 'static,
66 {
67 Self::InvalidAttributes(Box::new(error))
68 }
69}
70
71impl From<ProviderError> for PayloadBuilderError {
72 fn from(error: ProviderError) -> Self {
73 Self::Internal(RethError::Provider(error))
74 }
75}
76
77impl From<oneshot::error::RecvError> for PayloadBuilderError {
78 fn from(_: oneshot::error::RecvError) -> Self {
79 Self::ChannelClosed
80 }
81}
82
83impl From<BlockExecutionError> for PayloadBuilderError {
84 fn from(error: BlockExecutionError) -> Self {
85 Self::evm(error)
86 }
87}
88
89impl<T> From<mpsc::error::SendError<T>> for PayloadBuilderError {
90 fn from(_: mpsc::error::SendError<T>) -> Self {
91 Self::ChannelClosed
92 }
93}
94
95#[derive(thiserror::Error, Debug)]
101pub enum EngineObjectValidationError {
102 #[error("Payload validation error: {0}")]
105 Payload(VersionSpecificValidationError),
106
107 #[error("Payload attributes validation error: {0}")]
110 PayloadAttributes(VersionSpecificValidationError),
111
112 #[error("Unsupported fork")]
116 UnsupportedFork,
117 #[error("Invalid params: {0}")]
119 InvalidParams(#[from] Box<dyn core::error::Error + Send + Sync>),
120}
121
122#[derive(thiserror::Error, Debug)]
126pub enum VersionSpecificValidationError {
127 #[error("parent beacon block root not supported before V3")]
130 ParentBeaconBlockRootNotSupportedBeforeV3,
131 #[error("withdrawals not supported in V1")]
133 WithdrawalsNotSupportedInV1,
134 #[error("no withdrawals post-Shanghai")]
137 NoWithdrawalsPostShanghai,
138 #[error("withdrawals pre-Shanghai")]
141 HasWithdrawalsPreShanghai,
142 #[error("no parent beacon block root post-cancun")]
145 NoParentBeaconBlockRootPostCancun,
146 #[error("block access list not supported in this engine API version")]
148 BlockAccessListNotSupported,
149 #[error("no block access list post-Amsterdam")]
152 NoBlockAccessListPostAmsterdam,
153 #[error("block access list pre-Amsterdam")]
156 HasBlockAccessListPreAmsterdam,
157 #[error("slot number not supported in this engine API version")]
159 SlotNumberNotSupported,
160 #[error("no slot number post-Amsterdam")]
163 NoSlotNumberPostAmsterdam,
164 #[error("slot number pre-Amsterdam")]
167 HasSlotNumberPreAmsterdam,
168}
169
170#[derive(thiserror::Error, Debug)]
172pub enum NewPayloadError {
173 #[error(transparent)]
175 Eth(#[from] PayloadError),
176 #[error(transparent)]
178 Other(Box<dyn error::Error + Send + Sync>),
179}
180
181impl NewPayloadError {
182 #[inline]
184 pub fn other(err: impl error::Error + Send + Sync + 'static) -> Self {
185 Self::Other(Box::new(err))
186 }
187
188 #[inline]
190 pub const fn is_block_hash_mismatch(&self) -> bool {
191 matches!(self, Self::Eth(PayloadError::BlockHash { .. }))
192 }
193
194 #[inline]
196 pub const fn is_invalid_versioned_hashes(&self) -> bool {
197 matches!(self, Self::Eth(PayloadError::InvalidVersionedHashes))
198 }
199}
200
201impl From<NewPayloadError> for PayloadStatusEnum {
202 fn from(error: NewPayloadError) -> Self {
203 Self::Invalid { validation_error: error.to_string() }
204 }
205}
206
207impl EngineObjectValidationError {
208 pub fn invalid_params<E>(error: E) -> Self
210 where
211 E: core::error::Error + Send + Sync + 'static,
212 {
213 Self::InvalidParams(Box::new(error))
214 }
215}
216
217#[derive(thiserror::Error, Debug)]
219pub enum InvalidPayloadAttributesError {
220 #[error("invalid timestamp")]
222 InvalidTimestamp,
223 #[error("Invalid params: {0}")]
225 InvalidParams(#[from] Box<dyn core::error::Error + Send + Sync>),
226}
227
228impl From<InvalidPayloadAttributesError> for ForkchoiceUpdateError {
229 fn from(_: InvalidPayloadAttributesError) -> Self {
230 Self::UpdatedInvalidPayloadAttributes
231 }
232}