Skip to content

Commit c83e04c

Browse files
committed
Allow explicit specification of Blinded Path type in create_offer_builder
1. This commit introduces flexibility for the user to specify the type of Blinded Path they want, rather than relying on the Offers' absolute expiry to determine the Blinded Path type. 2. It also adds support for creating an Offer without a Blinded Path, using its signing public key for responding to the offer instead.
1 parent 5866dbc commit c83e04c

File tree

2 files changed

+57
-38
lines changed

2 files changed

+57
-38
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use crate::offers::signer;
7474
#[cfg(async_payments)]
7575
use crate::offers::static_invoice::StaticInvoice;
7676
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
77-
use crate::onion_message::messenger::{Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
77+
use crate::onion_message::messenger::{BlindedPathType, Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
7878
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
7979
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
8080
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -1780,12 +1780,13 @@ where
17801780
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
17811781
/// # use lightning::ln::channelmanager::AChannelManager;
17821782
/// # use lightning::offers::parse::Bolt12SemanticError;
1783+
/// # use lightning::onion_message::messenger::BlindedPathType;
17831784
/// #
17841785
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
17851786
/// # let channel_manager = channel_manager.get_cm();
1786-
/// # let absolute_expiry = None;
1787+
/// # let blinded_path = BlindedPathType::Full;
17871788
/// let offer = channel_manager
1788-
/// .create_offer_builder(absolute_expiry)?
1789+
/// .create_offer_builder(Some(blinded_path))?
17891790
/// # ;
17901791
/// # // Needed for compiling for c_bindings
17911792
/// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
@@ -9029,7 +9030,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
90299030
/// [`Offer`]: crate::offers::offer::Offer
90309031
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
90319032
pub fn create_offer_builder(
9032-
&$self, absolute_expiry: Option<Duration>
9033+
&$self, blinded_path: Option<BlindedPathType>,
90339034
) -> Result<$builder, Bolt12SemanticError> {
90349035
let node_id = $self.get_our_node_id();
90359036
let expanded_key = &$self.inbound_payment_key;
@@ -9038,16 +9039,32 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
90389039

90399040
let nonce = Nonce::from_entropy_source(entropy);
90409041
let context = OffersContext::InvoiceRequest { nonce };
9041-
let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
9042-
.and_then(|paths| paths.into_iter().next().ok_or(()))
9043-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9044-
let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9045-
.chain_hash($self.chain_hash)
9046-
.path(path);
9042+
let builder = match blinded_path {
9043+
Some(BlindedPathType::Compact) => {
9044+
let path = $self
9045+
.create_compact_blinded_paths(context)
9046+
.and_then(|paths| paths.into_iter().next().ok_or(()))
9047+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
90479048

9048-
let builder = match absolute_expiry {
9049-
None => builder,
9050-
Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
9049+
OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9050+
.chain_hash($self.chain_hash)
9051+
.path(path)
9052+
}
9053+
9054+
Some(BlindedPathType::Full) => {
9055+
let context = MessageContext::Offers(context);
9056+
let path = $self
9057+
.create_blinded_paths(context)
9058+
.and_then(|paths| paths.into_iter().next().ok_or(()))
9059+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9060+
9061+
OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9062+
.chain_hash($self.chain_hash)
9063+
.path(path)
9064+
}
9065+
9066+
None => OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9067+
.chain_hash($self.chain_hash),
90519068
};
90529069

90539070
Ok(builder.into())

lightning/src/ln/offers_tests.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use crate::offers::invoice_error::InvoiceError;
5959
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestFields};
6060
use crate::offers::nonce::Nonce;
6161
use crate::offers::parse::Bolt12SemanticError;
62-
use crate::onion_message::messenger::{Destination, PeeledOnion, MessageSendInstructions};
62+
use crate::onion_message::messenger::{BlindedPathType, Destination, MessageSendInstructions, PeeledOnion};
6363
use crate::onion_message::offers::OffersMessage;
6464
use crate::onion_message::packet::ParsedOnionMessageContents;
6565
use crate::routing::gossip::{NodeAlias, NodeId};
@@ -303,7 +303,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
303303
announce_node_address(charlie, &[alice, bob, david, &nodes[4], &nodes[5]], tor.clone());
304304

305305
let offer = bob.node
306-
.create_offer_builder(None).unwrap()
306+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
307307
.amount_msats(10_000_000)
308308
.build().unwrap();
309309
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -319,7 +319,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
319319
announce_node_address(&nodes[5], &[alice, bob, charlie, david, &nodes[4]], tor.clone());
320320

321321
let offer = bob.node
322-
.create_offer_builder(None).unwrap()
322+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
323323
.amount_msats(10_000_000)
324324
.build().unwrap();
325325
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -370,7 +370,7 @@ fn prefers_more_connected_nodes_in_blinded_paths() {
370370
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
371371

372372
let offer = bob.node
373-
.create_offer_builder(None).unwrap()
373+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
374374
.amount_msats(10_000_000)
375375
.build().unwrap();
376376
assert_ne!(offer.issuer_signing_pubkey(), Some(bob_id));
@@ -397,7 +397,8 @@ fn creates_short_lived_offer() {
397397

398398
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
399399
let offer = alice.node
400-
.create_offer_builder(Some(absolute_expiry)).unwrap()
400+
.create_offer_builder(Some(BlindedPathType::Compact)).unwrap()
401+
.absolute_expiry(absolute_expiry)
401402
.build().unwrap();
402403
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
403404
assert!(!offer.paths().is_empty());
@@ -424,8 +425,8 @@ fn creates_long_lived_offer() {
424425
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY
425426
+ Duration::from_secs(1);
426427
let offer = alice.node
427-
.create_offer_builder(Some(absolute_expiry))
428-
.unwrap()
428+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
429+
.absolute_expiry(absolute_expiry)
429430
.build().unwrap();
430431
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
431432
assert!(!offer.paths().is_empty());
@@ -434,7 +435,7 @@ fn creates_long_lived_offer() {
434435
}
435436

436437
let offer = alice.node
437-
.create_offer_builder(None).unwrap()
438+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
438439
.build().unwrap();
439440
assert_eq!(offer.absolute_expiry(), None);
440441
assert!(!offer.paths().is_empty());
@@ -538,7 +539,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
538539
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
539540

540541
let offer = alice.node
541-
.create_offer_builder(None)
542+
.create_offer_builder(Some(BlindedPathType::Full))
542543
.unwrap()
543544
.amount_msats(10_000_000)
544545
.build().unwrap();
@@ -707,7 +708,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
707708
let bob_id = bob.node.get_our_node_id();
708709

709710
let offer = alice.node
710-
.create_offer_builder(None).unwrap()
711+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
711712
.amount_msats(10_000_000)
712713
.build().unwrap();
713714
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -829,7 +830,7 @@ fn pays_for_offer_without_blinded_paths() {
829830
let bob_id = bob.node.get_our_node_id();
830831

831832
let offer = alice.node
832-
.create_offer_builder(None).unwrap()
833+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
833834
.clear_paths()
834835
.amount_msats(10_000_000)
835836
.build().unwrap();
@@ -952,7 +953,7 @@ fn send_invoice_requests_with_distinct_reply_path() {
952953
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
953954

954955
let offer = alice.node
955-
.create_offer_builder(None)
956+
.create_offer_builder(Some(BlindedPathType::Full))
956957
.unwrap()
957958
.amount_msats(10_000_000)
958959
.build().unwrap();
@@ -1088,7 +1089,7 @@ fn creates_and_pays_for_offer_with_retry() {
10881089
let bob_id = bob.node.get_our_node_id();
10891090

10901091
let offer = alice.node
1091-
.create_offer_builder(None).unwrap()
1092+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
10921093
.amount_msats(10_000_000)
10931094
.build().unwrap();
10941095
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1162,7 +1163,7 @@ fn pays_bolt12_invoice_asynchronously() {
11621163
let bob_id = bob.node.get_our_node_id();
11631164

11641165
let offer = alice.node
1165-
.create_offer_builder(None).unwrap()
1166+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
11661167
.amount_msats(10_000_000)
11671168
.build().unwrap();
11681169

@@ -1246,7 +1247,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
12461247
let bob_id = bob.node.get_our_node_id();
12471248

12481249
let offer = alice.node
1249-
.create_offer_builder(None).unwrap()
1250+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
12501251
.amount_msats(10_000_000)
12511252
.build().unwrap();
12521253
assert_ne!(offer.issuer_signing_pubkey(), Some(alice_id));
@@ -1375,7 +1376,7 @@ fn fails_authentication_when_handling_invoice_request() {
13751376
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
13761377

13771378
let offer = alice.node
1378-
.create_offer_builder(None)
1379+
.create_offer_builder(Some(BlindedPathType::Full))
13791380
.unwrap()
13801381
.amount_msats(10_000_000)
13811382
.build().unwrap();
@@ -1387,7 +1388,7 @@ fn fails_authentication_when_handling_invoice_request() {
13871388
}
13881389

13891390
let invalid_path = alice.node
1390-
.create_offer_builder(None)
1391+
.create_offer_builder(Some(BlindedPathType::Full))
13911392
.unwrap()
13921393
.build().unwrap()
13931394
.paths().first().unwrap()
@@ -1487,7 +1488,7 @@ fn fails_authentication_when_handling_invoice_for_offer() {
14871488
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
14881489

14891490
let offer = alice.node
1490-
.create_offer_builder(None)
1491+
.create_offer_builder(Some(BlindedPathType::Full))
14911492
.unwrap()
14921493
.amount_msats(10_000_000)
14931494
.build().unwrap();
@@ -1684,7 +1685,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16841685
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
16851686

16861687
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
1687-
match alice.node.create_offer_builder(Some(absolute_expiry)) {
1688+
match alice.node.create_offer_builder(Some(BlindedPathType::Full)) {
16881689
Ok(_) => panic!("Expected error"),
16891690
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
16901691
}
@@ -1694,7 +1695,8 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16941695
reconnect_nodes(args);
16951696

16961697
let offer = alice.node
1697-
.create_offer_builder(Some(absolute_expiry)).unwrap()
1698+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
1699+
.absolute_expiry(absolute_expiry)
16981700
.amount_msats(10_000_000)
16991701
.build().unwrap();
17001702

@@ -1798,7 +1800,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
17981800
let bob = &nodes[1];
17991801

18001802
let offer = alice.node
1801-
.create_offer_builder(None).unwrap()
1803+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
18021804
.clear_chains()
18031805
.chain(Network::Signet)
18041806
.build().unwrap();
@@ -1857,7 +1859,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
18571859
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
18581860

18591861
let offer = alice.node
1860-
.create_offer_builder(None).unwrap()
1862+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
18611863
.amount_msats(10_000_000)
18621864
.build().unwrap();
18631865

@@ -1891,7 +1893,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
18911893
disconnect_peers(alice, &[charlie, david, &nodes[4], &nodes[5]]);
18921894

18931895
let offer = alice.node
1894-
.create_offer_builder(None).unwrap()
1896+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
18951897
.amount_msats(10_000_000)
18961898
.build().unwrap();
18971899

@@ -1977,7 +1979,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() {
19771979
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
19781980

19791981
let offer = alice.node
1980-
.create_offer_builder(None).unwrap()
1982+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
19811983
.amount_msats(10_000_000)
19821984
.build().unwrap();
19831985

@@ -2186,7 +2188,7 @@ fn fails_paying_invoice_with_unknown_required_features() {
21862188
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
21872189

21882190
let offer = alice.node
2189-
.create_offer_builder(None).unwrap()
2191+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
21902192
.amount_msats(10_000_000)
21912193
.build().unwrap();
21922194

0 commit comments

Comments
 (0)