@@ -65,7 +65,7 @@ use crate::offers::merkle::SignError;
65
65
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
66
66
use crate::offers::parse::Bolt12SemanticError;
67
67
use crate::offers::refund::{Refund, RefundBuilder};
68
- use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message};
68
+ use crate::onion_message::{Destination, MessageRouter, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message};
69
69
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider};
70
70
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
71
71
use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
@@ -7416,10 +7416,13 @@ where
7416
7416
///
7417
7417
/// # Privacy
7418
7418
///
7419
- /// Uses a one-hop [`BlindedPath`] for the offer with [`ChannelManager::get_our_node_id`] as the
7420
- /// introduction node and a derived signing pubkey for recipient privacy. As such, currently,
7421
- /// the node must be announced. Otherwise, there is no way to find a path to the introduction
7422
- /// node in order to send the [`InvoiceRequest`].
7419
+ /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the offer.
7420
+ /// However, if one is not found, uses a one-hop [`BlindedPath`] with
7421
+ /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
7422
+ /// the node must be announced, otherwise, there is no way to find a path to the introduction in
7423
+ /// order to send the [`InvoiceRequest`].
7424
+ ///
7425
+ /// Also, uses a derived signing pubkey in the offer for recipient privacy.
7423
7426
///
7424
7427
/// # Limitations
7425
7428
///
@@ -7437,11 +7440,10 @@ where
7437
7440
let expanded_key = &self.inbound_payment_key;
7438
7441
let entropy = &*self.entropy_source;
7439
7442
let secp_ctx = &self.secp_ctx;
7440
- let path = self.create_one_hop_blinded_path();
7441
7443
7442
7444
OfferBuilder::deriving_signing_pubkey(description, node_id, expanded_key, entropy, secp_ctx)
7443
7445
.chain_hash(self.chain_hash)
7444
- .path(path )
7446
+ .path(self.create_blinded_path() )
7445
7447
}
7446
7448
7447
7449
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
@@ -7466,10 +7468,13 @@ where
7466
7468
///
7467
7469
/// # Privacy
7468
7470
///
7469
- /// Uses a one-hop [`BlindedPath`] for the refund with [`ChannelManager::get_our_node_id`] as
7470
- /// the introduction node and a derived payer id for payer privacy. As such, currently, the
7471
- /// node must be announced. Otherwise, there is no way to find a path to the introduction node
7472
- /// in order to send the [`Bolt12Invoice`].
7471
+ /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the refund.
7472
+ /// However, if one is not found, uses a one-hop [`BlindedPath`] with
7473
+ /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
7474
+ /// the node must be announced, otherwise, there is no way to find a path to the introduction in
7475
+ /// order to send the [`Bolt12Invoice`].
7476
+ ///
7477
+ /// Also, uses a derived payer id in the refund for payer privacy.
7473
7478
///
7474
7479
/// # Limitations
7475
7480
///
@@ -7494,14 +7499,13 @@ where
7494
7499
let expanded_key = &self.inbound_payment_key;
7495
7500
let entropy = &*self.entropy_source;
7496
7501
let secp_ctx = &self.secp_ctx;
7497
- let path = self.create_one_hop_blinded_path();
7498
7502
7499
7503
let builder = RefundBuilder::deriving_payer_id(
7500
7504
description, node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
7501
7505
)?
7502
7506
.chain_hash(self.chain_hash)
7503
7507
.absolute_expiry(absolute_expiry)
7504
- .path(path );
7508
+ .path(self.create_blinded_path() );
7505
7509
7506
7510
let expiration = StaleExpiration::AbsoluteTimeout(absolute_expiry);
7507
7511
self.pending_outbound_payments
@@ -7587,9 +7591,8 @@ where
7587
7591
None => builder,
7588
7592
Some(payer_note) => builder.payer_note(payer_note),
7589
7593
};
7590
-
7591
7594
let invoice_request = builder.build_and_sign()?;
7592
- let reply_path = self.create_one_hop_blinded_path ();
7595
+ let reply_path = self.create_blinded_path ();
7593
7596
7594
7597
let expiration = StaleExpiration::TimerTicks(1);
7595
7598
self.pending_outbound_payments
@@ -7665,7 +7668,7 @@ where
7665
7668
payment_paths, payment_hash, created_at, expanded_key, entropy
7666
7669
)?;
7667
7670
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
7668
- let reply_path = self.create_one_hop_blinded_path ();
7671
+ let reply_path = self.create_blinded_path ();
7669
7672
7670
7673
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
7671
7674
if refund.paths().is_empty() {
@@ -7792,6 +7795,15 @@ where
7792
7795
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
7793
7796
}
7794
7797
7798
+ /// Creates a multi-hop blinded path by delegating to [`MessageRouter::create_blinded_paths`].
7799
+ /// If the router returns an error or no paths, creates a one-hop blinded path instead.
7800
+ fn create_blinded_path(&self) -> BlindedPath {
7801
+ self.create_multi_hop_blinded_paths(1)
7802
+ .ok()
7803
+ .and_then(|paths| paths.into_iter().next())
7804
+ .unwrap_or_else(|| self.create_one_hop_blinded_path())
7805
+ }
7806
+
7795
7807
/// Creates a one-hop blinded path with [`ChannelManager::get_our_node_id`] as the introduction
7796
7808
/// node.
7797
7809
fn create_one_hop_blinded_path(&self) -> BlindedPath {
@@ -7800,6 +7812,25 @@ where
7800
7812
BlindedPath::one_hop_for_message(self.get_our_node_id(), entropy_source, secp_ctx).unwrap()
7801
7813
}
7802
7814
7815
+ /// Creates `count` blinded paths by delegating to [`MessageRouter::create_blinded_paths`].
7816
+ ///
7817
+ /// May return fewer paths if there are fewer than `count` peers that [support onion messages].
7818
+ ///
7819
+ /// [support onion messages]: crate::ln::features::InitFeatures::supports_onion_messages
7820
+ fn create_multi_hop_blinded_paths(&self, count: usize) -> Result<Vec<BlindedPath>, ()> {
7821
+ let recipient = self.get_our_node_id();
7822
+ let entropy_source = self.entropy_source.deref();
7823
+ let secp_ctx = &self.secp_ctx;
7824
+
7825
+ let peers = self.per_peer_state.read().unwrap()
7826
+ .iter()
7827
+ .filter(|(_, peer)| peer.lock().unwrap().latest_features.supports_onion_messages())
7828
+ .map(|(node_id, _)| *node_id)
7829
+ .collect::<Vec<_>>();
7830
+
7831
+ self.router.create_blinded_paths(recipient, peers, count, entropy_source, secp_ctx)
7832
+ }
7833
+
7803
7834
/// Creates a one-hop blinded payment path with [`ChannelManager::get_our_node_id`] as the
7804
7835
/// introduction node.
7805
7836
fn create_one_hop_blinded_payment_path(
0 commit comments