mithril_aggregator/dependency_injection/containers/
serve.rs1use slog::Logger;
2use std::sync::Arc;
3use tokio::sync::RwLock;
4
5use mithril_common::{
6 api_version::APIVersionProvider,
7 chain_observer::ChainObserver,
8 entities::{
9 CardanoTransactionsSigningConfig, Epoch, ProtocolParameters, SignerWithStake,
10 StakeDistribution,
11 },
12 era::{EraChecker, EraReader},
13 signable_builder::SignableBuilderService,
14 test_utils::MithrilFixture,
15 TickerService,
16};
17
18use mithril_persistence::store::StakeStorer;
19use mithril_signed_entity_lock::SignedEntityTypeLock;
20
21use crate::{
22 database::repository::{
23 CertificateRepository, SignedEntityStorer, SignerGetter, StakePoolStore,
24 },
25 entities::AggregatorEpochSettings,
26 event_store::{EventMessage, TransmitterService},
27 services::{
28 CertifierService, EpochService, MessageService, ProverService, SignedEntityService,
29 SignerRecorder, SignerSynchronizer, StakeDistributionService, UpkeepService,
30 },
31 EpochSettingsStorer, MetricsService, SignerRegisterer, SignerRegistrationRoundOpener,
32 SingleSignatureAuthenticator, VerificationKeyStorer,
33};
34
35pub type EpochServiceWrapper = Arc<RwLock<dyn EpochService>>;
37
38pub struct ServeCommandDependenciesContainer {
40 pub(crate) root_logger: Logger,
42
43 pub(crate) stake_store: Arc<StakePoolStore>,
46
47 pub certificate_repository: Arc<CertificateRepository>,
50
51 pub verification_key_store: Arc<dyn VerificationKeyStorer>,
53
54 pub epoch_settings_storer: Arc<dyn EpochSettingsStorer>,
56
57 pub(crate) chain_observer: Arc<dyn ChainObserver>,
59
60 pub signer_registerer: Arc<dyn SignerRegisterer>,
62
63 pub(crate) signer_synchronizer: Arc<dyn SignerSynchronizer>,
65
66 pub(crate) signer_registration_round_opener: Arc<dyn SignerRegistrationRoundOpener>,
68
69 pub(crate) era_checker: Arc<EraChecker>,
71
72 pub(crate) era_reader: Arc<EraReader>,
74
75 pub(crate) event_transmitter: Arc<TransmitterService<EventMessage>>,
77
78 pub(crate) api_version_provider: Arc<APIVersionProvider>,
80
81 pub(crate) stake_distribution_service: Arc<dyn StakeDistributionService>,
83
84 pub(crate) signer_recorder: Arc<dyn SignerRecorder>,
86
87 pub signable_builder_service: Arc<dyn SignableBuilderService>,
89
90 pub(crate) signed_entity_service: Arc<dyn SignedEntityService>,
92
93 pub certifier_service: Arc<dyn CertifierService>,
95
96 pub(crate) epoch_service: EpochServiceWrapper,
98
99 pub(crate) ticker_service: Arc<dyn TickerService>,
101
102 pub signed_entity_storer: Arc<dyn SignedEntityStorer>,
104
105 pub(crate) signer_getter: Arc<dyn SignerGetter>,
107
108 pub message_service: Arc<dyn MessageService>,
110
111 pub prover_service: Arc<dyn ProverService>,
113
114 pub signed_entity_type_lock: Arc<SignedEntityTypeLock>,
116
117 pub(crate) upkeep_service: Arc<dyn UpkeepService>,
119
120 pub(crate) single_signer_authenticator: Arc<SingleSignatureAuthenticator>,
122
123 pub(crate) metrics_service: Arc<MetricsService>,
125}
126
127#[doc(hidden)]
128impl ServeCommandDependenciesContainer {
129 pub async fn get_genesis_epochs(&self) -> (Epoch, Epoch) {
133 let current_epoch = self
134 .chain_observer
135 .get_current_epoch()
136 .await
137 .expect("get_current_epoch should not fail")
138 .expect("an epoch should've been set to the chain observer");
139 let work_epoch = current_epoch
140 .offset_to_signer_retrieval_epoch()
141 .expect("epoch.offset_by SIGNER_EPOCH_RETRIEVAL_OFFSET should not fail");
142 let epoch_to_sign = current_epoch.offset_to_next_signer_retrieval_epoch();
143
144 (work_epoch, epoch_to_sign)
145 }
146
147 pub async fn init_state_from_fixture(
152 &self,
153 fixture: &MithrilFixture,
154 cardano_transactions_signing_config: &CardanoTransactionsSigningConfig,
155 target_epochs: &[Epoch],
156 ) {
157 for epoch in target_epochs {
158 self.epoch_settings_storer
159 .save_epoch_settings(
160 *epoch,
161 AggregatorEpochSettings {
162 protocol_parameters: fixture.protocol_parameters(),
163 cardano_transactions_signing_config: cardano_transactions_signing_config
164 .clone(),
165 },
166 )
167 .await
168 .expect("save_epoch_settings should not fail");
169 self.fill_verification_key_store(*epoch, &fixture.signers_with_stake())
170 .await;
171 self.fill_stakes_store(*epoch, fixture.signers_with_stake())
172 .await;
173 }
174 }
175
176 pub async fn prepare_for_genesis(
185 &self,
186 genesis_signers: Vec<SignerWithStake>,
187 second_epoch_signers: Vec<SignerWithStake>,
188 genesis_protocol_parameters: &ProtocolParameters,
189 cardano_transactions_signing_config: &CardanoTransactionsSigningConfig,
190 ) {
191 self.init_epoch_settings_storer(&AggregatorEpochSettings {
192 protocol_parameters: genesis_protocol_parameters.clone(),
193 cardano_transactions_signing_config: cardano_transactions_signing_config.clone(),
194 })
195 .await;
196
197 let (work_epoch, epoch_to_sign) = self.get_genesis_epochs().await;
198 for (epoch, signers) in [
199 (work_epoch, genesis_signers),
200 (epoch_to_sign, second_epoch_signers),
201 ] {
202 self.fill_verification_key_store(epoch, &signers).await;
203 self.fill_stakes_store(epoch, signers).await;
204 }
205 }
206
207 pub async fn init_epoch_settings_storer(&self, epoch_settings: &AggregatorEpochSettings) {
211 let (work_epoch, epoch_to_sign) = self.get_genesis_epochs().await;
212 let mut epochs_to_save = Vec::new();
213 epochs_to_save.push(work_epoch);
214 epochs_to_save.push(epoch_to_sign);
215 epochs_to_save.push(epoch_to_sign.next());
216 for epoch in epochs_to_save {
217 self.epoch_settings_storer
218 .save_epoch_settings(epoch, epoch_settings.clone())
219 .await
220 .expect("save_epoch_settings should not fail");
221 }
222 }
223
224 async fn fill_verification_key_store(&self, target_epoch: Epoch, signers: &[SignerWithStake]) {
225 for signer in signers {
226 self.signer_recorder
227 .record_signer_registration(signer.party_id.clone())
228 .await
229 .expect("record_signer_registration should not fail");
230 self.verification_key_store
231 .save_verification_key(target_epoch, signer.clone())
232 .await
233 .expect("save_verification_key should not fail");
234 }
235 }
236
237 async fn fill_stakes_store(&self, target_epoch: Epoch, signers: Vec<SignerWithStake>) {
238 let _ = self
239 .stake_store
240 .save_stakes(
241 target_epoch,
242 signers
243 .iter()
244 .map(|s| s.into())
245 .collect::<StakeDistribution>(),
246 )
247 .await
248 .expect("save_stakes should not fail");
249 }
250}
251
252#[cfg(test)]
253pub(crate) mod tests {
254
255 use std::{path::PathBuf, sync::Arc};
256
257 use crate::{
258 dependency_injection::DependenciesBuilder, ServeCommandConfiguration,
259 ServeCommandDependenciesContainer,
260 };
261
262 #[macro_export]
265 macro_rules! initialize_dependencies {
266 () => {{
267 initialize_dependencies(mithril_common::temp_dir!())
268 }};
269 }
270
271 pub async fn initialize_dependencies(tmp_path: PathBuf) -> ServeCommandDependenciesContainer {
272 let config = ServeCommandConfiguration::new_sample(tmp_path);
273
274 let mut builder = DependenciesBuilder::new_with_stdout_logger(Arc::new(config));
275
276 builder.build_serve_dependencies_container().await.unwrap()
277 }
278}