@@ -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,61 @@ 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 :: InvalidData ,
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
126
- let txid = Txid :: from_hex ( filename. unwrap ( ) . split_at ( 64 ) . 0 ) ;
127
- if txid. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
128
-
129
- let index = filename. unwrap ( ) . split_at ( 65 ) . 1 . split ( '.' ) . next ( ) . unwrap ( ) . parse ( ) ;
130
- if index. 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 :: InvalidData ,
131
+ "Invalid tx ID in filename" ,
132
+ ) ) ;
133
+ }
131
134
132
- let contents = fs:: read ( & file. path ( ) ) ;
133
- if contents. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
135
+ let index = filename. unwrap ( ) . split_at ( 65 ) . 1 . parse ( ) ;
136
+ if index. is_err ( ) {
137
+ return Err ( std:: io:: Error :: new (
138
+ std:: io:: ErrorKind :: InvalidData ,
139
+ "Invalid tx index in filename" ,
140
+ ) ) ;
141
+ }
134
142
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
- }
143
+ let contents = fs:: read ( & file. path ( ) ) ?;
144
+ let mut buffer = Cursor :: new ( & contents) ;
145
+ match <( BlockHash , ChannelMonitor < Signer > ) >:: read ( & mut buffer, & * keys_manager) {
146
+ Ok ( ( blockhash, channel_monitor) ) => {
147
+ outpoint_to_channelmonitor. insert (
148
+ OutPoint { txid : txid. unwrap ( ) , index : index. unwrap ( ) } ,
149
+ ( blockhash, channel_monitor) ,
150
+ ) ;
151
+ }
152
+ Err ( e) => return Err ( std:: io:: Error :: new (
153
+ std:: io:: ErrorKind :: InvalidData ,
154
+ format ! ( "Failed to deserialize ChannelMonitor: {}" , e) ,
155
+ ) )
141
156
}
142
- Ok ( res)
143
157
}
158
+ Ok ( outpoint_to_channelmonitor)
159
+ }
144
160
}
145
161
146
162
impl < ChannelSigner : Sign + Send + Sync > channelmonitor:: Persist < ChannelSigner > for FilesystemPersister {
@@ -210,22 +226,22 @@ mod tests {
210
226
211
227
// Check that the persisted channel data is empty before any channels are
212
228
// open.
213
- let mut persisted_chan_data_0 = persister_0. load_channel_data ( nodes[ 0 ] . keys_manager ) . unwrap ( ) ;
229
+ let mut persisted_chan_data_0 = persister_0. read_channelmonitors ( nodes[ 0 ] . keys_manager ) . unwrap ( ) ;
214
230
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 ( ) ;
231
+ let mut persisted_chan_data_1 = persister_1. read_channelmonitors ( nodes[ 1 ] . keys_manager ) . unwrap ( ) ;
216
232
assert_eq ! ( persisted_chan_data_1. keys( ) . len( ) , 0 ) ;
217
233
218
234
// Helper to make sure the channel is on the expected update ID.
219
235
macro_rules! check_persisted_data {
220
236
( $expected_update_id: expr) => {
221
- persisted_chan_data_0 = persister_0. load_channel_data ( nodes[ 0 ] . keys_manager) . unwrap( ) ;
237
+ persisted_chan_data_0 = persister_0. read_channelmonitors ( nodes[ 0 ] . keys_manager) . unwrap( ) ;
222
238
assert_eq!( persisted_chan_data_0. keys( ) . len( ) , 1 ) ;
223
- for mon in persisted_chan_data_0. values( ) {
239
+ for ( _ , mon) in persisted_chan_data_0. values( ) {
224
240
assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
225
241
}
226
- persisted_chan_data_1 = persister_1. load_channel_data ( nodes[ 1 ] . keys_manager) . unwrap( ) ;
242
+ persisted_chan_data_1 = persister_1. read_channelmonitors ( nodes[ 1 ] . keys_manager) . unwrap( ) ;
227
243
assert_eq!( persisted_chan_data_1. keys( ) . len( ) , 1 ) ;
228
- for mon in persisted_chan_data_1. values( ) {
244
+ for ( _ , mon) in persisted_chan_data_1. values( ) {
229
245
assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
230
246
}
231
247
}
0 commit comments