diff --git a/crates/evm/execution-errors/src/trie.rs b/crates/evm/execution-errors/src/trie.rs index 7dd749f0c11..1f331e35ff6 100644 --- a/crates/evm/execution-errors/src/trie.rs +++ b/crates/evm/execution-errors/src/trie.rs @@ -7,7 +7,7 @@ use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; use thiserror::Error; /// State root errors. -#[derive(Error, PartialEq, Eq, Clone, Debug)] +#[derive(Error, Clone, Debug)] pub enum StateRootError { /// Internal database error. #[error(transparent)] @@ -27,7 +27,7 @@ impl From for DatabaseError { } /// Storage root error. -#[derive(Error, PartialEq, Eq, Clone, Debug)] +#[derive(Error, Clone, Debug)] pub enum StorageRootError { /// Internal database error. #[error(transparent)] @@ -43,7 +43,7 @@ impl From for DatabaseError { } /// State proof errors. -#[derive(Error, PartialEq, Eq, Clone, Debug)] +#[derive(Error, Clone, Debug)] pub enum StateProofError { /// Internal database error. #[error(transparent)] diff --git a/crates/optimism/trie/src/api.rs b/crates/optimism/trie/src/api.rs index 234aab6ca27..14fad7e6010 100644 --- a/crates/optimism/trie/src/api.rs +++ b/crates/optimism/trie/src/api.rs @@ -5,49 +5,14 @@ use alloy_eips::eip1898::BlockWithParent; use alloy_primitives::{map::HashMap, B256, U256}; use auto_impl::auto_impl; use reth_primitives_traits::Account; -use reth_trie::{updates::TrieUpdates, BranchNodeCompact, HashedPostState, Nibbles}; +use reth_trie::{ + hashed_cursor::{HashedCursor, HashedStorageCursor}, + trie_cursor::TrieCursor, + updates::TrieUpdates, + BranchNodeCompact, HashedPostState, Nibbles, +}; use std::{fmt::Debug, time::Duration}; -/// Seeks and iterates over trie nodes in the database by path (lexicographical order) -pub trait OpProofsTrieCursorRO: Send + Sync { - /// Seek to an exact path, otherwise return None if not found. - fn seek_exact( - &mut self, - path: Nibbles, - ) -> OpProofsStorageResult>; - - /// Seek to a path, otherwise return the first path greater than the given path - /// lexicographically. - fn seek( - &mut self, - path: Nibbles, - ) -> OpProofsStorageResult>; - - /// Move the cursor to the next path and return it. - fn next(&mut self) -> OpProofsStorageResult>; - - /// Get the current path. - fn current(&mut self) -> OpProofsStorageResult>; -} - -/// Seeks and iterates over hashed entries in the database by key. -pub trait OpProofsHashedCursorRO: Send + Sync { - /// Value returned by the cursor. - type Value: Debug; - - /// Seek an entry greater or equal to the given key and position the cursor there. - /// Returns the first entry with the key greater or equal to the sought key. - fn seek(&mut self, key: B256) -> OpProofsStorageResult>; - - /// Move the cursor to the next entry and return it. - fn next(&mut self) -> OpProofsStorageResult>; - - /// Returns `true` if there are no entries for a given key. - fn is_storage_empty(&mut self) -> OpProofsStorageResult { - Ok(self.seek(B256::ZERO)?.is_none()) - } -} - /// Diff of trie updates and post state for a block. #[derive(Debug, Clone, Default)] pub struct BlockStateDiff { @@ -98,22 +63,22 @@ pub struct OperationDurations { #[auto_impl(Arc)] pub trait OpProofsStore: Send + Sync + Debug { /// Cursor for iterating over trie branches. - type StorageTrieCursor<'tx>: OpProofsTrieCursorRO + 'tx + type StorageTrieCursor<'tx>: TrieCursor + 'tx where Self: 'tx; /// Cursor for iterating over account trie branches. - type AccountTrieCursor<'tx>: OpProofsTrieCursorRO + 'tx + type AccountTrieCursor<'tx>: TrieCursor + 'tx where Self: 'tx; /// Cursor for iterating over storage leaves. - type StorageCursor<'tx>: OpProofsHashedCursorRO + 'tx + type StorageCursor<'tx>: HashedStorageCursor + Send + Sync + 'tx where Self: 'tx; /// Cursor for iterating over account leaves. - type AccountHashedCursor<'tx>: OpProofsHashedCursorRO + 'tx + type AccountHashedCursor<'tx>: HashedCursor + Send + Sync + 'tx where Self: 'tx; diff --git a/crates/optimism/trie/src/backfill.rs b/crates/optimism/trie/src/backfill.rs index 2de8f864567..830da66dd23 100644 --- a/crates/optimism/trie/src/backfill.rs +++ b/crates/optimism/trie/src/backfill.rs @@ -348,13 +348,16 @@ impl<'a, Tx: DbTx, S: OpProofsStore + Send> BackfillJob<'a, Tx, S> { #[cfg(test)] mod tests { use super::*; - use crate::{InMemoryProofsStorage, OpProofsHashedCursorRO, OpProofsTrieCursorRO}; + use crate::InMemoryProofsStorage; use alloy_primitives::{keccak256, Address, U256}; use reth_db::{ cursor::DbCursorRW, test_utils::create_test_rw_db, transaction::DbTxMut, Database, }; use reth_primitives_traits::Account; - use reth_trie::{BranchNodeCompact, StorageTrieEntry, StoredNibbles, StoredNibblesSubKey}; + use reth_trie::{ + hashed_cursor::HashedCursor, trie_cursor::TrieCursor, BranchNodeCompact, StorageTrieEntry, + StoredNibbles, StoredNibblesSubKey, + }; use std::sync::Arc; /// Helper function to create a test branch node diff --git a/crates/optimism/trie/src/cursor.rs b/crates/optimism/trie/src/cursor.rs index 8d6d0ae840e..78a60f0b0f6 100644 --- a/crates/optimism/trie/src/cursor.rs +++ b/crates/optimism/trie/src/cursor.rs @@ -1,7 +1,6 @@ //! Implementation of [`HashedCursor`] and [`TrieCursor`] for //! [`OpProofsStorage`](crate::OpProofsStorage). -use crate::{OpProofsHashedCursorRO, OpProofsTrieCursorRO}; use alloy_primitives::{B256, U256}; use derive_more::{Constructor, From}; use reth_db::DatabaseError; @@ -12,20 +11,20 @@ use reth_trie::{ BranchNodeCompact, Nibbles, }; -/// Manages reading storage or account trie nodes from [`OpProofsTrieCursorRO`]. +/// Manages reading storage or account trie nodes from [`TrieCursor`]. #[derive(Debug, Clone, Constructor, From)] -pub struct OpProofsTrieCursor(pub C); +pub struct OpProofsTrieCursor(pub C); impl TrieCursor for OpProofsTrieCursor where - C: OpProofsTrieCursorRO, + C: TrieCursor, { #[inline] fn seek_exact( &mut self, key: Nibbles, ) -> Result, DatabaseError> { - Ok(self.0.seek_exact(key)?) + self.0.seek_exact(key) } #[inline] @@ -33,17 +32,17 @@ where &mut self, key: Nibbles, ) -> Result, DatabaseError> { - Ok(self.0.seek(key)?) + self.0.seek(key) } #[inline] fn next(&mut self) -> Result, DatabaseError> { - Ok(self.0.next()?) + self.0.next() } #[inline] fn current(&mut self) -> Result, DatabaseError> { - Ok(self.0.current()?) + self.0.current() } } @@ -53,18 +52,18 @@ pub struct OpProofsHashedAccountCursor(pub C); impl HashedCursor for OpProofsHashedAccountCursor where - C: OpProofsHashedCursorRO + Send + Sync, + C: HashedCursor + Send + Sync, { type Value = Account; #[inline] fn seek(&mut self, key: B256) -> Result, DatabaseError> { - Ok(self.0.seek(key)?) + self.0.seek(key) } #[inline] fn next(&mut self) -> Result, DatabaseError> { - Ok(self.0.next()?) + self.0.next() } } @@ -74,27 +73,27 @@ pub struct OpProofsHashedStorageCursor(pub C); impl HashedCursor for OpProofsHashedStorageCursor where - C: OpProofsHashedCursorRO + Send + Sync, + C: HashedCursor + Send + Sync, { type Value = U256; #[inline] fn seek(&mut self, key: B256) -> Result, DatabaseError> { - Ok(self.0.seek(key)?) + self.0.seek(key) } #[inline] fn next(&mut self) -> Result, DatabaseError> { - Ok(self.0.next()?) + self.0.next() } } impl HashedStorageCursor for OpProofsHashedStorageCursor where - C: OpProofsHashedCursorRO + Send + Sync, + C: HashedStorageCursor + Send + Sync, { #[inline] fn is_storage_empty(&mut self) -> Result { - Ok(self.0.is_storage_empty()?) + self.0.is_storage_empty() } } diff --git a/crates/optimism/trie/src/db/cursor.rs b/crates/optimism/trie/src/db/cursor.rs index 5982d359400..2cc7248c0aa 100644 --- a/crates/optimism/trie/src/db/cursor.rs +++ b/crates/optimism/trie/src/db/cursor.rs @@ -5,17 +5,21 @@ use crate::{ AccountTrieHistory, HashedAccountHistory, HashedStorageHistory, HashedStorageKey, MaybeDeleted, StorageTrieHistory, StorageTrieKey, VersionedValue, }, - OpProofsHashedCursorRO, OpProofsStorageResult, OpProofsTrieCursorRO, + OpProofsStorageResult, }; use alloy_primitives::{B256, U256}; use reth_db::{ cursor::{DbCursorRO, DbDupCursorRO}, table::{DupSort, Table}, transaction::DbTx, - Database, DatabaseEnv, + Database, DatabaseEnv, DatabaseError, }; use reth_primitives_traits::Account; -use reth_trie::{BranchNodeCompact, Nibbles, StoredNibbles}; +use reth_trie::{ + hashed_cursor::{HashedCursor, HashedStorageCursor}, + trie_cursor::TrieCursor, + BranchNodeCompact, Nibbles, StoredNibbles, +}; /// Generic alias for dup cursor for T pub(crate) type Dup<'tx, T> = <::TX as DbTx>::DupCursor; @@ -141,7 +145,7 @@ where } } -/// MDBX implementation of [`OpProofsTrieCursorRO`]. +/// MDBX implementation of [`TrieCursor`]. #[derive(Debug)] pub struct MdbxTrieCursor { inner: BlockNumberVersionedCursor, @@ -160,50 +164,52 @@ impl< } } -impl OpProofsTrieCursorRO for MdbxTrieCursor +impl TrieCursor for MdbxTrieCursor where Cursor: DbCursorRO + DbDupCursorRO + Send + Sync, { fn seek_exact( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { - self.inner + ) -> Result, DatabaseError> { + Ok(self + .inner .seek_exact(StoredNibbles(path)) - .map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node))) + .map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node)))?) } fn seek( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { - self.inner + ) -> Result, DatabaseError> { + Ok(self + .inner .seek(StoredNibbles(path)) - .map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node))) + .map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node)))?) } - fn next(&mut self) -> OpProofsStorageResult> { - self.inner.next().map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node))) + fn next(&mut self) -> Result, DatabaseError> { + Ok(self.inner.next().map(|opt| opt.map(|(StoredNibbles(n), node)| (n, node)))?) } - fn current(&mut self) -> OpProofsStorageResult> { - Ok(self.inner.cursor.current().map(|opt| opt.map(|(StoredNibbles(n), _)| n))?) + fn current(&mut self) -> Result, DatabaseError> { + self.inner.cursor.current().map(|opt| opt.map(|(StoredNibbles(n), _)| n)) } } -impl OpProofsTrieCursorRO for MdbxTrieCursor +impl TrieCursor for MdbxTrieCursor where Cursor: DbCursorRO + DbDupCursorRO + Send + Sync, { fn seek_exact( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { if let Some(address) = self.hashed_address { let key = StorageTrieKey::new(address, StoredNibbles(path)); - return self.inner.seek_exact(key).map(|opt| { + return Ok(self.inner.seek_exact(key).map(|opt| { opt.and_then(|(k, node)| (k.hashed_address == address).then_some((k.path.0, node))) - }) + })?) } Ok(None) } @@ -211,36 +217,36 @@ where fn seek( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { if let Some(address) = self.hashed_address { let key = StorageTrieKey::new(address, StoredNibbles(path)); - return self.inner.seek(key).map(|opt| { + return Ok(self.inner.seek(key).map(|opt| { opt.and_then(|(k, node)| (k.hashed_address == address).then_some((k.path.0, node))) - }) + })?) } Ok(None) } - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { if let Some(address) = self.hashed_address { - return self.inner.next().map(|opt| { + return Ok(self.inner.next().map(|opt| { opt.and_then(|(k, node)| (k.hashed_address == address).then_some((k.path.0, node))) - }) + })?) } Ok(None) } - fn current(&mut self) -> OpProofsStorageResult> { + fn current(&mut self) -> Result, DatabaseError> { if let Some(address) = self.hashed_address { - return Ok(self.inner.cursor.current().map(|opt| { + return self.inner.cursor.current().map(|opt| { opt.and_then(|(k, _)| (k.hashed_address == address).then_some(k.path.0)) - })?); + }); } Ok(None) } } -/// MDBX implementation of [`OpProofsHashedCursorRO`] for storage state. +/// MDBX implementation of [`HashedCursor`] for storage state. #[derive(Debug)] pub struct MdbxStorageCursor { inner: BlockNumberVersionedCursor, @@ -257,13 +263,13 @@ where } } -impl OpProofsHashedCursorRO for MdbxStorageCursor +impl HashedCursor for MdbxStorageCursor where Cursor: DbCursorRO + DbDupCursorRO + Send + Sync, { type Value = U256; - fn seek(&mut self, key: B256) -> OpProofsStorageResult> { + fn seek(&mut self, key: B256) -> Result, DatabaseError> { let storage_key = HashedStorageKey::new(self.hashed_address, key); // hashed storage values can be zero, which means the storage slot is deleted, so we should @@ -284,7 +290,7 @@ where Ok(result) } - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { let result = self.inner.next().map(|opt| { opt.and_then(|(k, v)| { // Only return entries that belong to the bound address @@ -304,7 +310,14 @@ where } } -/// MDBX implementation of [`OpProofsHashedCursorRO`] for account state. +impl HashedStorageCursor for MdbxStorageCursor> { + #[inline] + fn is_storage_empty(&mut self) -> Result { + Ok(self.seek(B256::ZERO)?.is_none()) + } +} + +/// MDBX implementation of [`HashedCursor`] for account state. #[derive(Debug)] pub struct MdbxAccountCursor { inner: BlockNumberVersionedCursor, @@ -320,18 +333,18 @@ where } } -impl OpProofsHashedCursorRO for MdbxAccountCursor +impl HashedCursor for MdbxAccountCursor where Cursor: DbCursorRO + DbDupCursorRO + Send + Sync, { type Value = Account; - fn seek(&mut self, key: B256) -> OpProofsStorageResult> { - self.inner.seek(key) + fn seek(&mut self, key: B256) -> Result, DatabaseError> { + Ok(self.inner.seek(key)?) } - fn next(&mut self) -> OpProofsStorageResult> { - self.inner.next() + fn next(&mut self) -> Result, DatabaseError> { + Ok(self.inner.next()?) } } @@ -930,7 +943,7 @@ mod tests { let mut cur = account_trie_cursor(&tx, 100); // Wrapper should return (Nibbles, BranchNodeCompact) - let out = OpProofsTrieCursorRO::seek_exact(&mut cur, k).expect("ok").expect("some"); + let out = TrieCursor::seek_exact(&mut cur, k).expect("ok").expect("some"); assert_eq!(out.0, k); } @@ -949,7 +962,7 @@ mod tests { let tx = db.tx().expect("ro tx"); let mut cur = account_trie_cursor(&tx, 10); - let out = OpProofsTrieCursorRO::seek_exact(&mut cur, k).expect("ok"); + let out = TrieCursor::seek_exact(&mut cur, k).expect("ok"); assert!(out.is_none(), "account seek_exact must filter tombstone"); } @@ -970,15 +983,15 @@ mod tests { let mut cur = account_trie_cursor(&tx, 100); // seek at k1 - let out1 = OpProofsTrieCursorRO::seek(&mut cur, k1).expect("ok").expect("some"); + let out1 = TrieCursor::seek(&mut cur, k1).expect("ok").expect("some"); assert_eq!(out1.0, k1); // current should be k1 - let cur_k = OpProofsTrieCursorRO::current(&mut cur).expect("ok").expect("some"); + let cur_k = TrieCursor::current(&mut cur).expect("ok").expect("some"); assert_eq!(cur_k, k1); // next should move to k2 - let out2 = OpProofsTrieCursorRO::next(&mut cur).expect("ok").expect("some"); + let out2 = TrieCursor::next(&mut cur).expect("ok").expect("some"); assert_eq!(out2.0, k2); } @@ -1004,12 +1017,12 @@ mod tests { // Cursor bound to A must not see B’s data let mut cur_a = storage_trie_cursor(&tx, 100, addr_a); - let out_a = OpProofsTrieCursorRO::seek_exact(&mut cur_a, path).expect("ok"); + let out_a = TrieCursor::seek_exact(&mut cur_a, path).expect("ok"); assert!(out_a.is_none(), "no data for addr A"); // Cursor bound to B should see it let mut cur_b = storage_trie_cursor(&tx, 100, addr_b); - let out_b = OpProofsTrieCursorRO::seek_exact(&mut cur_b, path).expect("ok").expect("some"); + let out_b = TrieCursor::seek_exact(&mut cur_b, path).expect("ok").expect("some"); assert_eq!(out_b.0, path); } @@ -1039,15 +1052,15 @@ mod tests { let mut cur_a = storage_trie_cursor(&tx, 100, addr_a); // seek at p1: for A there is no p1; the next key >= p1 under A is p2 - let out = OpProofsTrieCursorRO::seek(&mut cur_a, p1).expect("ok").expect("some"); + let out = TrieCursor::seek(&mut cur_a, p1).expect("ok").expect("some"); assert_eq!(out.0, p2); // seek at p2: exact match - let out = OpProofsTrieCursorRO::seek(&mut cur_a, p2).expect("ok").expect("some"); + let out = TrieCursor::seek(&mut cur_a, p2).expect("ok").expect("some"); assert_eq!(out.0, p2); // seek at p3: no p3 under A; no next key ≥ p3 under A → None - let out = OpProofsTrieCursorRO::seek(&mut cur_a, p3).expect("ok"); + let out = TrieCursor::seek(&mut cur_a, p3).expect("ok"); assert!(out.is_none(), "no key ≥ p3 under A"); } @@ -1056,15 +1069,15 @@ mod tests { let tx = db.tx().expect("ro tx"); let mut cur_a = storage_trie_cursor(&tx, 100, addr_a); - let out = OpProofsTrieCursorRO::next(&mut cur_a).expect("ok").expect("some"); + let out = TrieCursor::next(&mut cur_a).expect("ok").expect("some"); assert_eq!(out.0, p2); // next should yield None as there is no further key under A - let out = OpProofsTrieCursorRO::next(&mut cur_a).expect("ok"); + let out = TrieCursor::next(&mut cur_a).expect("ok"); assert!(out.is_none(), "no more keys under A"); // current should return None - let out = OpProofsTrieCursorRO::current(&mut cur_a).expect("ok"); + let out = TrieCursor::current(&mut cur_a).expect("ok"); assert!(out.is_none(), "no current key after EOF"); } @@ -1074,15 +1087,15 @@ mod tests { let mut cur_a = storage_trie_cursor(&tx, 100, addr_a); // seek_exact at p1: no exact match - let out = OpProofsTrieCursorRO::seek_exact(&mut cur_a, p1).expect("ok"); + let out = TrieCursor::seek_exact(&mut cur_a, p1).expect("ok"); assert!(out.is_none(), "no exact p1 under A"); // seek_exact at p2: exact match - let out = OpProofsTrieCursorRO::seek_exact(&mut cur_a, p2).expect("ok").expect("some"); + let out = TrieCursor::seek_exact(&mut cur_a, p2).expect("ok").expect("some"); assert_eq!(out.0, p2); // seek_exact at p3: no exact match - let out = OpProofsTrieCursorRO::seek_exact(&mut cur_a, p3).expect("ok"); + let out = TrieCursor::seek_exact(&mut cur_a, p3).expect("ok"); assert!(out.is_none(), "no exact p3 under A"); } } @@ -1108,10 +1121,10 @@ mod tests { let mut cur_a = storage_trie_cursor(&tx, 100, addr_a); // position at p1 (A) - let _ = OpProofsTrieCursorRO::seek_exact(&mut cur_a, p1).expect("ok").expect("some"); + let _ = TrieCursor::seek_exact(&mut cur_a, p1).expect("ok").expect("some"); // next should reach boundary; impl filters different address and returns None - let out = OpProofsTrieCursorRO::next(&mut cur_a).expect("ok"); + let out = TrieCursor::next(&mut cur_a).expect("ok"); assert!(out.is_none(), "next() should stop when next key is a different address"); } @@ -1131,9 +1144,9 @@ mod tests { let tx = db.tx().expect("ro tx"); let mut cur = storage_trie_cursor(&tx, 100, addr); - let _ = OpProofsTrieCursorRO::seek_exact(&mut cur, p).expect("ok").expect("some"); + let _ = TrieCursor::seek_exact(&mut cur, p).expect("ok").expect("some"); - let now = OpProofsTrieCursorRO::current(&mut cur).expect("ok").expect("some"); + let now = TrieCursor::current(&mut cur).expect("ok").expect("some"); assert_eq!(now, p); } @@ -1152,8 +1165,7 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = storage_cursor(&tx, 100, addr); - let (got_slot, got_val) = - OpProofsHashedCursorRO::seek(&mut cur, slot).expect("ok").expect("some"); + let (got_slot, got_val) = cur.seek(slot).expect("ok").expect("some"); assert_eq!(got_slot, slot); assert_eq!(got_val, U256::from(7)); } @@ -1174,7 +1186,7 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = storage_cursor(&tx, 10, addr); - let out = OpProofsHashedCursorRO::seek(&mut cur, slot).expect("ok"); + let out = cur.seek(slot).expect("ok"); assert!(out.is_none(), "wrapper must filter tombstoned latest"); } @@ -1195,10 +1207,10 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = storage_cursor(&tx, 100, addr); - let (k1, v1) = OpProofsHashedCursorRO::seek(&mut cur, s1).expect("ok").expect("some"); + let (k1, v1) = cur.seek(s1).expect("ok").expect("some"); assert_eq!((k1, v1), (s1, U256::from(11))); - let (k2, v2) = OpProofsHashedCursorRO::next(&mut cur).expect("ok").expect("some"); + let (k2, v2) = cur.next().expect("ok").expect("some"); assert_eq!((k2, v2), (s2, U256::from(22))); } @@ -1228,22 +1240,22 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = storage_cursor(&tx, 100, addr1); - let (k1, v1) = OpProofsHashedCursorRO::next(&mut cur).expect("ok").expect("some"); + let (k1, v1) = cur.next().expect("ok").expect("some"); assert_eq!((k1, v1), (s1, U256::from(11))); - let (k2, v2) = OpProofsHashedCursorRO::next(&mut cur).expect("ok").expect("some"); + let (k2, v2) = cur.next().expect("ok").expect("some"); assert_eq!((k2, v2), (s2, U256::from(22))); - let out = OpProofsHashedCursorRO::next(&mut cur).expect("ok"); + let out = cur.next().expect("ok"); assert!(out.is_none(), "should stop at address boundary"); - let (k1, v1) = OpProofsHashedCursorRO::seek(&mut cur, s1).expect("ok").expect("some"); + let (k1, v1) = cur.seek(s1).expect("ok").expect("some"); assert_eq!((k1, v1), (s1, U256::from(11))); - let (k2, v2) = OpProofsHashedCursorRO::seek(&mut cur, s2).expect("ok").expect("some"); + let (k2, v2) = cur.seek(s2).expect("ok").expect("some"); assert_eq!((k2, v2), (s2, U256::from(22))); - let out = OpProofsHashedCursorRO::seek(&mut cur, s3).expect("ok"); + let out = cur.seek(s3).expect("ok"); assert!(out.is_none(), "should not see keys from other address"); } @@ -1261,8 +1273,7 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = account_cursor(&tx, 100); - let (got_key, _acc) = - OpProofsHashedCursorRO::seek(&mut cur, key).expect("ok").expect("some"); + let (got_key, _acc) = cur.seek(key).expect("ok").expect("some"); assert_eq!(got_key, key); } @@ -1281,7 +1292,7 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = account_cursor(&tx, 10); - let out = OpProofsHashedCursorRO::seek(&mut cur, key).expect("ok"); + let out = cur.seek(key).expect("ok"); assert!(out.is_none(), "wrapper must filter tombstoned latest"); } @@ -1301,10 +1312,10 @@ mod tests { let tx = db.tx().expect("ro"); let mut cur = account_cursor(&tx, 100); - let (got1, _) = OpProofsHashedCursorRO::seek(&mut cur, k1).expect("ok").expect("some"); + let (got1, _) = cur.seek(k1).expect("ok").expect("some"); assert_eq!(got1, k1); - let (got2, _) = OpProofsHashedCursorRO::next(&mut cur).expect("ok").expect("some"); + let (got2, _) = cur.next().expect("ok").expect("some"); assert_eq!(got2, k2); } } diff --git a/crates/optimism/trie/src/db/store.rs b/crates/optimism/trie/src/db/store.rs index 4648bc80764..9989cd5e75e 100644 --- a/crates/optimism/trie/src/db/store.rs +++ b/crates/optimism/trie/src/db/store.rs @@ -10,8 +10,7 @@ use crate::{ }, MdbxAccountCursor, MdbxStorageCursor, MdbxTrieCursor, }, - BlockStateDiff, OpProofsHashedCursorRO, OpProofsStorageError, OpProofsStorageResult, - OpProofsStore, OpProofsTrieCursorRO, + BlockStateDiff, OpProofsStorageError, OpProofsStorageResult, OpProofsStore, }; use alloy_eips::{eip1898::BlockWithParent, NumHash}; use alloy_primitives::{map::HashMap, B256, U256}; @@ -24,7 +23,10 @@ use reth_db::{ Database, DatabaseEnv, DatabaseError, }; use reth_primitives_traits::Account; -use reth_trie::{updates::StorageTrieUpdates, BranchNodeCompact, HashedStorage, Nibbles}; +use reth_trie::{ + hashed_cursor::HashedCursor, trie_cursor::TrieCursor, updates::StorageTrieUpdates, + BranchNodeCompact, HashedStorage, Nibbles, +}; use std::{cmp::max, ops::RangeBounds, path::Path}; /// MDBX implementation of [`OpProofsStore`]. @@ -302,7 +304,9 @@ impl MdbxProofsStorage { // Yet to have any update for the current block number - So just using up to // previous block number let mut ro = self.storage_trie_cursor(hashed_address, block_number - 1)?; - let keys = self.wipe_storage(tx, block_number, hashed_address, || ro.next())?; + let keys = + self.wipe_storage(tx, block_number, hashed_address, || Ok(ro.next()?))?; + storage_trie_keys.extend(keys); // Skip any further processing for this hashed_address @@ -325,7 +329,8 @@ impl MdbxProofsStorage { // Yet to have any update for the current block number - So just using up to // previous block number let mut ro = self.storage_hashed_cursor(hashed_address, block_number - 1)?; - let keys = self.wipe_storage(tx, block_number, hashed_address, || ro.next())?; + let keys = + self.wipe_storage(tx, block_number, hashed_address, || Ok(ro.next()?))?; hashed_storage_keys.extend(keys); // Skip any further processing for this hashed_address continue; diff --git a/crates/optimism/trie/src/error.rs b/crates/optimism/trie/src/error.rs index 65435fa93a3..4a07a594419 100644 --- a/crates/optimism/trie/src/error.rs +++ b/crates/optimism/trie/src/error.rs @@ -3,11 +3,12 @@ use alloy_primitives::B256; use reth_db::DatabaseError; use reth_trie::Nibbles; +use std::sync::Arc; use thiserror::Error; use tokio::sync::TryLockError; /// Error type for storage operations -#[derive(Debug, Error)] +#[derive(Debug, Clone, Error)] pub enum OpProofsStorageError { /// No blocks found #[error("No blocks found")] @@ -77,17 +78,61 @@ pub enum OpProofsStorageError { }, /// Error occurred while interacting with the database. #[error(transparent)] - DatabaseError(#[from] DatabaseError), + DatabaseError(DatabaseError), /// Error occurred while trying to acquire a lock. - #[error(transparent)] - TryLockError(#[from] TryLockError), + #[error("failed lock attempt")] + TryLockError, +} + +impl From for OpProofsStorageError { + fn from(_: TryLockError) -> Self { + Self::TryLockError + } } impl From for DatabaseError { fn from(error: OpProofsStorageError) -> Self { - Self::Other(error.to_string()) + match error { + OpProofsStorageError::DatabaseError(err) => err, + _ => Self::Custom(Arc::new(error)), + } + } +} + +impl From for OpProofsStorageError { + fn from(error: DatabaseError) -> Self { + if let DatabaseError::Custom(ref err) = error && + let Some(err) = err.downcast_ref::() + { + return err.clone() + } + Self::DatabaseError(error) } } /// Result type for storage operations pub type OpProofsStorageResult = Result; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_op_proofs_store_error_to_db_error() { + let original_error = OpProofsStorageError::NoBlocksFound; + let db_error: DatabaseError = original_error.into(); + let converted_error: OpProofsStorageError = db_error.into(); + + assert!(matches!(converted_error, OpProofsStorageError::NoBlocksFound)) + } + + #[test] + fn test_db_error_to_op_proofs_store_error() { + let original_error = DatabaseError::Decode; + let op_proofs_store_error: OpProofsStorageError = original_error.into(); + let converted_error: DatabaseError = op_proofs_store_error.into(); + println!("{:?}", converted_error); + + assert!(matches!(converted_error, DatabaseError::Decode)) + } +} diff --git a/crates/optimism/trie/src/in_memory.rs b/crates/optimism/trie/src/in_memory.rs index 5a8e8622aaa..6a4673be1e7 100644 --- a/crates/optimism/trie/src/in_memory.rs +++ b/crates/optimism/trie/src/in_memory.rs @@ -1,13 +1,16 @@ //! In-memory implementation of [`OpProofsStore`] for testing purposes -use crate::{ - api::WriteCounts, BlockStateDiff, OpProofsHashedCursorRO, OpProofsStorageResult, OpProofsStore, - OpProofsTrieCursorRO, -}; +use crate::{api::WriteCounts, BlockStateDiff, OpProofsStorageResult, OpProofsStore}; use alloy_eips::eip1898::BlockWithParent; use alloy_primitives::{map::HashMap, B256, U256}; +use reth_db::DatabaseError; use reth_primitives_traits::Account; -use reth_trie::{updates::TrieUpdates, BranchNodeCompact, HashedPostState, Nibbles}; +use reth_trie::{ + hashed_cursor::{HashedCursor, HashedStorageCursor}, + trie_cursor::TrieCursor, + updates::TrieUpdates, + BranchNodeCompact, HashedPostState, Nibbles, +}; use std::{collections::BTreeMap, sync::Arc}; use tokio::sync::RwLock; @@ -156,7 +159,7 @@ impl InMemoryProofsStorage { } } -/// In-memory implementation of [`OpProofsTrieCursorRO`]. +/// In-memory implementation of [`TrieCursor`]. #[derive(Debug)] pub struct InMemoryTrieCursor { /// Current position in the iteration (-1 means not positioned yet) @@ -223,11 +226,11 @@ impl InMemoryTrieCursor { } } -impl OpProofsTrieCursorRO for InMemoryTrieCursor { +impl TrieCursor for InMemoryTrieCursor { fn seek_exact( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { if let Some(pos) = self.entries.iter().position(|(p, _)| *p == path) { self.position = pos as isize; Ok(Some(self.entries[pos].clone())) @@ -239,7 +242,7 @@ impl OpProofsTrieCursorRO for InMemoryTrieCursor { fn seek( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { if let Some(pos) = self.entries.iter().position(|(p, _)| *p >= path) { self.position = pos as isize; Ok(Some(self.entries[pos].clone())) @@ -248,7 +251,7 @@ impl OpProofsTrieCursorRO for InMemoryTrieCursor { } } - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { self.position += 1; if self.position >= 0 && (self.position as usize) < self.entries.len() { Ok(Some(self.entries[self.position as usize].clone())) @@ -257,7 +260,7 @@ impl OpProofsTrieCursorRO for InMemoryTrieCursor { } } - fn current(&mut self) -> OpProofsStorageResult> { + fn current(&mut self) -> Result, DatabaseError> { if self.position >= 0 && (self.position as usize) < self.entries.len() { Ok(Some(self.entries[self.position as usize].0)) } else { @@ -266,7 +269,7 @@ impl OpProofsTrieCursorRO for InMemoryTrieCursor { } } -/// In-memory implementation of [`OpProofsHashedCursorRO`] for storage slots +/// In-memory implementation of [`HashedCursor`] for storage slots #[derive(Debug)] pub struct InMemoryStorageCursor { /// Current position in the iteration (-1 means not positioned yet) @@ -313,10 +316,10 @@ impl InMemoryStorageCursor { } } -impl OpProofsHashedCursorRO for InMemoryStorageCursor { +impl HashedCursor for InMemoryStorageCursor { type Value = U256; - fn seek(&mut self, key: B256) -> OpProofsStorageResult> { + fn seek(&mut self, key: B256) -> Result, DatabaseError> { if let Some(pos) = self.entries.iter().position(|(k, _)| *k >= key) { self.position = pos as isize; Ok(Some(self.entries[pos])) @@ -325,7 +328,7 @@ impl OpProofsHashedCursorRO for InMemoryStorageCursor { } } - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { self.position += 1; if self.position >= 0 && (self.position as usize) < self.entries.len() { Ok(Some(self.entries[self.position as usize])) @@ -335,7 +338,13 @@ impl OpProofsHashedCursorRO for InMemoryStorageCursor { } } -/// In-memory implementation of [`OpProofsHashedCursorRO`] for accounts +impl HashedStorageCursor for InMemoryStorageCursor { + fn is_storage_empty(&mut self) -> Result { + Ok(self.seek(B256::ZERO)?.is_none()) + } +} + +/// In-memory implementation of [`HashedCursor`] for accounts #[derive(Debug)] pub struct InMemoryAccountCursor { /// Current position in the iteration (-1 means not positioned yet) @@ -373,10 +382,10 @@ impl InMemoryAccountCursor { } } -impl OpProofsHashedCursorRO for InMemoryAccountCursor { +impl HashedCursor for InMemoryAccountCursor { type Value = Account; - fn seek(&mut self, key: B256) -> OpProofsStorageResult> { + fn seek(&mut self, key: B256) -> Result, DatabaseError> { if let Some(pos) = self.entries.iter().position(|(k, _)| *k >= key) { self.position = pos as isize; Ok(Some(self.entries[pos])) @@ -385,7 +394,7 @@ impl OpProofsHashedCursorRO for InMemoryAccountCursor { } } - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { self.position += 1; if self.position >= 0 && (self.position as usize) < self.entries.len() { Ok(Some(self.entries[self.position as usize])) diff --git a/crates/optimism/trie/src/lib.rs b/crates/optimism/trie/src/lib.rs index c2e1a87a5fd..0d6f49b17b3 100644 --- a/crates/optimism/trie/src/lib.rs +++ b/crates/optimism/trie/src/lib.rs @@ -13,7 +13,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] pub mod api; -pub use api::{BlockStateDiff, OpProofsHashedCursorRO, OpProofsStore, OpProofsTrieCursorRO}; +pub use api::{BlockStateDiff, OpProofsStore}; pub mod backfill; pub use backfill::BackfillJob; diff --git a/crates/optimism/trie/src/metrics.rs b/crates/optimism/trie/src/metrics.rs index a7a08ed7a24..fd1ddcbfab2 100644 --- a/crates/optimism/trie/src/metrics.rs +++ b/crates/optimism/trie/src/metrics.rs @@ -2,16 +2,20 @@ use crate::{ api::{OperationDurations, WriteCounts}, - cursor, BlockStateDiff, OpProofsHashedCursorRO, OpProofsStorageResult, OpProofsStore, - OpProofsTrieCursorRO, + cursor, BlockStateDiff, OpProofsStorageResult, OpProofsStore, }; use alloy_eips::eip1898::BlockWithParent; use alloy_primitives::{map::HashMap, B256, U256}; use derive_more::Constructor; use metrics::{Counter, Gauge, Histogram}; +use reth_db::DatabaseError; use reth_metrics::Metrics; use reth_primitives_traits::Account; -use reth_trie::{BranchNodeCompact, Nibbles}; +use reth_trie::{ + hashed_cursor::{HashedCursor, HashedStorageCursor}, + trie_cursor::TrieCursor, + BranchNodeCompact, Nibbles, +}; use std::{ fmt::Debug, future::Future, @@ -23,7 +27,7 @@ use strum::{EnumCount, EnumIter, IntoEnumIterator}; /// Alias for [`OpProofsStorageWithMetrics`]. pub type OpProofsStorage = OpProofsStorageWithMetrics; -/// Alias for [`OpProofsTrieCursorRO`](cursor::OpProofsTrieCursor) with metrics layer. +/// Alias for [`TrieCursor`](cursor::OpProofsTrieCursor) with metrics layer. pub type OpProofsTrieCursor = cursor::OpProofsTrieCursor>; /// Alias for [`OpProofsHashedAccountCursor`](cursor::OpProofsHashedAccountCursor) with metrics @@ -243,19 +247,19 @@ impl BlockMetrics { } } -/// Wrapper for [`OpProofsTrieCursorRO`] that records metrics. +/// Wrapper for [`TrieCursor`] that records metrics. #[derive(Debug, Constructor, Clone)] pub struct OpProofsTrieCursorWithMetrics { cursor: C, metrics: Arc, } -impl OpProofsTrieCursorRO for OpProofsTrieCursorWithMetrics { +impl TrieCursor for OpProofsTrieCursorWithMetrics { #[inline] fn seek_exact( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::TrieCursorSeekExact, || { self.cursor.seek_exact(path) }) @@ -265,42 +269,49 @@ impl OpProofsTrieCursorRO for OpProofsTrieCursorWithMet fn seek( &mut self, path: Nibbles, - ) -> OpProofsStorageResult> { + ) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::TrieCursorSeek, || self.cursor.seek(path)) } #[inline] - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::TrieCursorNext, || self.cursor.next()) } #[inline] - fn current(&mut self) -> OpProofsStorageResult> { + fn current(&mut self) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::TrieCursorCurrent, || self.cursor.current()) } } -/// Wrapper for [`OpProofsHashedCursorRO`] type that records metrics. +/// Wrapper for [`HashedCursor`] type that records metrics. #[derive(Debug, Constructor, Clone)] pub struct OpProofsHashedCursorWithMetrics { cursor: C, metrics: Arc, } -impl OpProofsHashedCursorRO for OpProofsHashedCursorWithMetrics { +impl HashedCursor for OpProofsHashedCursorWithMetrics { type Value = C::Value; #[inline] - fn seek(&mut self, key: B256) -> OpProofsStorageResult> { + fn seek(&mut self, key: B256) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::HashedCursorSeek, || self.cursor.seek(key)) } #[inline] - fn next(&mut self) -> OpProofsStorageResult> { + fn next(&mut self) -> Result, DatabaseError> { self.metrics.record_operation(StorageOperation::HashedCursorNext, || self.cursor.next()) } } +impl HashedStorageCursor for OpProofsHashedCursorWithMetrics { + #[inline] + fn is_storage_empty(&mut self) -> Result { + self.cursor.is_storage_empty() + } +} + /// Wrapper around [`OpProofsStore`] type that records metrics for all operations. #[derive(Debug, Clone)] pub struct OpProofsStorageWithMetrics { @@ -332,19 +343,19 @@ where type StorageTrieCursor<'tx> = OpProofsTrieCursorWithMetrics> where - S: 'tx; + Self: 'tx; type AccountTrieCursor<'tx> = OpProofsTrieCursorWithMetrics> where - S: 'tx; + Self: 'tx; type StorageCursor<'tx> = OpProofsHashedCursorWithMetrics> where - S: 'tx; + Self: 'tx; type AccountHashedCursor<'tx> = OpProofsHashedCursorWithMetrics> where - S: 'tx; + Self: 'tx; #[inline] async fn store_account_branches( diff --git a/crates/optimism/trie/src/provider.rs b/crates/optimism/trie/src/provider.rs index ce7f2d99e5d..044e97c8070 100644 --- a/crates/optimism/trie/src/provider.rs +++ b/crates/optimism/trie/src/provider.rs @@ -5,7 +5,7 @@ use crate::{ DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, }, - OpProofsHashedCursorRO, OpProofsStorage, OpProofsStorageError, OpProofsStore, + OpProofsStorage, OpProofsStorageError, OpProofsStore, }; use alloy_primitives::keccak256; use derive_more::Constructor; @@ -19,6 +19,7 @@ use reth_revm::{ primitives::{alloy_primitives::BlockNumber, Address, Bytes, StorageValue, B256}, }; use reth_trie::{ + hashed_cursor::HashedCursor, proof::{Proof, StorageProof}, updates::TrieUpdates, witness::TrieWitness, diff --git a/crates/optimism/trie/src/prune/error.rs b/crates/optimism/trie/src/prune/error.rs index ca43536633a..bbfcfcc573a 100644 --- a/crates/optimism/trie/src/prune/error.rs +++ b/crates/optimism/trie/src/prune/error.rs @@ -8,7 +8,7 @@ use std::{ use strum::Display; use thiserror::Error; -/// Result of [`OpProofStoragePruner::run`] execution. +/// Result of [`OpProofStoragePruner::run`](crate::OpProofStoragePruner::run) execution. pub type OpProofStoragePrunerResult = Result; /// Successful prune summary. diff --git a/crates/optimism/trie/src/prune/pruner.rs b/crates/optimism/trie/src/prune/pruner.rs index 4b4f19d47ad..25f8a406f2a 100644 --- a/crates/optimism/trie/src/prune/pruner.rs +++ b/crates/optimism/trie/src/prune/pruner.rs @@ -111,13 +111,16 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{db::MdbxProofsStorage, OpProofsHashedCursorRO, OpProofsTrieCursorRO}; + use crate::db::MdbxProofsStorage; use alloy_eips::{BlockHashOrNumber, NumHash}; use alloy_primitives::{BlockNumber, B256, U256}; use mockall::mock; use reth_primitives_traits::Account; use reth_storage_errors::provider::ProviderResult; - use reth_trie::{updates::StorageTrieUpdates, BranchNodeCompact, HashedStorage, Nibbles}; + use reth_trie::{ + hashed_cursor::HashedCursor, trie_cursor::TrieCursor, updates::StorageTrieUpdates, + BranchNodeCompact, HashedStorage, Nibbles, + }; use std::sync::Arc; use tempfile::TempDir; diff --git a/crates/optimism/trie/tests/lib.rs b/crates/optimism/trie/tests/lib.rs index 15c5fd2eea8..db884f1391c 100644 --- a/crates/optimism/trie/tests/lib.rs +++ b/crates/optimism/trie/tests/lib.rs @@ -3,12 +3,13 @@ use alloy_eips::{eip1898::BlockWithParent, NumHash}; use alloy_primitives::{map::HashMap, B256, U256}; use reth_optimism_trie::{ - db::MdbxProofsStorage, BlockStateDiff, InMemoryProofsStorage, OpProofsHashedCursorRO, - OpProofsStorageError, OpProofsStore, OpProofsTrieCursorRO, + db::MdbxProofsStorage, BlockStateDiff, InMemoryProofsStorage, OpProofsStorageError, + OpProofsStore, }; use reth_primitives_traits::Account; use reth_trie::{ - updates::TrieUpdates, BranchNodeCompact, HashedPostState, HashedStorage, Nibbles, TrieMask, + hashed_cursor::HashedCursor, trie_cursor::TrieCursor, updates::TrieUpdates, BranchNodeCompact, + HashedPostState, HashedStorage, Nibbles, TrieMask, }; use serial_test::serial; use std::sync::Arc; diff --git a/crates/storage/db/src/implementation/mdbx/mod.rs b/crates/storage/db/src/implementation/mdbx/mod.rs index b00bfd3c9a5..d89a35fbf9d 100644 --- a/crates/storage/db/src/implementation/mdbx/mod.rs +++ b/crates/storage/db/src/implementation/mdbx/mod.rs @@ -670,14 +670,14 @@ mod tests { dup_cursor.upsert(Address::with_last_byte(1), &entry_1).expect(ERROR_UPSERT); assert_eq!( - dup_cursor.walk(None).unwrap().collect::, _>>(), - Ok(vec![(Address::with_last_byte(1), entry_0), (Address::with_last_byte(1), entry_1),]) + dup_cursor.walk(None).unwrap().collect::, _>>().unwrap(), + vec![(Address::with_last_byte(1), entry_0), (Address::with_last_byte(1), entry_1),] ); let mut walker = dup_cursor.walk(None).unwrap(); walker.delete_current().expect(ERROR_DEL); - assert_eq!(walker.next(), Some(Ok((Address::with_last_byte(1), entry_1)))); + assert_eq!(walker.next().unwrap().unwrap(), (Address::with_last_byte(1), entry_1)); // Check the tx view - it correctly holds entry_1 assert_eq!( @@ -685,14 +685,15 @@ mod tests { .unwrap() .walk(None) .unwrap() - .collect::, _>>(), - Ok(vec![ + .collect::, _>>() + .unwrap(), + vec![ (Address::with_last_byte(1), entry_1), // This is ok - we removed entry_0 - ]) + ] ); // Check the remainder of walker - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); } #[test] @@ -737,51 +738,51 @@ mod tests { // [1, 3) let mut walker = cursor.walk_range(1..3).unwrap(); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); - assert_eq!(walker.next(), None); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); + assert!(walker.next().is_none()); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); // [1, 2] let mut walker = cursor.walk_range(1..=2).unwrap(); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); // [1, ∞) let mut walker = cursor.walk_range(1..).unwrap(); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((3, B256::ZERO)))); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (3, B256::ZERO)); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); // [2, 4) let mut walker = cursor.walk_range(2..4).unwrap(); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(walker.next(), None); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert!(walker.next().is_none()); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); // (∞, 3) let mut walker = cursor.walk_range(..3).unwrap(); - assert_eq!(walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); + assert_eq!(walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); // (∞, ∞) let mut walker = cursor.walk_range(..).unwrap(); - assert_eq!(walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((2, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((3, B256::ZERO)))); + assert_eq!(walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (2, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (3, B256::ZERO)); // next() returns None after walker is done - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); } #[test] @@ -816,13 +817,31 @@ mod tests { assert_eq!(entries.len(), 7); let mut walker = cursor.walk_range(0..=1).unwrap(); - assert_eq!(walker.next(), Some(Ok((0, AccountBeforeTx { address: address0, info: None })))); - assert_eq!(walker.next(), Some(Ok((0, AccountBeforeTx { address: address1, info: None })))); - assert_eq!(walker.next(), Some(Ok((0, AccountBeforeTx { address: address2, info: None })))); - assert_eq!(walker.next(), Some(Ok((1, AccountBeforeTx { address: address0, info: None })))); - assert_eq!(walker.next(), Some(Ok((1, AccountBeforeTx { address: address1, info: None })))); - assert_eq!(walker.next(), Some(Ok((1, AccountBeforeTx { address: address2, info: None })))); - assert_eq!(walker.next(), None); + assert_eq!( + walker.next().unwrap().unwrap(), + (0, AccountBeforeTx { address: address0, info: None }) + ); + assert_eq!( + walker.next().unwrap().unwrap(), + (0, AccountBeforeTx { address: address1, info: None }) + ); + assert_eq!( + walker.next().unwrap().unwrap(), + (0, AccountBeforeTx { address: address2, info: None }) + ); + assert_eq!( + walker.next().unwrap().unwrap(), + (1, AccountBeforeTx { address: address0, info: None }) + ); + assert_eq!( + walker.next().unwrap().unwrap(), + (1, AccountBeforeTx { address: address1, info: None }) + ); + assert_eq!( + walker.next().unwrap().unwrap(), + (1, AccountBeforeTx { address: address2, info: None }) + ); + assert!(walker.next().is_none()); } #[expect(clippy::reversed_empty_ranges)] @@ -843,15 +862,15 @@ mod tests { // start bound greater than end bound let mut res = cursor.walk_range(3..1).unwrap(); - assert_eq!(res.next(), None); + assert!(res.next().is_none()); // start bound greater than end bound let mut res = cursor.walk_range(15..=2).unwrap(); - assert_eq!(res.next(), None); + assert!(res.next().is_none()); // returning nothing let mut walker = cursor.walk_range(1..1).unwrap(); - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); } #[test] @@ -871,17 +890,17 @@ mod tests { let mut walker = Walker::new(&mut cursor, None); - assert_eq!(walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(walker.next(), None); + assert_eq!(walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert!(walker.next().is_none()); // transform to ReverseWalker let mut reverse_walker = walker.rev(); - assert_eq!(reverse_walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); } #[test] @@ -901,17 +920,17 @@ mod tests { let mut reverse_walker = ReverseWalker::new(&mut cursor, None); - assert_eq!(reverse_walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); // transform to Walker let mut walker = reverse_walker.forward(); - assert_eq!(walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(walker.next(), None); + assert_eq!(walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert!(walker.next().is_none()); } #[test] @@ -930,27 +949,27 @@ mod tests { let mut cursor = tx.cursor_read::().unwrap(); let mut reverse_walker = cursor.walk_back(Some(1)).unwrap(); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); let mut reverse_walker = cursor.walk_back(Some(2)).unwrap(); - assert_eq!(reverse_walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); let mut reverse_walker = cursor.walk_back(Some(4)).unwrap(); - assert_eq!(reverse_walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); let mut reverse_walker = cursor.walk_back(None).unwrap(); - assert_eq!(reverse_walker.next(), Some(Ok((3, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((1, B256::ZERO)))); - assert_eq!(reverse_walker.next(), Some(Ok((0, B256::ZERO)))); - assert_eq!(reverse_walker.next(), None); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (3, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (1, B256::ZERO)); + assert_eq!(reverse_walker.next().unwrap().unwrap(), (0, B256::ZERO)); + assert!(reverse_walker.next().is_none()); } #[test] @@ -969,12 +988,12 @@ mod tests { let missing_key = 2; let tx = db.tx().expect(ERROR_INIT_TX); let mut cursor = tx.cursor_read::().unwrap(); - assert_eq!(cursor.current(), Ok(None)); + assert!(cursor.current().unwrap().is_none()); // Seek exact let exact = cursor.seek_exact(missing_key).unwrap(); assert_eq!(exact, None); - assert_eq!(cursor.current(), Ok(None)); + assert!(cursor.current().unwrap().is_none()); } #[test] @@ -994,21 +1013,18 @@ mod tests { let mut cursor = tx.cursor_write::().unwrap(); // INSERT - assert_eq!(cursor.insert(key_to_insert, &B256::ZERO), Ok(())); - assert_eq!(cursor.current(), Ok(Some((key_to_insert, B256::ZERO)))); - + assert!(cursor.insert(key_to_insert, &B256::ZERO).is_ok()); + assert_eq!(cursor.current().unwrap(), Some((key_to_insert, B256::ZERO))); // INSERT (failure) - assert_eq!( - cursor.insert(key_to_insert, &B256::ZERO), - Err(DatabaseWriteError { - info: Error::KeyExist.into(), - operation: DatabaseWriteOperation::CursorInsert, - table_name: CanonicalHeaders::NAME, - key: key_to_insert.encode().into(), - } - .into()) - ); - assert_eq!(cursor.current(), Ok(Some((key_to_insert, B256::ZERO)))); + assert!(matches!( + cursor.insert(key_to_insert, &B256::ZERO).unwrap_err(), + DatabaseError::Write(err) if *err == DatabaseWriteError { + info: Error::KeyExist.into(), + operation: DatabaseWriteOperation::CursorInsert, + table_name: CanonicalHeaders::NAME, + key: key_to_insert.encode().into(), + })); + assert_eq!(cursor.current().unwrap(), Some((key_to_insert, B256::ZERO))); tx.commit().expect(ERROR_COMMIT); @@ -1054,19 +1070,18 @@ mod tests { // Seek & delete key2 cursor.seek_exact(key2).unwrap(); - assert_eq!(cursor.delete_current(), Ok(())); - assert_eq!(cursor.seek_exact(key2), Ok(None)); + assert!(cursor.delete_current().is_ok()); + assert!(cursor.seek_exact(key2).unwrap().is_none()); // Seek & delete key2 again - assert_eq!(cursor.seek_exact(key2), Ok(None)); - assert_eq!( - cursor.delete_current(), - Err(DatabaseError::Delete(reth_libmdbx::Error::NoData.into())) - ); + assert!(cursor.seek_exact(key2).unwrap().is_none()); + assert!(matches!( + cursor.delete_current().unwrap_err(), + DatabaseError::Delete(err) if err == reth_libmdbx::Error::NoData.into())); // Assert that key1 is still there - assert_eq!(cursor.seek_exact(key1), Ok(Some((key1, Account::default())))); + assert_eq!(cursor.seek_exact(key1).unwrap(), Some((key1, Account::default()))); // Assert that key3 is still there - assert_eq!(cursor.seek_exact(key3), Ok(Some((key3, Account::default())))); + assert_eq!(cursor.seek_exact(key3).unwrap(), Some((key3, Account::default()))); } #[test] @@ -1086,11 +1101,11 @@ mod tests { // INSERT (cursor starts at last) cursor.last().unwrap(); - assert_eq!(cursor.current(), Ok(Some((9, B256::ZERO)))); + assert_eq!(cursor.current().unwrap(), Some((9, B256::ZERO))); for pos in (2..=8).step_by(2) { - assert_eq!(cursor.insert(pos, &B256::ZERO), Ok(())); - assert_eq!(cursor.current(), Ok(Some((pos, B256::ZERO)))); + assert!(cursor.insert(pos, &B256::ZERO).is_ok()); + assert_eq!(cursor.current().unwrap(), Some((pos, B256::ZERO))); } tx.commit().expect(ERROR_COMMIT); @@ -1118,7 +1133,7 @@ mod tests { let key_to_append = 5; let tx = db.tx_mut().expect(ERROR_INIT_TX); let mut cursor = tx.cursor_write::().unwrap(); - assert_eq!(cursor.append(key_to_append, &B256::ZERO), Ok(())); + assert!(cursor.append(key_to_append, &B256::ZERO).is_ok()); tx.commit().expect(ERROR_COMMIT); // Confirm the result @@ -1145,17 +1160,15 @@ mod tests { let key_to_append = 2; let tx = db.tx_mut().expect(ERROR_INIT_TX); let mut cursor = tx.cursor_write::().unwrap(); - assert_eq!( - cursor.append(key_to_append, &B256::ZERO), - Err(DatabaseWriteError { - info: Error::KeyMismatch.into(), - operation: DatabaseWriteOperation::CursorAppend, - table_name: CanonicalHeaders::NAME, - key: key_to_append.encode().into(), - } - .into()) - ); - assert_eq!(cursor.current(), Ok(Some((5, B256::ZERO)))); // the end of table + assert!(matches!( + cursor.append(key_to_append, &B256::ZERO).unwrap_err(), + DatabaseError::Write(err) if *err == DatabaseWriteError { + info: Error::KeyMismatch.into(), + operation: DatabaseWriteOperation::CursorAppend, + table_name: CanonicalHeaders::NAME, + key: key_to_append.encode().into(), + })); + assert_eq!(cursor.current().unwrap(), Some((5, B256::ZERO))); // the end of table tx.commit().expect(ERROR_COMMIT); // Confirm the result @@ -1176,15 +1189,15 @@ mod tests { let account = Account::default(); cursor.upsert(key, &account).expect(ERROR_UPSERT); - assert_eq!(cursor.seek_exact(key), Ok(Some((key, account)))); + assert_eq!(cursor.seek_exact(key).unwrap(), Some((key, account))); let account = Account { nonce: 1, ..Default::default() }; cursor.upsert(key, &account).expect(ERROR_UPSERT); - assert_eq!(cursor.seek_exact(key), Ok(Some((key, account)))); + assert_eq!(cursor.seek_exact(key).unwrap(), Some((key, account))); let account = Account { nonce: 2, ..Default::default() }; cursor.upsert(key, &account).expect(ERROR_UPSERT); - assert_eq!(cursor.seek_exact(key), Ok(Some((key, account)))); + assert_eq!(cursor.seek_exact(key).unwrap(), Some((key, account))); let mut dup_cursor = tx.cursor_dup_write::().unwrap(); let subkey = B256::random(); @@ -1192,13 +1205,13 @@ mod tests { let value = U256::from(1); let entry1 = StorageEntry { key: subkey, value }; dup_cursor.upsert(key, &entry1).expect(ERROR_UPSERT); - assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey), Ok(Some(entry1))); + assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey).unwrap(), Some(entry1)); let value = U256::from(2); let entry2 = StorageEntry { key: subkey, value }; dup_cursor.upsert(key, &entry2).expect(ERROR_UPSERT); - assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey), Ok(Some(entry1))); - assert_eq!(dup_cursor.next_dup_val(), Ok(Some(entry2))); + assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey).unwrap(), Some(entry1)); + assert_eq!(dup_cursor.next_dup_val().unwrap(), Some(entry2)); } #[test] @@ -1224,39 +1237,45 @@ mod tests { let subkey_to_append = 2; let tx = db.tx_mut().expect(ERROR_INIT_TX); let mut cursor = tx.cursor_write::().unwrap(); - assert_eq!( - cursor.append_dup( + assert!(matches!( + cursor + .append_dup( transition_id, - AccountBeforeTx { address: Address::with_last_byte(subkey_to_append), info: None } - ), - Err(DatabaseWriteError { - info: Error::KeyMismatch.into(), - operation: DatabaseWriteOperation::CursorAppendDup, - table_name: AccountChangeSets::NAME, - key: transition_id.encode().into(), - } - .into()) - ); - assert_eq!( - cursor.append( - transition_id - 1, - &AccountBeforeTx { address: Address::with_last_byte(subkey_to_append), info: None } - ), - Err(DatabaseWriteError { + AccountBeforeTx { + address: Address::with_last_byte(subkey_to_append), + info: None + } + ) + .unwrap_err(), + DatabaseError::Write(err) if *err == DatabaseWriteError { + info: Error::KeyMismatch.into(), + operation: DatabaseWriteOperation::CursorAppendDup, + table_name: AccountChangeSets::NAME, + key: transition_id.encode().into(), + })); + assert!(matches!( + cursor + .append( + transition_id - 1, + &AccountBeforeTx { + address: Address::with_last_byte(subkey_to_append), + info: None + } + ) + .unwrap_err(), + DatabaseError::Write(err) if *err == DatabaseWriteError { info: Error::KeyMismatch.into(), operation: DatabaseWriteOperation::CursorAppend, table_name: AccountChangeSets::NAME, key: (transition_id - 1).encode().into(), } - .into()) - ); - assert_eq!( - cursor.append( + )); + assert!(cursor + .append( transition_id, &AccountBeforeTx { address: Address::with_last_byte(subkey_to_append), info: None } - ), - Ok(()) - ); + ) + .is_ok()); } #[test] @@ -1364,7 +1383,7 @@ mod tests { let mut cursor = tx.cursor_dup_read::().unwrap(); let not_existing_key = Address::ZERO; let mut walker = cursor.walk_dup(Some(not_existing_key), None).unwrap(); - assert_eq!(walker.next(), None); + assert!(walker.next().is_none()); } } @@ -1395,11 +1414,11 @@ mod tests { let mut walker = cursor.walk_dup(None, None).unwrap(); // Notice that value11 and value22 have been ordered in the DB. - assert_eq!(Some(Ok((key1, value00))), walker.next()); - assert_eq!(Some(Ok((key1, value11))), walker.next()); + assert_eq!((key1, value00), walker.next().unwrap().unwrap()); + assert_eq!((key1, value11), walker.next().unwrap().unwrap()); // NOTE: Dup cursor does NOT iterates on all values but only on duplicated values of the // same key. assert_eq!(Ok(Some(value22.clone())), walker.next()); - assert_eq!(None, walker.next()); + assert!(walker.next().is_none()); } // Iterate by using `walk` @@ -1408,9 +1427,9 @@ mod tests { let mut cursor = tx.cursor_dup_read::().unwrap(); let first = cursor.first().unwrap().unwrap(); let mut walker = cursor.walk(Some(first.0)).unwrap(); - assert_eq!(Some(Ok((key1, value00))), walker.next()); - assert_eq!(Some(Ok((key1, value11))), walker.next()); - assert_eq!(Some(Ok((key2, value22))), walker.next()); + assert_eq!((key1, value00), walker.next().unwrap().unwrap()); + assert_eq!((key1, value11), walker.next().unwrap().unwrap()); + assert_eq!((key2, value22), walker.next().unwrap().unwrap()); } } @@ -1440,9 +1459,9 @@ mod tests { let mut walker = cursor.walk(Some(first.0)).unwrap(); // NOTE: Both values are present - assert_eq!(Some(Ok((key1, value00))), walker.next()); - assert_eq!(Some(Ok((key1, value01))), walker.next()); - assert_eq!(Some(Ok((key2, value22))), walker.next()); + assert_eq!((key1, value00), walker.next().unwrap().unwrap()); + assert_eq!((key1, value01), walker.next().unwrap().unwrap()); + assert_eq!((key2, value22), walker.next().unwrap().unwrap()); } // seek_by_key_subkey @@ -1451,9 +1470,9 @@ mod tests { let mut cursor = tx.cursor_dup_read::().unwrap(); // NOTE: There are two values with same SubKey but only first one is shown - assert_eq!(Ok(Some(value00)), cursor.seek_by_key_subkey(key1, value00.key)); + assert_eq!(value00, cursor.seek_by_key_subkey(key1, value00.key).unwrap().unwrap()); // key1 but value is greater than the one in the DB - assert_eq!(Ok(None), cursor.seek_by_key_subkey(key1, value22.key)); + assert_eq!(None, cursor.seek_by_key_subkey(key1, value22.key).unwrap()); } } diff --git a/crates/storage/db/src/implementation/mdbx/tx.rs b/crates/storage/db/src/implementation/mdbx/tx.rs index 0ca4d44a6cd..6f9ca4f230b 100644 --- a/crates/storage/db/src/implementation/mdbx/tx.rs +++ b/crates/storage/db/src/implementation/mdbx/tx.rs @@ -460,10 +460,9 @@ mod tests { sleep(MAX_DURATION + Duration::from_millis(100)); // Transaction has not timed out. - assert_eq!( - tx.get::(0), - Err(DatabaseError::Open(reth_libmdbx::Error::NotFound.into())) - ); + assert!(matches!( + tx.get::(0).unwrap_err(), + DatabaseError::Open(err) if err == reth_libmdbx::Error::NotFound.into())); // Backtrace is not recorded. assert!(!tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); } @@ -485,10 +484,9 @@ mod tests { sleep(MAX_DURATION + Duration::from_millis(100)); // Transaction has timed out. - assert_eq!( - tx.get::(0), - Err(DatabaseError::Open(reth_libmdbx::Error::ReadTransactionTimeout.into())) - ); + assert!(matches!( + tx.get::(0).unwrap_err(), + DatabaseError::Open(err) if err == reth_libmdbx::Error::ReadTransactionTimeout.into())); // Backtrace is recorded. assert!(tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); } diff --git a/crates/storage/errors/src/db.rs b/crates/storage/errors/src/db.rs index b12ad28898f..2eaf2fe44d1 100644 --- a/crates/storage/errors/src/db.rs +++ b/crates/storage/errors/src/db.rs @@ -2,15 +2,17 @@ use alloc::{ boxed::Box, format, string::{String, ToString}, + sync::Arc, vec::Vec, }; use core::{ + error::Error, fmt::{Debug, Display}, str::FromStr, }; /// Database error type. -#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Clone, Debug, thiserror::Error)] pub enum DatabaseError { /// Failed to open the database. #[error("failed to open the database: {_0}")] @@ -48,6 +50,9 @@ pub enum DatabaseError { /// Other unspecified error. #[error("{_0}")] Other(String), + /// Other unspecified error. + #[error(transparent)] + Custom(#[from] Arc), } /// Common error struct to propagate implementation-specific error information. diff --git a/crates/storage/provider/src/changesets_utils/trie.rs b/crates/storage/provider/src/changesets_utils/trie.rs index f4365aab103..cc14b516b30 100644 --- a/crates/storage/provider/src/changesets_utils/trie.rs +++ b/crates/storage/provider/src/changesets_utils/trie.rs @@ -140,7 +140,7 @@ pub fn storage_trie_wiped_changeset_iter( // Due to the ordering closure passed to `merge_join_by` it's not possible for either // value to be an error here. debug_assert!(changed.is_ok(), "unreachable error condition: {changed:?}"); - debug_assert_eq!(changed, _wiped); + debug_assert_eq!(*changed.as_ref().unwrap(), _wiped.unwrap()); changed } })) diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 6e8f1f1f800..cb59c2be25c 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -721,16 +721,16 @@ mod tests { assert_matches!(provider.insert_block(block.clone().try_recover().unwrap()), Ok(_)); - let senders = provider.take::(range.clone()); + let senders = provider.take::(range.clone()).unwrap(); assert_eq!( senders, - Ok(range + range .clone() .map(|tx_number| ( tx_number, block.body().transactions[tx_number as usize].recover_signer().unwrap() )) - .collect()) + .collect::>() ); let db_senders = provider.senders_by_tx_range(range);