Skip to content

Commit 0fdb3c3

Browse files
Account for Path::blinded_tail in InflightHtlcs::process_path
1 parent 829134a commit 0fdb3c3

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

lightning/src/routing/router.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,19 @@ impl InFlightHtlcs {
171171

172172
/// Takes in a path with payer's node id and adds the path's details to `InFlightHtlcs`.
173173
pub fn process_path(&mut self, path: &Path, payer_node_id: PublicKey) {
174-
if path.hops.is_empty() { return };
174+
if path.len() == 0 { return };
175+
176+
let mut cumulative_msat = 0;
177+
if let Some(tail) = &path.blinded_tail {
178+
cumulative_msat += tail.final_value_msat + tail.fee_msat;
179+
self.0
180+
.entry((tail.intro_node_scid,
181+
NodeId::from_pubkey(&path.hops.last().map_or(payer_node_id, |hop| hop.pubkey)) <
182+
NodeId::from_pubkey(&tail.path.introduction_node_id)))
183+
.and_modify(|used_liquidity_msat| *used_liquidity_msat += cumulative_msat)
184+
.or_insert(cumulative_msat);
185+
}
186+
175187
// total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
176188
// that is held up. However, the `hops` array, which is a path returned by `find_route` in
177189
// the router excludes the payer node. In the following lines, the payer's information is
@@ -180,7 +192,6 @@ impl InFlightHtlcs {
180192
let reversed_hops_with_payer = path.hops.iter().rev().skip(1)
181193
.map(|hop| hop.pubkey)
182194
.chain(core::iter::once(payer_node_id));
183-
let mut cumulative_msat = 0;
184195

185196
// Taking the reversed vector from above, we zip it with just the reversed hops list to
186197
// work "backwards" of the given path, since the last hop's `fee_msat` actually represents
@@ -290,6 +301,13 @@ pub struct Path {
290301
pub blinded_tail: Option<BlindedTail>,
291302
}
292303

304+
impl Path {
305+
/// The length of this path, including the hops of its [`Path::blinded_tail`], if any.
306+
pub fn len(&self) -> usize {
307+
self.hops.len() + self.blinded_tail.as_ref().map_or(0, |tail| tail.path.blinded_hops.len())
308+
}
309+
}
310+
293311
/// A route directs a payment from the sender (us) to the recipient. If the recipient supports MPP,
294312
/// it can take multiple paths. Each path is composed of one or more hops through the network.
295313
#[derive(Clone, Hash, PartialEq, Eq)]
@@ -2247,10 +2265,11 @@ fn build_route_from_hops_internal<L: Deref>(
22472265

22482266
#[cfg(test)]
22492267
mod tests {
2268+
use crate::blinded_path::BlindedPath;
22502269
use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, EffectiveCapacity};
22512270
use crate::routing::utxo::UtxoResult;
22522271
use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
2253-
Path, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
2272+
BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
22542273
DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
22552274
use crate::routing::scoring::{ChannelUsage, FixedPenaltyScorer, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
22562275
use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel};
@@ -5747,6 +5766,36 @@ mod tests {
57475766
let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes);
57485767
assert!(route.is_ok());
57495768
}
5769+
5770+
#[test]
5771+
fn blinded_path_inflight_processing() {
5772+
// Ensure we'll score the channel that's inbound to a blinded path's introduction node.
5773+
let mut inflight_htlcs = InFlightHtlcs::new();
5774+
let path = Path {
5775+
hops: vec![RouteHop {
5776+
pubkey: ln_test_utils::pubkey(42),
5777+
node_features: NodeFeatures::empty(),
5778+
short_channel_id: 42,
5779+
channel_features: ChannelFeatures::empty(),
5780+
fee_msat: 100,
5781+
cltv_expiry_delta: 0,
5782+
}],
5783+
blinded_tail: Some(BlindedTail {
5784+
path: BlindedPath {
5785+
introduction_node_id: ln_test_utils::pubkey(43),
5786+
blinding_point: ln_test_utils::pubkey(44),
5787+
blinded_hops: Vec::new(),
5788+
},
5789+
intro_node_scid: 43,
5790+
fee_msat: 1,
5791+
cltv_expiry_delta: 0,
5792+
final_value_msat: 200,
5793+
}),
5794+
};
5795+
inflight_htlcs.process_path(&path, ln_test_utils::pubkey(44));
5796+
assert_eq!(*inflight_htlcs.0.get(&(42, true)).unwrap(), 301);
5797+
assert_eq!(*inflight_htlcs.0.get(&(43, false)).unwrap(), 201);
5798+
}
57505799
}
57515800

57525801
#[cfg(all(test, not(feature = "no-std")))]

lightning/src/util/test_utils.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ use crate::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, Node
6060
use std::time::{SystemTime, UNIX_EPOCH};
6161
use bitcoin::Sequence;
6262

63+
pub fn pubkey(byte: u8) -> PublicKey {
64+
let secp_ctx = Secp256k1::new();
65+
PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
66+
}
67+
68+
pub fn privkey(byte: u8) -> SecretKey {
69+
SecretKey::from_slice(&[byte; 32]).unwrap()
70+
}
71+
6372
pub struct TestVecWriter(pub Vec<u8>);
6473
impl Writer for TestVecWriter {
6574
fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {

0 commit comments

Comments
 (0)