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}