11use std:: {
22 collections:: { HashMap , HashSet } ,
3+ env,
34 num:: ParseIntError ,
45} ;
56
67use alloy:: hex:: FromHexError ;
78use dry_hint_processor:: syscall_handler:: { evm, starknet, SyscallHandler } ;
9+ use eth_trie_proofs:: { tx_receipt_trie:: TxReceiptsMptHandler , tx_trie:: TxsMptHandler } ;
810use futures:: StreamExt ;
911use indexer:: models:: IndexerError ;
1012use indicatif:: { MultiProgress , ProgressBar , ProgressStyle } ;
11- use proof_keys:: { evm:: ProofKeys as EvmProofKeys , starknet:: ProofKeys as StarknetProofKeys , ProofKeys } ;
13+ use proof_keys:: {
14+ evm:: { FlattenedKey , ProofKeys as EvmProofKeys } ,
15+ starknet:: ProofKeys as StarknetProofKeys ,
16+ ProofKeys ,
17+ } ;
18+ use reqwest:: Url ;
1219use starknet_types_core:: felt:: FromStrError ;
1320use thiserror:: Error ;
14- use types:: proofs:: {
15- evm:: {
16- account:: Account , header:: Header as EvmHeader , receipt:: Receipt , storage:: Storage , transaction:: Transaction , Proofs as EvmProofs ,
21+ use types:: {
22+ proofs:: {
23+ evm:: {
24+ account:: Account , header:: Header as EvmHeader , receipt:: Receipt , storage:: Storage , transaction:: Transaction ,
25+ Proofs as EvmProofs ,
26+ } ,
27+ header:: HeaderMmrMeta ,
28+ mmr:: MmrMeta ,
29+ starknet:: { header:: Header as StarknetHeader , storage:: Storage as StarknetStorage , Proofs as StarknetProofs } ,
1730 } ,
18- header:: HeaderMmrMeta ,
19- mmr:: MmrMeta ,
20- starknet:: { header:: Header as StarknetHeader , storage:: Storage as StarknetStorage , Proofs as StarknetProofs } ,
31+ RPC_URL_ETHEREUM ,
2132} ;
2233
2334pub mod proof_keys;
@@ -127,7 +138,6 @@ pub struct Fetcher<'a> {
127138 #[ cfg( feature = "progress_bars" ) ]
128139 progress_bars : ProgressBars ,
129140}
130-
131141impl < ' a > Fetcher < ' a > {
132142 pub fn new ( proof_keys : & ' a ProofKeys ) -> Self {
133143 Self {
@@ -137,18 +147,13 @@ impl<'a> Fetcher<'a> {
137147 }
138148 }
139149
140- pub async fn collect_evm_proofs ( & self ) -> Result < EvmProofs , FetcherError > {
150+ async fn collect_evm_headers_proofs (
151+ & self ,
152+ flattened_keys : & HashSet < FlattenedKey > ,
153+ ) -> Result < HashMap < MmrMeta , Vec < EvmHeader > > , FetcherError > {
141154 let mut headers_with_mmr = HashMap :: default ( ) ;
142- let mut accounts: HashSet < Account > = HashSet :: default ( ) ;
143- let mut storages: HashSet < Storage > = HashSet :: default ( ) ;
144- let mut receipts: HashSet < Receipt > = HashSet :: default ( ) ;
145- let mut transactions: HashSet < Transaction > = HashSet :: default ( ) ;
146-
147- // Collect header proofs
148155 let mut header_fut = futures:: stream:: iter (
149- self . proof_keys
150- . evm
151- . header_keys
156+ flattened_keys
152157 . iter ( )
153158 . map ( |key| EvmProofKeys :: fetch_header_proof ( key. chain_id , key. block_number ) ) ,
154159 )
@@ -166,23 +171,30 @@ impl<'a> Fetcher<'a> {
166171 self . progress_bars . evm_header . safe_inc ( ) ;
167172 }
168173
174+ Ok ( headers_with_mmr)
175+ }
176+
177+ pub async fn collect_evm_proofs ( & self ) -> Result < EvmProofs , FetcherError > {
178+ let mut accounts: HashSet < Account > = HashSet :: default ( ) ;
179+ let mut storages: HashSet < Storage > = HashSet :: default ( ) ;
180+ let mut receipts: HashSet < Receipt > = HashSet :: default ( ) ;
181+ let mut transactions: HashSet < Transaction > = HashSet :: default ( ) ;
182+
183+ let flattened_keys = self . proof_keys . evm . to_flattened_keys ( ) ;
184+
185+ // Collect required header proofs for all keys
186+ let headers_with_mmr = self . collect_evm_headers_proofs ( & flattened_keys) . await ?;
187+
169188 #[ cfg( feature = "progress_bars" ) ]
170- self . progress_bars
171- . evm_header
172- . safe_finish_with_message ( "ethereum header keys - finished" ) ;
189+ self . progress_bars . evm_header . safe_finish_with_message ( "evm header keys - finished" ) ;
173190
174191 // Collect account proofs
175192 let mut account_fut = futures:: stream:: iter ( self . proof_keys . evm . account_keys . iter ( ) . map ( EvmProofKeys :: fetch_account_proof) )
176193 . buffer_unordered ( BUFFER_UNORDERED )
177194 . boxed ( ) ;
178195
179196 while let Some ( result) = account_fut. next ( ) . await {
180- let ( header_with_mmr, account) = result?;
181- headers_with_mmr
182- . entry ( header_with_mmr. mmr_meta )
183- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
184- . or_insert ( header_with_mmr. headers ) ;
185- accounts. insert ( account) ;
197+ accounts. insert ( result?) ;
186198
187199 #[ cfg( feature = "progress_bars" ) ]
188200 self . progress_bars . evm_account . safe_inc ( ) ;
@@ -191,19 +203,15 @@ impl<'a> Fetcher<'a> {
191203 #[ cfg( feature = "progress_bars" ) ]
192204 self . progress_bars
193205 . evm_account
194- . safe_finish_with_message ( "ethereum account keys - finished" ) ;
206+ . safe_finish_with_message ( "evm account keys - finished" ) ;
195207
196208 // Collect storage proofs
197209 let mut storage_fut = futures:: stream:: iter ( self . proof_keys . evm . storage_keys . iter ( ) . map ( EvmProofKeys :: fetch_storage_proof) )
198210 . buffer_unordered ( BUFFER_UNORDERED )
199211 . boxed ( ) ;
200212
201213 while let Some ( result) = storage_fut. next ( ) . await {
202- let ( header_with_mmr, account, storage) = result?;
203- headers_with_mmr
204- . entry ( header_with_mmr. mmr_meta )
205- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
206- . or_insert ( header_with_mmr. headers ) ;
214+ let ( account, storage) = result?;
207215 accounts. insert ( account) ;
208216 storages. insert ( storage) ;
209217
@@ -214,56 +222,73 @@ impl<'a> Fetcher<'a> {
214222 #[ cfg( feature = "progress_bars" ) ]
215223 self . progress_bars
216224 . evm_storage
217- . safe_finish_with_message ( "ethereum storage keys - finished" ) ;
225+ . safe_finish_with_message ( "evm storage keys - finished" ) ;
218226
219- // Collect ransaction receipts proofs
220- let mut transaction_receipts_fut =
221- futures:: stream:: iter ( self . proof_keys . evm . receipt_keys . iter ( ) . map ( EvmProofKeys :: fetch_receipt_proof) )
222- . buffer_unordered ( BUFFER_UNORDERED )
223- . boxed ( ) ;
227+ // For each block, we need to create a mpt_handler
228+ let mut receipt_mpt_handlers: HashMap < u64 , TxReceiptsMptHandler > = HashMap :: default ( ) ;
224229
225- while let Some ( Ok ( ( header_with_mmr, transaction_receipt) ) ) = transaction_receipts_fut. next ( ) . await {
226- headers_with_mmr
227- . entry ( header_with_mmr. mmr_meta )
228- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
229- . or_insert ( header_with_mmr. headers ) ;
230- receipts. insert ( transaction_receipt) ;
230+ for block_number in self . proof_keys . evm . receipt_keys . iter ( ) . map ( |key| key. block_number ) {
231+ if let std:: collections:: hash_map:: Entry :: Vacant ( entry) = receipt_mpt_handlers. entry ( block_number) {
232+ let mut mpt_handler = TxReceiptsMptHandler :: new ( Url :: parse ( & env:: var ( RPC_URL_ETHEREUM ) . unwrap ( ) ) . unwrap ( ) )
233+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
234+
235+ mpt_handler
236+ . build_tx_receipts_tree_from_block ( block_number)
237+ . await
238+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
239+
240+ entry. insert ( mpt_handler) ;
241+ }
231242
232243 #[ cfg( feature = "progress_bars" ) ]
233244 self . progress_bars . evm_receipts . safe_inc ( ) ;
234245 }
235246
247+ receipts. extend (
248+ self . proof_keys
249+ . evm
250+ . receipt_keys
251+ . iter ( )
252+ . map ( |key| EvmProofKeys :: compute_receipt_proof ( key, receipt_mpt_handlers. get_mut ( & key. block_number ) . unwrap ( ) ) . unwrap ( ) ) ,
253+ ) ;
254+
236255 #[ cfg( feature = "progress_bars" ) ]
237256 self . progress_bars
238257 . evm_receipts
239- . safe_finish_with_message ( "ethereum receipt keys - finished" ) ;
258+ . safe_finish_with_message ( "evm receipt keys - finished" ) ;
240259
241- // Collect storage proofs
242- let mut transaction_keys_fut = futures:: stream:: iter (
243- self . proof_keys
244- . evm
245- . transaction_keys
246- . iter ( )
247- . map ( EvmProofKeys :: fetch_transaction_proof) ,
248- )
249- . buffer_unordered ( BUFFER_UNORDERED )
250- . boxed ( ) ;
260+ // For each tx block, we need to create a mpt_handler
261+ let mut tx_mpt_handlers: HashMap < u64 , TxsMptHandler > = HashMap :: default ( ) ;
251262
252- while let Some ( Ok ( ( header_with_mmr, transaction) ) ) = transaction_keys_fut. next ( ) . await {
253- headers_with_mmr
254- . entry ( header_with_mmr. mmr_meta )
255- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
256- . or_insert ( header_with_mmr. headers ) ;
257- transactions. insert ( transaction) ;
263+ for key in self . proof_keys . evm . transaction_keys . iter ( ) {
264+ if let std:: collections:: hash_map:: Entry :: Vacant ( entry) = tx_mpt_handlers. entry ( key. block_number ) {
265+ let mut mpt_handler = TxsMptHandler :: new ( Url :: parse ( & env:: var ( RPC_URL_ETHEREUM ) . unwrap ( ) ) . unwrap ( ) )
266+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
267+
268+ mpt_handler
269+ . build_tx_tree_from_block ( key. block_number )
270+ . await
271+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
272+
273+ entry. insert ( mpt_handler) ;
274+ }
258275
259276 #[ cfg( feature = "progress_bars" ) ]
260277 self . progress_bars . evm_transactions . safe_inc ( ) ;
261278 }
262279
280+ transactions. extend (
281+ self . proof_keys
282+ . evm
283+ . transaction_keys
284+ . iter ( )
285+ . map ( |key| EvmProofKeys :: compute_transaction_proof ( key, tx_mpt_handlers. get_mut ( & key. block_number ) . unwrap ( ) ) . unwrap ( ) ) ,
286+ ) ;
287+
263288 #[ cfg( feature = "progress_bars" ) ]
264289 self . progress_bars
265290 . evm_transactions
266- . safe_finish_with_message ( "ethereum storage keys - finished" ) ;
291+ . safe_finish_with_message ( "evm storage keys - finished" ) ;
267292
268293 Ok ( EvmProofs {
269294 headers_with_mmr : process_headers ( headers_with_mmr) ,
0 commit comments