Add a `user_payment_id` to `get_payment_secret`+`PaymentReceived`
authorMatt Corallo <git@bluematt.me>
Tue, 27 Apr 2021 01:29:39 +0000 (01:29 +0000)
committerMatt Corallo <git@bluematt.me>
Wed, 28 Apr 2021 19:30:25 +0000 (15:30 -0400)
This allows users to store metadata about an invoice at
invoice-generation time and then index into that storage with a
general-purpose id when they call `get_payment_secret`. They will
then be provided the same index when the payment has been received.

fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/util/events.rs

index bdd8b4e95c72c4b0299b954e8746be3abd2cc204..8ff741c720a4c3fc475ecd2f43ec086979d6d7b5 100644 (file)
@@ -266,7 +266,7 @@ fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(Payme
        let mut payment_hash;
        for _ in 0..256 {
                payment_hash = PaymentHash(Sha256::hash(&[*payment_id; 1]).into_inner());
-               if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 7200) {
+               if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 7200, 0) {
                        return Some((payment_secret, payment_hash));
                }
                *payment_id = payment_id.wrapping_add(1);
@@ -687,7 +687,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                let had_events = !events.is_empty();
                                for event in events.drain(..) {
                                        match event {
-                                               events::Event::PaymentReceived { payment_hash, payment_secret, amt } => {
+                                               events::Event::PaymentReceived { payment_hash, payment_secret, amt, user_payment_id: _ } => {
                                                        if claim_set.insert(payment_hash.0) {
                                                                if $fail {
                                                                        assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
index 8543555c16ab40b9de67b2ac0422965bbb0ed130..be9294c1d35fbe89586aa5f6d0d88fa62c971704 100644 (file)
@@ -497,7 +497,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                let payment_hash = PaymentHash(Sha256::from_engine(sha).into_inner());
                                // Note that this may fail - our hashes may collide and we'll end up trying to
                                // double-register the same payment_hash.
-                               let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1);
+                               let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1, 0);
                        },
                        9 => {
                                for (payment, payment_secret, _) in payments_received.drain(..) {
@@ -580,7 +580,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
                                        pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script));
                                },
-                               Event::PaymentReceived { payment_hash, payment_secret, amt } => {
+                               Event::PaymentReceived { payment_hash, payment_secret, amt, user_payment_id: _ } => {
                                        //TODO: enhance by fetching random amounts from fuzz input?
                                        payments_received.push((payment_hash, payment_secret, amt));
                                },
index 3563e463bd67706d1079cfce1f9b066df143cc55..1994cf1d62e657de3ceacaa4de4d57eadc33bfe5 100644 (file)
@@ -206,7 +206,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail
        let events_3 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_3.len(), 1);
        match events_3[0] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(payment_hash_1, *payment_hash);
                        assert_eq!(Some(payment_secret_1), *payment_secret);
                        assert_eq!(amt, 1000000);
@@ -574,7 +574,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        let events_5 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_5.len(), 1);
        match events_5[0] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(payment_hash_2, *payment_hash);
                        assert_eq!(Some(payment_secret_2), *payment_secret);
                        assert_eq!(amt, 1000000);
@@ -688,7 +688,7 @@ fn test_monitor_update_fail_cs() {
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
        match events[0] {
-               Event::PaymentReceived { payment_hash, payment_secret, amt } => {
+               Event::PaymentReceived { payment_hash, payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(payment_hash, our_payment_hash);
                        assert_eq!(Some(our_payment_secret), payment_secret);
                        assert_eq!(amt, 1000000);
index 672cc220576d9ab0f7de00fd66fb765d0b0b8509..bfe7ee39ea76d25ea176c2e6efa7eab5670cd602 100644 (file)
@@ -362,6 +362,8 @@ struct PendingInboundPayment {
        /// Time at which this HTLC expires - blocks with a header time above this value will result in
        /// this payment being removed.
        expiry_time: u64,
+       /// Arbitrary identifier the user specifies (or not)
+       user_payment_id: u64,
        // Other required attributes of the payment, optionally enforced:
        payment_preimage: Option<PaymentPreimage>,
        min_value_msat: Option<u64>,
@@ -2024,6 +2026,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                                        payment_hash,
                                                                                                        payment_secret: Some(payment_data.payment_secret),
                                                                                                        amt: total_value,
+                                                                                                       user_payment_id: inbound_payment.get().user_payment_id,
                                                                                                });
                                                                                                // Only ever generate at most one PaymentReceived
                                                                                                // per registered payment_hash, even if it isn't
@@ -3377,7 +3380,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                }
        }
 
-       fn set_payment_hash_secret_map(&self, payment_hash: PaymentHash, payment_preimage: Option<PaymentPreimage>, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<PaymentSecret, APIError> {
+       fn set_payment_hash_secret_map(&self, payment_hash: PaymentHash, payment_preimage: Option<PaymentPreimage>, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> Result<PaymentSecret, APIError> {
                assert!(invoice_expiry_delta_secs <= 60*60*24*365); // Sadly bitcoin timestamps are u32s, so panic before 2106
 
                let payment_secret = PaymentSecret(self.keys_manager.get_secure_random_bytes());
@@ -3387,7 +3390,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                match payment_secrets.entry(payment_hash) {
                        hash_map::Entry::Vacant(e) => {
                                e.insert(PendingInboundPayment {
-                                       payment_secret, min_value_msat, payment_preimage,
+                                       payment_secret, min_value_msat, user_payment_id, payment_preimage,
                                        // We assume that highest_seen_timestamp is pretty close to the current time -
                                        // its updated when we receive a new block with the maximum time we've seen in
                                        // a header. It should never be more than two hours in the future.
@@ -3412,12 +3415,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// See [`create_inbound_payment_for_hash`] for detailed documentation on behavior and requirements.
        ///
        /// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
-       pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> (PaymentHash, PaymentSecret) {
+       pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> (PaymentHash, PaymentSecret) {
                let payment_preimage = PaymentPreimage(self.keys_manager.get_secure_random_bytes());
                let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
 
                (payment_hash,
-                       self.set_payment_hash_secret_map(payment_hash, Some(payment_preimage), min_value_msat, invoice_expiry_delta_secs)
+                       self.set_payment_hash_secret_map(payment_hash, Some(payment_preimage), min_value_msat, invoice_expiry_delta_secs, user_payment_id)
                                .expect("RNG Generated Duplicate PaymentHash"))
        }
 
@@ -3431,6 +3434,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// The [`PaymentHash`] (and corresponding [`PaymentPreimage`]) must be globally unique. This
        /// method may return an Err if another payment with the same payment_hash is still pending.
        ///
+       /// `user_payment_id` will be provided back in [`PaymentReceived::user_payment_id`] events to
+       /// allow tracking of which events correspond with which calls to this and
+       /// [`create_inbound_payment`]. `user_payment_id` has no meaning inside of LDK, it is simply
+       /// copied to events and otherwise ignored. It may be used to correlate PaymentReceived events
+       /// with invoice metadata stored elsewhere.
+       ///
        /// `min_value_msat` should be set if the invoice being generated contains a value. Any payment
        /// received for the returned [`PaymentHash`] will be required to be at least `min_value_msat`
        /// before a [`PaymentReceived`] event will be generated, ensuring that we do not provide the
@@ -3452,8 +3461,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        ///
        /// [`create_inbound_payment`]: Self::create_inbound_payment
        /// [`PaymentReceived`]: events::Event::PaymentReceived
-       pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<PaymentSecret, APIError> {
-               self.set_payment_hash_secret_map(payment_hash, None, min_value_msat, invoice_expiry_delta_secs)
+       /// [`PaymentReceived::user_payment_id`]: events::Event::PaymentReceived::user_payment_id
+       pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> Result<PaymentSecret, APIError> {
+               self.set_payment_hash_secret_map(payment_hash, None, min_value_msat, invoice_expiry_delta_secs, user_payment_id)
        }
 }
 
@@ -4280,6 +4290,7 @@ impl Readable for HTLCForwardInfo {
 impl_writeable!(PendingInboundPayment, 0, {
        payment_secret,
        expiry_time,
+       user_payment_id,
        payment_preimage,
        min_value_msat
 });
@@ -4824,7 +4835,7 @@ pub mod bench {
                                payment_preimage.0[0..8].copy_from_slice(&payment_count.to_le_bytes());
                                payment_count += 1;
                                let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
-                               let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+                               let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
 
                                $node_a.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
                                let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap());
index a76c3fd5a261429dae174346d374a0bde8b453db..5b79cba050cbd5049e37dc54fc9827e76b99f5bb 100644 (file)
@@ -899,7 +899,7 @@ macro_rules! get_payment_preimage_hash {
                        let payment_preimage = PaymentPreimage([*$dest_node.network_payment_count.borrow(); 32]);
                        *$dest_node.network_payment_count.borrow_mut() += 1;
                        let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
-                       let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+                       let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
                        (payment_preimage, payment_hash, payment_secret)
                }
        }
@@ -941,7 +941,7 @@ macro_rules! expect_payment_received {
                let events = $node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
                match events[0] {
-                       Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+                       Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                                assert_eq!($expected_payment_hash, *payment_hash);
                                assert_eq!(Some($expected_payment_secret), *payment_secret);
                                assert_eq!($expected_recv_value, amt);
@@ -1009,7 +1009,7 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path
                        if payment_received_expected {
                                assert_eq!(events_2.len(), 1);
                                match events_2[0] {
-                                       Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+                                       Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                                                assert_eq!(our_payment_hash, *payment_hash);
                                                assert_eq!(Some(our_payment_secret), *payment_secret);
                                                assert_eq!(amt, recv_value);
index 0e3e3f01eee84c0278017ed6f2b3efda261982a7..1f5dcb8fef9c9e82cbd1064304103309e79bd884 100644 (file)
@@ -1470,7 +1470,7 @@ fn test_duplicate_htlc_different_direction_onchain() {
 
        let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
        let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800_000, TEST_FINAL_CLTV, &logger).unwrap();
-       let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+       let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
        send_along_route_with_secret(&nodes[1], route, &[&[&nodes[0]]], 800_000, payment_hash, node_a_payment_secret);
 
        // Provide preimage to node 0 by claiming payment
@@ -2070,7 +2070,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        let events = nodes[2].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 2);
        match events[0] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(our_payment_hash_21, *payment_hash);
                        assert_eq!(Some(our_payment_secret_21), *payment_secret);
                        assert_eq!(recv_value_21, amt);
@@ -2078,7 +2078,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
                _ => panic!("Unexpected event"),
        }
        match events[1] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(our_payment_hash_22, *payment_hash);
                        assert_eq!(Some(our_payment_secret_22), *payment_secret);
                        assert_eq!(recv_value_22, amt);
@@ -3646,7 +3646,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8) {
        let events_2 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_2.len(), 1);
        match events_2[0] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt, user_payment_id: _ } => {
                        assert_eq!(payment_hash_1, *payment_hash);
                        assert_eq!(Some(payment_secret_1), *payment_secret);
                        assert_eq!(amt, 1000000);
@@ -3983,7 +3983,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
        let events_5 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_5.len(), 1);
        match events_5[0] {
-               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt: _ } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt: _, user_payment_id: _ } => {
                        assert_eq!(payment_hash_2, *payment_hash);
                        assert_eq!(Some(payment_secret_2), *payment_secret);
                },
@@ -5113,7 +5113,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
 
        let (our_payment_preimage, duplicate_payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 900000);
 
-       let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200).unwrap();
+       let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200, 0).unwrap();
        let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(),
                &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 900000, TEST_FINAL_CLTV, nodes[0].logger).unwrap();
        send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 900000, duplicate_payment_hash, payment_secret);
@@ -5307,30 +5307,30 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
        let our_node_id = &nodes[1].node.get_our_node_id();
        let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
        // 2nd HTLC:
-       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee
        // 3rd HTLC:
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee
        // 4th HTLC:
        let (_, payment_hash_3, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        // 5th HTLC:
        let (_, payment_hash_4, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
        // 6th HTLC:
-       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200, 0).unwrap());
        // 7th HTLC:
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200, 0).unwrap());
 
        // 8th HTLC:
        let (_, payment_hash_5, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
        // 9th HTLC:
        let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee
 
        // 10th HTLC:
        let (_, payment_hash_6, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
        // 11th HTLC:
        let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
-       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200).unwrap());
+       send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200, 0).unwrap());
 
        // Double-check that six of the new HTLC were added
        // We now have six HTLCs pending over the dust limit and six HTLCs under the dust limit (ie,
index 8b8cc1230372821aa52c0cd4e6edbdc01cb5f1bd..4486d0510cbd2e1bafeeab069c437f9075bb5bda 100644 (file)
@@ -75,6 +75,15 @@ pub enum Event {
                /// compare this to the expected value before accepting the payment (as otherwise you are
                /// providing proof-of-payment for less than the value you expected!).
                amt: u64,
+               /// This is the `user_payment_id` which was provided to
+               /// [`ChannelManager::create_inbound_payment_for_hash`] or
+               /// [`ChannelManager::create_inbound_payment`]. It has no meaning inside of LDK and is
+               /// simply copied here. It may be used to correlate PaymentReceived events with invoice
+               /// metadata stored elsewhere.
+               ///
+               /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
+               /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
+               user_payment_id: u64,
        },
        /// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
        /// and we got back the payment preimage for it).
@@ -129,11 +138,12 @@ 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::PaymentReceived { ref payment_hash, ref payment_secret, ref amt } => {
+                       &Event::PaymentReceived { ref payment_hash, ref payment_secret, ref amt, ref user_payment_id } => {
                                1u8.write(writer)?;
                                payment_hash.write(writer)?;
                                payment_secret.write(writer)?;
                                amt.write(writer)?;
+                               user_payment_id.write(writer)?;
                        },
                        &Event::PaymentSent { ref payment_preimage } => {
                                2u8.write(writer)?;
@@ -177,6 +187,7 @@ impl MaybeReadable for Event {
                                        payment_hash: Readable::read(reader)?,
                                        payment_secret: Readable::read(reader)?,
                                        amt: Readable::read(reader)?,
+                                       user_payment_id: Readable::read(reader)?,
                                })),
                        2u8 => Ok(Some(Event::PaymentSent {
                                        payment_preimage: Readable::read(reader)?,