Skip to content

Commit 28b3f75

Browse files
Account for Path::blinded_tail in InflightHtlcs::process_path
1 parent 5dc938c commit 28b3f75

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
@@ -292,6 +303,13 @@ pub struct Path {
292303
pub blinded_tail: Option<BlindedTail>,
293304
}
294305

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

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

57545803
#[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)