Skip to content

Commit f526f10

Browse files
committed
Disconnect peers on pending channels not making progress
1 parent 926dc25 commit f526f10

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
@@ -583,9 +583,15 @@ pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
583583
/// * `EXPIRE_PREV_CONFIG_TICKS` = convergence_delay / tick_interval
584584
pub(crate) const EXPIRE_PREV_CONFIG_TICKS: usize = 5;
585585

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

19701998
// Internal utility functions for channels
@@ -3663,7 +3691,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
36633691
Some(self.get_last_revoke_and_ack())
36643692
} else { None };
36653693
let commitment_update = if self.context.monitor_pending_commitment_signed {
3666-
self.mark_awaiting_response();
3694+
self.context.mark_awaiting_response();
36673695
Some(self.get_last_commitment_update(logger))
36683696
} else { None };
36693697

@@ -3918,7 +3946,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
39183946
// the corresponding revoke_and_ack back yet.
39193947
let is_awaiting_remote_revoke = self.context.channel_state & ChannelState::AwaitingRemoteRevoke as u32 != 0;
39203948
if is_awaiting_remote_revoke && !self.is_awaiting_monitor_update() {
3921-
self.mark_awaiting_response();
3949+
self.context.mark_awaiting_response();
39223950
}
39233951
let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self.context.cur_counterparty_commitment_transaction_number + if is_awaiting_remote_revoke { 1 } else { 0 };
39243952

@@ -4084,28 +4112,6 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
40844112
}), None))
40854113
}
40864114

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

5783-
pub fn get_open_channel(&self, chain_hash: BlockHash) -> msgs::OpenChannel {
5789+
pub fn get_open_channel(&mut self, chain_hash: BlockHash) -> msgs::OpenChannel {
57845790
if !self.context.is_outbound() {
57855791
panic!("Tried to open a channel for an inbound channel?");
57865792
}
@@ -5792,6 +5798,10 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
57925798
panic!("Tried to send an open_channel for a channel that has already advanced");
57935799
}
57945800

5801+
// If we're not making progress on a new pending channel we'll want to disconnect. So we mark the
5802+
// channel as awaiting response.
5803+
self.context.mark_awaiting_response();
5804+
57955805
let first_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
57965806
let keys = self.context.get_holder_pubkeys();
57975807

@@ -5949,6 +5959,8 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
59495959

59505960
self.context.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
59515961
self.context.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
5962+
// We're no longer awaiting our peer to respond to our open_channel message.
5963+
self.context.sent_message_awaiting_response = None;
59525964

59535965
Ok(())
59545966
}
@@ -6320,6 +6332,9 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
63206332

63216333
self.context.user_id = user_id;
63226334
self.context.inbound_awaiting_accept = false;
6335+
// If we're not making progress on a new pending channel we'll want to disconnect. So we mark the
6336+
// channel as awaiting response.
6337+
self.context.mark_awaiting_response();
63236338

63246339
self.generate_accept_channel_message()
63256340
}
@@ -6477,6 +6492,10 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
64776492
self.context.channel_id = funding_txo.to_channel_id();
64786493
self.context.cur_counterparty_commitment_transaction_number -= 1;
64796494
self.context.cur_holder_commitment_transaction_number -= 1;
6495+
// We're no longer awaiting our peer to respond to our accept_channel message. Since we're now
6496+
// just waiting for the channel to be ready, we're done handling pending channel establishment
6497+
// timeouts.
6498+
self.context.sent_message_awaiting_response = None;
64806499

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

@@ -7524,7 +7543,7 @@ mod tests {
75247543

75257544
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
75267545
let config = UserConfig::default();
7527-
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();
7546+
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();
75287547

75297548
// Now change the fee so we can check that the fee in the open_channel message is the
75307549
// same as the old fee.
@@ -7744,7 +7763,7 @@ mod tests {
77447763
// Test that `OutboundV1Channel::new` creates a channel with the correct value for
77457764
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
77467765
// which is set to the lower bound + 1 (2%) of the `channel_value`.
7747-
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();
7766+
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();
77487767
let chan_1_value_msat = chan_1.context.channel_value_satoshis * 1000;
77497768
assert_eq!(chan_1.context.holder_max_htlc_value_in_flight_msat, (chan_1_value_msat as f64 * 0.02) as u64);
77507769

@@ -7829,7 +7848,7 @@ mod tests {
78297848

78307849
let mut outbound_node_config = UserConfig::default();
78317850
outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
7832-
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();
7851+
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();
78337852

78347853
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);
78357854
assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
@@ -8699,7 +8718,7 @@ mod tests {
86998718

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

87058724
let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
@@ -8743,7 +8762,7 @@ mod tests {
87438762
expected_channel_type.set_static_remote_key_required();
87448763
expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
87458764

8746-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8765+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
87478766
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
87488767
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
87498768
).unwrap();
@@ -8780,7 +8799,7 @@ mod tests {
87808799
let raw_init_features = static_remote_key_required | simple_anchors_required;
87818800
let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
87828801

8783-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8802+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
87848803
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
87858804
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
87868805
).unwrap();
@@ -8826,7 +8845,7 @@ mod tests {
88268845
// First, we'll try to open a channel between A and B where A requests a channel type for
88278846
// the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
88288847
// B as it's not supported by LDK.
8829-
let channel_a = OutboundV1Channel::<EnforcingSigner>::new(
8848+
let mut channel_a = OutboundV1Channel::<EnforcingSigner>::new(
88308849
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
88318850
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
88328851
).unwrap();

lightning/src/ln/channelmanager.rs

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

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

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

0 commit comments

Comments
 (0)