Skip to content

Commit 18d9c06

Browse files
committed
feature(client-lib): return also list of non verified files in case of proof computation error
1 parent 1e51cd5 commit 18d9c06

File tree

1 file changed

+134
-10
lines changed

1 file changed

+134
-10
lines changed

mithril-client/src/message.rs

Lines changed: 134 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ cfg_fs! {
5050
pub missing: Vec<ImmutableFileName>,
5151
/// List of tampered immutable files.
5252
pub tampered: Vec<ImmutableFileName>,
53+
/// List of non-verifiable immutable files.
54+
pub non_verifiable: Vec<ImmutableFileName>,
5355
}
5456

5557
/// Compute Cardano database message related errors.
@@ -85,9 +87,8 @@ cfg_fs! {
8587
.join("\n")
8688
}
8789

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);
9090
if !lists.missing.is_empty() {
91+
let missing_files_subset = get_first_10_files_path(&lists.missing, &lists.immutables_dir);
9192
writeln!(
9293
f,
9394
"Number of missing immutable files: {}",
@@ -100,10 +101,20 @@ cfg_fs! {
100101
writeln!(f)?;
101102
}
102103
if !lists.tampered.is_empty() {
104+
let tampered_files_subset = get_first_10_files_path(&lists.tampered, &lists.immutables_dir);
103105
writeln!(f,"Number of tampered immutable files: {}",lists.tampered.len())?;
104106
writeln!(f, "First 10 tampered immutable files paths:")?;
105107
writeln!(f, "{tampered_files_subset}")?;
106108
}
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+
}
107118
Ok(())
108119
}
109120
ComputeCardanoDatabaseMessageError::ImmutableFilesDigester(e) => {
@@ -269,20 +280,22 @@ impl MessageBuilder {
269280
return Ok(message);
270281
}
271282

272-
let tampered_files = match proof_result {
283+
let (tampered, non_verifiable) = match proof_result {
273284
Err(e) => {
274285
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)
278290
}
279-
Ok(_) => vec![],
291+
Ok(_) => (vec![], vec![]),
280292
};
281293
Err(
282294
ComputeCardanoDatabaseMessageError::ImmutableFilesVerification(ImmutableFilesLists {
283295
immutables_dir: Self::immutable_dir(database_dir),
284296
missing: missing_immutable_files,
285-
tampered: tampered_files,
297+
tampered,
298+
non_verifiable,
286299
}),
287300
)
288301
}
@@ -591,6 +604,7 @@ mod tests {
591604
immutables_dir: MessageBuilder::immutable_dir(&database_dir),
592605
missing: to_vec_immutable_file_name(&files_to_remove),
593606
tampered: vec![],
607+
non_verifiable: vec![],
594608
}
595609
);
596610
}
@@ -677,6 +691,7 @@ mod tests {
677691
immutables_dir: MessageBuilder::immutable_dir(&database_dir),
678692
missing: vec![],
679693
tampered: to_vec_immutable_file_name(&files_to_tamper),
694+
non_verifiable: vec![],
680695
}
681696
)
682697
}
@@ -727,9 +742,77 @@ mod tests {
727742
immutables_dir: MessageBuilder::immutable_dir(&database_dir),
728743
missing: to_vec_immutable_file_name(&files_to_remove),
729744
tampered: to_vec_immutable_file_name(&files_to_tamper),
745+
non_verifiable: vec![],
730746
}
731747
)
732748
}
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+
}
733816
}
734817

735818
mod compute_cardano_database_message_error {
@@ -738,6 +821,7 @@ mod tests {
738821
fn generate_immutable_files_verification_error(
739822
missing_range: Option<RangeInclusive<usize>>,
740823
tampered_range: Option<RangeInclusive<usize>>,
824+
non_verifiable_range: Option<RangeInclusive<usize>>,
741825
immutable_path: &str,
742826
) -> ComputeCardanoDatabaseMessageError {
743827
let missing: Vec<ImmutableFileName> = match missing_range {
@@ -753,10 +837,18 @@ mod tests {
753837
None => vec![],
754838
};
755839

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+
756847
ComputeCardanoDatabaseMessageError::ImmutableFilesVerification(ImmutableFilesLists {
757848
immutables_dir: PathBuf::from(immutable_path),
758849
missing,
759850
tampered,
851+
non_verifiable,
760852
})
761853
}
762854

@@ -769,6 +861,7 @@ mod tests {
769861
let error = generate_immutable_files_verification_error(
770862
Some(1..=15),
771863
Some(20..=31),
864+
Some(40..=41),
772865
"/path/to/immutables",
773866
);
774867

@@ -801,15 +894,21 @@ First 10 tampered immutable files paths:
801894
/path/to/immutables/00027.chunk
802895
/path/to/immutables/00028.chunk
803896
/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
804902
"###
805903
);
806904
}
807905

808906
#[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() {
810908
let error = generate_immutable_files_verification_error(
811909
None,
812910
Some(1..=1),
911+
None,
813912
"/path/to/immutables",
814913
);
815914

@@ -825,10 +924,11 @@ First 10 tampered immutable files paths:
825924
}
826925

827926
#[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() {
829928
let error = generate_immutable_files_verification_error(
830929
Some(1..=1),
831930
None,
931+
None,
832932
"/path/to/immutables",
833933
);
834934

@@ -839,6 +939,30 @@ First 10 tampered immutable files paths:
839939
r###"Number of missing immutable files: 1
840940
First 10 missing immutable files paths:
841941
/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
842966
"###
843967
);
844968
}

0 commit comments

Comments
 (0)