Skip to content

Commit 4457117

Browse files
authored
Merge pull request #141 from HerodotusDev/optimize/fetcher
Optimize/fetcher (EVM)
2 parents 5de3f1d + fd69cf1 commit 4457117

File tree

6 files changed

+302
-99
lines changed

6 files changed

+302
-99
lines changed

crates/fetcher/src/lib.rs

Lines changed: 88 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
use std::{
22
collections::{HashMap, HashSet},
3+
env,
34
num::ParseIntError,
45
};
56

67
use alloy::hex::FromHexError;
78
use dry_hint_processor::syscall_handler::{evm, starknet, SyscallHandler};
9+
use eth_trie_proofs::{tx_receipt_trie::TxReceiptsMptHandler, tx_trie::TxsMptHandler};
810
use futures::StreamExt;
911
use indexer::models::IndexerError;
1012
use 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;
1219
use starknet_types_core::felt::FromStrError;
1320
use 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

2334
pub mod proof_keys;
@@ -127,7 +138,6 @@ pub struct Fetcher<'a> {
127138
#[cfg(feature = "progress_bars")]
128139
progress_bars: ProgressBars,
129140
}
130-
131141
impl<'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

Comments
 (0)