Merge pull request #1059 from jkczyz/2021-08-payment-retry
[rust-lightning] / lightning / src / util / events.rs
index be9296161768314aeae20da5feecdd69eeb8fa76..bcd84ba42a6a069989523123290c384e594740b8 100644 (file)
 //! few other things.
 
 use chain::keysinterface::SpendableOutputDescriptor;
+use ln::channelmanager::PaymentId;
 use ln::msgs;
 use ln::msgs::DecodeError;
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 use routing::network_graph::NetworkUpdate;
 use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
+use routing::router::{RouteHop, RouteParameters};
 
+use bitcoin::Transaction;
 use bitcoin::blockdata::script::Script;
-
+use bitcoin::hashes::Hash;
+use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::key::PublicKey;
 
 use io;
 use prelude::*;
 use core::time::Duration;
 use core::ops::Deref;
+use sync::Arc;
 
 /// Some information provided on receipt of payment depends on whether the payment received is a
 /// spontaneous payment or a "conventional" lightning payment that's paying an invoice.
@@ -143,25 +148,27 @@ pub enum Event {
                channel_value_satoshis: u64,
                /// The script which should be used in the transaction output.
                output_script: Script,
-               /// The value passed in to ChannelManager::create_channel
+               /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or 0 for
+               /// an inbound channel.
+               ///
+               /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
                user_channel_id: u64,
        },
        /// Indicates we've received money! Just gotta dig out that payment preimage and feed it to
-       /// ChannelManager::claim_funds to get it....
-       /// Note that if the preimage is not known or the amount paid is incorrect, you should call
-       /// ChannelManager::fail_htlc_backwards to free up resources for this HTLC and avoid
+       /// [`ChannelManager::claim_funds`] to get it....
+       /// Note that if the preimage is not known, you should call
+       /// [`ChannelManager::fail_htlc_backwards`] to free up resources for this HTLC and avoid
        /// network congestion.
-       /// The amount paid should be considered 'incorrect' when it is less than or more than twice
-       /// the amount expected.
-       /// If you fail to call either ChannelManager::claim_funds or
-       /// ChannelManager::fail_htlc_backwards within the HTLC's timeout, the HTLC will be
+       /// If you fail to call either [`ChannelManager::claim_funds`] or
+       /// [`ChannelManager::fail_htlc_backwards`] within the HTLC's timeout, the HTLC will be
        /// automatically failed.
+       ///
+       /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
+       /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards
        PaymentReceived {
                /// The hash for which the preimage should be handed to the ChannelManager.
                payment_hash: PaymentHash,
-               /// The value, in thousandths of a satoshi, that this payment is for. Note that you must
-               /// 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!).
+               /// The value, in thousandths of a satoshi, that this payment is for.
                amt: u64,
                /// 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.
@@ -170,17 +177,33 @@ pub enum Event {
        /// Indicates an outbound payment we made succeeded (i.e. it made it all the way to its target
        /// and we got back the payment preimage for it).
        ///
-       /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentFailed` event.
-       /// In this situation, you SHOULD treat this payment as having succeeded.
+       /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed`
+       /// event. In this situation, you SHOULD treat this payment as having succeeded.
        PaymentSent {
+               /// The id returned by [`ChannelManager::send_payment`] and used with
+               /// [`ChannelManager::retry_payment`].
+               ///
+               /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
+               payment_id: Option<PaymentId>,
                /// The preimage to the hash given to ChannelManager::send_payment.
                /// Note that this serves as a payment receipt, if you wish to have such a thing, you must
                /// store it somehow!
                payment_preimage: PaymentPreimage,
+               /// The hash which was given to [`ChannelManager::send_payment`].
+               ///
+               /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+               payment_hash: PaymentHash,
        },
        /// Indicates an outbound payment we made failed. Probably some intermediary node dropped
        /// something. You may wish to retry with a different route.
-       PaymentFailed {
+       PaymentPathFailed {
+               /// The id returned by [`ChannelManager::send_payment`] and used with
+               /// [`ChannelManager::retry_payment`].
+               ///
+               /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+               /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
+               payment_id: Option<PaymentId>,
                /// The hash which was given to ChannelManager::send_payment.
                payment_hash: PaymentHash,
                /// Indicates the payment was rejected for some reason by the recipient. This implies that
@@ -200,6 +223,20 @@ pub enum Event {
                /// failed. This will be set to false if (1) this is an MPP payment and (2) other parts of the
                /// larger MPP payment were still in flight when this event was generated.
                all_paths_failed: bool,
+               /// The payment path that failed.
+               path: Vec<RouteHop>,
+               /// The channel responsible for the failed payment path.
+               ///
+               /// If this is `Some`, then the corresponding channel should be avoided when the payment is
+               /// retried. May be `None` for older [`Event`] serializations.
+               short_channel_id: Option<u64>,
+               /// Parameters needed to compute a new [`Route`] when retrying the failed payment path.
+               ///
+               /// See [`find_route`] for details.
+               ///
+               /// [`Route`]: crate::routing::router::Route
+               /// [`find_route`]: crate::routing::router::find_route
+               retry: Option<RouteParameters>,
 #[cfg(test)]
                error_code: Option<u16>,
 #[cfg(test)]
@@ -249,8 +286,22 @@ pub enum Event {
                /// The channel_id of the channel which has been closed. Note that on-chain transactions
                /// resolving the channel are likely still awaiting confirmation.
                channel_id: [u8; 32],
+               /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or 0 for
+               /// an inbound channel. This will always be zero for objects serialized with LDK versions
+               /// prior to 0.0.102.
+               ///
+               /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
+               user_channel_id: u64,
                /// The reason the channel was closed.
                reason: ClosureReason
+       },
+       /// Used to indicate to the user that they can abandon the funding transaction and recycle the
+       /// inputs for another purpose.
+       DiscardFunding {
+               /// The channel_id of the channel which has been closed.
+               channel_id: [u8; 32],
+               /// The full transaction received from the user
+               transaction: Transaction
        }
 }
 
@@ -285,13 +336,17 @@ impl Writeable for Event {
                                        (8, payment_preimage, option),
                                });
                        },
-                       &Event::PaymentSent { ref payment_preimage } => {
+                       &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash} => {
                                2u8.write(writer)?;
                                write_tlv_fields!(writer, {
                                        (0, payment_preimage, required),
+                                       (1, payment_hash, required),
+                                       (3, payment_id, option),
                                });
                        },
-                       &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref all_paths_failed,
+                       &Event::PaymentPathFailed {
+                               ref payment_id, ref payment_hash, ref rejected_by_dest, ref network_update,
+                               ref all_paths_failed, ref path, ref short_channel_id, ref retry,
                                #[cfg(test)]
                                ref error_code,
                                #[cfg(test)]
@@ -307,13 +362,16 @@ impl Writeable for Event {
                                        (1, network_update, option),
                                        (2, rejected_by_dest, required),
                                        (3, all_paths_failed, required),
+                                       (5, path, vec_type),
+                                       (7, short_channel_id, option),
+                                       (9, retry, option),
+                                       (11, payment_id, option),
                                });
                        },
                        &Event::PendingHTLCsForwardable { time_forwardable: _ } => {
                                4u8.write(writer)?;
-                               write_tlv_fields!(writer, {});
-                               // We don't write the time_fordwardable out at all, as we presume when the user
-                               // deserializes us at least that much time has elapsed.
+                               // Note that we now ignore these on the read end as we'll re-generate them in
+                               // ChannelManager, we write them here only for backwards compatibility.
                        },
                        &Event::SpendableOutputs { ref outputs } => {
                                5u8.write(writer)?;
@@ -328,13 +386,21 @@ impl Writeable for Event {
                                        (2, claim_from_onchain_tx, required),
                                });
                        },
-                       &Event::ChannelClosed { ref channel_id, ref reason } => {
+                       &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => {
                                9u8.write(writer)?;
                                write_tlv_fields!(writer, {
                                        (0, channel_id, required),
+                                       (1, user_channel_id, required),
                                        (2, reason, required)
                                });
                        },
+                       &Event::DiscardFunding { ref channel_id, ref transaction } => {
+                               11u8.write(writer)?;
+                               write_tlv_fields!(writer, {
+                                       (0, channel_id, required),
+                                       (2, transaction, required)
+                               })
+                       },
                        // Note that, going forward, all new events must only write data inside of
                        // `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
                        // data via `write_tlv_fields`.
@@ -384,11 +450,20 @@ impl MaybeReadable for Event {
                        2u8 => {
                                let f = || {
                                        let mut payment_preimage = PaymentPreimage([0; 32]);
+                                       let mut payment_hash = None;
+                                       let mut payment_id = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_preimage, required),
+                                               (1, payment_hash, option),
+                                               (3, payment_id, option),
                                        });
+                                       if payment_hash.is_none() {
+                                               payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()));
+                                       }
                                        Ok(Some(Event::PaymentSent {
+                                               payment_id,
                                                payment_preimage,
+                                               payment_hash: payment_hash.unwrap(),
                                        }))
                                };
                                f()
@@ -403,17 +478,29 @@ impl MaybeReadable for Event {
                                        let mut rejected_by_dest = false;
                                        let mut network_update = None;
                                        let mut all_paths_failed = Some(true);
+                                       let mut path: Option<Vec<RouteHop>> = Some(vec![]);
+                                       let mut short_channel_id = None;
+                                       let mut retry = None;
+                                       let mut payment_id = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_hash, required),
                                                (1, network_update, ignorable),
                                                (2, rejected_by_dest, required),
                                                (3, all_paths_failed, option),
+                                               (5, path, vec_type),
+                                               (7, short_channel_id, option),
+                                               (9, retry, option),
+                                               (11, payment_id, option),
                                        });
-                                       Ok(Some(Event::PaymentFailed {
+                                       Ok(Some(Event::PaymentPathFailed {
+                                               payment_id,
                                                payment_hash,
                                                rejected_by_dest,
                                                network_update,
                                                all_paths_failed: all_paths_failed.unwrap(),
+                                               path: path.unwrap(),
+                                               short_channel_id,
+                                               retry,
                                                #[cfg(test)]
                                                error_code,
                                                #[cfg(test)]
@@ -422,15 +509,7 @@ impl MaybeReadable for Event {
                                };
                                f()
                        },
-                       4u8 => {
-                               let f = || {
-                                       read_tlv_fields!(reader, {});
-                                       Ok(Some(Event::PendingHTLCsForwardable {
-                                               time_forwardable: Duration::from_secs(0)
-                                       }))
-                               };
-                               f()
-                       },
+                       4u8 => Ok(None),
                        5u8 => {
                                let f = || {
                                        let mut outputs = VecReadWrapper(Vec::new());
@@ -454,14 +533,32 @@ impl MaybeReadable for Event {
                                f()
                        },
                        9u8 => {
-                               let mut channel_id = [0; 32];
-                               let mut reason = None;
-                               read_tlv_fields!(reader, {
-                                       (0, channel_id, required),
-                                       (2, reason, ignorable),
-                               });
-                               if reason.is_none() { return Ok(None); }
-                               Ok(Some(Event::ChannelClosed { channel_id, reason: reason.unwrap() }))
+                               let f = || {
+                                       let mut channel_id = [0; 32];
+                                       let mut reason = None;
+                                       let mut user_channel_id_opt = None;
+                                       read_tlv_fields!(reader, {
+                                               (0, channel_id, required),
+                                               (1, user_channel_id_opt, option),
+                                               (2, reason, ignorable),
+                                       });
+                                       if reason.is_none() { return Ok(None); }
+                                       let user_channel_id = if let Some(id) = user_channel_id_opt { id } else { 0 };
+                                       Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: reason.unwrap() }))
+                               };
+                               f()
+                       },
+                       11u8 => {
+                               let f = || {
+                                       let mut channel_id = [0; 32];
+                                       let mut transaction = Transaction{ version: 2, lock_time: 0, input: Vec::new(), output: Vec::new() };
+                                       read_tlv_fields!(reader, {
+                                               (0, channel_id, required),
+                                               (2, transaction, required),
+                                       });
+                                       Ok(Some(Event::DiscardFunding { channel_id, transaction } ))
+                               };
+                               f()
                        },
                        // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
                        // Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
@@ -685,3 +782,9 @@ impl<F> EventHandler for F where F: Fn(&Event) {
                self(event)
        }
 }
+
+impl<T: EventHandler> EventHandler for Arc<T> {
+       fn handle_event(&self, event: &Event) {
+               self.deref().handle_event(event)
+       }
+}