reth_execution_errors/
trie.rs

1//! Errors when computing the state root.
2
3use alloc::{boxed::Box, string::ToString};
4use alloy_primitives::{Bytes, B256};
5use nybbles::Nibbles;
6use reth_storage_errors::{db::DatabaseError, provider::ProviderError};
7use thiserror::Error;
8
9/// State root errors.
10#[derive(Error, PartialEq, Eq, Clone, Debug)]
11pub enum StateRootError {
12    /// Internal database error.
13    #[error(transparent)]
14    Database(#[from] DatabaseError),
15    /// Storage root error.
16    #[error(transparent)]
17    StorageRootError(#[from] StorageRootError),
18}
19
20impl From<StateRootError> for DatabaseError {
21    fn from(err: StateRootError) -> Self {
22        match err {
23            StateRootError::Database(err) |
24            StateRootError::StorageRootError(StorageRootError::Database(err)) => err,
25        }
26    }
27}
28
29/// Storage root error.
30#[derive(Error, PartialEq, Eq, Clone, Debug)]
31pub enum StorageRootError {
32    /// Internal database error.
33    #[error(transparent)]
34    Database(#[from] DatabaseError),
35}
36
37impl From<StorageRootError> for DatabaseError {
38    fn from(err: StorageRootError) -> Self {
39        match err {
40            StorageRootError::Database(err) => err,
41        }
42    }
43}
44
45/// State proof errors.
46#[derive(Error, PartialEq, Eq, Clone, Debug)]
47pub enum StateProofError {
48    /// Internal database error.
49    #[error(transparent)]
50    Database(#[from] DatabaseError),
51    /// RLP decoding error.
52    #[error(transparent)]
53    Rlp(#[from] alloy_rlp::Error),
54}
55
56impl From<StateProofError> for ProviderError {
57    fn from(value: StateProofError) -> Self {
58        match value {
59            StateProofError::Database(error) => Self::Database(error),
60            StateProofError::Rlp(error) => Self::Rlp(error),
61        }
62    }
63}
64
65/// Result type with [`SparseStateTrieError`] as error.
66pub type SparseStateTrieResult<Ok> = Result<Ok, SparseStateTrieError>;
67
68/// Error encountered in `SparseStateTrie`.
69#[derive(Error, Debug)]
70#[error(transparent)]
71pub struct SparseStateTrieError(#[from] Box<SparseStateTrieErrorKind>);
72
73impl<T: Into<SparseStateTrieErrorKind>> From<T> for SparseStateTrieError {
74    #[cold]
75    fn from(value: T) -> Self {
76        Self(Box::new(value.into()))
77    }
78}
79
80impl From<SparseTrieError> for SparseStateTrieErrorKind {
81    #[cold]
82    fn from(value: SparseTrieError) -> Self {
83        Self::Sparse(*value.0)
84    }
85}
86
87impl SparseStateTrieError {
88    /// Returns the error kind.
89    pub const fn kind(&self) -> &SparseStateTrieErrorKind {
90        &self.0
91    }
92
93    /// Consumes the error and returns the error kind.
94    pub fn into_kind(self) -> SparseStateTrieErrorKind {
95        *self.0
96    }
97}
98
99/// Error encountered in `SparseStateTrie`.
100#[derive(Error, Debug)]
101pub enum SparseStateTrieErrorKind {
102    /// Encountered invalid root node.
103    #[error("invalid root node at {path:?}: {node:?}")]
104    InvalidRootNode {
105        /// Path to first proof node.
106        path: Nibbles,
107        /// Encoded first proof node.
108        node: Bytes,
109    },
110    /// Sparse trie error.
111    #[error(transparent)]
112    Sparse(#[from] SparseTrieErrorKind),
113    /// RLP error.
114    #[error(transparent)]
115    Rlp(#[from] alloy_rlp::Error),
116}
117
118/// Result type with [`SparseTrieError`] as error.
119pub type SparseTrieResult<Ok> = Result<Ok, SparseTrieError>;
120
121/// Error encountered in `SparseTrie`.
122#[derive(Error, Debug)]
123#[error(transparent)]
124pub struct SparseTrieError(#[from] Box<SparseTrieErrorKind>);
125
126impl<T: Into<SparseTrieErrorKind>> From<T> for SparseTrieError {
127    #[cold]
128    fn from(value: T) -> Self {
129        Self(Box::new(value.into()))
130    }
131}
132
133impl SparseTrieError {
134    /// Returns the error kind.
135    pub const fn kind(&self) -> &SparseTrieErrorKind {
136        &self.0
137    }
138
139    /// Consumes the error and returns the error kind.
140    pub fn into_kind(self) -> SparseTrieErrorKind {
141        *self.0
142    }
143}
144
145/// [`SparseTrieError`] kind.
146#[derive(Error, Debug)]
147pub enum SparseTrieErrorKind {
148    /// Sparse trie is still blind. Thrown on attempt to update it.
149    #[error("sparse trie is blind")]
150    Blind,
151    /// Encountered blinded node on update.
152    #[error("attempted to update blind node at {path:?}: {hash}")]
153    BlindedNode {
154        /// Blind node path.
155        path: Nibbles,
156        /// Node hash
157        hash: B256,
158    },
159    /// Encountered unexpected node at path when revealing.
160    #[error("encountered an invalid node at path {path:?} when revealing: {node:?}")]
161    Reveal {
162        /// Path to the node.
163        path: Nibbles,
164        /// Node that was at the path when revealing.
165        node: Box<dyn core::fmt::Debug + Send>,
166    },
167    /// RLP error.
168    #[error(transparent)]
169    Rlp(#[from] alloy_rlp::Error),
170    /// Other.
171    #[error(transparent)]
172    Other(#[from] Box<dyn core::error::Error + Send>),
173}
174
175/// Trie witness errors.
176#[derive(Error, Debug)]
177pub enum TrieWitnessError {
178    /// Error gather proofs.
179    #[error(transparent)]
180    Proof(#[from] StateProofError),
181    /// RLP decoding error.
182    #[error(transparent)]
183    Rlp(#[from] alloy_rlp::Error),
184    /// Sparse state trie error.
185    #[error(transparent)]
186    Sparse(#[from] SparseStateTrieError),
187    /// Missing account.
188    #[error("missing account {_0}")]
189    MissingAccount(B256),
190}
191
192impl From<SparseStateTrieErrorKind> for TrieWitnessError {
193    fn from(error: SparseStateTrieErrorKind) -> Self {
194        Self::Sparse(error.into())
195    }
196}
197
198impl From<TrieWitnessError> for ProviderError {
199    fn from(error: TrieWitnessError) -> Self {
200        Self::TrieWitnessError(error.to_string())
201    }
202}