diff --git a/chain/ethereum/src/ethereum_adapter.rs b/chain/ethereum/src/ethereum_adapter.rs index 7c4d2d38f73..3ca046f359b 100644 --- a/chain/ethereum/src/ethereum_adapter.rs +++ b/chain/ethereum/src/ethereum_adapter.rs @@ -58,7 +58,7 @@ use std::time::Instant; use crate::adapter::EthereumRpcError; use crate::adapter::ProviderStatus; use crate::chain::BlockFinality; -use crate::trigger::LogRef; +use crate::trigger::{LogPosition, LogRef}; use crate::Chain; use crate::NodeCapabilities; use crate::TriggerFilter; @@ -1978,8 +1978,24 @@ pub(crate) fn parse_log_triggers( .transaction_receipts .iter() .flat_map(move |receipt| { - receipt.logs.iter().enumerate().map(move |(index, _)| { - EthereumTrigger::Log(LogRef::LogPosition(index, receipt.cheap_clone())) + 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); + + EthereumTrigger::Log(LogRef::LogPosition(LogPosition { + index, + receipt: receipt.cheap_clone(), + requires_transaction_receipt, + })) }) }) .collect() diff --git a/chain/ethereum/src/trigger.rs b/chain/ethereum/src/trigger.rs index 017e3f58194..6acd326f76e 100644 --- a/chain/ethereum/src/trigger.rs +++ b/chain/ethereum/src/trigger.rs @@ -235,24 +235,43 @@ impl ToAscPtr for MappingTrigger { } } +#[derive(Clone, Debug)] +pub struct LogPosition { + pub index: usize, + pub receipt: Arc, + pub requires_transaction_receipt: bool, +} + #[derive(Clone, Debug)] pub enum LogRef { FullLog(Arc, Option>), - LogPosition(usize, Arc), + LogPosition(LogPosition), } impl LogRef { pub fn log(&self) -> &Log { match self { LogRef::FullLog(log, _) => log.as_ref(), - LogRef::LogPosition(index, receipt) => receipt.logs.get(*index).unwrap(), + LogRef::LogPosition(pos) => pos.receipt.logs.get(pos.index).unwrap(), } } + /// Returns the transaction receipt if it's available and required. + /// + /// For `FullLog` variants, returns the receipt if present. + /// For `LogPosition` variants, only returns the receipt if the + /// `requires_transaction_receipt` flag is true, otherwise returns None + /// even though the receipt is stored internally. pub fn receipt(&self) -> Option<&Arc> { match self { LogRef::FullLog(_, receipt) => receipt.as_ref(), - LogRef::LogPosition(_, receipt) => Some(receipt), + LogRef::LogPosition(pos) => { + if pos.requires_transaction_receipt { + Some(&pos.receipt) + } else { + None + } + } } }