From 88b282daab43177dd6377cf360f6ba80f35d1c06 Mon Sep 17 00:00:00 2001 From: incrypto32 Date: Wed, 4 Mar 2026 19:30:54 +0400 Subject: [PATCH 1/2] chain/ethereum: Use O(1) edge lookup in EthereumLogFilter Replace all_edges() linear scan with contains_edge() and edge_weight() in matches() and requires_transaction_receipt(). --- chain/ethereum/src/adapter.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/chain/ethereum/src/adapter.rs b/chain/ethereum/src/adapter.rs index d161462b933..34b360d9674 100644 --- a/chain/ethereum/src/adapter.rs +++ b/chain/ethereum/src/adapter.rs @@ -399,8 +399,7 @@ impl EthereumLogFilter { let contract = LogFilterNode::Contract(log.address()); let event = LogFilterNode::Event(*sig); self.contracts_and_events_graph - .all_edges() - .any(|(s, t, _)| (s == contract && t == event) || (t == contract && s == event)) + .contains_edge(contract, event) || self.wildcard_events.contains_key(sig) || self .events_with_topic_filters @@ -439,13 +438,12 @@ impl EthereumLogFilter { let contract_node = LogFilterNode::Contract(*address); let event_node = LogFilterNode::Event(*event_signature); - // Directly iterate over all edges and return true if a matching edge that requires a receipt is found. - for (s, t, &r) in self.contracts_and_events_graph.all_edges() { - if r && ((s == contract_node && t == event_node) - || (t == contract_node && s == event_node)) - { - return true; - } + if self + .contracts_and_events_graph + .edge_weight(contract_node, event_node) + == Some(&true) + { + return true; } } From bfe38a617f9aed7161b18c51769dc4505aab0617 Mon Sep 17 00:00:00 2001 From: incrypto32 Date: Wed, 4 Mar 2026 19:30:59 +0400 Subject: [PATCH 2/2] chain/ethereum: Pre-allocate triggers Vec in parse_log_triggers Replace flat_map(...).collect() with explicit loops and a pre-sized Vec to avoid repeated reallocations. --- chain/ethereum/src/ethereum_adapter.rs | 49 ++++++++++++++------------ 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/chain/ethereum/src/ethereum_adapter.rs b/chain/ethereum/src/ethereum_adapter.rs index b1a96fe9129..3f9312e0449 100644 --- a/chain/ethereum/src/ethereum_adapter.rs +++ b/chain/ethereum/src/ethereum_adapter.rs @@ -1911,31 +1911,36 @@ pub(crate) fn parse_log_triggers( return vec![]; } - block + let total_logs: usize = block .transaction_receipts .iter() - .flat_map(move |receipt| { - receipt.logs().iter().enumerate().map(move |(index, log)| { - let requires_transaction_receipt = log - .topics() - .first() - .map(|signature| { - log_filter.requires_transaction_receipt( - signature, - Some(&log.address()), - log.topics(), - ) - }) - .unwrap_or(false); + .map(|r| r.logs().len()) + .sum(); + let mut triggers = Vec::with_capacity(total_logs); + + for receipt in &block.transaction_receipts { + for (index, log) in receipt.logs().iter().enumerate() { + let requires_transaction_receipt = log + .topics() + .first() + .map(|signature| { + log_filter.requires_transaction_receipt( + signature, + Some(&log.address()), + log.topics(), + ) + }) + .unwrap_or(false); - EthereumTrigger::Log(LogRef::LogPosition(LogPosition { - index, - receipt: receipt.cheap_clone(), - requires_transaction_receipt, - })) - }) - }) - .collect() + triggers.push(EthereumTrigger::Log(LogRef::LogPosition(LogPosition { + index, + receipt: receipt.cheap_clone(), + requires_transaction_receipt, + }))); + } + } + + triggers } pub(crate) fn parse_call_triggers(