@@ -63,7 +63,7 @@ use crate::ln::onion_utils::{HTLCFailReason, LocalHTLCFailureReason};
6363use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, CommitmentUpdate, DecodeError, FinalOnionHopData, LightningError, MessageSendEvent};
6464#[cfg(test)]
6565use crate::ln::outbound_payment;
66- use crate::ln::outbound_payment::{Bolt11PaymentError, OutboundPayments, PendingOutboundPayment, RetryableInvoiceRequest, SendAlongPathArgs, StaleExpiration};
66+ use crate::ln::outbound_payment::{Bolt11PaymentError, NextTrampolineHopInfo, OutboundPayments, PendingOutboundPayment, RetryableInvoiceRequest, SendAlongPathArgs, StaleExpiration, TrampolineForwardInfo };
6767use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6868use crate::offers::invoice_error::InvoiceError;
6969use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
@@ -670,7 +670,7 @@ impl_writeable_tlv_based_enum!(SentHTLCId,
670670 },
671671 (4, TrampolineForward) => {
672672 (0, session_priv, required),
673- (2, previous_hop_data , required_vec),
673+ (2, previous_hop_ids , required_vec),
674674 },
675675);
676676
@@ -4667,24 +4667,35 @@ where
46674667 let _lck = self.total_consistency_lock.read().unwrap();
46684668 self.send_payment_along_path(SendAlongPathArgs {
46694669 path, payment_hash, recipient_onion: &recipient_onion, total_value,
4670- cur_height, payment_id, keysend_preimage, invoice_request: None, session_priv_bytes
4670+ cur_height, payment_id, keysend_preimage, invoice_request: None, session_priv_bytes,
4671+ trampoline_forward_info: None
46714672 })
46724673 }
46734674
46744675 fn send_payment_along_path(&self, args: SendAlongPathArgs) -> Result<(), APIError> {
46754676 let SendAlongPathArgs {
46764677 path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
4677- invoice_request, session_priv_bytes
4678+ invoice_request, session_priv_bytes, trampoline_forward_info
46784679 } = args;
46794680 // The top-level caller should hold the total_consistency_lock read lock.
46804681 debug_assert!(self.total_consistency_lock.try_write().is_err());
46814682 let prng_seed = self.entropy_source.get_secure_random_bytes();
46824683 let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
46834684
4684- let (onion_packet, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion(
4685- &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height,
4686- payment_hash, keysend_preimage, invoice_request, prng_seed
4687- ).map_err(|e| {
4685+ let onion_result = if let Some(trampoline_forward_info) = trampoline_forward_info {
4686+ // todo: ensure inter-Trampoline payment secret is always available for Trampoline forwards
4687+ onion_utils::create_trampoline_forward_onion(
4688+ &self.secp_ctx, &path, &session_priv, total_value, recipient_onion.payment_secret.unwrap(), cur_height,
4689+ payment_hash, keysend_preimage, &trampoline_forward_info.next_hop_info, prng_seed
4690+ )
4691+ } else {
4692+ onion_utils::create_payment_onion(
4693+ &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height,
4694+ payment_hash, keysend_preimage, invoice_request, prng_seed
4695+ )
4696+ };
4697+
4698+ let (onion_packet, htlc_msat, htlc_cltv) = onion_result.map_err(|e| {
46884699 let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
46894700 log_error!(logger, "Failed to build an onion for path for payment hash {}", payment_hash);
46904701 e
@@ -4718,13 +4729,25 @@ where
47184729 }
47194730 let funding_txo = chan.funding.get_funding_txo().unwrap();
47204731 let logger = WithChannelContext::from(&self.logger, &chan.context, Some(*payment_hash));
4721- let send_res = chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(),
4722- htlc_cltv, HTLCSource::OutboundRoute {
4732+
4733+ let htlc_source = match trampoline_forward_info {
4734+ None => HTLCSource::OutboundRoute {
47234735 path: path.clone(),
47244736 session_priv: session_priv.clone(),
47254737 first_hop_htlc_msat: htlc_msat,
47264738 payment_id,
4727- }, onion_packet, None, &self.fee_estimator, &&logger);
4739+ },
4740+ Some(trampoline_forward_info) => HTLCSource::TrampolineForward {
4741+ previous_hop_data: trampoline_forward_info.previous_hop_data.clone(),
4742+ // todo: fix
4743+ incoming_trampoline_shared_secret: [0; 32],
4744+ session_priv: session_priv.clone(),
4745+ hops: path.clone().hops,
4746+ }
4747+ };
4748+
4749+ let send_res = chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(),
4750+ htlc_cltv, htlc_source, onion_packet, None, &self.fee_estimator, &&logger);
47284751 match break_channel_entry!(self, peer_state, send_res, chan_entry) {
47294752 Some(monitor_update) => {
47304753 match handle_new_monitor_update!(self, funding_txo, monitor_update, peer_state_lock, peer_state, per_peer_state, chan) {
@@ -6300,33 +6323,74 @@ where
63006323 }
63016324 };
63026325
6303- let usable_channels: Vec<ChannelDetails> = self.list_usable_channels();
6304-
63056326 // assume any Trampoline node supports MPP
63066327 let mut recipient_features = Bolt11InvoiceFeatures::empty();
63076328 recipient_features.set_basic_mpp_optional();
63086329
6309- let route = match self.router.find_route(
6310- &self.node_signer.get_node_id(Recipient::Node).unwrap(),
6311- &RouteParameters {
6312- payment_params: PaymentParameters {
6313- payee: Payee::Clear {
6314- node_id: next_node_id,
6315- route_hints: vec![],
6316- features: Some(recipient_features),
6317- final_cltv_expiry_delta: 0,
6318- },
6319- expiry_time: None,
6320- max_total_cltv_expiry_delta: cltv_expiry_delta,
6321- max_path_count: DEFAULT_MAX_PATH_COUNT,
6322- max_path_length: MAX_PATH_LENGTH_ESTIMATE / 2,
6323- max_channel_saturation_power_of_half: 2,
6324- previously_failed_channels: vec![],
6325- previously_failed_blinded_path_idxs: vec![],
6330+ println!("PATH CONSTRUCTION CLTV: {} -> {} (delta: {})", incoming_cltv_expiry, outgoing_cltv_value, cltv_expiry_delta);
6331+
6332+ let route_parameters = RouteParameters {
6333+ payment_params: PaymentParameters {
6334+ payee: Payee::Clear {
6335+ node_id: next_node_id,
6336+ route_hints: vec![],
6337+ features: Some(recipient_features),
6338+ final_cltv_expiry_delta: 4,
63266339 },
6327- final_value_msat: outgoing_amt_msat,
6328- max_total_routing_fee_msat: Some(max_total_routing_fee_msat),
6340+ expiry_time: None,
6341+ max_total_cltv_expiry_delta: cltv_expiry_delta,
6342+ max_path_count: DEFAULT_MAX_PATH_COUNT,
6343+ max_path_length: MAX_PATH_LENGTH_ESTIMATE / 2,
6344+ max_channel_saturation_power_of_half: 2,
6345+ previously_failed_channels: vec![],
6346+ previously_failed_blinded_path_idxs: vec![],
63296347 },
6348+ final_value_msat: outgoing_amt_msat,
6349+ max_total_routing_fee_msat: Some(max_total_routing_fee_msat),
6350+ };
6351+
6352+ self.pending_outbound_payments.send_payment_for_trampoline_forward(
6353+ PaymentId(payment_hash.0),
6354+ payment_hash,
6355+ TrampolineForwardInfo {
6356+ next_hop_info: NextTrampolineHopInfo {
6357+ onion_packet: onion_packet.clone(),
6358+ blinding_point: next_blinding_point,
6359+ },
6360+ previous_hop_data: vec![HTLCPreviousHopData {
6361+ short_channel_id: prev_short_channel_id,
6362+ user_channel_id: Some(prev_user_channel_id),
6363+ counterparty_node_id: prev_counterparty_node_id,
6364+ channel_id: prev_channel_id,
6365+ outpoint: prev_funding_outpoint,
6366+ htlc_id: prev_htlc_id,
6367+ incoming_packet_shared_secret: incoming_outer_shared_secret,
6368+ // Phantom payments are only PendingHTLCRouting::Receive.
6369+ phantom_shared_secret: None,
6370+ blinded_failure: blinded.map(|b| b.failure),
6371+ cltv_expiry: Some(incoming_cltv_expiry),
6372+ }],
6373+ },
6374+ Retry::Attempts(3),
6375+ route_parameters.clone(),
6376+ &self.router,
6377+ self.list_usable_channels(),
6378+ || self.compute_inflight_htlcs(),
6379+ &self.entropy_source,
6380+ &self.node_signer,
6381+ self.current_best_block().height,
6382+ &self.logger,
6383+ &self.pending_events,
6384+ |args| self.send_payment_along_path(args)
6385+ );
6386+
6387+ continue;
6388+
6389+ let usable_channels: Vec<ChannelDetails> = self.list_usable_channels();
6390+
6391+ let route = match self.router.find_route(
6392+ &self.node_signer.get_node_id(Recipient::Node).unwrap(),
6393+ &route_parameters,
63306394 Some(&usable_channels.iter().collect::<Vec<_>>()),
63316395 self.compute_inflight_htlcs()
63326396 ) {
@@ -6414,6 +6478,7 @@ where
64146478 }
64156479 }
64166480
6481+
64176482 let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &inter_trampoline_session_priv);
64186483 let outer_onion_prng_seed = self.entropy_source.get_secure_random_bytes();
64196484 let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, outer_onion_prng_seed, &payment_hash).unwrap();
0 commit comments