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