@@ -17,7 +17,6 @@ extern crate libc;
17
17
use bitcoin:: hash_types:: { BlockHash , Txid } ;
18
18
use bitcoin:: hashes:: hex:: { FromHex , ToHex } ;
19
19
use lightning:: routing:: network_graph:: NetworkGraph ;
20
- use crate :: util:: DiskWriteable ;
21
20
use lightning:: chain;
22
21
use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
23
22
use lightning:: chain:: channelmonitor:: { ChannelMonitor , ChannelMonitorUpdate } ;
@@ -28,9 +27,38 @@ use lightning::ln::channelmanager::ChannelManager;
28
27
use lightning:: util:: logger:: Logger ;
29
28
use lightning:: util:: ser:: { ReadableArgs , Writeable } ;
30
29
use std:: fs;
31
- use std:: io:: { Cursor , Error } ;
30
+ use std:: io:: { Cursor , Error , Write } ;
32
31
use std:: ops:: Deref ;
33
- use std:: path:: { Path , PathBuf } ;
32
+ use std:: path:: { Path , PathBuf , MAIN_SEPARATOR } ;
33
+
34
+
35
+ /// Trait that handles persisting a [`ChannelManager`] and [`NetworkGraph`] to disk.
36
+ pub trait Persister
37
+ {
38
+ /// Persist the given [`ChannelManager`] to disk, returning an error if persistence failed
39
+ /// (which will cause the BackgroundProcessor which called this method to exit).
40
+ fn persist_manager < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > ( & self , channel_manager : & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > where
41
+ M :: Target : ' static + chain:: Watch < Signer > ,
42
+ T :: Target : ' static + BroadcasterInterface ,
43
+ K :: Target : ' static + KeysInterface < Signer = Signer > ,
44
+ F :: Target : ' static + FeeEstimator ,
45
+ L :: Target : ' static + Logger ;
46
+
47
+ /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
48
+ fn persist_graph ( & self , network_graph : & NetworkGraph ) -> Result < ( ) , std:: io:: Error > ;
49
+ }
50
+
51
+ /// Trait for a key-value store for persisting some writeable object at some key
52
+ pub trait KVStorePersister < W : Writeable > {
53
+ /// Persist the given writeable using the provided key
54
+ fn persist ( & self , key : String , object : & W ) -> std:: io:: Result < ( ) > ;
55
+ }
56
+
57
+ impl < W : Writeable > KVStorePersister < W > for FilesystemPersister {
58
+ fn persist ( & self , key : String , object : & W ) -> std:: io:: Result < ( ) > {
59
+ util:: write_to_file ( format ! ( "{}{}{}" , self . path_to_channel_data, MAIN_SEPARATOR , key) , object)
60
+ }
61
+ }
34
62
35
63
/// FilesystemPersister persists channel data on disk, where each channel's
36
64
/// data is stored in a file named after its funding outpoint.
@@ -48,31 +76,6 @@ pub struct FilesystemPersister {
48
76
path_to_channel_data : String ,
49
77
}
50
78
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
-
76
79
impl FilesystemPersister {
77
80
/// Initialize a new FilesystemPersister and set the path to the individual channels'
78
81
/// files.
@@ -87,34 +90,8 @@ impl FilesystemPersister {
87
90
self . path_to_channel_data . clone ( )
88
91
}
89
92
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)
93
+ pub ( crate ) fn path_to_monitor_data ( & self ) -> String {
94
+ format ! ( "{}{}monitors" , self . path_to_channel_data, MAIN_SEPARATOR )
118
95
}
119
96
120
97
/// Read `ChannelMonitor`s from disk.
@@ -124,7 +101,7 @@ impl FilesystemPersister {
124
101
where K :: Target : KeysInterface < Signer =Signer > + Sized ,
125
102
{
126
103
let path = self . path_to_monitor_data ( ) ;
127
- if !Path :: new ( & path) . exists ( ) {
104
+ if !Path :: new ( & PathBuf :: from ( & path) ) . exists ( ) {
128
105
return Ok ( Vec :: new ( ) ) ;
129
106
}
130
107
let mut res = Vec :: new ( ) ;
@@ -187,18 +164,39 @@ impl<ChannelSigner: Sign> chainmonitor::Persist<ChannelSigner> for FilesystemPer
187
164
// even broadcasting!
188
165
189
166
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)
167
+ let key = format ! ( "monitors{}{} _{}" , MAIN_SEPARATOR , funding_txo. txid. to_hex( ) , funding_txo. index) ;
168
+ self . persist ( key , monitor)
192
169
. map_err ( |_| chain:: ChannelMonitorUpdateErr :: PermanentFailure )
193
170
}
194
171
195
172
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)
173
+ let key = format ! ( "monitors{}{} _{}" , MAIN_SEPARATOR , funding_txo. txid. to_hex( ) , funding_txo. index) ;
174
+ self . persist ( key , monitor)
198
175
. map_err ( |_| chain:: ChannelMonitorUpdateErr :: PermanentFailure )
199
176
}
200
177
}
201
178
179
+ impl Persister for FilesystemPersister {
180
+ fn persist_manager < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > ( & self , channel_manager : & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > where
181
+ M :: Target : ' static + chain:: Watch < Signer > ,
182
+ T :: Target : ' static + BroadcasterInterface ,
183
+ K :: Target : ' static + KeysInterface < Signer =Signer > ,
184
+ F :: Target : ' static + FeeEstimator ,
185
+ L :: Target : ' static + Logger {
186
+ self . persist ( "manager" . to_string ( ) , channel_manager)
187
+ }
188
+
189
+ fn persist_graph ( & self , network_graph : & NetworkGraph ) -> Result < ( ) , std:: io:: Error > {
190
+ if self . persist ( "network_graph" . to_string ( ) , network_graph) . is_err ( )
191
+ {
192
+ // Persistence errors here are non-fatal as we can just fetch the routing graph
193
+ // again later, but they may indicate a disk error which could be fatal elsewhere.
194
+ eprintln ! ( "Warning: Failed to persist network graph, check your disk and permissions" ) ;
195
+ }
196
+ Ok ( ( ) )
197
+ }
198
+ }
199
+
202
200
#[ cfg( test) ]
203
201
mod tests {
204
202
extern crate lightning;
0 commit comments