@@ -1004,16 +1004,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1004
1004
}
1005
1005
}
1006
1006
1007
- fn force_close_channel_with_peer ( & self , channel_id : & [ u8 ; 32 ] , peer_node_id : Option < & PublicKey > ) -> Result < ( ) , APIError > {
1007
+ fn force_close_channel_with_peer ( & self , channel_id : & [ u8 ; 32 ] , peer_node_id : Option < & PublicKey > ) -> Result < PublicKey , APIError > {
1008
1008
let mut chan = {
1009
1009
let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1010
1010
let channel_state = & mut * channel_state_lock;
1011
1011
if let hash_map:: Entry :: Occupied ( chan) = channel_state. by_id . entry ( channel_id. clone ( ) ) {
1012
1012
if let Some ( node_id) = peer_node_id {
1013
1013
if chan. get ( ) . get_counterparty_node_id ( ) != * node_id {
1014
- // Error or Ok here doesn't matter - the result is only exposed publicly
1015
- // when peer_node_id is None anyway.
1016
- return Ok ( ( ) ) ;
1014
+ return Err ( APIError :: ChannelUnavailable { err : "No such channel" . to_owned ( ) } ) ;
1017
1015
}
1018
1016
}
1019
1017
if let Some ( short_id) = chan. get ( ) . get_short_channel_id ( ) {
@@ -1033,14 +1031,27 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1033
1031
} ) ;
1034
1032
}
1035
1033
1036
- Ok ( ( ) )
1034
+ Ok ( chan . get_counterparty_node_id ( ) )
1037
1035
}
1038
1036
1039
1037
/// Force closes a channel, immediately broadcasting the latest local commitment transaction to
1040
1038
/// the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager.
1041
1039
pub fn force_close_channel ( & self , channel_id : & [ u8 ; 32 ] ) -> Result < ( ) , APIError > {
1042
1040
let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
1043
- self . force_close_channel_with_peer ( channel_id, None )
1041
+ match self . force_close_channel_with_peer ( channel_id, None ) {
1042
+ Ok ( counterparty_node_id) => {
1043
+ self . channel_state . lock ( ) . unwrap ( ) . pending_msg_events . push (
1044
+ events:: MessageSendEvent :: HandleError {
1045
+ node_id : counterparty_node_id,
1046
+ action : msgs:: ErrorAction :: SendErrorMessage {
1047
+ msg : msgs:: ErrorMessage { channel_id : * channel_id, data : "Channel force-closed" . to_owned ( ) }
1048
+ } ,
1049
+ }
1050
+ ) ;
1051
+ Ok ( ( ) )
1052
+ } ,
1053
+ Err ( e) => Err ( e)
1054
+ }
1044
1055
}
1045
1056
1046
1057
/// Force close all channels, immediately broadcasting the latest local commitment transaction
@@ -3196,6 +3207,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3196
3207
msg : update
3197
3208
} ) ;
3198
3209
}
3210
+ pending_msg_events. push ( events:: MessageSendEvent :: HandleError {
3211
+ node_id : chan. get_counterparty_node_id ( ) ,
3212
+ action : msgs:: ErrorAction :: SendErrorMessage {
3213
+ msg : msgs:: ErrorMessage { channel_id : chan. channel_id ( ) , data : "Channel force-closed" . to_owned ( ) }
3214
+ } ,
3215
+ } ) ;
3199
3216
}
3200
3217
} ,
3201
3218
}
@@ -3278,12 +3295,26 @@ where
3278
3295
L :: Target : Logger ,
3279
3296
{
3280
3297
fn block_connected ( & self , block : & Block , height : u32 ) {
3298
+ assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , block. header. prev_blockhash,
3299
+ "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3300
+ assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3301
+ "Blocks must be connected in chain-order - the connected block height must be one greater than the previous height" ) ;
3281
3302
let txdata: Vec < _ > = block. txdata . iter ( ) . enumerate ( ) . collect ( ) ;
3282
- ChannelManager :: block_connected ( self , & block. header , & txdata, height) ;
3303
+ self . transactions_confirmed ( & block. header , height, & txdata) ;
3304
+ self . update_best_block ( & block. header , height) ;
3283
3305
}
3284
3306
3285
- fn block_disconnected ( & self , header : & BlockHeader , _height : u32 ) {
3286
- ChannelManager :: block_disconnected ( self , header) ;
3307
+ fn block_disconnected ( & self , header : & BlockHeader , height : u32 ) {
3308
+ assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , header. block_hash( ) ,
3309
+ "Blocks must be disconnected in chain-order - the disconnected header must be the last connected header" ) ;
3310
+
3311
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3312
+ let new_height = self . latest_block_height . fetch_sub ( 1 , Ordering :: AcqRel ) as u32 - 1 ;
3313
+ assert_eq ! ( new_height, height - 1 ,
3314
+ "Blocks must be disconnected in chain-order - the disconnected block must have the correct height" ) ;
3315
+ * self . last_block_hash . write ( ) . unwrap ( ) = header. prev_blockhash ;
3316
+
3317
+ self . do_chain_event ( new_height, |channel| channel. update_best_block ( new_height, header. time ) ) ;
3287
3318
}
3288
3319
}
3289
3320
@@ -3294,22 +3325,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3294
3325
F :: Target : FeeEstimator ,
3295
3326
L :: Target : Logger ,
3296
3327
{
3297
- /// Updates channel state based on transactions seen in a connected block.
3298
- pub fn block_connected ( & self , header : & BlockHeader , txdata : & TransactionData , height : u32 ) {
3328
+ fn do_chain_event < FN : Fn ( & mut Channel < Signer > ) -> Result < ( Option < msgs :: FundingLocked > , Vec < ( HTLCSource , PaymentHash ) > ) , msgs :: ErrorMessage > >
3329
+ ( & self , height : u32 , f : FN ) {
3299
3330
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3300
3331
// during initialization prior to the chain_monitor being fully configured in some cases.
3301
3332
// See the docs for `ChannelManagerReadArgs` for more.
3302
- let block_hash = header. block_hash ( ) ;
3303
- log_trace ! ( self . logger, "Block {} at height {} connected" , block_hash, height) ;
3304
-
3305
- let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3306
-
3307
- assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , header. prev_blockhash,
3308
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3309
- assert_eq ! ( self . latest_block_height. load( Ordering :: Acquire ) as u64 , height as u64 - 1 ,
3310
- "Blocks must be connected in chain-order - the connected header must build on the last connected header" ) ;
3311
- self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3312
- * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3313
3333
3314
3334
let mut failed_channels = Vec :: new ( ) ;
3315
3335
let mut timed_out_htlcs = Vec :: new ( ) ;
@@ -3319,7 +3339,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3319
3339
let short_to_id = & mut channel_state. short_to_id ;
3320
3340
let pending_msg_events = & mut channel_state. pending_msg_events ;
3321
3341
channel_state. by_id . retain ( |_, channel| {
3322
- let res = channel . block_connected ( header , txdata , height ) ;
3342
+ let res = f ( channel ) ;
3323
3343
if let Ok ( ( chan_res, mut timed_out_pending_htlcs) ) = res {
3324
3344
for ( source, payment_hash) in timed_out_pending_htlcs. drain ( ..) {
3325
3345
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
@@ -3345,32 +3365,23 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3345
3365
short_to_id. insert ( channel. get_short_channel_id ( ) . unwrap ( ) , channel. channel_id ( ) ) ;
3346
3366
}
3347
3367
} else if let Err ( e) = res {
3368
+ if let Some ( short_id) = channel. get_short_channel_id ( ) {
3369
+ short_to_id. remove ( & short_id) ;
3370
+ }
3371
+ // It looks like our counterparty went on-chain or funding transaction was
3372
+ // reorged out of the main chain. Close the channel.
3373
+ failed_channels. push ( channel. force_shutdown ( true ) ) ;
3374
+ if let Ok ( update) = self . get_channel_update ( & channel) {
3375
+ pending_msg_events. push ( events:: MessageSendEvent :: BroadcastChannelUpdate {
3376
+ msg : update
3377
+ } ) ;
3378
+ }
3348
3379
pending_msg_events. push ( events:: MessageSendEvent :: HandleError {
3349
3380
node_id : channel. get_counterparty_node_id ( ) ,
3350
3381
action : msgs:: ErrorAction :: SendErrorMessage { msg : e } ,
3351
3382
} ) ;
3352
3383
return false ;
3353
3384
}
3354
- if let Some ( funding_txo) = channel. get_funding_txo ( ) {
3355
- for & ( _, tx) in txdata. iter ( ) {
3356
- for inp in tx. input . iter ( ) {
3357
- if inp. previous_output == funding_txo. into_bitcoin_outpoint ( ) {
3358
- log_trace ! ( self . logger, "Detected channel-closing tx {} spending {}:{}, closing channel {}" , tx. txid( ) , inp. previous_output. txid, inp. previous_output. vout, log_bytes!( channel. channel_id( ) ) ) ;
3359
- if let Some ( short_id) = channel. get_short_channel_id ( ) {
3360
- short_to_id. remove ( & short_id) ;
3361
- }
3362
- // It looks like our counterparty went on-chain. Close the channel.
3363
- failed_channels. push ( channel. force_shutdown ( true ) ) ;
3364
- if let Ok ( update) = self . get_channel_update ( & channel) {
3365
- pending_msg_events. push ( events:: MessageSendEvent :: BroadcastChannelUpdate {
3366
- msg : update
3367
- } ) ;
3368
- }
3369
- return false ;
3370
- }
3371
- }
3372
- }
3373
- }
3374
3385
true
3375
3386
} ) ;
3376
3387
@@ -3399,6 +3410,64 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3399
3410
for ( source, payment_hash, reason) in timed_out_htlcs. drain ( ..) {
3400
3411
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , source, & payment_hash, reason) ;
3401
3412
}
3413
+ }
3414
+
3415
+ /// Updates channel state to take note of transactions which were confirmed in the given block
3416
+ /// at the given height.
3417
+ ///
3418
+ /// Note that you must still call (or have called) [`update_best_block`] with the block
3419
+ /// information which is included here.
3420
+ ///
3421
+ /// This method may be called before or after [`update_best_block`] for a given block's
3422
+ /// transaction data and may be called multiple times with additional transaction data for a
3423
+ /// given block.
3424
+ ///
3425
+ /// This method may be called for a previous block after an [`update_best_block`] call has
3426
+ /// been made for a later block, however it must *not* be called with transaction data from a
3427
+ /// block which is no longer in the best chain (ie where [`update_best_block`] has already
3428
+ /// been informed about a blockchain reorganization which no longer includes the block which
3429
+ /// corresponds to `header`).
3430
+ ///
3431
+ /// [`update_best_block`]: `Self::update_best_block`
3432
+ pub fn transactions_confirmed ( & self , header : & BlockHeader , height : u32 , txdata : & TransactionData ) {
3433
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3434
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3435
+ // See the docs for `ChannelManagerReadArgs` for more.
3436
+
3437
+ let block_hash = header. block_hash ( ) ;
3438
+ log_trace ! ( self . logger, "{} transactions included in block {} at height {} provided" , txdata. len( ) , block_hash, height) ;
3439
+
3440
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3441
+ self . do_chain_event ( height, |channel| channel. transactions_confirmed ( & block_hash, height, txdata, & self . logger ) . map ( |a| ( a, Vec :: new ( ) ) ) ) ;
3442
+ }
3443
+
3444
+ /// Updates channel state with the current best blockchain tip. You should attempt to call this
3445
+ /// quickly after a new block becomes available, however if multiple new blocks become
3446
+ /// available at the same time, only a single `update_best_block()` call needs to be made.
3447
+ ///
3448
+ /// This method should also be called immediately after any block disconnections, once at the
3449
+ /// reorganization fork point, and once with the new chain tip. Calling this method at the
3450
+ /// blockchain reorganization fork point ensures we learn when a funding transaction which was
3451
+ /// previously confirmed is reorganized out of the blockchain, ensuring we do not continue to
3452
+ /// accept payments which cannot be enforced on-chain.
3453
+ ///
3454
+ /// In both the block-connection and block-disconnection case, this method may be called either
3455
+ /// once per block connected or disconnected, or simply at the fork point and new tip(s),
3456
+ /// skipping any intermediary blocks.
3457
+ pub fn update_best_block ( & self , header : & BlockHeader , height : u32 ) {
3458
+ // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
3459
+ // during initialization prior to the chain_monitor being fully configured in some cases.
3460
+ // See the docs for `ChannelManagerReadArgs` for more.
3461
+
3462
+ let block_hash = header. block_hash ( ) ;
3463
+ log_trace ! ( self . logger, "New best block: {} at height {}" , block_hash, height) ;
3464
+
3465
+ let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3466
+
3467
+ self . latest_block_height . store ( height as usize , Ordering :: Release ) ;
3468
+ * self . last_block_hash . write ( ) . unwrap ( ) = block_hash;
3469
+
3470
+ self . do_chain_event ( height, |channel| channel. update_best_block ( height, header. time ) ) ;
3402
3471
3403
3472
loop {
3404
3473
// Update last_node_announcement_serial to be the max of its current value and the
@@ -3414,48 +3483,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3414
3483
}
3415
3484
}
3416
3485
3417
- /// Updates channel state based on a disconnected block.
3418
- ///
3419
- /// If necessary, the channel may be force-closed without letting the counterparty participate
3420
- /// in the shutdown.
3421
- pub fn block_disconnected ( & self , header : & BlockHeader ) {
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
- let _persistence_guard = PersistenceNotifierGuard :: new ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3426
-
3427
- assert_eq ! ( * self . last_block_hash. read( ) . unwrap( ) , header. block_hash( ) ,
3428
- "Blocks must be disconnected in chain-order - the disconnected header must be the last connected header" ) ;
3429
- self . latest_block_height . fetch_sub ( 1 , Ordering :: AcqRel ) ;
3430
- * self . last_block_hash . write ( ) . unwrap ( ) = header. prev_blockhash ;
3431
-
3432
- let mut failed_channels = Vec :: new ( ) ;
3433
- {
3434
- let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
3435
- let channel_state = & mut * channel_lock;
3436
- let short_to_id = & mut channel_state. short_to_id ;
3437
- let pending_msg_events = & mut channel_state. pending_msg_events ;
3438
- channel_state. by_id . retain ( |_, v| {
3439
- if v. block_disconnected ( header) {
3440
- if let Some ( short_id) = v. get_short_channel_id ( ) {
3441
- short_to_id. remove ( & short_id) ;
3442
- }
3443
- failed_channels. push ( v. force_shutdown ( true ) ) ;
3444
- if let Ok ( update) = self . get_channel_update ( & v) {
3445
- pending_msg_events. push ( events:: MessageSendEvent :: BroadcastChannelUpdate {
3446
- msg : update
3447
- } ) ;
3448
- }
3449
- false
3450
- } else {
3451
- true
3452
- }
3453
- } ) ;
3454
- }
3455
-
3456
- self . handle_init_event_channel_failures ( failed_channels) ;
3457
- }
3458
-
3459
3486
/// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
3460
3487
/// indicating whether persistence is necessary. Only one listener on
3461
3488
/// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken
0 commit comments