@@ -165,8 +165,8 @@ pub trait Persist<ChannelSigner: EcdsaChannelSigner> {
165
165
fn archive_persisted_channel ( & self , channel_funding_outpoint : OutPoint ) ;
166
166
}
167
167
168
- struct MonitorHolder < ChannelSigner : EcdsaChannelSigner > {
169
- monitor : ChannelMonitor < ChannelSigner > ,
168
+ pub ( crate ) struct MonitorHolder < ChannelSigner : EcdsaChannelSigner > {
169
+ pub ( crate ) monitor : ChannelMonitor < ChannelSigner > ,
170
170
/// The full set of pending monitor updates for this Channel.
171
171
///
172
172
/// Note that this lock must be held from [`ChannelMonitor::update_monitor`] through to
@@ -181,7 +181,7 @@ struct MonitorHolder<ChannelSigner: EcdsaChannelSigner> {
181
181
/// could cause users to have a full [`ChannelMonitor`] on disk as well as a
182
182
/// [`ChannelMonitorUpdate`] which was already applied. While this isn't an issue for the
183
183
/// LDK-provided update-based [`Persist`], it is somewhat surprising for users so we avoid it.
184
- pending_monitor_updates : Mutex < Vec < u64 > > ,
184
+ pub ( crate ) pending_monitor_updates : Mutex < Vec < u64 > > ,
185
185
}
186
186
187
187
impl < ChannelSigner : EcdsaChannelSigner > MonitorHolder < ChannelSigner > {
@@ -195,8 +195,8 @@ impl<ChannelSigner: EcdsaChannelSigner> MonitorHolder<ChannelSigner> {
195
195
/// Note that this holds a mutex in [`ChainMonitor`] and may block other events until it is
196
196
/// released.
197
197
pub struct LockedChannelMonitor < ' a , ChannelSigner : EcdsaChannelSigner > {
198
- lock : RwLockReadGuard < ' a , HashMap < OutPoint , MonitorHolder < ChannelSigner > > > ,
199
- funding_txo : OutPoint ,
198
+ pub ( crate ) lock : RwLockReadGuard < ' a , HashMap < OutPoint , MonitorHolder < ChannelSigner > > > ,
199
+ pub ( crate ) funding_txo : OutPoint ,
200
200
}
201
201
202
202
impl < ChannelSigner : EcdsaChannelSigner > Deref for LockedChannelMonitor < ' _ , ChannelSigner > {
@@ -247,73 +247,19 @@ pub struct ChainMonitor<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F
247
247
event_notifier : Notifier ,
248
248
}
249
249
250
- impl < ChannelSigner : EcdsaChannelSigner , C : Deref , T : Deref , F : Deref , L : Deref , P : Deref > ChainMonitor < ChannelSigner , C , T , F , L , P >
251
- where C :: Target : chain:: Filter ,
252
- T :: Target : BroadcasterInterface ,
253
- F :: Target : FeeEstimator ,
254
- L :: Target : Logger ,
255
- P :: Target : Persist < ChannelSigner > ,
256
- {
257
- /// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
258
- /// of a channel and reacting accordingly based on transactions in the given chain data. See
259
- /// [`ChannelMonitor::block_connected`] for details. Any HTLCs that were resolved on chain will
260
- /// be returned by [`chain::Watch::release_pending_monitor_events`].
261
- ///
262
- /// Calls back to [`chain::Filter`] if any monitor indicated new outputs to watch. Subsequent
263
- /// calls must not exclude any transactions matching the new outputs nor any in-block
264
- /// descendants of such transactions. It is not necessary to re-fetch the block to obtain
265
- /// updated `txdata`.
266
- ///
267
- /// Calls which represent a new blockchain tip height should set `best_height`.
268
- fn process_chain_data < FN > ( & self , header : & Header , best_height : Option < u32 > , txdata : & TransactionData , process : FN )
250
+ pub ( crate ) fn update_monitor_with_chain_data_util < FN , P : Deref , ChannelSigner , C : Deref , L : Deref > (
251
+ persister : & P , chain_source : & Option < C > , logger : & L , header : & Header , best_height : Option < u32 > , txdata : & TransactionData , process : FN , funding_outpoint : & OutPoint ,
252
+ monitor_state : & MonitorHolder < ChannelSigner > , channel_count : usize ,
253
+ ) -> Result < ( ) , ( ) >
269
254
where
270
- FN : Fn ( & ChannelMonitor < ChannelSigner > , & TransactionData ) -> Vec < TransactionOutputs > ,
255
+ C :: Target : chain:: Filter ,
256
+ FN : Fn ( & ChannelMonitor < ChannelSigner > , & TransactionData ) -> Vec < TransactionOutputs > ,
257
+ P :: Target : Persist < ChannelSigner > ,
258
+ L :: Target : Logger ,
259
+ ChannelSigner : EcdsaChannelSigner ,
271
260
{
272
- let err_str = "ChannelMonitor[Update] persistence failed unrecoverably. This indicates we cannot continue normal operation and must shut down." ;
273
- let funding_outpoints = hash_set_from_iter ( self . monitors . read ( ) . unwrap ( ) . keys ( ) . cloned ( ) ) ;
274
- let channel_count = funding_outpoints. len ( ) ;
275
- for funding_outpoint in funding_outpoints. iter ( ) {
276
- let monitor_lock = self . monitors . read ( ) . unwrap ( ) ;
277
- if let Some ( monitor_state) = monitor_lock. get ( funding_outpoint) {
278
- if self . update_monitor_with_chain_data ( header, best_height, txdata, & process, funding_outpoint, & monitor_state, channel_count) . is_err ( ) {
279
- // Take the monitors lock for writing so that we poison it and any future
280
- // operations going forward fail immediately.
281
- core:: mem:: drop ( monitor_lock) ;
282
- let _poison = self . monitors . write ( ) . unwrap ( ) ;
283
- log_error ! ( self . logger, "{}" , err_str) ;
284
- panic ! ( "{}" , err_str) ;
285
- }
286
- }
287
- }
288
-
289
- // do some followup cleanup if any funding outpoints were added in between iterations
290
- let monitor_states = self . monitors . write ( ) . unwrap ( ) ;
291
- for ( funding_outpoint, monitor_state) in monitor_states. iter ( ) {
292
- if !funding_outpoints. contains ( funding_outpoint) {
293
- if self . update_monitor_with_chain_data ( header, best_height, txdata, & process, funding_outpoint, & monitor_state, channel_count) . is_err ( ) {
294
- log_error ! ( self . logger, "{}" , err_str) ;
295
- panic ! ( "{}" , err_str) ;
296
- }
297
- }
298
- }
299
-
300
- if let Some ( height) = best_height {
301
- // If the best block height is being updated, update highest_chain_height under the
302
- // monitors write lock.
303
- let old_height = self . highest_chain_height . load ( Ordering :: Acquire ) ;
304
- let new_height = height as usize ;
305
- if new_height > old_height {
306
- self . highest_chain_height . store ( new_height, Ordering :: Release ) ;
307
- }
308
- }
309
- }
310
-
311
- fn update_monitor_with_chain_data < FN > (
312
- & self , header : & Header , best_height : Option < u32 > , txdata : & TransactionData , process : FN , funding_outpoint : & OutPoint ,
313
- monitor_state : & MonitorHolder < ChannelSigner > , channel_count : usize ,
314
- ) -> Result < ( ) , ( ) > where FN : Fn ( & ChannelMonitor < ChannelSigner > , & TransactionData ) -> Vec < TransactionOutputs > {
315
261
let monitor = & monitor_state. monitor ;
316
- let logger = WithChannelMonitor :: from ( & self . logger , & monitor, None ) ;
262
+ let logger = WithChannelMonitor :: from ( logger, & monitor, None ) ;
317
263
318
264
let mut txn_outputs = process ( monitor, txdata) ;
319
265
@@ -338,7 +284,7 @@ where C::Target: chain::Filter,
338
284
// `ChannelMonitorUpdate` after a channel persist for a channel with the same
339
285
// `latest_update_id`.
340
286
let _pending_monitor_updates = monitor_state. pending_monitor_updates . lock ( ) . unwrap ( ) ;
341
- match self . persister . update_persisted_channel ( * funding_outpoint, None , monitor) {
287
+ match persister. update_persisted_channel ( * funding_outpoint, None , monitor) {
342
288
ChannelMonitorUpdateStatus :: Completed =>
343
289
log_trace ! ( logger, "Finished syncing Channel Monitor for channel {} for block-data" ,
344
290
log_funding_info!( monitor)
@@ -354,7 +300,7 @@ where C::Target: chain::Filter,
354
300
355
301
// Register any new outputs with the chain source for filtering, storing any dependent
356
302
// transactions from within the block that previously had not been included in txdata.
357
- if let Some ( ref chain_source ) = self . chain_source {
303
+ if let Some ( ref chain_source_ref ) = chain_source {
358
304
let block_hash = header. block_hash ( ) ;
359
305
for ( txid, mut outputs) in txn_outputs. drain ( ..) {
360
306
for ( idx, output) in outputs. drain ( ..) {
@@ -365,13 +311,85 @@ where C::Target: chain::Filter,
365
311
script_pubkey : output. script_pubkey ,
366
312
} ;
367
313
log_trace ! ( logger, "Adding monitoring for spends of outpoint {} to the filter" , output. outpoint) ;
368
- chain_source . register_output ( output) ;
314
+ chain_source_ref . register_output ( output) ;
369
315
}
370
316
}
371
317
}
372
318
Ok ( ( ) )
373
319
}
374
320
321
+ pub ( crate ) fn process_chain_data_util < FN , ChannelSigner : EcdsaChannelSigner , L : Deref , P : Deref , C : Deref > ( persister : & P , chain_source : & Option < C > ,
322
+ logger : & L , monitors : & RwLock < HashMap < OutPoint , MonitorHolder < ChannelSigner > > > , highest_chain_height : & AtomicUsize ,
323
+ header : & Header , best_height : Option < u32 > , txdata : & TransactionData , process : FN )
324
+ where
325
+ FN : Fn ( & ChannelMonitor < ChannelSigner > , & TransactionData ) -> Vec < TransactionOutputs > ,
326
+ L :: Target : Logger ,
327
+ P :: Target : Persist < ChannelSigner > ,
328
+ C :: Target : chain:: Filter ,
329
+ {
330
+ let err_str = "ChannelMonitor[Update] persistence failed unrecoverably. This indicates we cannot continue normal operation and must shut down." ;
331
+ let funding_outpoints = hash_set_from_iter ( monitors. read ( ) . unwrap ( ) . keys ( ) . cloned ( ) ) ;
332
+ let channel_count = funding_outpoints. len ( ) ;
333
+ for funding_outpoint in funding_outpoints. iter ( ) {
334
+ let monitor_lock = monitors. read ( ) . unwrap ( ) ;
335
+ if let Some ( monitor_state) = monitor_lock. get ( funding_outpoint) {
336
+ if update_monitor_with_chain_data_util ( persister, chain_source, logger, header, best_height, txdata, & process, funding_outpoint, & monitor_state, channel_count) . is_err ( ) {
337
+ // Take the monitors lock for writing so that we poison it and any future
338
+ // operations going forward fail immediately.
339
+ core:: mem:: drop ( monitor_lock) ;
340
+ let _poison = monitors. write ( ) . unwrap ( ) ;
341
+ log_error ! ( logger, "{}" , err_str) ;
342
+ panic ! ( "{}" , err_str) ;
343
+ }
344
+ }
345
+ }
346
+
347
+ // do some followup cleanup if any funding outpoints were added in between iterations
348
+ let monitor_states = monitors. write ( ) . unwrap ( ) ;
349
+ for ( funding_outpoint, monitor_state) in monitor_states. iter ( ) {
350
+ if !funding_outpoints. contains ( funding_outpoint) {
351
+ if update_monitor_with_chain_data_util ( persister, chain_source, logger, header, best_height, txdata, & process, funding_outpoint, & monitor_state, channel_count) . is_err ( ) {
352
+ log_error ! ( logger, "{}" , err_str) ;
353
+ panic ! ( "{}" , err_str) ;
354
+ }
355
+ }
356
+ }
357
+
358
+ if let Some ( height) = best_height {
359
+ // If the best block height is being updated, update highest_chain_height under the
360
+ // monitors write lock.
361
+ let old_height = highest_chain_height. load ( Ordering :: Acquire ) ;
362
+ let new_height = height as usize ;
363
+ if new_height > old_height {
364
+ highest_chain_height. store ( new_height, Ordering :: Release ) ;
365
+ }
366
+ }
367
+ }
368
+ impl < ChannelSigner : EcdsaChannelSigner , C : Deref , T : Deref , F : Deref , L : Deref , P : Deref > ChainMonitor < ChannelSigner , C , T , F , L , P >
369
+ where C :: Target : chain:: Filter ,
370
+ T :: Target : BroadcasterInterface ,
371
+ F :: Target : FeeEstimator ,
372
+ L :: Target : Logger ,
373
+ P :: Target : Persist < ChannelSigner > ,
374
+ {
375
+ /// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
376
+ /// of a channel and reacting accordingly based on transactions in the given chain data. See
377
+ /// [`ChannelMonitor::block_connected`] for details. Any HTLCs that were resolved on chain will
378
+ /// be returned by [`chain::Watch::release_pending_monitor_events`].
379
+ ///
380
+ /// Calls back to [`chain::Filter`] if any monitor indicated new outputs to watch. Subsequent
381
+ /// calls must not exclude any transactions matching the new outputs nor any in-block
382
+ /// descendants of such transactions. It is not necessary to re-fetch the block to obtain
383
+ /// updated `txdata`.
384
+ ///
385
+ /// Calls which represent a new blockchain tip height should set `best_height`.
386
+ fn process_chain_data < FN > ( & self , header : & Header , best_height : Option < u32 > , txdata : & TransactionData , process : FN )
387
+ where
388
+ FN : Fn ( & ChannelMonitor < ChannelSigner > , & TransactionData ) -> Vec < TransactionOutputs > ,
389
+ {
390
+ process_chain_data_util ( & self . persister , & self . chain_source , & self . logger , & self . monitors , & self . highest_chain_height , header, best_height, txdata, process) ;
391
+ }
392
+
375
393
/// Creates a new `ChainMonitor` used to watch on-chain activity pertaining to channels.
376
394
///
377
395
/// When an optional chain source implementing [`chain::Filter`] is provided, the chain monitor
@@ -750,17 +768,6 @@ where C::Target: chain::Filter,
750
768
L :: Target : Logger ,
751
769
P :: Target : Persist < ChannelSigner > ,
752
770
{
753
- fn get_stub_cids_with_counterparty ( & self , counterparty_node_id : PublicKey ) -> Vec < ChannelId > {
754
- let stub_monitors = self . stub_monitors . read ( ) . unwrap ( ) ;
755
- let mut stubs = vec ! [ ] ;
756
- for ( _, mon) in stub_monitors. iter ( ) {
757
- if mon. get_counterparty_node_id ( ) == Some ( counterparty_node_id) {
758
- stubs. push ( mon. channel_id ( ) ) ;
759
- }
760
- }
761
- stubs
762
- }
763
-
764
771
fn watch_channel ( & self , funding_outpoint : OutPoint , monitor : ChannelMonitor < ChannelSigner > ) -> Result < ChannelMonitorUpdateStatus , ( ) > {
765
772
let logger = WithChannelMonitor :: from ( & self . logger , & monitor, None ) ;
766
773
let mut monitors = self . monitors . write ( ) . unwrap ( ) ;
0 commit comments