1use alloy_primitives::{Address, B256, U256};
2use alloy_rpc_types::BlockId;
3use futures::channel::mpsc::{SendError, TrySendError};
4use std::{
5 convert::Infallible,
6 sync::{mpsc::RecvError, Arc},
7};
8
9pub type DatabaseResult<T> = Result<T, DatabaseError>;
11
12#[derive(Debug, thiserror::Error)]
14#[allow(missing_docs)]
15pub enum DatabaseError {
16 #[error("missing bytecode for code hash {0}")]
17 MissingCode(B256),
18 #[error(transparent)]
19 Recv(#[from] RecvError),
20 #[error(transparent)]
21 Send(#[from] SendError),
22 #[error("failed to get account for {0}: {1}")]
23 GetAccount(Address, Arc<eyre::Error>),
24 #[error("failed to get storage for {0} at {1}: {2}")]
25 GetStorage(Address, U256, Arc<eyre::Error>),
26 #[error("failed to get block hash for {0}: {1}")]
27 GetBlockHash(u64, Arc<eyre::Error>),
28 #[error("failed to get full block for {0:?}: {1}")]
29 GetFullBlock(BlockId, Arc<eyre::Error>),
30 #[error("block {0:?} does not exist")]
31 BlockNotFound(BlockId),
32 #[error("failed to get transaction {0}: {1}")]
33 GetTransaction(B256, Arc<eyre::Error>),
34 #[error("failed to process AnyRequest: {0}")]
35 AnyRequest(Arc<eyre::Error>),
36}
37
38impl DatabaseError {
39 fn get_rpc_error(&self) -> Option<&eyre::Error> {
40 match self {
41 Self::GetAccount(_, err) => Some(err),
42 Self::GetStorage(_, _, err) => Some(err),
43 Self::GetBlockHash(_, err) => Some(err),
44 Self::GetFullBlock(_, err) => Some(err),
45 Self::GetTransaction(_, err) => Some(err),
46 Self::AnyRequest(err) => Some(err),
47 Self::MissingCode(_) | Self::Recv(_) | Self::Send(_) | Self::BlockNotFound(_) => None,
49 }
50 }
51
52 pub fn is_possibly_non_archive_node_error(&self) -> bool {
55 static GETH_MESSAGE: &str = "missing trie node";
56
57 self.get_rpc_error()
58 .map(|err| err.to_string().to_lowercase().contains(GETH_MESSAGE))
59 .unwrap_or(false)
60 }
61}
62
63impl<T> From<TrySendError<T>> for DatabaseError {
64 fn from(value: TrySendError<T>) -> Self {
65 value.into_send_error().into()
66 }
67}
68
69impl From<Infallible> for DatabaseError {
70 fn from(value: Infallible) -> Self {
71 match value {}
72 }
73}
74
75impl revm::database::DBErrorMarker for DatabaseError {}