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::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    let (static_dir, _) = create_test_static_files_dir();
49    let db = create_test_rw_db();
50    ProviderFactory::new(
51        db,
52        chain_spec,
53        StaticFileProvider::read_write(static_dir.into_path()).expect("static file provider"),
54    )
55}
56
57/// Inserts the genesis alloc from the provided chain spec into the trie.
58pub fn insert_genesis<N: ProviderNodeTypes<ChainSpec = ChainSpec>>(
59    provider_factory: &ProviderFactory<N>,
60    chain_spec: Arc<N::ChainSpec>,
61) -> ProviderResult<B256> {
62    let provider = provider_factory.provider_rw()?;
63
64    // Hash accounts and insert them into hashing table.
65    let genesis = chain_spec.genesis();
66    let alloc_accounts =
67        genesis.alloc.iter().map(|(addr, account)| (*addr, Some(Account::from(account))));
68    provider.insert_account_for_hashing(alloc_accounts).unwrap();
69
70    let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {
71        // Only return `Some` if there is storage.
72        account.storage.map(|storage| {
73            (
74                addr,
75                storage.into_iter().map(|(key, value)| StorageEntry {
76                    key,
77                    value: value.into(),
78                    ..Default::default()
79                }),
80            )
81        })
82    });
83    provider.insert_storage_for_hashing(alloc_storage)?;
84
85    let (root, updates) = StateRoot::from_tx(provider.tx_ref())
86        .root_with_updates()
87        .map_err(reth_db::DatabaseError::from)?;
88    provider.write_trie_updates(&updates).unwrap();
89
90    provider.commit()?;
91
92    Ok(root)
93}