@@ -12,7 +12,8 @@ extern crate lightning;
1212extern crate bitcoin;
1313extern crate libc;
1414
15- use bitcoin:: hashes:: hex:: ToHex ;
15+ use bitcoin:: { BlockHash , Txid } ;
16+ use bitcoin:: hashes:: hex:: { FromHex , ToHex } ;
1617use crate :: util:: DiskWriteable ;
1718use lightning:: chain;
1819use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
@@ -22,21 +23,14 @@ use lightning::chain::keysinterface::{Sign, KeysInterface};
2223use lightning:: chain:: transaction:: OutPoint ;
2324use lightning:: ln:: channelmanager:: ChannelManager ;
2425use lightning:: util:: logger:: Logger ;
25- use lightning:: util:: ser:: Writeable ;
26+ use lightning:: util:: ser:: { ReadableArgs , Writeable } ;
27+ use std:: collections:: HashMap ;
2628use 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 } ;
2932use std:: sync:: Arc ;
3033
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-
4034/// FilesystemPersister persists channel data on disk, where each channel's
4135/// data is stored in a file named after its funding outpoint.
4236///
@@ -108,39 +102,61 @@ impl FilesystemPersister {
108102 util:: write_to_file ( path, "manager" . to_string ( ) , manager)
109103 }
110104
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+ ) ) ;
116125 }
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- }
125126
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+ }
131134
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+ }
134142
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+ ) )
141156 }
142- Ok ( res)
143157 }
158+ Ok ( outpoint_to_channelmonitor)
159+ }
144160}
145161
146162impl < ChannelSigner : Sign + Send + Sync > channelmonitor:: Persist < ChannelSigner > for FilesystemPersister {
@@ -210,22 +226,22 @@ mod tests {
210226
211227 // Check that the persisted channel data is empty before any channels are
212228 // 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 ( ) ;
214230 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 ( ) ;
216232 assert_eq ! ( persisted_chan_data_1. keys( ) . len( ) , 0 ) ;
217233
218234 // Helper to make sure the channel is on the expected update ID.
219235 macro_rules! check_persisted_data {
220236 ( $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( ) ;
222238 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( ) {
224240 assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
225241 }
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( ) ;
227243 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( ) {
229245 assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
230246 }
231247 }
0 commit comments