You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if let HTLCSource::TrampolineForward { ref mut hops, .. } = htlc_source {
6342
-
*hops = inter_trampoline_hops.clone();
6342
+
let inter_trampoline_payment_secret = PaymentSecret(self.entropy_source.get_secure_random_bytes());
6343
+
for current_path in route.paths {
6344
+
let inter_trampoline_session_priv = SecretKey::from_slice(&self.entropy_source.get_secure_random_bytes()).unwrap();
6345
+
let inter_trampoline_hops = current_path.hops.clone();
6346
+
let mut current_htlc_source = htlc_source.clone();
6347
+
if let HTLCSource::TrampolineForward { ref mut session_priv, ref mut hops, .. } = current_htlc_source {
6348
+
*session_priv = inter_trampoline_session_priv;
6349
+
*hops = inter_trampoline_hops.clone();
6350
+
};
6351
+
6352
+
let outgoing_scid = match inter_trampoline_hops.first() {
6353
+
Some(hop) => hop.short_channel_id,
6354
+
None => {
6355
+
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), current_htlc_source, None, 0x2000 | 25, Vec::new());
6356
+
break;
6343
6357
}
6344
-
inter_trampoline_hops
6345
-
},
6346
-
None => {
6347
-
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), htlc_source, None, 0x2000 | 25, Vec::new());
6348
-
continue;
6349
-
}
6350
-
};
6358
+
};
6351
6359
6352
-
let outgoing_scid = match hops.first() {
6353
-
Some(hop) => hop.short_channel_id,
6354
-
None => {
6355
-
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), htlc_source, None, 0x2000 | 25, Vec::new());
6356
-
continue;
6360
+
let chan_info_opt = self.short_to_chan_info.read().unwrap().get(&outgoing_scid).cloned();
6361
+
let (counterparty_node_id, forward_chan_id) = match chan_info_opt {
6362
+
Some((cp_id, chan_id)) => (cp_id, chan_id),
6363
+
None => {
6364
+
push_trampoline_forwarding_failure(format!("Could not find forwarding channel {outgoing_scid} to route to next Trampoline hop {next_node_id}"), current_htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6365
+
break;
6366
+
}
6367
+
};
6368
+
let per_peer_state = self.per_peer_state.read().unwrap();
6369
+
let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
6370
+
if peer_state_mutex_opt.is_none() {
6371
+
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), current_htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6372
+
break;
6357
6373
}
6358
-
};
6374
+
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
6375
+
let peer_state = &mut *peer_state_lock;
6359
6376
6360
-
let chan_info_opt = self.short_to_chan_info.read().unwrap().get(&outgoing_scid).cloned();
6361
-
let (counterparty_node_id, forward_chan_id) = match chan_info_opt {
6362
-
Some((cp_id, chan_id)) => (cp_id, chan_id),
6363
-
None => {
6364
-
push_trampoline_forwarding_failure(format!("Could not find forwarding channel {outgoing_scid} to route to next Trampoline hop {next_node_id}"), htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6365
-
continue;
6366
-
}
6367
-
};
6368
-
let per_peer_state = self.per_peer_state.read().unwrap();
6369
-
let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
6370
-
if peer_state_mutex_opt.is_none() {
6371
-
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6372
-
continue;
6373
-
}
6374
-
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
6375
-
let peer_state = &mut *peer_state_lock;
6377
+
let (outer_onion_packet, outer_value_msat, outer_cltv) = {
6378
+
let path = Path {
6379
+
hops: inter_trampoline_hops,
6380
+
blinded_tail: None,
6381
+
};
6382
+
let recipient_onion = RecipientOnionFields::spontaneous_empty();
6383
+
let (mut onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
6384
+
&path,
6385
+
current_path.final_value_msat(),
6386
+
&recipient_onion,
6387
+
outgoing_cltv_value,
6388
+
&None,
6389
+
None,
6390
+
None,
6391
+
).unwrap();
6392
+
6393
+
let multipath_trampoline_data = Some(FinalOnionHopData { payment_secret: inter_trampoline_payment_secret, total_msat: outgoing_amt_msat });
6394
+
if let Some(last_payload) = onion_payloads.last_mut() {
let optimal_channel = match maybe_optimal_channel {
6444
+
Some(chan) => chan,
6445
+
None => {
6446
+
// Fall back to the specified channel to return an appropriate error.
6447
+
if let Some(chan) = peer_state.channel_by_id
6448
+
.get_mut(&forward_chan_id)
6449
+
.and_then(Channel::as_funded_mut)
6450
+
{
6451
+
chan
6452
+
} else {
6453
+
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), current_htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6454
+
break;
6414
6455
}
6415
6456
}
6416
-
}
6417
-
6418
-
let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &inter_trampoline_session_priv).map_err(|_| {
6419
-
APIError::InvalidRoute { err: "Pubkey along hop was maliciously selected".to_owned() }
6420
-
}).unwrap();
6421
-
let outer_onion_prng_seed = self.entropy_source.get_secure_random_bytes();
6422
-
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, outer_onion_prng_seed, &payment_hash).unwrap();
6423
-
6424
-
(onion_packet, htlc_msat, htlc_cltv)
6425
-
};
6457
+
};
6426
6458
6427
-
// Forward the HTLC over the most appropriate channel with the corresponding peer,
6428
-
// applying non-strict forwarding.
6429
-
// The channel with the least amount of outbound liquidity will be used to maximize the
6430
-
// probability of being able to successfully forward a subsequent HTLC.
6431
-
let maybe_optimal_channel = peer_state.channel_by_id.values_mut()
6432
-
.filter_map(Channel::as_funded_mut)
6433
-
.filter_map(|chan| {
6434
-
let balances = chan.get_available_balances(&self.fee_estimator);
6435
-
if outer_value_msat <= balances.next_outbound_htlc_limit_msat &&
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6455
-
continue;
6491
+
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), current_htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
6492
+
break;
6456
6493
}
6457
6494
}
6458
-
};
6459
-
6460
-
let logger = WithChannelContext::from(&self.logger, &optimal_channel.context, Some(payment_hash));
6461
-
let channel_description = if optimal_channel.context.get_short_channel_id() == Some(short_chan_id) {
6462
-
"specified"
6463
-
} else {
6464
-
"alternate"
6465
-
};
6466
-
log_trace!(logger, "Forwarding HTLC from SCID {} with payment_hash {} and next hop SCID {} over {} channel {} with corresponding peer {}",
push_trampoline_forwarding_failure(format!("Could not to route to next Trampoline hop {next_node_id} via forwarding channel {outgoing_scid}"), htlc_source, Some(outgoing_scid), 0x2000 | 25, Vec::new());
0 commit comments