@@ -3236,8 +3236,18 @@ where
3236
3236
L :: Target : Logger ,
3237
3237
{
3238
3238
fn block_connected ( & self , block : & Block , height : u32 ) {
3239
+ // This assertion should be enforced in tests, however we have a number of tests that
3240
+ // were written before this requirement and do not meet it.
3241
+ #[ cfg( not( test) ) ]
3242
+ {
3243
+ assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , block. header. prev_blockhash,
3244
+ "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3245
+ assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3246
+ "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3247
+ }
3239
3248
let txdata: Vec < _ > = block. txdata . iter ( ) . enumerate ( ) . collect ( ) ;
3240
- ChannelManager :: block_connected ( self , & block. header , & txdata, height) ;
3249
+ self . transactions_confirmed ( & block. header , height, & txdata) ;
3250
+ self . update_best_block ( & block. header , height) ;
3241
3251
}
3242
3252
3243
3253
fn block_disconnected ( & self , header : & BlockHeader , _height : u32 ) {
@@ -3252,27 +3262,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3252
3262
F :: Target : FeeEstimator ,
3253
3263
L :: Target : Logger ,
3254
3264
{
3255
- /// Updates channel state based on transactions seen in a connected block.
3256
- pub fn block_connected ( & self , header : & BlockHeader , txdata : & TransactionData , height : u32 ) {
3265
+ fn do_block_event < FN : Fn ( & mut Channel < Signer > ) -> Result < ( Option < msgs :: FundingLocked > , Vec < ( HTLCSource , PaymentHash ) > ) , msgs :: ErrorMessage > >
3266
+ ( & self , height : u32 , f : FN ) {
3257
3267
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3258
3268
// during initialization prior to the chain_monitor being fully configured in some cases.
3259
3269
// See the docs for `ChannelManagerReadArgs` for more.
3260
- let block_hash = header. block_hash ( ) ;
3261
- log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3262
-
3263
- let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3264
-
3265
- // This assertion should be enforced in tests, however we have a number of tests that
3266
- // were written before this requirement and do not meet it.
3267
- #[ cfg( not( test) ) ]
3268
- {
3269
- assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , header. prev_blockhash,
3270
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3271
- assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3272
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3273
- }
3274
- self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3275
- * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3276
3270
3277
3271
let mut failed_channels = Vec :: new ( ) ;
3278
3272
let mut timed_out_htlcs = Vec :: new ( ) ;
@@ -3282,8 +3276,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3282
3276
let short_to_id = & mut channel_state. short_to_id ;
3283
3277
let pending_msg_events = & mut channel_state. pending_msg_events ;
3284
3278
channel_state. by_id . retain ( |_, channel| {
3285
- let res = channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger )
3286
- . and_then ( |_| channel. update_best_block ( height, header. time ) ) ;
3279
+ let res = f ( channel) ;
3287
3280
if let Ok ( ( chan_res, mut timed_out_pending_htlcs) ) = res {
3288
3281
for ( source, payment_hash) in timed_out_pending_htlcs. drain ( ..) {
3289
3282
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
@@ -3353,6 +3346,46 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3353
3346
for ( source, payment_hash, reason) in timed_out_htlcs. drain ( ..) {
3354
3347
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason) ;
3355
3348
}
3349
+ }
3350
+
3351
+ /// Updates channel state to take note of transactions which were confirmed in the given block
3352
+ /// at the given height.
3353
+ ///
3354
+ /// Note that you must still call update_best_block with the block information here.
3355
+ ///
3356
+ /// XXX: Note that in the case that a transaction which was provided via this method is
3357
+ /// reorganized out of the best chain, the only current way to correctly handle the any
3358
+ /// associated channel force-closure is to walk the chain back from the current tip with
3359
+ /// repeated `block_disconnected` calls, followed by an `update_best_block` call.
3360
+ pub fn transactions_confirmed ( & self , header : & BlockHeader , height : u32 , txdata : & TransactionData ) {
3361
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3362
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3363
+ // See the docs for `ChannelManagerReadArgs` for more.
3364
+
3365
+ let block_hash = header. block_hash ( ) ;
3366
+ log_trace ! ( self . logger, "{} transactions included in block {} at height {} provided" , txdata. len( ) , block_hash, height) ;
3367
+
3368
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3369
+ self . do_block_event ( height, |channel| channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger ) . map ( |a| ( a, Vec :: new ( ) ) ) ) ;
3370
+ }
3371
+
3372
+ /// Updates channel state with the current best blockchain tip. You should attempt to call this
3373
+ /// quickly after a new block becomes available, however it does not need to be called for each
3374
+ /// new block.
3375
+ pub fn update_best_block ( & self , header : & BlockHeader , height : u32 ) {
3376
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3377
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3378
+ // See the docs for `ChannelManagerReadArgs` for more.
3379
+
3380
+ let block_hash = header. block_hash ( ) ;
3381
+ log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3382
+
3383
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3384
+
3385
+ self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3386
+ * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3387
+
3388
+ self . do_block_event ( height, |channel| channel. update_best_block ( height, header. time ) ) ;
3356
3389
3357
3390
loop {
3358
3391
// Update last_node_announcement_serial to be the max of its current value and the
0 commit comments