1
1
use std:: {
2
2
cmp:: Ordering ,
3
+ ffi:: OsString ,
3
4
path:: { Path , PathBuf } ,
4
5
} ;
5
6
use thiserror:: Error ;
@@ -20,15 +21,16 @@ fn find_ledger_dir(path_to_walk: &Path) -> Option<PathBuf> {
20
21
21
22
/// Represent an ledger file in a Cardano node database directory
22
23
#[ 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
+ } ,
32
34
}
33
35
34
36
/// [LedgerStateSnapshot::list_all_in_dir] related errors.
@@ -40,28 +42,34 @@ pub enum LedgerStateSnapshotListingError {
40
42
}
41
43
42
44
impl 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 {
46
48
path,
47
49
slot_number,
48
- filename : filename . into ( ) ,
50
+ filename,
49
51
}
50
52
}
51
53
52
54
/// Convert a path to a [LedgerStateSnapshot] if it satisfies the constraints.
53
55
///
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).
56
59
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
+ } )
65
73
}
66
74
67
75
/// List all [`LedgerStateSnapshot`] in a given directory.
@@ -88,6 +96,22 @@ impl LedgerStateSnapshot {
88
96
89
97
Ok ( files)
90
98
}
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
+ }
91
115
}
92
116
93
117
impl PartialOrd for LedgerStateSnapshot {
@@ -98,24 +122,23 @@ impl PartialOrd for LedgerStateSnapshot {
98
122
99
123
impl Ord for LedgerStateSnapshot {
100
124
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 ( ) )
104
126
}
105
127
}
106
128
107
129
#[ cfg( test) ]
108
130
mod tests {
109
- use std:: fs:: File ;
131
+ use std:: fs:: { create_dir , File } ;
110
132
use std:: io:: prelude:: * ;
111
- use std:: path:: { Path , PathBuf } ;
112
133
113
- use crate :: test_utils:: TempDir ;
134
+ use crate :: test_utils:: temp_dir_create ;
114
135
115
- use super :: LedgerStateSnapshot ;
136
+ use super :: * ;
116
137
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
119
142
}
120
143
121
144
fn create_fake_files ( parent_dir : & Path , child_filenames : & [ & str ] ) {
@@ -129,52 +152,57 @@ mod tests {
129
152
fn extract_filenames ( ledger_files : & [ LedgerStateSnapshot ] ) -> Vec < String > {
130
153
ledger_files
131
154
. 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 ( ) )
133
157
. collect ( )
134
158
}
135
159
136
160
#[ test]
137
161
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 ! ( ) ;
141
163
142
- LedgerStateSnapshot :: list_all_in_dir ( target_dir. parent ( ) . unwrap ( ) )
164
+ LedgerStateSnapshot :: list_all_in_dir ( & target_dir)
143
165
. expect_err ( "LedgerStateSnapshot::list_all_in_dir should have Failed" ) ;
144
166
}
145
167
146
168
#[ test]
147
169
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)
150
173
. expect ( "LedgerStateSnapshot::list_all_in_dir should work in a empty folder" ) ;
151
174
152
- assert ! ( result . is_empty ( ) ) ;
175
+ assert_eq ! ( Vec :: < LedgerStateSnapshot > :: new ( ) , result ) ;
153
176
}
154
177
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
+ }
168
195
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
+ }
179
207
}
180
208
}
0 commit comments