@@ -12,7 +12,8 @@ extern crate lightning;
12
12
extern crate bitcoin;
13
13
extern crate libc;
14
14
15
- use bitcoin:: hashes:: hex:: ToHex ;
15
+ use bitcoin:: { BlockHash , Txid } ;
16
+ use bitcoin:: hashes:: hex:: { FromHex , ToHex } ;
16
17
use crate :: util:: DiskWriteable ;
17
18
use lightning:: chain;
18
19
use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
@@ -22,21 +23,14 @@ use lightning::chain::keysinterface::{Sign, KeysInterface};
22
23
use lightning:: chain:: transaction:: OutPoint ;
23
24
use lightning:: ln:: channelmanager:: ChannelManager ;
24
25
use lightning:: util:: logger:: Logger ;
25
- use lightning:: util:: ser:: Writeable ;
26
+ use lightning:: util:: ser:: { ReadableArgs , Writeable } ;
27
+ use std:: collections:: HashMap ;
26
28
use std:: fs;
27
- use std:: io:: Error ;
28
- use std:: path:: PathBuf ;
29
+ use std:: io:: { Cursor , Error } ;
30
+ use std:: ops:: Deref ;
31
+ use std:: path:: { Path , PathBuf } ;
29
32
use std:: sync:: Arc ;
30
33
31
- #[ cfg( test) ]
32
- use {
33
- lightning:: util:: ser:: ReadableArgs ,
34
- bitcoin:: { BlockHash , Txid } ,
35
- bitcoin:: hashes:: hex:: FromHex ,
36
- std:: collections:: HashMap ,
37
- std:: io:: Cursor
38
- } ;
39
-
40
34
/// FilesystemPersister persists channel data on disk, where each channel's
41
35
/// data is stored in a file named after its funding outpoint.
42
36
///
@@ -108,39 +102,64 @@ impl FilesystemPersister {
108
102
util:: write_to_file ( path, "manager" . to_string ( ) , manager)
109
103
}
110
104
111
- #[ cfg( test) ]
112
- fn load_channel_data < Keys : KeysInterface > ( & self , keys : & Keys ) ->
113
- Result < HashMap < OutPoint , ChannelMonitor < Keys :: Signer > > , ChannelMonitorUpdateErr > {
114
- if let Err ( _) = fs:: create_dir_all ( self . path_to_monitor_data ( ) ) {
115
- return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ;
105
+ /// Read `ChannelMonitor`s from disk.
106
+ pub fn read_channelmonitors < Signer : Sign , K : Deref > (
107
+ & self , keys_manager : K
108
+ ) -> Result < HashMap < OutPoint , ( BlockHash , ChannelMonitor < Signer > ) > , std:: io:: Error >
109
+ where K :: Target : KeysInterface < Signer =Signer > + Sized
110
+ {
111
+ let path = self . path_to_monitor_data ( ) ;
112
+ if !Path :: new ( & path) . exists ( ) {
113
+ return Ok ( HashMap :: new ( ) ) ;
114
+ }
115
+ let mut outpoint_to_channelmonitor = HashMap :: new ( ) ;
116
+ for file_option in fs:: read_dir ( path) . unwrap ( ) {
117
+ let file = file_option. unwrap ( ) ;
118
+ let owned_file_name = file. file_name ( ) ;
119
+ let filename = owned_file_name. to_str ( ) ;
120
+ if !filename. is_some ( ) || !filename. unwrap ( ) . is_ascii ( ) || filename. unwrap ( ) . len ( ) < 65 {
121
+ return Err ( std:: io:: Error :: new (
122
+ std:: io:: ErrorKind :: Other ,
123
+ "Invalid ChannelMonitor file name" ,
124
+ ) ) ;
116
125
}
117
- let mut res = HashMap :: new ( ) ;
118
- for file_option in fs:: read_dir ( self . path_to_monitor_data ( ) ) . unwrap ( ) {
119
- let file = file_option. unwrap ( ) ;
120
- let owned_file_name = file. file_name ( ) ;
121
- let filename = owned_file_name. to_str ( ) ;
122
- if !filename. is_some ( ) || !filename. unwrap ( ) . is_ascii ( ) || filename. unwrap ( ) . len ( ) < 65 {
123
- return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ;
124
- }
125
-
126
- let txid = Txid :: from_hex ( filename. unwrap ( ) . split_at ( 64 ) . 0 ) ;
127
- if txid. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
128
126
129
- let index = filename. unwrap ( ) . split_at ( 65 ) . 1 . split ( '.' ) . next ( ) . unwrap ( ) . parse ( ) ;
130
- if index. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
131
-
132
- let contents = fs:: read ( & file. path ( ) ) ;
133
- if contents. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
127
+ let txid = Txid :: from_hex ( filename. unwrap ( ) . split_at ( 64 ) . 0 ) ;
128
+ if txid. is_err ( ) {
129
+ return Err ( std:: io:: Error :: new (
130
+ std:: io:: ErrorKind :: Other ,
131
+ "Invalid tx ID in filename" ,
132
+ ) ) ;
133
+ }
134
134
135
- if let Ok ( ( _ , loaded_monitor ) ) =
136
- < ( BlockHash , ChannelMonitor < Keys :: Signer > ) > :: read ( & mut Cursor :: new ( & contents . unwrap ( ) ) , keys ) {
137
- res . insert ( OutPoint { txid : txid . unwrap ( ) , index : index . unwrap ( ) } , loaded_monitor ) ;
138
- } else {
139
- return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ;
140
- }
135
+ let index = filename . unwrap ( ) . split_at ( 65 ) . 1 . split ( '.' ) . next ( ) . unwrap ( ) . parse ( ) ;
136
+ if index . is_err ( ) {
137
+ return Err ( std :: io :: Error :: new (
138
+ std :: io :: ErrorKind :: Other ,
139
+ "Invalid tx index in filename" ,
140
+ ) ) ;
141
141
}
142
- Ok ( res)
142
+
143
+ let contents = fs:: read ( & file. path ( ) ) ?;
144
+
145
+ if let Ok ( ( blockhash, channel_monitor) ) =
146
+ <( BlockHash , ChannelMonitor < Signer > ) >:: read (
147
+ & mut Cursor :: new ( & contents) ,
148
+ & * keys_manager,
149
+ ) {
150
+ outpoint_to_channelmonitor. insert (
151
+ OutPoint { txid : txid. unwrap ( ) , index : index. unwrap ( ) } ,
152
+ ( blockhash, channel_monitor) ,
153
+ ) ;
154
+ } else {
155
+ return Err ( std:: io:: Error :: new (
156
+ std:: io:: ErrorKind :: Other ,
157
+ "Failed to deserialize ChannelMonitor" ,
158
+ ) ) ;
159
+ }
143
160
}
161
+ Ok ( outpoint_to_channelmonitor)
162
+ }
144
163
}
145
164
146
165
impl < ChannelSigner : Sign + Send + Sync > channelmonitor:: Persist < ChannelSigner > for FilesystemPersister {
@@ -210,22 +229,22 @@ mod tests {
210
229
211
230
// Check that the persisted channel data is empty before any channels are
212
231
// open.
213
- let mut persisted_chan_data_0 = persister_0. load_channel_data ( nodes[ 0 ] . keys_manager ) . unwrap ( ) ;
232
+ let mut persisted_chan_data_0 = persister_0. read_channelmonitors ( nodes[ 0 ] . keys_manager ) . unwrap ( ) ;
214
233
assert_eq ! ( persisted_chan_data_0. keys( ) . len( ) , 0 ) ;
215
- let mut persisted_chan_data_1 = persister_1. load_channel_data ( nodes[ 1 ] . keys_manager ) . unwrap ( ) ;
234
+ let mut persisted_chan_data_1 = persister_1. read_channelmonitors ( nodes[ 1 ] . keys_manager ) . unwrap ( ) ;
216
235
assert_eq ! ( persisted_chan_data_1. keys( ) . len( ) , 0 ) ;
217
236
218
237
// Helper to make sure the channel is on the expected update ID.
219
238
macro_rules! check_persisted_data {
220
239
( $expected_update_id: expr) => {
221
- persisted_chan_data_0 = persister_0. load_channel_data ( nodes[ 0 ] . keys_manager) . unwrap( ) ;
240
+ persisted_chan_data_0 = persister_0. read_channelmonitors ( nodes[ 0 ] . keys_manager) . unwrap( ) ;
222
241
assert_eq!( persisted_chan_data_0. keys( ) . len( ) , 1 ) ;
223
- for mon in persisted_chan_data_0. values( ) {
242
+ for ( _ , mon) in persisted_chan_data_0. values( ) {
224
243
assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
225
244
}
226
- persisted_chan_data_1 = persister_1. load_channel_data ( nodes[ 1 ] . keys_manager) . unwrap( ) ;
245
+ persisted_chan_data_1 = persister_1. read_channelmonitors ( nodes[ 1 ] . keys_manager) . unwrap( ) ;
227
246
assert_eq!( persisted_chan_data_1. keys( ) . len( ) , 1 ) ;
228
- for mon in persisted_chan_data_1. values( ) {
247
+ for ( _ , mon) in persisted_chan_data_1. values( ) {
229
248
assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
230
249
}
231
250
}
0 commit comments