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::ExecutionEnvironment;
20use crate::dependency_injection::{DependenciesBuilder, Result};
21use crate::get_dependency;
22use crate::services::{MithrilStakeDistributionService, StakeDistributionService};
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.preload_security_parameter(),
138            self.get_chain_observer().await?,
139            self.root_logger(),
140            Arc::new(CardanoTransactionsPreloaderActivation::new(activation)),
141        );
142
143        Ok(Arc::new(cardano_transactions_preloader))
144    }
145
146    async fn build_stake_distribution_service(
147        &mut self,
148    ) -> Result<Arc<dyn StakeDistributionService>> {
149        let stake_distribution_service = Arc::new(MithrilStakeDistributionService::new(
150            self.get_stake_store().await?,
151            self.get_chain_observer().await?,
152        ));
153
154        Ok(stake_distribution_service)
155    }
156
157    /// [StakeDistributionService] service
158    pub async fn get_stake_distribution_service(
159        &mut self,
160    ) -> Result<Arc<dyn StakeDistributionService>> {
161        get_dependency!(self.stake_distribution_service)
162    }
163}
164
165#[cfg(test)]
166mod tests {
167    use mithril_common::{entities::SignedEntityTypeDiscriminants, temp_dir};
168
169    use crate::ServeCommandConfiguration;
170
171    use super::*;
172
173    #[tokio::test]
174    async fn cardano_transactions_preloader_activated_with_cardano_transactions_signed_entity_type_in_configuration()
175     {
176        assert_cardano_transactions_preloader_activation(
177            SignedEntityTypeDiscriminants::CardanoTransactions.to_string(),
178            true,
179        )
180        .await;
181        assert_cardano_transactions_preloader_activation(
182            SignedEntityTypeDiscriminants::MithrilStakeDistribution.to_string(),
183            false,
184        )
185        .await;
186    }
187
188    async fn assert_cardano_transactions_preloader_activation(
189        signed_entity_types: String,
190        expected_activation: bool,
191    ) {
192        let configuration = ServeCommandConfiguration {
193            signed_entity_types: Some(signed_entity_types),
194            ..ServeCommandConfiguration::new_sample(temp_dir!())
195        };
196        let mut dep_builder = DependenciesBuilder::new_with_stdout_logger(Arc::new(configuration));
197
198        let cardano_transactions_preloader =
199            dep_builder.create_cardano_transactions_preloader().await.unwrap();
200
201        let is_activated = cardano_transactions_preloader.is_activated().await.unwrap();
202        assert_eq!(
203            expected_activation, is_activated,
204            "'is_activated' expected {expected_activation}, but was {is_activated}"
205        );
206    }
207}