@@ -3293,8 +3293,13 @@ where
3293
3293
L :: Target : Logger ,
3294
3294
{
3295
3295
fn block_connected ( & self , block : & Block , height : u32 ) {
3296
+ assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , block. header. prev_blockhash,
3297
+ "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3298
+ assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3299
+ "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3296
3300
let txdata: Vec < _ > = block. txdata . iter ( ) . enumerate ( ) . collect ( ) ;
3297
- ChannelManager :: block_connected ( self , & block. header , & txdata, height) ;
3301
+ self . transactions_confirmed ( & block. header , height, & txdata) ;
3302
+ self . update_best_block ( & block. header , height) ;
3298
3303
}
3299
3304
3300
3305
fn block_disconnected ( & self , header : & BlockHeader , _height : u32 ) {
@@ -3309,22 +3314,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3309
3314
F :: Target : FeeEstimator ,
3310
3315
L :: Target : Logger ,
3311
3316
{
3312
- /// Updates channel state based on transactions seen in a connected block.
3313
- pub fn block_connected ( & self , header : & BlockHeader , txdata : & TransactionData , height : u32 ) {
3317
+ fn do_chain_event < FN : Fn ( & mut Channel < Signer > ) -> Result < ( Option < msgs :: FundingLocked > , Vec < ( HTLCSource , PaymentHash ) > ) , msgs :: ErrorMessage > >
3318
+ ( & self , height : u32 , f : FN ) {
3314
3319
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3315
3320
// during initialization prior to the chain_monitor being fully configured in some cases.
3316
3321
// See the docs for `ChannelManagerReadArgs` for more.
3317
- let block_hash = header. block_hash ( ) ;
3318
- log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3319
-
3320
- let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3321
-
3322
- assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , header. prev_blockhash,
3323
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3324
- assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3325
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3326
- self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3327
- * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3328
3322
3329
3323
let mut failed_channels = Vec :: new ( ) ;
3330
3324
let mut timed_out_htlcs = Vec :: new ( ) ;
@@ -3334,8 +3328,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3334
3328
let short_to_id = & mut channel_state. short_to_id ;
3335
3329
let pending_msg_events = & mut channel_state. pending_msg_events ;
3336
3330
channel_state. by_id . retain ( |_, channel| {
3337
- let res = channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger )
3338
- . and_then ( |_| channel. update_best_block ( height, header. time ) ) ;
3331
+ let res = f ( channel) ;
3339
3332
if let Ok ( ( chan_res, mut timed_out_pending_htlcs) ) = res {
3340
3333
for ( source, payment_hash) in timed_out_pending_htlcs. drain ( ..) {
3341
3334
let chan_update = self . get_channel_update ( & channel) . map ( |u| u. encode_with_len ( ) ) . unwrap ( ) ; // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
@@ -3405,6 +3398,46 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3405
3398
for ( source, payment_hash, reason) in timed_out_htlcs. drain ( ..) {
3406
3399
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason) ;
3407
3400
}
3401
+ }
3402
+
3403
+ /// Updates channel state to take note of transactions which were confirmed in the given block
3404
+ /// at the given height.
3405
+ ///
3406
+ /// Note that you must still call update_best_block with the block information here.
3407
+ ///
3408
+ /// XXX: Note that in the case that a transaction which was provided via this method is
3409
+ /// reorganized out of the best chain, the only current way to correctly handle the any
3410
+ /// associated channel force-closure is to walk the chain back from the current tip with
3411
+ /// repeated `block_disconnected` calls, followed by an `update_best_block` call.
3412
+ pub fn transactions_confirmed ( & self , header : & BlockHeader , height : u32 , txdata : & TransactionData ) {
3413
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3414
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3415
+ // See the docs for `ChannelManagerReadArgs` for more.
3416
+
3417
+ let block_hash = header. block_hash ( ) ;
3418
+ log_trace ! ( self . logger, "{} transactions included in block {} at height {} provided" , txdata. len( ) , block_hash, height) ;
3419
+
3420
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3421
+ self . do_chain_event ( height, |channel| channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger ) . map ( |a| ( a, Vec :: new ( ) ) ) ) ;
3422
+ }
3423
+
3424
+ /// Updates channel state with the current best blockchain tip. You should attempt to call this
3425
+ /// quickly after a new block becomes available, however it does not need to be called for each
3426
+ /// new block.
3427
+ pub fn update_best_block ( & self , header : & BlockHeader , height : u32 ) {
3428
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3429
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3430
+ // See the docs for `ChannelManagerReadArgs` for more.
3431
+
3432
+ let block_hash = header. block_hash ( ) ;
3433
+ log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3434
+
3435
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3436
+
3437
+ self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3438
+ * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3439
+
3440
+ self . do_chain_event ( height, |channel| channel. update_best_block ( height, header. time ) ) ;
3408
3441
3409
3442
loop {
3410
3443
// Update last_node_announcement_serial to be the max of its current value and the
0 commit comments