mithril_aggregator/dependency_injection/builder/enablers/
cardano_node.rs

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