Skip to main content

reth_engine_primitives/
error.rs

1use alloc::boxed::Box;
2use alloy_rpc_types_engine::ForkchoiceUpdateError;
3use reth_errors::{BlockExecutionError, BlockValidationError, ConsensusError, ProviderError};
4use reth_execution_errors::InternalBlockExecutionError;
5
6/// Represents all error cases when handling a new payload.
7///
8/// This represents all possible error cases that must be returned as JSON RPC errors back to the
9/// beacon node.
10#[derive(Debug, thiserror::Error)]
11pub enum BeaconOnNewPayloadError {
12    /// Thrown when the engine task is unavailable/stopped.
13    #[error("beacon consensus engine task stopped")]
14    EngineUnavailable,
15    /// An internal error occurred, not necessarily related to the payload.
16    #[error(transparent)]
17    Internal(Box<dyn core::error::Error + Send + Sync>),
18}
19
20impl BeaconOnNewPayloadError {
21    /// Create a new internal error.
22    pub fn internal<E: core::error::Error + Send + Sync + 'static>(e: E) -> Self {
23        Self::Internal(Box::new(e))
24    }
25}
26
27/// Represents error cases for an applied forkchoice update.
28///
29/// This represents all possible error cases, that must be returned as JSON RPC errors back to the
30/// beacon node.
31#[derive(Debug, thiserror::Error)]
32pub enum BeaconForkChoiceUpdateError {
33    /// Thrown when a forkchoice update resulted in an error.
34    #[error("forkchoice update error: {0}")]
35    ForkchoiceUpdateError(#[from] ForkchoiceUpdateError),
36    /// Thrown when the engine task is unavailable/stopped.
37    #[error("beacon consensus engine task stopped")]
38    EngineUnavailable,
39    /// An internal error occurred, not necessarily related to the update.
40    #[error(transparent)]
41    Internal(Box<dyn core::error::Error + Send + Sync>),
42}
43
44impl BeaconForkChoiceUpdateError {
45    /// Create a new internal error.
46    pub fn internal<E: core::error::Error + Send + Sync + 'static>(e: E) -> Self {
47        Self::Internal(Box::new(e))
48    }
49}
50
51/// All error variants possible when inserting or validating a block.
52#[derive(Debug, thiserror::Error)]
53pub enum InsertBlockErrorKind {
54    /// Block violated consensus rules.
55    #[error(transparent)]
56    Consensus(#[from] ConsensusError),
57    /// Block execution failed.
58    #[error(transparent)]
59    Execution(#[from] BlockExecutionError),
60    /// Provider error.
61    #[error(transparent)]
62    Provider(#[from] ProviderError),
63    /// Other errors.
64    #[error(transparent)]
65    Other(#[from] Box<dyn core::error::Error + Send + Sync + 'static>),
66}
67
68impl InsertBlockErrorKind {
69    /// Returns whether the error was caused by an invalid block.
70    pub const fn is_validation_error(&self) -> bool {
71        matches!(self, Self::Consensus(_) | Self::Execution(BlockExecutionError::Validation(_)))
72    }
73
74    /// Returns an [`InsertBlockValidationError`] if the error is caused by an invalid block.
75    ///
76    /// Returns an [`InsertBlockFatalError`] if the error is caused by an error that is not
77    /// validation related or is otherwise fatal.
78    ///
79    /// This is intended to be used to determine if we should respond `INVALID` as a response when
80    /// processing a new block.
81    pub fn ensure_validation_error(
82        self,
83    ) -> Result<InsertBlockValidationError, InsertBlockFatalError> {
84        match self {
85            Self::Consensus(err) => Ok(InsertBlockValidationError::Consensus(err)),
86            Self::Execution(err) => match err {
87                BlockExecutionError::Validation(err) => {
88                    Ok(InsertBlockValidationError::Validation(err))
89                }
90                BlockExecutionError::Internal(error) => {
91                    Err(InsertBlockFatalError::BlockExecutionError(error))
92                }
93            },
94            Self::Provider(err) => Err(InsertBlockFatalError::Provider(err)),
95            Self::Other(err) => Err(InternalBlockExecutionError::Other(err).into()),
96        }
97    }
98}
99
100/// Error variants that are not caused by invalid blocks.
101#[derive(Debug, thiserror::Error)]
102pub enum InsertBlockFatalError {
103    /// A provider error.
104    #[error(transparent)]
105    Provider(#[from] ProviderError),
106    /// An internal or fatal block execution error.
107    #[error(transparent)]
108    BlockExecutionError(#[from] InternalBlockExecutionError),
109}
110
111/// Error variants that are caused by invalid blocks.
112#[derive(Debug, thiserror::Error)]
113pub enum InsertBlockValidationError {
114    /// Block violated consensus rules.
115    #[error(transparent)]
116    Consensus(#[from] ConsensusError),
117    /// Validation error, transparently wrapping [`BlockValidationError`].
118    #[error(transparent)]
119    Validation(#[from] BlockValidationError),
120}