From 48d9245f199e58449bb4f7d0eeb314fa5aca104e Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 26 Mar 2024 18:48:39 -0500 Subject: [PATCH] Include Offer context in blinded payment paths When constructing blinded payment paths for a Bolt12Invoice response, include the OfferId so that the eventual payment can be correlated with the Offer. --- lightning/src/blinded_path/payment.rs | 22 ++++++++++++++++++++++ lightning/src/ln/channelmanager.rs | 16 +++++++++++----- lightning/src/offers/offer.rs | 2 +- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lightning/src/blinded_path/payment.rs b/lightning/src/blinded_path/payment.rs index 39f7c7f1..99979ecf 100644 --- a/lightning/src/blinded_path/payment.rs +++ b/lightning/src/blinded_path/payment.rs @@ -12,6 +12,7 @@ use crate::ln::channelmanager::CounterpartyForwardingInfo; use crate::ln::features::BlindedHopFeatures; use crate::ln::msgs::DecodeError; use crate::offers::invoice::BlindedPayInfo; +use crate::offers::offer::OfferId; use crate::util::ser::{HighZeroBytesDroppedBigSize, Readable, Writeable, Writer}; #[allow(unused_imports)] @@ -108,12 +109,28 @@ pub struct PaymentConstraints { pub enum PaymentContext { /// The payment context was unknown. Unknown(UnknownPaymentContext), + + /// The payment was made for an invoice requested from a BOLT 12 [`Offer`]. + /// + /// [`Offer`]: crate::offers::offer::Offer + Bolt12Offer(Bolt12OfferContext), } /// An unknown payment context. #[derive(Clone, Debug, Eq, PartialEq)] pub struct UnknownPaymentContext(()); +/// The context of a payment made for an invoice requested from a BOLT 12 [`Offer`]. +/// +/// [`Offer`]: crate::offers::offer::Offer +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Bolt12OfferContext { + /// The identifier of the [`Offer`]. + /// + /// [`Offer`]: crate::offers::offer::Offer + pub offer_id: OfferId, +} + impl PaymentContext { pub(crate) fn unknown() -> Self { PaymentContext::Unknown(UnknownPaymentContext(())) @@ -340,6 +357,7 @@ impl Readable for PaymentConstraints { impl_writeable_tlv_based_enum!(PaymentContext, ; (0, Unknown), + (1, Bolt12Offer), ); impl Writeable for UnknownPaymentContext { @@ -354,6 +372,10 @@ impl Readable for UnknownPaymentContext { } } +impl_writeable_tlv_based!(Bolt12OfferContext, { + (0, offer_id, required), +}); + #[cfg(test)] mod tests { use bitcoin::secp256k1::PublicKey; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index ef10717a..5487ae8a 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -32,7 +32,7 @@ use bitcoin::secp256k1::Secp256k1; use bitcoin::{secp256k1, Sequence}; use crate::blinded_path::{BlindedPath, NodeIdLookUp}; -use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs}; +use crate::blinded_path::payment::{Bolt12OfferContext, PaymentConstraints, PaymentContext, ReceiveTlvs}; use crate::chain; use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock}; use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator}; @@ -8826,7 +8826,10 @@ where match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) { Ok((payment_hash, payment_secret)) => { - let payment_paths = self.create_blinded_payment_paths(amount_msats, payment_secret) + let payment_context = PaymentContext::unknown(); + let payment_paths = self.create_blinded_payment_paths( + amount_msats, payment_secret, payment_context + ) .map_err(|_| Bolt12SemanticError::MissingPaths)?; #[cfg(feature = "std")] @@ -8992,7 +8995,7 @@ where /// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to /// [`Router::create_blinded_payment_paths`]. fn create_blinded_payment_paths( - &self, amount_msats: u64, payment_secret: PaymentSecret + &self, amount_msats: u64, payment_secret: PaymentSecret, payment_context: PaymentContext ) -> Result, ()> { let secp_ctx = &self.secp_ctx; @@ -9006,7 +9009,7 @@ where max_cltv_expiry, htlc_minimum_msat: 1, }, - payment_context: PaymentContext::unknown(), + payment_context, }; self.router.create_blinded_payment_paths( payee_node_id, first_hops, payee_tlvs, amount_msats, secp_ctx @@ -10360,8 +10363,11 @@ where }, }; + let payment_context = PaymentContext::Bolt12Offer(Bolt12OfferContext { + offer_id: invoice_request.offer_id, + }); let payment_paths = match self.create_blinded_payment_paths( - amount_msats, payment_secret + amount_msats, payment_secret, payment_context ) { Ok(payment_paths) => payment_paths, Err(()) => { diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 324e3ea4..3dedc6cd 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -115,7 +115,7 @@ use std::time::SystemTime; pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Offer ~~~~~~"; /// An identifier for an [`Offer`] built using [`DerivedMetadata`]. -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OfferId(pub [u8; 32]); impl OfferId { -- 2.30.2