@@ -50,6 +50,8 @@ cfg_fs! {
50
50
pub missing: Vec <ImmutableFileName >,
51
51
/// List of tampered immutable files.
52
52
pub tampered: Vec <ImmutableFileName >,
53
+ /// List of non-verifiable immutable files.
54
+ pub non_verifiable: Vec <ImmutableFileName >,
53
55
}
54
56
55
57
/// Compute Cardano database message related errors.
@@ -85,9 +87,8 @@ cfg_fs! {
85
87
. join( "\n " )
86
88
}
87
89
88
- let missing_files_subset = get_first_10_files_path( & lists. missing, & lists. immutables_dir) ;
89
- let tampered_files_subset = get_first_10_files_path( & lists. tampered, & lists. immutables_dir) ;
90
90
if !lists. missing. is_empty( ) {
91
+ let missing_files_subset = get_first_10_files_path( & lists. missing, & lists. immutables_dir) ;
91
92
writeln!(
92
93
f,
93
94
"Number of missing immutable files: {}" ,
@@ -100,10 +101,20 @@ cfg_fs! {
100
101
writeln!( f) ?;
101
102
}
102
103
if !lists. tampered. is_empty( ) {
104
+ let tampered_files_subset = get_first_10_files_path( & lists. tampered, & lists. immutables_dir) ;
103
105
writeln!( f, "Number of tampered immutable files: {}" , lists. tampered. len( ) ) ?;
104
106
writeln!( f, "First 10 tampered immutable files paths:" ) ?;
105
107
writeln!( f, "{tampered_files_subset}" ) ?;
106
108
}
109
+ if ( !lists. missing. is_empty( ) || !lists. tampered. is_empty( ) ) && !lists. non_verifiable. is_empty( ) {
110
+ writeln!( f) ?;
111
+ }
112
+ if !lists. non_verifiable. is_empty( ) {
113
+ let non_verifiable_files_subset = get_first_10_files_path( & lists. non_verifiable, & lists. immutables_dir) ;
114
+ writeln!( f, "Number of non verifiable immutable files: {}" , lists. non_verifiable. len( ) ) ?;
115
+ writeln!( f, "First 10 non verifiable immutable files paths:" ) ?;
116
+ writeln!( f, "{non_verifiable_files_subset}" ) ?;
117
+ }
107
118
Ok ( ( ) )
108
119
}
109
120
ComputeCardanoDatabaseMessageError :: ImmutableFilesDigester ( e) => {
@@ -269,20 +280,22 @@ impl MessageBuilder {
269
280
return Ok ( message) ;
270
281
}
271
282
272
- let tampered_files = match proof_result {
283
+ let ( tampered , non_verifiable ) = match proof_result {
273
284
Err ( e) => {
274
285
warn!( self . logger, "{MERKLE_PROOF_COMPUTATION_ERROR}: {e:}" ) ;
275
- verified_digests
276
- . list_immutable_files_not_verified( & computed_digest_entries)
277
- . tampered_files
286
+ let verified_digests = verified_digests
287
+ . list_immutable_files_not_verified( & computed_digest_entries) ;
288
+
289
+ ( verified_digests. tampered_files, verified_digests. non_verifiable_files)
278
290
}
279
- Ok ( _) => vec![ ] ,
291
+ Ok ( _) => ( vec![ ] , vec! [ ] ) ,
280
292
} ;
281
293
Err (
282
294
ComputeCardanoDatabaseMessageError :: ImmutableFilesVerification ( ImmutableFilesLists {
283
295
immutables_dir: Self :: immutable_dir( database_dir) ,
284
296
missing: missing_immutable_files,
285
- tampered: tampered_files,
297
+ tampered,
298
+ non_verifiable,
286
299
} ) ,
287
300
)
288
301
}
@@ -591,6 +604,7 @@ mod tests {
591
604
immutables_dir: MessageBuilder :: immutable_dir( & database_dir) ,
592
605
missing: to_vec_immutable_file_name( & files_to_remove) ,
593
606
tampered: vec![ ] ,
607
+ non_verifiable: vec![ ] ,
594
608
}
595
609
) ;
596
610
}
@@ -677,6 +691,7 @@ mod tests {
677
691
immutables_dir: MessageBuilder :: immutable_dir( & database_dir) ,
678
692
missing: vec![ ] ,
679
693
tampered: to_vec_immutable_file_name( & files_to_tamper) ,
694
+ non_verifiable: vec![ ] ,
680
695
}
681
696
)
682
697
}
@@ -727,9 +742,77 @@ mod tests {
727
742
immutables_dir: MessageBuilder :: immutable_dir( & database_dir) ,
728
743
missing: to_vec_immutable_file_name( & files_to_remove) ,
729
744
tampered: to_vec_immutable_file_name( & files_to_tamper) ,
745
+ non_verifiable: vec![ ] ,
730
746
}
731
747
)
732
748
}
749
+
750
+ #[ tokio:: test]
751
+ async fn compute_cardano_database_message_should_fail_if_there_is_more_local_immutable_than_verified_digest ( )
752
+ {
753
+ let last_verified_digest_number = 10 ;
754
+ let last_local_immutable_file_number = 15 ;
755
+ let range_of_non_verifiable_files =
756
+ last_verified_digest_number + 1 ..=last_local_immutable_file_number;
757
+
758
+ let expected_non_verifiable_files: Vec < ImmutableFileName > =
759
+ ( range_of_non_verifiable_files)
760
+ . flat_map ( |i| {
761
+ [
762
+ format ! ( "{i:05}.chunk" ) ,
763
+ format ! ( "{i:05}.primary" ) ,
764
+ format ! ( "{i:05}.secondary" ) ,
765
+ ]
766
+ } )
767
+ . collect ( ) ;
768
+
769
+ let beacon = CardanoDbBeacon {
770
+ epoch : Epoch ( 123 ) ,
771
+ immutable_file_number : last_verified_digest_number,
772
+ } ;
773
+ //create verified digests for immutable files 1 to 10
774
+ let ( _, certificate, verified_digests) = prepare_db_and_verified_digests (
775
+ "database_dir_for_verified_digests" ,
776
+ & beacon,
777
+ & ( 1 ..=last_verified_digest_number) ,
778
+ )
779
+ . await ;
780
+ //create a local database with immutable files 1 to 15
781
+ let ( database_dir, _, _) = prepare_db_and_verified_digests (
782
+ "database_dir_for_local_immutables" ,
783
+ & beacon,
784
+ & ( 1 ..=last_local_immutable_file_number) ,
785
+ )
786
+ . await ;
787
+
788
+ let error = MessageBuilder :: new ( )
789
+ . compute_cardano_database_message (
790
+ & certificate,
791
+ & CardanoDatabaseSnapshotMessage :: dummy ( ) ,
792
+ & ImmutableFileRange :: Range ( 1 , 15 ) ,
793
+ false ,
794
+ & database_dir,
795
+ & verified_digests,
796
+ )
797
+ . await
798
+ . expect_err (
799
+ "compute_cardano_database_message should fail if there is more local immutable than verified digest" ,
800
+ ) ;
801
+
802
+ let error_lists = match error {
803
+ ComputeCardanoDatabaseMessageError :: ImmutableFilesVerification ( lists) => lists,
804
+ _ => panic ! ( "Expected ImmutableFilesVerification error, got: {error}" ) ,
805
+ } ;
806
+ assert_eq ! (
807
+ error_lists,
808
+ ImmutableFilesLists {
809
+ immutables_dir: MessageBuilder :: immutable_dir( & database_dir) ,
810
+ missing: vec![ ] ,
811
+ tampered: vec![ ] ,
812
+ non_verifiable: expected_non_verifiable_files,
813
+ }
814
+ ) ;
815
+ }
733
816
}
734
817
735
818
mod compute_cardano_database_message_error {
@@ -738,6 +821,7 @@ mod tests {
738
821
fn generate_immutable_files_verification_error (
739
822
missing_range : Option < RangeInclusive < usize > > ,
740
823
tampered_range : Option < RangeInclusive < usize > > ,
824
+ non_verifiable_range : Option < RangeInclusive < usize > > ,
741
825
immutable_path : & str ,
742
826
) -> ComputeCardanoDatabaseMessageError {
743
827
let missing: Vec < ImmutableFileName > = match missing_range {
@@ -753,10 +837,18 @@ mod tests {
753
837
None => vec ! [ ] ,
754
838
} ;
755
839
840
+ let non_verifiable: Vec < ImmutableFileName > = match non_verifiable_range {
841
+ Some ( range) => range
842
+ . map ( |i| ImmutableFileName :: from ( format ! ( "{i:05}.chunk" ) ) )
843
+ . collect ( ) ,
844
+ None => vec ! [ ] ,
845
+ } ;
846
+
756
847
ComputeCardanoDatabaseMessageError :: ImmutableFilesVerification ( ImmutableFilesLists {
757
848
immutables_dir : PathBuf :: from ( immutable_path) ,
758
849
missing,
759
850
tampered,
851
+ non_verifiable,
760
852
} )
761
853
}
762
854
@@ -769,6 +861,7 @@ mod tests {
769
861
let error = generate_immutable_files_verification_error (
770
862
Some ( 1 ..=15 ) ,
771
863
Some ( 20 ..=31 ) ,
864
+ Some ( 40 ..=41 ) ,
772
865
"/path/to/immutables" ,
773
866
) ;
774
867
@@ -801,15 +894,21 @@ First 10 tampered immutable files paths:
801
894
/path/to/immutables/00027.chunk
802
895
/path/to/immutables/00028.chunk
803
896
/path/to/immutables/00029.chunk
897
+
898
+ Number of non verifiable immutable files: 2
899
+ First 10 non verifiable immutable files paths:
900
+ /path/to/immutables/00040.chunk
901
+ /path/to/immutables/00041.chunk
804
902
"###
805
903
) ;
806
904
}
807
905
808
906
#[ test]
809
- fn display_immutable_files_should_not_display_error_list_if_missing_is_empty ( ) {
907
+ fn display_immutable_files_should_display_tampered_files_only ( ) {
810
908
let error = generate_immutable_files_verification_error (
811
909
None ,
812
910
Some ( 1 ..=1 ) ,
911
+ None ,
813
912
"/path/to/immutables" ,
814
913
) ;
815
914
@@ -825,10 +924,11 @@ First 10 tampered immutable files paths:
825
924
}
826
925
827
926
#[ test]
828
- fn display_immutable_files_should_not_display_error_list_if_tampered_is_empty ( ) {
927
+ fn display_immutable_files_should_display_missing_files_only ( ) {
829
928
let error = generate_immutable_files_verification_error (
830
929
Some ( 1 ..=1 ) ,
831
930
None ,
931
+ None ,
832
932
"/path/to/immutables" ,
833
933
) ;
834
934
@@ -839,6 +939,30 @@ First 10 tampered immutable files paths:
839
939
r###"Number of missing immutable files: 1
840
940
First 10 missing immutable files paths:
841
941
/path/to/immutables/00001.chunk
942
+ "###
943
+ ) ;
944
+ }
945
+
946
+ #[ test]
947
+ fn display_immutable_files_should_display_non_verifiable_files_only ( ) {
948
+ let error = generate_immutable_files_verification_error (
949
+ None ,
950
+ None ,
951
+ Some ( 1 ..=5 ) ,
952
+ "/path/to/immutables" ,
953
+ ) ;
954
+
955
+ let display = normalize_path_separators ( & format ! ( "{error}" ) ) ;
956
+
957
+ assert_eq ! (
958
+ display,
959
+ r###"Number of non verifiable immutable files: 5
960
+ First 10 non verifiable immutable files paths:
961
+ /path/to/immutables/00001.chunk
962
+ /path/to/immutables/00002.chunk
963
+ /path/to/immutables/00003.chunk
964
+ /path/to/immutables/00004.chunk
965
+ /path/to/immutables/00005.chunk
842
966
"###
843
967
) ;
844
968
}
0 commit comments