@@ -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 block height must be one greater than the previous height" ) ;
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
@@ -3406,6 +3399,64 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3406
3399
for ( source, payment_hash, reason) in timed_out_htlcs. drain ( ..) {
3407
3400
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason) ;
3408
3401
}
3402
+ }
3403
+
3404
+ /// Updates channel state to take note of transactions which were confirmed in the given block
3405
+ /// at the given height.
3406
+ ///
3407
+ /// Note that you must still call (or have called) [`update_best_block`] with the block
3408
+ /// information which is included here.
3409
+ ///
3410
+ /// This method may be called before or after [`update_best_block`] for a given block's
3411
+ /// transaction data and may be called multiple times with additional transaction data for a
3412
+ /// given block.
3413
+ ///
3414
+ /// This method may be called for a previous block after an [`update_best_block`] call has
3415
+ /// been made for a later block, however it must *not* be called with transaction data from a
3416
+ /// block which is no longer in the best chain (ie where [`update_best_block`] has already
3417
+ /// been informed about a blockchain reorganization which no longer includes the block which
3418
+ /// corresponds to `header`).
3419
+ ///
3420
+ /// [`update_best_block`]: `Self::update_best_block`
3421
+ pub fn transactions_confirmed ( & self , header : & BlockHeader , height : u32 , txdata : & TransactionData ) {
3422
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3423
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3424
+ // See the docs for `ChannelManagerReadArgs` for more.
3425
+
3426
+ let block_hash = header. block_hash ( ) ;
3427
+ log_trace ! ( self . logger, "{} transactions included in block {} at height {} provided" , txdata. len( ) , block_hash, height) ;
3428
+
3429
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3430
+ self . do_chain_event ( height, |channel| channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger ) . map ( |_| ( None , Vec :: new ( ) ) ) ) ;
3431
+ }
3432
+
3433
+ /// Updates channel state with the current best blockchain tip. You should attempt to call this
3434
+ /// quickly after a new block becomes available, however if multiple new blocks become
3435
+ /// available at the same time, only a single `update_best_block()` call needs to be made.
3436
+ ///
3437
+ /// This method should also be called immediately after any block disconnections, once at the
3438
+ /// reorganization fork point, and once with the new chain tip. Calling this method at the
3439
+ /// blockchain reorganization fork point ensures we learn when a funding transaction which was
3440
+ /// previously confirmed is reorganized out of the blockchain, ensuring we do not continue to
3441
+ /// accept payments which cannot be enforced on-chain.
3442
+ ///
3443
+ /// In both the block-connection and block-disconnection case, this method may be called either
3444
+ /// once per block connected or disconnected, or simply at the fork point and new tip(s),
3445
+ /// skipping any intermediary blocks.
3446
+ pub fn update_best_block ( & self , header : & BlockHeader , height : u32 ) {
3447
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3448
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3449
+ // See the docs for `ChannelManagerReadArgs` for more.
3450
+
3451
+ let block_hash = header. block_hash ( ) ;
3452
+ log_trace ! ( self . logger, "New best block: {} at height {}" , block_hash, height) ;
3453
+
3454
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3455
+
3456
+ self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3457
+ * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3458
+
3459
+ self . do_chain_event ( height, |channel| channel. update_best_block ( height, header. time ) ) ;
3409
3460
3410
3461
loop {
3411
3462
// Update last_node_announcement_serial to be the max of its current value and the
0 commit comments