Skip to content

Commit 5326171

Browse files
committed
Refactor MessageRouter::create_blinded_paths
Using compact blinded paths isn't always necessary or desirable. For instance, reply paths are communicated via onion messages where space isn't a premium unlike in QR codes. Additionally, long-lived paths could become invalid if the channel associated with the SCID is closed. Refactor MessageRouter::create_blinded_paths into two methods: one for compact blinded paths and one for normal blinded paths.
1 parent defc540 commit 5326171

File tree

7 files changed

+80
-25
lines changed

7 files changed

+80
-25
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use bitcoin::hashes::sha256d::Hash as Sha256dHash;
3434
use bitcoin::hash_types::BlockHash;
3535

3636
use lightning::blinded_path::BlindedPath;
37-
use lightning::blinded_path::message::ForwardNode;
3837
use lightning::blinded_path::payment::ReceiveTlvs;
3938
use lightning::chain;
4039
use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, chainmonitor, channelmonitor, Confirm, Watch};
@@ -124,7 +123,7 @@ impl MessageRouter for FuzzRouter {
124123
}
125124

126125
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
127-
&self, _recipient: PublicKey, _peers: Vec<ForwardNode>, _secp_ctx: &Secp256k1<T>,
126+
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
128127
) -> Result<Vec<BlindedPath>, ()> {
129128
unreachable!()
130129
}

fuzz/src/full_stack.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use bitcoin::hashes::sha256d::Hash as Sha256dHash;
3131
use bitcoin::hash_types::{Txid, BlockHash};
3232

3333
use lightning::blinded_path::BlindedPath;
34-
use lightning::blinded_path::message::ForwardNode;
3534
use lightning::blinded_path::payment::ReceiveTlvs;
3635
use lightning::chain;
3736
use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen};
@@ -162,7 +161,7 @@ impl MessageRouter for FuzzRouter {
162161
}
163162

164163
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
165-
&self, _recipient: PublicKey, _peers: Vec<ForwardNode>, _secp_ctx: &Secp256k1<T>,
164+
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
166165
) -> Result<Vec<BlindedPath>, ()> {
167166
unreachable!()
168167
}

fuzz/src/onion_message.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use bitcoin::secp256k1::ecdsa::RecoverableSignature;
77
use bitcoin::secp256k1::schnorr;
88

99
use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
10-
use lightning::blinded_path::message::ForwardNode;
1110
use lightning::ln::features::InitFeatures;
1211
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
1312
use lightning::ln::script::ShutdownScript;
@@ -89,7 +88,7 @@ impl MessageRouter for TestMessageRouter {
8988
}
9089

9190
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
92-
&self, _recipient: PublicKey, _peers: Vec<ForwardNode>, _secp_ctx: &Secp256k1<T>,
91+
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
9392
) -> Result<Vec<BlindedPath>, ()> {
9493
unreachable!()
9594
}

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8245,8 +8245,8 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
82458245
///
82468246
/// # Privacy
82478247
///
8248-
/// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the offer.
8249-
/// However, if one is not found, uses a one-hop [`BlindedPath`] with
8248+
/// Uses [`MessageRouter::create_compact_blinded_paths`] to construct a [`BlindedPath`] for the
8249+
/// offer. However, if one is not found, uses a one-hop [`BlindedPath`] with
82508250
/// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
82518251
/// the node must be announced, otherwise, there is no way to find a path to the introduction in
82528252
/// order to send the [`InvoiceRequest`].
@@ -8304,8 +8304,8 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
83048304
///
83058305
/// # Privacy
83068306
///
8307-
/// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the refund.
8308-
/// However, if one is not found, uses a one-hop [`BlindedPath`] with
8307+
/// Uses [`MessageRouter::create_compact_blinded_paths`] to construct a [`BlindedPath`] for the
8308+
/// refund. However, if one is not found, uses a one-hop [`BlindedPath`] with
83098309
/// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
83108310
/// the node must be announced, otherwise, there is no way to find a path to the introduction in
83118311
/// order to send the [`Bolt12Invoice`].
@@ -8686,7 +8686,7 @@ where
86868686
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
86878687
}
86888688

8689-
/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
8689+
/// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`].
86908690
///
86918691
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
86928692
fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
@@ -8708,7 +8708,7 @@ where
87088708
.collect::<Vec<_>>();
87098709

87108710
self.router
8711-
.create_blinded_paths(recipient, peers, secp_ctx)
8711+
.create_compact_blinded_paths(recipient, peers, secp_ctx)
87128712
.and_then(|paths| paths.into_iter().next().ok_or(()))
87138713
}
87148714

lightning/src/onion_message/messenger.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH> where
162162
/// # })
163163
/// # }
164164
/// # fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
165-
/// # &self, _recipient: PublicKey, _peers: Vec<ForwardNode>, _secp_ctx: &Secp256k1<T>
165+
/// # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>
166166
/// # ) -> Result<Vec<BlindedPath>, ()> {
167167
/// # unreachable!()
168168
/// # }
@@ -426,8 +426,33 @@ pub trait MessageRouter {
426426
fn create_blinded_paths<
427427
T: secp256k1::Signing + secp256k1::Verification
428428
>(
429-
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
429+
&self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
430430
) -> Result<Vec<BlindedPath>, ()>;
431+
432+
/// Creates compact [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed
433+
/// to be direct peers with the `recipient`.
434+
///
435+
/// Compact blinded paths use short channel ids instead of pubkeys for a smaller serialization,
436+
/// which is beneficial when a QR code is used to transport the data. The SCID is passed using a
437+
/// [`ForwardNode`] but may be `None` for graceful degradation.
438+
///
439+
/// Implementations using additional intermediate nodes are responsible for using a
440+
/// [`ForwardNode`] with `Some` short channel id, if possible. Similarly, implementations should
441+
/// call [`BlindedPath::use_compact_introduction_node`].
442+
///
443+
/// The provided implementation simply delegates to [`MessageRouter::create_blinded_paths`],
444+
/// ignoring the short channel ids.
445+
fn create_compact_blinded_paths<
446+
T: secp256k1::Signing + secp256k1::Verification
447+
>(
448+
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
449+
) -> Result<Vec<BlindedPath>, ()> {
450+
let peers = peers
451+
.into_iter()
452+
.map(|ForwardNode { node_id, short_channel_id: _ }| node_id)
453+
.collect();
454+
self.create_blinded_paths(recipient, peers, secp_ctx)
455+
}
431456
}
432457

433458
/// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
@@ -454,7 +479,7 @@ where
454479
I: Iterator<Item = ForwardNode>,
455480
T: secp256k1::Signing + secp256k1::Verification
456481
>(
457-
&self, recipient: PublicKey, peers: I, secp_ctx: &Secp256k1<T>,
482+
&self, recipient: PublicKey, peers: I, secp_ctx: &Secp256k1<T>, compact_paths: bool
458483
) -> Result<Vec<BlindedPath>, ()> {
459484
// Limit the number of blinded paths that are computed.
460485
const MAX_PATHS: usize = 3;
@@ -502,8 +527,11 @@ where
502527
}
503528
},
504529
}?;
505-
for path in &mut paths {
506-
path.use_compact_introduction_node(&network_graph);
530+
531+
if compact_paths {
532+
for path in &mut paths {
533+
path.use_compact_introduction_node(&network_graph);
534+
}
507535
}
508536

509537
Ok(paths)
@@ -550,10 +578,21 @@ where
550578

551579
fn create_blinded_paths<
552580
T: secp256k1::Signing + secp256k1::Verification
581+
>(
582+
&self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
583+
) -> Result<Vec<BlindedPath>, ()> {
584+
let peers = peers
585+
.into_iter()
586+
.map(|node_id| ForwardNode { node_id, short_channel_id: None });
587+
self.create_blinded_paths_from_iter(recipient, peers, secp_ctx, false)
588+
}
589+
590+
fn create_compact_blinded_paths<
591+
T: secp256k1::Signing + secp256k1::Verification
553592
>(
554593
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
555594
) -> Result<Vec<BlindedPath>, ()> {
556-
self.create_blinded_paths_from_iter(recipient, peers.into_iter(), secp_ctx)
595+
self.create_blinded_paths_from_iter(recipient, peers.into_iter(), secp_ctx, true)
557596
}
558597
}
559598

@@ -1090,10 +1129,7 @@ where
10901129
let peers = self.message_recipients.lock().unwrap()
10911130
.iter()
10921131
.filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_)))
1093-
.map(|(node_id, _ )| ForwardNode {
1094-
node_id: *node_id,
1095-
short_channel_id: None,
1096-
})
1132+
.map(|(node_id, _ )| *node_id)
10971133
.collect::<Vec<_>>();
10981134

10991135
self.message_router

lightning/src/routing/router.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,18 @@ impl< G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
173173
fn create_blinded_paths<
174174
T: secp256k1::Signing + secp256k1::Verification
175175
> (
176-
&self, recipient: PublicKey, peers: Vec<message::ForwardNode>, secp_ctx: &Secp256k1<T>,
176+
&self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
177177
) -> Result<Vec<BlindedPath>, ()> {
178178
self.message_router.create_blinded_paths(recipient, peers, secp_ctx)
179179
}
180+
181+
fn create_compact_blinded_paths<
182+
T: secp256k1::Signing + secp256k1::Verification
183+
> (
184+
&self, recipient: PublicKey, peers: Vec<message::ForwardNode>, secp_ctx: &Secp256k1<T>,
185+
) -> Result<Vec<BlindedPath>, ()> {
186+
self.message_router.create_compact_blinded_paths(recipient, peers, secp_ctx)
187+
}
180188
}
181189

182190
/// A trait defining behavior for routing a payment.

lightning/src/util/test_utils.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,18 @@ impl<'a> MessageRouter for TestRouter<'a> {
250250
fn create_blinded_paths<
251251
T: secp256k1::Signing + secp256k1::Verification
252252
>(
253-
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
253+
&self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
254254
) -> Result<Vec<BlindedPath>, ()> {
255255
self.router.create_blinded_paths(recipient, peers, secp_ctx)
256256
}
257+
258+
fn create_compact_blinded_paths<
259+
T: secp256k1::Signing + secp256k1::Verification
260+
>(
261+
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
262+
) -> Result<Vec<BlindedPath>, ()> {
263+
self.router.create_compact_blinded_paths(recipient, peers, secp_ctx)
264+
}
257265
}
258266

259267
impl<'a> Drop for TestRouter<'a> {
@@ -285,10 +293,16 @@ impl<'a> MessageRouter for TestMessageRouter<'a> {
285293
}
286294

287295
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
288-
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
296+
&self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
289297
) -> Result<Vec<BlindedPath>, ()> {
290298
self.inner.create_blinded_paths(recipient, peers, secp_ctx)
291299
}
300+
301+
fn create_compact_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
302+
&self, recipient: PublicKey, peers: Vec<ForwardNode>, secp_ctx: &Secp256k1<T>,
303+
) -> Result<Vec<BlindedPath>, ()> {
304+
self.inner.create_compact_blinded_paths(recipient, peers, secp_ctx)
305+
}
292306
}
293307

294308
pub struct OnlyReadsKeysInterface {}

0 commit comments

Comments
 (0)