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