@@ -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,64 @@ 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 :: Other ,
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- }
125-
126- let txid = Txid :: from_hex ( filename. unwrap ( ) . split_at ( 64 ) . 0 ) ;
127- if txid. is_err ( ) { return Err ( ChannelMonitorUpdateErr :: PermanentFailure ) ; }
128126
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+ }
134134
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+ ) ) ;
141141 }
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+ }
143160 }
161+ Ok ( outpoint_to_channelmonitor)
162+ }
144163}
145164
146165impl < ChannelSigner : Sign + Send + Sync > channelmonitor:: Persist < ChannelSigner > for FilesystemPersister {
@@ -210,22 +229,22 @@ mod tests {
210229
211230 // Check that the persisted channel data is empty before any channels are
212231 // 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 ( ) ;
214233 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 ( ) ;
216235 assert_eq ! ( persisted_chan_data_1. keys( ) . len( ) , 0 ) ;
217236
218237 // Helper to make sure the channel is on the expected update ID.
219238 macro_rules! check_persisted_data {
220239 ( $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( ) ;
222241 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( ) {
224243 assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
225244 }
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( ) ;
227246 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( ) {
229248 assert_eq!( mon. get_latest_update_id( ) , $expected_update_id) ;
230249 }
231250 }
0 commit comments