Skip to content

Commit 472b6d0

Browse files
committed
Introduce a Unified Function Flow for Creating Blinded Paths
This refactor simplifies the codebase while ensuring that the existing functionality is maintained.
1 parent 398bd57 commit 472b6d0

File tree

7 files changed

+72
-170
lines changed

7 files changed

+72
-170
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ use lightning::ln::script::ShutdownScript;
5858
use lightning::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
5959
use lightning::offers::invoice::UnsignedBolt12Invoice;
6060
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
61-
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
61+
use lightning::onion_message::messenger::{
62+
BlindedPathType, Destination, MessageRouter, OnionMessagePath,
63+
};
6264
use lightning::routing::router::{InFlightHtlcs, Path, Route, RouteHop, RouteParameters, Router};
6365
use lightning::sign::{
6466
EntropySource, InMemorySigner, KeyMaterial, NodeSigner, Recipient, SignerProvider,
@@ -141,8 +143,8 @@ impl MessageRouter for FuzzRouter {
141143
}
142144

143145
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
144-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
145-
_secp_ctx: &Secp256k1<T>,
146+
&self, _recipient: PublicKey, _context: MessageContext, _blinded_path: BlindedPathType,
147+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
146148
) -> Result<Vec<BlindedMessagePath>, ()> {
147149
unreachable!()
148150
}

fuzz/src/full_stack.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ use lightning::ln::script::ShutdownScript;
5151
use lightning::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
5252
use lightning::offers::invoice::UnsignedBolt12Invoice;
5353
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
54-
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
54+
use lightning::onion_message::messenger::{
55+
BlindedPathType, Destination, MessageRouter, OnionMessagePath,
56+
};
5557
use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
5658
use lightning::routing::router::{
5759
InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router,
@@ -176,8 +178,8 @@ impl MessageRouter for FuzzRouter {
176178
}
177179

178180
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
179-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
180-
_secp_ctx: &Secp256k1<T>,
181+
&self, _recipient: PublicKey, _context: MessageContext, _blinded_path: BlindedPathType,
182+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
181183
) -> Result<Vec<BlindedMessagePath>, ()> {
182184
unreachable!()
183185
}

fuzz/src/onion_message.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use lightning::onion_message::async_payments::{
1616
AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc,
1717
};
1818
use lightning::onion_message::messenger::{
19-
CustomOnionMessageHandler, Destination, MessageRouter, MessageSendInstructions,
20-
OnionMessagePath, OnionMessenger, Responder, ResponseInstruction,
19+
BlindedPathType, CustomOnionMessageHandler, Destination, MessageRouter,
20+
MessageSendInstructions, OnionMessagePath, OnionMessenger, Responder, ResponseInstruction,
2121
};
2222
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
2323
use lightning::onion_message::packet::OnionMessageContents;
@@ -96,8 +96,8 @@ impl MessageRouter for TestMessageRouter {
9696
}
9797

9898
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
99-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
100-
_secp_ctx: &Secp256k1<T>,
99+
&self, _recipient: PublicKey, _context: MessageContext, _blinded_path: BlindedPathType,
100+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
101101
) -> Result<Vec<BlindedMessagePath>, ()> {
102102
unreachable!()
103103
}

lightning/src/ln/channelmanager.rs

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,9 +2497,7 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
24972497
/// short-lived, while anything with a greater expiration is considered long-lived.
24982498
///
24992499
/// Using [`ChannelManager::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2500-
/// will included a [`BlindedMessagePath`] created using:
2501-
/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and
2502-
/// - [`MessageRouter::create_blinded_paths`] when long-lived.
2500+
/// will included a [`BlindedMessagePath`] created using [`MessageRouter::create_blinded_paths`].
25032501
///
25042502
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
25052503
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
@@ -8881,20 +8879,9 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
88818879
let nonce = Nonce::from_entropy_source(entropy);
88828880
let context = OffersContext::InvoiceRequest { nonce };
88838881
let builder = match blinded_path {
8884-
Some(BlindedPathType::Compact) => {
8882+
Some(blinded_path) => {
88858883
let path = $self
8886-
.create_compact_blinded_paths(context)
8887-
.and_then(|paths| paths.into_iter().next().ok_or(()))
8888-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8889-
8890-
OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
8891-
.chain_hash($self.chain_hash)
8892-
.path(path)
8893-
}
8894-
8895-
Some(BlindedPathType::Full) => {
8896-
let path = $self
8897-
.create_blinded_paths(context)
8884+
.create_blinded_paths(context, blinded_path)
88988885
.and_then(|paths| paths.into_iter().next().ok_or(()))
88998886
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
89008887

@@ -8970,24 +8957,9 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
89708957
let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: None };
89718958

89728959
let builder = match blinded_path {
8973-
Some(BlindedPathType::Compact) => {
8974-
let path = $self
8975-
.create_compact_blinded_paths(context)
8976-
.and_then(|paths| paths.into_iter().next().ok_or(()))
8977-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8978-
8979-
RefundBuilder::deriving_payer_id(
8980-
node_id, expanded_key, nonce, secp_ctx,
8981-
amount_msats, payment_id,
8982-
)?
8983-
.chain_hash($self.chain_hash)
8984-
.absolute_expiry(absolute_expiry)
8985-
.path(path)
8986-
}
8987-
8988-
Some(BlindedPathType::Full) => {
8960+
Some(blinded_path) => {
89898961
let path = $self
8990-
.create_blinded_paths(context)
8962+
.create_blinded_paths(context, blinded_path)
89918963
.and_then(|paths| paths.into_iter().next().ok_or(()))
89928964
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
89938965

@@ -9134,7 +9106,7 @@ where
91349106

91359107
let hmac = payment_id.hmac_for_offer_payment(nonce, expanded_key);
91369108
let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) };
9137-
let reply_paths = self.create_blinded_paths(context)
9109+
let reply_paths = self.create_blinded_paths(context, BlindedPathType::Full)
91389110
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
91399111

91409112
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
@@ -9241,7 +9213,7 @@ where
92419213
let context = OffersContext::InboundPayment {
92429214
payment_hash: invoice.payment_hash(),
92439215
};
9244-
let reply_paths = self.create_blinded_paths(context)
9216+
let reply_paths = self.create_blinded_paths(context, BlindedPathType::Full)
92459217
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
92469218

92479219
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
@@ -9391,7 +9363,7 @@ where
93919363
/// [`MessageRouter::create_blinded_paths`].
93929364
///
93939365
/// Errors if the `MessageRouter` errors.
9394-
fn create_blinded_paths(&self, context: OffersContext) -> Result<Vec<BlindedMessagePath>, ()> {
9366+
fn create_blinded_paths(&self, context: OffersContext, blinded_path: BlindedPathType) -> Result<Vec<BlindedMessagePath>, ()> {
93959367
let recipient = self.get_our_node_id();
93969368
let secp_ctx = &self.secp_ctx;
93979369

@@ -9400,44 +9372,30 @@ where
94009372
.map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap()))
94019373
.filter(|(_, peer)| peer.is_connected)
94029374
.filter(|(_, peer)| peer.latest_features.supports_onion_messages())
9403-
.map(|(node_id, _)| {
9404-
MessageForwardNode {
9405-
node_id: *node_id,
9406-
short_channel_id: None,
9375+
.map(|(node_id, peer)| {
9376+
match blinded_path {
9377+
BlindedPathType::Full => {
9378+
MessageForwardNode {
9379+
node_id: *node_id,
9380+
short_channel_id: None,
9381+
}
9382+
}
9383+
BlindedPathType::Compact => {
9384+
MessageForwardNode {
9385+
node_id: *node_id,
9386+
short_channel_id: peer.channel_by_id
9387+
.iter()
9388+
.filter(|(_, channel)| channel.context().is_usable())
9389+
.min_by_key(|(_, channel)| channel.context().channel_creation_height)
9390+
.and_then(|(_, channel)| channel.context().get_short_channel_id()),
9391+
}
9392+
}
94079393
}
94089394
})
94099395
.collect::<Vec<_>>();
94109396

94119397
self.router
9412-
.create_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
9413-
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
9414-
}
9415-
9416-
/// Creates a collection of blinded paths by delegating to
9417-
/// [`MessageRouter::create_compact_blinded_paths`].
9418-
///
9419-
/// Errors if the `MessageRouter` errors.
9420-
fn create_compact_blinded_paths(&self, context: OffersContext) -> Result<Vec<BlindedMessagePath>, ()> {
9421-
let recipient = self.get_our_node_id();
9422-
let secp_ctx = &self.secp_ctx;
9423-
9424-
let peers = self.per_peer_state.read().unwrap()
9425-
.iter()
9426-
.map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap()))
9427-
.filter(|(_, peer)| peer.is_connected)
9428-
.filter(|(_, peer)| peer.latest_features.supports_onion_messages())
9429-
.map(|(node_id, peer)| MessageForwardNode {
9430-
node_id: *node_id,
9431-
short_channel_id: peer.channel_by_id
9432-
.iter()
9433-
.filter(|(_, channel)| channel.context().is_usable())
9434-
.min_by_key(|(_, channel)| channel.context().channel_creation_height)
9435-
.and_then(|(_, channel)| channel.context().get_short_channel_id()),
9436-
})
9437-
.collect::<Vec<_>>();
9438-
9439-
self.router
9440-
.create_compact_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
9398+
.create_blinded_paths(recipient, MessageContext::Offers(context), blinded_path, peers, secp_ctx)
94419399
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
94429400
}
94439401

lightning/src/onion_message/messenger.rs

Lines changed: 22 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
151151
/// # use lightning::blinded_path::message::{BlindedMessagePath, MessageForwardNode, MessageContext};
152152
/// # use lightning::sign::{EntropySource, KeysManager};
153153
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
154-
/// # use lightning::onion_message::messenger::{Destination, MessageRouter, MessageSendInstructions, OnionMessagePath, OnionMessenger};
154+
/// # use lightning::onion_message::messenger::{BlindedPathType, Destination, MessageRouter, MessageSendInstructions, OnionMessagePath, OnionMessenger};
155155
/// # use lightning::onion_message::packet::OnionMessageContents;
156156
/// # use lightning::util::logger::{Logger, Record};
157157
/// # use lightning::util::ser::{Writeable, Writer};
@@ -175,7 +175,7 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
175175
/// # })
176176
/// # }
177177
/// # fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
178-
/// # &self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<MessageForwardNode>, _secp_ctx: &Secp256k1<T>
178+
/// # &self, _recipient: PublicKey, _context: MessageContext, _blinded_path: BlindedPathType, _peers: Vec<MessageForwardNode>, _secp_ctx: &Secp256k1<T>
179179
/// # ) -> Result<Vec<BlindedMessagePath>, ()> {
180180
/// # unreachable!()
181181
/// # }
@@ -449,14 +449,9 @@ pub trait MessageRouter {
449449

450450
/// Creates [`BlindedMessagePath`]s to the `recipient` node. The nodes in `peers` are assumed to
451451
/// be direct peers with the `recipient`.
452-
fn create_blinded_paths<
453-
T: secp256k1::Signing + secp256k1::Verification
454-
>(
455-
&self, recipient: PublicKey, context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
456-
) -> Result<Vec<BlindedMessagePath>, ()>;
457-
458-
/// Creates compact [`BlindedMessagePath`]s to the `recipient` node. The nodes in `peers` are
459-
/// assumed to be direct peers with the `recipient`.
452+
///
453+
/// # Note of compact blinded path:
454+
/// User can decide to create compact blinded path by specifying the appropirate [`BlindedPathType`].
460455
///
461456
/// Compact blinded paths use short channel ids instead of pubkeys for a smaller serialization,
462457
/// which is beneficial when a QR code is used to transport the data. The SCID is passed using
@@ -465,24 +460,12 @@ pub trait MessageRouter {
465460
/// Implementations using additional intermediate nodes are responsible for using a
466461
/// [`MessageForwardNode`] with `Some` short channel id, if possible. Similarly, implementations
467462
/// should call [`BlindedMessagePath::use_compact_introduction_node`].
468-
///
469-
/// The provided implementation simply delegates to [`MessageRouter::create_blinded_paths`],
470-
/// ignoring the short channel ids.
471-
fn create_compact_blinded_paths<
463+
fn create_blinded_paths<
472464
T: secp256k1::Signing + secp256k1::Verification
473465
>(
474-
&self, recipient: PublicKey, context: MessageContext,
466+
&self, recipient: PublicKey, context: MessageContext, blinded_path: BlindedPathType,
475467
peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
476-
) -> Result<Vec<BlindedMessagePath>, ()> {
477-
let peers = peers
478-
.into_iter()
479-
.map(|mut node| {
480-
node.short_channel_id = None;
481-
node
482-
})
483-
.collect();
484-
self.create_blinded_paths(recipient, context, peers, secp_ctx)
485-
}
468+
) -> Result<Vec<BlindedMessagePath>, ()>;
486469
}
487470

488471
/// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
@@ -516,8 +499,8 @@ where
516499
I: ExactSizeIterator<Item = MessageForwardNode>,
517500
T: secp256k1::Signing + secp256k1::Verification
518501
>(
519-
network_graph: &G, recipient: PublicKey, context: MessageContext, peers: I,
520-
entropy_source: &ES, secp_ctx: &Secp256k1<T>, compact_paths: bool,
502+
network_graph: &G, recipient: PublicKey, context: MessageContext, blinded_path: BlindedPathType,
503+
peers: I, entropy_source: &ES, secp_ctx: &Secp256k1<T>
521504
) -> Result<Vec<BlindedMessagePath>, ()> {
522505
// Limit the number of blinded paths that are computed.
523506
const MAX_PATHS: usize = 3;
@@ -573,10 +556,13 @@ where
573556
},
574557
}?;
575558

576-
if compact_paths {
577-
for path in &mut paths {
578-
path.use_compact_introduction_node(&network_graph);
559+
match blinded_path {
560+
BlindedPathType::Compact => {
561+
for path in &mut paths {
562+
path.use_compact_introduction_node(&network_graph);
563+
}
579564
}
565+
BlindedPathType::Full => {}
580566
}
581567

582568
Ok(paths)
@@ -618,25 +604,10 @@ where
618604
pub(crate) fn create_blinded_paths<
619605
T: secp256k1::Signing + secp256k1::Verification
620606
>(
621-
network_graph: &G, recipient: PublicKey, context: MessageContext,
607+
network_graph: &G, recipient: PublicKey, context: MessageContext, blinded_path: BlindedPathType,
622608
peers: Vec<MessageForwardNode>, entropy_source: &ES, secp_ctx: &Secp256k1<T>,
623609
) -> Result<Vec<BlindedMessagePath>, ()> {
624-
let peers = peers
625-
.into_iter()
626-
.map(|mut node| {
627-
node.short_channel_id = None;
628-
node
629-
});
630-
Self::create_blinded_paths_from_iter(network_graph, recipient, context, peers.into_iter(), entropy_source, secp_ctx, false)
631-
}
632-
633-
pub(crate) fn create_compact_blinded_paths<
634-
T: secp256k1::Signing + secp256k1::Verification
635-
>(
636-
network_graph: &G, recipient: PublicKey, context: MessageContext,
637-
peers: Vec<MessageForwardNode>, entropy_source: &ES, secp_ctx: &Secp256k1<T>,
638-
) -> Result<Vec<BlindedMessagePath>, ()> {
639-
Self::create_blinded_paths_from_iter(network_graph, recipient, context, peers.into_iter(), entropy_source, secp_ctx, true)
610+
Self::create_blinded_paths_from_iter(network_graph, recipient, context, blinded_path, peers.into_iter(), entropy_source, secp_ctx)
640611
}
641612
}
642613

@@ -654,19 +625,11 @@ where
654625
fn create_blinded_paths<
655626
T: secp256k1::Signing + secp256k1::Verification
656627
>(
657-
&self, recipient: PublicKey, context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
658-
) -> Result<Vec<BlindedMessagePath>, ()> {
659-
Self::create_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx)
660-
}
661-
662-
fn create_compact_blinded_paths<
663-
T: secp256k1::Signing + secp256k1::Verification
664-
>(
665-
&self, recipient: PublicKey, context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
628+
&self, recipient: PublicKey, context: MessageContext, blinded_path: BlindedPathType,
629+
peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
666630
) -> Result<Vec<BlindedMessagePath>, ()> {
667-
Self::create_compact_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx)
631+
Self::create_blinded_paths(&self.network_graph, recipient, context, blinded_path, peers, &self.entropy_source, secp_ctx)
668632
}
669-
670633
}
671634

672635
/// A path for sending an [`OnionMessage`].
@@ -1266,7 +1229,7 @@ where
12661229
.collect::<Vec<_>>();
12671230

12681231
self.message_router
1269-
.create_blinded_paths(recipient, context, peers, secp_ctx)
1232+
.create_blinded_paths(recipient, context, BlindedPathType::Full, peers, secp_ctx)
12701233
.and_then(|paths| paths.into_iter().next().ok_or(()))
12711234
.map_err(|_| SendError::PathNotFound)
12721235
}

lightning/src/routing/router.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::ln::features::{BlindedHopFeatures, Bolt11InvoiceFeatures, Bolt12Invoi
2121
use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
2222
use crate::ln::onion_utils;
2323
use crate::offers::invoice::Bolt12Invoice;
24-
use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, OnionMessagePath};
24+
use crate::onion_message::messenger::{BlindedPathType, DefaultMessageRouter, Destination, MessageRouter, OnionMessagePath};
2525
use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId};
2626
use crate::routing::scoring::{ChannelUsage, LockableScore, ScoreLookUp};
2727
use crate::sign::EntropySource;
@@ -197,17 +197,10 @@ impl< G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Siz
197197
fn create_blinded_paths<
198198
T: secp256k1::Signing + secp256k1::Verification
199199
> (
200-
&self, recipient: PublicKey, context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
200+
&self, recipient: PublicKey, context: MessageContext, blinded_path: BlindedPathType, peers: Vec<MessageForwardNode>,
201+
secp_ctx: &Secp256k1<T>,
201202
) -> Result<Vec<BlindedMessagePath>, ()> {
202-
DefaultMessageRouter::create_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx)
203-
}
204-
205-
fn create_compact_blinded_paths<
206-
T: secp256k1::Signing + secp256k1::Verification
207-
> (
208-
&self, recipient: PublicKey, context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
209-
) -> Result<Vec<BlindedMessagePath>, ()> {
210-
DefaultMessageRouter::create_compact_blinded_paths(&self.network_graph, recipient, context, peers, &self.entropy_source, secp_ctx)
203+
DefaultMessageRouter::create_blinded_paths(&self.network_graph, recipient, context, blinded_path, peers, &self.entropy_source, secp_ctx)
211204
}
212205
}
213206

0 commit comments

Comments
 (0)