@@ -251,6 +251,7 @@ enum HTLCUpdateAwaitingACK {
251
251
/// Note that PeerDisconnected can be set on both ChannelReady and FundingSent.
252
252
/// ChannelReady can then get all remaining flags set on it, until we finish shutdown, then we
253
253
/// move on to ShutdownComplete, at which point most calls into this channel are disallowed.
254
+ #[ derive( Copy , Clone ) ]
254
255
enum ChannelState {
255
256
/// Implies we have (or are prepared to) send our open_channel/accept_channel message
256
257
OurInitSent = 1 << 0 ,
@@ -479,6 +480,13 @@ pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
479
480
/// * `EXPIRE_PREV_CONFIG_TICKS` = convergence_delay / tick_interval
480
481
pub ( crate ) const EXPIRE_PREV_CONFIG_TICKS : usize = 5 ;
481
482
483
+ /// The number of ticks that may elapse while we're waiting for a response to a
484
+ /// [`msgs::RevokeAndACK`] or [`msgs::ChannelReestablish`] message before we attempt to disconnect
485
+ /// them.
486
+ ///
487
+ /// See [`Channel::sent_message_awaiting_response`] for more information.
488
+ pub ( crate ) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS : usize = 2 ;
489
+
482
490
struct PendingChannelMonitorUpdate {
483
491
update : ChannelMonitorUpdate ,
484
492
/// In some cases we need to delay letting the [`ChannelMonitorUpdate`] go until after an
@@ -715,6 +723,18 @@ pub(super) struct Channel<Signer: ChannelSigner> {
715
723
/// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
716
724
pub workaround_lnd_bug_4006 : Option < msgs:: ChannelReady > ,
717
725
726
+ /// An option set when we wish to track how many ticks we've remained in the same state for
727
+ /// after sending a message which requires a response. The first element in the tuple tracks the
728
+ /// state which we should no longer be in after receiving the response to the message we sent.
729
+ /// The second element tracks the number of ticks that have elapsed since the message was sent.
730
+ /// If the peer has yet to respond after reaching `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`, a
731
+ /// reconnection should be attempted to try to unblock the state machine.
732
+ ///
733
+ /// This behavior is mostly motivated by a few lnd bugs (such as the one outlined in
734
+ /// `workaround_lnd_bug_4006`), in which we don't receive a message we expect to in a timely
735
+ /// manner, which may lead to channels becoming unusable and/or force-closed.
736
+ sent_message_awaiting_response : Option < ( ChannelState , usize ) > ,
737
+
718
738
#[ cfg( any( test, fuzzing) ) ]
719
739
// When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
720
740
// corresponding HTLC on the inbound path. If, then, the outbound path channel is
@@ -1130,6 +1150,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
1130
1150
next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
1131
1151
1132
1152
workaround_lnd_bug_4006 : None ,
1153
+ sent_message_awaiting_response : None ,
1133
1154
1134
1155
latest_inbound_scid_alias : None ,
1135
1156
outbound_scid_alias,
@@ -1489,6 +1510,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
1489
1510
next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
1490
1511
1491
1512
workaround_lnd_bug_4006 : None ,
1513
+ sent_message_awaiting_response : None ,
1492
1514
1493
1515
latest_inbound_scid_alias : None ,
1494
1516
outbound_scid_alias,
@@ -3526,6 +3548,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
3526
3548
// OK, we step the channel here and *then* if the new generation fails we can fail the
3527
3549
// channel based on that, but stepping stuff here should be safe either way.
3528
3550
self . channel_state &= !( ChannelState :: AwaitingRemoteRevoke as u32 ) ;
3551
+ self . sent_message_awaiting_response = None ;
3529
3552
self . counterparty_prev_commitment_point = self . counterparty_cur_commitment_point ;
3530
3553
self . counterparty_cur_commitment_point = Some ( msg. next_per_commitment_point ) ;
3531
3554
self . cur_counterparty_commitment_transaction_number -= 1 ;
@@ -3841,6 +3864,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
3841
3864
}
3842
3865
}
3843
3866
3867
+ self . sent_message_awaiting_response = None ;
3868
+
3844
3869
self . channel_state |= ChannelState :: PeerDisconnected as u32 ;
3845
3870
log_trace ! ( logger, "Peer disconnection resulted in {} remote-announced HTLC drops on channel {}" , inbound_drop_count, log_bytes!( self . channel_id( ) ) ) ;
3846
3871
}
@@ -3943,6 +3968,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
3943
3968
Some ( self . get_last_revoke_and_ack ( ) )
3944
3969
} else { None } ;
3945
3970
let commitment_update = if self . monitor_pending_commitment_signed {
3971
+ self . mark_awaiting_remote_revoke ( ) ;
3946
3972
Some ( self . get_last_commitment_update ( logger) )
3947
3973
} else { None } ;
3948
3974
@@ -4132,6 +4158,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
4132
4158
// Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all
4133
4159
// remaining cases either succeed or ErrorMessage-fail).
4134
4160
self . channel_state &= !( ChannelState :: PeerDisconnected as u32 ) ;
4161
+ self . sent_message_awaiting_response = None ;
4135
4162
4136
4163
let shutdown_msg = if self . channel_state & ( ChannelState :: LocalShutdownSent as u32 ) != 0 {
4137
4164
assert ! ( self . shutdown_scriptpubkey. is_some( ) ) ;
@@ -4192,7 +4219,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
4192
4219
// revoke_and_ack, not on sending commitment_signed, so we add one if have
4193
4220
// AwaitingRemoteRevoke set, which indicates we sent a commitment_signed but haven't gotten
4194
4221
// the corresponding revoke_and_ack back yet.
4195
- let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self . cur_counterparty_commitment_transaction_number + if ( self . channel_state & ChannelState :: AwaitingRemoteRevoke as u32 ) != 0 { 1 } else { 0 } ;
4222
+ let is_awaiting_remote_revoke = self . channel_state & ChannelState :: AwaitingRemoteRevoke as u32 != 0 ;
4223
+ if is_awaiting_remote_revoke {
4224
+ self . mark_awaiting_remote_revoke ( ) ;
4225
+ }
4226
+ let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self . cur_counterparty_commitment_transaction_number + if is_awaiting_remote_revoke { 1 } else { 0 } ;
4196
4227
4197
4228
let channel_ready = if msg. next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self . cur_holder_commitment_transaction_number == 1 {
4198
4229
// We should never have to worry about MonitorUpdateInProgress resending ChannelReady
@@ -4361,6 +4392,41 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
4361
4392
} ) , None ) )
4362
4393
}
4363
4394
4395
+ // Marks the channels as waiting for the counterparty's [`msgs::ChannelReestablish`] message.
4396
+ // If it's not received [`DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`] after sending our own
4397
+ // to them, then we'll attempt a reconnection.
4398
+ pub fn mark_awaiting_channel_reestablish ( & mut self ) {
4399
+ self . sent_message_awaiting_response = Some ( ( ChannelState :: PeerDisconnected , 0 ) ) ;
4400
+ }
4401
+
4402
+ // Marks the channels as waiting for the counterparty's [`msgs::RevokeAndACK`] message.
4403
+ // If it's not received [`DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`] after sending our own
4404
+ // to them, then we'll attempt a reconnection.
4405
+ fn mark_awaiting_remote_revoke ( & mut self ) {
4406
+ self . sent_message_awaiting_response = Some ( ( ChannelState :: AwaitingRemoteRevoke , 0 ) ) ;
4407
+ }
4408
+
4409
+ /// Determines whether we should disconnect the counterparty due to not receiving a response
4410
+ /// within our expected timeframe.
4411
+ ///
4412
+ /// This should be called on every [`super::channelmanager::ChannelManager::timer_tick_occurred`].
4413
+ pub fn should_disconnect_peer_awaiting_response ( & mut self ) -> bool {
4414
+ let ( state, ticks_elapsed) = if let Some ( ticks_elapsed) = self . sent_message_awaiting_response . as_mut ( ) {
4415
+ ticks_elapsed
4416
+ } else {
4417
+ // Don't disconnect when we're not waiting on a response.
4418
+ return false ;
4419
+ } ;
4420
+ * ticks_elapsed += 1 ;
4421
+ if * ticks_elapsed < DISCONNECT_PEER_AWAITING_RESPONSE_TICKS {
4422
+ // Don't disconnect yet, they still have time left.
4423
+ return false ;
4424
+ }
4425
+ // `state` represents the `ChannelState` variant that should no longer be present after
4426
+ // processing the counterparty's response.
4427
+ self . channel_state & * state as u32 == * state as u32
4428
+ }
4429
+
4364
4430
pub fn shutdown < SP : Deref > (
4365
4431
& mut self , signer_provider : & SP , their_features : & InitFeatures , msg : & msgs:: Shutdown
4366
4432
) -> Result < ( Option < msgs:: Shutdown > , Option < & ChannelMonitorUpdate > , Vec < ( HTLCSource , PaymentHash ) > ) , ChannelError >
@@ -7090,6 +7156,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7090
7156
next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
7091
7157
7092
7158
workaround_lnd_bug_4006 : None ,
7159
+ sent_message_awaiting_response : None ,
7093
7160
7094
7161
latest_inbound_scid_alias,
7095
7162
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
0 commit comments