reth_provider/test_utils/
mod.rs

1use crate::{
2    providers::{ProviderNodeTypes, StaticFileProvider},
3    HashingWriter, ProviderFactory, TrieWriter,
4};
5use alloy_primitives::B256;
6use reth_chainspec::{ChainSpec, MAINNET};
7use reth_db::{
8    test_utils::{create_test_rw_db, create_test_static_files_dir, TempDatabase},
9    DatabaseEnv,
10};
11use reth_errors::ProviderResult;
12use reth_ethereum_engine_primitives::EthEngineTypes;
13use reth_node_types::{NodeTypes, NodeTypesWithDBAdapter};
14use reth_primitives_traits::{Account, StorageEntry};
15use reth_trie::StateRoot;
16use reth_trie_db::DatabaseStateRoot;
17use std::sync::Arc;
18
19pub mod blocks;
20mod mock;
21mod noop;
22
23pub use mock::{ExtendedAccount, MockEthProvider};
24pub use noop::NoopProvider;
25pub use reth_chain_state::test_utils::TestCanonStateSubscriptions;
26
27/// Mock [`reth_node_types::NodeTypes`] for testing.
28pub type MockNodeTypes = reth_node_types::AnyNodeTypesWithEngine<
29    reth_ethereum_primitives::EthPrimitives,
30    reth_ethereum_engine_primitives::EthEngineTypes,
31    reth_chainspec::ChainSpec,
32    reth_trie_db::MerklePatriciaTrie,
33    crate::EthStorage,
34    EthEngineTypes,
35>;
36
37/// Mock [`reth_node_types::NodeTypesWithDB`] for testing.
38pub type MockNodeTypesWithDB<DB = TempDatabase<DatabaseEnv>> =
39    NodeTypesWithDBAdapter<MockNodeTypes, Arc<DB>>;
40
41/// Creates test provider factory with mainnet chain spec.
42pub fn create_test_provider_factory() -> ProviderFactory<MockNodeTypesWithDB> {
43    create_test_provider_factory_with_chain_spec(MAINNET.clone())
44}
45
46/// Creates test provider factory with provided chain spec.
47pub fn create_test_provider_factory_with_chain_spec(
48    chain_spec: Arc<ChainSpec>,
49) -> ProviderFactory<MockNodeTypesWithDB> {
50    create_test_provider_factory_with_node_types::<MockNodeTypes>(chain_spec)
51}
52
53/// Creates test provider factory with provided chain spec.
54pub fn create_test_provider_factory_with_node_types<N: NodeTypes>(
55    chain_spec: Arc<N::ChainSpec>,
56) -> ProviderFactory<NodeTypesWithDBAdapter<N, Arc<TempDatabase<DatabaseEnv>>>> {
57    let (static_dir, _) = create_test_static_files_dir();
58    let db = create_test_rw_db();
59    ProviderFactory::new(
60        db,
61        chain_spec,
62        StaticFileProvider::read_write(static_dir.into_path()).expect("static file provider"),
63    )
64}
65
66/// Inserts the genesis alloc from the provided chain spec into the trie.
67pub fn insert_genesis<N: ProviderNodeTypes<ChainSpec = ChainSpec>>(
68    provider_factory: &ProviderFactory<N>,
69    chain_spec: Arc<N::ChainSpec>,
70) -> ProviderResult<B256> {
71    let provider = provider_factory.provider_rw()?;
72
73    // Hash accounts and insert them into hashing table.
74    let genesis = chain_spec.genesis();
75    let alloc_accounts =
76        genesis.alloc.iter().map(|(addr, account)| (*addr, Some(Account::from(account))));
77    provider.insert_account_for_hashing(alloc_accounts).unwrap();
78
79    let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {
80        // Only return `Some` if there is storage.
81        account.storage.map(|storage| {
82            (
83                addr,
84                storage.into_iter().map(|(key, value)| StorageEntry { key, value: value.into() }),
85            )
86        })
87    });
88    provider.insert_storage_for_hashing(alloc_storage)?;
89
90    let (root, updates) = StateRoot::from_tx(provider.tx_ref())
91        .root_with_updates()
92        .map_err(reth_db::DatabaseError::from)?;
93    provider.write_trie_updates(&updates).unwrap();
94
95    provider.commit()?;
96
97    Ok(root)
98}