From: Jeffrey Czyz Date: Wed, 20 Mar 2024 21:42:30 +0000 (-0500) Subject: Add BlindedPath::introduction_node_id method X-Git-Tag: v0.0.123-beta~10^2~7 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commitdiff_plain;h=63ebaccca3c284c28f24537c2c0c034f9cc9c3c4 Add BlindedPath::introduction_node_id method Blinded paths use a pubkey to identify the introduction node, but it will soon allow using a directed short channel id instead. Add an introduction_node_id method to BlindedPath to facilitate lookup in the latter case. --- diff --git a/lightning/src/blinded_path/mod.rs b/lightning/src/blinded_path/mod.rs index e70f310f..5d199269 100644 --- a/lightning/src/blinded_path/mod.rs +++ b/lightning/src/blinded_path/mod.rs @@ -17,6 +17,7 @@ use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey}; use crate::ln::msgs::DecodeError; use crate::offers::invoice::BlindedPayInfo; +use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph}; use crate::sign::EntropySource; use crate::util::ser::{Readable, Writeable, Writer}; @@ -125,6 +126,14 @@ impl BlindedPath { ).map_err(|_| ())?, })) } + + /// Returns the introduction [`NodeId`] of the blinded path. + pub fn public_introduction_node_id<'a>( + &self, network_graph: &'a ReadOnlyNetworkGraph + ) -> Option<&'a NodeId> { + let node_id = NodeId::from_pubkey(&self.introduction_node_id); + network_graph.nodes().get_key_value(&node_id).map(|(key, _)| key) + } } impl Writeable for BlindedPath { diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index e8276712..b01d853b 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1863,17 +1863,17 @@ where L::Target: Logger { } }, Payee::Blinded { route_hints, .. } => { - if route_hints.iter().all(|(_, path)| &path.introduction_node_id == our_node_pubkey) { + if route_hints.iter().all(|(_, path)| path.public_introduction_node_id(network_graph) == Some(&our_node_id)) { return Err(LightningError{err: "Cannot generate a route to blinded paths if we are the introduction node to all of them".to_owned(), action: ErrorAction::IgnoreError}); } for (_, blinded_path) in route_hints.iter() { if blinded_path.blinded_hops.len() == 0 { return Err(LightningError{err: "0-hop blinded path provided".to_owned(), action: ErrorAction::IgnoreError}); - } else if &blinded_path.introduction_node_id == our_node_pubkey { + } else if blinded_path.public_introduction_node_id(network_graph) == Some(&our_node_id) { log_info!(logger, "Got blinded path with ourselves as the introduction node, ignoring"); } else if blinded_path.blinded_hops.len() == 1 && route_hints.iter().any( |(_, p)| p.blinded_hops.len() == 1 - && p.introduction_node_id != blinded_path.introduction_node_id) + && p.public_introduction_node_id(network_graph) != blinded_path.public_introduction_node_id(network_graph)) { return Err(LightningError{err: format!("1-hop blinded paths must all have matching introduction node ids"), action: ErrorAction::IgnoreError}); } @@ -5301,10 +5301,15 @@ mod tests { if let Some(bt) = &path.blinded_tail { assert_eq!(path.hops.len() + if bt.hops.len() == 1 { 0 } else { 1 }, 2); if bt.hops.len() > 1 { - assert_eq!(path.hops.last().unwrap().pubkey, + let network_graph = network_graph.read_only(); + assert_eq!( + NodeId::from_pubkey(&path.hops.last().unwrap().pubkey), payment_params.payee.blinded_route_hints().iter() .find(|(p, _)| p.htlc_maximum_msat == path.final_value_msat()) - .map(|(_, p)| p.introduction_node_id).unwrap()); + .and_then(|(_, p)| p.public_introduction_node_id(&network_graph)) + .copied() + .unwrap() + ); } else { assert_eq!(path.hops.last().unwrap().pubkey, nodes[2]); } @@ -7432,7 +7437,10 @@ mod tests { assert_eq!(tail.final_value_msat, 1001); let final_hop = route.paths[0].hops.last().unwrap(); - assert_eq!(final_hop.pubkey, blinded_path.introduction_node_id); + assert_eq!( + NodeId::from_pubkey(&final_hop.pubkey), + *blinded_path.public_introduction_node_id(&network_graph).unwrap() + ); if tail.hops.len() > 1 { assert_eq!(final_hop.fee_msat, blinded_payinfo.fee_base_msat as u64 + blinded_payinfo.fee_proportional_millionths as u64 * tail.final_value_msat / 1000000);