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")]
136 NoWithdrawalsPostShanghai,
137 #[error("withdrawals pre-Shanghai")]
140 HasWithdrawalsPreShanghai,
141 #[error("no parent beacon block root post-cancun")]
144 NoParentBeaconBlockRootPostCancun,
145 #[error("block access list not supported in this engine API version")]
147 BlockAccessListNotSupported,
148 #[error("no block access list post-Amsterdam")]
150 NoBlockAccessListPostAmsterdam,
151 #[error("slot number not supported in this engine API version")]
153 SlotNumberNotSupported,
154 #[error("no slot number post-Amsterdam")]
156 NoSlotNumberPostAmsterdam,
157}
158
159#[derive(thiserror::Error, Debug)]
161pub enum NewPayloadError {
162 #[error(transparent)]
164 Eth(#[from] PayloadError),
165 #[error(transparent)]
167 Other(Box<dyn error::Error + Send + Sync>),
168}
169
170impl NewPayloadError {
171 #[inline]
173 pub fn other(err: impl error::Error + Send + Sync + 'static) -> Self {
174 Self::Other(Box::new(err))
175 }
176
177 #[inline]
179 pub const fn is_block_hash_mismatch(&self) -> bool {
180 matches!(self, Self::Eth(PayloadError::BlockHash { .. }))
181 }
182
183 #[inline]
185 pub const fn is_invalid_versioned_hashes(&self) -> bool {
186 matches!(self, Self::Eth(PayloadError::InvalidVersionedHashes))
187 }
188}
189
190impl From<NewPayloadError> for PayloadStatusEnum {
191 fn from(error: NewPayloadError) -> Self {
192 Self::Invalid { validation_error: error.to_string() }
193 }
194}
195
196impl EngineObjectValidationError {
197 pub fn invalid_params<E>(error: E) -> Self
199 where
200 E: core::error::Error + Send + Sync + 'static,
201 {
202 Self::InvalidParams(Box::new(error))
203 }
204}
205
206#[derive(thiserror::Error, Debug)]
208pub enum InvalidPayloadAttributesError {
209 #[error("invalid timestamp")]
211 InvalidTimestamp,
212 #[error("Invalid params: {0}")]
214 InvalidParams(#[from] Box<dyn core::error::Error + Send + Sync>),
215}
216
217impl From<InvalidPayloadAttributesError> for ForkchoiceUpdateError {
218 fn from(_: InvalidPayloadAttributesError) -> Self {
219 Self::UpdatedInvalidPayloadAttributes
220 }
221}