mithril_aggregator/dependency_injection/builder/enablers/
cardano_node.rs1use 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 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 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 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 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 pub async fn get_immutable_digester(&mut self) -> Result<Arc<dyn ImmutableDigester>> {
129 get_dependency!(self.immutable_digester)
130 }
131
132 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 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}