Skip to content

Commit 8d0ba4a

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 d799607 commit 8d0ba4a

File tree

2 files changed

+55
-37
lines changed

2 files changed

+55
-37
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use crate::offers::parse::Bolt12SemanticError;
7272
use crate::offers::refund::{Refund, RefundBuilder};
7373
use crate::offers::signer;
7474
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
75-
use crate::onion_message::messenger::{Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
75+
use crate::onion_message::messenger::{BlindedPathType, Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
7676
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
7777
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7878
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -1726,12 +1726,13 @@ where
17261726
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
17271727
/// # use lightning::ln::channelmanager::AChannelManager;
17281728
/// # use lightning::offers::parse::Bolt12SemanticError;
1729+
/// # use lightning::onion_message::messenger::BlindedPathType;
17291730
/// #
17301731
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
17311732
/// # let channel_manager = channel_manager.get_cm();
1732-
/// # let absolute_expiry = None;
1733+
/// # let blinded_path = BlindedPathType::Full;
17331734
/// let offer = channel_manager
1734-
/// .create_offer_builder(absolute_expiry)?
1735+
/// .create_offer_builder(Some(blinded_path))?
17351736
/// # ;
17361737
/// # // Needed for compiling for c_bindings
17371738
/// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
@@ -8868,7 +8869,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
88688869
/// [`Offer`]: crate::offers::offer::Offer
88698870
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
88708871
pub fn create_offer_builder(
8871-
&$self, absolute_expiry: Option<Duration>
8872+
&$self, blinded_path: Option<BlindedPathType>,
88728873
) -> Result<$builder, Bolt12SemanticError> {
88738874
let node_id = $self.get_our_node_id();
88748875
let expanded_key = &$self.inbound_payment_key;
@@ -8877,16 +8878,31 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
88778878

88788879
let nonce = Nonce::from_entropy_source(entropy);
88798880
let context = OffersContext::InvoiceRequest { nonce };
8880-
let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
8881-
.and_then(|paths| paths.into_iter().next().ok_or(()))
8882-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8883-
let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
8884-
.chain_hash($self.chain_hash)
8885-
.path(path);
8881+
let builder = match blinded_path {
8882+
Some(BlindedPathType::Compact) => {
8883+
let path = $self
8884+
.create_compact_blinded_paths(context)
8885+
.and_then(|paths| paths.into_iter().next().ok_or(()))
8886+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
88868887

8887-
let builder = match absolute_expiry {
8888-
None => builder,
8889-
Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
8888+
OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
8889+
.chain_hash($self.chain_hash)
8890+
.path(path)
8891+
}
8892+
8893+
Some(BlindedPathType::Full) => {
8894+
let path = $self
8895+
.create_blinded_paths(context)
8896+
.and_then(|paths| paths.into_iter().next().ok_or(()))
8897+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8898+
8899+
OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
8900+
.chain_hash($self.chain_hash)
8901+
.path(path)
8902+
}
8903+
8904+
None => OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
8905+
.chain_hash($self.chain_hash),
88908906
};
88918907

88928908
Ok(builder.into())

lightning/src/ln/offers_tests.rs

Lines changed: 26 additions & 24 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};
@@ -301,7 +301,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
301301
announce_node_address(charlie, &[alice, bob, david, &nodes[4], &nodes[5]], tor.clone());
302302

303303
let offer = bob.node
304-
.create_offer_builder(None).unwrap()
304+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
305305
.amount_msats(10_000_000)
306306
.build().unwrap();
307307
assert_ne!(offer.signing_pubkey(), Some(bob_id));
@@ -317,7 +317,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() {
317317
announce_node_address(&nodes[5], &[alice, bob, charlie, david, &nodes[4]], tor.clone());
318318

319319
let offer = bob.node
320-
.create_offer_builder(None).unwrap()
320+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
321321
.amount_msats(10_000_000)
322322
.build().unwrap();
323323
assert_ne!(offer.signing_pubkey(), Some(bob_id));
@@ -368,7 +368,7 @@ fn prefers_more_connected_nodes_in_blinded_paths() {
368368
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
369369

370370
let offer = bob.node
371-
.create_offer_builder(None).unwrap()
371+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
372372
.amount_msats(10_000_000)
373373
.build().unwrap();
374374
assert_ne!(offer.signing_pubkey(), Some(bob_id));
@@ -395,7 +395,8 @@ fn creates_short_lived_offer() {
395395

396396
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
397397
let offer = alice.node
398-
.create_offer_builder(Some(absolute_expiry)).unwrap()
398+
.create_offer_builder(Some(BlindedPathType::Compact)).unwrap()
399+
.absolute_expiry(absolute_expiry)
399400
.build().unwrap();
400401
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
401402
assert!(!offer.paths().is_empty());
@@ -422,8 +423,8 @@ fn creates_long_lived_offer() {
422423
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY
423424
+ Duration::from_secs(1);
424425
let offer = alice.node
425-
.create_offer_builder(Some(absolute_expiry))
426-
.unwrap()
426+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
427+
.absolute_expiry(absolute_expiry)
427428
.build().unwrap();
428429
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
429430
assert!(!offer.paths().is_empty());
@@ -432,7 +433,7 @@ fn creates_long_lived_offer() {
432433
}
433434

434435
let offer = alice.node
435-
.create_offer_builder(None).unwrap()
436+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
436437
.build().unwrap();
437438
assert_eq!(offer.absolute_expiry(), None);
438439
assert!(!offer.paths().is_empty());
@@ -536,7 +537,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
536537
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
537538

538539
let offer = alice.node
539-
.create_offer_builder(None)
540+
.create_offer_builder(Some(BlindedPathType::Full))
540541
.unwrap()
541542
.amount_msats(10_000_000)
542543
.build().unwrap();
@@ -694,7 +695,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
694695
let bob_id = bob.node.get_our_node_id();
695696

696697
let offer = alice.node
697-
.create_offer_builder(None).unwrap()
698+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
698699
.amount_msats(10_000_000)
699700
.build().unwrap();
700701
assert_ne!(offer.signing_pubkey(), Some(alice_id));
@@ -814,7 +815,7 @@ fn pays_for_offer_without_blinded_paths() {
814815
let bob_id = bob.node.get_our_node_id();
815816

816817
let offer = alice.node
817-
.create_offer_builder(None).unwrap()
818+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
818819
.clear_paths()
819820
.amount_msats(10_000_000)
820821
.build().unwrap();
@@ -937,7 +938,7 @@ fn send_invoice_requests_with_distinct_reply_path() {
937938
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
938939

939940
let offer = alice.node
940-
.create_offer_builder(None)
941+
.create_offer_builder(Some(BlindedPathType::Full))
941942
.unwrap()
942943
.amount_msats(10_000_000)
943944
.build().unwrap();
@@ -1075,7 +1076,7 @@ fn pays_bolt12_invoice_asynchronously() {
10751076
let bob_id = bob.node.get_our_node_id();
10761077

10771078
let offer = alice.node
1078-
.create_offer_builder(None).unwrap()
1079+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
10791080
.amount_msats(10_000_000)
10801081
.build().unwrap();
10811082

@@ -1159,7 +1160,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
11591160
let bob_id = bob.node.get_our_node_id();
11601161

11611162
let offer = alice.node
1162-
.create_offer_builder(None).unwrap()
1163+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
11631164
.amount_msats(10_000_000)
11641165
.build().unwrap();
11651166
assert_ne!(offer.signing_pubkey(), Some(alice_id));
@@ -1287,7 +1288,7 @@ fn fails_authentication_when_handling_invoice_request() {
12871288
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
12881289

12891290
let offer = alice.node
1290-
.create_offer_builder(None)
1291+
.create_offer_builder(Some(BlindedPathType::Full))
12911292
.unwrap()
12921293
.amount_msats(10_000_000)
12931294
.build().unwrap();
@@ -1299,7 +1300,7 @@ fn fails_authentication_when_handling_invoice_request() {
12991300
}
13001301

13011302
let invalid_path = alice.node
1302-
.create_offer_builder(None)
1303+
.create_offer_builder(Some(BlindedPathType::Full))
13031304
.unwrap()
13041305
.build().unwrap()
13051306
.paths().first().unwrap()
@@ -1399,7 +1400,7 @@ fn fails_authentication_when_handling_invoice_for_offer() {
13991400
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
14001401

14011402
let offer = alice.node
1402-
.create_offer_builder(None)
1403+
.create_offer_builder(Some(BlindedPathType::Full))
14031404
.unwrap()
14041405
.amount_msats(10_000_000)
14051406
.build().unwrap();
@@ -1596,7 +1597,7 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
15961597
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
15971598

15981599
let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
1599-
match alice.node.create_offer_builder(Some(absolute_expiry)) {
1600+
match alice.node.create_offer_builder(Some(BlindedPathType::Full)) {
16001601
Ok(_) => panic!("Expected error"),
16011602
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
16021603
}
@@ -1606,7 +1607,8 @@ fn fails_creating_or_paying_for_offer_without_connected_peers() {
16061607
reconnect_nodes(args);
16071608

16081609
let offer = alice.node
1609-
.create_offer_builder(Some(absolute_expiry)).unwrap()
1610+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
1611+
.absolute_expiry(absolute_expiry)
16101612
.amount_msats(10_000_000)
16111613
.build().unwrap();
16121614

@@ -1710,7 +1712,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() {
17101712
let bob = &nodes[1];
17111713

17121714
let offer = alice.node
1713-
.create_offer_builder(None).unwrap()
1715+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
17141716
.clear_chains()
17151717
.chain(Network::Signet)
17161718
.build().unwrap();
@@ -1769,7 +1771,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
17691771
disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]);
17701772

17711773
let offer = alice.node
1772-
.create_offer_builder(None).unwrap()
1774+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
17731775
.amount_msats(10_000_000)
17741776
.build().unwrap();
17751777

@@ -1803,7 +1805,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() {
18031805
disconnect_peers(alice, &[charlie, david, &nodes[4], &nodes[5]]);
18041806

18051807
let offer = alice.node
1806-
.create_offer_builder(None).unwrap()
1808+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
18071809
.amount_msats(10_000_000)
18081810
.build().unwrap();
18091811

@@ -1889,7 +1891,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() {
18891891
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
18901892

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

@@ -2098,7 +2100,7 @@ fn fails_paying_invoice_with_unknown_required_features() {
20982100
disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]);
20992101

21002102
let offer = alice.node
2101-
.create_offer_builder(None).unwrap()
2103+
.create_offer_builder(Some(BlindedPathType::Full)).unwrap()
21022104
.amount_msats(10_000_000)
21032105
.build().unwrap();
21042106

0 commit comments

Comments
 (0)