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 {
6327
-
*hops = inter_trampoline_hops.clone();
6328
+
let inter_trampoline_payment_secret = PaymentSecret(self.entropy_source.get_secure_random_bytes());
6329
+
for current_path in route.paths {
6330
+
let inter_trampoline_session_priv = SecretKey::from_slice(&self.entropy_source.get_secure_random_bytes()).unwrap();
6331
+
let inter_trampoline_hops = current_path.hops.clone();
6332
+
let mut current_htlc_source = htlc_source.clone();
6333
+
if let HTLCSource::TrampolineForward { ref mut session_priv, ref mut hops, .. } = current_htlc_source {
6334
+
*session_priv = inter_trampoline_session_priv;
6335
+
*hops = inter_trampoline_hops.clone();
6336
+
};
6337
+
6338
+
let outgoing_scid = match inter_trampoline_hops.first() {
6339
+
Some(hop) => hop.short_channel_id,
6340
+
None => {
6341
+
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), current_htlc_source, None, 0x2000 | 25, Vec::new());
6342
+
break;
6328
6343
}
6329
-
inter_trampoline_hops
6330
-
},
6331
-
None => {
6332
-
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), htlc_source, None, 0x2000 | 25, Vec::new());
6333
-
continue;
6334
-
}
6335
-
};
6344
+
};
6336
6345
6337
-
let outgoing_scid = match hops.first() {
6338
-
Some(hop) => hop.short_channel_id,
6339
-
None => {
6340
-
push_trampoline_forwarding_failure(format!("Could not find route to next Trampoline hop {next_node_id}"), htlc_source, None, 0x2000 | 25, Vec::new());
6341
-
continue;
6346
+
let chan_info_opt = self.short_to_chan_info.read().unwrap().get(&outgoing_scid).cloned();
6347
+
let (counterparty_node_id, forward_chan_id) = match chan_info_opt {
6348
+
Some((cp_id, chan_id)) => (cp_id, chan_id),
6349
+
None => {
6350
+
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());
6351
+
break;
6352
+
}
6353
+
};
6354
+
let per_peer_state = self.per_peer_state.read().unwrap();
6355
+
let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
6356
+
if peer_state_mutex_opt.is_none() {
6357
+
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());
6358
+
break;
6342
6359
}
6343
-
};
6360
+
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
6361
+
let peer_state = &mut *peer_state_lock;
6344
6362
6345
-
let chan_info_opt = self.short_to_chan_info.read().unwrap().get(&outgoing_scid).cloned();
6346
-
let (counterparty_node_id, forward_chan_id) = match chan_info_opt {
6347
-
Some((cp_id, chan_id)) => (cp_id, chan_id),
6348
-
None => {
6349
-
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());
6350
-
continue;
6351
-
}
6352
-
};
6353
-
let per_peer_state = self.per_peer_state.read().unwrap();
6354
-
let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
6355
-
if peer_state_mutex_opt.is_none() {
6356
-
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());
6357
-
continue;
6358
-
}
6359
-
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
6360
-
let peer_state = &mut *peer_state_lock;
6363
+
let (outer_onion_packet, outer_value_msat, outer_cltv) = {
6364
+
let path = Path {
6365
+
hops: inter_trampoline_hops,
6366
+
blinded_tail: None,
6367
+
};
6368
+
let recipient_onion = RecipientOnionFields::spontaneous_empty();
6369
+
let (mut onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
6370
+
&path,
6371
+
current_path.final_value_msat(),
6372
+
&recipient_onion,
6373
+
outgoing_cltv_value,
6374
+
&None,
6375
+
None,
6376
+
None,
6377
+
).unwrap();
6378
+
6379
+
let multipath_trampoline_data = Some(FinalOnionHopData { payment_secret: inter_trampoline_payment_secret, total_msat: outgoing_amt_msat });
6380
+
if let Some(last_payload) = onion_payloads.last_mut() {
let optimal_channel = match maybe_optimal_channel {
6432
+
Some(chan) => chan,
6433
+
None => {
6434
+
// Fall back to the specified channel to return an appropriate error.
6435
+
if let Some(chan) = peer_state.channel_by_id
6436
+
.get_mut(&forward_chan_id)
6437
+
.and_then(Channel::as_funded_mut)
6438
+
{
6439
+
chan
6440
+
} else {
6441
+
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());
6442
+
break;
6399
6443
}
6400
6444
}
6401
-
}
6402
-
6403
-
let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &inter_trampoline_session_priv).map_err(|_| {
6404
-
APIError::InvalidRoute { err: "Pubkey along hop was maliciously selected".to_owned() }
6405
-
}).unwrap();
6406
-
let outer_onion_prng_seed = self.entropy_source.get_secure_random_bytes();
6407
-
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, outer_onion_prng_seed, &payment_hash).unwrap();
6408
-
6409
-
(onion_packet, htlc_msat, htlc_cltv)
6410
-
};
6445
+
};
6411
6446
6412
-
// Forward the HTLC over the most appropriate channel with the corresponding peer,
6413
-
// applying non-strict forwarding.
6414
-
// The channel with the least amount of outbound liquidity will be used to maximize the
6415
-
// probability of being able to successfully forward a subsequent HTLC.
6416
-
let maybe_optimal_channel = peer_state.channel_by_id.values_mut()
6417
-
.filter_map(Channel::as_funded_mut)
6418
-
.filter_map(|chan| {
6419
-
let balances = chan.get_available_balances(&self.fee_estimator);
6420
-
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());
6440
-
continue;
6479
+
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());
6480
+
break;
6441
6481
}
6442
6482
}
6443
-
};
6444
-
6445
-
let logger = WithChannelContext::from(&self.logger, &optimal_channel.context, Some(payment_hash));
6446
-
let channel_description = if optimal_channel.context.get_short_channel_id() == Some(short_chan_id) {
6447
-
"specified"
6448
-
} else {
6449
-
"alternate"
6450
-
};
6451
-
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