mithril_aggregator/dependency_injection/builder/enablers/
cardano_node.rs

1use anyhow::Context;
2use std::sync::Arc;
3use std::time::Duration;
4use tokio::sync::Mutex;
5
6use mithril_cardano_node_chain::{
7    chain_observer::{CardanoCliRunner, ChainObserver, ChainObserverBuilder, ChainObserverType},
8    chain_reader::{ChainBlockReader, PallasChainReader},
9    chain_scanner::{BlockScanner, CardanoBlockScanner},
10    test::double::FakeChainObserver,
11};
12use mithril_cardano_node_internal_database::digesters::{
13    CardanoImmutableDigester, ImmutableDigester,
14};
15use mithril_common::entities::SignedEntityTypeDiscriminants;
16use mithril_signed_entity_preloader::{
17    CardanoTransactionsPreloader, CardanoTransactionsPreloaderActivation,
18};
19
20use crate::ExecutionEnvironment;
21use crate::dependency_injection::{DependenciesBuilder, Result};
22use crate::get_dependency;
23use crate::services::{MithrilStakeDistributionService, StakeDistributionService};
24impl DependenciesBuilder {
25    async fn build_chain_observer(&mut self) -> Result<Arc<dyn ChainObserver>> {
26        let chain_observer: Arc<dyn ChainObserver> = match self.configuration.environment() {
27            ExecutionEnvironment::Production => {
28                let chain_observer_type = &self.configuration.chain_observer_type();
29                let cardano_cli_runner = match chain_observer_type {
30                    ChainObserverType::CardanoCli => Some(self.get_cardano_cli_runner().await?),
31                    _ => None,
32                };
33                let cardano_node_socket_path = &self.configuration.cardano_node_socket_path();
34                let cardano_network = &self
35                    .configuration
36                    .get_network()
37                    .with_context(|| "Dependencies Builder can not get Cardano network while building the chain observer")?;
38                let chain_observer_builder = ChainObserverBuilder::new(
39                    chain_observer_type,
40                    cardano_node_socket_path,
41                    cardano_network,
42                    cardano_cli_runner.as_deref(),
43                );
44
45                chain_observer_builder
46                    .build()
47                    .with_context(|| "Dependencies Builder can not build chain observer")?
48            }
49            _ => Arc::new(FakeChainObserver::default()),
50        };
51
52        Ok(chain_observer)
53    }
54
55    /// Return a [ChainObserver]
56    pub async fn get_chain_observer(&mut self) -> Result<Arc<dyn ChainObserver>> {
57        get_dependency!(self.chain_observer)
58    }
59
60    async fn build_cardano_cli_runner(&mut self) -> Result<Box<CardanoCliRunner>> {
61        let cli_runner = CardanoCliRunner::new(
62            self.configuration.cardano_cli_path(),
63            self.configuration.cardano_node_socket_path(),
64            self.configuration.get_network().with_context(|| {
65                "Dependencies Builder can not get Cardano network while building cardano cli runner"
66            })?,
67        );
68
69        Ok(Box::new(cli_runner))
70    }
71
72    /// Return a [CardanoCliRunner]
73    pub async fn get_cardano_cli_runner(&mut self) -> Result<Box<CardanoCliRunner>> {
74        get_dependency!(self.cardano_cli_runner)
75    }
76
77    async fn build_chain_block_reader(&mut self) -> Result<Arc<Mutex<dyn ChainBlockReader>>> {
78        let chain_block_reader = PallasChainReader::new(
79            &self.configuration.cardano_node_socket_path(),
80            self.configuration.get_network()?,
81            self.root_logger(),
82        );
83
84        Ok(Arc::new(Mutex::new(chain_block_reader)))
85    }
86
87    /// Chain reader
88    pub async fn get_chain_block_reader(&mut self) -> Result<Arc<Mutex<dyn ChainBlockReader>>> {
89        get_dependency!(self.chain_block_reader)
90    }
91
92    async fn build_block_scanner(&mut self) -> Result<Arc<dyn BlockScanner>> {
93        let block_scanner = CardanoBlockScanner::new(
94            self.get_chain_block_reader().await?,
95            self.configuration
96                .cardano_transactions_block_streamer_max_roll_forwards_per_poll(),
97            self.root_logger(),
98        )
99        .set_throttling_interval(
100            self.configuration
101                .cardano_transactions_block_streamer_throttling_interval()
102                .map(Duration::from_millis),
103        );
104
105        Ok(Arc::new(block_scanner))
106    }
107
108    /// Block scanner
109    pub async fn get_block_scanner(&mut self) -> Result<Arc<dyn BlockScanner>> {
110        get_dependency!(self.block_scanner)
111    }
112
113    async fn build_immutable_digester(&mut self) -> Result<Arc<dyn ImmutableDigester>> {
114        let immutable_digester_cache = match self.configuration.environment() {
115            ExecutionEnvironment::Production => Some(self.get_immutable_cache_provider().await?),
116            _ => None,
117        };
118        let digester = CardanoImmutableDigester::new(
119            self.configuration.get_network()?.to_string(),
120            immutable_digester_cache,
121            self.root_logger(),
122        );
123
124        Ok(Arc::new(digester))
125    }
126
127    /// Immutable digester.
128    pub async fn get_immutable_digester(&mut self) -> Result<Arc<dyn ImmutableDigester>> {
129        get_dependency!(self.immutable_digester)
130    }
131
132    /// Create a [CardanoTransactionsPreloader] instance.
133    pub async fn create_cardano_transactions_preloader(
134        &mut self,
135    ) -> Result<Arc<CardanoTransactionsPreloader>> {
136        let activation = self
137            .configuration
138            .compute_allowed_signed_entity_types_discriminants()?
139            .contains(&SignedEntityTypeDiscriminants::CardanoTransactions);
140        let cardano_transactions_preloader = CardanoTransactionsPreloader::new(
141            self.get_signed_entity_type_lock().await?,
142            self.get_chain_data_importer().await?,
143            self.configuration.preload_security_parameter(),
144            self.get_chain_observer().await?,
145            self.root_logger(),
146            Arc::new(CardanoTransactionsPreloaderActivation::new(activation)),
147        );
148
149        Ok(Arc::new(cardano_transactions_preloader))
150    }
151
152    async fn build_stake_distribution_service(
153        &mut self,
154    ) -> Result<Arc<dyn StakeDistributionService>> {
155        let stake_distribution_service = Arc::new(MithrilStakeDistributionService::new(
156            self.get_stake_store().await?,
157            self.get_chain_observer().await?,
158        ));
159
160        Ok(stake_distribution_service)
161    }
162
163    /// [StakeDistributionService] service
164    pub async fn get_stake_distribution_service(
165        &mut self,
166    ) -> Result<Arc<dyn StakeDistributionService>> {
167        get_dependency!(self.stake_distribution_service)
168    }
169}
170
171#[cfg(test)]
172mod tests {
173    use mithril_common::{entities::SignedEntityTypeDiscriminants, temp_dir};
174
175    use crate::ServeCommandConfiguration;
176
177    use super::*;
178
179    #[tokio::test]
180    async fn cardano_transactions_preloader_activated_with_cardano_transactions_signed_entity_type_in_configuration()
181     {
182        assert_cardano_transactions_preloader_activation(
183            SignedEntityTypeDiscriminants::CardanoTransactions.to_string(),
184            true,
185        )
186        .await;
187        assert_cardano_transactions_preloader_activation(
188            SignedEntityTypeDiscriminants::MithrilStakeDistribution.to_string(),
189            false,
190        )
191        .await;
192    }
193
194    async fn assert_cardano_transactions_preloader_activation(
195        signed_entity_types: String,
196        expected_activation: bool,
197    ) {
198        let configuration = ServeCommandConfiguration {
199            signed_entity_types: Some(signed_entity_types),
200            ..ServeCommandConfiguration::new_sample(temp_dir!())
201        };
202        let mut dep_builder = DependenciesBuilder::new_with_stdout_logger(Arc::new(configuration));
203
204        let cardano_transactions_preloader =
205            dep_builder.create_cardano_transactions_preloader().await.unwrap();
206
207        let is_activated = cardano_transactions_preloader.is_activated().await.unwrap();
208        assert_eq!(
209            expected_activation, is_activated,
210            "'is_activated' expected {expected_activation}, but was {is_activated}"
211        );
212    }
213}