Skip to content

Commit

Permalink
perf: avoid redundant tx receipt fetching in verify_logs (#397)
Browse files Browse the repository at this point in the history
* perf: avoid redundant tx receipt fetching in verify_logs

* rebase with master
  • Loading branch information
eshaan7 authored Oct 26, 2024
1 parent 4f14e16 commit 65397b7
Showing 1 changed file with 34 additions and 18 deletions.
52 changes: 34 additions & 18 deletions core/src/execution/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

use alloy::network::ReceiptResponse;
use alloy::primitives::{keccak256, Address, B256, U256};
Expand Down Expand Up @@ -290,27 +290,43 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> ExecutionClient<N, R> {
}

async fn verify_logs(&self, logs: &[Log]) -> Result<()> {
for log in logs.iter() {
// For every log
// Get the hash of the tx that generated it
let tx_hash = log
.transaction_hash
.ok_or(eyre::eyre!("tx hash not found in log"))?;

// Get its proven receipt
let receipt = self
.get_transaction_receipt(tx_hash)
.await?
.ok_or(ExecutionError::NoReceiptForTransaction(tx_hash))?;
// Collect all (unique) tx hashes
let txs_hash = logs
.iter()
.map(|log| {
log.transaction_hash
.ok_or(eyre::eyre!("tx hash not found in log"))
})
.collect::<Result<HashSet<_>, _>>()?;

// Collect all (proven) tx receipts as a map of tx hash to receipt
let receipts_fut = txs_hash.iter().map(|&tx_hash| async move {
let receipt = self.get_transaction_receipt(tx_hash).await;
receipt?.map(|r| (tx_hash, r)).ok_or(eyre::eyre!(
ExecutionError::NoReceiptForTransaction(tx_hash)
))
});
let receipts = join_all(receipts_fut).await;
let receipts: HashMap<_, _> = receipts.into_iter().collect::<Result<_, _>>()?;

// Map tx hashes to encoded logs
let receipts_logs_encoded: HashMap<_, _> = receipts
.iter()
.map(|(tx_hash, receipt)| {
let encoded_logs = N::receipt_logs(&receipt)
.iter()
.map(|l| encode(&l.inner))
.collect::<Vec<_>>();
(tx_hash, encoded_logs)
})
.collect();

for log in logs.iter() {
// Check if the receipt contains the desired log
// Encoding logs for comparison
let receipt_logs_encoded = N::receipt_logs(&receipt)
.iter()
.map(|log| encode(&log.inner))
.collect::<Vec<_>>();

let tx_hash = log.transaction_hash.unwrap();
let log_encoded = encode(&log.inner);
let receipt_logs_encoded = receipts_logs_encoded.get(&tx_hash).unwrap();

if !receipt_logs_encoded.contains(&log_encoded) {
return Err(ExecutionError::MissingLog(
Expand Down

0 comments on commit 65397b7

Please sign in to comment.