@@ -63,7 +63,7 @@ use crate::ln::onion_utils::{HTLCFailReason, LocalHTLCFailureReason};
63
63
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, CommitmentUpdate, DecodeError, FinalOnionHopData, LightningError, MessageSendEvent};
64
64
#[cfg(test)]
65
65
use 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 };
67
67
use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
68
68
use crate::offers::invoice_error::InvoiceError;
69
69
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
@@ -670,7 +670,7 @@ impl_writeable_tlv_based_enum!(SentHTLCId,
670
670
},
671
671
(4, TrampolineForward) => {
672
672
(0, session_priv, required),
673
- (2, previous_hop_data , required_vec),
673
+ (2, previous_hop_ids , required_vec),
674
674
},
675
675
);
676
676
@@ -4667,24 +4667,35 @@ where
4667
4667
let _lck = self.total_consistency_lock.read().unwrap();
4668
4668
self.send_payment_along_path(SendAlongPathArgs {
4669
4669
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
4671
4672
})
4672
4673
}
4673
4674
4674
4675
fn send_payment_along_path(&self, args: SendAlongPathArgs) -> Result<(), APIError> {
4675
4676
let SendAlongPathArgs {
4676
4677
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
4678
4679
} = args;
4679
4680
// The top-level caller should hold the total_consistency_lock read lock.
4680
4681
debug_assert!(self.total_consistency_lock.try_write().is_err());
4681
4682
let prng_seed = self.entropy_source.get_secure_random_bytes();
4682
4683
let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
4683
4684
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| {
4688
4699
let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
4689
4700
log_error!(logger, "Failed to build an onion for path for payment hash {}", payment_hash);
4690
4701
e
@@ -4718,13 +4729,25 @@ where
4718
4729
}
4719
4730
let funding_txo = chan.funding.get_funding_txo().unwrap();
4720
4731
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 {
4723
4735
path: path.clone(),
4724
4736
session_priv: session_priv.clone(),
4725
4737
first_hop_htlc_msat: htlc_msat,
4726
4738
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);
4728
4751
match break_channel_entry!(self, peer_state, send_res, chan_entry) {
4729
4752
Some(monitor_update) => {
4730
4753
match handle_new_monitor_update!(self, funding_txo, monitor_update, peer_state_lock, peer_state, per_peer_state, chan) {
@@ -6300,33 +6323,74 @@ where
6300
6323
}
6301
6324
};
6302
6325
6303
- let usable_channels: Vec<ChannelDetails> = self.list_usable_channels();
6304
-
6305
6326
// assume any Trampoline node supports MPP
6306
6327
let mut recipient_features = Bolt11InvoiceFeatures::empty();
6307
6328
recipient_features.set_basic_mpp_optional();
6308
6329
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,
6326
6339
},
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![],
6329
6347
},
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,
6330
6394
Some(&usable_channels.iter().collect::<Vec<_>>()),
6331
6395
self.compute_inflight_htlcs()
6332
6396
) {
@@ -6414,6 +6478,7 @@ where
6414
6478
}
6415
6479
}
6416
6480
6481
+
6417
6482
let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &inter_trampoline_session_priv);
6418
6483
let outer_onion_prng_seed = self.entropy_source.get_secure_random_bytes();
6419
6484
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, outer_onion_prng_seed, &payment_hash).unwrap();
0 commit comments