Skip to content

Commit 5b0e487

Browse files
committed
refactor(common): transform LedgerStateSnapshot to an enum
To easilly add the Utxo-hd memory variant afterward
1 parent afdce2d commit 5b0e487

File tree

2 files changed

+93
-64
lines changed

2 files changed

+93
-64
lines changed

mithril-aggregator/src/services/snapshotter/compressed_archive_snapshotter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ impl CompressedArchiveSnapshotter {
263263
.iter()
264264
.rev()
265265
.take(2)
266-
.map(|ledger_file| PathBuf::from(LEDGER_DIR).join(&ledger_file.filename))
266+
.flat_map(|ledger_state_snapshot| ledger_state_snapshot.get_files_relative_path())
267+
.map(|path| PathBuf::from(LEDGER_DIR).join(path))
267268
.collect();
268269
if latest_ledger_files.is_empty() {
269270
return Err(anyhow!(
Lines changed: 91 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
22
cmp::Ordering,
3+
ffi::OsString,
34
path::{Path, PathBuf},
45
};
56
use 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

4244
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 {
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

93117
impl PartialOrd for LedgerStateSnapshot {
@@ -98,24 +122,23 @@ impl PartialOrd for LedgerStateSnapshot {
98122

99123
impl 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)]
108130
mod 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

Comments
 (0)