@@ -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, Route, RouteHop, RouteParameters, RouteParametersConfig, Router };
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};
@@ -628,6 +628,7 @@ impl Readable for InterceptId {
628628pub(crate) enum SentHTLCId {
629629 PreviousHopData { short_channel_id: u64, htlc_id: u64 },
630630 OutboundRoute { session_priv: [u8; SECRET_KEY_SIZE] },
631+ TrampolineForward { session_priv: [u8; SECRET_KEY_SIZE], previous_short_channel_id: u64, htlc_id: u64 }
631632}
632633impl SentHTLCId {
633634 pub(crate) fn from_source(source: &HTLCSource) -> Self {
@@ -638,6 +639,11 @@ impl SentHTLCId {
638639 },
639640 HTLCSource::OutboundRoute { session_priv, .. } =>
640641 Self::OutboundRoute { session_priv: session_priv.secret_bytes() },
642+ HTLCSource::TrampolineForward { previous_hop_data, session_priv, .. } => Self::TrampolineForward {
643+ session_priv: session_priv.secret_bytes(),
644+ previous_short_channel_id: previous_hop_data.short_channel_id,
645+ htlc_id: previous_hop_data.htlc_id,
646+ },
641647 }
642648 }
643649}
@@ -649,6 +655,11 @@ impl_writeable_tlv_based_enum!(SentHTLCId,
649655 (2, OutboundRoute) => {
650656 (0, session_priv, required),
651657 },
658+ (4, TrampolineForward) => {
659+ (0, session_priv, required),
660+ (2, previous_short_channel_id, required),
661+ (4, htlc_id, required),
662+ },
652663);
653664
654665mod fuzzy_channelmanager {
@@ -659,6 +670,12 @@ mod fuzzy_channelmanager {
659670 #[derive(Clone, Debug, PartialEq, Eq)]
660671 pub enum HTLCSource {
661672 PreviousHopData(HTLCPreviousHopData),
673+ TrampolineForward {
674+ previous_hop_data: HTLCPreviousHopData,
675+ incoming_trampoline_shared_secret: [u8; 32],
676+ hops: Vec<RouteHop>,
677+ session_priv: SecretKey,
678+ },
662679 OutboundRoute {
663680 path: Path,
664681 session_priv: SecretKey,
@@ -710,6 +727,13 @@ impl core::hash::Hash for HTLCSource {
710727 payment_id.hash(hasher);
711728 first_hop_htlc_msat.hash(hasher);
712729 },
730+ HTLCSource::TrampolineForward { previous_hop_data, incoming_trampoline_shared_secret, hops, session_priv } => {
731+ 2u8.hash(hasher);
732+ previous_hop_data.hash(hasher);
733+ incoming_trampoline_shared_secret.hash(hasher);
734+ hops.hash(hasher);
735+ session_priv[..].hash(hasher);
736+ },
713737 }
714738 }
715739}
@@ -7067,6 +7091,61 @@ where
70677091 failed_next_destination: destination,
70687092 }, None));
70697093 },
7094+ HTLCSource::TrampolineForward { previous_hop_data, incoming_trampoline_shared_secret, .. } => {
7095+ // todo: what do we want to do with this given we do not wish to propagate it directly?
7096+ let _decoded_onion_failure = onion_error.decode_onion_failure(&self.secp_ctx, &self.logger, &source);
7097+
7098+ let incoming_packet_shared_secret = previous_hop_data.incoming_packet_shared_secret;
7099+ let channel_id = previous_hop_data.channel_id;
7100+ let short_channel_id = previous_hop_data.short_channel_id;
7101+ let htlc_id = previous_hop_data.htlc_id;
7102+ let blinded_failure = previous_hop_data.blinded_failure;
7103+ log_trace!(
7104+ WithContext::from(&self.logger, None, Some(channel_id), Some(*payment_hash)),
7105+ "Failing {}HTLC with payment_hash {} backwards from us following Trampoline forwarding failure: {:?}",
7106+ if blinded_failure.is_some() { "blinded " } else { "" }, &payment_hash, onion_error
7107+ );
7108+ let failure = match blinded_failure {
7109+ Some(BlindedFailure::FromIntroductionNode) => {
7110+ let blinded_onion_error = HTLCFailReason::reason(INVALID_ONION_BLINDING, vec![0; 32]);
7111+ let err_packet = blinded_onion_error.get_encrypted_failure_packet(
7112+ &incoming_packet_shared_secret, &Some(incoming_trampoline_shared_secret.clone())
7113+ );
7114+ HTLCForwardInfo::FailHTLC { htlc_id, err_packet }
7115+ },
7116+ Some(BlindedFailure::FromBlindedNode) => {
7117+ HTLCForwardInfo::FailMalformedHTLC {
7118+ htlc_id,
7119+ failure_code: INVALID_ONION_BLINDING,
7120+ sha256_of_onion: [0; 32]
7121+ }
7122+ },
7123+ None => {
7124+ let err_code = 0x2000 | 25;
7125+ let err_packet = HTLCFailReason::reason(err_code, Vec::new())
7126+ .get_encrypted_failure_packet(&incoming_packet_shared_secret, &Some(incoming_trampoline_shared_secret.clone()));
7127+ HTLCForwardInfo::FailHTLC { htlc_id, err_packet }
7128+ }
7129+ };
7130+
7131+ push_forward_event = self.decode_update_add_htlcs.lock().unwrap().is_empty();
7132+ let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
7133+ push_forward_event &= forward_htlcs.is_empty();
7134+ match forward_htlcs.entry(short_channel_id) {
7135+ hash_map::Entry::Occupied(mut entry) => {
7136+ entry.get_mut().push(failure);
7137+ },
7138+ hash_map::Entry::Vacant(entry) => {
7139+ entry.insert(vec!(failure));
7140+ }
7141+ }
7142+ mem::drop(forward_htlcs);
7143+ let mut pending_events = self.pending_events.lock().unwrap();
7144+ pending_events.push_back((events::Event::HTLCHandlingFailed {
7145+ prev_channel_id: channel_id,
7146+ failed_next_destination: destination,
7147+ }, None));
7148+ },
70707149 }
70717150 push_forward_event
70727151 }
@@ -7471,7 +7550,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
74717550 session_priv, path, from_onchain, ev_completion_action, &self.pending_events,
74727551 &self.logger);
74737552 },
7474- HTLCSource::PreviousHopData(hop_data) => {
7553+ HTLCSource::PreviousHopData(hop_data) | HTLCSource::TrampolineForward { previous_hop_data: hop_data, .. } => {
74757554 let prev_channel_id = hop_data.channel_id;
74767555 let prev_user_channel_id = hop_data.user_channel_id;
74777556 let prev_node_id = hop_data.counterparty_node_id;
@@ -13176,6 +13255,24 @@ impl Readable for HTLCSource {
1317613255 })
1317713256 }
1317813257 1 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)),
13258+ 2 => {
13259+ let mut previous_hop_data: crate::util::ser::RequiredWrapper<HTLCPreviousHopData> = crate::util::ser::RequiredWrapper(None);
13260+ let mut incoming_trampoline_shared_secret: crate::util::ser::RequiredWrapper<[u8; 32]> = crate::util::ser::RequiredWrapper(None);
13261+ let mut session_priv: crate::util::ser::RequiredWrapper<SecretKey> = crate::util::ser::RequiredWrapper(None);
13262+ let mut hops = Vec::new();
13263+ read_tlv_fields!(reader, {
13264+ (0, previous_hop_data, required),
13265+ (2, incoming_trampoline_shared_secret, required),
13266+ (4, session_priv, required),
13267+ (6, hops, required_vec),
13268+ });
13269+ Ok(HTLCSource::TrampolineForward {
13270+ previous_hop_data: previous_hop_data.0.unwrap(),
13271+ incoming_trampoline_shared_secret: incoming_trampoline_shared_secret.0.unwrap(),
13272+ hops,
13273+ session_priv: session_priv.0.unwrap(),
13274+ })
13275+ },
1317913276 _ => Err(DecodeError::UnknownRequiredFeature),
1318013277 }
1318113278 }
@@ -13201,6 +13298,16 @@ impl Writeable for HTLCSource {
1320113298 1u8.write(writer)?;
1320213299 field.write(writer)?;
1320313300 }
13301+ HTLCSource::TrampolineForward { ref previous_hop_data, ref incoming_trampoline_shared_secret, ref session_priv, hops: hops_ref } => {
13302+ 2u8.write(writer)?;
13303+ let hops = hops_ref.clone();
13304+ write_tlv_fields!(writer, {
13305+ (0, previous_hop_data, required),
13306+ (2, incoming_trampoline_shared_secret, required),
13307+ (4, session_priv, required),
13308+ (6, hops, required_vec),
13309+ });
13310+ }
1320413311 }
1320513312 Ok(())
1320613313 }
@@ -14334,7 +14441,7 @@ where
1433414441 for (htlc_source, (htlc, preimage_opt)) in monitor.get_all_current_outbound_htlcs() {
1433514442 let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash));
1433614443 match htlc_source {
14337- HTLCSource::PreviousHopData(prev_hop_data) => {
14444+ HTLCSource::PreviousHopData(prev_hop_data) | HTLCSource::TrampolineForward { previous_hop_data: prev_hop_data, .. } => {
1433814445 let pending_forward_matches_htlc = |info: &PendingAddHTLCInfo| {
1433914446 info.prev_funding_outpoint == prev_hop_data.outpoint &&
1434014447 info.prev_htlc_id == prev_hop_data.htlc_id
0 commit comments