Merge pull request #1891 from tnull/2022-12-rename-payment-events
[rust-lightning] / lightning / src / util / events.rs
index 3032aec75820d2d602a9ebf6d619ac7f13bf9cc1..28bd6978f6a5c9c7dad0563639e30a163bec5062 100644 (file)
@@ -17,7 +17,7 @@
 use crate::chain::keysinterface::SpendableOutputDescriptor;
 #[cfg(anchors)]
 use crate::ln::chan_utils::HTLCOutputInCommitment;
-use crate::ln::channelmanager::PaymentId;
+use crate::ln::channelmanager::{InterceptId, PaymentId};
 use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
 use crate::ln::features::ChannelTypeFeatures;
 use crate::ln::msgs;
@@ -182,6 +182,12 @@ pub enum HTLCDestination {
                /// Short channel id we are requesting to forward an HTLC to.
                requested_forward_scid: u64,
        },
+       /// We couldn't forward to the outgoing scid. An example would be attempting to send a duplicate
+       /// intercept HTLC.
+       InvalidForward {
+               /// Short channel id we are requesting to forward an HTLC to.
+               requested_forward_scid: u64
+       },
        /// Failure scenario where an HTLC may have been forwarded to be intended for us,
        /// but is invalid for some reason, so we reject it.
        ///
@@ -200,12 +206,15 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination,
                (0, node_id, required),
                (2, channel_id, required),
        },
+       (1, InvalidForward) => {
+               (0, requested_forward_scid, required),
+       },
        (2, UnknownNextHop) => {
                (0, requested_forward_scid, required),
        },
        (4, FailedPayment) => {
                (0, payment_hash, required),
-       }
+       },
 );
 
 #[cfg(anchors)]
@@ -288,6 +297,22 @@ pub enum BumpTransactionEvent {
        },
 }
 
+/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path.
+/// Currently only used in serialization for the sake of maintaining compatibility. More variants
+/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward
+/// intercepts in upcoming work.
+enum InterceptNextHop {
+       FakeScid {
+               requested_next_hop_scid: u64,
+       },
+}
+
+impl_writeable_tlv_based_enum!(InterceptNextHop,
+       (0, FakeScid) => {
+               (0, requested_next_hop_scid, required),
+       };
+);
+
 /// An Event which you should probably take some action in response to.
 ///
 /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
@@ -325,8 +350,8 @@ pub enum Event {
                /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
                user_channel_id: u128,
        },
-       /// Indicates we've received (an offer of) money! Just gotta dig out that payment preimage and
-       /// feed it to [`ChannelManager::claim_funds`] to get it....
+       /// Indicates that we've been offered a payment and it needs to be claimed via calling
+       /// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`].
        ///
        /// Note that if the preimage is not known, you should call
        /// [`ChannelManager::fail_htlc_backwards`] to free up resources for this HTLC and avoid
@@ -337,17 +362,20 @@ pub enum Event {
        ///
        /// # Note
        /// LDK will not stop an inbound payment from being paid multiple times, so multiple
-       /// `PaymentReceived` events may be generated for the same payment.
+       /// `PaymentClaimable` events may be generated for the same payment.
+       ///
+       /// # Note
+       /// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier.
        ///
        /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
        /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards
-       PaymentReceived {
-               /// The node that received the payment.
-               /// This is useful to identify payments which were received via [phantom node payments].
+       PaymentClaimable {
+               /// The node that will receive the payment after it has been claimed.
+               /// This is useful to identify payments received via [phantom nodes].
                /// This field will always be filled in when the event was generated by LDK versions
                /// 0.0.113 and above.
                ///
-               /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
+               /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager
                receiver_node_id: Option<PublicKey>,
                /// 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.
@@ -357,35 +385,39 @@ pub enum Event {
                /// Information for claiming this received payment, based on whether the purpose of the
                /// payment is to pay an invoice or to send a spontaneous payment.
                purpose: PaymentPurpose,
+               /// The `channel_id` indicating over which channel we received the payment.
+               via_channel_id: Option<[u8; 32]>,
+               /// The `user_channel_id` indicating over which channel we received the payment.
+               via_user_channel_id: Option<u128>,
        },
        /// Indicates a payment has been claimed and we've received money!
        ///
        /// This most likely occurs when [`ChannelManager::claim_funds`] has been called in response
-       /// to an [`Event::PaymentReceived`]. However, if we previously crashed during a
+       /// to an [`Event::PaymentClaimable`]. However, if we previously crashed during a
        /// [`ChannelManager::claim_funds`] call you may see this event without a corresponding
-       /// [`Event::PaymentReceived`] event.
+       /// [`Event::PaymentClaimable`] event.
        ///
        /// # Note
        /// LDK will not stop an inbound payment from being paid multiple times, so multiple
-       /// `PaymentReceived` events may be generated for the same payment. If you then call
-       /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentReceived`] you may get
+       /// `PaymentClaimable` events may be generated for the same payment. If you then call
+       /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentClaimable`] you may get
        /// multiple `PaymentClaimed` events.
        ///
        /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
        PaymentClaimed {
                /// The node that received the payment.
-               /// This is useful to identify payments which were received via [phantom node payments].
+               /// This is useful to identify payments which were received via [phantom nodes].
                /// This field will always be filled in when the event was generated by LDK versions
                /// 0.0.113 and above.
                ///
-               /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
+               /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager
                receiver_node_id: Option<PublicKey>,
                /// The payment hash of the claimed payment. Note that LDK will not stop you from
                /// registering duplicate payment hashes for inbound payments.
                payment_hash: PaymentHash,
                /// The value, in thousandths of a satoshi, that this payment is for.
                amount_msat: u64,
-               /// The purpose of this claimed payment, i.e. whether the payment was for an invoice or a
+               /// The purpose of the claimed payment, i.e. whether the payment was for an invoice or a
                /// spontaneous payment.
                purpose: PaymentPurpose,
        },
@@ -581,6 +613,38 @@ pub enum Event {
                /// now + 5*time_forwardable).
                time_forwardable: Duration,
        },
+       /// Used to indicate that we've intercepted an HTLC forward. This event will only be generated if
+       /// you've encoded an intercept scid in the receiver's invoice route hints using
+       /// [`ChannelManager::get_intercept_scid`] and have set [`UserConfig::accept_intercept_htlcs`].
+       ///
+       /// [`ChannelManager::forward_intercepted_htlc`] or
+       /// [`ChannelManager::fail_intercepted_htlc`] MUST be called in response to this event. See
+       /// their docs for more information.
+       ///
+       /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid
+       /// [`UserConfig::accept_intercept_htlcs`]: crate::util::config::UserConfig::accept_intercept_htlcs
+       /// [`ChannelManager::forward_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::forward_intercepted_htlc
+       /// [`ChannelManager::fail_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::fail_intercepted_htlc
+       HTLCIntercepted {
+               /// An id to help LDK identify which HTLC is being forwarded or failed.
+               intercept_id: InterceptId,
+               /// The fake scid that was programmed as the next hop's scid, generated using
+               /// [`ChannelManager::get_intercept_scid`].
+               ///
+               /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid
+               requested_next_hop_scid: u64,
+               /// The payment hash used for this HTLC.
+               payment_hash: PaymentHash,
+               /// How many msats were received on the inbound edge of this HTLC.
+               inbound_amount_msat: u64,
+               /// How many msats the payer intended to route to the next node. Depending on the reason you are
+               /// intercepting this payment, you might take a fee by forwarding less than this amount.
+               ///
+               /// Note that LDK will NOT check that expected fees were factored into this value. You MUST
+               /// check that whatever fee you want has been included here or subtract it as required. Further,
+               /// LDK will not stop you from forwarding more than you received.
+               expected_outbound_amount_msat: u64,
+       },
        /// Used to indicate that an output which you should know how to spend was confirmed on chain
        /// and is now spendable.
        /// Such an output will *not* ever be spent by rust-lightning, and are not at risk of your
@@ -753,7 +817,7 @@ 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 amount_msat, ref purpose, ref receiver_node_id } => {
+                       &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id } => {
                                1u8.write(writer)?;
                                let mut payment_secret = None;
                                let payment_preimage;
@@ -770,7 +834,9 @@ impl Writeable for Event {
                                        (0, payment_hash, required),
                                        (1, receiver_node_id, option),
                                        (2, payment_secret, option),
+                                       (3, via_channel_id, option),
                                        (4, amount_msat, required),
+                                       (5, via_user_channel_id, option),
                                        (6, 0u64, required), // user_payment_id required for compatibility with 0.0.103 and earlier
                                        (8, payment_preimage, option),
                                });
@@ -819,6 +885,17 @@ impl Writeable for Event {
                                        (0, WithoutLength(outputs), required),
                                });
                        },
+                       &Event::HTLCIntercepted { requested_next_hop_scid, payment_hash, inbound_amount_msat, expected_outbound_amount_msat, intercept_id } => {
+                               6u8.write(writer)?;
+                               let intercept_scid = InterceptNextHop::FakeScid { requested_next_hop_scid };
+                               write_tlv_fields!(writer, {
+                                       (0, intercept_id, required),
+                                       (2, intercept_scid, required),
+                                       (4, payment_hash, required),
+                                       (6, inbound_amount_msat, required),
+                                       (8, expected_outbound_amount_msat, required),
+                               });
+                       }
                        &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
                                7u8.write(writer)?;
                                write_tlv_fields!(writer, {
@@ -941,11 +1018,15 @@ impl MaybeReadable for Event {
                                        let mut amount_msat = 0;
                                        let mut receiver_node_id = None;
                                        let mut _user_payment_id = None::<u64>; // For compatibility with 0.0.103 and earlier
+                                       let mut via_channel_id = None;
+                                       let mut via_user_channel_id = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_hash, required),
                                                (1, receiver_node_id, option),
                                                (2, payment_secret, option),
+                                               (3, via_channel_id, option),
                                                (4, amount_msat, required),
+                                               (5, via_user_channel_id, option),
                                                (6, _user_payment_id, option),
                                                (8, payment_preimage, option),
                                        });
@@ -957,11 +1038,13 @@ impl MaybeReadable for Event {
                                                None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()),
                                                None => return Err(msgs::DecodeError::InvalidValue),
                                        };
-                                       Ok(Some(Event::PaymentReceived {
+                                       Ok(Some(Event::PaymentClaimable {
                                                receiver_node_id,
                                                payment_hash,
                                                amount_msat,
                                                purpose,
+                                               via_channel_id,
+                                               via_user_channel_id,
                                        }))
                                };
                                f()
@@ -1042,6 +1125,30 @@ impl MaybeReadable for Event {
                                };
                                f()
                        },
+                       6u8 => {
+                               let mut payment_hash = PaymentHash([0; 32]);
+                               let mut intercept_id = InterceptId([0; 32]);
+                               let mut requested_next_hop_scid = InterceptNextHop::FakeScid { requested_next_hop_scid: 0 };
+                               let mut inbound_amount_msat = 0;
+                               let mut expected_outbound_amount_msat = 0;
+                               read_tlv_fields!(reader, {
+                                       (0, intercept_id, required),
+                                       (2, requested_next_hop_scid, required),
+                                       (4, payment_hash, required),
+                                       (6, inbound_amount_msat, required),
+                                       (8, expected_outbound_amount_msat, required),
+                               });
+                               let next_scid = match requested_next_hop_scid {
+                                       InterceptNextHop::FakeScid { requested_next_hop_scid: scid } => scid
+                               };
+                               Ok(Some(Event::HTLCIntercepted {
+                                       payment_hash,
+                                       requested_next_hop_scid: next_scid,
+                                       inbound_amount_msat,
+                                       expected_outbound_amount_msat,
+                                       intercept_id,
+                               }))
+                       },
                        7u8 => {
                                let f = || {
                                        let mut fee_earned_msat = None;