Skip to content

Commit 11fedb6

Browse files
implement Persist and Persister with generic KVStorePersister trait
1 parent 711bcef commit 11fedb6

File tree

5 files changed

+151
-152
lines changed

5 files changed

+151
-152
lines changed

lightning-background-processor/src/lib.rs

+26-39
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescr
2020
use lightning::routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
2121
use lightning::util::events::{Event, EventHandler, EventsProvider};
2222
use lightning::util::logger::Logger;
23+
use lightning::util::persist::Persister;
2324
use std::sync::Arc;
2425
use std::sync::atomic::{AtomicBool, Ordering};
2526
use std::thread;
@@ -80,22 +81,7 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 60;
8081
#[cfg(test)]
8182
const FIRST_NETWORK_PRUNE_TIMER: u64 = 1;
8283

83-
/// Trait that handles persisting a [`ChannelManager`] and [`NetworkGraph`] to disk.
84-
pub trait Persister<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
85-
where
86-
M::Target: 'static + chain::Watch<Signer>,
87-
T::Target: 'static + BroadcasterInterface,
88-
K::Target: 'static + KeysInterface<Signer = Signer>,
89-
F::Target: 'static + FeeEstimator,
90-
L::Target: 'static + Logger,
91-
{
92-
/// Persist the given [`ChannelManager`] to disk, returning an error if persistence failed
93-
/// (which will cause the [`BackgroundProcessor`] which called this method to exit).
94-
fn persist_manager(&self, channel_manager: &ChannelManager<Signer, M, T, K, F, L>) -> Result<(), std::io::Error>;
95-
96-
/// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
97-
fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), std::io::Error>;
98-
}
84+
9985

10086
/// Decorates an [`EventHandler`] with common functionality provided by standard [`EventHandler`]s.
10187
struct DecoratingEventHandler<
@@ -133,6 +119,7 @@ impl BackgroundProcessor {
133119
/// The thread runs indefinitely unless the object is dropped, [`stop`] is called, or
134120
/// [`Persister::persist_manager`] returns an error. In case of an error, the error is retrieved by calling
135121
/// either [`join`] or [`stop`].
122+
///
136123
///
137124
/// # Data Persistence
138125
///
@@ -142,7 +129,7 @@ impl BackgroundProcessor {
142129
/// provided implementation.
143130
///
144131
/// [`Persister::persist_graph`] is responsible for writing out the [`NetworkGraph`] to disk. See
145-
/// [`NetworkGraph::write`] for writing out a [`NetworkGraph`]. See [`FilesystemPersister::persist_network_graph`]
132+
/// [`NetworkGraph::write`] for writing out a [`NetworkGraph`]. See [`FilesystemPersister::persist_graph`]
146133
/// for Rust-Lightning's provided implementation.
147134
///
148135
/// Typically, users should either implement [`Persister::persist_manager`] to never return an
@@ -161,8 +148,8 @@ impl BackgroundProcessor {
161148
/// [`stop`]: Self::stop
162149
/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
163150
/// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable
164-
/// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager
165-
/// [`FilesystemPersister::persist_network_graph`]: lightning_persister::FilesystemPersister::persist_network_graph
151+
/// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister#impl-Persister
152+
/// [`FilesystemPersister::persist_graph`]: lightning_persister::FilesystemPersister#impl-Persister
166153
/// [`NetworkGraph`]: lightning::routing::network_graph::NetworkGraph
167154
/// [`NetworkGraph::write`]: lightning::routing::network_graph::NetworkGraph#impl-Writeable
168155
pub fn start<
@@ -180,7 +167,7 @@ impl BackgroundProcessor {
180167
CMH: 'static + Deref + Send + Sync,
181168
RMH: 'static + Deref + Send + Sync,
182169
EH: 'static + EventHandler + Send,
183-
PS: 'static + Send + Persister<Signer, CW, T, K, F, L>,
170+
PS: 'static + Deref + Send,
184171
M: 'static + Deref<Target = ChainMonitor<Signer, CF, T, F, L, P>> + Send + Sync,
185172
CM: 'static + Deref<Target = ChannelManager<Signer, CW, T, K, F, L>> + Send + Sync,
186173
NG: 'static + Deref<Target = NetGraphMsgHandler<G, CA, L>> + Send + Sync,
@@ -202,6 +189,7 @@ impl BackgroundProcessor {
202189
CMH::Target: 'static + ChannelMessageHandler,
203190
RMH::Target: 'static + RoutingMessageHandler,
204191
UMH::Target: 'static + CustomMessageHandler,
192+
PS::Target: 'static + Persister<Signer, CW, T, K, F, L>
205193
{
206194
let stop_thread = Arc::new(AtomicBool::new(false));
207195
let stop_thread_clone = stop_thread.clone();
@@ -365,10 +353,11 @@ mod tests {
365353
use lightning::util::logger::Logger;
366354
use lightning::util::ser::Writeable;
367355
use lightning::util::test_utils;
356+
use lightning::util::persist::KVStorePersister;
368357
use lightning_invoice::payment::{InvoicePayer, RetryAttempts};
369358
use lightning_invoice::utils::DefaultRouter;
370-
use lightning_persister::FilesystemPersister;
371-
use std::fs;
359+
use lightning_persister::{FilesystemPersister};
360+
use std::fs::{self, File};
372361
use std::ops::Deref;
373362
use std::path::PathBuf;
374363
use std::sync::{Arc, Mutex};
@@ -414,7 +403,7 @@ mod tests {
414403
struct Persister {
415404
data_dir: String,
416405
graph_error: Option<(std::io::ErrorKind, &'static str)>,
417-
manager_error: Option<(std::io::ErrorKind, &'static str)>
406+
manager_error: Option<(std::io::ErrorKind, &'static str)>,
418407
}
419408

420409
impl Persister {
@@ -431,25 +420,23 @@ mod tests {
431420
}
432421
}
433422

434-
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L:Deref> super::Persister<Signer, M, T, K, F, L> for Persister where
435-
M::Target: 'static + chain::Watch<Signer>,
436-
T::Target: 'static + BroadcasterInterface,
437-
K::Target: 'static + KeysInterface<Signer = Signer>,
438-
F::Target: 'static + FeeEstimator,
439-
L::Target: 'static + Logger,
440-
{
441-
fn persist_manager(&self, channel_manager: &ChannelManager<Signer, M, T, K, F, L>) -> Result<(), std::io::Error> {
442-
match self.manager_error {
443-
None => FilesystemPersister::persist_manager(self.data_dir.clone(), channel_manager),
444-
Some((error, message)) => Err(std::io::Error::new(error, message)),
423+
impl KVStorePersister for Persister {
424+
fn persist<W: Writeable>(&self, key: String, object: &W) -> std::io::Result<()> {
425+
if key == self.get_channel_manager_key() {
426+
return match self.manager_error {
427+
None => Ok(()),
428+
Some((error, message)) => Err(std::io::Error::new(error, message))
429+
}
445430
}
446-
}
447431

448-
fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), std::io::Error> {
449-
match self.graph_error {
450-
None => FilesystemPersister::persist_network_graph(self.data_dir.clone(), network_graph),
451-
Some((error, message)) => Err(std::io::Error::new(error, message)),
432+
if key == self.get_network_graph_key() {
433+
return match self.graph_error {
434+
None => Ok(()),
435+
Some((error, message)) => Err(std::io::Error::new(error, message))
436+
}
452437
}
438+
439+
Ok(())
453440
}
454441
}
455442

lightning-persister/src/lib.rs

+11-82
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,15 @@ extern crate bitcoin;
1515
extern crate libc;
1616

1717
use bitcoin::hash_types::{BlockHash, Txid};
18-
use bitcoin::hashes::hex::{FromHex, ToHex};
19-
use lightning::routing::network_graph::NetworkGraph;
20-
use crate::util::DiskWriteable;
21-
use lightning::chain;
22-
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
23-
use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate};
24-
use lightning::chain::chainmonitor;
18+
use bitcoin::hashes::hex::FromHex;
19+
use lightning::chain::channelmonitor::ChannelMonitor;
2520
use lightning::chain::keysinterface::{Sign, KeysInterface};
26-
use lightning::chain::transaction::OutPoint;
27-
use lightning::ln::channelmanager::ChannelManager;
28-
use lightning::util::logger::Logger;
2921
use lightning::util::ser::{ReadableArgs, Writeable};
22+
use lightning::util::persist::KVStorePersister;
3023
use std::fs;
31-
use std::io::{Cursor, Error};
24+
use std::io::Cursor;
3225
use std::ops::Deref;
33-
use std::path::{Path, PathBuf};
26+
use std::path::{Path, PathBuf, MAIN_SEPARATOR};
3427

3528
/// FilesystemPersister persists channel data on disk, where each channel's
3629
/// data is stored in a file named after its funding outpoint.
@@ -48,31 +41,6 @@ pub struct FilesystemPersister {
4841
path_to_channel_data: String,
4942
}
5043

51-
impl<Signer: Sign> DiskWriteable for ChannelMonitor<Signer> {
52-
fn write_to_file(&self, writer: &mut fs::File) -> Result<(), Error> {
53-
self.write(writer)
54-
}
55-
}
56-
57-
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> DiskWriteable for ChannelManager<Signer, M, T, K, F, L>
58-
where
59-
M::Target: chain::Watch<Signer>,
60-
T::Target: BroadcasterInterface,
61-
K::Target: KeysInterface<Signer=Signer>,
62-
F::Target: FeeEstimator,
63-
L::Target: Logger,
64-
{
65-
fn write_to_file(&self, writer: &mut fs::File) -> Result<(), std::io::Error> {
66-
self.write(writer)
67-
}
68-
}
69-
70-
impl DiskWriteable for NetworkGraph {
71-
fn write_to_file(&self, writer: &mut fs::File) -> Result<(), std::io::Error> {
72-
self.write(writer)
73-
}
74-
}
75-
7644
impl FilesystemPersister {
7745
/// Initialize a new FilesystemPersister and set the path to the individual channels'
7846
/// files.
@@ -87,34 +55,8 @@ impl FilesystemPersister {
8755
self.path_to_channel_data.clone()
8856
}
8957

90-
pub(crate) fn path_to_monitor_data(&self) -> PathBuf {
91-
let mut path = PathBuf::from(self.path_to_channel_data.clone());
92-
path.push("monitors");
93-
path
94-
}
95-
96-
/// Writes the provided `ChannelManager` to the path provided at `FilesystemPersister`
97-
/// initialization, within a file called "manager".
98-
pub fn persist_manager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
99-
data_dir: String,
100-
manager: &ChannelManager<Signer, M, T, K, F, L>
101-
) -> Result<(), std::io::Error>
102-
where
103-
M::Target: chain::Watch<Signer>,
104-
T::Target: BroadcasterInterface,
105-
K::Target: KeysInterface<Signer=Signer>,
106-
F::Target: FeeEstimator,
107-
L::Target: Logger,
108-
{
109-
let path = PathBuf::from(data_dir);
110-
util::write_to_file(path, "manager".to_string(), manager)
111-
}
112-
113-
/// Write the provided `NetworkGraph` to the path provided at `FilesystemPersister`
114-
/// initialization, within a file called "network_graph"
115-
pub fn persist_network_graph(data_dir: String, network_graph: &NetworkGraph) -> Result<(), std::io::Error> {
116-
let path = PathBuf::from(data_dir);
117-
util::write_to_file(path, "network_graph".to_string(), network_graph)
58+
pub(crate) fn path_to_monitor_data(&self) -> String {
59+
format!("{}{}monitors", self.path_to_channel_data, MAIN_SEPARATOR)
11860
}
11961

12062
/// Read `ChannelMonitor`s from disk.
@@ -124,7 +66,7 @@ impl FilesystemPersister {
12466
where K::Target: KeysInterface<Signer=Signer> + Sized,
12567
{
12668
let path = self.path_to_monitor_data();
127-
if !Path::new(&path).exists() {
69+
if !Path::new(&PathBuf::from(&path)).exists() {
12870
return Ok(Vec::new());
12971
}
13072
let mut res = Vec::new();
@@ -180,22 +122,9 @@ impl FilesystemPersister {
180122
}
181123
}
182124

183-
impl<ChannelSigner: Sign> chainmonitor::Persist<ChannelSigner> for FilesystemPersister {
184-
// TODO: We really need a way for the persister to inform the user that its time to crash/shut
185-
// down once these start returning failure.
186-
// A PermanentFailure implies we need to shut down since we're force-closing channels without
187-
// even broadcasting!
188-
189-
fn persist_new_channel(&self, funding_txo: OutPoint, monitor: &ChannelMonitor<ChannelSigner>, _update_id: chainmonitor::MonitorUpdateId) -> Result<(), chain::ChannelMonitorUpdateErr> {
190-
let filename = format!("{}_{}", funding_txo.txid.to_hex(), funding_txo.index);
191-
util::write_to_file(self.path_to_monitor_data(), filename, monitor)
192-
.map_err(|_| chain::ChannelMonitorUpdateErr::PermanentFailure)
193-
}
194-
195-
fn update_persisted_channel(&self, funding_txo: OutPoint, _update: &Option<ChannelMonitorUpdate>, monitor: &ChannelMonitor<ChannelSigner>, _update_id: chainmonitor::MonitorUpdateId) -> Result<(), chain::ChannelMonitorUpdateErr> {
196-
let filename = format!("{}_{}", funding_txo.txid.to_hex(), funding_txo.index);
197-
util::write_to_file(self.path_to_monitor_data(), filename, monitor)
198-
.map_err(|_| chain::ChannelMonitorUpdateErr::PermanentFailure)
125+
impl KVStorePersister for FilesystemPersister {
126+
fn persist<W: Writeable>(&self, key: String, object: &W) -> std::io::Result<()> {
127+
util::write_to_file(format!("{}{}{}", self.path_to_channel_data, MAIN_SEPARATOR, key), object)
199128
}
200129
}
201130

0 commit comments

Comments
 (0)