Add TrampolineForward variant to PendingHTLCRouting

Forwarding Trampoline packets requires storing their shared secrets on
top of the outer onion's shared secrets, as well as referencing the
next hop by its node ID as opposed to by an SCID. We modify
PendingHTLCRouting to adequately represent this information.
This commit is contained in:
Arik Sosman 2025-02-09 22:42:25 -08:00
parent 4d9deff091
commit b616559aae
No known key found for this signature in database
GPG key ID: CFF795E7811C0093
2 changed files with 64 additions and 0 deletions

View file

@ -62,6 +62,7 @@ check-cfg = [
"cfg(ldk_bench)",
"cfg(ldk_test_vectors)",
"cfg(taproot)",
"cfg(trampoline)",
"cfg(require_route_graph_test)",
"cfg(splicing)",
"cfg(async_payments)",

View file

@ -55,6 +55,8 @@ use crate::ln::channel_state::ChannelDetails;
use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
#[cfg(any(feature = "_test_utils", test))]
use crate::types::features::Bolt11InvoiceFeatures;
#[cfg(trampoline)]
use crate::routing::gossip::NodeId;
use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, Router};
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundHTLCErr, NextPacketDetails};
use crate::ln::msgs;
@ -169,6 +171,24 @@ pub enum PendingHTLCRouting {
/// The absolute CLTV of the inbound HTLC
incoming_cltv_expiry: Option<u32>,
},
/// An HTLC which should be forwarded on to another Trampoline node.
#[cfg(trampoline)]
TrampolineForward {
/// The onion shared secret we build with the sender (or the preceding Trampoline node) used
/// to decrypt the onion.
///
/// This is later used to encrypt failure packets in the event that the HTLC is failed.
incoming_shared_secret: [u8; 32],
/// The onion which should be included in the forwarded HTLC, telling the next hop what to
/// do with the HTLC.
onion_packet: msgs::TrampolineOnionPacket,
/// The node ID of the Trampoline node which we need to route this HTLC to.
node_id: NodeId,
/// Set if this HTLC is being forwarded within a blinded path.
blinded: Option<BlindedForward>,
/// The absolute CLTV of the inbound HTLC
incoming_cltv_expiry: u32,
},
/// The onion indicates that this is a payment for an invoice (supposedly) generated by us.
///
/// Note that at this point, we have not checked that the invoice being paid was actually
@ -270,6 +290,8 @@ impl PendingHTLCRouting {
fn blinded_failure(&self) -> Option<BlindedFailure> {
match self {
Self::Forward { blinded: Some(BlindedForward { failure, .. }), .. } => Some(*failure),
#[cfg(trampoline)]
Self::TrampolineForward { blinded: Some(BlindedForward { failure, .. }), .. } => Some(*failure),
Self::Receive { requires_blinded_error: true, .. } => Some(BlindedFailure::FromBlindedNode),
Self::ReceiveKeysend { requires_blinded_error: true, .. } => Some(BlindedFailure::FromBlindedNode),
_ => None,
@ -279,6 +301,8 @@ impl PendingHTLCRouting {
fn incoming_cltv_expiry(&self) -> Option<u32> {
match self {
Self::Forward { incoming_cltv_expiry, .. } => *incoming_cltv_expiry,
#[cfg(trampoline)]
Self::TrampolineForward { incoming_cltv_expiry, .. } => Some(*incoming_cltv_expiry),
Self::Receive { incoming_cltv_expiry, .. } => Some(*incoming_cltv_expiry),
Self::ReceiveKeysend { incoming_cltv_expiry, .. } => Some(*incoming_cltv_expiry),
}
@ -8909,6 +8933,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
let scid = match forward_info.routing {
PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id,
#[cfg(trampoline)]
PendingHTLCRouting::TrampolineForward { .. } => 0,
PendingHTLCRouting::Receive { .. } => 0,
PendingHTLCRouting::ReceiveKeysend { .. } => 0,
};
@ -12449,6 +12475,7 @@ impl_writeable_tlv_based!(BlindedForward, {
(3, next_blinding_override, option),
});
#[cfg(not(trampoline))]
impl_writeable_tlv_based_enum!(PendingHTLCRouting,
(0, Forward) => {
(0, onion_packet, required),
@ -12477,6 +12504,42 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
(11, invoice_request, option),
},
);
#[cfg(trampoline)]
impl_writeable_tlv_based_enum!(PendingHTLCRouting,
(0, Forward) => {
(0, onion_packet, required),
(1, blinded, option),
(2, short_channel_id, required),
(3, incoming_cltv_expiry, option),
},
(1, Receive) => {
(0, payment_data, required),
(1, phantom_shared_secret, option),
(2, incoming_cltv_expiry, required),
(3, payment_metadata, option),
(5, custom_tlvs, optional_vec),
(7, requires_blinded_error, (default_value, false)),
(9, payment_context, option),
},
(2, ReceiveKeysend) => {
(0, payment_preimage, required),
(1, requires_blinded_error, (default_value, false)),
(2, incoming_cltv_expiry, required),
(3, payment_metadata, option),
(4, payment_data, option), // Added in 0.0.116
(5, custom_tlvs, optional_vec),
(7, has_recipient_created_payment_secret, (default_value, false)),
(9, payment_context, option),
(11, invoice_request, option),
},
(3, TrampolineForward) => {
(0, incoming_shared_secret, required),
(2, onion_packet, required),
(4, blinded, option),
(6, node_id, required),
(8, incoming_cltv_expiry, required),
}
);
impl_writeable_tlv_based!(PendingHTLCInfo, {
(0, routing, required),