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    /// Storage sparse trie error.
111    #[error("error in storage trie for address {0:?}: {1:?}")]
112    SparseStorageTrie(B256, SparseTrieErrorKind),
113    /// Sparse trie error.
114    #[error(transparent)]
115    Sparse(#[from] SparseTrieErrorKind),
116    /// RLP error.
117    #[error(transparent)]
118    Rlp(#[from] alloy_rlp::Error),
119}
120
121/// Result type with [`SparseTrieError`] as error.
122pub type SparseTrieResult<Ok> = Result<Ok, SparseTrieError>;
123
124/// Error encountered in `SparseTrie`.
125#[derive(Error, Debug)]
126#[error(transparent)]
127pub struct SparseTrieError(#[from] Box<SparseTrieErrorKind>);
128
129impl<T: Into<SparseTrieErrorKind>> From<T> for SparseTrieError {
130    #[cold]
131    fn from(value: T) -> Self {
132        Self(Box::new(value.into()))
133    }
134}
135
136impl SparseTrieError {
137    /// Returns the error kind.
138    pub const fn kind(&self) -> &SparseTrieErrorKind {
139        &self.0
140    }
141
142    /// Consumes the error and returns the error kind.
143    pub fn into_kind(self) -> SparseTrieErrorKind {
144        *self.0
145    }
146}
147
148/// [`SparseTrieError`] kind.
149#[derive(Error, Debug)]
150pub enum SparseTrieErrorKind {
151    /// Sparse trie is still blind. Thrown on attempt to update it.
152    #[error("sparse trie is blind")]
153    Blind,
154    /// Encountered blinded node on update.
155    #[error("attempted to update blind node at {path:?}: {hash}")]
156    BlindedNode {
157        /// Blind node path.
158        path: Nibbles,
159        /// Node hash
160        hash: B256,
161    },
162    /// Encountered unexpected node at path when revealing.
163    #[error("encountered an invalid node at path {path:?} when revealing: {node:?}")]
164    Reveal {
165        /// Path to the node.
166        path: Nibbles,
167        /// Node that was at the path when revealing.
168        node: Box<dyn core::fmt::Debug + Send>,
169    },
170    /// RLP error.
171    #[error(transparent)]
172    Rlp(#[from] alloy_rlp::Error),
173    /// Other.
174    #[error(transparent)]
175    Other(#[from] Box<dyn core::error::Error + Send>),
176}
177
178/// Trie witness errors.
179#[derive(Error, Debug)]
180pub enum TrieWitnessError {
181    /// Error gather proofs.
182    #[error(transparent)]
183    Proof(#[from] StateProofError),
184    /// RLP decoding error.
185    #[error(transparent)]
186    Rlp(#[from] alloy_rlp::Error),
187    /// Sparse state trie error.
188    #[error(transparent)]
189    Sparse(#[from] SparseStateTrieError),
190    /// Missing account.
191    #[error("missing account {_0}")]
192    MissingAccount(B256),
193}
194
195impl From<SparseStateTrieErrorKind> for TrieWitnessError {
196    fn from(error: SparseStateTrieErrorKind) -> Self {
197        Self::Sparse(error.into())
198    }
199}
200
201impl From<TrieWitnessError> for ProviderError {
202    fn from(error: TrieWitnessError) -> Self {
203        Self::TrieWitnessError(error.to_string())
204    }
205}