Expose the `RecipientOnionFields` in `Event::PaymentClaimable`
authorMatt Corallo <git@bluematt.me>
Fri, 7 Apr 2023 20:48:01 +0000 (20:48 +0000)
committerMatt Corallo <git@bluematt.me>
Wed, 19 Apr 2023 14:55:42 +0000 (14:55 +0000)
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
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/outbound_payment.rs

index b482996b916d077b16da87696230abcac8f4e1bc..18d2929178f7f1b7a6b44c3c926d2e8a42c62d6f 100644 (file)
@@ -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<RecipientOnionFields>,
                /// 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()
index 9f0861ce3c610a527ea52f81779ff149d5939b7e..6b3d3dacfb5ea55bbbd8f690429a0a71ba5fb29d 100644 (file)
@@ -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(_) => {
index 16a2fd486bdcfdbddf0f24a4c1e02f934a3131f6..7421601d9537b0185cc65f630615f2405c59a6db 100644 (file)
@@ -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);
index 59efbcfa8c38e1740cad3fb507d0334c61f2e974..345046c2daad66f37d7d25890273b49ff0ce141e 100644 (file)
@@ -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