reth_engine_tree/tree/
error.rs

1//! Internal errors for the tree module.
2
3use alloy_consensus::BlockHeader;
4use reth_consensus::ConsensusError;
5use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError};
6use reth_evm::execute::InternalBlockExecutionError;
7use reth_payload_primitives::NewPayloadError;
8use reth_primitives_traits::{Block, BlockBody, SealedBlock};
9use tokio::sync::oneshot::error::TryRecvError;
10
11/// This is an error that can come from advancing persistence. Either this can be a
12/// [`TryRecvError`], or this can be a [`ProviderError`]
13#[derive(Debug, thiserror::Error)]
14pub enum AdvancePersistenceError {
15    /// An error that can be from failing to receive a value from persistence
16    #[error(transparent)]
17    RecvError(#[from] TryRecvError),
18    /// A provider error
19    #[error(transparent)]
20    Provider(#[from] ProviderError),
21}
22
23#[derive(thiserror::Error)]
24#[error("Failed to insert block (hash={}, number={}, parent_hash={}): {}",
25    .block.hash(),
26    .block.number(),
27    .block.parent_hash(),
28    .kind)]
29struct InsertBlockErrorData<B: Block> {
30    block: SealedBlock<B>,
31    #[source]
32    kind: InsertBlockErrorKind,
33}
34
35impl<B: Block> std::fmt::Debug for InsertBlockErrorData<B> {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        f.debug_struct("InsertBlockError")
38            .field("error", &self.kind)
39            .field("hash", &self.block.hash())
40            .field("number", &self.block.number())
41            .field("parent_hash", &self.block.parent_hash())
42            .field("num_txs", &self.block.body().transactions().len())
43            .finish_non_exhaustive()
44    }
45}
46
47impl<B: Block> InsertBlockErrorData<B> {
48    const fn new(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Self {
49        Self { block, kind }
50    }
51
52    fn boxed(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Box<Self> {
53        Box::new(Self::new(block, kind))
54    }
55}
56
57/// Error thrown when inserting a block failed because the block is considered invalid.
58#[derive(thiserror::Error)]
59#[error(transparent)]
60pub struct InsertBlockError<B: Block> {
61    inner: Box<InsertBlockErrorData<B>>,
62}
63
64// === impl InsertBlockErrorTwo ===
65
66impl<B: Block> InsertBlockError<B> {
67    /// Create a new `InsertInvalidBlockErrorTwo`
68    pub fn new(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Self {
69        Self { inner: InsertBlockErrorData::boxed(block, kind) }
70    }
71
72    /// Create a new `InsertInvalidBlockError` from a consensus error
73    pub fn consensus_error(error: ConsensusError, block: SealedBlock<B>) -> Self {
74        Self::new(block, InsertBlockErrorKind::Consensus(error))
75    }
76
77    /// Consumes the error and returns the block that resulted in the error
78    #[inline]
79    pub fn into_block(self) -> SealedBlock<B> {
80        self.inner.block
81    }
82
83    /// Returns the error kind
84    #[inline]
85    pub const fn kind(&self) -> &InsertBlockErrorKind {
86        &self.inner.kind
87    }
88
89    /// Returns the block that resulted in the error
90    #[inline]
91    pub const fn block(&self) -> &SealedBlock<B> {
92        &self.inner.block
93    }
94
95    /// Consumes the type and returns the block and error kind.
96    #[inline]
97    pub fn split(self) -> (SealedBlock<B>, InsertBlockErrorKind) {
98        let inner = *self.inner;
99        (inner.block, inner.kind)
100    }
101}
102
103impl<B: Block> std::fmt::Debug for InsertBlockError<B> {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        std::fmt::Debug::fmt(&self.inner, f)
106    }
107}
108
109/// All error variants possible when inserting a block
110#[derive(Debug, thiserror::Error)]
111pub enum InsertBlockErrorKind {
112    /// Block violated consensus rules.
113    #[error(transparent)]
114    Consensus(#[from] ConsensusError),
115    /// Block execution failed.
116    #[error(transparent)]
117    Execution(#[from] BlockExecutionError),
118    /// Provider error.
119    #[error(transparent)]
120    Provider(#[from] ProviderError),
121    /// Other errors.
122    #[error(transparent)]
123    Other(#[from] Box<dyn core::error::Error + Send + Sync + 'static>),
124}
125
126impl InsertBlockErrorKind {
127    /// Returns an [`InsertBlockValidationError`] if the error is caused by an invalid block.
128    ///
129    /// Returns an [`InsertBlockFatalError`] if the error is caused by an error that is not
130    /// validation related or is otherwise fatal.
131    ///
132    /// This is intended to be used to determine if we should respond `INVALID` as a response when
133    /// processing a new block.
134    pub fn ensure_validation_error(
135        self,
136    ) -> Result<InsertBlockValidationError, InsertBlockFatalError> {
137        match self {
138            Self::Consensus(err) => Ok(InsertBlockValidationError::Consensus(err)),
139            // other execution errors that are considered internal errors
140            Self::Execution(err) => {
141                match err {
142                    BlockExecutionError::Validation(err) => {
143                        Ok(InsertBlockValidationError::Validation(err))
144                    }
145                    // these are internal errors, not caused by an invalid block
146                    BlockExecutionError::Internal(error) => {
147                        Err(InsertBlockFatalError::BlockExecutionError(error))
148                    }
149                }
150            }
151            Self::Provider(err) => Err(InsertBlockFatalError::Provider(err)),
152            Self::Other(err) => Err(InternalBlockExecutionError::Other(err).into()),
153        }
154    }
155}
156
157/// Error variants that are not caused by invalid blocks
158#[derive(Debug, thiserror::Error)]
159pub enum InsertBlockFatalError {
160    /// A provider error
161    #[error(transparent)]
162    Provider(#[from] ProviderError),
163    /// An internal / fatal block execution error
164    #[error(transparent)]
165    BlockExecutionError(#[from] InternalBlockExecutionError),
166}
167
168/// Error variants that are caused by invalid blocks
169#[derive(Debug, thiserror::Error)]
170pub enum InsertBlockValidationError {
171    /// Block violated consensus rules.
172    #[error(transparent)]
173    Consensus(#[from] ConsensusError),
174    /// Validation error, transparently wrapping [`BlockValidationError`]
175    #[error(transparent)]
176    Validation(#[from] BlockValidationError),
177}
178
179/// Errors that may occur when inserting a payload.
180#[derive(Debug, thiserror::Error)]
181pub enum InsertPayloadError<B: Block> {
182    /// Block validation error
183    #[error(transparent)]
184    Block(#[from] InsertBlockError<B>),
185    /// Payload validation error
186    #[error(transparent)]
187    Payload(#[from] NewPayloadError),
188}