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