Skip to content

Commit dd5e639

Browse files
committed
Update create_offer_builder to use create_blinded_paths
To simplify blinded path creation and uphold the principle of "One `MessageRouter`, one `BlindedPath` type," this commit updates `create_offer_builder` to use the `create_blinded_paths` method of the `MessageRouter`. Now, when `create_offer_builder` is called, the offer will be created using the `MessageRouter` implementation that the `ChannelManager` or `OffersMessageFlow` is parameterized with. If a user wishes to create an offer with a different type of blinded path, they can explicitly use `create_offer_builder_using_router`, which allows passing a custom `MessageRouter`. The reasoning behind this change is to give users clearer, more deterministic control over the type of blinded path used in the offer. It also improves user awareness, ensuring that creating a non-default blinded path becomes an *intentional choice*.
1 parent f3e20da commit dd5e639

File tree

6 files changed

+133
-103
lines changed

6 files changed

+133
-103
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ mod test {
482482

483483
let name = HumanReadableName::from_encoded("[email protected]").unwrap();
484484

485-
let bs_offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
485+
let bs_offer = nodes[1].node.create_offer_builder().unwrap().build().unwrap();
486486
let resolvers = vec![Destination::Node(resolver_id)];
487487
let retry = Retry::Attempts(0);
488488
let amt = 42_000;

lightning/src/ln/channelmanager.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,9 +2214,8 @@ where
22142214
/// #
22152215
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
22162216
/// # let channel_manager = channel_manager.get_cm();
2217-
/// # let absolute_expiry = None;
22182217
/// let offer = channel_manager
2219-
/// .create_offer_builder(absolute_expiry)?
2218+
/// .create_offer_builder()?
22202219
/// # ;
22212220
/// # // Needed for compiling for c_bindings
22222221
/// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
@@ -10901,9 +10900,8 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
1090110900
///
1090210901
/// # Privacy
1090310902
///
10904-
/// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the offer based on the given
10905-
/// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
10906-
/// privacy implications.
10903+
/// Uses the [`MessageRouter`] provided to the [`ChannelManager`] at construction to build a
10904+
/// [`BlindedMessagePath`] for the offer. See those docs for privacy implications.
1090710905
///
1090810906
/// Also, uses a derived signing pubkey in the offer for recipient privacy.
1090910907
///
@@ -10913,17 +10911,40 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
1091310911
///
1091410912
/// # Errors
1091510913
///
10916-
/// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
10914+
/// Errors if the parameterized [`MessageRouter`] is unable to create a blinded path for the offer.
1091710915
///
1091810916
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
1091910917
/// [`Offer`]: crate::offers::offer::Offer
1092010918
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
10921-
pub fn create_offer_builder(
10922-
&$self, absolute_expiry: Option<Duration>
10923-
) -> Result<$builder, Bolt12SemanticError> {
10924-
let entropy = &*$self.entropy_source;
10919+
pub fn create_offer_builder(&$self) -> Result<$builder, Bolt12SemanticError> {
10920+
let builder = $self.flow.create_offer_builder(
10921+
&*$self.entropy_source, $self.get_peers_for_blinded_path()
10922+
)?;
1092510923

10926-
let builder = $self.flow.create_offer_builder(entropy, absolute_expiry, $self.get_peers_for_blinded_path())?;
10924+
Ok(builder.into())
10925+
}
10926+
10927+
/// Same as [`Self::create_offer_builder`], but allows specifying a custom [`MessageRouter`]
10928+
/// instead of using the [`MessageRouter`] provided to the [`ChannelManager`] at construction.
10929+
///
10930+
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
10931+
/// including the option to omit it entirely.
10932+
///
10933+
/// See [`Self::create_offer_builder`] for details on offer construction, privacy, and limitations.
10934+
///
10935+
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
10936+
/// [`Offer`]: crate::offers::offer::Offer
10937+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
10938+
pub fn create_offer_builder_using_router<ME: Deref>(
10939+
&$self,
10940+
router: ME,
10941+
) -> Result<$builder, Bolt12SemanticError>
10942+
where
10943+
ME::Target: MessageRouter,
10944+
{
10945+
let builder = $self.flow.create_offer_builder_using_router(
10946+
router, &*$self.entropy_source, $self.get_peers_for_blinded_path()
10947+
)?;
1092710948

1092810949
Ok(builder.into())
1092910950
}

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
517517
),
518518
]);
519519

520-
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
520+
let offer = nodes[1].node.create_offer_builder().unwrap().build().unwrap();
521521
let payment_id = PaymentId([1; 32]);
522522
let route_config = RouteParametersConfig::default();
523523
nodes[0]

lightning/src/ln/offers_tests.rs

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use crate::offers::invoice_error::InvoiceError;
6060
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestFields};
6161
use crate::offers::nonce::Nonce;
6262
use crate::offers::parse::Bolt12SemanticError;
63-
use crate::onion_message::messenger::{Destination, PeeledOnion, MessageSendInstructions};
63+
use crate::onion_message::messenger::{Destination, MessageSendInstructions, NodeIdMessageRouter, PeeledOnion};
6464
use crate::onion_message::offers::OffersMessage;
6565
use crate::routing::gossip::{NodeAlias, NodeId};
6666
use crate::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
@@ -307,7 +307,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
307307
announce_node_address(charlie, &[alice, bob, david, &nodes[4], &nodes[5]], tor.clone());
308308

309309
let offer = bob.node
310-
.create_offer_builder(None).unwrap()
310+
.create_offer_builder().unwrap()
311311
.amount_msats(10_000_000)
312312
.build().unwrap();
313313
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -323,7 +323,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
323323
announce_node_address(&nodes[5], &[alice, bob, charlie, david, &nodes[4]], tor.clone());
324324

325325
let offer = bob.node
326-
.create_offer_builder(None).unwrap()
326+
.create_offer_builder().unwrap()
327327
.amount_msats(10_000_000)
328328
.build().unwrap();
329329
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -374,7 +374,7 @@ fn prefers_more_connected_nodes_in_blinded_paths() {
374374
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
375375

376376
let offer = bob.node
377-
.create_offer_builder(None).unwrap()
377+
.create_offer_builder().unwrap()
378378
.amount_msats(10_000_000)
379379
.build().unwrap();
380380
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -399,11 +399,9 @@ fn creates_short_lived_offer() {
399399
let alice_id = alice.node.get_our_node_id();
400400
let bob = &nodes[1];
401401

402-
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
403402
let offer = alice.node
404-
.create_offer_builder(Some(absolute_expiry)).unwrap()
403+
.create_offer_builder().unwrap()
405404
.build().unwrap();
406-
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
407405
assert!(!offer.paths().is_empty());
408406
for path in offer.paths() {
409407
let introduction_node_id = resolve_introduction_node(bob, &path);
@@ -416,7 +414,7 @@ fn creates_short_lived_offer() {
416414
#[test]
417415
fn creates_long_lived_offer() {
418416
let chanmon_cfgs = create_chanmon_cfgs(2);
419-
let node_cfgs = create_node_cfgs_with_node_id_message_router(2, &chanmon_cfgs);
417+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
420418
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
421419
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
422420

@@ -425,22 +423,11 @@ fn creates_long_lived_offer() {
425423
let alice = &nodes[0];
426424
let alice_id = alice.node.get_our_node_id();
427425

428-
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY
429-
+ Duration::from_secs(1);
426+
let router = NodeIdMessageRouter::new(alice.network_graph, alice.keys_manager);
430427
let offer = alice.node
431-
.create_offer_builder(Some(absolute_expiry))
428+
.create_offer_builder_using_router(&router)
432429
.unwrap()
433430
.build().unwrap();
434-
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
435-
assert!(!offer.paths().is_empty());
436-
for path in offer.paths() {
437-
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
438-
}
439-
440-
let offer = alice.node
441-
.create_offer_builder(None).unwrap()
442-
.build().unwrap();
443-
assert_eq!(offer.absolute_expiry(), None);
444431
assert!(!offer.paths().is_empty());
445432
for path in offer.paths() {
446433
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
@@ -542,7 +529,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
542529
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
543530

544531
let offer = alice.node
545-
.create_offer_builder(None)
532+
.create_offer_builder()
546533
.unwrap()
547534
.amount_msats(10_000_000)
548535
.build().unwrap();
@@ -709,7 +696,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
709696
let bob_id = bob.node.get_our_node_id();
710697

711698
let offer = alice.node
712-
.create_offer_builder(None).unwrap()
699+
.create_offer_builder().unwrap()
713700
.amount_msats(10_000_000)
714701
.build().unwrap();
715702
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -832,7 +819,7 @@ fn pays_for_offer_without_blinded_paths() {
832819
let bob_id = bob.node.get_our_node_id();
833820

834821
let offer = alice.node
835-
.create_offer_builder(None).unwrap()
822+
.create_offer_builder().unwrap()
836823
.clear_paths()
837824
.amount_msats(10_000_000)
838825
.build().unwrap();
@@ -956,7 +943,7 @@ fn send_invoice_requests_with_distinct_reply_path() {
956943
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
957944

958945
let offer = alice.node
959-
.create_offer_builder(None)
946+
.create_offer_builder()
960947
.unwrap()
961948
.amount_msats(10_000_000)
962949
.build().unwrap();
@@ -1092,7 +1079,7 @@ fn creates_and_pays_for_offer_with_retry() {
10921079
let bob_id = bob.node.get_our_node_id();
10931080

10941081
let offer = alice.node
1095-
.create_offer_builder(None).unwrap()
1082+
.create_offer_builder().unwrap()
10961083
.amount_msats(10_000_000)
10971084
.build().unwrap();
10981085
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1168,7 +1155,7 @@ fn pays_bolt12_invoice_asynchronously() {
11681155
let bob_id = bob.node.get_our_node_id();
11691156

11701157
let offer = alice.node
1171-
.create_offer_builder(None).unwrap()
1158+
.create_offer_builder().unwrap()
11721159
.amount_msats(10_000_000)
11731160
.build().unwrap();
11741161

@@ -1260,7 +1247,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
12601247
let bob_id = bob.node.get_our_node_id();
12611248

12621249
let offer = alice.node
1263-
.create_offer_builder(None).unwrap()
1250+
.create_offer_builder().unwrap()
12641251
.amount_msats(10_000_000)
12651252
.build().unwrap();
12661253
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1390,7 +1377,7 @@ fn fails_authentication_when_handling_invoice_request() {
13901377
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
13911378

13921379
let offer = alice.node
1393-
.create_offer_builder(None)
1380+
.create_offer_builder()
13941381
.unwrap()
13951382
.amount_msats(10_000_000)
13961383
.build().unwrap();
@@ -1402,7 +1389,7 @@ fn fails_authentication_when_handling_invoice_request() {
14021389
}
14031390

14041391
let invalid_path = alice.node
1405-
.create_offer_builder(None)
1392+
.create_offer_builder()
14061393
.unwrap()
14071394
.build().unwrap()
14081395
.paths().first().unwrap()
@@ -1502,7 +1489,7 @@ fn fails_authentication_when_handling_invoice_for_offer() {
15021489
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
15031490

15041491
let offer = alice.node
1505-
.create_offer_builder(None)
1492+
.create_offer_builder()
15061493
.unwrap()
15071494
.amount_msats(10_000_000)
15081495
.build().unwrap();
@@ -1698,8 +1685,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16981685
disconnect_peers(alice, &[bob, charlie, david, &nodes[4], &nodes[5]]);
16991686
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
17001687

1701-
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
1702-
match alice.node.create_offer_builder(Some(absolute_expiry)) {
1688+
match alice.node.create_offer_builder() {
17031689
Ok(_) => panic!("Expected error"),
17041690
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
17051691
}
@@ -1708,9 +1694,11 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
17081694
args.send_channel_ready = (true, true);
17091695
reconnect_nodes(args);
17101696

1697+
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
17111698
let offer = alice.node
1712-
.create_offer_builder(Some(absolute_expiry)).unwrap()
1699+
.create_offer_builder().unwrap()
17131700
.amount_msats(10_000_000)
1701+
.absolute_expiry(absolute_expiry)
17141702
.build().unwrap();
17151703

17161704
let payment_id = PaymentId([1; 32]);
@@ -1813,7 +1801,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
18131801
let bob = &nodes[1];
18141802

18151803
let offer = alice.node
1816-
.create_offer_builder(None).unwrap()
1804+
.create_offer_builder().unwrap()
18171805
.clear_chains()
18181806
.chain(Network::Signet)
18191807
.build().unwrap();
@@ -1872,7 +1860,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
18721860
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
18731861

18741862
let offer = alice.node
1875-
.create_offer_builder(None).unwrap()
1863+
.create_offer_builder().unwrap()
18761864
.amount_msats(10_000_000)
18771865
.build().unwrap();
18781866

@@ -1906,7 +1894,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
19061894
disconnect_peers(alice, &[charlie, david, &nodes[4], &nodes[5]]);
19071895

19081896
let offer = alice.node
1909-
.create_offer_builder(None).unwrap()
1897+
.create_offer_builder().unwrap()
19101898
.amount_msats(10_000_000)
19111899
.build().unwrap();
19121900

@@ -1992,7 +1980,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() {
19921980
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
19931981

19941982
let offer = alice.node
1995-
.create_offer_builder(None).unwrap()
1983+
.create_offer_builder().unwrap()
19961984
.amount_msats(10_000_000)
19971985
.build().unwrap();
19981986

@@ -2201,7 +2189,7 @@ fn fails_paying_invoice_with_unknown_required_features() {
22012189
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
22022190

22032191
let offer = alice.node
2204-
.create_offer_builder(None).unwrap()
2192+
.create_offer_builder().unwrap()
22052193
.amount_msats(10_000_000)
22062194
.build().unwrap();
22072195

@@ -2280,7 +2268,7 @@ fn rejects_keysend_to_non_static_invoice_path() {
22802268
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
22812269

22822270
// First pay the offer and save the payment preimage and invoice.
2283-
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
2271+
let offer = nodes[1].node.create_offer_builder().unwrap().build().unwrap();
22842272
let amt_msat = 5000;
22852273
let payment_id = PaymentId([1; 32]);
22862274
nodes[0].node.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), RouteParametersConfig::default()).unwrap();
@@ -2360,7 +2348,7 @@ fn no_double_pay_with_stale_channelmanager() {
23602348

23612349
let amt_msat = nodes[0].node.list_usable_channels()[0].next_outbound_htlc_limit_msat + 1; // Force MPP
23622350
let offer = nodes[1].node
2363-
.create_offer_builder(None).unwrap()
2351+
.create_offer_builder().unwrap()
23642352
.clear_paths()
23652353
.amount_msats(amt_msat)
23662354
.build().unwrap();

0 commit comments

Comments
 (0)