@@ -56,7 +56,7 @@ use crate::ln::channel_state::ChannelDetails;
5656use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
5757#[cfg(any(feature = "_test_utils", test))]
5858use crate::types::features::Bolt11InvoiceFeatures;
59- use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, RouteParametersConfig, Router, FixedRouter, Route };
59+ use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, RouteParametersConfig, Route, RouteHop, Router, MAX_PATH_LENGTH_ESTIMATE };
6060use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, HopConnector, InboundHTLCErr, NextPacketDetails};
6161use crate::ln::msgs;
6262use crate::ln::onion_utils::{self};
@@ -186,6 +186,8 @@ pub enum PendingHTLCRouting {
186186 blinded: Option<BlindedForward>,
187187 /// The absolute CLTV of the inbound HTLC
188188 incoming_cltv_expiry: u32,
189+ /// Path to send the packet to the next hop
190+ hops: Vec<RouteHop>
189191 },
190192 /// The onion indicates that this is a payment for an invoice (supposedly) generated by us.
191193 ///
@@ -4353,8 +4355,6 @@ where
43534355 // we don't have the channel here.
43544356 return Err(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10));
43554357 }
4356- } else {
4357- return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
43584358 }
43594359
43604360 // Note that we could technically not return an error yet here and just hope
@@ -4404,12 +4404,17 @@ where
44044404 }
44054405
44064406 fn can_forward_htlc(
4407- &self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
4407+ &self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails, trampoline_outgoing_scid: Option<u64>
44084408 ) -> Result<(), (&'static str, u16)> {
44094409 let outgoing_scid = match next_packet_details.outgoing_connector {
44104410 HopConnector::ShortChannelId(scid) => scid,
44114411 HopConnector::Trampoline(_) => {
4412- return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
4412+ match trampoline_outgoing_scid {
4413+ Some(scid) => scid,
4414+ None => {
4415+ return Err(("Cannot forward by Node ID without SCID.", 0x4000 | 10));
4416+ }
4417+ }
44134418 }
44144419 };
44154420 match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
@@ -4494,6 +4499,7 @@ where
44944499 &self, msg: &msgs::UpdateAddHTLC, counterparty_node_id: &PublicKey, shared_secret: [u8; 32],
44954500 decoded_hop: onion_utils::Hop, allow_underpay: bool,
44964501 next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>,
4502+ inter_trampoline_path_option: Option<Vec<RouteHop>>
44974503 ) -> PendingHTLCStatus {
44984504 macro_rules! return_err {
44994505 ($msg: expr, $err_code: expr, $data: expr) => {
@@ -4541,13 +4547,13 @@ where
45414547 }
45424548 },
45434549 onion_utils::Hop::Forward { .. } | onion_utils::Hop::BlindedForward { .. } => {
4544- match create_fwd_pending_htlc_info(msg, decoded_hop, shared_secret, next_packet_pubkey_opt) {
4550+ match create_fwd_pending_htlc_info(msg, decoded_hop, shared_secret, next_packet_pubkey_opt, None ) {
45454551 Ok(info) => PendingHTLCStatus::Forward(info),
45464552 Err(InboundHTLCErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
45474553 }
45484554 },
45494555 onion_utils::Hop::TrampolineForward { .. } | onion_utils::Hop::TrampolineBlindedForward { .. } => {
4550- match create_fwd_pending_htlc_info(msg, decoded_hop, shared_secret, next_packet_pubkey_opt) {
4556+ match create_fwd_pending_htlc_info(msg, decoded_hop, shared_secret, next_packet_pubkey_opt, inter_trampoline_path_option ) {
45514557 Ok(info) => PendingHTLCStatus::Forward(info),
45524558 Err(InboundHTLCErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
45534559 }
@@ -5828,10 +5834,50 @@ where
58285834 None => continue 'outer_loop,
58295835 }
58305836
5837+ let mut inter_trampoline_path = None;
5838+
58315839 // Now process the HTLC on the outgoing channel if it's a forward.
58325840 if let Some(next_packet_details) = next_packet_details_opt.as_ref() {
5841+ let first_hop_scid_override = match (&next_packet_details.outgoing_connector, &next_hop) {
5842+ (HopConnector::Trampoline(next_node_id), onion_utils::Hop::TrampolineForward { ref outer_hop_data, .. } | onion_utils::Hop::TrampolineBlindedForward { ref outer_hop_data, .. }) => {
5843+ let incoming_amount = outer_hop_data.amt_to_forward;
5844+ let incoming_cltv = outer_hop_data.outgoing_cltv_value;
5845+ let outgoing_amount = next_packet_details.outgoing_amt_msat;
5846+ let outgoing_cltv = next_packet_details.outgoing_cltv_value;
5847+
5848+ let routes = self.router.find_route(
5849+ &self.node_signer.get_node_id(Recipient::Node).unwrap(),
5850+ &RouteParameters {
5851+ payment_params: PaymentParameters {
5852+ payee: Payee::Clear {
5853+ node_id: next_node_id.clone(),
5854+ route_hints: vec![],
5855+ features: None,
5856+ final_cltv_expiry_delta: 0,
5857+ },
5858+ expiry_time: None,
5859+ max_total_cltv_expiry_delta: incoming_cltv - outgoing_cltv,
5860+ max_path_count: 1,
5861+ max_path_length: MAX_PATH_LENGTH_ESTIMATE.div_ceil(2),
5862+ max_channel_saturation_power_of_half: 2,
5863+ previously_failed_channels: vec![],
5864+ previously_failed_blinded_path_idxs: vec![],
5865+ },
5866+ final_value_msat: outgoing_amount,
5867+ max_total_routing_fee_msat: Some(incoming_amount - outgoing_amount),
5868+ },
5869+ None,
5870+ InFlightHtlcs::new()
5871+ ).unwrap();
5872+
5873+ inter_trampoline_path = routes.paths.first().map(|path| path.hops.clone());
5874+ inter_trampoline_path.as_ref().and_then(|hops| hops.first().map(|hop| hop.short_channel_id))
5875+ },
5876+ _ => None
5877+ };
5878+
58335879 if let Err((err, code)) = self.can_forward_htlc(
5834- &update_add_htlc, next_packet_details
5880+ &update_add_htlc, next_packet_details, first_hop_scid_override
58355881 ) {
58365882 let htlc_fail = self.htlc_failure_from_update_add_err(
58375883 &update_add_htlc, &incoming_counterparty_node_id, err, code,
@@ -5845,7 +5891,7 @@ where
58455891
58465892 match self.construct_pending_htlc_status(
58475893 &update_add_htlc, &incoming_counterparty_node_id, shared_secret, next_hop,
5848- incoming_accept_underpaying_htlcs, next_packet_details_opt.map(|d| d.next_packet_pubkey),
5894+ incoming_accept_underpaying_htlcs, next_packet_details_opt.map(|d| d.next_packet_pubkey), inter_trampoline_path
58495895 ) {
58505896 PendingHTLCStatus::Forward(htlc_forward) => {
58515897 htlc_forwards.push((htlc_forward, update_add_htlc.htlc_id));
@@ -9086,7 +9132,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
90869132 for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
90879133 let scid = match forward_info.routing {
90889134 PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id,
9089- PendingHTLCRouting::TrampolineForward { .. } => 0 ,
9135+ PendingHTLCRouting::TrampolineForward { ref hops, .. } => hops.first().map_or(0, |hop| hop.short_channel_id) ,
90909136 PendingHTLCRouting::Receive { .. } => 0,
90919137 PendingHTLCRouting::ReceiveKeysend { .. } => 0,
90929138 };
@@ -12950,6 +12996,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1295012996 (4, blinded, option),
1295112997 (6, node_id, required),
1295212998 (8, incoming_cltv_expiry, required),
12999+ (10, hops, required),
1295313000 }
1295413001);
1295513002
0 commit comments