1515//! 4. Store the fetched certificates in the database, from genesis to latest, for each certificate:
1616//! - if it exists in the database, it is replaced
1717//! - if it doesn't exist, it is inserted
18- //! 5. End
18+ //! 5. Create a certified open message in the database, based on the latest certificate and with a
19+ //! MithrilStakeDistribution signed entity type
20+ //! 6. End
1921//!
2022use anyhow:: { Context , anyhow} ;
2123use async_trait:: async_trait;
24+ use chrono:: Utc ;
2225use slog:: { Logger , debug, info} ;
2326use std:: collections:: VecDeque ;
2427use std:: sync:: Arc ;
2528
2629use mithril_common:: StdResult ;
2730use mithril_common:: certificate_chain:: CertificateVerifier ;
2831use mithril_common:: crypto_helper:: ProtocolGenesisVerifier ;
29- use mithril_common:: entities:: Certificate ;
32+ use mithril_common:: entities:: { Certificate , SignedEntityType } ;
3033use mithril_common:: logging:: LoggerExtensions ;
3134
35+ use crate :: entities:: OpenMessage ;
36+
3237use super :: {
33- CertificateChainSynchronizer , RemoteCertificateRetriever , SynchronizedCertificateStorer ,
38+ CertificateChainSynchronizer , OpenMessageStorer , RemoteCertificateRetriever ,
39+ SynchronizedCertificateStorer ,
3440} ;
3541
3642/// Service that synchronizes the certificate chain with a remote aggregator
@@ -39,6 +45,7 @@ pub struct MithrilCertificateChainSynchronizer {
3945 certificate_storer : Arc < dyn SynchronizedCertificateStorer > ,
4046 certificate_verifier : Arc < dyn CertificateVerifier > ,
4147 genesis_verifier : Arc < ProtocolGenesisVerifier > ,
48+ open_message_storer : Arc < dyn OpenMessageStorer > ,
4249 logger : Logger ,
4350}
4451
@@ -68,13 +75,15 @@ impl MithrilCertificateChainSynchronizer {
6875 certificate_storer : Arc < dyn SynchronizedCertificateStorer > ,
6976 certificate_verifier : Arc < dyn CertificateVerifier > ,
7077 genesis_verifier : Arc < ProtocolGenesisVerifier > ,
78+ open_message_storer : Arc < dyn OpenMessageStorer > ,
7179 logger : Logger ,
7280 ) -> Self {
7381 Self {
7482 remote_certificate_retriever,
7583 certificate_storer,
7684 certificate_verifier,
7785 genesis_verifier,
86+ open_message_storer,
7887 logger : logger. new_with_component_name :: < Self > ( ) ,
7988 }
8089 }
@@ -164,13 +173,18 @@ impl CertificateChainSynchronizer for MithrilCertificateChainSynchronizer {
164173 anyhow ! ( "Remote aggregator doesn't have a chain yet" )
165174 . context ( "Failed to retrieve latest remote certificate details" ) ,
166175 ) ?;
176+ let open_message = prepare_open_message_to_store ( & starting_point) ;
167177 let remote_certificate_chain = self
168178 . retrieve_and_validate_remote_certificate_chain ( starting_point)
169179 . await
170180 . with_context ( || "Failed to retrieve and validate remote certificate chain" ) ?;
171181 self . store_certificate_chain ( remote_certificate_chain)
172182 . await
173183 . with_context ( || "Failed to store remote retrieved certificate chain" ) ?;
184+ self . open_message_storer
185+ . insert_or_replace_open_message ( open_message)
186+ . await
187+ . with_context ( || "Failed to store open message when synchronizing certificate chain" ) ?;
174188
175189 info ! (
176190 self . logger,
@@ -180,6 +194,19 @@ impl CertificateChainSynchronizer for MithrilCertificateChainSynchronizer {
180194 }
181195}
182196
197+ fn prepare_open_message_to_store ( latest_certificate : & Certificate ) -> OpenMessage {
198+ OpenMessage {
199+ epoch : latest_certificate. epoch ,
200+ signed_entity_type : SignedEntityType :: MithrilStakeDistribution ( latest_certificate. epoch ) ,
201+ protocol_message : latest_certificate. protocol_message . clone ( ) ,
202+ is_certified : true ,
203+ is_expired : false ,
204+ single_signatures : Vec :: new ( ) ,
205+ created_at : Utc :: now ( ) ,
206+ expires_at : None ,
207+ }
208+ }
209+
183210#[ cfg( test) ]
184211mod tests {
185212 use anyhow:: anyhow;
@@ -194,7 +221,9 @@ mod tests {
194221 mock_extensions:: MockBuilder ,
195222 } ;
196223
197- use crate :: services:: { MockRemoteCertificateRetriever , MockSynchronizedCertificateStorer } ;
224+ use crate :: services:: {
225+ MockOpenMessageStorer , MockRemoteCertificateRetriever , MockSynchronizedCertificateStorer ,
226+ } ;
198227 use crate :: test_tools:: TestLogger ;
199228
200229 use super :: * ;
@@ -240,6 +269,7 @@ mod tests {
240269 Arc :: new ( ProtocolGenesisVerifier :: from_verification_key (
241270 genesis_verification_key,
242271 ) ) ,
272+ Arc :: new ( MockOpenMessageStorer :: new ( ) ) ,
243273 TestLogger :: stdout ( ) ,
244274 )
245275 }
@@ -599,6 +629,8 @@ mod tests {
599629 }
600630
601631 mod synchronize_certificate_chain {
632+ use mockall:: predicate:: function;
633+
602634 use super :: * ;
603635
604636 fn build_synchroniser (
@@ -617,6 +649,17 @@ mod tests {
617649 . return_once ( move || Ok ( Some ( latest) ) ) ;
618650 } ) ,
619651 certificate_verifier : fake_verifier ( remote_chain) ,
652+ open_message_storer : MockBuilder :: < MockOpenMessageStorer > :: configure ( |mock| {
653+ // Ensure that `store_open_message` is called
654+ let expected_msd_epoch = remote_chain. latest_certificate ( ) . epoch ;
655+ mock. expect_insert_or_replace_open_message ( )
656+ . with ( function ( move |open_message : & OpenMessage | {
657+ open_message. signed_entity_type
658+ == SignedEntityType :: MithrilStakeDistribution ( expected_msd_epoch)
659+ } ) )
660+ . times ( 1 ..)
661+ . returning ( |_| Ok ( ( ) ) ) ;
662+ } ) ,
620663 ..MithrilCertificateChainSynchronizer :: default_for_test ( )
621664 }
622665 }
0 commit comments