@@ -479,6 +479,13 @@ pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
479479/// * `EXPIRE_PREV_CONFIG_TICKS` = convergence_delay / tick_interval
480480pub ( crate ) const EXPIRE_PREV_CONFIG_TICKS : usize = 5 ;
481481
482+ /// The number of ticks that may elapse while we're waiting for a response to a
483+ /// [`msgs::RevokeAndACK`] or [`msgs::ChannelReestablish`] message before we attempt to disconnect
484+ /// them.
485+ ///
486+ /// See [`Channel::sent_message_awaiting_response`] for more information.
487+ pub ( crate ) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS : usize = 2 ;
488+
482489struct PendingChannelMonitorUpdate {
483490 update : ChannelMonitorUpdate ,
484491 /// In some cases we need to delay letting the [`ChannelMonitorUpdate`] go until after an
@@ -715,6 +722,19 @@ pub(super) struct Channel<Signer: ChannelSigner> {
715722 /// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
716723 pub workaround_lnd_bug_4006 : Option < msgs:: ChannelReady > ,
717724
725+ /// An option set when we wish to track how many ticks have elapsed while waiting for a response
726+ /// from our counterparty after sending a message. If the peer has yet to respond after reaching
727+ /// `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`, a reconnection should be attempted to try to
728+ /// unblock the state machine.
729+ ///
730+ /// This behavior is mostly motivated by a lnd bug in which we don't receive a message we expect
731+ /// to in a timely manner, which may lead to channels becoming unusable and/or force-closed. An
732+ /// example of such can be found at <https://github.com/lightningnetwork/lnd/issues/7682>.
733+ ///
734+ /// This is currently only used when waiting for a [`msgs::ChannelReestablish`] or
735+ /// [`msgs::RevokeAndACK`] message from the counterparty.
736+ sent_message_awaiting_response : Option < usize > ,
737+
718738 #[ cfg( any( test, fuzzing) ) ]
719739 // When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
720740 // corresponding HTLC on the inbound path. If, then, the outbound path channel is
@@ -1130,6 +1150,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
11301150 next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
11311151
11321152 workaround_lnd_bug_4006 : None ,
1153+ sent_message_awaiting_response : None ,
11331154
11341155 latest_inbound_scid_alias : None ,
11351156 outbound_scid_alias,
@@ -1489,6 +1510,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
14891510 next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
14901511
14911512 workaround_lnd_bug_4006 : None ,
1513+ sent_message_awaiting_response : None ,
14921514
14931515 latest_inbound_scid_alias : None ,
14941516 outbound_scid_alias,
@@ -3526,6 +3548,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
35263548 // OK, we step the channel here and *then* if the new generation fails we can fail the
35273549 // channel based on that, but stepping stuff here should be safe either way.
35283550 self . channel_state &= !( ChannelState :: AwaitingRemoteRevoke as u32 ) ;
3551+ self . sent_message_awaiting_response = None ;
35293552 self . counterparty_prev_commitment_point = self . counterparty_cur_commitment_point ;
35303553 self . counterparty_cur_commitment_point = Some ( msg. next_per_commitment_point ) ;
35313554 self . cur_counterparty_commitment_transaction_number -= 1 ;
@@ -3841,6 +3864,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
38413864 }
38423865 }
38433866
3867+ self . sent_message_awaiting_response = None ;
3868+
38443869 self . channel_state |= ChannelState :: PeerDisconnected as u32 ;
38453870 log_trace ! ( logger, "Peer disconnection resulted in {} remote-announced HTLC drops on channel {}" , inbound_drop_count, log_bytes!( self . channel_id( ) ) ) ;
38463871 }
@@ -3943,6 +3968,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
39433968 Some ( self . get_last_revoke_and_ack ( ) )
39443969 } else { None } ;
39453970 let commitment_update = if self . monitor_pending_commitment_signed {
3971+ self . mark_awaiting_response ( ) ;
39463972 Some ( self . get_last_commitment_update ( logger) )
39473973 } else { None } ;
39483974
@@ -4132,6 +4158,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
41324158 // Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all
41334159 // remaining cases either succeed or ErrorMessage-fail).
41344160 self . channel_state &= !( ChannelState :: PeerDisconnected as u32 ) ;
4161+ self . sent_message_awaiting_response = None ;
41354162
41364163 let shutdown_msg = if self . channel_state & ( ChannelState :: LocalShutdownSent as u32 ) != 0 {
41374164 assert ! ( self . shutdown_scriptpubkey. is_some( ) ) ;
@@ -4192,7 +4219,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
41924219 // revoke_and_ack, not on sending commitment_signed, so we add one if have
41934220 // AwaitingRemoteRevoke set, which indicates we sent a commitment_signed but haven't gotten
41944221 // 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 && !self . is_awaiting_monitor_update ( ) {
4224+ self . mark_awaiting_response ( ) ;
4225+ }
4226+ let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self . cur_counterparty_commitment_transaction_number + if is_awaiting_remote_revoke { 1 } else { 0 } ;
41964227
41974228 let channel_ready = if msg. next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self . cur_holder_commitment_transaction_number == 1 {
41984229 // We should never have to worry about MonitorUpdateInProgress resending ChannelReady
@@ -4361,6 +4392,28 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
43614392 } ) , None ) )
43624393 }
43634394
4395+ // Marks a channel as waiting for a response from the counterparty. If it's not received
4396+ // [`DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`] after sending our own to them, then we'll attempt
4397+ // a reconnection.
4398+ fn mark_awaiting_response ( & mut self ) {
4399+ self . sent_message_awaiting_response = Some ( 0 ) ;
4400+ }
4401+
4402+ /// Determines whether we should disconnect the counterparty due to not receiving a response
4403+ /// within our expected timeframe.
4404+ ///
4405+ /// This should be called on every [`super::channelmanager::ChannelManager::timer_tick_occurred`].
4406+ pub fn should_disconnect_peer_awaiting_response ( & mut self ) -> bool {
4407+ let ticks_elapsed = if let Some ( ticks_elapsed) = self . sent_message_awaiting_response . as_mut ( ) {
4408+ ticks_elapsed
4409+ } else {
4410+ // Don't disconnect when we're not waiting on a response.
4411+ return false ;
4412+ } ;
4413+ * ticks_elapsed += 1 ;
4414+ * ticks_elapsed >= DISCONNECT_PEER_AWAITING_RESPONSE_TICKS
4415+ }
4416+
43644417 pub fn shutdown < SP : Deref > (
43654418 & mut self , signer_provider : & SP , their_features : & InitFeatures , msg : & msgs:: Shutdown
43664419 ) -> Result < ( Option < msgs:: Shutdown > , Option < & ChannelMonitorUpdate > , Vec < ( HTLCSource , PaymentHash ) > ) , ChannelError >
@@ -5733,7 +5786,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
57335786
57345787 /// May panic if called on a channel that wasn't immediately-previously
57355788 /// self.remove_uncommitted_htlcs_and_mark_paused()'d
5736- pub fn get_channel_reestablish < L : Deref > ( & self , logger : & L ) -> msgs:: ChannelReestablish where L :: Target : Logger {
5789+ pub fn get_channel_reestablish < L : Deref > ( & mut self , logger : & L ) -> msgs:: ChannelReestablish where L :: Target : Logger {
57375790 assert_eq ! ( self . channel_state & ChannelState :: PeerDisconnected as u32 , ChannelState :: PeerDisconnected as u32 ) ;
57385791 assert_ne ! ( self . cur_counterparty_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER ) ;
57395792 // Prior to static_remotekey, my_current_per_commitment_point was critical to claiming
@@ -5752,6 +5805,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
57525805 log_info ! ( logger, "Sending a data_loss_protect with no previous remote per_commitment_secret for channel {}" , log_bytes!( self . channel_id( ) ) ) ;
57535806 [ 0 ; 32 ]
57545807 } ;
5808+ self . mark_awaiting_response ( ) ;
57555809 msgs:: ChannelReestablish {
57565810 channel_id : self . channel_id ( ) ,
57575811 // The protocol has two different commitment number concepts - the "commitment
@@ -7090,6 +7144,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
70907144 next_remote_commitment_tx_fee_info_cached : Mutex :: new ( None ) ,
70917145
70927146 workaround_lnd_bug_4006 : None ,
7147+ sent_message_awaiting_response : None ,
70937148
70947149 latest_inbound_scid_alias,
70957150 // Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
0 commit comments