hopr_chain_indexer/traits.rs
1use std::sync::Arc;
2
3use alloy::primitives::B256;
4use async_trait::async_trait;
5use hopr_chain_types::{ContractAddresses, chain_events::SignificantChainEvent};
6use hopr_primitive_types::prelude::*;
7
8use crate::errors::Result;
9
10#[async_trait]
11pub trait ChainLogHandler {
12 fn contract_addresses(&self) -> Vec<Address>;
13
14 /// Returns the mapping of contract types to their deployed addresses.
15 ///
16 /// This method provides access to the configuration that maps logical
17 /// contract roles (token, channels, registry, etc.) to their actual
18 /// deployed Ethereum addresses.
19 ///
20 /// # Returns
21 /// * `&ContractAddresses` - Reference to the contract addresses configuration
22 fn contract_addresses_map(&self) -> Arc<ContractAddresses>;
23
24 /// Returns the event signature topics for efficient log filtering.
25 ///
26 /// This method provides the event signatures (topics) that should be
27 /// monitored for a given contract address, enabling efficient blockchain
28 /// log filtering by combining address and topic filters.
29 ///
30 /// # Arguments
31 /// * `contract` - The contract address to get event topics for
32 ///
33 /// # Returns
34 /// * `Vec<B256>` - Vector of event signature hashes (topics) for the contract
35 fn contract_address_topics(&self, contract: Address) -> Vec<B256>;
36
37 /// Returns the safe address for this HOPR node.
38 ///
39 /// The safe address is the Ethereum address that holds the node's tokens
40 /// and is used for filtering events that are relevant to this specific node.
41 ///
42 /// # Returns
43 /// * `Address` - The safe contract address for this node
44 fn safe_address(&self) -> Address;
45
46 /// Processes a single blockchain log and extracts significant events.
47 ///
48 /// This method processes individual blockchain logs, replacing the previous
49 /// batch processing approach for better error isolation and granular control.
50 ///
51 /// # Arguments
52 /// * `log` - The blockchain log to process
53 /// * `is_synced` - Whether the indexer has completed initial synchronization
54 ///
55 /// # Returns
56 /// * `Result<Option<SignificantChainEvent>>` - Extracted event or None if not significant
57 async fn collect_log_event(&self, log: SerializableLog, is_synced: bool) -> Result<Option<SignificantChainEvent>>;
58}
59
60#[cfg(test)]
61use mockall::mock;
62
63#[cfg(test)]
64mock! {
65 /// Mock implementation of ChainLogHandler for testing.
66 ///
67 /// # Example
68 /// ```
69 /// use mockall::predicate::*;
70 /// let mut mock = MockChainLogHandler::new();
71 /// mock.expect_collect_log_event()
72 /// .returning(|_, _| Ok(None));
73 /// ```
74 pub ChainLogHandler {}
75
76 impl Clone for ChainLogHandler {
77 fn clone(&self) -> Self;
78 }
79
80 #[async_trait]
81 impl ChainLogHandler for ChainLogHandler {
82 fn contract_addresses(&self) -> Vec<Address>;
83 fn contract_addresses_map(&self) -> Arc<ContractAddresses>;
84 fn contract_address_topics(&self, contract: Address) -> Vec<B256>;
85 fn safe_address(&self) -> Address;
86 async fn collect_log_event(&self, log: SerializableLog, is_synced: bool) -> Result<Option<SignificantChainEvent>>;
87 }
88}