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} ;
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 syscall_handler:: SyscallHandler ;
1421use thiserror:: Error ;
15- use types:: proofs:: {
16- evm:: {
17- account:: Account , header:: Header as EvmHeader , receipt:: Receipt , storage:: Storage , transaction:: Transaction , Proofs as EvmProofs ,
22+ use types:: {
23+ proofs:: {
24+ evm:: {
25+ account:: Account , header:: Header as EvmHeader , receipt:: Receipt , storage:: Storage , transaction:: Transaction ,
26+ Proofs as EvmProofs ,
27+ } ,
28+ header:: HeaderMmrMeta ,
29+ mmr:: MmrMeta ,
30+ starknet:: { header:: Header as StarknetHeader , storage:: Storage as StarknetStorage , Proofs as StarknetProofs } ,
1831 } ,
19- header:: HeaderMmrMeta ,
20- mmr:: MmrMeta ,
21- starknet:: { header:: Header as StarknetHeader , storage:: Storage as StarknetStorage , Proofs as StarknetProofs } ,
32+ RPC_URL_ETHEREUM ,
2233} ;
2334
2435pub mod proof_keys;
@@ -128,7 +139,6 @@ pub struct Fetcher<'a> {
128139 #[ cfg( feature = "progress_bars" ) ]
129140 progress_bars : ProgressBars ,
130141}
131-
132142impl < ' a > Fetcher < ' a > {
133143 pub fn new ( proof_keys : & ' a ProofKeys ) -> Self {
134144 Self {
@@ -138,18 +148,13 @@ impl<'a> Fetcher<'a> {
138148 }
139149 }
140150
141- pub async fn collect_evm_proofs ( & self ) -> Result < EvmProofs , FetcherError > {
151+ async fn collect_evm_headers_proofs (
152+ & self ,
153+ flattened_keys : & HashSet < FlattenedKey > ,
154+ ) -> Result < HashMap < MmrMeta , Vec < EvmHeader > > , FetcherError > {
142155 let mut headers_with_mmr = HashMap :: default ( ) ;
143- let mut accounts: HashSet < Account > = HashSet :: default ( ) ;
144- let mut storages: HashSet < Storage > = HashSet :: default ( ) ;
145- let mut receipts: HashSet < Receipt > = HashSet :: default ( ) ;
146- let mut transactions: HashSet < Transaction > = HashSet :: default ( ) ;
147-
148- // Collect header proofs
149156 let mut header_fut = futures:: stream:: iter (
150- self . proof_keys
151- . evm
152- . header_keys
157+ flattened_keys
153158 . iter ( )
154159 . map ( |key| EvmProofKeys :: fetch_header_proof ( key. chain_id , key. block_number ) ) ,
155160 )
@@ -167,23 +172,30 @@ impl<'a> Fetcher<'a> {
167172 self . progress_bars . evm_header . safe_inc ( ) ;
168173 }
169174
175+ Ok ( headers_with_mmr)
176+ }
177+
178+ pub async fn collect_evm_proofs ( & self ) -> Result < EvmProofs , FetcherError > {
179+ let mut accounts: HashSet < Account > = HashSet :: default ( ) ;
180+ let mut storages: HashSet < Storage > = HashSet :: default ( ) ;
181+ let mut receipts: HashSet < Receipt > = HashSet :: default ( ) ;
182+ let mut transactions: HashSet < Transaction > = HashSet :: default ( ) ;
183+
184+ let flattened_keys = self . proof_keys . evm . to_flattened_keys ( ) ;
185+
186+ // Collect required header proofs for all keys
187+ let headers_with_mmr = self . collect_evm_headers_proofs ( & flattened_keys) . await ?;
188+
170189 #[ cfg( feature = "progress_bars" ) ]
171- self . progress_bars
172- . evm_header
173- . safe_finish_with_message ( "ethereum header keys - finished" ) ;
190+ self . progress_bars . evm_header . safe_finish_with_message ( "evm header keys - finished" ) ;
174191
175192 // Collect account proofs
176193 let mut account_fut = futures:: stream:: iter ( self . proof_keys . evm . account_keys . iter ( ) . map ( EvmProofKeys :: fetch_account_proof) )
177194 . buffer_unordered ( BUFFER_UNORDERED )
178195 . boxed ( ) ;
179196
180197 while let Some ( result) = account_fut. next ( ) . await {
181- let ( header_with_mmr, account) = result?;
182- headers_with_mmr
183- . entry ( header_with_mmr. mmr_meta )
184- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
185- . or_insert ( header_with_mmr. headers ) ;
186- accounts. insert ( account) ;
198+ accounts. insert ( result?) ;
187199
188200 #[ cfg( feature = "progress_bars" ) ]
189201 self . progress_bars . evm_account . safe_inc ( ) ;
@@ -192,19 +204,15 @@ impl<'a> Fetcher<'a> {
192204 #[ cfg( feature = "progress_bars" ) ]
193205 self . progress_bars
194206 . evm_account
195- . safe_finish_with_message ( "ethereum account keys - finished" ) ;
207+ . safe_finish_with_message ( "evm account keys - finished" ) ;
196208
197209 // Collect storage proofs
198210 let mut storage_fut = futures:: stream:: iter ( self . proof_keys . evm . storage_keys . iter ( ) . map ( EvmProofKeys :: fetch_storage_proof) )
199211 . buffer_unordered ( BUFFER_UNORDERED )
200212 . boxed ( ) ;
201213
202214 while let Some ( result) = storage_fut. next ( ) . await {
203- let ( header_with_mmr, account, storage) = result?;
204- headers_with_mmr
205- . entry ( header_with_mmr. mmr_meta )
206- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
207- . or_insert ( header_with_mmr. headers ) ;
215+ let ( account, storage) = result?;
208216 accounts. insert ( account) ;
209217 storages. insert ( storage) ;
210218
@@ -215,56 +223,73 @@ impl<'a> Fetcher<'a> {
215223 #[ cfg( feature = "progress_bars" ) ]
216224 self . progress_bars
217225 . evm_storage
218- . safe_finish_with_message ( "ethereum storage keys - finished" ) ;
226+ . safe_finish_with_message ( "evm storage keys - finished" ) ;
219227
220- // Collect ransaction receipts proofs
221- let mut transaction_receipts_fut =
222- futures:: stream:: iter ( self . proof_keys . evm . receipt_keys . iter ( ) . map ( EvmProofKeys :: fetch_receipt_proof) )
223- . buffer_unordered ( BUFFER_UNORDERED )
224- . boxed ( ) ;
228+ // For each block, we need to create a mpt_handler
229+ let mut receipt_mpt_handlers: HashMap < u64 , TxReceiptsMptHandler > = HashMap :: default ( ) ;
225230
226- while let Some ( Ok ( ( header_with_mmr, transaction_receipt) ) ) = transaction_receipts_fut. next ( ) . await {
227- headers_with_mmr
228- . entry ( header_with_mmr. mmr_meta )
229- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
230- . or_insert ( header_with_mmr. headers ) ;
231- receipts. insert ( transaction_receipt) ;
231+ for block_number in self . proof_keys . evm . receipt_keys . iter ( ) . map ( |key| key. block_number ) {
232+ if let std:: collections:: hash_map:: Entry :: Vacant ( entry) = receipt_mpt_handlers. entry ( block_number) {
233+ let mut mpt_handler = TxReceiptsMptHandler :: new ( Url :: parse ( & env:: var ( RPC_URL_ETHEREUM ) . unwrap ( ) ) . unwrap ( ) )
234+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
235+
236+ mpt_handler
237+ . build_tx_receipts_tree_from_block ( block_number)
238+ . await
239+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
240+
241+ entry. insert ( mpt_handler) ;
242+ }
232243
233244 #[ cfg( feature = "progress_bars" ) ]
234245 self . progress_bars . evm_receipts . safe_inc ( ) ;
235246 }
236247
248+ receipts. extend (
249+ self . proof_keys
250+ . evm
251+ . receipt_keys
252+ . iter ( )
253+ . map ( |key| EvmProofKeys :: compute_receipt_proof ( key, receipt_mpt_handlers. get_mut ( & key. block_number ) . unwrap ( ) ) . unwrap ( ) ) ,
254+ ) ;
255+
237256 #[ cfg( feature = "progress_bars" ) ]
238257 self . progress_bars
239258 . evm_receipts
240- . safe_finish_with_message ( "ethereum receipt keys - finished" ) ;
259+ . safe_finish_with_message ( "evm receipt keys - finished" ) ;
241260
242- // Collect storage proofs
243- let mut transaction_keys_fut = futures:: stream:: iter (
244- self . proof_keys
245- . evm
246- . transaction_keys
247- . iter ( )
248- . map ( EvmProofKeys :: fetch_transaction_proof) ,
249- )
250- . buffer_unordered ( BUFFER_UNORDERED )
251- . boxed ( ) ;
261+ // For each tx block, we need to create a mpt_handler
262+ let mut tx_mpt_handlers: HashMap < u64 , TxsMptHandler > = HashMap :: default ( ) ;
252263
253- while let Some ( Ok ( ( header_with_mmr, transaction) ) ) = transaction_keys_fut. next ( ) . await {
254- headers_with_mmr
255- . entry ( header_with_mmr. mmr_meta )
256- . and_modify ( |headers : & mut Vec < EvmHeader > | headers. extend ( header_with_mmr. headers . clone ( ) ) )
257- . or_insert ( header_with_mmr. headers ) ;
258- transactions. insert ( transaction) ;
264+ for key in self . proof_keys . evm . transaction_keys . iter ( ) {
265+ if let std:: collections:: hash_map:: Entry :: Vacant ( entry) = tx_mpt_handlers. entry ( key. block_number ) {
266+ let mut mpt_handler = TxsMptHandler :: new ( Url :: parse ( & env:: var ( RPC_URL_ETHEREUM ) . unwrap ( ) ) . unwrap ( ) )
267+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
268+
269+ mpt_handler
270+ . build_tx_tree_from_block ( key. block_number )
271+ . await
272+ . map_err ( |e| FetcherError :: InternalError ( e. to_string ( ) ) ) ?;
273+
274+ entry. insert ( mpt_handler) ;
275+ }
259276
260277 #[ cfg( feature = "progress_bars" ) ]
261278 self . progress_bars . evm_transactions . safe_inc ( ) ;
262279 }
263280
281+ transactions. extend (
282+ self . proof_keys
283+ . evm
284+ . transaction_keys
285+ . iter ( )
286+ . map ( |key| EvmProofKeys :: compute_transaction_proof ( key, tx_mpt_handlers. get_mut ( & key. block_number ) . unwrap ( ) ) . unwrap ( ) ) ,
287+ ) ;
288+
264289 #[ cfg( feature = "progress_bars" ) ]
265290 self . progress_bars
266291 . evm_transactions
267- . safe_finish_with_message ( "ethereum storage keys - finished" ) ;
292+ . safe_finish_with_message ( "evm storage keys - finished" ) ;
268293
269294 Ok ( EvmProofs {
270295 headers_with_mmr : process_headers ( headers_with_mmr) ,
0 commit comments