reth_provider/test_utils/
mod.rs

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