From 8d8416b956f97c097bc6ca831001f277b952bae7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 30 Sep 2024 18:18:38 +0000 Subject: [PATCH] Store the source `HumanReadableName` in `InvoiceRequestFields` When we receive a payment to an offer we issued resolved with a human readable name, it may have been resolved using a wildcard DNS entry which we want to map to a specific recipient account locally. To do this, we need the human readable name from the `InvoiceRequest` in the `PaymentClaim{able,ed}`, which we pipe through here using `InvoiceRequestFields`. --- fuzz/src/invoice_request_deser.rs | 1 + lightning/src/events/mod.rs | 4 ++++ lightning/src/ln/offers_tests.rs | 6 ++++++ lightning/src/offers/invoice_request.rs | 8 ++++++++ 4 files changed, 19 insertions(+) diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs index aa3c006ab..d5a43ae46 100644 --- a/fuzz/src/invoice_request_deser.rs +++ b/fuzz/src/invoice_request_deser.rs @@ -89,6 +89,7 @@ fn build_response( payer_note_truncated: invoice_request .payer_note() .map(|s| UntrustedString(s.to_string())), + human_readable_name: None, }, }); let payee_tlvs = ReceiveTlvs { diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index 3538aa367..033086981 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -125,6 +125,10 @@ pub enum PaymentPurpose { /// The context of the payment such as information about the corresponding [`Offer`] and /// [`InvoiceRequest`]. /// + /// This includes the Human Readable Name which the sender indicated they were paying to, + /// for possible recipient disambiguation if you're using a single wildcard DNS entry to + /// resolve to many recipients. + /// /// [`Offer`]: crate::offers::offer::Offer /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest payment_context: Bolt12OfferContext, diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index b667ce2c0..a7eeebf98 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -564,6 +564,7 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); assert_eq!(invoice_request.amount_msats(), None); @@ -724,6 +725,7 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); assert_eq!(invoice_request.amount_msats(), None); @@ -844,6 +846,7 @@ fn pays_for_offer_without_blinded_paths() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); @@ -1111,6 +1114,7 @@ fn creates_and_pays_for_offer_with_retry() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); assert_eq!(invoice_request.amount_msats(), None); @@ -1175,6 +1179,7 @@ fn pays_bolt12_invoice_asynchronously() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); @@ -1264,6 +1269,7 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() { payer_signing_pubkey: invoice_request.payer_signing_pubkey(), quantity: None, payer_note_truncated: None, + human_readable_name: None, }, }); assert_ne!(invoice_request.payer_signing_pubkey(), bob_id); diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index c269eb01b..f7f1c2287 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -1030,6 +1030,7 @@ impl VerifiedInvoiceRequest { quantity: *quantity, payer_note_truncated: payer_note.clone() .map(|mut s| { s.truncate(PAYER_NOTE_LIMIT); UntrustedString(s) }), + human_readable_name: self.offer_from_hrn().clone(), } } } @@ -1350,6 +1351,9 @@ pub struct InvoiceRequestFields { /// A payer-provided note which will be seen by the recipient and reflected back in the invoice /// response. Truncated to [`PAYER_NOTE_LIMIT`] characters. pub payer_note_truncated: Option, + + /// The Human Readable Name which the sender indicated they were paying to. + pub human_readable_name: Option, } /// The maximum number of characters included in [`InvoiceRequestFields::payer_note_truncated`]. @@ -1359,6 +1363,7 @@ impl Writeable for InvoiceRequestFields { fn write(&self, writer: &mut W) -> Result<(), io::Error> { write_tlv_fields!(writer, { (0, self.payer_signing_pubkey, required), + (1, self.human_readable_name, option), (2, self.quantity.map(|v| HighZeroBytesDroppedBigSize(v)), option), (4, self.payer_note_truncated.as_ref().map(|s| WithoutLength(&s.0)), option), }); @@ -1370,6 +1375,7 @@ impl Readable for InvoiceRequestFields { fn read(reader: &mut R) -> Result { _init_and_read_len_prefixed_tlv_fields!(reader, { (0, payer_signing_pubkey, required), + (1, human_readable_name, option), (2, quantity, (option, encoding: (u64, HighZeroBytesDroppedBigSize))), (4, payer_note_truncated, (option, encoding: (String, WithoutLength))), }); @@ -1378,6 +1384,7 @@ impl Readable for InvoiceRequestFields { payer_signing_pubkey: payer_signing_pubkey.0.unwrap(), quantity, payer_note_truncated: payer_note_truncated.map(|s| UntrustedString(s)), + human_readable_name, }) } } @@ -2733,6 +2740,7 @@ mod tests { payer_signing_pubkey: payer_pubkey(), quantity: Some(1), payer_note_truncated: Some(UntrustedString("0".repeat(PAYER_NOTE_LIMIT))), + human_readable_name: None, } ); -- 2.39.5