Skip to content

Commit 985676e

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 985676e

File tree

6 files changed

+134
-95
lines changed

6 files changed

+134
-95
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: 30 additions & 33 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,20 +423,18 @@ 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));
435431
assert!(!offer.paths().is_empty());
436432
for path in offer.paths() {
437433
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
438434
}
439435

440436
let offer = alice.node
441-
.create_offer_builder(None).unwrap()
437+
.create_offer_builder_using_router(&router).unwrap()
442438
.build().unwrap();
443439
assert_eq!(offer.absolute_expiry(), None);
444440
assert!(!offer.paths().is_empty());
@@ -542,7 +538,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
542538
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
543539

544540
let offer = alice.node
545-
.create_offer_builder(None)
541+
.create_offer_builder()
546542
.unwrap()
547543
.amount_msats(10_000_000)
548544
.build().unwrap();
@@ -709,7 +705,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
709705
let bob_id = bob.node.get_our_node_id();
710706

711707
let offer = alice.node
712-
.create_offer_builder(None).unwrap()
708+
.create_offer_builder().unwrap()
713709
.amount_msats(10_000_000)
714710
.build().unwrap();
715711
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -832,7 +828,7 @@ fn pays_for_offer_without_blinded_paths() {
832828
let bob_id = bob.node.get_our_node_id();
833829

834830
let offer = alice.node
835-
.create_offer_builder(None).unwrap()
831+
.create_offer_builder().unwrap()
836832
.clear_paths()
837833
.amount_msats(10_000_000)
838834
.build().unwrap();
@@ -956,7 +952,7 @@ fn send_invoice_requests_with_distinct_reply_path() {
956952
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
957953

958954
let offer = alice.node
959-
.create_offer_builder(None)
955+
.create_offer_builder()
960956
.unwrap()
961957
.amount_msats(10_000_000)
962958
.build().unwrap();
@@ -1092,7 +1088,7 @@ fn creates_and_pays_for_offer_with_retry() {
10921088
let bob_id = bob.node.get_our_node_id();
10931089

10941090
let offer = alice.node
1095-
.create_offer_builder(None).unwrap()
1091+
.create_offer_builder().unwrap()
10961092
.amount_msats(10_000_000)
10971093
.build().unwrap();
10981094
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1168,7 +1164,7 @@ fn pays_bolt12_invoice_asynchronously() {
11681164
let bob_id = bob.node.get_our_node_id();
11691165

11701166
let offer = alice.node
1171-
.create_offer_builder(None).unwrap()
1167+
.create_offer_builder().unwrap()
11721168
.amount_msats(10_000_000)
11731169
.build().unwrap();
11741170

@@ -1260,7 +1256,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
12601256
let bob_id = bob.node.get_our_node_id();
12611257

12621258
let offer = alice.node
1263-
.create_offer_builder(None).unwrap()
1259+
.create_offer_builder().unwrap()
12641260
.amount_msats(10_000_000)
12651261
.build().unwrap();
12661262
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1390,7 +1386,7 @@ fn fails_authentication_when_handling_invoice_request() {
13901386
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
13911387

13921388
let offer = alice.node
1393-
.create_offer_builder(None)
1389+
.create_offer_builder()
13941390
.unwrap()
13951391
.amount_msats(10_000_000)
13961392
.build().unwrap();
@@ -1402,7 +1398,7 @@ fn fails_authentication_when_handling_invoice_request() {
14021398
}
14031399

14041400
let invalid_path = alice.node
1405-
.create_offer_builder(None)
1401+
.create_offer_builder()
14061402
.unwrap()
14071403
.build().unwrap()
14081404
.paths().first().unwrap()
@@ -1502,7 +1498,7 @@ fn fails_authentication_when_handling_invoice_for_offer() {
15021498
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
15031499

15041500
let offer = alice.node
1505-
.create_offer_builder(None)
1501+
.create_offer_builder()
15061502
.unwrap()
15071503
.amount_msats(10_000_000)
15081504
.build().unwrap();
@@ -1698,8 +1694,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16981694
disconnect_peers(alice, &[bob, charlie, david, &nodes[4], &nodes[5]]);
16991695
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
17001696

1701-
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
1702-
match alice.node.create_offer_builder(Some(absolute_expiry)) {
1697+
match alice.node.create_offer_builder() {
17031698
Ok(_) => panic!("Expected error"),
17041699
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
17051700
}
@@ -1708,9 +1703,11 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
17081703
args.send_channel_ready = (true, true);
17091704
reconnect_nodes(args);
17101705

1706+
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
17111707
let offer = alice.node
1712-
.create_offer_builder(Some(absolute_expiry)).unwrap()
1708+
.create_offer_builder().unwrap()
17131709
.amount_msats(10_000_000)
1710+
.absolute_expiry(absolute_expiry)
17141711
.build().unwrap();
17151712

17161713
let payment_id = PaymentId([1; 32]);
@@ -1813,7 +1810,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
18131810
let bob = &nodes[1];
18141811

18151812
let offer = alice.node
1816-
.create_offer_builder(None).unwrap()
1813+
.create_offer_builder().unwrap()
18171814
.clear_chains()
18181815
.chain(Network::Signet)
18191816
.build().unwrap();
@@ -1872,7 +1869,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
18721869
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
18731870

18741871
let offer = alice.node
1875-
.create_offer_builder(None).unwrap()
1872+
.create_offer_builder().unwrap()
18761873
.amount_msats(10_000_000)
18771874
.build().unwrap();
18781875

@@ -1906,7 +1903,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
19061903
disconnect_peers(alice, &[charlie, david, &nodes[4], &nodes[5]]);
19071904

19081905
let offer = alice.node
1909-
.create_offer_builder(None).unwrap()
1906+
.create_offer_builder().unwrap()
19101907
.amount_msats(10_000_000)
19111908
.build().unwrap();
19121909

@@ -1992,7 +1989,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() {
19921989
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
19931990

19941991
let offer = alice.node
1995-
.create_offer_builder(None).unwrap()
1992+
.create_offer_builder().unwrap()
19961993
.amount_msats(10_000_000)
19971994
.build().unwrap();
19981995

@@ -2201,7 +2198,7 @@ fn fails_paying_invoice_with_unknown_required_features() {
22012198
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
22022199

22032200
let offer = alice.node
2204-
.create_offer_builder(None).unwrap()
2201+
.create_offer_builder().unwrap()
22052202
.amount_msats(10_000_000)
22062203
.build().unwrap();
22072204

@@ -2280,7 +2277,7 @@ fn rejects_keysend_to_non_static_invoice_path() {
22802277
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
22812278

22822279
// First pay the offer and save the payment preimage and invoice.
2283-
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
2280+
let offer = nodes[1].node.create_offer_builder().unwrap().build().unwrap();
22842281
let amt_msat = 5000;
22852282
let payment_id = PaymentId([1; 32]);
22862283
nodes[0].node.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), RouteParametersConfig::default()).unwrap();
@@ -2360,7 +2357,7 @@ fn no_double_pay_with_stale_channelmanager() {
23602357

23612358
let amt_msat = nodes[0].node.list_usable_channels()[0].next_outbound_htlc_limit_msat + 1; // Force MPP
23622359
let offer = nodes[1].node
2363-
.create_offer_builder(None).unwrap()
2360+
.create_offer_builder().unwrap()
23642361
.clear_paths()
23652362
.amount_msats(amt_msat)
23662363
.build().unwrap();

0 commit comments

Comments
 (0)