Skip to content

Commit bc727e0

Browse files
Account for Path::blinded_tail when adding a shadow cltv offset
1 parent 6029b1c commit bc727e0

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

lightning/src/routing/router.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,8 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
21312131
let network_nodes = network_graph.nodes();
21322132

21332133
for path in route.paths.iter_mut() {
2134+
if path.blinded_tail.as_ref().map_or(false, |tail| tail.path.blinded_hops.len() > 1) { continue }
2135+
21342136
let mut shadow_ctlv_expiry_delta_offset: u32 = 0;
21352137

21362138
// Remember the last three nodes of the random walk and avoid looping back on them.
@@ -2199,7 +2201,10 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
21992201
shadow_ctlv_expiry_delta_offset = cmp::min(shadow_ctlv_expiry_delta_offset, max_path_offset);
22002202

22012203
// Add 'shadow' CLTV offset to the final hop
2202-
if let Some(last_hop) = path.hops.last_mut() {
2204+
if let Some(tail) = path.blinded_tail.as_mut() {
2205+
tail.cltv_expiry_delta = tail.cltv_expiry_delta
2206+
.checked_add(shadow_ctlv_expiry_delta_offset).unwrap_or(tail.cltv_expiry_delta);
2207+
} else if let Some(last_hop) = path.hops.last_mut() {
22032208
last_hop.cltv_expiry_delta = last_hop.cltv_expiry_delta
22042209
.checked_add(shadow_ctlv_expiry_delta_offset).unwrap_or(last_hop.cltv_expiry_delta);
22052210
}
@@ -2287,7 +2292,7 @@ fn build_route_from_hops_internal<L: Deref>(
22872292

22882293
#[cfg(test)]
22892294
mod tests {
2290-
use crate::blinded_path::BlindedPath;
2295+
use crate::blinded_path::{BlindedHop, BlindedPath};
22912296
use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, EffectiveCapacity};
22922297
use crate::routing::utxo::UtxoResult;
22932298
use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
@@ -5818,6 +5823,45 @@ mod tests {
58185823
assert_eq!(*inflight_htlcs.0.get(&(42, true)).unwrap(), 301);
58195824
assert_eq!(*inflight_htlcs.0.get(&(43, false)).unwrap(), 201);
58205825
}
5826+
5827+
#[test]
5828+
fn blinded_path_cltv_shadow_offset() {
5829+
// Don't add a shadow offset to blinded paths with more than 1 hop.
5830+
let mut route = Route { paths: vec![Path {
5831+
hops: vec![RouteHop {
5832+
pubkey: ln_test_utils::pubkey(42),
5833+
node_features: NodeFeatures::empty(),
5834+
short_channel_id: 42,
5835+
channel_features: ChannelFeatures::empty(),
5836+
fee_msat: 100,
5837+
cltv_expiry_delta: 0,
5838+
}],
5839+
blinded_tail: Some(BlindedTail {
5840+
path: BlindedPath {
5841+
introduction_node_id: ln_test_utils::pubkey(43),
5842+
blinding_point: ln_test_utils::pubkey(44),
5843+
blinded_hops: vec![
5844+
BlindedHop { blinded_node_id: ln_test_utils::pubkey(45), encrypted_payload: Vec::new() },
5845+
BlindedHop { blinded_node_id: ln_test_utils::pubkey(46), encrypted_payload: Vec::new() }
5846+
],
5847+
},
5848+
intro_node_scid: 43,
5849+
fee_msat: 1,
5850+
cltv_expiry_delta: 0,
5851+
final_value_msat: 200,
5852+
}),
5853+
}], payment_params: None};
5854+
5855+
let payment_params = PaymentParameters::from_node_id(ln_test_utils::pubkey(47), 18);
5856+
let (_, network_graph, _, _, _) = build_line_graph();
5857+
add_random_cltv_offset(&mut route, &payment_params, &network_graph.read_only(), &[0; 32]);
5858+
assert_eq!(route.paths[0].blinded_tail.as_ref().unwrap().cltv_expiry_delta, 0);
5859+
5860+
// Add a shadow offset if we're sending to a 1-hop blinded path.
5861+
route.paths[0].blinded_tail.as_mut().unwrap().path.blinded_hops.pop();
5862+
add_random_cltv_offset(&mut route, &payment_params, &network_graph.read_only(), &[0; 32]);
5863+
assert_eq!(route.paths[0].blinded_tail.as_ref().unwrap().cltv_expiry_delta, 40);
5864+
}
58215865
}
58225866

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

0 commit comments

Comments
 (0)