@@ -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,12 @@ 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
+ ///asdf
3266
+ fn do_block_event < FN : Fn ( & mut Channel < Signer > ) -> Result < ( Option < msgs:: FundingLocked > , Vec < ( HTLCSource , PaymentHash ) > ) , msgs:: ErrorMessage > >
3267
+ ( & self , height : u32 , f : FN ) {
3257
3268
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3258
3269
// during initialization prior to the chain_monitor being fully configured in some cases.
3259
3270
// 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
3271
3277
3272
let mut failed_channels = Vec :: new ( ) ;
3278
3273
let mut timed_out_htlcs = Vec :: new ( ) ;
@@ -3282,8 +3277,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3282
3277
let short_to_id = & mut channel_state. short_to_id ;
3283
3278
let pending_msg_events = & mut channel_state. pending_msg_events ;
3284
3279
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 ) ) ;
3280
+ let res = f ( channel) ;
3287
3281
if let Ok ( ( chan_res, mut timed_out_pending_htlcs) ) = res {
3288
3282
for ( source, payment_hash) in timed_out_pending_htlcs. drain ( ..) {
3289
3283
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 +3347,46 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3353
3347
for ( source, payment_hash, reason) in timed_out_htlcs. drain ( ..) {
3354
3348
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason) ;
3355
3349
}
3350
+ }
3351
+
3352
+ /// Updates channel state to take note of transactions which were confirmed in the given block
3353
+ /// at the given height.
3354
+ ///
3355
+ /// Note that you must still call update_best_block with the block information here.
3356
+ ///
3357
+ /// XXX: Note that in the case that a transaction which was provided via this method is
3358
+ /// reorganized out of the best chain, the only current way to correctly handle the any
3359
+ /// associated channel force-closure is to walk the chain back from the current tip with
3360
+ /// repeated `block_disconnected` calls, followed by an `update_best_block` call.
3361
+ pub fn transactions_confirmed ( & self , header : & BlockHeader , height : u32 , txdata : & TransactionData ) {
3362
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3363
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3364
+ // See the docs for `ChannelManagerReadArgs` for more.
3365
+
3366
+ let block_hash = header. block_hash ( ) ;
3367
+ log_trace ! ( self . logger, "{} transactions included in block {} at height {} provided" , txdata. len( ) , block_hash, height) ;
3368
+
3369
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3370
+ self . do_block_event ( height, |channel| channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger ) . map ( |a| ( a, Vec :: new ( ) ) ) ) ;
3371
+ }
3372
+
3373
+ /// Updates channel state with the current best blockchain tip. You should attempt to call this
3374
+ /// quickly after a new block becomes available, however it does not need to be called for each
3375
+ /// new block.
3376
+ pub fn update_best_block ( & self , header : & BlockHeader , height : u32 ) {
3377
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3378
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3379
+ // See the docs for `ChannelManagerReadArgs` for more.
3380
+
3381
+ let block_hash = header. block_hash ( ) ;
3382
+ log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3383
+
3384
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3385
+
3386
+ self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3387
+ * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3388
+
3389
+ self . do_block_event ( height, |channel| channel. update_best_block ( height, header. time ) ) ;
3356
3390
3357
3391
loop {
3358
3392
// Update last_node_announcement_serial to be the max of its current value and the
0 commit comments