11use std:: {
22 cmp:: Ordering ,
3+ ffi:: OsString ,
34 path:: { Path , PathBuf } ,
45} ;
56use thiserror:: Error ;
@@ -20,15 +21,16 @@ fn find_ledger_dir(path_to_walk: &Path) -> Option<PathBuf> {
2021
2122/// Represent an ledger file in a Cardano node database directory
2223#[ derive( Debug , PartialEq , Eq , Clone ) ]
23- pub struct LedgerStateSnapshot {
24- /// The path to the ledger file
25- pub path : PathBuf ,
26-
27- /// The ledger file slot number
28- pub slot_number : SlotNumber ,
29-
30- /// The filename
31- pub filename : String ,
24+ pub enum LedgerStateSnapshot {
25+ /// Snapshot of a legacy ledger state (before UTxO-HD)
26+ Legacy {
27+ /// The path to the ledger file
28+ path : PathBuf ,
29+ /// The ledger file slot number
30+ slot_number : SlotNumber ,
31+ /// The filename
32+ filename : OsString ,
33+ } ,
3234}
3335
3436/// [LedgerStateSnapshot::list_all_in_dir] related errors.
@@ -40,28 +42,34 @@ pub enum LedgerStateSnapshotListingError {
4042}
4143
4244impl LedgerStateSnapshot {
43- /// `LedgerStateSnapshot` factory
44- pub fn new < T : Into < String > > ( path : PathBuf , slot_number : SlotNumber , filename : T ) -> Self {
45- Self {
45+ /// `LedgerStateSnapshot::Legacy ` factory
46+ pub fn legacy ( path : PathBuf , slot_number : SlotNumber , filename : OsString ) -> Self {
47+ Self :: Legacy {
4648 path,
4749 slot_number,
48- filename : filename . into ( ) ,
50+ filename,
4951 }
5052 }
5153
5254 /// Convert a path to a [LedgerStateSnapshot] if it satisfies the constraints.
5355 ///
54- /// The constraints are: the path must be a file, the filename should only contain a number (no
55- /// extension).
56+ /// The constraints are:
57+ /// - legacy state snapshot: the path must be a file, the filename should only contain a number (no
58+ /// extension).
5659 pub fn from_path ( path : & Path ) -> Option < LedgerStateSnapshot > {
57- path. file_name ( )
58- . map ( |name| name. to_string_lossy ( ) )
59- . and_then ( |filename| {
60- filename
61- . parse :: < u64 > ( )
62- . map ( |number| Self :: new ( path. to_path_buf ( ) , SlotNumber ( number) , filename) )
63- . ok ( )
64- } )
60+ path. file_name ( ) . and_then ( |filename| {
61+ filename
62+ . to_string_lossy ( )
63+ . parse :: < u64 > ( )
64+ . map ( |number| {
65+ Self :: legacy (
66+ path. to_path_buf ( ) ,
67+ SlotNumber ( number) ,
68+ filename. to_os_string ( ) ,
69+ )
70+ } )
71+ . ok ( )
72+ } )
6573 }
6674
6775 /// List all [`LedgerStateSnapshot`] in a given directory.
@@ -88,6 +96,22 @@ impl LedgerStateSnapshot {
8896
8997 Ok ( files)
9098 }
99+
100+ /// Return paths to all files that constitute this snapshot
101+ ///
102+ /// Returned path are relative to the cardano node database ledger dir
103+ pub fn get_files_relative_path ( & self ) -> Vec < PathBuf > {
104+ match self {
105+ LedgerStateSnapshot :: Legacy { filename, .. } => vec ! [ PathBuf :: from( filename) ] ,
106+ }
107+ }
108+
109+ /// Return the slot number when this snapshot was taken
110+ pub fn slot_number ( & self ) -> SlotNumber {
111+ match self {
112+ LedgerStateSnapshot :: Legacy { slot_number, .. } => * slot_number,
113+ }
114+ }
91115}
92116
93117impl PartialOrd for LedgerStateSnapshot {
@@ -98,24 +122,23 @@ impl PartialOrd for LedgerStateSnapshot {
98122
99123impl Ord for LedgerStateSnapshot {
100124 fn cmp ( & self , other : & Self ) -> Ordering {
101- self . slot_number
102- . cmp ( & other. slot_number )
103- . then ( self . path . cmp ( & other. path ) )
125+ self . slot_number ( ) . cmp ( & other. slot_number ( ) )
104126 }
105127}
106128
107129#[ cfg( test) ]
108130mod tests {
109- use std:: fs:: File ;
131+ use std:: fs:: { create_dir , File } ;
110132 use std:: io:: prelude:: * ;
111- use std:: path:: { Path , PathBuf } ;
112133
113- use crate :: test_utils:: TempDir ;
134+ use crate :: test_utils:: temp_dir_create ;
114135
115- use super :: LedgerStateSnapshot ;
136+ use super :: * ;
116137
117- fn get_test_dir ( subdir_name : & str ) -> PathBuf {
118- TempDir :: create ( "ledger_file" , subdir_name)
138+ fn create_ledger_dir ( parent_dir : & Path ) -> PathBuf {
139+ let ledger_dir = parent_dir. join ( LEDGER_DIR ) ;
140+ create_dir ( & ledger_dir) . unwrap ( ) ;
141+ ledger_dir
119142 }
120143
121144 fn create_fake_files ( parent_dir : & Path , child_filenames : & [ & str ] ) {
@@ -129,52 +152,57 @@ mod tests {
129152 fn extract_filenames ( ledger_files : & [ LedgerStateSnapshot ] ) -> Vec < String > {
130153 ledger_files
131154 . iter ( )
132- . map ( |i| i. path . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) )
155+ . flat_map ( |i| i. get_files_relative_path ( ) )
156+ . map ( |p| p. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) )
133157 . collect ( )
134158 }
135159
136160 #[ test]
137161 fn list_all_ledger_file_fail_if_not_in_ledger_dir ( ) {
138- let target_dir = get_test_dir ( "list_all_ledger_file_fail_if_not_in_ledger_dir/invalid" ) ;
139- let entries = vec ! [ ] ;
140- create_fake_files ( & target_dir, & entries) ;
162+ let target_dir = temp_dir_create ! ( ) ;
141163
142- LedgerStateSnapshot :: list_all_in_dir ( target_dir. parent ( ) . unwrap ( ) )
164+ LedgerStateSnapshot :: list_all_in_dir ( & target_dir)
143165 . expect_err ( "LedgerStateSnapshot::list_all_in_dir should have Failed" ) ;
144166 }
145167
146168 #[ test]
147169 fn list_all_ledger_file_should_works_in_a_empty_folder ( ) {
148- let target_dir = get_test_dir ( "list_all_ledger_file_should_works_in_a_empty_folder/ledger" ) ;
149- let result = LedgerStateSnapshot :: list_all_in_dir ( target_dir. parent ( ) . unwrap ( ) )
170+ let target_dir = temp_dir_create ! ( ) ;
171+ create_ledger_dir ( & target_dir) ;
172+ let result = LedgerStateSnapshot :: list_all_in_dir ( & target_dir)
150173 . expect ( "LedgerStateSnapshot::list_all_in_dir should work in a empty folder" ) ;
151174
152- assert ! ( result . is_empty ( ) ) ;
175+ assert_eq ! ( Vec :: < LedgerStateSnapshot > :: new ( ) , result ) ;
153176 }
154177
155- #[ test]
156- fn list_all_ledger_file_order_should_be_deterministic ( ) {
157- let target_dir = get_test_dir ( "list_all_ledger_file_order_should_be_deterministic/ledger" ) ;
158- let entries = vec ! [ "424" , "123" , "124" , "00125" , "21" , "223" , "0423" ] ;
159- create_fake_files ( & target_dir, & entries) ;
160- let ledger_files = LedgerStateSnapshot :: list_all_in_dir ( target_dir. parent ( ) . unwrap ( ) )
161- . expect ( "LedgerStateSnapshot::list_all_in_dir Failed" ) ;
162-
163- assert_eq ! (
164- vec![ "21" , "123" , "124" , "00125" , "223" , "0423" , "424" ] ,
165- extract_filenames( & ledger_files)
166- ) ;
167- }
178+ mod legacy_ledger_state {
179+ use super :: * ;
180+
181+ #[ test]
182+ fn list_all_ledger_file_order_should_be_deterministic ( ) {
183+ let target_dir = temp_dir_create ! ( ) ;
184+ let ledger_dir = create_ledger_dir ( & target_dir) ;
185+ let entries = vec ! [ "424" , "123" , "124" , "00125" , "21" , "223" , "0423" ] ;
186+ create_fake_files ( & ledger_dir, & entries) ;
187+ let ledger_files = LedgerStateSnapshot :: list_all_in_dir ( & target_dir)
188+ . expect ( "LedgerStateSnapshot::list_all_in_dir Failed" ) ;
189+
190+ assert_eq ! (
191+ vec![ "21" , "123" , "124" , "00125" , "223" , "0423" , "424" ] ,
192+ extract_filenames( & ledger_files)
193+ ) ;
194+ }
168195
169- #[ test]
170- fn list_all_ledger_file_should_work_with_non_ledger_files ( ) {
171- let target_dir =
172- get_test_dir ( "list_all_ledger_file_should_work_with_non_ledger_files/ledger" ) ;
173- let entries = vec ! [ "123" , "124" , "README.md" , "124.back" ] ;
174- create_fake_files ( & target_dir, & entries) ;
175- let ledger_files = LedgerStateSnapshot :: list_all_in_dir ( target_dir. parent ( ) . unwrap ( ) )
176- . expect ( "LedgerStateSnapshot::list_all_in_dir Failed" ) ;
177-
178- assert_eq ! ( vec![ "123" , "124" ] , extract_filenames( & ledger_files) ) ;
196+ #[ test]
197+ fn list_all_ledger_file_should_work_with_non_ledger_files ( ) {
198+ let target_dir = temp_dir_create ! ( ) ;
199+ let ledger_dir = create_ledger_dir ( & target_dir) ;
200+ let entries = vec ! [ "123" , "124" , "README.md" , "124.back" ] ;
201+ create_fake_files ( & ledger_dir, & entries) ;
202+ let ledger_files = LedgerStateSnapshot :: list_all_in_dir ( & target_dir)
203+ . expect ( "LedgerStateSnapshot::list_all_in_dir Failed" ) ;
204+
205+ assert_eq ! ( vec![ "123" , "124" ] , extract_filenames( & ledger_files) ) ;
206+ }
179207 }
180208}
0 commit comments