Skip to content

Commit 1ab6420

Browse files
committed
Optimize log filter matching and trigger allocation (#6419)
* 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: Pre-allocate triggers Vec in parse_log_triggers Replace flat_map(...).collect() with explicit loops and a pre-sized Vec to avoid repeated reallocations.
1 parent 65ff988 commit 1ab6420

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

chain/ethereum/src/adapter.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,7 @@ impl EthereumLogFilter {
399399
let contract = LogFilterNode::Contract(log.address());
400400
let event = LogFilterNode::Event(*sig);
401401
self.contracts_and_events_graph
402-
.all_edges()
403-
.any(|(s, t, _)| (s == contract && t == event) || (t == contract && s == event))
402+
.contains_edge(contract, event)
404403
|| self.wildcard_events.contains_key(sig)
405404
|| self
406405
.events_with_topic_filters
@@ -439,13 +438,12 @@ impl EthereumLogFilter {
439438
let contract_node = LogFilterNode::Contract(*address);
440439
let event_node = LogFilterNode::Event(*event_signature);
441440

442-
// Directly iterate over all edges and return true if a matching edge that requires a receipt is found.
443-
for (s, t, &r) in self.contracts_and_events_graph.all_edges() {
444-
if r && ((s == contract_node && t == event_node)
445-
|| (t == contract_node && s == event_node))
446-
{
447-
return true;
448-
}
441+
if self
442+
.contracts_and_events_graph
443+
.edge_weight(contract_node, event_node)
444+
== Some(&true)
445+
{
446+
return true;
449447
}
450448
}
451449

chain/ethereum/src/ethereum_adapter.rs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,31 +1911,36 @@ pub(crate) fn parse_log_triggers(
19111911
return vec![];
19121912
}
19131913

1914-
block
1914+
let total_logs: usize = block
19151915
.transaction_receipts
19161916
.iter()
1917-
.flat_map(move |receipt| {
1918-
receipt.logs().iter().enumerate().map(move |(index, log)| {
1919-
let requires_transaction_receipt = log
1920-
.topics()
1921-
.first()
1922-
.map(|signature| {
1923-
log_filter.requires_transaction_receipt(
1924-
signature,
1925-
Some(&log.address()),
1926-
log.topics(),
1927-
)
1928-
})
1929-
.unwrap_or(false);
1917+
.map(|r| r.logs().len())
1918+
.sum();
1919+
let mut triggers = Vec::with_capacity(total_logs);
1920+
1921+
for receipt in &block.transaction_receipts {
1922+
for (index, log) in receipt.logs().iter().enumerate() {
1923+
let requires_transaction_receipt = log
1924+
.topics()
1925+
.first()
1926+
.map(|signature| {
1927+
log_filter.requires_transaction_receipt(
1928+
signature,
1929+
Some(&log.address()),
1930+
log.topics(),
1931+
)
1932+
})
1933+
.unwrap_or(false);
19301934

1931-
EthereumTrigger::Log(LogRef::LogPosition(LogPosition {
1932-
index,
1933-
receipt: receipt.cheap_clone(),
1934-
requires_transaction_receipt,
1935-
}))
1936-
})
1937-
})
1938-
.collect()
1935+
triggers.push(EthereumTrigger::Log(LogRef::LogPosition(LogPosition {
1936+
index,
1937+
receipt: receipt.cheap_clone(),
1938+
requires_transaction_receipt,
1939+
})));
1940+
}
1941+
}
1942+
1943+
triggers
19391944
}
19401945

19411946
pub(crate) fn parse_call_triggers(

0 commit comments

Comments
 (0)