reth_storage_errors/
provider.rs

1use crate::{db::DatabaseError, lockfile::StorageLockError, writer::UnifiedStorageWriterError};
2use alloc::{boxed::Box, string::String};
3use alloy_eips::{BlockHashOrNumber, HashOrNumber};
4use alloy_primitives::{Address, BlockHash, BlockNumber, TxNumber, B256};
5use derive_more::Display;
6use reth_enclave::EnclaveError;
7use reth_primitives_traits::GotExpected;
8use reth_static_file_types::StaticFileSegment;
9
10/// Provider result type.
11pub type ProviderResult<Ok> = Result<Ok, ProviderError>;
12
13/// Bundled errors variants thrown by various providers.
14#[derive(Clone, Debug, Display, PartialEq, Eq)]
15pub enum ProviderError {
16    /// Database error.
17    Database(DatabaseError),
18    /// RLP error.
19    Rlp(alloy_rlp::Error),
20    /// Filesystem path error.
21    #[display("{_0}")]
22    FsPathError(String),
23    /// Nippy jar error.
24    #[display("nippy jar error: {_0}")]
25    NippyJar(String),
26    /// Trie witness error.
27    #[display("trie witness error: {_0}")]
28    TrieWitnessError(String),
29    /// Error when recovering the sender for a transaction
30    #[display("failed to recover sender for transaction")]
31    SenderRecoveryError,
32    /// The header number was not found for the given block hash.
33    #[display("block hash {_0} does not exist in Headers table")]
34    BlockHashNotFound(BlockHash),
35    /// A block body is missing.
36    #[display("block meta not found for block #{_0}")]
37    BlockBodyIndicesNotFound(BlockNumber),
38    /// The transition ID was found for the given address and storage key, but the changeset was
39    /// not found.
40    #[display(
41        "storage change set for address {address} and key {storage_key} at block #{block_number} does not exist"
42    )]
43    StorageChangesetNotFound {
44        /// The block number found for the address and storage key.
45        block_number: BlockNumber,
46        /// The account address.
47        address: Address,
48        /// The storage key.
49        // NOTE: This is a Box only because otherwise this variant is 16 bytes larger than the
50        // second largest (which uses `BlockHashOrNumber`).
51        storage_key: Box<B256>,
52    },
53    /// The block number was found for the given address, but the changeset was not found.
54    #[display("account change set for address {address} at block #{block_number} does not exist")]
55    AccountChangesetNotFound {
56        /// Block number found for the address.
57        block_number: BlockNumber,
58        /// The account address.
59        address: Address,
60    },
61    /// The total difficulty for a block is missing.
62    #[display("total difficulty not found for block #{_0}")]
63    TotalDifficultyNotFound(BlockNumber),
64    /// when required header related data was not found but was required.
65    #[display("no header found for {_0:?}")]
66    HeaderNotFound(BlockHashOrNumber),
67    /// The specific transaction identified by hash or id is missing.
68    #[display("no transaction found for {_0:?}")]
69    TransactionNotFound(HashOrNumber),
70    /// The specific receipt for a transaction identified by hash or id is missing
71    #[display("no receipt found for {_0:?}")]
72    ReceiptNotFound(HashOrNumber),
73    /// Unable to find the best block.
74    #[display("best block does not exist")]
75    BestBlockNotFound,
76    /// Unable to find the finalized block.
77    #[display("finalized block does not exist")]
78    FinalizedBlockNotFound,
79    /// Unable to find the safe block.
80    #[display("safe block does not exist")]
81    SafeBlockNotFound,
82    /// Thrown when the cache service task dropped.
83    #[display("cache service task stopped")]
84    CacheServiceUnavailable,
85    /// Thrown when we failed to lookup a block for the pending state.
86    #[display("unknown block {_0}")]
87    UnknownBlockHash(B256),
88    /// Thrown when we were unable to find a state for a block hash.
89    #[display("no state found for block {_0}")]
90    StateForHashNotFound(B256),
91    /// Thrown when we were unable to find a state for a block number.
92    #[display("no state found for block number {_0}")]
93    StateForNumberNotFound(u64),
94    /// Unable to find the block number for a given transaction index.
95    #[display("unable to find the block number for a given transaction index")]
96    BlockNumberForTransactionIndexNotFound,
97    /// Root mismatch.
98    #[display("merkle trie {_0}")]
99    StateRootMismatch(Box<RootMismatch>),
100    /// Root mismatch during unwind
101    #[display("unwind merkle trie {_0}")]
102    UnwindStateRootMismatch(Box<RootMismatch>),
103    /// State is not available for the given block number because it is pruned.
104    #[display("state at block #{_0} is pruned")]
105    StateAtBlockPruned(BlockNumber),
106    /// Provider does not support this particular request.
107    #[display("this provider does not support this request")]
108    UnsupportedProvider,
109    /// Static File is not found at specified path.
110    #[cfg(feature = "std")]
111    #[display("not able to find {_0} static file at {_1:?}")]
112    MissingStaticFilePath(StaticFileSegment, std::path::PathBuf),
113    /// Static File is not found for requested block.
114    #[display("not able to find {_0} static file for block number {_1}")]
115    MissingStaticFileBlock(StaticFileSegment, BlockNumber),
116    /// Static File is not found for requested transaction.
117    #[display("unable to find {_0} static file for transaction id {_1}")]
118    MissingStaticFileTx(StaticFileSegment, TxNumber),
119    /// Static File is finalized and cannot be written to.
120    #[display("unable to write block #{_1} to finalized static file {_0}")]
121    FinalizedStaticFile(StaticFileSegment, BlockNumber),
122    /// Trying to insert data from an unexpected block number.
123    #[display("trying to append data to {_0} as block #{_1} but expected block #{_2}")]
124    UnexpectedStaticFileBlockNumber(StaticFileSegment, BlockNumber, BlockNumber),
125    /// Trying to insert data from an unexpected block number.
126    #[display("trying to append row to {_0} at index #{_1} but expected index #{_2}")]
127    UnexpectedStaticFileTxNumber(StaticFileSegment, TxNumber, TxNumber),
128    /// Static File Provider was initialized as read-only.
129    #[display("cannot get a writer on a read-only environment.")]
130    ReadOnlyStaticFileAccess,
131    /// Consistent view error.
132    #[display("failed to initialize consistent view: {_0}")]
133    ConsistentView(Box<ConsistentViewError>),
134    /// Storage lock error.
135    StorageLockError(StorageLockError),
136    /// Storage writer error.
137    UnifiedStorageWriterError(UnifiedStorageWriterError),
138    /// Received invalid output from configured storage implementation.
139    InvalidStorageOutput,
140    /// Enclave encryptography error.
141    EnclaveError(EnclaveError),
142}
143
144impl From<EnclaveError> for ProviderError {
145    fn from(err: EnclaveError) -> Self {
146        Self::EnclaveError(err)
147    }
148}
149
150impl From<DatabaseError> for ProviderError {
151    fn from(error: DatabaseError) -> Self {
152        Self::Database(error)
153    }
154}
155
156impl From<alloy_rlp::Error> for ProviderError {
157    fn from(error: alloy_rlp::Error) -> Self {
158        Self::Rlp(error)
159    }
160}
161
162impl From<StorageLockError> for ProviderError {
163    fn from(error: StorageLockError) -> Self {
164        Self::StorageLockError(error)
165    }
166}
167
168impl From<UnifiedStorageWriterError> for ProviderError {
169    fn from(error: UnifiedStorageWriterError) -> Self {
170        Self::UnifiedStorageWriterError(error)
171    }
172}
173
174impl core::error::Error for ProviderError {
175    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
176        match self {
177            Self::Database(source) => core::error::Error::source(source),
178            Self::StorageLockError(source) => core::error::Error::source(source),
179            Self::UnifiedStorageWriterError(source) => core::error::Error::source(source),
180            _ => Option::None,
181        }
182    }
183}
184
185/// A root mismatch error at a given block height.
186#[derive(Clone, Debug, PartialEq, Eq, Display)]
187#[display("root mismatch at #{block_number} ({block_hash}): {root}")]
188pub struct RootMismatch {
189    /// The target block root diff.
190    pub root: GotExpected<B256>,
191    /// The target block number.
192    pub block_number: BlockNumber,
193    /// The target block hash.
194    pub block_hash: BlockHash,
195}
196
197/// Consistent database view error.
198#[derive(Clone, Debug, PartialEq, Eq, Display)]
199pub enum ConsistentViewError {
200    /// Error thrown on attempt to initialize provider while node is still syncing.
201    #[display("node is syncing. best block: {best_block:?}")]
202    Syncing {
203        /// Best block diff.
204        best_block: GotExpected<BlockNumber>,
205    },
206    /// Error thrown on inconsistent database view.
207    #[display("inconsistent database state: {tip:?}")]
208    Inconsistent {
209        /// The tip diff.
210        tip: GotExpected<Option<B256>>,
211    },
212}
213
214impl From<ConsistentViewError> for ProviderError {
215    fn from(error: ConsistentViewError) -> Self {
216        Self::ConsistentView(Box::new(error))
217    }
218}