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