@@ -180,10 +180,15 @@ impl CertificateChainSynchronizer for MithrilCertificateChainSynchronizer {
180180#[ cfg( test) ]
181181mod tests {
182182 use anyhow:: anyhow;
183+ use std:: sync:: RwLock ;
183184
185+ use mithril_common:: certificate_chain:: {
186+ FakeCertificaterRetriever , MithrilCertificateVerifier ,
187+ } ;
184188 use mithril_common:: crypto_helper:: ProtocolGenesisVerificationKey ;
185189 use mithril_common:: test_utils:: {
186- CertificateChainBuilder , fake_data, fake_keys, mock_extensions:: MockBuilder ,
190+ CertificateChainBuilder , CertificateChainFixture , fake_data, fake_keys,
191+ mock_extensions:: MockBuilder ,
187192 } ;
188193
189194 use crate :: services:: { MockRemoteCertificateRetriever , MockSynchronizedCertificateStorer } ;
@@ -293,6 +298,51 @@ mod tests {
293298 } ;
294299 }
295300
301+ fn fake_verifier ( remote_certificate_chain : & [ Certificate ] ) -> Arc < dyn CertificateVerifier > {
302+ let verifier = MithrilCertificateVerifier :: new (
303+ TestLogger :: stdout ( ) ,
304+ Arc :: new ( FakeCertificaterRetriever :: from_certificates (
305+ remote_certificate_chain,
306+ ) ) ,
307+ ) ;
308+ Arc :: new ( verifier)
309+ }
310+
311+ #[ derive( Default ) ]
312+ struct DumbCertificateStorer {
313+ certificates : RwLock < Vec < Certificate > > ,
314+ genesis_certificate : Option < Certificate > ,
315+ }
316+
317+ impl DumbCertificateStorer {
318+ fn new ( genesis : Certificate , already_stored : Vec < Certificate > ) -> Self {
319+ Self {
320+ certificates : RwLock :: new ( already_stored) ,
321+ genesis_certificate : Some ( genesis) ,
322+ }
323+ }
324+
325+ fn stored_certificates ( & self ) -> Vec < Certificate > {
326+ self . certificates . read ( ) . unwrap ( ) . clone ( )
327+ }
328+ }
329+
330+ #[ async_trait]
331+ impl SynchronizedCertificateStorer for DumbCertificateStorer {
332+ async fn insert_or_replace_many (
333+ & self ,
334+ certificates_chain : Vec < Certificate > ,
335+ ) -> StdResult < ( ) > {
336+ let mut certificates = self . certificates . write ( ) . unwrap ( ) ;
337+ * certificates = certificates_chain;
338+ Ok ( ( ) )
339+ }
340+
341+ async fn get_latest_genesis ( & self ) -> StdResult < Option < Certificate > > {
342+ Ok ( self . genesis_certificate . clone ( ) )
343+ }
344+ }
345+
296346 mod check_sync_state {
297347 use super :: * ;
298348
@@ -395,22 +445,8 @@ mod tests {
395445 }
396446
397447 mod retrieve_validate_remote_certificate_chain {
398- use mithril_common:: certificate_chain:: {
399- FakeCertificaterRetriever , MithrilCertificateVerifier ,
400- } ;
401-
402448 use super :: * ;
403449
404- fn fake_verifier ( remote_certificate_chain : & [ Certificate ] ) -> Arc < dyn CertificateVerifier > {
405- let verifier = MithrilCertificateVerifier :: new (
406- TestLogger :: stdout ( ) ,
407- Arc :: new ( FakeCertificaterRetriever :: from_certificates (
408- remote_certificate_chain,
409- ) ) ,
410- ) ;
411- Arc :: new ( verifier)
412- }
413-
414450 #[ tokio:: test]
415451 async fn succeed_if_the_remote_chain_only_contains_a_genesis_certificate ( ) {
416452 let chain = CertificateChainBuilder :: new ( ) . with_total_certificates ( 1 ) . build ( ) ;
@@ -464,37 +500,8 @@ mod tests {
464500 }
465501
466502 mod store_remote_certificate_chain {
467- use std:: sync:: RwLock ;
468-
469503 use super :: * ;
470504
471- #[ derive( Default ) ]
472- struct DumbCertificateStorer {
473- certificates : RwLock < Vec < Certificate > > ,
474- }
475-
476- impl DumbCertificateStorer {
477- fn stored_certificates ( & self ) -> Vec < Certificate > {
478- self . certificates . read ( ) . unwrap ( ) . clone ( )
479- }
480- }
481-
482- #[ async_trait]
483- impl SynchronizedCertificateStorer for DumbCertificateStorer {
484- async fn insert_or_replace_many (
485- & self ,
486- certificates_chain : Vec < Certificate > ,
487- ) -> StdResult < ( ) > {
488- let mut certificates = self . certificates . write ( ) . unwrap ( ) ;
489- * certificates = certificates_chain;
490- Ok ( ( ) )
491- }
492-
493- async fn get_latest_genesis ( & self ) -> StdResult < Option < Certificate > > {
494- unimplemented ! ( "not needed in store_remote_certificate_chain tests" )
495- }
496- }
497-
498505 #[ tokio:: test]
499506 async fn do_store_given_certificates ( ) {
500507 let certificates_chain = vec ! [
@@ -536,4 +543,74 @@ mod tests {
536543 . unwrap_err ( ) ;
537544 }
538545 }
546+
547+ mod synchronize_certificate_chain {
548+ use super :: * ;
549+
550+ fn build_synchroniser (
551+ remote_chain : & CertificateChainFixture ,
552+ storer : Arc < dyn SynchronizedCertificateStorer > ,
553+ ) -> MithrilCertificateChainSynchronizer {
554+ MithrilCertificateChainSynchronizer {
555+ certificate_storer : storer. clone ( ) ,
556+ remote_certificate_retriever :
557+ MockBuilder :: < MockRemoteCertificateRetriever > :: configure ( |mock| {
558+ let genesis = remote_chain. genesis_certificate ( ) . clone ( ) ;
559+ mock. expect_get_genesis_certificate_details ( )
560+ . return_once ( move || Ok ( Some ( genesis) ) ) ;
561+ let latest = remote_chain. latest_certificate ( ) . clone ( ) ;
562+ mock. expect_get_latest_certificate_details ( )
563+ . return_once ( move || Ok ( Some ( latest) ) ) ;
564+ } ) ,
565+ certificate_verifier : fake_verifier ( remote_chain) ,
566+ ..MithrilCertificateChainSynchronizer :: default_for_test ( )
567+ }
568+ }
569+
570+ #[ tokio:: test]
571+ async fn store_all ( ) {
572+ let remote_chain = CertificateChainBuilder :: default ( )
573+ . with_certificates_per_epoch ( 3 )
574+ . with_total_certificates ( 8 )
575+ . build ( ) ;
576+ let storer = Arc :: new ( DumbCertificateStorer :: default ( ) ) ;
577+ let synchroniser = build_synchroniser ( & remote_chain, storer. clone ( ) ) ;
578+
579+ // Will sync even if force is false
580+ synchroniser. synchronize_certificate_chain ( false ) . await . unwrap ( ) ;
581+
582+ assert_eq ! (
583+ remote_chain. certificate_path_to_genesis( & remote_chain. latest_certificate( ) . hash) ,
584+ storer. stored_certificates( )
585+ ) ;
586+ }
587+
588+ #[ tokio:: test]
589+ async fn store_partial ( ) {
590+ let remote_chain = CertificateChainBuilder :: default ( )
591+ . with_certificates_per_epoch ( 1 )
592+ . with_total_certificates ( 8 )
593+ . build ( ) ;
594+ let existing_certificates =
595+ remote_chain. certificate_path_to_genesis ( & remote_chain[ 5 ] . hash ) ;
596+ let storer = Arc :: new ( DumbCertificateStorer :: new (
597+ remote_chain. genesis_certificate ( ) . clone ( ) ,
598+ existing_certificates. clone ( ) ,
599+ ) ) ;
600+ let synchroniser = build_synchroniser ( & remote_chain, storer. clone ( ) ) ;
601+
602+ // Force false - won't sync
603+ synchroniser. synchronize_certificate_chain ( false ) . await . unwrap ( ) ;
604+
605+ assert_eq ! ( & existing_certificates, & storer. stored_certificates( ) ) ;
606+
607+ // Force true - will sync
608+ synchroniser. synchronize_certificate_chain ( true ) . await . unwrap ( ) ;
609+
610+ assert_eq ! (
611+ remote_chain. certificate_path_to_genesis( & remote_chain. latest_certificate( ) . hash) ,
612+ storer. stored_certificates( )
613+ ) ;
614+ }
615+ }
539616}
0 commit comments