Skip to content

Commit 6c67e3e

Browse files
committed
Functional tests for offers without blinded paths
1 parent 1059ac3 commit 6c67e3e

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

lightning/src/ln/offers_tests.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,88 @@ fn creates_and_pays_for_refund_using_one_hop_blinded_path() {
213213
claim_bolt12_payment(bob, &[alice]);
214214
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
215215
}
216+
217+
/// Checks that an invoice for an offer without any blinded paths can be requested. Note that while
218+
/// the requested is sent directly using the node's pubkey, the response and the payment still use
219+
/// blinded paths as required by the spec.
220+
#[test]
221+
fn pays_for_offer_without_blinded_paths() {
222+
let chanmon_cfgs = create_chanmon_cfgs(2);
223+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
224+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
225+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
226+
227+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
228+
229+
let alice = &nodes[0];
230+
let alice_id = alice.node.get_our_node_id();
231+
let bob = &nodes[1];
232+
let bob_id = bob.node.get_our_node_id();
233+
234+
let offer = alice.node
235+
.create_offer_builder("coffee".to_string()).unwrap()
236+
.clear_paths()
237+
.amount_msats(10_000_000)
238+
.build().unwrap();
239+
assert_eq!(offer.signing_pubkey(), alice_id);
240+
assert!(offer.paths().is_empty());
241+
242+
let payment_id = PaymentId([1; 32]);
243+
bob.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None).unwrap();
244+
expect_recent_payment!(bob, RecentPaymentDetails::AwaitingInvoice, payment_id);
245+
246+
let onion_message = bob.onion_messenger.next_onion_message_for_peer(alice_id).unwrap();
247+
alice.onion_messenger.handle_onion_message(&bob_id, &onion_message);
248+
249+
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
250+
bob.onion_messenger.handle_onion_message(&alice_id, &onion_message);
251+
252+
let invoice = extract_invoice(bob, &onion_message);
253+
route_bolt12_payment(bob, &[alice], &invoice);
254+
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
255+
256+
claim_bolt12_payment(bob, &[alice]);
257+
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
258+
}
259+
260+
/// Checks that a refund without any blinded paths can be paid. Note that while the invoice is sent
261+
/// directly using the node's pubkey, the payment still use blinded paths as required by the spec.
262+
#[test]
263+
fn pays_for_refund_without_blinded_paths() {
264+
let chanmon_cfgs = create_chanmon_cfgs(2);
265+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
266+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
267+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
268+
269+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000);
270+
271+
let alice = &nodes[0];
272+
let alice_id = alice.node.get_our_node_id();
273+
let bob = &nodes[1];
274+
let bob_id = bob.node.get_our_node_id();
275+
276+
let absolute_expiry = Duration::from_secs(u64::MAX);
277+
let payment_id = PaymentId([1; 32]);
278+
let refund = bob.node
279+
.create_refund_builder(
280+
"refund".to_string(), 10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None
281+
)
282+
.unwrap()
283+
.clear_paths()
284+
.build().unwrap();
285+
assert_eq!(refund.payer_id(), bob_id);
286+
assert!(refund.paths().is_empty());
287+
expect_recent_payment!(bob, RecentPaymentDetails::AwaitingInvoice, payment_id);
288+
289+
alice.node.request_refund_payment(&refund).unwrap();
290+
291+
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
292+
bob.onion_messenger.handle_onion_message(&alice_id, &onion_message);
293+
294+
let invoice = extract_invoice(bob, &onion_message);
295+
route_bolt12_payment(bob, &[alice], &invoice);
296+
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
297+
298+
claim_bolt12_payment(bob, &[alice]);
299+
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
300+
}

lightning/src/offers/offer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,11 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> {
339339
self
340340
}
341341

342+
pub(crate) fn clear_paths(mut self) -> Self {
343+
self.offer.paths = None;
344+
self
345+
}
346+
342347
pub(super) fn build_unchecked(self) -> Offer {
343348
self.build_without_checks()
344349
}

lightning/src/offers/refund.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
297297

298298
#[cfg(test)]
299299
impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
300+
pub(crate) fn clear_paths(mut self) -> Self {
301+
self.refund.paths = None;
302+
self
303+
}
304+
300305
fn features_unchecked(mut self, features: InvoiceRequestFeatures) -> Self {
301306
self.refund.features = features;
302307
self

0 commit comments

Comments
 (0)