Skip to content

Commit 4210c01

Browse files
committed
Enable decoding new incoming HTLC onions when fully committed
This commit ensures all new incoming HTLCs going forward will have their onion decoded when they become fully committed to decide how we should proceed with each one. As a result, we'll obtain `HTLCHandlingFailed` events for _any_ failed HTLC that comes across a channel. We will now start writing channels with the new serialization version (4), and we will still be able to downgrade back to the commit that introduced it since reading version 4 is supported. Note that existing pending inbound HTLCs may already have their resolution if they were received in a previous version of LDK. We must support those until we no longer allow downgrading beyond this commit.
1 parent 61e5a00 commit 4210c01

11 files changed

+326
-272
lines changed

lightning/src/events/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1021,9 +1021,11 @@ pub enum Event {
10211021
/// * When an unknown SCID is requested for forwarding a payment.
10221022
/// * Expected MPP amount has already been reached
10231023
/// * The HTLC has timed out
1024+
/// * The HTLC failed to meet the forwarding requirements (i.e. insufficient fees paid, or a
1025+
/// CLTV that is too soon)
10241026
///
1025-
/// This event, however, does not get generated if an HTLC fails to meet the forwarding
1026-
/// requirements (i.e. insufficient fees paid, or a CLTV that is too soon).
1027+
/// The list above is not meant to cover all scenarios. This event should be expected for each
1028+
/// incoming HTLC that has been fully committed but we failed to handle.
10271029
HTLCHandlingFailed {
10281030
/// The channel over which the HTLC was received.
10291031
prev_channel_id: ChannelId,

lightning/src/ln/blinded_payment_tests.rs

+54-10
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,10 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
274274
// We need the session priv to construct a bogus onion packet later.
275275
*nodes[0].keys_manager.override_random_bytes.lock().unwrap() = Some([3; 32]);
276276
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
277-
let chan_upd_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0).0.contents;
278-
let chan_upd_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0).0.contents;
277+
let chan_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0);
278+
let chan_upd_1_2 = chan_1_2.0.contents;
279+
let chan_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0);
280+
let chan_upd_2_3 = chan_2_3.0.contents;
279281

280282
let amt_msat = 5000;
281283
let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[3], Some(amt_msat), None);
@@ -327,18 +329,27 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
327329
check_added_monitors!(nodes[1], 0);
328330
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates_0_1.commitment_signed, true, true);
329331

332+
expect_pending_htlcs_forwardable!(nodes[1]);
333+
check_added_monitors!(nodes[1], 1);
334+
330335
if intro_fails {
331336
let mut updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
332337
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
333338
do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);
339+
let failed_destination = match check {
340+
ForwardCheckFail::InboundOnionCheck => HTLCDestination::InvalidOnion,
341+
ForwardCheckFail::ForwardPayloadEncodedAsReceive => HTLCDestination::FailedPayment { payment_hash },
342+
ForwardCheckFail::OutboundChannelCheck =>
343+
HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_1_2.2 },
344+
};
345+
expect_htlc_handling_failed_destinations!(
346+
nodes[1].node.get_and_clear_pending_events(), &[failed_destination.clone()]
347+
);
334348
expect_payment_failed_conditions(&nodes[0], payment_hash, false,
335349
PaymentFailedConditions::new().expected_htlc_error_data(INVALID_ONION_BLINDING, &[0; 32]));
336350
return
337351
}
338352

339-
expect_pending_htlcs_forwardable!(nodes[1]);
340-
check_added_monitors!(nodes[1], 1);
341-
342353
let mut updates_1_2 = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
343354
let mut update_add = &mut updates_1_2.update_add_htlcs[0];
344355

@@ -348,6 +359,17 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
348359
check_added_monitors!(nodes[2], 0);
349360
do_commitment_signed_dance(&nodes[2], &nodes[1], &updates_1_2.commitment_signed, true, true);
350361

362+
expect_pending_htlcs_forwardable!(nodes[2]);
363+
let failed_destination = match check {
364+
ForwardCheckFail::InboundOnionCheck|ForwardCheckFail::ForwardPayloadEncodedAsReceive => HTLCDestination::InvalidOnion,
365+
ForwardCheckFail::OutboundChannelCheck =>
366+
HTLCDestination::NextHopChannel { node_id: Some(nodes[3].node.get_our_node_id()), channel_id: chan_2_3.2 },
367+
};
368+
expect_htlc_handling_failed_destinations!(
369+
nodes[2].node.get_and_clear_pending_events(), &[failed_destination.clone()]
370+
);
371+
check_added_monitors!(nodes[2], 1);
372+
351373
let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
352374
let update_malformed = &mut updates.update_fail_malformed_htlcs[0];
353375
assert_eq!(update_malformed.failure_code, INVALID_ONION_BLINDING);
@@ -407,7 +429,10 @@ fn failed_backwards_to_intro_node() {
407429
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]);
408430
check_added_monitors!(nodes[2], 0);
409431
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event.commitment_msg, true, true);
410-
nodes[2].node.process_pending_htlc_forwards();
432+
433+
expect_pending_htlcs_forwardable!(nodes[2]);
434+
expect_htlc_handling_failed_destinations!(nodes[2].node.get_and_clear_pending_events(), &[HTLCDestination::InvalidOnion]);
435+
check_added_monitors(&nodes[2], 1);
411436

412437
let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
413438
let mut update_malformed = &mut updates.update_fail_malformed_htlcs[0];
@@ -483,7 +508,7 @@ fn do_forward_fail_in_process_pending_htlc_fwds(check: ProcessPendingHTLCsCheck,
483508
// intro node will error backwards.
484509
$curr_node.node.peer_disconnected(&$next_node.node.get_our_node_id());
485510
expect_pending_htlcs_forwardable!($curr_node);
486-
expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!($curr_node,
511+
expect_htlc_handling_failed_destinations!($curr_node.node.get_and_clear_pending_events(),
487512
vec![HTLCDestination::NextHopChannel { node_id: Some($next_node.node.get_our_node_id()), channel_id: $failed_chan_id }]);
488513
},
489514
ProcessPendingHTLCsCheck::FwdChannelClosed => {
@@ -499,12 +524,12 @@ fn do_forward_fail_in_process_pending_htlc_fwds(check: ProcessPendingHTLCsCheck,
499524
crate::events::Event::ChannelClosed { .. } => {},
500525
_ => panic!("Unexpected event {:?}", events),
501526
}
527+
check_closed_broadcast(&$curr_node, 1, true);
528+
check_added_monitors!($curr_node, 1);
502529

503530
$curr_node.node.process_pending_htlc_forwards();
504-
expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!($curr_node,
531+
expect_htlc_handling_failed_destinations!($curr_node.node.get_and_clear_pending_events(),
505532
vec![HTLCDestination::UnknownNextHop { requested_forward_scid: $failed_scid }]);
506-
check_closed_broadcast(&$curr_node, 1, true);
507-
check_added_monitors!($curr_node, 1);
508533
$curr_node.node.process_pending_htlc_forwards();
509534
},
510535
}
@@ -590,6 +615,7 @@ fn do_blinded_intercept_payment(intercept_node_fails: bool) {
590615
};
591616
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
592617
commitment_signed_dance!(nodes[1], nodes[0], &payment_event.commitment_msg, false, true);
618+
expect_pending_htlcs_forwardable!(nodes[1]);
593619

594620
let events = nodes[1].node.get_and_clear_pending_events();
595621
assert_eq!(events.len(), 1);
@@ -891,13 +917,19 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
891917
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), update_add);
892918
check_added_monitors!(nodes[2], 0);
893919
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event_1_2.commitment_msg, true, true);
920+
expect_pending_htlcs_forwardable!(nodes[2]);
921+
expect_htlc_handling_failed_destinations!(nodes[2].node.get_and_clear_pending_events(), &[HTLCDestination::InvalidOnion]);
922+
check_added_monitors(&nodes[2], 1);
894923
},
895924
ReceiveCheckFail::ReceiveRequirements => {
896925
let update_add = &mut payment_event_1_2.msgs[0];
897926
update_add.amount_msat -= 1;
898927
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), update_add);
899928
check_added_monitors!(nodes[2], 0);
900929
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event_1_2.commitment_msg, true, true);
930+
expect_pending_htlcs_forwardable!(nodes[2]);
931+
expect_htlc_handling_failed_destinations!(nodes[2].node.get_and_clear_pending_events(), &[HTLCDestination::FailedPayment { payment_hash }]);
932+
check_added_monitors(&nodes[2], 1);
901933
},
902934
ReceiveCheckFail::ChannelCheck => {
903935
nodes[2].node.close_channel(&chan_id_1_2, &nodes[1].node.get_our_node_id()).unwrap();
@@ -911,6 +943,9 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
911943

912944
nodes[2].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
913945
commitment_signed_dance!(nodes[2], nodes[1], (), false, true, false, false);
946+
expect_pending_htlcs_forwardable!(nodes[2]);
947+
expect_htlc_handling_failed_destinations!(nodes[2].node.get_and_clear_pending_events(), &[HTLCDestination::FailedPayment { payment_hash }]);
948+
check_added_monitors(&nodes[2], 1);
914949
},
915950
ReceiveCheckFail::ProcessPendingHTLCsCheck => {
916951
assert_eq!(payment_event_1_2.msgs[0].cltv_expiry, nodes[0].best_block_info().1 + 1 + excess_final_cltv_delta_opt.unwrap() as u32 + TEST_FINAL_CLTV);
@@ -926,6 +961,9 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
926961
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event_1_2.msgs[0]);
927962
check_added_monitors!(nodes[2], 0);
928963
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event_1_2.commitment_msg, true, true);
964+
expect_pending_htlcs_forwardable!(nodes[2]);
965+
expect_htlc_handling_failed_destinations!(nodes[2].node.get_and_clear_pending_events(), &[HTLCDestination::FailedPayment { payment_hash }]);
966+
check_added_monitors(&nodes[2], 1);
929967
}
930968
}
931969

@@ -1126,6 +1164,12 @@ fn min_htlc() {
11261164
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event_0_1.msgs[0]);
11271165
check_added_monitors!(nodes[1], 0);
11281166
do_commitment_signed_dance(&nodes[1], &nodes[0], &payment_event_0_1.commitment_msg, true, true);
1167+
expect_pending_htlcs_forwardable!(nodes[1]);
1168+
expect_htlc_handling_failed_destinations!(
1169+
nodes[1].node.get_and_clear_pending_events(),
1170+
&[HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_1_2.2 }]
1171+
);
1172+
check_added_monitors(&nodes[1], 1);
11291173
let mut updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
11301174
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
11311175
do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);

lightning/src/ln/channel.rs

+10-45
Original file line numberDiff line numberDiff line change
@@ -4118,9 +4118,7 @@ impl<SP: Deref> Channel<SP> where
41184118
Ok(self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block.height, logger))
41194119
}
41204120

4121-
pub fn update_add_htlc(
4122-
&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_status: PendingHTLCStatus,
4123-
) -> Result<(), ChannelError> {
4121+
pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC) -> Result<(), ChannelError> {
41244122
if !matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
41254123
return Err(ChannelError::Close("Got add HTLC message when channel was not in an operational state".to_owned()));
41264124
}
@@ -4218,21 +4216,15 @@ impl<SP: Deref> Channel<SP> where
42184216
return Err(ChannelError::Close("Remote provided CLTV expiry in seconds instead of block height".to_owned()));
42194217
}
42204218

4221-
if self.context.channel_state.is_local_shutdown_sent() {
4222-
if let PendingHTLCStatus::Forward(_) = pending_forward_status {
4223-
panic!("ChannelManager shouldn't be trying to add a forwardable HTLC after we've started closing");
4224-
}
4225-
}
4226-
42274219
// Now update local state:
42284220
self.context.next_counterparty_htlc_id += 1;
42294221
self.context.pending_inbound_htlcs.push(InboundHTLCOutput {
42304222
htlc_id: msg.htlc_id,
42314223
amount_msat: msg.amount_msat,
42324224
payment_hash: msg.payment_hash,
42334225
cltv_expiry: msg.cltv_expiry,
4234-
state: InboundHTLCState::RemoteAnnounced(InboundHTLCResolution::Resolved {
4235-
pending_htlc_status: pending_forward_status
4226+
state: InboundHTLCState::RemoteAnnounced(InboundHTLCResolution::Pending {
4227+
update_add_htlc: msg.clone(),
42364228
}),
42374229
});
42384230
Ok(())
@@ -6115,7 +6107,7 @@ impl<SP: Deref> Channel<SP> where
61156107
};
61166108
let exposure_dust_limit_timeout_sats = htlc_timeout_dust_limit + self.context.counterparty_dust_limit_satoshis;
61176109
if msg.amount_msat / 1000 < exposure_dust_limit_timeout_sats {
6118-
let on_counterparty_tx_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat + msg.amount_msat;
6110+
let on_counterparty_tx_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat;
61196111
if on_counterparty_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat {
61206112
log_info!(logger, "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx",
61216113
on_counterparty_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat);
@@ -6125,7 +6117,7 @@ impl<SP: Deref> Channel<SP> where
61256117

61266118
let exposure_dust_limit_success_sats = htlc_success_dust_limit + self.context.holder_dust_limit_satoshis;
61276119
if msg.amount_msat / 1000 < exposure_dust_limit_success_sats {
6128-
let on_holder_tx_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat + msg.amount_msat;
6120+
let on_holder_tx_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat;
61296121
if on_holder_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat {
61306122
log_info!(logger, "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx",
61316123
on_holder_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat);
@@ -6159,11 +6151,11 @@ impl<SP: Deref> Channel<SP> where
61596151
// side, only on the sender's. Note that with anchor outputs we are no longer as
61606152
// sensitive to fee spikes, so we need to account for them.
61616153
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
6162-
let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
6154+
let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, None);
61636155
if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
61646156
remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
61656157
}
6166-
if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(self.context.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat {
6158+
if pending_remote_value_msat.saturating_sub(self.context.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat {
61676159
log_info!(logger, "Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", &self.context.channel_id());
61686160
return Err(("Fee spike buffer violation", 0x1000|7));
61696161
}
@@ -8367,18 +8359,7 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
83678359
// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
83688360
// called.
83698361

8370-
let version_to_write = if self.context.pending_inbound_htlcs.iter().any(|htlc| match htlc.state {
8371-
InboundHTLCState::AwaitingRemoteRevokeToAnnounce(ref htlc_resolution)|
8372-
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(ref htlc_resolution) => {
8373-
matches!(htlc_resolution, InboundHTLCResolution::Pending { .. })
8374-
},
8375-
_ => false,
8376-
}) {
8377-
SERIALIZATION_VERSION
8378-
} else {
8379-
MIN_SERIALIZATION_VERSION
8380-
};
8381-
write_ver_prefix!(writer, version_to_write, MIN_SERIALIZATION_VERSION);
8362+
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
83828363

83838364
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
83848365
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We write
@@ -8436,27 +8417,11 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
84368417
&InboundHTLCState::RemoteAnnounced(_) => unreachable!(),
84378418
&InboundHTLCState::AwaitingRemoteRevokeToAnnounce(ref htlc_resolution) => {
84388419
1u8.write(writer)?;
8439-
if version_to_write <= 3 {
8440-
if let InboundHTLCResolution::Resolved { pending_htlc_status } = htlc_resolution {
8441-
pending_htlc_status.write(writer)?;
8442-
} else {
8443-
panic!();
8444-
}
8445-
} else {
8446-
htlc_resolution.write(writer)?;
8447-
}
8420+
htlc_resolution.write(writer)?;
84488421
},
84498422
&InboundHTLCState::AwaitingAnnouncedRemoteRevoke(ref htlc_resolution) => {
84508423
2u8.write(writer)?;
8451-
if version_to_write <= 3 {
8452-
if let InboundHTLCResolution::Resolved { pending_htlc_status } = htlc_resolution {
8453-
pending_htlc_status.write(writer)?;
8454-
} else {
8455-
panic!();
8456-
}
8457-
} else {
8458-
htlc_resolution.write(writer)?;
8459-
}
8424+
htlc_resolution.write(writer)?;
84608425
},
84618426
&InboundHTLCState::Committed => {
84628427
3u8.write(writer)?;

0 commit comments

Comments
 (0)