Skip to content

Commit 1926533

Browse files
committed
Disconnect peers on pending channels not making progress
1 parent 9a19af8 commit 1926533

File tree

3 files changed

+186
-52
lines changed

3 files changed

+186
-52
lines changed

lightning/src/ln/channel.rs

+55-36
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,15 @@ pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
579579
/// * `EXPIRE_PREV_CONFIG_TICKS` = convergence_delay / tick_interval
580580
pub(crate) const EXPIRE_PREV_CONFIG_TICKS: usize = 5;
581581

582-
/// The number of ticks that may elapse while we're waiting for a response to a
583-
/// [`msgs::RevokeAndACK`] or [`msgs::ChannelReestablish`] message before we attempt to disconnect
584-
/// them.
582+
/// The number of ticks that may elapse while we're waiting for a response to any of the following
583+
/// messages
584+
///
585+
/// [`msgs::RevokeAndACK`]
586+
/// [`msgs::ChannelReestablish`]
587+
/// [`msgs::OpenChannel`]
588+
/// [`msgs::AcceptChannel`]
589+
///
590+
/// before we attempt to disconnect them.
585591
///
586592
/// See [`ChannelContext::sent_message_awaiting_response`] for more information.
587593
pub(crate) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS: usize = 2;
@@ -1961,6 +1967,28 @@ impl<Signer: ChannelSigner> ChannelContext<Signer> {
19611967
self.update_time_counter += 1;
19621968
(monitor_update, dropped_outbound_htlcs)
19631969
}
1970+
1971+
// Marks a channel as waiting for a response from the counterparty. If it's not received
1972+
// [`DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`] after sending our own to them, then we'll attempt
1973+
// a reconnection.
1974+
fn mark_awaiting_response(&mut self) {
1975+
self.sent_message_awaiting_response = Some(0);
1976+
}
1977+
1978+
/// Determines whether we should disconnect the counterparty due to not receiving a response
1979+
/// within our expected timeframe.
1980+
///
1981+
/// This should be called on every [`super::channelmanager::ChannelManager::timer_tick_occurred`].
1982+
pub fn should_disconnect_peer_awaiting_response(&mut self) -> bool {
1983+
let ticks_elapsed = if let Some(ticks_elapsed) = self.sent_message_awaiting_response.as_mut() {
1984+
ticks_elapsed
1985+
} else {
1986+
// Don't disconnect when we're not waiting on a response.
1987+
return false;
1988+
};
1989+
*ticks_elapsed += 1;
1990+
*ticks_elapsed >= DISCONNECT_PEER_AWAITING_RESPONSE_TICKS
1991+
}
19641992
}
19651993

19661994
// Internal utility functions for channels
@@ -3659,7 +3687,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
36593687
Some(self.get_last_revoke_and_ack())
36603688
} else { None };
36613689
let commitment_update = if self.context.monitor_pending_commitment_signed {
3662-
self.mark_awaiting_response();
3690+
self.context.mark_awaiting_response();
36633691
Some(self.get_last_commitment_update(logger))
36643692
} else { None };
36653693

@@ -3914,7 +3942,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
39143942
// the corresponding revoke_and_ack back yet.
39153943
let is_awaiting_remote_revoke = self.context.channel_state & ChannelState::AwaitingRemoteRevoke as u32 != 0;
39163944
if is_awaiting_remote_revoke && !self.is_awaiting_monitor_update() {
3917-
self.mark_awaiting_response();
3945+
self.context.mark_awaiting_response();
39183946
}
39193947
let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self.context.cur_counterparty_commitment_transaction_number + if is_awaiting_remote_revoke { 1 } else { 0 };
39203948

@@ -4080,28 +4108,6 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
40804108
}), None))
40814109
}
40824110

4083-
// Marks a channel as waiting for a response from the counterparty. If it's not received
4084-
// [`DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`] after sending our own to them, then we'll attempt
4085-
// a reconnection.
4086-
fn mark_awaiting_response(&mut self) {
4087-
self.context.sent_message_awaiting_response = Some(0);
4088-
}
4089-
4090-
/// Determines whether we should disconnect the counterparty due to not receiving a response
4091-
/// within our expected timeframe.
4092-
///
4093-
/// This should be called on every [`super::channelmanager::ChannelManager::timer_tick_occurred`].
4094-
pub fn should_disconnect_peer_awaiting_response(&mut self) -> bool {
4095-
let ticks_elapsed = if let Some(ticks_elapsed) = self.context.sent_message_awaiting_response.as_mut() {
4096-
ticks_elapsed
4097-
} else {
4098-
// Don't disconnect when we're not waiting on a response.
4099-
return false;
4100-
};
4101-
*ticks_elapsed += 1;
4102-
*ticks_elapsed >= DISCONNECT_PEER_AWAITING_RESPONSE_TICKS
4103-
}
4104-
41054111
pub fn shutdown<SP: Deref>(
41064112
&mut self, signer_provider: &SP, their_features: &InitFeatures, msg: &msgs::Shutdown
41074113
) -> Result<(Option<msgs::Shutdown>, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
@@ -5013,7 +5019,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
50135019
log_info!(logger, "Sending a data_loss_protect with no previous remote per_commitment_secret for channel {}", log_bytes!(self.context.channel_id()));
50145020
[0;32]
50155021
};
5016-
self.mark_awaiting_response();
5022+
self.context.mark_awaiting_response();
50175023
msgs::ChannelReestablish {
50185024
channel_id: self.context.channel_id(),
50195025
// The protocol has two different commitment number concepts - the "commitment
@@ -5776,7 +5782,7 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
57765782
Ok(self.get_open_channel(chain_hash))
57775783
}
57785784

5779-
pub fn get_open_channel(&self, chain_hash: BlockHash) -> msgs::OpenChannel {
5785+
pub fn get_open_channel(&mut self, chain_hash: BlockHash) -> msgs::OpenChannel {
57805786
if !self.context.is_outbound() {
57815787
panic!("Tried to open a channel for an inbound channel?");
57825788
}
@@ -5788,6 +5794,10 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
57885794
panic!("Tried to send an open_channel for a channel that has already advanced");
57895795
}
57905796

5797+
// If we're not making progress on a new pending channel we'll want to disconnect. So we mark the
5798+
// channel as awaiting response.
5799+
self.context.mark_awaiting_response();
5800+
57915801
let first_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
57925802
let keys = self.context.get_holder_pubkeys();
57935803

@@ -5945,6 +5955,8 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
59455955

59465956
self.context.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
59475957
self.context.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
5958+
// We're no longer awaiting our peer to respond to our open_channel message.
5959+
self.context.sent_message_awaiting_response = None;
59485960

59495961
Ok(())
59505962
}
@@ -6316,6 +6328,9 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
63166328

63176329
self.context.user_id = user_id;
63186330
self.context.inbound_awaiting_accept = false;
6331+
// If we're not making progress on a new pending channel we'll want to disconnect. So we mark the
6332+
// channel as awaiting response.
6333+
self.context.mark_awaiting_response();
63196334

63206335
self.generate_accept_channel_message()
63216336
}
@@ -6473,6 +6488,10 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
64736488
self.context.channel_id = funding_txo.to_channel_id();
64746489
self.context.cur_counterparty_commitment_transaction_number -= 1;
64756490
self.context.cur_holder_commitment_transaction_number -= 1;
6491+
// We're no longer awaiting our peer to respond to our accept_channel message. Since we're now
6492+
// just waiting for the channel to be ready, we're done handling pending channel establishment
6493+
// timeouts.
6494+
self.context.sent_message_awaiting_response = None;
64766495

64776496
log_info!(logger, "Generated funding_signed for peer for channel {}", log_bytes!(self.context.channel_id()));
64786497

@@ -7520,7 +7539,7 @@ mod tests {
75207539

75217540
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
75227541
let config = UserConfig::default();
7523-
let node_a_chan = OutboundV1Channel::<EnforcingSigner>::new(&bounded_fee_estimator, &&keys_provider, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
7542+
let mut node_a_chan = OutboundV1Channel::<EnforcingSigner>::new(&bounded_fee_estimator, &&keys_provider, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
75247543

75257544
// Now change the fee so we can check that the fee in the open_channel message is the
75267545
// same as the old fee.
@@ -7740,7 +7759,7 @@ mod tests {
77407759
// Test that `OutboundV1Channel::new` creates a channel with the correct value for
77417760
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
77427761
// which is set to the lower bound + 1 (2%) of the `channel_value`.
7743-
let chan_1 = OutboundV1Channel::<EnforcingSigner>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_2_percent), 10000000, 100000, 42, &config_2_percent, 0, 42).unwrap();
7762+
let mut chan_1 = OutboundV1Channel::<EnforcingSigner>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_2_percent), 10000000, 100000, 42, &config_2_percent, 0, 42).unwrap();
77447763
let chan_1_value_msat = chan_1.context.channel_value_satoshis * 1000;
77457764
assert_eq!(chan_1.context.holder_max_htlc_value_in_flight_msat, (chan_1_value_msat as f64 * 0.02) as u64);
77467765

@@ -7825,7 +7844,7 @@ mod tests {
78257844

78267845
let mut outbound_node_config = UserConfig::default();
78277846
outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
7828-
let chan = OutboundV1Channel::<EnforcingSigner>::new(&&fee_est, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&outbound_node_config), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42).unwrap();
7847+
let mut chan = OutboundV1Channel::<EnforcingSigner>::new(&&fee_est, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&outbound_node_config), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42).unwrap();
78297848

78307849
let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.context.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64);
78317850
assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
@@ -8695,7 +8714,7 @@ mod tests {
86958714

86968715
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
86978716
let config = UserConfig::default();
8698-
let node_a_chan = OutboundV1Channel::<EnforcingSigner>::new(&feeest, &&keys_provider, &&keys_provider,
8717+
let mut node_a_chan = OutboundV1Channel::<EnforcingSigner>::new(&feeest, &&keys_provider, &&keys_provider,
86998718
node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42).unwrap();
87008719

87018720
let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
@@ -8739,7 +8758,7 @@ mod tests {
87398758
expected_channel_type.set_static_remote_key_required();
87408759
expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
87418760

8742-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8761+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
87438762
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
87448763
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
87458764
).unwrap();
@@ -8776,7 +8795,7 @@ mod tests {
87768795
let raw_init_features = static_remote_key_required | simple_anchors_required;
87778796
let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
87788797

8779-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8798+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
87808799
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
87818800
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
87828801
).unwrap();
@@ -8822,7 +8841,7 @@ mod tests {
88228841
// First, we'll try to open a channel between A and B where A requests a channel type for
88238842
// the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
88248843
// B as it's not supported by LDK.
8825-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8844+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
88268845
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
88278846
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
88288847
).unwrap();

lightning/src/ln/channelmanager.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,7 @@ where
22032203
.ok_or_else(|| APIError::APIMisuseError{ err: format!("Not connected to node: {}", their_network_key) })?;
22042204

22052205
let mut peer_state = peer_state_mutex.lock().unwrap();
2206-
let channel = {
2206+
let mut channel = {
22072207
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
22082208
let their_features = &peer_state.latest_features;
22092209
let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
@@ -4324,6 +4324,24 @@ where
43244324
let peer_state = &mut *peer_state_lock;
43254325
let pending_msg_events = &mut peer_state.pending_msg_events;
43264326
let counterparty_node_id = *counterparty_node_id;
4327+
4328+
let maybe_disconnect_peer_for_no_channel_progress =
4329+
|chan_id: &[u8; 32], context: &mut ChannelContext<<SP::Target as SignerProvider>::Signer>, pending_msg_events: &mut Vec<MessageSendEvent>| {
4330+
if context.should_disconnect_peer_awaiting_response() {
4331+
log_debug!(self.logger, "Disconnecting peer {} due to not making any progress on channel {}",
4332+
counterparty_node_id, log_bytes!(*chan_id));
4333+
pending_msg_events.push(MessageSendEvent::HandleError {
4334+
node_id: counterparty_node_id,
4335+
action: msgs::ErrorAction::DisconnectPeerWithWarning {
4336+
msg: msgs::WarningMessage {
4337+
channel_id: *chan_id,
4338+
data: "Disconnecting due to timeout awaiting response".to_owned(),
4339+
},
4340+
},
4341+
});
4342+
}
4343+
};
4344+
43274345
peer_state.channel_by_id.retain(|chan_id, chan| {
43284346
let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
43294347
if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
@@ -4373,23 +4391,16 @@ where
43734391
}
43744392

43754393
chan.context.maybe_expire_prev_config();
4376-
4377-
if chan.should_disconnect_peer_awaiting_response() {
4378-
log_debug!(self.logger, "Disconnecting peer {} due to not making any progress on channel {}",
4379-
counterparty_node_id, log_bytes!(*chan_id));
4380-
pending_msg_events.push(MessageSendEvent::HandleError {
4381-
node_id: counterparty_node_id,
4382-
action: msgs::ErrorAction::DisconnectPeerWithWarning {
4383-
msg: msgs::WarningMessage {
4384-
channel_id: *chan_id,
4385-
data: "Disconnecting due to timeout awaiting response".to_owned(),
4386-
},
4387-
},
4388-
});
4389-
}
4390-
4394+
maybe_disconnect_peer_for_no_channel_progress(chan_id, &mut chan.context, pending_msg_events);
43914395
true
43924396
});
4397+
for (chan_id, chan) in peer_state.outbound_v1_channel_by_id.iter_mut() {
4398+
maybe_disconnect_peer_for_no_channel_progress(chan_id, &mut chan.context, pending_msg_events);
4399+
}
4400+
for (chan_id, chan) in peer_state.inbound_v1_channel_by_id.iter_mut() {
4401+
maybe_disconnect_peer_for_no_channel_progress(chan_id, &mut chan.context, pending_msg_events);
4402+
4403+
}
43934404
if peer_state.ok_to_remove(true) {
43944405
pending_peers_awaiting_removal.push(counterparty_node_id);
43954406
}

0 commit comments

Comments
 (0)