From: Valentine Wallace Date: Fri, 28 Jun 2024 15:40:53 +0000 (-0400) Subject: Support encoding invreqs in outbound onion payloads X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=a80af56af7c33dba0db5136a8c4b77f4db1a2ec1;p=rust-lightning Support encoding invreqs in outbound onion payloads Per BOLTs PR 1149, when paying a static invoice we need to include our original invoice request in the HTLC onion since the recipient wouldn't have received it previously. We use an experimental TLV type for this new onion payload field, since the spec is still not merged in the BOLTs. --- diff --git a/lightning/src/ln/max_payment_path_len_tests.rs b/lightning/src/ln/max_payment_path_len_tests.rs index 8c24ef363..501ddcc57 100644 --- a/lightning/src/ln/max_payment_path_len_tests.rs +++ b/lightning/src/ln/max_payment_path_len_tests.rs @@ -184,6 +184,7 @@ fn one_hop_blinded_path_with_custom_tlv() { encrypted_tlvs: &blinded_path.blinded_hops()[0].encrypted_payload, intro_node_blinding_point: Some(blinded_path.blinding_point()), keysend_preimage: None, + invoice_request: None, custom_tlvs: &Vec::new() }.serialized_length(); let max_custom_tlv_len = 1300 diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 4837a40e1..6f508efa6 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -1747,6 +1747,7 @@ pub struct FinalOnionHopData { mod fuzzy_internal_msgs { use bitcoin::secp256k1::PublicKey; use crate::blinded_path::payment::{BlindedPaymentPath, PaymentConstraints, PaymentContext, PaymentRelay}; + use crate::offers::invoice_request::InvoiceRequest; use crate::types::payment::{PaymentPreimage, PaymentSecret}; use crate::types::features::{BlindedHopFeatures, Bolt12InvoiceFeatures}; use super::{FinalOnionHopData, TrampolineOnionPacket}; @@ -1827,6 +1828,7 @@ mod fuzzy_internal_msgs { intro_node_blinding_point: Option, // Set if the introduction node of the blinded path is the final node keysend_preimage: Option, custom_tlvs: &'a Vec<(u64, Vec)>, + invoice_request: Option<&'a InvoiceRequest>, } } @@ -2760,13 +2762,17 @@ impl<'a> Writeable for OutboundOnionPayload<'a> { }, Self::BlindedReceive { sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, encrypted_tlvs, - intro_node_blinding_point, keysend_preimage, ref custom_tlvs, + intro_node_blinding_point, keysend_preimage, ref invoice_request, ref custom_tlvs, } => { // We need to update [`ln::outbound_payment::RecipientOnionFields::with_custom_tlvs`] // to reject any reserved types in the experimental range if new ones are ever // standardized. + let invoice_request_tlv = invoice_request.map(|invreq| (77_777, invreq.encode())); // TODO: update TLV type once the async payments spec is merged let keysend_tlv = keysend_preimage.map(|preimage| (5482373484, preimage.encode())); - let mut custom_tlvs: Vec<&(u64, Vec)> = custom_tlvs.iter().chain(keysend_tlv.iter()).collect(); + let mut custom_tlvs: Vec<&(u64, Vec)> = custom_tlvs.iter() + .chain(invoice_request_tlv.iter()) + .chain(keysend_tlv.iter()) + .collect(); custom_tlvs.sort_unstable_by_key(|(typ, _)| *typ); _encode_varint_length_prefixed_tlv!(w, { (2, HighZeroBytesDroppedBigSize(*sender_intended_htlc_amt_msat), required), diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 208096c12..68866fc03 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -262,6 +262,7 @@ where encrypted_tlvs: &blinded_hop.encrypted_payload, intro_node_blinding_point: blinding_point.take(), keysend_preimage: *keysend_preimage, + invoice_request: None, custom_tlvs: &recipient_onion.custom_tlvs, }, ); diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index 04736f2a8..01f6c1d09 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -641,6 +641,7 @@ impl RecipientOnionFields { for (typ, _) in custom_tlvs.iter() { if *typ < 1 << 16 { return Err(()); } if *typ == 5482373484 { return Err(()); } // keysend + if *typ == 77_777 { return Err(()); } // invoice requests for async payments match prev_type { Some(prev) if prev >= *typ => return Err(()), _ => {},