Skip to content

Commit 3219b4c

Browse files
committed
Decode fully committed incoming HTLC onions upon channel resumption
This is currently done as soon as we receive the `UpdateAddHTLC` message, but it will be phased out as we transition to decoding incoming HTLC onions once the HTLC has been fully committed to by both sides. Doing so within the monitor update completion path meshes well as it already handles forwarding and failing back HTLCs – the two possible outcomes of decoding an incoming HTLC onion.
1 parent 53dc48c commit 3219b4c

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

lightning/src/ln/channel.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -4240,13 +4240,15 @@ impl<SP: Deref> Channel<SP> where
42404240
mem::swap(&mut failed_htlcs, &mut self.context.monitor_pending_failures);
42414241
let mut finalized_claimed_htlcs = Vec::new();
42424242
mem::swap(&mut finalized_claimed_htlcs, &mut self.context.monitor_pending_finalized_fulfills);
4243+
let mut pending_htlc_status = Vec::new();
4244+
mem::swap(&mut pending_htlc_status, &mut self.context.monitor_pending_htlc_status);
42434245

42444246
if self.context.channel_state.is_peer_disconnected() {
42454247
self.context.monitor_pending_revoke_and_ack = false;
42464248
self.context.monitor_pending_commitment_signed = false;
42474249
return MonitorRestoreUpdates {
42484250
raa: None, commitment_update: None, order: RAACommitmentOrder::RevokeAndACKFirst,
4249-
accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, pending_htlc_status: Vec::new(),
4251+
accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, pending_htlc_status,
42504252
funding_broadcastable, channel_ready, announcement_sigs
42514253
};
42524254
}
@@ -4270,7 +4272,7 @@ impl<SP: Deref> Channel<SP> where
42704272
match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"});
42714273
MonitorRestoreUpdates {
42724274
raa, commitment_update, order, accepted_htlcs, failed_htlcs, finalized_claimed_htlcs,
4273-
pending_htlc_status: Vec::new(), funding_broadcastable, channel_ready, announcement_sigs
4275+
pending_htlc_status, funding_broadcastable, channel_ready, announcement_sigs
42744276
}
42754277
}
42764278

lightning/src/ln/channelmanager.rs

+59-10
Original file line numberDiff line numberDiff line change
@@ -2189,16 +2189,17 @@ macro_rules! handle_monitor_update_completion {
21892189
let update_actions = $peer_state.monitor_update_blocked_actions
21902190
.remove(&$chan.context.channel_id()).unwrap_or(Vec::new());
21912191

2192-
let htlc_forwards = $self.handle_channel_resumption(
2192+
let (htlc_forwards, mut htlc_fails) = $self.handle_channel_resumption(
21932193
&mut $peer_state.pending_msg_events, $chan, updates.raa,
2194-
updates.commitment_update, updates.order, updates.accepted_htlcs,
2194+
updates.commitment_update, updates.order, updates.accepted_htlcs, updates.pending_htlc_status,
21952195
updates.funding_broadcastable, updates.channel_ready,
21962196
updates.announcement_sigs);
21972197
if let Some(upd) = channel_update {
21982198
$peer_state.pending_msg_events.push(upd);
21992199
}
22002200

22012201
let channel_id = $chan.context.channel_id();
2202+
let scid = $chan.context.get_short_channel_id().or($chan.context.latest_inbound_scid_alias());
22022203
let unbroadcasted_batch_funding_txid = $chan.context.unbroadcasted_batch_funding_txid();
22032204
core::mem::drop($peer_state_lock);
22042205
core::mem::drop($per_peer_state_lock);
@@ -2253,6 +2254,37 @@ macro_rules! handle_monitor_update_completion {
22532254
$self.forward_htlcs(&mut [forwards][..]);
22542255
}
22552256
$self.finalize_claims(updates.finalized_claimed_htlcs);
2257+
for (htlc_fail, outgoing_scid) in htlc_fails.drain(..) {
2258+
if let Some(scid) = scid {
2259+
let (channel_id, failure) = match htlc_fail {
2260+
HTLCFailureMsg::Relay(fail_htlc) => (fail_htlc.channel_id, HTLCForwardInfo::FailHTLC {
2261+
htlc_id: fail_htlc.htlc_id,
2262+
err_packet: fail_htlc.reason,
2263+
}),
2264+
HTLCFailureMsg::Malformed(fail_malformed_htlc) => (fail_malformed_htlc.channel_id, HTLCForwardInfo::FailMalformedHTLC {
2265+
htlc_id: fail_malformed_htlc.htlc_id,
2266+
sha256_of_onion: fail_malformed_htlc.sha256_of_onion,
2267+
failure_code: fail_malformed_htlc.failure_code,
2268+
}),
2269+
};
2270+
let destination = if let Some(outgoing_scid) = outgoing_scid {
2271+
match $self.short_to_chan_info.read().unwrap().get(&outgoing_scid) {
2272+
Some((_, outgoing_channel_id)) => HTLCDestination::NextHopChannel {
2273+
node_id: Some(counterparty_node_id),
2274+
channel_id: *outgoing_channel_id,
2275+
},
2276+
None => HTLCDestination::UnknownNextHop {
2277+
requested_forward_scid: outgoing_scid,
2278+
},
2279+
}
2280+
} else {
2281+
HTLCDestination::InvalidOnion
2282+
};
2283+
$self.push_htlc_failure(scid, channel_id, failure, destination);
2284+
} else {
2285+
debug_assert!(false, "Channel with failed HTLC should have a real/alias short_channel_id")
2286+
}
2287+
}
22562288
for failure in updates.failed_htlcs.drain(..) {
22572289
let receiver = HTLCDestination::NextHopChannel { node_id: Some(counterparty_node_id), channel_id };
22582290
$self.fail_htlc_backwards_internal(&failure.0, &failure.1, &failure.2, receiver);
@@ -5872,9 +5904,10 @@ where
58725904
fn handle_channel_resumption(&self, pending_msg_events: &mut Vec<MessageSendEvent>,
58735905
channel: &mut Channel<SP>, raa: Option<msgs::RevokeAndACK>,
58745906
commitment_update: Option<msgs::CommitmentUpdate>, order: RAACommitmentOrder,
5875-
pending_forwards: Vec<(PendingHTLCInfo, u64)>, funding_broadcastable: Option<Transaction>,
5907+
mut pending_forwards: Vec<(PendingHTLCInfo, u64)>, pending_htlc_status: Vec<msgs::UpdateAddHTLC>,
5908+
funding_broadcastable: Option<Transaction>,
58765909
channel_ready: Option<msgs::ChannelReady>, announcement_sigs: Option<msgs::AnnouncementSignatures>)
5877-
-> Option<(u64, OutPoint, u128, Vec<(PendingHTLCInfo, u64)>)> {
5910+
-> (Option<(u64, OutPoint, u128, Vec<(PendingHTLCInfo, u64)>)>, Vec<(HTLCFailureMsg, Option<u64>)>) {
58785911
let logger = WithChannelContext::from(&self.logger, &channel.context);
58795912
log_trace!(logger, "Handling channel resumption for channel {} with {} RAA, {} commitment update, {} pending forwards, {}broadcasting funding, {} channel ready, {} announcement",
58805913
&channel.context.channel_id(),
@@ -5885,10 +5918,26 @@ where
58855918
if announcement_sigs.is_some() { "sending" } else { "without" });
58865919

58875920
let mut htlc_forwards = None;
5888-
5921+
let mut htlc_fails = Vec::new();
58895922
let counterparty_node_id = channel.context.get_counterparty_node_id();
5923+
let short_channel_id = channel.context.get_short_channel_id().unwrap_or(channel.context.outbound_scid_alias());
5924+
for update_add_htlc in pending_htlc_status {
5925+
let decoded_hop_res = self.decode_update_add_htlc_onion(&update_add_htlc, &counterparty_node_id, Some(channel));
5926+
match decoded_hop_res {
5927+
Ok((next_hop, shared_secret, next_packet_pk_opt)) => {
5928+
match self.construct_pending_htlc_status(
5929+
&update_add_htlc, &counterparty_node_id, shared_secret, next_hop,
5930+
channel.context.config().accept_underpaying_htlcs, next_packet_pk_opt,
5931+
) {
5932+
PendingHTLCStatus::Forward(htlc_forward) => pending_forwards.push((htlc_forward, update_add_htlc.htlc_id)),
5933+
PendingHTLCStatus::Fail(htlc_fail) => htlc_fails.push((htlc_fail, None)),
5934+
}
5935+
},
5936+
Err(e) => htlc_fails.push(e),
5937+
};
5938+
}
58905939
if !pending_forwards.is_empty() {
5891-
htlc_forwards = Some((channel.context.get_short_channel_id().unwrap_or(channel.context.outbound_scid_alias()),
5940+
htlc_forwards = Some((short_channel_id,
58925941
channel.context.get_funding_txo().unwrap(), channel.context.get_user_id(), pending_forwards));
58935942
}
58945943

@@ -5940,7 +5989,7 @@ where
59405989
emit_channel_ready_event!(pending_events, channel);
59415990
}
59425991

5943-
htlc_forwards
5992+
(htlc_forwards, htlc_fails)
59445993
}
59455994

59465995
fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64, counterparty_node_id: Option<&PublicKey>) {
@@ -7199,10 +7248,10 @@ where
71997248
}
72007249
}
72017250
let need_lnd_workaround = chan.context.workaround_lnd_bug_4006.take();
7202-
let htlc_forwards = self.handle_channel_resumption(
7251+
let (htlc_forwards, htlc_fails) = self.handle_channel_resumption(
72037252
&mut peer_state.pending_msg_events, chan, responses.raa, responses.commitment_update, responses.order,
7204-
Vec::new(), None, responses.channel_ready, responses.announcement_sigs);
7205-
debug_assert!(htlc_forwards.is_none());
7253+
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs);
7254+
debug_assert!(htlc_forwards.is_none() && htlc_fails.is_empty());
72067255
if let Some(upd) = channel_update {
72077256
peer_state.pending_msg_events.push(upd);
72087257
}

0 commit comments

Comments
 (0)