mithril_aggregator/services/
network_configuration_provider.rs1use anyhow::Context;
2use async_trait::async_trait;
3use std::collections::BTreeSet;
4use std::sync::Arc;
5
6use mithril_common::StdResult;
7use mithril_common::entities::{Epoch, SignedEntityTypeDiscriminants};
8use mithril_protocol_config::interface::MithrilNetworkConfigurationProvider;
9use mithril_protocol_config::model::{
10 MithrilNetworkConfiguration, MithrilNetworkConfigurationForEpoch, SignedEntityTypeConfiguration,
11};
12
13use crate::EpochSettingsStorer;
14use crate::entities::AggregatorEpochSettings;
15
16pub struct LocalMithrilNetworkConfigurationProvider {
19 local_configuration_epoch_settings: AggregatorEpochSettings,
20 allowed_discriminants: BTreeSet<SignedEntityTypeDiscriminants>,
21 epoch_settings_store: Arc<dyn EpochSettingsStorer>,
22}
23
24impl LocalMithrilNetworkConfigurationProvider {
25 pub fn new(
27 local_configuration_epoch_settings: AggregatorEpochSettings,
28 allowed_discriminants: BTreeSet<SignedEntityTypeDiscriminants>,
29 epoch_settings_store: Arc<dyn EpochSettingsStorer>,
30 ) -> Self {
31 Self {
32 local_configuration_epoch_settings,
33 allowed_discriminants,
34 epoch_settings_store,
35 }
36 }
37
38 async fn get_stored_configuration_or_fallback(
40 &self,
41 epoch: Epoch,
42 ) -> StdResult<MithrilNetworkConfigurationForEpoch> {
43 let epoch_settings = self.epoch_settings_store.get_epoch_settings(epoch).await?.unwrap_or(
44 AggregatorEpochSettings {
45 protocol_parameters: self
46 .local_configuration_epoch_settings
47 .protocol_parameters
48 .clone(),
49 cardano_transactions_signing_config: self
50 .local_configuration_epoch_settings
51 .cardano_transactions_signing_config
52 .clone(),
53 cardano_blocks_transactions_signing_config: self
54 .local_configuration_epoch_settings
55 .cardano_blocks_transactions_signing_config
56 .clone(),
57 },
58 );
59
60 Ok(MithrilNetworkConfigurationForEpoch {
61 enabled_signed_entity_types: self.allowed_discriminants.clone(),
62 protocol_parameters: epoch_settings.protocol_parameters,
63 signed_entity_types_config: SignedEntityTypeConfiguration {
64 cardano_transactions: epoch_settings.cardano_transactions_signing_config,
65 cardano_blocks_transactions: epoch_settings
66 .cardano_blocks_transactions_signing_config,
67 },
68 })
69 }
70}
71
72#[async_trait]
73impl MithrilNetworkConfigurationProvider for LocalMithrilNetworkConfigurationProvider {
74 async fn get_network_configuration(
75 &self,
76 epoch: Epoch,
77 ) -> StdResult<MithrilNetworkConfiguration> {
78 let aggregation_epoch =
79 epoch.offset_to_signer_retrieval_epoch().with_context(|| {
80 format!("MithrilNetworkConfigurationProvider could not compute aggregation epoch from epoch: {epoch}")
81 })?;
82 let next_aggregation_epoch = epoch.offset_to_next_signer_retrieval_epoch();
83 let registration_epoch = epoch.offset_to_next_signer_retrieval_epoch().next();
84
85 let configuration_for_aggregation =
86 self.get_stored_configuration_or_fallback(aggregation_epoch).await?;
87 let configuration_for_next_aggregation = self
88 .get_stored_configuration_or_fallback(next_aggregation_epoch)
89 .await?;
90 let configuration_for_registration =
91 self.get_stored_configuration_or_fallback(registration_epoch).await?;
92
93 let config = MithrilNetworkConfiguration {
94 epoch,
95 configuration_for_aggregation,
96 configuration_for_next_aggregation,
97 configuration_for_registration,
98 };
99 Ok(config)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use mithril_common::{
106 entities::{
107 BlockNumber, CardanoBlocksTransactionsSigningConfig, CardanoTransactionsSigningConfig,
108 ProtocolParameters,
109 },
110 test::double::Dummy,
111 };
112
113 use crate::store::FakeEpochSettingsStorer;
114
115 use super::*;
116
117 #[tokio::test]
118 async fn get_stored_configuration_with_stored_value_returns_them() {
119 let local_configuration_epoch_settings = AggregatorEpochSettings {
120 protocol_parameters: ProtocolParameters::new(2000, 200, 0.2),
121 ..Dummy::dummy()
122 };
123 let stored_epoch_settings = AggregatorEpochSettings {
124 protocol_parameters: ProtocolParameters::new(1000, 100, 0.1),
125 ..Dummy::dummy()
126 };
127
128 let local_provider = LocalMithrilNetworkConfigurationProvider::new(
129 local_configuration_epoch_settings,
130 SignedEntityTypeDiscriminants::all(),
131 Arc::new(FakeEpochSettingsStorer::new(vec![(
132 Epoch(42),
133 stored_epoch_settings.clone(),
134 )])),
135 );
136
137 let network_configuration = local_provider
138 .get_stored_configuration_or_fallback(Epoch(42))
139 .await
140 .unwrap();
141
142 assert_eq!(
143 stored_epoch_settings.protocol_parameters,
144 network_configuration.protocol_parameters
145 )
146 }
147
148 #[tokio::test]
149 async fn get_stored_configuration_without_stored_value_fallback_to_configuration_value() {
150 let local_configuration_epoch_settings = AggregatorEpochSettings {
151 protocol_parameters: ProtocolParameters::new(2000, 200, 0.2),
152 ..Dummy::dummy()
153 };
154
155 let local_provider = LocalMithrilNetworkConfigurationProvider::new(
156 local_configuration_epoch_settings.clone(),
157 SignedEntityTypeDiscriminants::all(),
158 Arc::new(FakeEpochSettingsStorer::new(vec![])),
159 );
160
161 let network_configuration = local_provider
162 .get_stored_configuration_or_fallback(Epoch(42))
163 .await
164 .unwrap();
165
166 assert_eq!(
167 local_configuration_epoch_settings.protocol_parameters,
168 network_configuration.protocol_parameters
169 )
170 }
171
172 #[tokio::test]
173 async fn test_get_network_configuration_retrieve_configurations_for_aggregation_next_aggregation_and_registration()
174 {
175 let local_configuration_epoch_settings = AggregatorEpochSettings {
176 protocol_parameters: ProtocolParameters::new(3000, 300, 0.3),
177 cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig {
178 security_parameter: BlockNumber(3),
179 step: BlockNumber(30),
180 }),
181 cardano_blocks_transactions_signing_config: Some(
182 CardanoBlocksTransactionsSigningConfig {
183 security_parameter: BlockNumber(33),
184 step: BlockNumber(330),
185 },
186 ),
187 };
188
189 let local_provider = LocalMithrilNetworkConfigurationProvider::new(
191 local_configuration_epoch_settings,
192 SignedEntityTypeDiscriminants::all(),
193 Arc::new(FakeEpochSettingsStorer::new(vec![
194 (
195 Epoch(42),
196 AggregatorEpochSettings {
197 protocol_parameters: ProtocolParameters::new(1000, 100, 0.1),
198 cardano_transactions_signing_config: Some(
199 CardanoTransactionsSigningConfig {
200 security_parameter: BlockNumber(1),
201 step: BlockNumber(10),
202 },
203 ),
204 cardano_blocks_transactions_signing_config: Some(
205 CardanoBlocksTransactionsSigningConfig {
206 security_parameter: BlockNumber(11),
207 step: BlockNumber(110),
208 },
209 ),
210 },
211 ),
212 (
213 Epoch(43),
214 AggregatorEpochSettings {
215 protocol_parameters: ProtocolParameters::new(2000, 200, 0.2),
216 cardano_transactions_signing_config: Some(
217 CardanoTransactionsSigningConfig {
218 security_parameter: BlockNumber(2),
219 step: BlockNumber(20),
220 },
221 ),
222 cardano_blocks_transactions_signing_config: Some(
223 CardanoBlocksTransactionsSigningConfig {
224 security_parameter: BlockNumber(22),
225 step: BlockNumber(220),
226 },
227 ),
228 },
229 ),
230 ])),
231 );
232
233 let configuration = local_provider.get_network_configuration(Epoch(43)).await.unwrap();
234
235 assert_eq!(Epoch(43), configuration.epoch);
236
237 assert_eq!(
238 MithrilNetworkConfigurationForEpoch {
239 protocol_parameters: ProtocolParameters::new(1000, 100, 0.1),
240 enabled_signed_entity_types: SignedEntityTypeDiscriminants::all(),
241 signed_entity_types_config: SignedEntityTypeConfiguration {
242 cardano_transactions: Some(CardanoTransactionsSigningConfig {
243 security_parameter: BlockNumber(1),
244 step: BlockNumber(10),
245 }),
246 cardano_blocks_transactions: Some(CardanoBlocksTransactionsSigningConfig {
247 security_parameter: BlockNumber(11),
248 step: BlockNumber(110),
249 },),
250 },
251 },
252 configuration.configuration_for_aggregation
253 );
254
255 assert_eq!(
256 MithrilNetworkConfigurationForEpoch {
257 protocol_parameters: ProtocolParameters::new(2000, 200, 0.2),
258 enabled_signed_entity_types: SignedEntityTypeDiscriminants::all(),
259 signed_entity_types_config: SignedEntityTypeConfiguration {
260 cardano_transactions: Some(CardanoTransactionsSigningConfig {
261 security_parameter: BlockNumber(2),
262 step: BlockNumber(20),
263 }),
264 cardano_blocks_transactions: Some(CardanoBlocksTransactionsSigningConfig {
265 security_parameter: BlockNumber(22),
266 step: BlockNumber(220),
267 },),
268 },
269 },
270 configuration.configuration_for_next_aggregation
271 );
272
273 assert_eq!(
274 MithrilNetworkConfigurationForEpoch {
275 protocol_parameters: ProtocolParameters::new(3000, 300, 0.3),
276 enabled_signed_entity_types: SignedEntityTypeDiscriminants::all(),
277 signed_entity_types_config: SignedEntityTypeConfiguration {
278 cardano_transactions: Some(CardanoTransactionsSigningConfig {
279 security_parameter: BlockNumber(3),
280 step: BlockNumber(30),
281 }),
282 cardano_blocks_transactions: Some(CardanoBlocksTransactionsSigningConfig {
283 security_parameter: BlockNumber(33),
284 step: BlockNumber(330),
285 },),
286 },
287 },
288 configuration.configuration_for_registration
289 );
290 }
291}