1use crate::{
2 ChainSpecProvider, DBProvider, EitherWriter, HistoryWriter, NodePrimitivesProvider,
3 ProviderResult, RocksDBProviderFactory, StorageSettingsCache,
4};
5use alloy_consensus::BlockHeader;
6use alloy_genesis::GenesisAccount;
7use alloy_primitives::Address;
8use reth_chainspec::EthChainSpec;
9use reth_db::{
10 models::{storage_sharded_key::StorageShardedKey, ShardedKey},
11 transaction::DbTxMut,
12 BlockNumberList,
13};
14use tracing::trace;
15
16pub fn insert_genesis_history<'a, 'b, Provider>(
21 provider: &Provider,
22 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)> + Clone,
23) -> ProviderResult<()>
24where
25 Provider: DBProvider<Tx: DbTxMut>
26 + HistoryWriter
27 + ChainSpecProvider
28 + StorageSettingsCache
29 + RocksDBProviderFactory
30 + NodePrimitivesProvider,
31{
32 let genesis_block_number = provider.chain_spec().genesis_header().number();
33 insert_history(provider, alloc, genesis_block_number)
34}
35
36pub fn insert_genesis_account_history<'a, 'b, Provider>(
38 provider: &Provider,
39 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)>,
40) -> ProviderResult<()>
41where
42 Provider: DBProvider<Tx: DbTxMut>
43 + HistoryWriter
44 + ChainSpecProvider
45 + StorageSettingsCache
46 + RocksDBProviderFactory
47 + NodePrimitivesProvider,
48{
49 let genesis_block_number = provider.chain_spec().genesis_header().number();
50 insert_account_history(provider, alloc, genesis_block_number)
51}
52
53pub fn insert_genesis_storage_history<'a, 'b, Provider>(
55 provider: &Provider,
56 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)>,
57) -> ProviderResult<()>
58where
59 Provider: DBProvider<Tx: DbTxMut>
60 + HistoryWriter
61 + ChainSpecProvider
62 + StorageSettingsCache
63 + RocksDBProviderFactory
64 + NodePrimitivesProvider,
65{
66 let genesis_block_number = provider.chain_spec().genesis_header().number();
67 insert_storage_history(provider, alloc, genesis_block_number)
68}
69
70pub fn insert_history<'a, 'b, Provider>(
75 provider: &Provider,
76 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)> + Clone,
77 block: u64,
78) -> ProviderResult<()>
79where
80 Provider: DBProvider<Tx: DbTxMut>
81 + HistoryWriter
82 + StorageSettingsCache
83 + RocksDBProviderFactory
84 + NodePrimitivesProvider,
85{
86 insert_account_history(provider, alloc.clone(), block)?;
87 insert_storage_history(provider, alloc, block)?;
88 Ok(())
89}
90
91pub fn insert_account_history<'a, 'b, Provider>(
93 provider: &Provider,
94 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)>,
95 block: u64,
96) -> ProviderResult<()>
97where
98 Provider: DBProvider<Tx: DbTxMut>
99 + HistoryWriter
100 + StorageSettingsCache
101 + RocksDBProviderFactory
102 + NodePrimitivesProvider,
103{
104 provider.with_rocksdb_batch(|batch| {
105 let mut writer = EitherWriter::new_accounts_history(provider, batch)?;
106 let list = BlockNumberList::new([block]).expect("single block always fits");
107 for (addr, _) in alloc {
108 writer.upsert_account_history(ShardedKey::last(*addr), &list)?;
109 }
110 trace!(target: "reth::provider", "Inserted account history");
111 Ok(((), writer.into_raw_rocksdb_batch()))
112 })?;
113
114 Ok(())
115}
116
117pub fn insert_storage_history<'a, 'b, Provider>(
119 provider: &Provider,
120 alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)>,
121 block: u64,
122) -> ProviderResult<()>
123where
124 Provider: DBProvider<Tx: DbTxMut>
125 + HistoryWriter
126 + StorageSettingsCache
127 + RocksDBProviderFactory
128 + NodePrimitivesProvider,
129{
130 provider.with_rocksdb_batch(|batch| {
131 let mut writer = EitherWriter::new_storages_history(provider, batch)?;
132 let list = BlockNumberList::new([block]).expect("single block always fits");
133 for (addr, account) in alloc {
134 if let Some(storage) = &account.storage {
135 for key in storage.keys() {
136 writer.upsert_storage_history(StorageShardedKey::last(*addr, *key), &list)?;
137 }
138 }
139 }
140 trace!(target: "reth::cli", "Inserted storage history");
141 Ok(((), writer.into_raw_rocksdb_batch()))
142 })?;
143
144 Ok(())
145}