Skip to content

Commit f109e16

Browse files
committed
f - test case for paying fresh invoice first and other comments
1 parent c80638f commit f109e16

File tree

5 files changed

+108
-24
lines changed

5 files changed

+108
-24
lines changed

lightning/src/events/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,12 +1655,10 @@ pub enum Event {
16551655
/// The invoice that should be persisted and later provided to payers when handling a future
16561656
/// [`Event::StaticInvoiceRequested`].
16571657
invoice: StaticInvoice,
1658-
/// The path to where invoice requests will be forwarded. As a static invoice
1659-
/// server, if we receive an invoice request on behalf of an async recipient, a static
1660-
/// invoice will be provided to the payer. However, we'll also forward the invoice
1661-
/// request to this path to the async recipient in case it is online so that the
1662-
/// recipient can provide a new invoice. This path should be persisted and later
1663-
/// provided to [`ChannelManager::send_response_static_invoice_request`].
1658+
/// The path to where invoice requests will be forwarded. If we receive an invoice
1659+
/// request, we'll forward it to the async recipient over this path in case the
1660+
/// recipient is online to provide a new invoice. This path should be persisted and
1661+
/// later provided to [`ChannelManager::send_response_static_invoice_request`].
16641662
///
16651663
/// [`ChannelManager::send_response_static_invoice_request`]: crate::ln::channelmanager::ChannelManager::send_response_static_invoice_request
16661664
invoice_request_path: BlindedMessagePath,
@@ -1718,8 +1716,9 @@ pub enum Event {
17181716
///
17191717
/// [`ChannelManager::send_response_static_invoice_request`]: crate::ln::channelmanager::ChannelManager::send_response_static_invoice_request
17201718
reply_path: Responder,
1721-
/// The invoice request that will be forwarded to the async recipient to give it a
1722-
/// chance to provide an invoice in case it is online. It should be provided to [`ChannelManager::send_response_static_invoice_request`].
1719+
/// The invoice request that will be forwarded to the async recipient to give the
1720+
/// recipient a chance to provide an invoice in case it is online. It should be
1721+
/// provided to [`ChannelManager::send_response_static_invoice_request`].
17231722
///
17241723
/// [`ChannelManager::send_response_static_invoice_request`]: crate::ln::channelmanager::ChannelManager::send_response_static_invoice_request
17251724
invoice_request: InvoiceRequest,

lightning/src/ln/async_payments_tests.rs

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ fn ignore_duplicate_invoice() {
742742
static_invoice.clone(),
743743
reply_path,
744744
invoice_request,
745-
invoice_flow_res.invoice_request_path,
745+
invoice_flow_res.invoice_request_path.clone(),
746746
)
747747
.unwrap();
748748

@@ -751,17 +751,15 @@ fn ignore_duplicate_invoice() {
751751
// payer.
752752
let invreq_om =
753753
always_online_node.onion_messenger.next_onion_message_for_peer(async_recipient_id).unwrap();
754-
755754
let peeled_msg = async_recipient.onion_messenger.peel_onion_message(&invreq_om).unwrap();
756755
assert!(matches!(peeled_msg, PeeledOnion::Offers(OffersMessage::InvoiceRequest(_), _, _)));
757756

758757
let static_invoice_om =
759758
always_online_node.onion_messenger.next_onion_message_for_peer(sender_node_id).unwrap();
760-
761759
let peeled_msg = sender.onion_messenger.peel_onion_message(&static_invoice_om).unwrap();
762760
assert!(matches!(peeled_msg, PeeledOnion::Offers(OffersMessage::StaticInvoice(_), _, _)));
763761

764-
// Handling the `invoice_request` from the async recipient we should get back a invoice.
762+
// Handling the `invoice_request` from the async recipient we should get back an invoice.
765763
async_recipient.onion_messenger.handle_onion_message(always_online_node_id, &invreq_om);
766764
let invoice_om =
767765
async_recipient.onion_messenger.next_onion_message_for_peer(sender_node_id).unwrap();
@@ -782,7 +780,6 @@ fn ignore_duplicate_invoice() {
782780

783781
let release_held_htlc_om =
784782
async_recipient.onion_messenger.next_onion_message_for_peer(sender_node_id).unwrap();
785-
786783
sender.onion_messenger.handle_onion_message(async_recipient_id, &release_held_htlc_om);
787784

788785
let mut events = sender.node.get_and_clear_pending_msg_events();
@@ -797,7 +794,7 @@ fn ignore_duplicate_invoice() {
797794
let keysend_preimage = extract_payment_preimage(&claimable_ev);
798795
let (res, _) =
799796
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
800-
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));
797+
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice.clone())));
801798

802799
// After paying the static invoice, check that regular invoice received from async recipient is ignored.
803800
match sender.onion_messenger.peel_onion_message(&invoice_om) {
@@ -809,6 +806,90 @@ fn ignore_duplicate_invoice() {
809806
},
810807
_ => panic!(),
811808
}
809+
810+
// Now handle case where the sender pays regular invoice and ignores static invoice.
811+
let payment_id = PaymentId([2; 32]);
812+
sender
813+
.node
814+
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), params)
815+
.unwrap();
816+
817+
let invreq_om =
818+
sender.onion_messenger.next_onion_message_for_peer(always_online_node_id).unwrap();
819+
always_online_node.onion_messenger.handle_onion_message(sender_node_id, &invreq_om);
820+
821+
let mut events = always_online_node.node.get_and_clear_pending_events();
822+
assert_eq!(events.len(), 1);
823+
let (reply_path, invoice_request) = match events.pop().unwrap() {
824+
Event::StaticInvoiceRequested {
825+
recipient_id: ev_id,
826+
invoice_slot: _,
827+
reply_path,
828+
invoice_request,
829+
} => {
830+
assert_eq!(recipient_id, ev_id);
831+
(reply_path, invoice_request)
832+
},
833+
_ => panic!(),
834+
};
835+
836+
always_online_node
837+
.node
838+
.send_response_static_invoice_request(
839+
static_invoice.clone(),
840+
reply_path,
841+
invoice_request,
842+
invoice_flow_res.invoice_request_path,
843+
)
844+
.unwrap();
845+
846+
let invreq_om =
847+
always_online_node.onion_messenger.next_onion_message_for_peer(async_recipient_id).unwrap();
848+
let peeled_msg = async_recipient.onion_messenger.peel_onion_message(&invreq_om).unwrap();
849+
assert!(matches!(peeled_msg, PeeledOnion::Offers(OffersMessage::InvoiceRequest(_), _, _)));
850+
851+
let static_invoice_om =
852+
always_online_node.onion_messenger.next_onion_message_for_peer(sender_node_id).unwrap();
853+
let peeled_msg = sender.onion_messenger.peel_onion_message(&static_invoice_om).unwrap();
854+
assert!(matches!(peeled_msg, PeeledOnion::Offers(OffersMessage::StaticInvoice(_), _, _)));
855+
856+
async_recipient.onion_messenger.handle_onion_message(always_online_node_id, &invreq_om);
857+
let invoice_om =
858+
async_recipient.onion_messenger.next_onion_message_for_peer(sender_node_id).unwrap();
859+
860+
let (invoice, context) = match sender.onion_messenger.peel_onion_message(&invoice_om) {
861+
Ok(PeeledOnion::Offers(OffersMessage::Invoice(invoice), context, _)) => (invoice, context),
862+
_ => panic!(),
863+
};
864+
865+
assert!(matches!(
866+
sender.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()),
867+
Ok(())
868+
));
869+
870+
let mut events = sender.node.get_and_clear_pending_msg_events();
871+
assert_eq!(events.len(), 1);
872+
let ev = remove_first_msg_event_to_node(&always_online_node_id, &mut events);
873+
let payment_hash = extract_payment_hash(&ev);
874+
check_added_monitors!(sender, 1);
875+
876+
let args = PassAlongPathArgs::new(sender, route[0], amt_msat, payment_hash, ev)
877+
.without_clearing_recipient_events();
878+
do_pass_along_path(args);
879+
880+
let payment_preimage = match get_event!(async_recipient, Event::PaymentClaimable) {
881+
Event::PaymentClaimable { purpose, .. } => purpose.preimage().unwrap(),
882+
_ => panic!("No Event::PaymentClaimable"),
883+
};
884+
885+
// After paying invoice, check that static invoice is ignored.
886+
let res = claim_payment(sender, route[0], payment_preimage);
887+
assert_eq!(res, Some(PaidBolt12Invoice::Bolt12Invoice(invoice)));
888+
889+
sender.onion_messenger.handle_onion_message(always_online_node_id, &static_invoice_om);
890+
let async_pmts_msgs = AsyncPaymentsMessageHandler::release_pending_messages(sender.node);
891+
assert!(async_pmts_msgs.is_empty());
892+
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
812893
}
813894

814895
#[test]

lightning/src/ln/channelmanager.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5292,9 +5292,10 @@ where
52925292
self.flow.static_invoice_persisted(invoice_persisted_path);
52935293
}
52945294

5295-
/// When handling an [`Event::StaticInvoiceRequested`], this should be called to forward the
5296-
/// [`InvoiceRequest`] over the `invoice_request_path` to the async recipient if it is online
5297-
/// and it will forward the [`StaticInvoice`] to the responder.
5295+
/// Forwards a [`StaticInvoice`] to a payer in response to an
5296+
/// [`Event::StaticInvoiceRequested`]. Also forwards the payer's [`InvoiceRequest`] to the
5297+
/// async recipient, in case the recipient is online to provide the payer with a fresh
5298+
/// [`Bolt12Invoice`].
52985299
pub fn send_response_static_invoice_request(
52995300
&self, invoice: StaticInvoice, responder: Responder, invoice_request: InvoiceRequest,
53005301
invoice_request_path: BlindedMessagePath,

lightning/src/offers/flow.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ pub enum InvreqResponseInstructions {
396396
SendInvoice(VerifiedInvoiceRequest),
397397
/// We are a static invoice server and should respond to this invoice request by retrieving the
398398
/// [`StaticInvoice`] corresponding to the `recipient_id` and `invoice_slot` and calling
399-
/// `OffersMessageFlow::enqueue_static_invoice`.
399+
/// [`OffersMessageFlow::enqueue_static_invoice`].
400400
///
401401
/// [`StaticInvoice`]: crate::offers::static_invoice::StaticInvoice
402402
SendStaticInvoice {
@@ -406,8 +406,9 @@ pub enum InvreqResponseInstructions {
406406
recipient_id: Vec<u8>,
407407
/// The slot number for the specific invoice being requested by the payer.
408408
invoice_slot: u16,
409-
/// The invoice request that should be forwarded to the async recipient in case it is
410-
/// online to respond.
409+
/// The invoice request that should be forwarded to the async recipient in case the
410+
/// recipient is online to respond. Should be forwarded by calling
411+
/// [`OffersMessageFlow::enqueue_invoice_request_to_forward`].
411412
invoice_request: InvoiceRequest,
412413
},
413414
}
@@ -1123,9 +1124,9 @@ where
11231124

11241125
/// Forwards an [`InvoiceRequest`] to the specified [`BlindedMessagePath`]. If we receive an
11251126
/// invoice request as a static invoice server on behalf of an often-offline recipient this
1126-
/// can be used to forward the request to the recipient to give it a chance to provide an
1127-
/// invoice if it is online. The reply_path [`Responder`] provided is the path to the sender
1128-
/// where the recipient can send the invoice.
1127+
/// can be used to forward the request to give the recipient a chance to provide an
1128+
/// invoice if the recipient is online. The reply_path [`Responder`] provided is the path to
1129+
/// the sender where the recipient can send the invoice.
11291130
///
11301131
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
11311132
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath

lightning/src/offers/invoice_request.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,15 +581,17 @@ impl AsRef<TaggedHash> for UnsignedInvoiceRequest {
581581
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
582582
/// [`Offer`]: crate::offers::offer::Offer
583583
#[derive(Clone, Debug)]
584+
#[cfg_attr(test, derive(PartialEq))]
584585
pub struct InvoiceRequest {
585586
pub(super) bytes: Vec<u8>,
586587
pub(super) contents: InvoiceRequestContents,
587588
signature: Signature,
588589
}
589590

591+
#[cfg(not(test))]
590592
impl PartialEq for InvoiceRequest {
591593
fn eq(&self, other: &Self) -> bool {
592-
self.bytes.eq(&other.bytes)
594+
self.bytes.eq(&other.bytes) && self.signature.eq(&other.signature)
593595
}
594596
}
595597

0 commit comments

Comments
 (0)