reth_engine_tree/tree/
error.rsuse alloy_consensus::BlockHeader;
use reth_consensus::ConsensusError;
use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError};
use reth_evm::execute::InternalBlockExecutionError;
use reth_primitives::SealedBlockFor;
use reth_primitives_traits::{Block, BlockBody};
use tokio::sync::oneshot::error::TryRecvError;
#[derive(Debug, thiserror::Error)]
pub enum AdvancePersistenceError {
#[error(transparent)]
RecvError(#[from] TryRecvError),
#[error(transparent)]
Provider(#[from] ProviderError),
}
#[derive(thiserror::Error)]
#[error("Failed to insert block (hash={}, number={}, parent_hash={}): {}",
.block.hash(),
.block.number(),
.block.parent_hash(),
.kind)]
struct InsertBlockErrorData<B: Block> {
block: SealedBlockFor<B>,
#[source]
kind: InsertBlockErrorKind,
}
impl<B: Block> std::fmt::Debug for InsertBlockErrorData<B> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("InsertBlockError")
.field("error", &self.kind)
.field("hash", &self.block.hash())
.field("number", &self.block.number())
.field("parent_hash", &self.block.parent_hash())
.field("num_txs", &self.block.body().transactions().len())
.finish_non_exhaustive()
}
}
impl<B: Block> InsertBlockErrorData<B> {
const fn new(block: SealedBlockFor<B>, kind: InsertBlockErrorKind) -> Self {
Self { block, kind }
}
fn boxed(block: SealedBlockFor<B>, kind: InsertBlockErrorKind) -> Box<Self> {
Box::new(Self::new(block, kind))
}
}
#[derive(thiserror::Error)]
#[error(transparent)]
pub struct InsertBlockError<B: Block> {
inner: Box<InsertBlockErrorData<B>>,
}
impl<B: Block> InsertBlockError<B> {
pub fn new(block: SealedBlockFor<B>, kind: InsertBlockErrorKind) -> Self {
Self { inner: InsertBlockErrorData::boxed(block, kind) }
}
pub fn consensus_error(error: ConsensusError, block: SealedBlockFor<B>) -> Self {
Self::new(block, InsertBlockErrorKind::Consensus(error))
}
pub fn sender_recovery_error(block: SealedBlockFor<B>) -> Self {
Self::new(block, InsertBlockErrorKind::SenderRecovery)
}
#[inline]
pub fn into_block(self) -> SealedBlockFor<B> {
self.inner.block
}
#[inline]
pub const fn kind(&self) -> &InsertBlockErrorKind {
&self.inner.kind
}
#[inline]
pub const fn block(&self) -> &SealedBlockFor<B> {
&self.inner.block
}
#[inline]
pub fn split(self) -> (SealedBlockFor<B>, InsertBlockErrorKind) {
let inner = *self.inner;
(inner.block, inner.kind)
}
}
impl<B: Block> std::fmt::Debug for InsertBlockError<B> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.inner, f)
}
}
#[derive(Debug, thiserror::Error)]
pub enum InsertBlockErrorKind {
#[error("failed to recover senders for block")]
SenderRecovery,
#[error(transparent)]
Consensus(#[from] ConsensusError),
#[error(transparent)]
Execution(#[from] BlockExecutionError),
#[error(transparent)]
Provider(#[from] ProviderError),
#[error(transparent)]
Other(#[from] Box<dyn core::error::Error + Send + Sync + 'static>),
}
impl InsertBlockErrorKind {
pub fn ensure_validation_error(
self,
) -> Result<InsertBlockValidationError, InsertBlockFatalError> {
match self {
Self::SenderRecovery => Ok(InsertBlockValidationError::SenderRecovery),
Self::Consensus(err) => Ok(InsertBlockValidationError::Consensus(err)),
Self::Execution(err) => {
match err {
BlockExecutionError::Validation(err) => {
Ok(InsertBlockValidationError::Validation(err))
}
BlockExecutionError::Consensus(err) => {
Ok(InsertBlockValidationError::Consensus(err))
}
BlockExecutionError::Internal(error) => {
Err(InsertBlockFatalError::BlockExecutionError(error))
}
}
}
Self::Provider(err) => Err(InsertBlockFatalError::Provider(err)),
Self::Other(err) => Err(InternalBlockExecutionError::Other(err).into()),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum InsertBlockFatalError {
#[error(transparent)]
Provider(#[from] ProviderError),
#[error(transparent)]
BlockExecutionError(#[from] InternalBlockExecutionError),
}
#[derive(Debug, thiserror::Error)]
pub enum InsertBlockValidationError {
#[error("failed to recover senders for block")]
SenderRecovery,
#[error(transparent)]
Consensus(#[from] ConsensusError),
#[error(transparent)]
Validation(#[from] BlockValidationError),
}
impl InsertBlockValidationError {
pub const fn is_block_pre_merge(&self) -> bool {
matches!(self, Self::Validation(BlockValidationError::BlockPreMerge { .. }))
}
}