Skip to content

Commit 0df7bb5

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

File tree

3 files changed

+529
-162
lines changed

3 files changed

+529
-162
lines changed

lightning/src/ln/channel.rs

Lines changed: 89 additions & 102 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
}
@@ -2727,7 +2714,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27272714

27282715
/// May panic if some calls other than message-handling calls (which will all Err immediately)
27292716
/// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
2730-
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 {
2717+
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>, Vec<(HTLCSource, PaymentHash)>, RAACommitmentOrder, Option<msgs::Shutdown>), ChannelError> where L::Target: Logger {
27312718
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
27322719
// While BOLT 2 doesn't indicate explicitly we should error this channel here, it
27332720
// almost certainly indicates we are going to end up out-of-sync in some way, so we
@@ -2778,15 +2765,15 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27782765
return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet".to_owned()));
27792766
}
27802767
// Short circuit the whole handler as there is nothing we can resend them
2781-
return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
2768+
return Ok((None, None, None, None, Vec::new(), RAACommitmentOrder::CommitmentFirst, shutdown_msg));
27822769
}
27832770

27842771
// We have OurFundingLocked set!
27852772
let next_per_commitment_point = self.local_keys.get_per_commitment_point(self.cur_local_commitment_transaction_number, &self.secp_ctx);
27862773
return Ok((Some(msgs::FundingLocked {
27872774
channel_id: self.channel_id(),
27882775
next_per_commitment_point: next_per_commitment_point,
2789-
}), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
2776+
}), None, None, None, Vec::new(), RAACommitmentOrder::CommitmentFirst, shutdown_msg));
27902777
}
27912778

27922779
let required_revoke = if msg.next_remote_commitment_number + 1 == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number {
@@ -2834,11 +2821,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28342821
match self.free_holding_cell_htlcs(logger) {
28352822
Err(ChannelError::Close(msg)) => return Err(ChannelError::Close(msg)),
28362823
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)),
2824+
Ok((Some((commitment_update, monitor_update)), htlcs_to_fail)) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), htlcs_to_fail, self.resend_order.clone(), shutdown_msg)),
2825+
Ok((None, htlcs_to_fail)) => return Ok((resend_funding_locked, required_revoke, None, None, htlcs_to_fail, self.resend_order.clone(), shutdown_msg)),
28392826
}
28402827
} else {
2841-
return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg));
2828+
return Ok((resend_funding_locked, required_revoke, None, None, Vec::new(), self.resend_order.clone(), shutdown_msg));
28422829
}
28432830
} else if msg.next_local_commitment_number == our_next_remote_commitment_number - 1 {
28442831
if required_revoke.is_some() {
@@ -2849,10 +2836,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28492836

28502837
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
28512838
self.monitor_pending_commitment_signed = true;
2852-
return Ok((resend_funding_locked, None, None, None, self.resend_order.clone(), shutdown_msg));
2839+
return Ok((resend_funding_locked, None, None, None, Vec::new(), self.resend_order.clone(), shutdown_msg));
28532840
}
28542841

2855-
return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update(logger)), None, self.resend_order.clone(), shutdown_msg));
2842+
return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update(logger)), None, Vec::new(), self.resend_order.clone(), shutdown_msg));
28562843
} else {
28572844
return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction".to_owned()));
28582845
}

0 commit comments

Comments
 (0)