use crate::{db::DatabaseError, lockfile::StorageLockError, writer::UnifiedStorageWriterError};
use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{Address, BlockHash, BlockNumber, TxNumber, B256, U256};
use derive_more::Display;
use reth_primitives::{GotExpected, StaticFileSegment, TxHashOrNumber};
#[cfg(feature = "std")]
use std::path::PathBuf;
use alloc::{boxed::Box, string::String};
pub type ProviderResult<Ok> = Result<Ok, ProviderError>;
#[derive(Clone, Debug, Display, PartialEq, Eq)]
pub enum ProviderError {
Database(DatabaseError),
Rlp(alloy_rlp::Error),
#[display("{_0}")]
FsPathError(String),
#[display("nippy jar error: {_0}")]
NippyJar(String),
#[display("trie witness error: {_0}")]
TrieWitnessError(String),
#[display("failed to recover sender for transaction")]
SenderRecoveryError,
#[display("block hash {_0} does not exist in Headers table")]
BlockHashNotFound(BlockHash),
#[display("block meta not found for block #{_0}")]
BlockBodyIndicesNotFound(BlockNumber),
#[display(
"storage change set for address {address} and key {storage_key} at block #{block_number} does not exist"
)]
StorageChangesetNotFound {
block_number: BlockNumber,
address: Address,
storage_key: Box<B256>,
},
#[display("account change set for address {address} at block #{block_number} does not exist")]
AccountChangesetNotFound {
block_number: BlockNumber,
address: Address,
},
#[display("total difficulty not found for block #{_0}")]
TotalDifficultyNotFound(BlockNumber),
#[display("no header found for {_0:?}")]
HeaderNotFound(BlockHashOrNumber),
#[display("no transaction found for {_0:?}")]
TransactionNotFound(TxHashOrNumber),
#[display("no receipt found for {_0:?}")]
ReceiptNotFound(TxHashOrNumber),
#[display("best block does not exist")]
BestBlockNotFound,
#[display("finalized block does not exist")]
FinalizedBlockNotFound,
#[display("safe block does not exist")]
SafeBlockNotFound,
#[display("mismatch of sender and transaction id {tx_id}")]
MismatchOfTransactionAndSenderId {
tx_id: TxNumber,
},
#[display("stored block indices does not match transaction count")]
BlockBodyTransactionCount,
#[display("cache service task stopped")]
CacheServiceUnavailable,
#[display("unknown block {_0}")]
UnknownBlockHash(B256),
#[display("no state found for block {_0}")]
StateForHashNotFound(B256),
#[display("no state found for block number {_0}")]
StateForNumberNotFound(u64),
#[display("unable to find the block number for a given transaction index")]
BlockNumberForTransactionIndexNotFound,
#[display("merkle trie {_0}")]
StateRootMismatch(Box<RootMismatch>),
#[display("unwind merkle trie {_0}")]
UnwindStateRootMismatch(Box<RootMismatch>),
#[display("state at block #{_0} is pruned")]
StateAtBlockPruned(BlockNumber),
#[display("this provider does not support this request")]
UnsupportedProvider,
#[cfg(feature = "std")]
#[display("not able to find {_0} static file at {_1:?}")]
MissingStaticFilePath(StaticFileSegment, PathBuf),
#[display("not able to find {_0} static file for block number {_1}")]
MissingStaticFileBlock(StaticFileSegment, BlockNumber),
#[display("unable to find {_0} static file for transaction id {_1}")]
MissingStaticFileTx(StaticFileSegment, TxNumber),
#[display("unable to write block #{_1} to finalized static file {_0}")]
FinalizedStaticFile(StaticFileSegment, BlockNumber),
#[display("trying to append data to {_0} as block #{_1} but expected block #{_2}")]
UnexpectedStaticFileBlockNumber(StaticFileSegment, BlockNumber, BlockNumber),
#[display("cannot get a writer on a read-only environment.")]
ReadOnlyStaticFileAccess,
#[display("failed to convert block number U256 to u64: {_0}")]
BlockNumberOverflow(U256),
#[display("failed to initialize consistent view: {_0}")]
ConsistentView(Box<ConsistentViewError>),
StorageLockError(StorageLockError),
UnifiedStorageWriterError(UnifiedStorageWriterError),
}
impl From<DatabaseError> for ProviderError {
fn from(error: DatabaseError) -> Self {
Self::Database(error)
}
}
impl From<alloy_rlp::Error> for ProviderError {
fn from(error: alloy_rlp::Error) -> Self {
Self::Rlp(error)
}
}
impl From<StorageLockError> for ProviderError {
fn from(error: StorageLockError) -> Self {
Self::StorageLockError(error)
}
}
impl From<UnifiedStorageWriterError> for ProviderError {
fn from(error: UnifiedStorageWriterError) -> Self {
Self::UnifiedStorageWriterError(error)
}
}
impl core::error::Error for ProviderError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::Database(source) => core::error::Error::source(source),
Self::Rlp(source) => core::error::Error::source(source),
Self::StorageLockError(source) => core::error::Error::source(source),
Self::UnifiedStorageWriterError(source) => core::error::Error::source(source),
_ => Option::None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Display)]
#[display("root mismatch at #{block_number} ({block_hash}): {root}")]
pub struct RootMismatch {
pub root: GotExpected<B256>,
pub block_number: BlockNumber,
pub block_hash: BlockHash,
}
#[derive(Clone, Debug, PartialEq, Eq, Display)]
pub enum ConsistentViewError {
#[display("node is syncing. best block: {best_block:?}")]
Syncing {
best_block: GotExpected<BlockNumber>,
},
#[display("inconsistent database state: {tip:?}")]
Inconsistent {
tip: GotExpected<Option<B256>>,
},
}
impl From<ConsistentViewError> for ProviderError {
fn from(error: ConsistentViewError) -> Self {
Self::ConsistentView(Box::new(error))
}
}