mithril_signer/services/chain_data/
preloader_checker.rs1use std::sync::Arc;
2
3use anyhow::Context;
4use async_trait::async_trait;
5
6use mithril_common::{StdResult, entities::SignedEntityTypeDiscriminants};
7use mithril_protocol_config::interface::MithrilNetworkConfigurationProvider;
8use mithril_signed_entity_preloader::CardanoTransactionsPreloaderChecker;
9use mithril_ticker::TickerService;
10
11pub struct CardanoTransactionsPreloaderActivationSigner {
13 network_configuration_provider: Arc<dyn MithrilNetworkConfigurationProvider>,
14 ticker_service: Arc<dyn TickerService>,
15}
16
17impl CardanoTransactionsPreloaderActivationSigner {
18 pub fn new(
20 network_configuration_provider: Arc<dyn MithrilNetworkConfigurationProvider>,
21 ticker_service: Arc<dyn TickerService>,
22 ) -> Self {
23 Self {
24 network_configuration_provider,
25 ticker_service,
26 }
27 }
28}
29
30#[async_trait]
31impl CardanoTransactionsPreloaderChecker for CardanoTransactionsPreloaderActivationSigner {
32 async fn is_activated(&self) -> StdResult<bool> {
33 let epoch = self.ticker_service.get_current_epoch().await?;
34
35 let configuration = self
36 .network_configuration_provider
37 .get_network_configuration(epoch)
38 .await
39 .context(format!(
40 "An error occurred while retrieving Mithril network configuration for epoch {epoch}"
41 ))?;
42
43 let activated_signed_entity_types = configuration
44 .configuration_for_aggregation
45 .enabled_signed_entity_types;
46
47 let next_activated_signed_entity_types = configuration
48 .configuration_for_next_aggregation
49 .enabled_signed_entity_types;
50
51 Ok(activated_signed_entity_types
52 .union(&next_activated_signed_entity_types)
53 .any(|s| s == &SignedEntityTypeDiscriminants::CardanoTransactions))
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use anyhow::anyhow;
60 use mithril_common::{
61 entities::{Epoch, SignedEntityTypeDiscriminants, TimePoint},
62 test::double::Dummy,
63 };
64 use mithril_protocol_config::model::{
65 MithrilNetworkConfiguration, MithrilNetworkConfigurationForEpoch,
66 };
67 use mockall::mock;
68 use std::collections::BTreeSet;
69
70 use super::*;
71
72 mock! {
73 pub MithrilNetworkConfigurationProvider {}
74
75 #[async_trait]
76 impl MithrilNetworkConfigurationProvider for MithrilNetworkConfigurationProvider {
77 async fn get_network_configuration(&self, epoch: Epoch) -> StdResult<MithrilNetworkConfiguration>;
78 }
79 }
80 mock! {
81 pub TickerService {}
82
83 #[async_trait]
84 impl TickerService for TickerService {
85 async fn get_current_time_point(&self) -> StdResult<TimePoint>;
86 async fn get_current_epoch(&self) -> StdResult<Epoch>;
87 }
88 }
89
90 #[tokio::test]
91 async fn preloader_activation_is_not_activated_when_cardano_transactions_not_in_current_or_next_configuration_for_aggregation()
92 {
93 let mut network_configuration_provider = MockMithrilNetworkConfigurationProvider::new();
94 network_configuration_provider
95 .expect_get_network_configuration()
96 .times(1)
97 .returning(|_| {
98 Ok(MithrilNetworkConfiguration {
99 configuration_for_aggregation: MithrilNetworkConfigurationForEpoch {
100 enabled_signed_entity_types: BTreeSet::from([]),
101 ..Dummy::dummy()
102 },
103 configuration_for_next_aggregation: MithrilNetworkConfigurationForEpoch {
104 enabled_signed_entity_types: BTreeSet::from([]),
105 ..Dummy::dummy()
106 },
107 ..Dummy::dummy()
108 })
109 });
110 let mut ticker_service = MockTickerService::new();
111 ticker_service
112 .expect_get_current_epoch()
113 .times(1)
114 .returning(|| Ok(Epoch(1)));
115
116 let preloader = CardanoTransactionsPreloaderActivationSigner::new(
117 Arc::new(network_configuration_provider),
118 Arc::new(ticker_service),
119 );
120
121 let is_activated = preloader.is_activated().await.unwrap();
122
123 assert!(!is_activated);
124 }
125
126 #[tokio::test]
127 async fn preloader_activation_is_activated_when_cardano_transactions_is_in_configuration_for_aggregation()
128 {
129 let mut network_configuration_provider = MockMithrilNetworkConfigurationProvider::new();
130 network_configuration_provider
131 .expect_get_network_configuration()
132 .times(1)
133 .returning(|_| {
134 Ok(MithrilNetworkConfiguration {
135 configuration_for_aggregation: MithrilNetworkConfigurationForEpoch {
136 enabled_signed_entity_types: BTreeSet::from([
137 SignedEntityTypeDiscriminants::CardanoTransactions,
138 ]),
139 ..Dummy::dummy()
140 },
141 configuration_for_next_aggregation: MithrilNetworkConfigurationForEpoch {
142 enabled_signed_entity_types: BTreeSet::from([]),
143 ..Dummy::dummy()
144 },
145 ..Dummy::dummy()
146 })
147 });
148
149 let mut ticker_service = MockTickerService::new();
150 ticker_service
151 .expect_get_current_epoch()
152 .times(1)
153 .returning(|| Ok(Epoch(1)));
154
155 let preloader = CardanoTransactionsPreloaderActivationSigner::new(
156 Arc::new(network_configuration_provider),
157 Arc::new(ticker_service),
158 );
159
160 let is_activated = preloader.is_activated().await.unwrap();
161
162 assert!(is_activated);
163 }
164
165 #[tokio::test]
166 async fn preloader_activation_is_activated_when_cardano_transactions_is_in_configuration_for_next_aggregation()
167 {
168 let mut network_configuration_provider = MockMithrilNetworkConfigurationProvider::new();
169 network_configuration_provider
170 .expect_get_network_configuration()
171 .times(1)
172 .returning(|_| {
173 Ok(MithrilNetworkConfiguration {
174 configuration_for_aggregation: MithrilNetworkConfigurationForEpoch {
175 enabled_signed_entity_types: BTreeSet::from([]),
176 ..Dummy::dummy()
177 },
178 configuration_for_next_aggregation: MithrilNetworkConfigurationForEpoch {
179 enabled_signed_entity_types: BTreeSet::from([
180 SignedEntityTypeDiscriminants::CardanoTransactions,
181 ]),
182 ..Dummy::dummy()
183 },
184 ..Dummy::dummy()
185 })
186 });
187
188 let mut ticker_service = MockTickerService::new();
189 ticker_service
190 .expect_get_current_epoch()
191 .times(1)
192 .returning(|| Ok(Epoch(1)));
193
194 let preloader = CardanoTransactionsPreloaderActivationSigner::new(
195 Arc::new(network_configuration_provider),
196 Arc::new(ticker_service),
197 );
198
199 let is_activated = preloader.is_activated().await.unwrap();
200
201 assert!(is_activated);
202 }
203
204 #[tokio::test]
205 async fn preloader_activation_state_activate_preloader_when_aggregator_call_fails() {
206 let mut network_configuration_provider = MockMithrilNetworkConfigurationProvider::new();
207 network_configuration_provider
208 .expect_get_network_configuration()
209 .times(1)
210 .returning(|_| Err(anyhow!("Aggregator call failure")));
211
212 let mut ticker_service = MockTickerService::new();
213 ticker_service
214 .expect_get_current_epoch()
215 .times(1)
216 .returning(|| Ok(Epoch(1)));
217
218 let preloader = CardanoTransactionsPreloaderActivationSigner::new(
219 Arc::new(network_configuration_provider),
220 Arc::new(ticker_service),
221 );
222
223 preloader
224 .is_activated()
225 .await
226 .expect_err("Should fail due to aggregator call failure");
227 }
228
229 #[tokio::test]
230 async fn preloader_activation_state_activate_preloader_when_ticker_service_call_fails() {
231 let network_configuration_provider = MockMithrilNetworkConfigurationProvider::new();
232
233 let mut ticker_service = MockTickerService::new();
234 ticker_service
235 .expect_get_current_epoch()
236 .times(1)
237 .returning(|| Err(anyhow!("Ticker service call failure")));
238
239 let preloader = CardanoTransactionsPreloaderActivationSigner::new(
240 Arc::new(network_configuration_provider),
241 Arc::new(ticker_service),
242 );
243
244 preloader
245 .is_activated()
246 .await
247 .expect_err("Should fail due to ticker service call failure");
248 }
249}