mithril_aggregator/dependency_injection/builder/enablers/
cardano_node.rs

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