From e1e79031bef6ab2d3be4347677a1cccc81c55fef Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 7 Apr 2023 20:48:01 +0000 Subject: [PATCH] Expose the `RecipientOnionFields` in `Event::PaymentClaimable` This finally completes the piping of the `payment_metadata` from from the BOLT11 invoice on the sending side all the way through the onion sending + receiving ends to the user on the receive events. --- lightning/src/events/mod.rs | 16 ++++++++++++++-- lightning/src/ln/channelmanager.rs | 2 ++ lightning/src/ln/functional_test_utils.rs | 11 ++++++++--- lightning/src/ln/outbound_payment.rs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index b482996b9..18d292917 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -21,7 +21,7 @@ pub mod bump_transaction; pub use bump_transaction::BumpTransactionEvent; use crate::chain::keysinterface::SpendableOutputDescriptor; -use crate::ln::channelmanager::{InterceptId, PaymentId}; +use crate::ln::channelmanager::{InterceptId, PaymentId, RecipientOnionFields}; use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs; @@ -342,6 +342,11 @@ pub enum Event { /// The hash for which the preimage should be handed to the ChannelManager. Note that LDK will /// not stop you from registering duplicate payment hashes for inbound payments. payment_hash: PaymentHash, + /// The fields in the onion which were received with each HTLC. Only fields which were + /// identical in each HTLC involved in the payment will be included here. + /// + /// Payments received on LDK versions prior to 0.0.115 will have this field unset. + onion_fields: Option, /// The value, in thousandths of a satoshi, that this payment is for. amount_msat: u64, /// Information for claiming this received payment, based on whether the purpose of the @@ -780,7 +785,10 @@ impl Writeable for Event { // We never write out FundingGenerationReady events as, upon disconnection, peers // drop any channels which have not yet exchanged funding_signed. }, - &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id, ref claim_deadline } => { + &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, + ref receiver_node_id, ref via_channel_id, ref via_user_channel_id, + ref claim_deadline, ref onion_fields + } => { 1u8.write(writer)?; let mut payment_secret = None; let payment_preimage; @@ -803,6 +811,7 @@ impl Writeable for Event { (6, 0u64, required), // user_payment_id required for compatibility with 0.0.103 and earlier (7, claim_deadline, option), (8, payment_preimage, option), + (9, onion_fields, option), }); }, &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { @@ -1002,6 +1011,7 @@ impl MaybeReadable for Event { let mut via_channel_id = None; let mut claim_deadline = None; let mut via_user_channel_id = None; + let mut onion_fields = None; read_tlv_fields!(reader, { (0, payment_hash, required), (1, receiver_node_id, option), @@ -1012,6 +1022,7 @@ impl MaybeReadable for Event { (6, _user_payment_id, option), (7, claim_deadline, option), (8, payment_preimage, option), + (9, onion_fields, option), }); let purpose = match payment_secret { Some(secret) => PaymentPurpose::InvoicePayment { @@ -1029,6 +1040,7 @@ impl MaybeReadable for Event { via_channel_id, via_user_channel_id, claim_deadline, + onion_fields, })) }; f() diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 9f0861ce3..6b3d3dacf 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -3432,6 +3432,7 @@ where via_channel_id: Some(prev_channel_id), via_user_channel_id: Some(prev_user_channel_id), claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER), + onion_fields: claimable_payment.onion_fields.clone(), }); payment_claimable_generated = true; } else { @@ -3501,6 +3502,7 @@ where via_channel_id: Some(prev_channel_id), via_user_channel_id: Some(prev_user_channel_id), claim_deadline, + onion_fields: Some(onion_fields), }); }, hash_map::Entry::Occupied(_) => { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 16a2fd486..7421601d9 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1981,21 +1981,26 @@ pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_p let events_2 = node.node.get_and_clear_pending_events(); if payment_claimable_expected { assert_eq!(events_2.len(), 1); - match events_2[0] { - Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, ref via_channel_id, ref via_user_channel_id, claim_deadline } => { + match &events_2[0] { + Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, + receiver_node_id, ref via_channel_id, ref via_user_channel_id, + claim_deadline, onion_fields, + } => { assert_eq!(our_payment_hash, *payment_hash); assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap()); + assert!(onion_fields.is_some()); match &purpose { PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => { assert_eq!(expected_preimage, *payment_preimage); assert_eq!(our_payment_secret.unwrap(), *payment_secret); + assert_eq!(Some(*payment_secret), onion_fields.as_ref().unwrap().payment_secret); }, PaymentPurpose::SpontaneousPayment(payment_preimage) => { assert_eq!(expected_preimage.unwrap(), *payment_preimage); assert!(our_payment_secret.is_none()); }, } - assert_eq!(amount_msat, recv_value); + assert_eq!(*amount_msat, recv_value); assert!(node.node.list_channels().iter().any(|details| details.channel_id == via_channel_id.unwrap())); assert!(node.node.list_channels().iter().any(|details| details.user_channel_id == via_user_channel_id.unwrap())); assert!(claim_deadline.unwrap() > node.best_block_info().1); diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index 59efbcfa8..345046c2d 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -409,7 +409,7 @@ pub enum PaymentSendFailure { /// /// This should generally be constructed with data communicated to us from the recipient (via a /// BOLT11 or BOLT12 invoice). -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct RecipientOnionFields { /// The [`PaymentSecret`] is an arbitrary 32 bytes provided by the recipient for us to repeat /// in the onion. It is unrelated to `payment_hash` (or [`PaymentPreimage`]) and exists to -- 2.39.5