@@ -14,34 +14,34 @@ use std::path::{Path, PathBuf};
1414
1515use anyhow:: Context ;
1616
17- use mithril_common:: digesters:: immutable_trio_names;
17+ use mithril_common:: digesters:: { immutable_trio_names, IMMUTABLE_DIR } ;
1818use mithril_common:: entities:: ImmutableFileNumber ;
1919use mithril_common:: StdResult ;
2020
2121const BASE_ERROR : & str = "Unexpected downloaded file check failed" ;
2222
2323/// Tool to check and remove unexpected files when downloading and unpacking Mithril archives
2424pub struct UnexpectedDownloadedFileVerifier {
25- dir_to_check : PathBuf ,
25+ target_cardano_db_dir : PathBuf ,
2626 immutable_files_range_to_expect : RangeInclusive < ImmutableFileNumber > ,
2727}
2828
2929/// List of expected files after downloading and unpacking, yielded by `UnexpectedDownloadedFileVerifier::compute_expected_state_after_download`
3030pub struct ExpectedFilesAfterDownload {
31- dir_to_check : PathBuf ,
31+ target_immutable_files_dir : PathBuf ,
3232 expected_files : HashSet < PathBuf > ,
3333}
3434
3535impl UnexpectedDownloadedFileVerifier {
3636 /// `UnexpectedDownloadedFileVerifier` factory
3737 pub fn new < P : AsRef < Path > > (
38- dir_to_check : P ,
38+ target_cardano_db_dir : P ,
3939 network_kind : & str ,
4040 include_ancillary : bool ,
4141 last_downloaded_immutable_file_number : ImmutableFileNumber ,
4242 ) -> Self {
4343 Self {
44- dir_to_check : dir_to_check . as_ref ( ) . to_path_buf ( ) ,
44+ target_cardano_db_dir : target_cardano_db_dir . as_ref ( ) . to_path_buf ( ) ,
4545 immutable_files_range_to_expect : compute_immutable_files_range_to_expect (
4646 network_kind,
4747 include_ancillary,
@@ -50,32 +50,42 @@ impl UnexpectedDownloadedFileVerifier {
5050 }
5151 }
5252
53+ fn target_immutable_files_dir ( & self ) -> PathBuf {
54+ self . target_cardano_db_dir . join ( IMMUTABLE_DIR )
55+ }
56+
5357 /// Compute the expected state of the folder after download finish
5458 pub async fn compute_expected_state_after_download (
5559 & self ,
5660 ) -> StdResult < ExpectedFilesAfterDownload > {
57- let dir_to_check = self . dir_to_check . to_path_buf ( ) ;
61+ let immutable_files_dir = self . target_immutable_files_dir ( ) ;
5862 let immutable_files_range_to_expect = self . immutable_files_range_to_expect . clone ( ) ;
5963 // target databases can be quite large, avoid blocking the main thread
6064 let expected_files = tokio:: task:: spawn_blocking ( move || -> StdResult < HashSet < PathBuf > > {
61- let mut files: HashSet < PathBuf > = std:: fs:: read_dir ( & dir_to_check)
62- . with_context ( || format ! ( "Failed to read directory {}" , dir_to_check. display( ) ) ) ?
63- . flat_map ( |e| e. map ( |e| e. path ( ) ) )
64- . collect ( ) ;
65+ let mut files: HashSet < PathBuf > = if immutable_files_dir. exists ( ) {
66+ std:: fs:: read_dir ( & immutable_files_dir)
67+ . with_context ( || {
68+ format ! ( "Failed to read directory {}" , immutable_files_dir. display( ) )
69+ } ) ?
70+ . flat_map ( |e| e. map ( |e| e. path ( ) ) )
71+ . collect ( )
72+ } else {
73+ HashSet :: new ( )
74+ } ;
6575
6676 // Complete the list with all rightfully downloaded immutable files
6777 for immutable_file_name in
6878 immutable_files_range_to_expect. flat_map ( immutable_trio_names)
6979 {
70- files. insert ( dir_to_check . join ( immutable_file_name) ) ;
80+ files. insert ( immutable_files_dir . join ( immutable_file_name) ) ;
7181 }
7282 Ok ( files)
7383 } )
7484 . await ?
7585 . with_context ( || BASE_ERROR ) ?;
7686
7787 Ok ( ExpectedFilesAfterDownload {
78- dir_to_check : self . dir_to_check . clone ( ) ,
88+ target_immutable_files_dir : self . target_immutable_files_dir ( ) ,
7989 expected_files,
8090 } )
8191 }
@@ -105,7 +115,7 @@ impl ExpectedFilesAfterDownload {
105115 /// *Note: removed directories names are suffixed with a "/"*
106116 pub async fn remove_unexpected_files ( self ) -> StdResult < Vec < String > > {
107117 tokio:: task:: spawn_blocking ( move || {
108- let unexpected_entries: Vec < _ > = std:: fs:: read_dir ( & self . dir_to_check )
118+ let unexpected_entries: Vec < _ > = std:: fs:: read_dir ( & self . target_immutable_files_dir )
109119 . with_context ( || BASE_ERROR ) ?
110120 . flatten ( )
111121 . filter ( |f| !self . expected_files . contains ( & f. path ( ) . to_path_buf ( ) ) )
@@ -159,6 +169,12 @@ mod tests {
159169
160170 use super :: * ;
161171
172+ fn create_immutable_files_dir ( parent_dir : & Path ) -> PathBuf {
173+ let immutable_files_dir = parent_dir. join ( IMMUTABLE_DIR ) ;
174+ create_dir ( & immutable_files_dir) . unwrap ( ) ;
175+ immutable_files_dir
176+ }
177+
162178 fn create_immutable_trio ( dir : & Path , immutable_file_number : ImmutableFileNumber ) {
163179 for immutable_file_name in immutable_trio_names ( immutable_file_number) {
164180 File :: create ( dir. join ( immutable_file_name) ) . unwrap ( ) ;
@@ -201,8 +217,10 @@ mod tests {
201217 use super :: * ;
202218
203219 #[ tokio:: test]
204- async fn when_dir_empty_return_empty_if_immutable_files_range_is_empty ( ) {
220+ async fn when_dir_empty_return_empty_if_immutable_files_dir_does_not_exist_and_range_is_empty (
221+ ) {
205222 let temp_dir = temp_dir_create ! ( ) ;
223+ create_immutable_files_dir ( & temp_dir) ;
206224 let existing_files =
207225 UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 0 )
208226 . compute_expected_state_after_download ( )
@@ -213,7 +231,20 @@ mod tests {
213231 }
214232
215233 #[ tokio:: test]
216- async fn when_dir_empty_return_immutables_trios_if_immutable_files_range_is_not_empty ( ) {
234+ async fn when_dir_empty_return_empty_if_immutable_files_dir_exist_and_range_is_empty ( ) {
235+ let temp_dir = temp_dir_create ! ( ) ;
236+ let existing_files =
237+ UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 0 )
238+ . compute_expected_state_after_download ( )
239+ . await
240+ . unwrap ( ) ;
241+
242+ assert_eq ! ( existing_files. expected_files, HashSet :: <PathBuf >:: new( ) ) ;
243+ }
244+
245+ #[ tokio:: test]
246+ async fn when_immutable_files_dir_does_not_exist_return_immutables_trios_if_immutable_files_range_is_not_empty (
247+ ) {
217248 let temp_dir = temp_dir_create ! ( ) ;
218249 let existing_files =
219250 UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 1 )
@@ -224,21 +255,43 @@ mod tests {
224255 assert_eq ! (
225256 existing_files. expected_files,
226257 HashSet :: from( [
227- temp_dir. join( "00001.chunk" ) ,
228- temp_dir. join( "00001.primary" ) ,
229- temp_dir. join( "00001.secondary" ) ,
258+ temp_dir. join( IMMUTABLE_DIR ) . join ( "00001.chunk" ) ,
259+ temp_dir. join( IMMUTABLE_DIR ) . join ( "00001.primary" ) ,
260+ temp_dir. join( IMMUTABLE_DIR ) . join ( "00001.secondary" ) ,
230261 ] )
231262 ) ;
232263 }
233264
234265 #[ tokio:: test]
235- async fn add_existing_files_and_dirs ( ) {
266+ async fn when_immutable_files_dir_empty_return_immutables_trios_if_immutable_files_range_is_not_empty (
267+ ) {
236268 let temp_dir = temp_dir_create ! ( ) ;
237- create_dir ( temp_dir. join ( "dir_1" ) ) . unwrap ( ) ;
238- create_dir ( temp_dir. join ( "dir_2" ) ) . unwrap ( ) ;
239- File :: create ( temp_dir. join ( "file_1.txt" ) ) . unwrap ( ) ;
240- File :: create ( temp_dir. join ( "file_2.txt" ) ) . unwrap ( ) ;
241- File :: create ( temp_dir. join ( "dir_2" ) . join ( "file_3.txt" ) ) . unwrap ( ) ;
269+ let immutable_files_dir = create_immutable_files_dir ( & temp_dir) ;
270+ let existing_files =
271+ UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 1 )
272+ . compute_expected_state_after_download ( )
273+ . await
274+ . unwrap ( ) ;
275+
276+ assert_eq ! (
277+ existing_files. expected_files,
278+ HashSet :: from( [
279+ immutable_files_dir. join( "00001.chunk" ) ,
280+ immutable_files_dir. join( "00001.primary" ) ,
281+ immutable_files_dir. join( "00001.secondary" ) ,
282+ ] )
283+ ) ;
284+ }
285+
286+ #[ tokio:: test]
287+ async fn add_existing_files_and_dirs_from_immutable_files_dir_to_expected_files ( ) {
288+ let temp_dir = temp_dir_create ! ( ) ;
289+ let immutable_files_dir = create_immutable_files_dir ( & temp_dir) ;
290+ create_dir ( immutable_files_dir. join ( "dir_1" ) ) . unwrap ( ) ;
291+ create_dir ( immutable_files_dir. join ( "dir_2" ) ) . unwrap ( ) ;
292+ File :: create ( immutable_files_dir. join ( "file_1.txt" ) ) . unwrap ( ) ;
293+ File :: create ( immutable_files_dir. join ( "file_2.txt" ) ) . unwrap ( ) ;
294+ File :: create ( immutable_files_dir. join ( "dir_2" ) . join ( "file_3.txt" ) ) . unwrap ( ) ;
242295
243296 let existing_files =
244297 UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 0 )
@@ -249,10 +302,10 @@ mod tests {
249302 assert_eq ! (
250303 existing_files. expected_files,
251304 HashSet :: from( [
252- temp_dir . join( "dir_1" ) ,
253- temp_dir . join( "dir_2" ) ,
254- temp_dir . join( "file_1.txt" ) ,
255- temp_dir . join( "file_2.txt" ) ,
305+ immutable_files_dir . join( "dir_1" ) ,
306+ immutable_files_dir . join( "dir_2" ) ,
307+ immutable_files_dir . join( "file_1.txt" ) ,
308+ immutable_files_dir . join( "file_2.txt" ) ,
256309 ] )
257310 ) ;
258311 }
@@ -267,7 +320,7 @@ mod tests {
267320 async fn when_dir_empty_do_nothing_and_return_none ( ) {
268321 let temp_dir = temp_dir_create ! ( ) ;
269322 let existing_before = ExpectedFilesAfterDownload {
270- dir_to_check : temp_dir. clone ( ) ,
323+ target_immutable_files_dir : temp_dir. clone ( ) ,
271324 expected_files : HashSet :: new ( ) ,
272325 } ;
273326
@@ -282,7 +335,7 @@ mod tests {
282335 create_dir ( temp_dir. join ( "dir_1" ) ) . unwrap ( ) ;
283336 File :: create ( temp_dir. join ( "file_1.txt" ) ) . unwrap ( ) ;
284337 let existing_before = ExpectedFilesAfterDownload {
285- dir_to_check : temp_dir. clone ( ) ,
338+ target_immutable_files_dir : temp_dir. clone ( ) ,
286339 expected_files : HashSet :: from ( [
287340 temp_dir. join ( "file_1.txt" ) ,
288341 temp_dir. join ( "dir_1" ) ,
@@ -299,7 +352,7 @@ mod tests {
299352 ) {
300353 let temp_dir = temp_dir_create ! ( ) ;
301354 let existing_before = ExpectedFilesAfterDownload {
302- dir_to_check : temp_dir. clone ( ) ,
355+ target_immutable_files_dir : temp_dir. clone ( ) ,
303356 expected_files : HashSet :: new ( ) ,
304357 } ;
305358
@@ -331,8 +384,9 @@ mod tests {
331384 let temp_dir = temp_dir_create ! ( ) ;
332385 let verifier = UnexpectedDownloadedFileVerifier :: new ( & temp_dir, "network" , false , 19999 ) ;
333386
387+ let immutable_files_dir = create_immutable_files_dir ( & temp_dir) ;
334388 for immutable_file_number in 0 ..=30000 {
335- create_immutable_trio ( & temp_dir , immutable_file_number) ;
389+ create_immutable_trio ( & immutable_files_dir , immutable_file_number) ;
336390 }
337391
338392 let now = Instant :: now ( ) ;
0 commit comments