Skip to content

Commit d28a14a

Browse files
committed
Allow Explicit Specification of Blinded Path Type in Refund
Similar to the offer case, this commit introduces the ability to explicitly specify the Blinded Path type.
1 parent c83e04c commit d28a14a

File tree

2 files changed

+59
-44
lines changed

2 files changed

+59
-44
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,16 +1884,18 @@ where
18841884
/// # use lightning::events::{Event, EventsProvider};
18851885
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
18861886
/// # use lightning::offers::parse::Bolt12SemanticError;
1887+
/// # use lightning::onion_message::messenger::BlindedPathType;
18871888
/// #
18881889
/// # fn example<T: AChannelManager>(
18891890
/// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
18901891
/// # max_total_routing_fee_msat: Option<u64>
18911892
/// # ) -> Result<(), Bolt12SemanticError> {
18921893
/// # let channel_manager = channel_manager.get_cm();
18931894
/// let payment_id = PaymentId([42; 32]);
1895+
/// let blinded_path = Some(BlindedPathType::Full);
18941896
/// let refund = channel_manager
18951897
/// .create_refund_builder(
1896-
/// amount_msats, absolute_expiry, payment_id, retry, max_total_routing_fee_msat
1898+
/// amount_msats, absolute_expiry, payment_id, retry, max_total_routing_fee_msat, blinded_path
18971899
/// )?
18981900
/// # ;
18991901
/// # // Needed for compiling for c_bindings
@@ -9119,7 +9121,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
91199121
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
91209122
pub fn create_refund_builder(
91219123
&$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
9122-
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
9124+
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>, blinded_path: Option<BlindedPathType>
91239125
) -> Result<$builder, Bolt12SemanticError> {
91249126
let node_id = $self.get_our_node_id();
91259127
let expanded_key = &$self.inbound_payment_key;
@@ -9128,16 +9130,47 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
91289130

91299131
let nonce = Nonce::from_entropy_source(entropy);
91309132
let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: None };
9131-
let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
9132-
.and_then(|paths| paths.into_iter().next().ok_or(()))
9133-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
91349133

9135-
let builder = RefundBuilder::deriving_signing_pubkey(
9136-
node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
9137-
)?
9134+
let builder = match blinded_path {
9135+
Some(BlindedPathType::Compact) => {
9136+
let path = $self
9137+
.create_compact_blinded_paths(context)
9138+
.and_then(|paths| paths.into_iter().next().ok_or(()))
9139+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9140+
9141+
RefundBuilder::deriving_signing_pubkey(
9142+
node_id, expanded_key, nonce, secp_ctx,
9143+
amount_msats, payment_id,
9144+
)?
9145+
.chain_hash($self.chain_hash)
9146+
.absolute_expiry(absolute_expiry)
9147+
.path(path)
9148+
}
9149+
9150+
Some(BlindedPathType::Full) => {
9151+
let context = MessageContext::Offers(context);
9152+
let path = $self
9153+
.create_blinded_paths(context)
9154+
.and_then(|paths| paths.into_iter().next().ok_or(()))
9155+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9156+
9157+
RefundBuilder::deriving_signing_pubkey(
9158+
node_id, expanded_key, nonce, secp_ctx,
9159+
amount_msats, payment_id,
9160+
)?
9161+
.chain_hash($self.chain_hash)
9162+
.absolute_expiry(absolute_expiry)
9163+
.path(path)
9164+
}
9165+
9166+
None => RefundBuilder::deriving_signing_pubkey(
9167+
node_id, expanded_key, nonce, secp_ctx,
9168+
amount_msats, payment_id,
9169+
)?
91389170
.chain_hash($self.chain_hash)
91399171
.absolute_expiry(absolute_expiry)
9140-
.path(path);
9172+
.absolute_expiry(absolute_expiry),
9173+
};
91419174

91429175
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop($self);
91439176

@@ -9520,25 +9553,7 @@ where
95209553
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
95219554
}
95229555

9523-
/// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
9524-
/// the path's intended lifetime.
9525-
///
9526-
/// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
9527-
/// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
9528-
/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
9529-
fn create_blinded_paths_using_absolute_expiry(
9530-
&self, context: OffersContext, absolute_expiry: Option<Duration>,
9531-
) -> Result<Vec<BlindedMessagePath>, ()> {
9532-
let now = self.duration_since_epoch();
9533-
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
9534-
9535-
if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9536-
self.create_compact_blinded_paths(context)
9537-
} else {
9538-
self.create_blinded_paths(MessageContext::Offers(context))
9539-
}
9540-
}
9541-
9556+
#[cfg(test)]
95429557
pub(super) fn duration_since_epoch(&self) -> Duration {
95439558
#[cfg(not(feature = "std"))]
95449559
let now = Duration::from_secs(

lightning/src/ln/offers_tests.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ fn creates_short_lived_refund() {
461461
let absolute_expiry = bob.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
462462
let payment_id = PaymentId([1; 32]);
463463
let refund = bob.node
464-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
464+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Compact))
465465
.unwrap()
466466
.build().unwrap();
467467
assert_eq!(refund.absolute_expiry(), Some(absolute_expiry));
@@ -490,7 +490,7 @@ fn creates_long_lived_refund() {
490490
+ Duration::from_secs(1);
491491
let payment_id = PaymentId([1; 32]);
492492
let refund = bob.node
493-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
493+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
494494
.unwrap()
495495
.build().unwrap();
496496
assert_eq!(refund.absolute_expiry(), Some(absolute_expiry));
@@ -648,7 +648,7 @@ fn creates_and_pays_for_refund_using_two_hop_blinded_path() {
648648
let absolute_expiry = Duration::from_secs(u64::MAX);
649649
let payment_id = PaymentId([1; 32]);
650650
let refund = david.node
651-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
651+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
652652
.unwrap()
653653
.build().unwrap();
654654
assert_eq!(refund.amount_msats(), 10_000_000);
@@ -776,7 +776,7 @@ fn creates_and_pays_for_refund_using_one_hop_blinded_path() {
776776
let absolute_expiry = Duration::from_secs(u64::MAX);
777777
let payment_id = PaymentId([1; 32]);
778778
let refund = bob.node
779-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
779+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
780780
.unwrap()
781781
.build().unwrap();
782782
assert_eq!(refund.amount_msats(), 10_000_000);
@@ -884,7 +884,7 @@ fn pays_for_refund_without_blinded_paths() {
884884
let absolute_expiry = Duration::from_secs(u64::MAX);
885885
let payment_id = PaymentId([1; 32]);
886886
let refund = bob.node
887-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
887+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
888888
.unwrap()
889889
.clear_paths()
890890
.build().unwrap();
@@ -1039,7 +1039,7 @@ fn send_invoice_for_refund_with_distinct_reply_path() {
10391039
let absolute_expiry = Duration::from_secs(u64::MAX);
10401040
let payment_id = PaymentId([1; 32]);
10411041
let refund = alice.node
1042-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1042+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
10431043
.unwrap()
10441044
.build().unwrap();
10451045
assert_ne!(refund.payer_signing_pubkey(), alice_id);
@@ -1314,7 +1314,7 @@ fn creates_refund_with_blinded_path_using_unannounced_introduction_node() {
13141314
let absolute_expiry = Duration::from_secs(u64::MAX);
13151315
let payment_id = PaymentId([1; 32]);
13161316
let refund = bob.node
1317-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1317+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
13181318
.unwrap()
13191319
.build().unwrap();
13201320
assert_ne!(refund.payer_signing_pubkey(), bob_id);
@@ -1597,7 +1597,7 @@ fn fails_authentication_when_handling_invoice_for_refund() {
15971597
let absolute_expiry = Duration::from_secs(u64::MAX);
15981598
let payment_id = PaymentId([1; 32]);
15991599
let refund = david.node
1600-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1600+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
16011601
.unwrap()
16021602
.build().unwrap();
16031603
assert_ne!(refund.payer_signing_pubkey(), david_id);
@@ -1631,7 +1631,7 @@ fn fails_authentication_when_handling_invoice_for_refund() {
16311631
let invalid_path = refund.paths().first().unwrap().clone();
16321632
let payment_id = PaymentId([2; 32]);
16331633
let refund = david.node
1634-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1634+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
16351635
.unwrap()
16361636
.build().unwrap();
16371637
assert_ne!(refund.payer_signing_pubkey(), david_id);
@@ -1759,7 +1759,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
17591759
let absolute_expiry = david.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY;
17601760
let payment_id = PaymentId([1; 32]);
17611761
match david.node.create_refund_builder(
1762-
10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None
1762+
10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full)
17631763
) {
17641764
Ok(_) => panic!("Expected error"),
17651765
Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths),
@@ -1770,7 +1770,7 @@ fn fails_creating_refund_or_sending_invoice_without_connected_peers() {
17701770
reconnect_nodes(args);
17711771

17721772
let refund = david.node
1773-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1773+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
17741774
.unwrap()
17751775
.build().unwrap();
17761776

@@ -1828,7 +1828,7 @@ fn fails_sending_invoice_with_unsupported_chain_for_refund() {
18281828
let absolute_expiry = Duration::from_secs(u64::MAX);
18291829
let payment_id = PaymentId([1; 32]);
18301830
let refund = bob.node
1831-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
1831+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
18321832
.unwrap()
18331833
.chain(Network::Signet)
18341834
.build().unwrap();
@@ -1926,13 +1926,13 @@ fn fails_creating_refund_with_duplicate_payment_id() {
19261926
let payment_id = PaymentId([1; 32]);
19271927
assert!(
19281928
nodes[0].node.create_refund_builder(
1929-
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None
1929+
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full)
19301930
).is_ok()
19311931
);
19321932
expect_recent_payment!(nodes[0], RecentPaymentDetails::AwaitingInvoice, payment_id);
19331933

19341934
match nodes[0].node.create_refund_builder(
1935-
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None
1935+
10_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full)
19361936
) {
19371937
Ok(_) => panic!("Expected error"),
19381938
Err(e) => assert_eq!(e, Bolt12SemanticError::DuplicatePaymentId),
@@ -2052,7 +2052,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_refund() {
20522052
let absolute_expiry = Duration::from_secs(u64::MAX);
20532053
let payment_id = PaymentId([1; 32]);
20542054
let refund = david.node
2055-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
2055+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
20562056
.unwrap()
20572057
.build().unwrap();
20582058

@@ -2101,7 +2101,7 @@ fn fails_paying_invoice_more_than_once() {
21012101
let absolute_expiry = Duration::from_secs(u64::MAX);
21022102
let payment_id = PaymentId([1; 32]);
21032103
let refund = david.node
2104-
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None)
2104+
.create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None, Some(BlindedPathType::Full))
21052105
.unwrap()
21062106
.build().unwrap();
21072107
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);

0 commit comments

Comments
 (0)