Skip to main content

reth_engine_tree/tree/
error.rs

1//! Internal errors for the tree module.
2
3use crate::tree::payload_processor::bal::BalExecutionError;
4use alloy_consensus::BlockHeader;
5use reth_consensus::ConsensusError;
6pub use reth_engine_primitives::{
7    BlockAccessListDecodeError, InsertBlockErrorKind, InsertBlockFatalError,
8    InsertBlockProcessingError, InsertBlockValidationError,
9};
10use reth_errors::ProviderError;
11use reth_payload_primitives::NewPayloadError;
12use reth_primitives_traits::{Block, BlockBody, SealedBlock};
13
14/// This is an error that can come from advancing persistence.
15#[derive(Debug, thiserror::Error)]
16pub enum AdvancePersistenceError {
17    /// The persistence channel was closed unexpectedly
18    #[error("persistence channel closed")]
19    ChannelClosed,
20    /// State/trie catch-up could not construct an input despite split persistence frontiers.
21    #[error("state/trie catch-up input unavailable while persistence frontiers are split")]
22    StateTrieCatchupUnavailable,
23    /// A provider error
24    #[error(transparent)]
25    Provider(#[from] ProviderError),
26}
27
28#[derive(thiserror::Error)]
29#[error("Failed to insert block (hash={}, number={}, parent_hash={}): {}",
30    .block.hash(),
31    .block.number(),
32    .block.parent_hash(),
33    .kind)]
34struct InsertBlockErrorData<B: Block> {
35    block: SealedBlock<B>,
36    #[source]
37    kind: InsertBlockErrorKind,
38}
39
40impl<B: Block> std::fmt::Debug for InsertBlockErrorData<B> {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        f.debug_struct("InsertBlockError")
43            .field("error", &self.kind)
44            .field("hash", &self.block.hash())
45            .field("number", &self.block.number())
46            .field("parent_hash", &self.block.parent_hash())
47            .field("num_txs", &self.block.body().transactions().len())
48            .finish_non_exhaustive()
49    }
50}
51
52impl<B: Block> InsertBlockErrorData<B> {
53    const fn new(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Self {
54        Self { block, kind }
55    }
56
57    fn boxed(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Box<Self> {
58        Box::new(Self::new(block, kind))
59    }
60}
61
62/// Error thrown when inserting a block failed because the block is considered invalid.
63#[derive(thiserror::Error)]
64#[error(transparent)]
65pub struct InsertBlockError<B: Block> {
66    inner: Box<InsertBlockErrorData<B>>,
67}
68
69// === impl InsertBlockErrorTwo ===
70
71impl<B: Block> InsertBlockError<B> {
72    /// Create a new `InsertInvalidBlockErrorTwo`
73    pub fn new(block: SealedBlock<B>, kind: InsertBlockErrorKind) -> Self {
74        Self { inner: InsertBlockErrorData::boxed(block, kind) }
75    }
76
77    /// Create a new `InsertInvalidBlockError` from a consensus error
78    pub fn consensus_error(error: ConsensusError, block: SealedBlock<B>) -> Self {
79        Self::new(block, InsertBlockErrorKind::Consensus(error))
80    }
81
82    /// Consumes the error and returns the block that resulted in the error
83    #[inline]
84    pub fn into_block(self) -> SealedBlock<B> {
85        self.inner.block
86    }
87
88    /// Returns the error kind
89    #[inline]
90    pub const fn kind(&self) -> &InsertBlockErrorKind {
91        &self.inner.kind
92    }
93
94    /// Returns the block that resulted in the error
95    #[inline]
96    pub const fn block(&self) -> &SealedBlock<B> {
97        &self.inner.block
98    }
99
100    /// Consumes the type and returns the block and error kind.
101    #[inline]
102    pub fn split(self) -> (SealedBlock<B>, InsertBlockErrorKind) {
103        let inner = *self.inner;
104        (inner.block, inner.kind)
105    }
106}
107
108impl<B: Block> std::fmt::Debug for InsertBlockError<B> {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        std::fmt::Debug::fmt(&self.inner, f)
111    }
112}
113
114impl From<BalExecutionError> for InsertBlockErrorKind {
115    fn from(e: BalExecutionError) -> Self {
116        match e {
117            BalExecutionError::Consensus(inner) => Self::Consensus(inner),
118            BalExecutionError::BlockAccessListDecode(inner) => Self::BlockAccessListDecode(inner),
119            BalExecutionError::Execution(inner) => Self::Execution(inner),
120            BalExecutionError::Provider(inner) => Self::Provider(inner),
121            BalExecutionError::Other(inner) => Self::Other(inner),
122        }
123    }
124}
125
126/// Errors that may occur when inserting a payload.
127#[derive(Debug, thiserror::Error)]
128pub enum InsertPayloadError<B: Block> {
129    /// Block validation error
130    #[error(transparent)]
131    Block(#[from] InsertBlockError<B>),
132    /// Payload validation error
133    #[error(transparent)]
134    Payload(#[from] NewPayloadError),
135}