mithril_aggregator/dependency_injection/containers/
serve.rs1use slog::Logger;
2use std::sync::Arc;
3use tokio::sync::RwLock;
4
5use mithril_cardano_node_chain::chain_observer::ChainObserver;
6use mithril_common::{
7 api_version::APIVersionProvider,
8 entities::{
9 CardanoTransactionsSigningConfig, Epoch, ProtocolParameters, SignerWithStake,
10 StakeDistribution,
11 },
12 signable_builder::SignableBuilderService,
13 test::builder::MithrilFixture,
14};
15
16use mithril_era::{EraChecker, EraReader};
17use mithril_persistence::store::StakeStorer;
18use mithril_signed_entity_lock::SignedEntityTypeLock;
19use mithril_ticker::TickerService;
20
21use crate::{
22 EpochSettingsStorer, MetricsService, SignerRegisterer, SignerRegistrationRoundOpener,
23 SingleSignatureAuthenticator, VerificationKeyStorer,
24 database::repository::{
25 CertificateRepository, SignedEntityStorer, SignerGetter, StakePoolStore,
26 },
27 entities::AggregatorEpochSettings,
28 event_store::{EventMessage, TransmitterService},
29 services::{
30 CertificateChainSynchronizer, CertifierService, EpochService, MessageService,
31 ProverService, SignedEntityService, SignerRecorder, SignerSynchronizer,
32 StakeDistributionService, UpkeepService,
33 },
34};
35
36pub type EpochServiceWrapper = Arc<RwLock<dyn EpochService>>;
38
39pub struct ServeCommandDependenciesContainer {
41 pub(crate) root_logger: Logger,
43
44 pub(crate) stake_store: Arc<StakePoolStore>,
47
48 pub certificate_repository: Arc<CertificateRepository>,
51
52 pub verification_key_store: Arc<dyn VerificationKeyStorer>,
54
55 pub epoch_settings_storer: Arc<dyn EpochSettingsStorer>,
57
58 pub(crate) chain_observer: Arc<dyn ChainObserver>,
60
61 pub(crate) certificate_chain_synchronizer: Arc<dyn CertificateChainSynchronizer>,
63
64 pub signer_registerer: Arc<dyn SignerRegisterer>,
66
67 pub(crate) signer_synchronizer: Arc<dyn SignerSynchronizer>,
69
70 pub(crate) signer_registration_round_opener: Arc<dyn SignerRegistrationRoundOpener>,
72
73 pub(crate) era_checker: Arc<EraChecker>,
75
76 pub(crate) era_reader: Arc<EraReader>,
78
79 pub(crate) event_transmitter: Arc<TransmitterService<EventMessage>>,
81
82 pub(crate) api_version_provider: Arc<APIVersionProvider>,
84
85 pub(crate) stake_distribution_service: Arc<dyn StakeDistributionService>,
87
88 pub(crate) signer_recorder: Arc<dyn SignerRecorder>,
90
91 pub signable_builder_service: Arc<dyn SignableBuilderService>,
93
94 pub(crate) signed_entity_service: Arc<dyn SignedEntityService>,
96
97 pub certifier_service: Arc<dyn CertifierService>,
99
100 pub(crate) epoch_service: EpochServiceWrapper,
102
103 pub(crate) ticker_service: Arc<dyn TickerService>,
105
106 pub signed_entity_storer: Arc<dyn SignedEntityStorer>,
108
109 pub(crate) signer_getter: Arc<dyn SignerGetter>,
111
112 pub message_service: Arc<dyn MessageService>,
114
115 pub prover_service: Arc<dyn ProverService>,
117
118 pub signed_entity_type_lock: Arc<SignedEntityTypeLock>,
120
121 pub(crate) upkeep_service: Arc<dyn UpkeepService>,
123
124 pub(crate) single_signer_authenticator: Arc<SingleSignatureAuthenticator>,
126
127 pub(crate) metrics_service: Arc<MetricsService>,
129}
130
131#[doc(hidden)]
132impl ServeCommandDependenciesContainer {
133 pub async fn get_genesis_epochs(&self) -> (Epoch, Epoch) {
137 let current_epoch = self
138 .chain_observer
139 .get_current_epoch()
140 .await
141 .expect("get_current_epoch should not fail")
142 .expect("an epoch should've been set to the chain observer");
143 let work_epoch = current_epoch
144 .offset_to_signer_retrieval_epoch()
145 .expect("epoch.offset_by SIGNER_EPOCH_RETRIEVAL_OFFSET should not fail");
146 let epoch_to_sign = current_epoch.offset_to_next_signer_retrieval_epoch();
147
148 (work_epoch, epoch_to_sign)
149 }
150
151 pub async fn init_state_from_fixture(
156 &self,
157 fixture: &MithrilFixture,
158 cardano_transactions_signing_config: &CardanoTransactionsSigningConfig,
159 target_epochs: &[Epoch],
160 ) {
161 for epoch in target_epochs {
162 self.epoch_settings_storer
163 .save_epoch_settings(
164 *epoch,
165 AggregatorEpochSettings {
166 protocol_parameters: fixture.protocol_parameters(),
167 cardano_transactions_signing_config: cardano_transactions_signing_config
168 .clone(),
169 },
170 )
171 .await
172 .expect("save_epoch_settings should not fail");
173 self.fill_verification_key_store(*epoch, &fixture.signers_with_stake())
174 .await;
175 self.fill_stakes_store(*epoch, fixture.signers_with_stake()).await;
176 }
177 }
178
179 pub async fn prepare_for_genesis(
188 &self,
189 genesis_signers: Vec<SignerWithStake>,
190 second_epoch_signers: Vec<SignerWithStake>,
191 genesis_protocol_parameters: &ProtocolParameters,
192 cardano_transactions_signing_config: &CardanoTransactionsSigningConfig,
193 ) {
194 self.init_epoch_settings_storer(&AggregatorEpochSettings {
195 protocol_parameters: genesis_protocol_parameters.clone(),
196 cardano_transactions_signing_config: cardano_transactions_signing_config.clone(),
197 })
198 .await;
199
200 let (work_epoch, epoch_to_sign) = self.get_genesis_epochs().await;
201 for (epoch, signers) in
202 [(work_epoch, genesis_signers), (epoch_to_sign, second_epoch_signers)]
203 {
204 self.fill_verification_key_store(epoch, &signers).await;
205 self.fill_stakes_store(epoch, signers).await;
206 }
207 }
208
209 pub async fn init_epoch_settings_storer(&self, epoch_settings: &AggregatorEpochSettings) {
213 let (work_epoch, epoch_to_sign) = self.get_genesis_epochs().await;
214 let mut epochs_to_save = Vec::new();
215 epochs_to_save.push(work_epoch);
216 epochs_to_save.push(epoch_to_sign);
217 epochs_to_save.push(epoch_to_sign.next());
218 for epoch in epochs_to_save {
219 self.epoch_settings_storer
220 .save_epoch_settings(epoch, epoch_settings.clone())
221 .await
222 .expect("save_epoch_settings should not fail");
223 }
224 }
225
226 async fn fill_verification_key_store(&self, target_epoch: Epoch, signers: &[SignerWithStake]) {
227 for signer in signers {
228 self.signer_recorder
229 .record_signer_registration(signer.party_id.clone())
230 .await
231 .expect("record_signer_registration should not fail");
232 self.verification_key_store
233 .save_verification_key(target_epoch, signer.clone())
234 .await
235 .expect("save_verification_key should not fail");
236 }
237 }
238
239 async fn fill_stakes_store(&self, target_epoch: Epoch, signers: Vec<SignerWithStake>) {
240 let _ = self
241 .stake_store
242 .save_stakes(
243 target_epoch,
244 signers.iter().map(|s| s.into()).collect::<StakeDistribution>(),
245 )
246 .await
247 .expect("save_stakes should not fail");
248 }
249}
250
251#[cfg(test)]
252pub(crate) mod tests {
253
254 use std::{path::PathBuf, sync::Arc};
255
256 use crate::{
257 ServeCommandConfiguration, ServeCommandDependenciesContainer,
258 dependency_injection::DependenciesBuilder,
259 };
260
261 #[macro_export]
264 macro_rules! initialize_dependencies {
265 () => {{ initialize_dependencies(mithril_common::temp_dir!()) }};
266 }
267
268 pub async fn initialize_dependencies(tmp_path: PathBuf) -> ServeCommandDependenciesContainer {
269 let config = ServeCommandConfiguration::new_sample(tmp_path);
270
271 let mut builder = DependenciesBuilder::new_with_stdout_logger(Arc::new(config));
272
273 builder.build_serve_dependencies_container().await.unwrap()
274 }
275}