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