Skip to content

Commit eb2a948

Browse files
committed
Stop failing back HTLCs on peer disconnection
Previously, if we got disconnected from a peer while there were HTLCs pending forwarding in the holding cell, we'd clear them and fail them all backwards. This is largely fine, but since we now have support for handling such HTLCs on reconnect, we might as well not, instead relying on our timeout logic to fail them backwards if it takes too long to forward them.
1 parent 3c85add commit eb2a948

File tree

2 files changed

+17
-61
lines changed

2 files changed

+17
-61
lines changed

lightning/src/ln/channel.rs

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,13 +2685,11 @@ impl<Signer: Sign> Channel<Signer> {
26852685
/// implicitly dropping) and the payment_hashes of HTLCs we tried to add but are dropping.
26862686
/// No further message handling calls may be made until a channel_reestablish dance has
26872687
/// completed.
2688-
pub fn remove_uncommitted_htlcs_and_mark_paused<L: Deref>(&mut self, logger: &L) -> Vec<(HTLCSource, PaymentHash)> where L::Target: Logger {
2689-
let mut outbound_drops = Vec::new();
2690-
2688+
pub fn remove_uncommitted_htlcs_and_mark_paused<L: Deref>(&mut self, logger: &L) where L::Target: Logger {
26912689
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
26922690
if self.channel_state < ChannelState::FundingSent as u32 {
26932691
self.channel_state = ChannelState::ShutdownComplete as u32;
2694-
return outbound_drops;
2692+
return;
26952693
}
26962694
// Upon reconnect we have to start the closing_signed dance over, but shutdown messages
26972695
// will be retransmitted.
@@ -2734,23 +2732,8 @@ impl<Signer: Sign> Channel<Signer> {
27342732
}
27352733
}
27362734

2737-
self.holding_cell_htlc_updates.retain(|htlc_update| {
2738-
match htlc_update {
2739-
// Note that currently on channel reestablish we assert that there are
2740-
// no holding cell HTLC update_adds, so if in the future we stop
2741-
// dropping added HTLCs here and failing them backwards, then there will
2742-
// need to be corresponding changes made in the Channel's re-establish
2743-
// logic.
2744-
&HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => {
2745-
outbound_drops.push((source.clone(), payment_hash.clone()));
2746-
false
2747-
},
2748-
&HTLCUpdateAwaitingACK::ClaimHTLC {..} | &HTLCUpdateAwaitingACK::FailHTLC {..} => true,
2749-
}
2750-
});
27512735
self.channel_state |= ChannelState::PeerDisconnected as u32;
2752-
log_debug!(logger, "Peer disconnection resulted in {} remote-announced HTLC drops and {} waiting-to-locally-announced HTLC drops on channel {}", outbound_drops.len(), inbound_drop_count, log_bytes!(self.channel_id()));
2753-
outbound_drops
2736+
log_debug!(logger, "Peer disconnection resulted in {} remote-announced HTLC drops on channel {}", inbound_drop_count, log_bytes!(self.channel_id()));
27542737
}
27552738

27562739
/// Indicates that a ChannelMonitor update failed to be stored by the client and further
@@ -2909,7 +2892,7 @@ impl<Signer: Sign> Channel<Signer> {
29092892

29102893
/// May panic if some calls other than message-handling calls (which will all Err immediately)
29112894
/// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
2912-
pub fn channel_reestablish<L: Deref>(&mut self, msg: &msgs::ChannelReestablish, logger: &L) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, Option<ChannelMonitorUpdate>, RAACommitmentOrder, Option<msgs::Shutdown>), ChannelError> where L::Target: Logger {
2895+
pub fn channel_reestablish<L: Deref>(&mut self, msg: &msgs::ChannelReestablish, logger: &L) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, Option<ChannelMonitorUpdate>, RAACommitmentOrder, Vec<(HTLCSource, PaymentHash)>, Option<msgs::Shutdown>), ChannelError> where L::Target: Logger {
29132896
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
29142897
// While BOLT 2 doesn't indicate explicitly we should error this channel here, it
29152898
// almost certainly indicates we are going to end up out-of-sync in some way, so we
@@ -2960,15 +2943,15 @@ impl<Signer: Sign> Channel<Signer> {
29602943
return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet".to_owned()));
29612944
}
29622945
// Short circuit the whole handler as there is nothing we can resend them
2963-
return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
2946+
return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, Vec::new(), shutdown_msg));
29642947
}
29652948

29662949
// We have OurFundingLocked set!
29672950
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
29682951
return Ok((Some(msgs::FundingLocked {
29692952
channel_id: self.channel_id(),
29702953
next_per_commitment_point,
2971-
}), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
2954+
}), None, None, None, RAACommitmentOrder::CommitmentFirst, Vec::new(), shutdown_msg));
29722955
}
29732956

29742957
let required_revoke = if msg.next_remote_commitment_number + 1 == INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number {
@@ -3009,14 +2992,6 @@ impl<Signer: Sign> Channel<Signer> {
30092992
}
30102993

30112994
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 {
3012-
// Note that if in the future we no longer drop holding cell update_adds on peer
3013-
// disconnect, this logic will need to be updated.
3014-
for htlc_update in self.holding_cell_htlc_updates.iter() {
3015-
if let &HTLCUpdateAwaitingACK::AddHTLC { .. } = htlc_update {
3016-
debug_assert!(false, "There shouldn't be any add-HTLCs in the holding cell now because they should have been dropped on peer disconnect. Panic here because said HTLCs won't be handled correctly.");
3017-
}
3018-
}
3019-
30202995
// We're up-to-date and not waiting on a remote revoke (if we are our
30212996
// channel_reestablish should result in them sending a revoke_and_ack), but we may
30222997
// have received some updates while we were disconnected. Free the holding cell
@@ -3025,20 +3000,14 @@ impl<Signer: Sign> Channel<Signer> {
30253000
Err(ChannelError::Close(msg)) => return Err(ChannelError::Close(msg)),
30263001
Err(ChannelError::Ignore(_)) | Err(ChannelError::CloseDelayBroadcast(_)) => panic!("Got non-channel-failing result from free_holding_cell_htlcs"),
30273002
Ok((Some((commitment_update, monitor_update)), htlcs_to_fail)) => {
3028-
// If in the future we no longer drop holding cell update_adds on peer
3029-
// disconnect, we may be handed some HTLCs to fail backwards here.
3030-
assert!(htlcs_to_fail.is_empty());
3031-
return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg));
3003+
return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), htlcs_to_fail, shutdown_msg));
30323004
},
30333005
Ok((None, htlcs_to_fail)) => {
3034-
// If in the future we no longer drop holding cell update_adds on peer
3035-
// disconnect, we may be handed some HTLCs to fail backwards here.
3036-
assert!(htlcs_to_fail.is_empty());
3037-
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg));
3006+
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), htlcs_to_fail, shutdown_msg));
30383007
},
30393008
}
30403009
} else {
3041-
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg));
3010+
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), Vec::new(), shutdown_msg));
30423011
}
30433012
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
30443013
if required_revoke.is_some() {
@@ -3049,10 +3018,10 @@ impl<Signer: Sign> Channel<Signer> {
30493018

30503019
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
30513020
self.monitor_pending_commitment_signed = true;
3052-
return Ok((resend_funding_locked, None, None, None, self.resend_order.clone(), shutdown_msg));
3021+
return Ok((resend_funding_locked, None, None, None, self.resend_order.clone(), Vec::new(), shutdown_msg));
30533022
}
30543023

3055-
return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update(logger)), None, self.resend_order.clone(), shutdown_msg));
3024+
return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update(logger)), None, self.resend_order.clone(), Vec::new(), shutdown_msg));
30563025
} else {
30573026
return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction".to_owned()));
30583027
}
@@ -4375,7 +4344,7 @@ impl Readable for InboundHTLCRemovalReason {
43754344
impl<Signer: Sign> Writeable for Channel<Signer> {
43764345
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
43774346
// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
4378-
// called but include holding cell updates (and obviously we don't modify self).
4347+
// called.
43794348

43804349
writer.write_all(&[SERIALIZATION_VERSION; 1])?;
43814350
writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;

lightning/src/ln/channelmanager.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,7 +3192,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31923192
}
31933193

31943194
fn internal_channel_reestablish(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
3195-
let chan_restoration_res = {
3195+
let (htlcs_failed_forward, chan_restoration_res) = {
31963196
let mut channel_state_lock = self.channel_state.lock().unwrap();
31973197
let channel_state = &mut *channel_state_lock;
31983198

@@ -3205,20 +3205,21 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32053205
// disconnect, so Channel's reestablish will never hand us any holding cell
32063206
// freed HTLCs to fail backwards. If in the future we no longer drop pending
32073207
// add-HTLCs on disconnect, we may be handed HTLCs to fail backwards here.
3208-
let (funding_locked, revoke_and_ack, commitment_update, monitor_update_opt, order, shutdown) =
3208+
let (funding_locked, revoke_and_ack, commitment_update, monitor_update_opt, order, htlcs_failed_forward, shutdown) =
32093209
try_chan_entry!(self, chan.get_mut().channel_reestablish(msg, &self.logger), channel_state, chan);
32103210
if let Some(msg) = shutdown {
32113211
channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
32123212
node_id: counterparty_node_id.clone(),
32133213
msg,
32143214
});
32153215
}
3216-
handle_chan_restoration_locked!(self, channel_state_lock, channel_state, chan, revoke_and_ack, commitment_update, order, monitor_update_opt, Vec::new(), None, funding_locked)
3216+
(htlcs_failed_forward, handle_chan_restoration_locked!(self, channel_state_lock, channel_state, chan, revoke_and_ack, commitment_update, order, monitor_update_opt, Vec::new(), None, funding_locked))
32173217
},
32183218
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
32193219
}
32203220
};
32213221
post_handle_chan_restoration!(self, chan_restoration_res);
3222+
self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id);
32223223
Ok(())
32233224
}
32243225

@@ -3775,7 +3776,6 @@ impl<Signer: Sign, M: Deref + Sync + Send, T: Deref + Sync + Send, K: Deref + Sy
37753776
fn peer_disconnected(&self, counterparty_node_id: &PublicKey, no_connection_possible: bool) {
37763777
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
37773778
let mut failed_channels = Vec::new();
3778-
let mut failed_payments = Vec::new();
37793779
let mut no_channels_remain = true;
37803780
{
37813781
let mut channel_state_lock = self.channel_state.lock().unwrap();
@@ -3804,16 +3804,8 @@ impl<Signer: Sign, M: Deref + Sync + Send, T: Deref + Sync + Send, K: Deref + Sy
38043804
log_debug!(self.logger, "Marking channels with {} disconnected and generating channel_updates", log_pubkey!(counterparty_node_id));
38053805
channel_state.by_id.retain(|_, chan| {
38063806
if chan.get_counterparty_node_id() == *counterparty_node_id {
3807-
// Note that currently on channel reestablish we assert that there are no
3808-
// holding cell add-HTLCs, so if in the future we stop removing uncommitted HTLCs
3809-
// on peer disconnect here, there will need to be corresponding changes in
3810-
// reestablish logic.
3811-
let failed_adds = chan.remove_uncommitted_htlcs_and_mark_paused(&self.logger);
3807+
chan.remove_uncommitted_htlcs_and_mark_paused(&self.logger);
38123808
chan.to_disabled_marked();
3813-
if !failed_adds.is_empty() {
3814-
let chan_update = self.get_channel_update(&chan).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
3815-
failed_payments.push((chan_update, failed_adds));
3816-
}
38173809
if chan.is_shutdown() {
38183810
if let Some(short_id) = chan.get_short_channel_id() {
38193811
short_to_id.remove(&short_id);
@@ -3857,11 +3849,6 @@ impl<Signer: Sign, M: Deref + Sync + Send, T: Deref + Sync + Send, K: Deref + Sy
38573849
for failure in failed_channels.drain(..) {
38583850
self.finish_force_close_channel(failure);
38593851
}
3860-
for (chan_update, mut htlc_sources) in failed_payments {
3861-
for (htlc_source, payment_hash) in htlc_sources.drain(..) {
3862-
self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, HTLCFailReason::Reason { failure_code: 0x1000 | 7, data: chan_update.clone() });
3863-
}
3864-
}
38653852
}
38663853

38673854
fn peer_connected(&self, counterparty_node_id: &PublicKey, init_msg: &msgs::Init) {

0 commit comments

Comments
 (0)