Skip to content

Commit dac9f3f

Browse files
committed
Fail channel if we can't sign a new commitment tx during HTLC claim
Previously, we could fail to generate a new commitment transaction but it simply indicated we had gone to doule-claim an HTLC. Now that double-claims are returned instead as Ok(None), we should handle the error case and fail the channel, as the only way to hit the error case is if key derivation failed or the user refused to sign the new commitment transaction. This also resolves an issue where we wouldn't inform our ChannelMonitor of the new payment preimage in case we failed to fetch a signature for the new commitment transaction.
1 parent 5fd9606 commit dac9f3f

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

lightning/src/ln/channel.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,10 +1344,13 @@ impl<Signer: Sign> Channel<Signer> {
13441344
}), monitor_update))
13451345
}
13461346

1347-
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<Option<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, ChannelMonitorUpdate)>, ChannelError> where L::Target: Logger {
1347+
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<Option<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, ChannelMonitorUpdate)>, (ChannelError, ChannelMonitorUpdate)> where L::Target: Logger {
13481348
match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger) {
13491349
Some((Some(update_fulfill_htlc), mut monitor_update)) => {
1350-
let (commitment, mut additional_update) = self.send_commitment_no_status_check(logger)?;
1350+
let (commitment, mut additional_update) = match self.send_commitment_no_status_check(logger) {
1351+
Err(e) => return Err((e, monitor_update)),
1352+
Ok(res) => res
1353+
};
13511354
// send_commitment_no_status_check may bump latest_monitor_id but we want them to be
13521355
// strictly increasing by one, so decrement it here.
13531356
self.latest_monitor_update_id = monitor_update.update_id;

lightning/src/ln/channelmanager.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2679,16 +2679,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
26792679
};
26802680

26812681
if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(chan_id) {
2682-
let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
26832682
match chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &self.logger) {
26842683
Ok(msgs_monitor_option) => {
26852684
if let Some((msgs, monitor_update)) = msgs_monitor_option {
26862685
if let Err(e) = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
2687-
if was_frozen_for_monitor {
2688-
assert!(msgs.is_none());
2689-
} else {
2690-
return Err(Some((chan.get().get_counterparty_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()).unwrap_err())));
2691-
}
2686+
return Err(Some((
2687+
chan.get().get_counterparty_node_id(),
2688+
handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()).unwrap_err(),
2689+
)));
26922690
}
26932691
if let Some((msg, commitment_signed)) = msgs {
26942692
log_debug!(self.logger, "Claiming funds for HTLC with preimage {} resulted in a commitment_signed for channel {}",
@@ -2708,16 +2706,17 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
27082706
}
27092707
return Ok(())
27102708
},
2711-
Err(e) => {
2712-
// TODO: Do something with e?
2713-
// This should only occur if we are claiming an HTLC at the same time as the
2714-
// HTLC is being failed (eg because a block is being connected and this caused
2715-
// an HTLC to time out). This should, of course, only occur if the user is the
2716-
// one doing the claiming (as it being a part of a peer claim would imply we're
2717-
// about to lose funds) and only if the lock in claim_funds was dropped as a
2718-
// previous HTLC was failed (thus not for an MPP payment).
2719-
debug_assert!(false, "This shouldn't be reachable except in absurdly rare cases between monitor updates and HTLC timeouts: {:?}", e);
2720-
return Err(None)
2709+
Err((e, monitor_update)) => {
2710+
if let Err(e) = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
2711+
log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
2712+
payment_preimage, e);
2713+
}
2714+
let counterparty_node_id = chan.get().get_counterparty_node_id();
2715+
let (drop, res) = convert_chan_err!(self, e, channel_state.short_to_id, chan.get_mut(), &chan_id);
2716+
if drop {
2717+
chan.remove_entry();
2718+
}
2719+
return Err(Some((counterparty_node_id, res)));
27212720
},
27222721
}
27232722
} else { unreachable!(); }

0 commit comments

Comments
 (0)