Skip to content

Commit 7b0841f

Browse files
Holding cell: if we fail to free an HTLC, fail it backwards
Plus add a test.
1 parent 779ff67 commit 7b0841f

File tree

3 files changed

+493
-99
lines changed

3 files changed

+493
-99
lines changed

lightning/src/ln/channel.rs

Lines changed: 106 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
21172117

21182118
/// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them
21192119
/// fulfilling or failing the last pending HTLC)
2120-
fn free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, ChannelError> where L::Target: Logger {
2120+
fn free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger {
21212121
assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0);
21222122
if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() {
21232123
log_trace!(logger, "Freeing holding cell with {} HTLC updates{}", self.holding_cell_htlc_updates.len(), if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" });
@@ -2132,110 +2132,97 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
21322132
let mut update_add_htlcs = Vec::with_capacity(htlc_updates.len());
21332133
let mut update_fulfill_htlcs = Vec::with_capacity(htlc_updates.len());
21342134
let mut update_fail_htlcs = Vec::with_capacity(htlc_updates.len());
2135-
let mut err = None;
2135+
let mut htlcs_to_fail = Vec::new();
21362136
for htlc_update in htlc_updates.drain(..) {
21372137
// Note that this *can* fail, though it should be due to rather-rare conditions on
21382138
// fee races with adding too many outputs which push our total payments just over
21392139
// the limit. In case it's less rare than I anticipate, we may want to revisit
21402140
// handling this case better and maybe fulfilling some of the HTLCs while attempting
21412141
// to rebalance channels.
2142-
if err.is_some() { // We're back to AwaitingRemoteRevoke (or are about to fail the channel)
2143-
self.holding_cell_htlc_updates.push(htlc_update);
2144-
} else {
2145-
match &htlc_update {
2146-
&HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => {
2147-
match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) {
2148-
Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()),
2149-
Err(e) => {
2150-
match e {
2151-
ChannelError::Ignore(ref msg) => {
2152-
log_info!(logger, "Failed to send HTLC with payment_hash {} due to {}", log_bytes!(payment_hash.0), msg);
2153-
},
2154-
_ => {
2155-
log_info!(logger, "Failed to send HTLC with payment_hash {} resulting in a channel closure during holding_cell freeing", log_bytes!(payment_hash.0));
2156-
},
2157-
}
2158-
err = Some(e);
2142+
match &htlc_update {
2143+
&HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => {
2144+
match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) {
2145+
Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()),
2146+
Err(e) => {
2147+
match e {
2148+
ChannelError::Ignore(ref msg) => {
2149+
log_info!(logger, "Failed to send HTLC with payment_hash {} due to {}", log_bytes!(payment_hash.0), msg);
2150+
// If we fail to send here, then this HTLC should
2151+
// be failed backwards. Failing to send here
2152+
// indicates that this HTLC may keep being put back
2153+
// into the holding cell without ever being
2154+
// successfully forwarded/failed/fulfilled, causing
2155+
// our counterparty to eventually close on us.
2156+
htlcs_to_fail.push((source.clone(), *payment_hash));
2157+
},
2158+
_ => {
2159+
panic!("Got a non-IgnoreError action trying to send holding cell HTLC");
2160+
},
21592161
}
21602162
}
2161-
},
2162-
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
2163-
match self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
2164-
Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => {
2165-
update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());
2166-
if let Some(mut additional_monitor_update) = additional_monitor_update_opt {
2167-
monitor_update.updates.append(&mut additional_monitor_update.updates);
2168-
}
2169-
},
2170-
Err(e) => {
2171-
if let ChannelError::Ignore(_) = e {}
2172-
else {
2173-
panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC");
2174-
}
2163+
}
2164+
},
2165+
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
2166+
match self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
2167+
Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => {
2168+
update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());
2169+
if let Some(mut additional_monitor_update) = additional_monitor_update_opt {
2170+
monitor_update.updates.append(&mut additional_monitor_update.updates);
2171+
}
2172+
},
2173+
Err(e) => {
2174+
if let ChannelError::Ignore(_) = e {}
2175+
else {
2176+
panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC");
21752177
}
21762178
}
2177-
},
2178-
&HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => {
2179-
match self.get_update_fail_htlc(htlc_id, err_packet.clone()) {
2180-
Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()),
2181-
Err(e) => {
2182-
if let ChannelError::Ignore(_) = e {}
2183-
else {
2184-
panic!("Got a non-IgnoreError action trying to fail holding cell HTLC");
2185-
}
2179+
}
2180+
},
2181+
&HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => {
2182+
match self.get_update_fail_htlc(htlc_id, err_packet.clone()) {
2183+
Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()),
2184+
Err(e) => {
2185+
if let ChannelError::Ignore(_) = e {}
2186+
else {
2187+
panic!("Got a non-IgnoreError action trying to fail holding cell HTLC");
21862188
}
21872189
}
2188-
},
2189-
}
2190-
if err.is_some() {
2191-
self.holding_cell_htlc_updates.push(htlc_update);
2192-
if let Some(ChannelError::Ignore(_)) = err {
2193-
// If we failed to add the HTLC, but got an Ignore error, we should
2194-
// still send the new commitment_signed, so reset the err to None.
2195-
err = None;
21962190
}
2197-
}
2191+
},
21982192
}
21992193
}
2200-
//TODO: Need to examine the type of err - if it's a fee issue or similar we may want to
2201-
//fail it back the route, if it's a temporary issue we can ignore it...
2202-
match err {
2203-
None => {
2204-
if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() {
2205-
// This should never actually happen and indicates we got some Errs back
2206-
// from update_fulfill_htlc/update_fail_htlc, but we handle it anyway in
2207-
// case there is some strange way to hit duplicate HTLC removes.
2208-
return Ok(None);
2209-
}
2210-
let update_fee = if let Some(feerate) = self.holding_cell_update_fee {
2211-
self.pending_update_fee = self.holding_cell_update_fee.take();
2212-
Some(msgs::UpdateFee {
2213-
channel_id: self.channel_id,
2214-
feerate_per_kw: feerate as u32,
2215-
})
2216-
} else {
2217-
None
2218-
};
2194+
if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() {
2195+
// Hitting this case indicates that we got some Errs back from update_fulfill_htlc
2196+
// or update_fail_htlc.
2197+
log_warn!(logger, "Attempted to fulfill or fail an HTLC that was already removed");
2198+
return Ok((None, htlcs_to_fail));
2199+
}
2200+
let update_fee = if let Some(feerate) = self.holding_cell_update_fee {
2201+
self.pending_update_fee = self.holding_cell_update_fee.take();
2202+
Some(msgs::UpdateFee {
2203+
channel_id: self.channel_id,
2204+
feerate_per_kw: feerate as u32,
2205+
})
2206+
} else {
2207+
None
2208+
};
22192209

2220-
let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?;
2221-
// send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id
2222-
// but we want them to be strictly increasing by one, so reset it here.
2223-
self.latest_monitor_update_id = monitor_update.update_id;
2224-
monitor_update.updates.append(&mut additional_update.updates);
2210+
let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?;
2211+
// send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id
2212+
// but we want them to be strictly increasing by one, so reset it here.
2213+
self.latest_monitor_update_id = monitor_update.update_id;
2214+
monitor_update.updates.append(&mut additional_update.updates);
22252215

2226-
Ok(Some((msgs::CommitmentUpdate {
2227-
update_add_htlcs,
2228-
update_fulfill_htlcs,
2229-
update_fail_htlcs,
2230-
update_fail_malformed_htlcs: Vec::new(),
2231-
update_fee: update_fee,
2232-
commitment_signed,
2233-
}, monitor_update)))
2234-
},
2235-
Some(e) => Err(e)
2236-
}
2216+
Ok((Some((msgs::CommitmentUpdate {
2217+
update_add_htlcs,
2218+
update_fulfill_htlcs,
2219+
update_fail_htlcs,
2220+
update_fail_malformed_htlcs: Vec::new(),
2221+
update_fee: update_fee,
2222+
commitment_signed,
2223+
}, monitor_update)), htlcs_to_fail))
22372224
} else {
2238-
Ok(None)
2225+
Ok((None, Vec::new()))
22392226
}
22402227
}
22412228

@@ -2244,7 +2231,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
22442231
/// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail,
22452232
/// generating an appropriate error *after* the channel state has been updated based on the
22462233
/// revoke_and_ack message.
2247-
pub fn revoke_and_ack<F: Deref, L: Deref>(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F, logger: &L) -> Result<(Option<msgs::CommitmentUpdate>, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option<msgs::ClosingSigned>, ChannelMonitorUpdate), ChannelError>
2234+
pub fn revoke_and_ack<F: Deref, L: Deref>(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F, logger: &L) -> Result<(Option<msgs::CommitmentUpdate>, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option<msgs::ClosingSigned>, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>), ChannelError>
22482235
where F::Target: FeeEstimator,
22492236
L::Target: Logger,
22502237
{
@@ -2419,11 +2406,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
24192406
}
24202407
self.monitor_pending_forwards.append(&mut to_forward_infos);
24212408
self.monitor_pending_failures.append(&mut revoked_htlcs);
2422-
return Ok((None, Vec::new(), Vec::new(), None, monitor_update))
2409+
return Ok((None, Vec::new(), Vec::new(), None, monitor_update, Vec::new()))
24232410
}
24242411

24252412
match self.free_holding_cell_htlcs(logger)? {
2426-
Some((mut commitment_update, mut additional_update)) => {
2413+
(Some((mut commitment_update, mut additional_update)), htlcs_to_fail) => {
24272414
commitment_update.update_fail_htlcs.reserve(update_fail_htlcs.len());
24282415
for fail_msg in update_fail_htlcs.drain(..) {
24292416
commitment_update.update_fail_htlcs.push(fail_msg);
@@ -2438,9 +2425,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
24382425
self.latest_monitor_update_id = monitor_update.update_id;
24392426
monitor_update.updates.append(&mut additional_update.updates);
24402427

2441-
Ok((Some(commitment_update), to_forward_infos, revoked_htlcs, None, monitor_update))
2428+
Ok((Some(commitment_update), to_forward_infos, revoked_htlcs, None, monitor_update, htlcs_to_fail))
24422429
},
2443-
None => {
2430+
(None, htlcs_to_fail) => {
24442431
if require_commitment {
24452432
let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?;
24462433

@@ -2456,9 +2443,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
24562443
update_fail_malformed_htlcs,
24572444
update_fee: None,
24582445
commitment_signed
2459-
}), to_forward_infos, revoked_htlcs, None, monitor_update))
2446+
}), to_forward_infos, revoked_htlcs, None, monitor_update, htlcs_to_fail))
24602447
} else {
2461-
Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), monitor_update))
2448+
Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), monitor_update, htlcs_to_fail))
24622449
}
24632450
}
24642451
}
@@ -2560,6 +2547,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
25602547

25612548
self.holding_cell_htlc_updates.retain(|htlc_update| {
25622549
match htlc_update {
2550+
// Note that currently on channel reestablish we assert that there are
2551+
// no holding cell HTLC update_adds, so if in the future we stop
2552+
// dropping added HTLCs here and failing them backwards, then there will
2553+
// need to be corresponding changes made in the Channel's re-establish
2554+
// logic.
25632555
&HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => {
25642556
outbound_drops.push((source.clone(), payment_hash.clone()));
25652557
false
@@ -2827,15 +2819,33 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28272819
}
28282820

28292821
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 {
2822+
// Note that if in the future we no longer drop holding cell update_adds on peer
2823+
// disconnect, this logic will need to be updated.
2824+
for htlc_update in self.holding_cell_htlc_updates.iter() {
2825+
if let &HTLCUpdateAwaitingACK::AddHTLC { .. } = htlc_update {
2826+
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.");
2827+
}
2828+
}
2829+
28302830
// We're up-to-date and not waiting on a remote revoke (if we are our
28312831
// channel_reestablish should result in them sending a revoke_and_ack), but we may
28322832
// have received some updates while we were disconnected. Free the holding cell
28332833
// now!
28342834
match self.free_holding_cell_htlcs(logger) {
28352835
Err(ChannelError::Close(msg)) => return Err(ChannelError::Close(msg)),
28362836
Err(ChannelError::Ignore(_)) | Err(ChannelError::CloseDelayBroadcast(_)) => panic!("Got non-channel-failing result from free_holding_cell_htlcs"),
2837-
Ok(Some((commitment_update, monitor_update))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg)),
2838-
Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)),
2837+
Ok((Some((commitment_update, monitor_update)), htlcs_to_fail)) => {
2838+
// If in the future we no longer drop holding cell update_adds on peer
2839+
// disconnect, we may be handed some HTLCs to fail backwards here.
2840+
assert!(htlcs_to_fail.is_empty());
2841+
return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg));
2842+
},
2843+
Ok((None, htlcs_to_fail)) => {
2844+
// If in the future we no longer drop holding cell update_adds on peer
2845+
// disconnect, we may be handed some HTLCs to fail backwards here.
2846+
assert!(htlcs_to_fail.is_empty());
2847+
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg));
2848+
},
28392849
}
28402850
} else {
28412851
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg));

0 commit comments

Comments
 (0)