Skip to content

Commit beb88e6

Browse files
authored
Merge pull request #806 from valentinewallace/monitor-data-persistence-path
persist: Persist ChannelMonitors in their own directory.
2 parents e77b160 + bfaec71 commit beb88e6

File tree

2 files changed

+45
-37
lines changed

2 files changed

+45
-37
lines changed

lightning-persister/src/lib.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use lightning::util::logger::Logger;
1717
use lightning::util::ser::Writeable;
1818
use std::fs;
1919
use std::io::Error;
20+
use std::path::PathBuf;
2021
use std::sync::Arc;
2122

2223
#[cfg(test)]
@@ -75,6 +76,12 @@ impl FilesystemPersister {
7576
self.path_to_channel_data.clone()
7677
}
7778

79+
pub(crate) fn path_to_monitor_data(&self) -> PathBuf {
80+
let mut path = PathBuf::from(self.path_to_channel_data.clone());
81+
path.push("monitors");
82+
path
83+
}
84+
7885
/// Writes the provided `ChannelManager` to the path provided at `FilesystemPersister`
7986
/// initialization, within a file called "manager".
8087
pub fn persist_manager<Signer, M, T, K, F, L>(
@@ -88,54 +95,55 @@ impl FilesystemPersister {
8895
F: FeeEstimator,
8996
L: Logger
9097
{
91-
util::write_to_file(data_dir, "manager".to_string(), manager)
98+
let path = PathBuf::from(data_dir);
99+
util::write_to_file(path, "manager".to_string(), manager)
92100
}
93101

94102
#[cfg(test)]
95103
fn load_channel_data<Keys: KeysInterface>(&self, keys: &Keys) ->
96104
Result<HashMap<OutPoint, ChannelMonitor<Keys::Signer>>, ChannelMonitorUpdateErr> {
97-
if let Err(_) = fs::create_dir_all(&self.path_to_channel_data) {
98-
return Err(ChannelMonitorUpdateErr::PermanentFailure);
99-
}
100-
let mut res = HashMap::new();
101-
for file_option in fs::read_dir(&self.path_to_channel_data).unwrap() {
102-
let file = file_option.unwrap();
103-
let owned_file_name = file.file_name();
104-
let filename = owned_file_name.to_str();
105-
if !filename.is_some() || !filename.unwrap().is_ascii() || filename.unwrap().len() < 65 {
105+
if let Err(_) = fs::create_dir_all(self.path_to_monitor_data()) {
106106
return Err(ChannelMonitorUpdateErr::PermanentFailure);
107107
}
108+
let mut res = HashMap::new();
109+
for file_option in fs::read_dir(self.path_to_monitor_data()).unwrap() {
110+
let file = file_option.unwrap();
111+
let owned_file_name = file.file_name();
112+
let filename = owned_file_name.to_str();
113+
if !filename.is_some() || !filename.unwrap().is_ascii() || filename.unwrap().len() < 65 {
114+
return Err(ChannelMonitorUpdateErr::PermanentFailure);
115+
}
108116

109-
let txid = Txid::from_hex(filename.unwrap().split_at(64).0);
110-
if txid.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
117+
let txid = Txid::from_hex(filename.unwrap().split_at(64).0);
118+
if txid.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
111119

112-
let index = filename.unwrap().split_at(65).1.split('.').next().unwrap().parse();
113-
if index.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
120+
let index = filename.unwrap().split_at(65).1.split('.').next().unwrap().parse();
121+
if index.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
114122

115-
let contents = fs::read(&file.path());
116-
if contents.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
123+
let contents = fs::read(&file.path());
124+
if contents.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
117125

118-
if let Ok((_, loaded_monitor)) =
119-
<(BlockHash, ChannelMonitor<Keys::Signer>)>::read(&mut Cursor::new(&contents.unwrap()), keys) {
120-
res.insert(OutPoint { txid: txid.unwrap(), index: index.unwrap() }, loaded_monitor);
121-
} else {
122-
return Err(ChannelMonitorUpdateErr::PermanentFailure);
126+
if let Ok((_, loaded_monitor)) =
127+
<(BlockHash, ChannelMonitor<Keys::Signer>)>::read(&mut Cursor::new(&contents.unwrap()), keys) {
128+
res.insert(OutPoint { txid: txid.unwrap(), index: index.unwrap() }, loaded_monitor);
129+
} else {
130+
return Err(ChannelMonitorUpdateErr::PermanentFailure);
131+
}
123132
}
133+
Ok(res)
124134
}
125-
Ok(res)
126-
}
127135
}
128136

129137
impl<ChannelSigner: Sign + Send + Sync> channelmonitor::Persist<ChannelSigner> for FilesystemPersister {
130138
fn persist_new_channel(&self, funding_txo: OutPoint, monitor: &ChannelMonitor<ChannelSigner>) -> Result<(), ChannelMonitorUpdateErr> {
131139
let filename = format!("{}_{}", funding_txo.txid.to_hex(), funding_txo.index);
132-
util::write_to_file(self.path_to_channel_data.clone(), filename, monitor)
140+
util::write_to_file(self.path_to_monitor_data(), filename, monitor)
133141
.map_err(|_| ChannelMonitorUpdateErr::PermanentFailure)
134142
}
135143

136144
fn update_persisted_channel(&self, funding_txo: OutPoint, _update: &ChannelMonitorUpdate, monitor: &ChannelMonitor<ChannelSigner>) -> Result<(), ChannelMonitorUpdateErr> {
137145
let filename = format!("{}_{}", funding_txo.txid.to_hex(), funding_txo.index);
138-
util::write_to_file(self.path_to_channel_data.clone(), filename, monitor)
146+
util::write_to_file(self.path_to_monitor_data(), filename, monitor)
139147
.map_err(|_| ChannelMonitorUpdateErr::PermanentFailure)
140148
}
141149
}

lightning-persister/src/util.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ pub(crate) trait DiskWriteable {
1717
fn write_to_file(&self, writer: &mut fs::File) -> Result<(), std::io::Error>;
1818
}
1919

20-
pub(crate) fn get_full_filepath(filepath: String, filename: String) -> String {
21-
let mut path = PathBuf::from(filepath);
22-
path.push(filename);
23-
path.to_str().unwrap().to_string()
20+
pub(crate) fn get_full_filepath(mut filepath: PathBuf, filename: String) -> String {
21+
filepath.push(filename);
22+
filepath.to_str().unwrap().to_string()
2423
}
2524

2625
#[cfg(target_os = "windows")]
@@ -40,7 +39,7 @@ fn path_to_windows_str<T: AsRef<OsStr>>(path: T) -> Vec<winapi::shared::ntdef::W
4039
}
4140

4241
#[allow(bare_trait_objects)]
43-
pub(crate) fn write_to_file<D: DiskWriteable>(path: String, filename: String, data: &D) -> std::io::Result<()> {
42+
pub(crate) fn write_to_file<D: DiskWriteable>(path: PathBuf, filename: String, data: &D) -> std::io::Result<()> {
4443
fs::create_dir_all(path.clone())?;
4544
// Do a crazy dance with lots of fsync()s to be overly cautious here...
4645
// We never want to end up in a state where we've lost the old data, or end up using the
@@ -92,6 +91,7 @@ mod tests {
9291
use std::fs;
9392
use std::io;
9493
use std::io::Write;
94+
use std::path::PathBuf;
9595

9696
struct TestWriteable{}
9797
impl DiskWriteable for TestWriteable {
@@ -113,7 +113,7 @@ mod tests {
113113
let mut perms = fs::metadata(path.to_string()).unwrap().permissions();
114114
perms.set_readonly(true);
115115
fs::set_permissions(path.to_string(), perms).unwrap();
116-
match write_to_file(path.to_string(), filename, &test_writeable) {
116+
match write_to_file(PathBuf::from(path.to_string()), filename, &test_writeable) {
117117
Err(e) => assert_eq!(e.kind(), io::ErrorKind::PermissionDenied),
118118
_ => panic!("Unexpected error message")
119119
}
@@ -131,10 +131,10 @@ mod tests {
131131
fn test_rename_failure() {
132132
let test_writeable = TestWriteable{};
133133
let filename = "test_rename_failure_filename";
134-
let path = "test_rename_failure_dir";
134+
let path = PathBuf::from("test_rename_failure_dir");
135135
// Create the channel data file and make it a directory.
136-
fs::create_dir_all(get_full_filepath(path.to_string(), filename.to_string())).unwrap();
137-
match write_to_file(path.to_string(), filename.to_string(), &test_writeable) {
136+
fs::create_dir_all(get_full_filepath(path.clone(), filename.to_string())).unwrap();
137+
match write_to_file(path.clone(), filename.to_string(), &test_writeable) {
138138
Err(e) => assert_eq!(e.kind(), io::ErrorKind::Other),
139139
_ => panic!("Unexpected Ok(())")
140140
}
@@ -151,9 +151,9 @@ mod tests {
151151
}
152152

153153
let filename = "test_diskwriteable_failure";
154-
let path = "test_diskwriteable_failure_dir";
154+
let path = PathBuf::from("test_diskwriteable_failure_dir");
155155
let test_writeable = FailingWriteable{};
156-
match write_to_file(path.to_string(), filename.to_string(), &test_writeable) {
156+
match write_to_file(path.clone(), filename.to_string(), &test_writeable) {
157157
Err(e) => {
158158
assert_eq!(e.kind(), std::io::ErrorKind::Other);
159159
assert_eq!(e.get_ref().unwrap().to_string(), "expected failure");
@@ -170,7 +170,7 @@ mod tests {
170170
fn test_tmp_file_creation_failure() {
171171
let test_writeable = TestWriteable{};
172172
let filename = "test_tmp_file_creation_failure_filename".to_string();
173-
let path = "test_tmp_file_creation_failure_dir".to_string();
173+
let path = PathBuf::from("test_tmp_file_creation_failure_dir");
174174

175175
// Create the tmp file and make it a directory.
176176
let tmp_path = get_full_filepath(path.clone(), format!("{}.tmp", filename.clone()));

0 commit comments

Comments
 (0)