Skip to content

Commit 9cdbb44

Browse files
add the bolt12 invoice to the PaymentSend event
To enable proof of payment, we need to share the bolt12 invoice with the library user. This is already possible if we `manually_handle_bolt12_invoices`, but this approach requires a significant amount of work from the user. This commit adds the bolt12 invoice to the PaymentSend event when the payment is completed. This allows the user to always have the option to perform proof of payment. Link: lightningdevkit#3344 Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent 4d83694 commit 9cdbb44

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

lightning/src/events/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,8 @@ pub enum Event {
939939
///
940940
/// [`Route::get_total_fees`]: crate::routing::router::Route::get_total_fees
941941
fee_paid_msat: Option<u64>,
942+
/// The bolt12 invoice that was paid. `None` if the payment was a non-bolt12 payment.
943+
bolt12_invoice: Option<Bolt12Invoice>,
942944
},
943945
/// Indicates an outbound payment failed. Individual [`Event::PaymentPathFailed`] events
944946
/// provide failure information for each path attempt in the payment, including retries.
@@ -1190,12 +1192,12 @@ pub enum Event {
11901192
/// events generated or serialized by versions prior to 0.0.122.
11911193
next_user_channel_id: Option<u128>,
11921194
/// The node id of the previous node.
1193-
///
1195+
///
11941196
/// This is only `None` for HTLCs received prior to 0.1 or for events serialized by
11951197
/// versions prior to 0.1
11961198
prev_node_id: Option<PublicKey>,
11971199
/// The node id of the next node.
1198-
///
1200+
///
11991201
/// This is only `None` for HTLCs received prior to 0.1 or for events serialized by
12001202
/// versions prior to 0.1
12011203
next_node_id: Option<PublicKey>,
@@ -1546,13 +1548,14 @@ impl Writeable for Event {
15461548
(13, payment_id, option),
15471549
});
15481550
},
1549-
&Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
1551+
&Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat, ref bolt12_invoice } => {
15501552
2u8.write(writer)?;
15511553
write_tlv_fields!(writer, {
15521554
(0, payment_preimage, required),
15531555
(1, payment_hash, required),
15541556
(3, payment_id, option),
15551557
(5, fee_paid_msat, option),
1558+
(7, bolt12_invoice, option),
15561559
});
15571560
},
15581561
&Event::PaymentPathFailed {
@@ -1886,11 +1889,13 @@ impl MaybeReadable for Event {
18861889
let mut payment_hash = None;
18871890
let mut payment_id = None;
18881891
let mut fee_paid_msat = None;
1892+
let mut bolt12_invoice = None;
18891893
read_tlv_fields!(reader, {
18901894
(0, payment_preimage, required),
18911895
(1, payment_hash, option),
18921896
(3, payment_id, option),
18931897
(5, fee_paid_msat, option),
1898+
(7, bolt12_invoice, option),
18941899
});
18951900
if payment_hash.is_none() {
18961901
payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()));
@@ -1900,6 +1905,7 @@ impl MaybeReadable for Event {
19001905
payment_preimage,
19011906
payment_hash: payment_hash.unwrap(),
19021907
fee_paid_msat,
1908+
bolt12_invoice,
19031909
}))
19041910
};
19051911
f()

lightning/src/ln/functional_test_utils.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use crate::util::test_channel_signer::SignerOp;
3737
use crate::util::test_utils;
3838
use crate::util::test_utils::{TestChainMonitor, TestScorer, TestKeysInterface};
3939
use crate::util::ser::{ReadableArgs, Writeable};
40+
use crate::offers::invoice::Bolt12Invoice;
4041

4142
use bitcoin::WPubkeyHash;
4243
use bitcoin::amount::Amount;
@@ -3093,10 +3094,11 @@ pub fn claim_payment_along_route(args: ClaimAlongRouteArgs) {
30933094
}
30943095
}
30953096

3096-
pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) {
3097+
pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) -> Option<Bolt12Invoice> {
30973098
claim_payment_along_route(
30983099
ClaimAlongRouteArgs::new(origin_node, &[expected_route], our_payment_preimage)
30993100
);
3101+
None
31003102
}
31013103

31023104
pub const TEST_FINAL_CLTV: u32 = 70;

lightning/src/ln/offers_tests.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ fn route_bolt12_payment<'a, 'b, 'c>(
168168
}
169169

170170
fn claim_bolt12_payment<'a, 'b, 'c>(
171-
node: &Node<'a, 'b, 'c>, path: &[&Node<'a, 'b, 'c>], expected_payment_context: PaymentContext
171+
node: &Node<'a, 'b, 'c>, path: &[&Node<'a, 'b, 'c>], expected_payment_context: PaymentContext, invoice: &Bolt12Invoice
172172
) {
173173
let recipient = &path[path.len() - 1];
174174
let payment_purpose = match get_event!(recipient, Event::PaymentClaimable) {
@@ -188,7 +188,10 @@ fn claim_bolt12_payment<'a, 'b, 'c>(
188188
},
189189
_ => panic!("Unexpected payment purpose: {:?}", payment_purpose),
190190
}
191-
claim_payment(node, path, payment_preimage);
191+
let Some(inv) = claim_payment(node, path, payment_preimage) else {
192+
return;
193+
};
194+
assert_eq!(inv, invoice.to_owned());
192195
}
193196

194197
fn extract_offer_nonce<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage) -> Nonce {
@@ -597,7 +600,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() {
597600
route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
598601
expect_recent_payment!(david, RecentPaymentDetails::Pending, payment_id);
599602

600-
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context);
603+
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context, &invoice);
601604
expect_recent_payment!(david, RecentPaymentDetails::Fulfilled, payment_id);
602605
}
603606

@@ -680,7 +683,7 @@ fn creates_and_pays_for_refund_using_two_hop_blinded_path() {
680683
route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
681684
expect_recent_payment!(david, RecentPaymentDetails::Pending, payment_id);
682685

683-
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context);
686+
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context, &invoice);
684687
expect_recent_payment!(david, RecentPaymentDetails::Fulfilled, payment_id);
685688
}
686689

@@ -747,7 +750,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() {
747750
route_bolt12_payment(bob, &[alice], &invoice);
748751
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
749752

750-
claim_bolt12_payment(bob, &[alice], payment_context);
753+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
751754
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
752755
}
753756

@@ -803,7 +806,7 @@ fn creates_and_pays_for_refund_using_one_hop_blinded_path() {
803806
route_bolt12_payment(bob, &[alice], &invoice);
804807
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
805808

806-
claim_bolt12_payment(bob, &[alice], payment_context);
809+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
807810
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
808811
}
809812

@@ -857,7 +860,7 @@ fn pays_for_offer_without_blinded_paths() {
857860
route_bolt12_payment(bob, &[alice], &invoice);
858861
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
859862

860-
claim_bolt12_payment(bob, &[alice], payment_context);
863+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
861864
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
862865
}
863866

@@ -900,7 +903,7 @@ fn pays_for_refund_without_blinded_paths() {
900903
route_bolt12_payment(bob, &[alice], &invoice);
901904
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
902905

903-
claim_bolt12_payment(bob, &[alice], payment_context);
906+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
904907
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
905908
}
906909

@@ -1138,7 +1141,7 @@ fn creates_and_pays_for_offer_with_retry() {
11381141
}
11391142
route_bolt12_payment(bob, &[alice], &invoice);
11401143
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
1141-
claim_bolt12_payment(bob, &[alice], payment_context);
1144+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
11421145
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
11431146
}
11441147

@@ -1209,7 +1212,7 @@ fn pays_bolt12_invoice_asynchronously() {
12091212
route_bolt12_payment(bob, &[alice], &invoice);
12101213
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
12111214

1212-
claim_bolt12_payment(bob, &[alice], payment_context);
1215+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
12131216
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
12141217

12151218
assert_eq!(
@@ -1289,7 +1292,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
12891292
route_bolt12_payment(bob, &[alice], &invoice);
12901293
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
12911294

1292-
claim_bolt12_payment(bob, &[alice], payment_context);
1295+
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
12931296
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
12941297
}
12951298

@@ -2145,7 +2148,7 @@ fn fails_paying_invoice_more_than_once() {
21452148
assert!(david.node.get_and_clear_pending_msg_events().is_empty());
21462149

21472150
// Complete paying the first invoice
2148-
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context);
2151+
claim_bolt12_payment(david, &[charlie, bob, alice], payment_context, &invoice1);
21492152
expect_recent_payment!(david, RecentPaymentDetails::Fulfilled, payment_id);
21502153
}
21512154

@@ -2405,4 +2408,3 @@ fn no_double_pay_with_stale_channelmanager() {
24052408
// generated in response to the duplicate invoice.
24062409
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
24072410
}
2408-

lightning/src/ln/outbound_payment.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,7 @@ impl OutboundPayments {
19471947
payment_preimage,
19481948
payment_hash,
19491949
fee_paid_msat,
1950+
bolt12_invoice: payment.get().bolt12_invoice().cloned(),
19501951
}, Some(ev_completion_action.clone())));
19511952
payment.get_mut().mark_fulfilled();
19521953
}

0 commit comments

Comments
 (0)