Skip to content

Commit 76956e4

Browse files
committed
Use a non-pubkey-associated node counter for blinded recipients
When routing, we have to assign a node counter for the recipient. When searching for a path to a blinded recipient, we do this by assigning a node counter to a NUMS pubkey. This should be fine as there is no known private key corresponding to this NUMS point, and thus no first-hop or network graph nodes can appear for the same pubkey. However, this can fail in fuzzing as the fuzzer can forge valid signatures for the NUMS pubkey. Thus, here, we adapt the node counter allocation to issue a node counter without a corresponding public key when paying to a blinded path.
1 parent 85185d8 commit 76956e4

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

lightning/src/routing/router.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,7 @@ struct NodeCounters<'a> {
17711771
network_graph: &'a ReadOnlyNetworkGraph<'a>,
17721772
private_node_id_to_node_counter: HashMap<NodeId, u32>,
17731773
private_hop_key_cache: HashMap<PublicKey, (NodeId, u32)>,
1774+
have_blinded_payee_counter: bool,
17741775
}
17751776

17761777
struct NodeCountersBuilder<'a>(NodeCounters<'a>);
@@ -1781,9 +1782,17 @@ impl<'a> NodeCountersBuilder<'a> {
17811782
network_graph,
17821783
private_node_id_to_node_counter: new_hash_map(),
17831784
private_hop_key_cache: new_hash_map(),
1785+
have_blinded_payee_counter: false,
17841786
})
17851787
}
17861788

1789+
fn select_node_counter_for_blinded_payee_and_build(mut self) -> (u32, NodeCounters<'a>) {
1790+
let next_node_counter = self.0.network_graph.max_node_counter() + 1 +
1791+
self.0.private_node_id_to_node_counter.len() as u32;
1792+
self.0.have_blinded_payee_counter = true;
1793+
(next_node_counter, self.0)
1794+
}
1795+
17871796
fn select_node_counter_for_pubkey(&mut self, pubkey: PublicKey) -> u32 {
17881797
let id = NodeId::from_pubkey(&pubkey);
17891798
let counter = self.select_node_counter_for_id(id);
@@ -1809,7 +1818,8 @@ impl<'a> NodeCountersBuilder<'a> {
18091818
impl<'a> NodeCounters<'a> {
18101819
fn max_counter(&self) -> u32 {
18111820
self.network_graph.max_node_counter() +
1812-
self.private_node_id_to_node_counter.len() as u32
1821+
self.private_node_id_to_node_counter.len() as u32 +
1822+
if self.have_blinded_payee_counter { 1 } else { 0 }
18131823
}
18141824

18151825
fn private_node_counter_from_pubkey(&self, pubkey: &PublicKey) -> Option<&(NodeId, u32)> {
@@ -2416,7 +2426,6 @@ where L::Target: Logger {
24162426
let mut node_counter_builder = NodeCountersBuilder::new(&network_graph);
24172427

24182428
let payer_node_counter = node_counter_builder.select_node_counter_for_pubkey(*our_node_pubkey);
2419-
let payee_node_counter = node_counter_builder.select_node_counter_for_pubkey(maybe_dummy_payee_pk);
24202429

24212430
for route in payment_params.payee.unblinded_route_hints().iter() {
24222431
for hop in route.0.iter() {
@@ -2455,7 +2464,11 @@ where L::Target: Logger {
24552464
}
24562465
}
24572466

2458-
let node_counters = node_counter_builder.build();
2467+
let (payee_node_counter, node_counters) = if let Some(pubkey) = payment_params.payee.node_id() {
2468+
(node_counter_builder.select_node_counter_for_pubkey(pubkey), node_counter_builder.build())
2469+
} else {
2470+
node_counter_builder.select_node_counter_for_blinded_payee_and_build()
2471+
};
24592472

24602473
let introduction_node_id_cache = calculate_blinded_path_intro_points(
24612474
&payment_params, &node_counters, network_graph, &logger, our_node_id, &first_hop_targets,

0 commit comments

Comments
 (0)