diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 8168f6a2ab..7811d9d7cf 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -1,4 +1,7 @@ -use crate::{AccountProvider, BlockHashProvider, Error, StateProvider}; +use crate::{ + providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider, Error, + StateProvider, +}; use reth_db::{ cursor::{DbCursorRO, DbDupCursorRO}, models::{storage_sharded_key::StorageShardedKey, ShardedKey}, @@ -130,32 +133,22 @@ impl<'a, TX: DbTx<'a>> HistoricalStateProvider<'a, TX> { pub fn new(tx: TX, transition: TransitionId) -> Self { Self { tx, transition, _phantom: PhantomData {} } } + + /// Returns a new provider that takes the `TX` as reference + #[inline(always)] + fn as_ref<'b>(&'b self) -> HistoricalStateProviderRef<'a, 'b, TX> { + HistoricalStateProviderRef::new(&self.tx, self.transition) + } } -/// Derive trait implementation for [HistoricalStateProvider] -/// from [HistoricalStateProviderRef] type. -/// -/// Used to implement provider traits. -macro_rules! derive_from_ref { - ($trait:ident, $(fn $func:ident(&self$(, )?$($arg_name:ident: $arg:ty),*) -> $ret:ty),*) => { - impl<'a, TX: DbTx<'a>> $trait for HistoricalStateProvider<'a, TX> { - $(fn $func(&self, $($arg_name: $arg),*) -> $ret { - HistoricalStateProviderRef::new(&self.tx, self.transition).$func($($arg_name),*) - })* - } - }; -} - -derive_from_ref!(AccountProvider, fn basic_account(&self, address: Address) -> Result>); -derive_from_ref!(BlockHashProvider, fn block_hash(&self, number: U256) -> Result>); -derive_from_ref!( - StateProvider, - fn storage(&self, account: Address, storage_key: StorageKey) -> Result>, - fn bytecode_by_hash(&self, code_hash: H256) -> Result> -); +// Delegates all provider impls to [HistoricalStateProviderRef] +delegate_provider_impls!(HistoricalStateProvider<'a, TX>); #[cfg(test)] mod tests { + use crate::{ + AccountProvider, HistoricalStateProvider, HistoricalStateProviderRef, StateProvider, + }; use reth_db::{ database::Database, mdbx::test_utils::create_test_rw_db, @@ -166,12 +159,16 @@ mod tests { }; use reth_primitives::{hex_literal::hex, Account, StorageEntry, H160, H256, U256}; - use crate::{AccountProvider, HistoricalStateProviderRef, StateProvider}; - const ADDRESS: H160 = H160(hex!("0000000000000000000000000000000000000001")); const STORAGE: H256 = H256(hex!("0000000000000000000000000000000000000000000000000000000000000001")); + fn assert_state_provider() {} + #[allow(unused)] + fn assert_historical_state_provider<'txn, T: DbTx<'txn> + 'txn>() { + assert_state_provider::>(); + } + #[test] fn history_provider_get_account() { let db = create_test_rw_db(); diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index 4f316cf884..ee2cb4832b 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -1,4 +1,7 @@ -use crate::{AccountProvider, BlockHashProvider, StateProvider}; +use crate::{ + providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider, + StateProvider, +}; use reth_db::{cursor::DbDupCursorRO, tables, transaction::DbTx}; use reth_interfaces::Result; use reth_primitives::{Account, Address, Bytes, StorageKey, StorageValue, H256, U256}; @@ -64,26 +67,24 @@ impl<'a, TX: DbTx<'a>> LatestStateProvider<'a, TX> { pub fn new(db: TX) -> Self { Self { db, _phantom: PhantomData {} } } + + /// Returns a new provider that takes the `TX` as reference + #[inline(always)] + fn as_ref<'b>(&'b self) -> LatestStateProviderRef<'a, 'b, TX> { + LatestStateProviderRef::new(&self.db) + } } -/// Derive trait implementation for [LatestStateProvider] -/// from [LatestStateProviderRef] type. -/// -/// Used to implement provider traits. -macro_rules! derive_from_ref { - ($trait:ident, $(fn $func:ident(&self$(, )?$($arg_name:ident: $arg:ty),*) -> $ret:ty),*) => { - impl<'a, TX: DbTx<'a>> $trait for LatestStateProvider<'a, TX> { - $(fn $func(&self, $($arg_name: $arg),*) -> $ret { - LatestStateProviderRef::new(&self.db).$func($($arg_name),*) - })* - } - }; -} +// Delegates all provider impls to [LatestStateProviderRef] +delegate_provider_impls!(LatestStateProvider<'a, TX>); -derive_from_ref!(AccountProvider, fn basic_account(&self, address: Address) -> Result>); -derive_from_ref!(BlockHashProvider, fn block_hash(&self, number: U256) -> Result>); -derive_from_ref!( - StateProvider, - fn storage(&self, account: Address, storage_key: StorageKey) -> Result>, - fn bytecode_by_hash(&self, code_hash: H256) -> Result> -); +#[cfg(test)] +mod tests { + use super::*; + + fn assert_state_provider() {} + #[allow(unused)] + fn assert_latest_state_provider<'txn, T: DbTx<'txn> + 'txn>() { + assert_state_provider::>(); + } +} diff --git a/crates/storage/provider/src/providers/state/macros.rs b/crates/storage/provider/src/providers/state/macros.rs new file mode 100644 index 0000000000..6c8353edf0 --- /dev/null +++ b/crates/storage/provider/src/providers/state/macros.rs @@ -0,0 +1,47 @@ +//! Helper macros for implementing traits for various [StateProvider](crate::StateProvider) +//! implementations + +/// A macro that delegates trait implementations to the `as_ref` function of the type. +/// +/// Used to implement provider traits. +macro_rules! delegate_impls_to_as_ref { + ( for $target:ty => $($trait:ident { $(fn $func:ident(&self, $($arg:ident: $argty:ty),*) -> $ret:ty;)* })* ) => { + + $( + impl<'a, TX: DbTx<'a>> $trait for $target { + $( + fn $func(&self, $($arg: $argty),*) -> $ret { + self.as_ref().$func($($arg),*) + } + )* + } + )* + }; +} + +pub(crate) use delegate_impls_to_as_ref; + +/// Delegates the provider trait implementations to the `as_ref` function of the type: +/// +/// [AccountProvider](crate::AccountProvider) +/// [BlockHashProvider](crate::BlockHashProvider) +/// [StateProvider](crate::StateProvider) +macro_rules! delegate_provider_impls { + ($target:ty) => { + $crate::providers::state::macros::delegate_impls_to_as_ref!( + for $target => + AccountProvider { + fn basic_account(&self, address: Address) -> Result>; + } + BlockHashProvider { + fn block_hash(&self, number: U256) -> Result>; + } + StateProvider { + fn storage(&self, account: Address, storage_key: StorageKey) -> Result>; + fn bytecode_by_hash(&self, code_hash: H256) -> Result>; + } + ); + } +} + +pub(crate) use delegate_provider_impls; diff --git a/crates/storage/provider/src/providers/state/mod.rs b/crates/storage/provider/src/providers/state/mod.rs index 4fb69fba13..c6118d1aeb 100644 --- a/crates/storage/provider/src/providers/state/mod.rs +++ b/crates/storage/provider/src/providers/state/mod.rs @@ -2,3 +2,4 @@ pub(crate) mod chain; pub(crate) mod historical; pub(crate) mod latest; +pub(crate) mod macros;