Merge pull request #1692 from TheBlueMatt/2022-08-time-goes-backwards
[rust-lightning] / lightning / src / util / events.rs
index caba7753f3fbb9bbf9b5364f6ab2488f8e6a6503..e86eae3c813a8af7a3684480171df913ea0883bd 100644 (file)
@@ -25,7 +25,7 @@ use routing::gossip::NetworkUpdate;
 use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
 use routing::router::{RouteHop, RouteParameters};
 
-use bitcoin::Transaction;
+use bitcoin::{PackedLockTime, Transaction};
 use bitcoin::blockdata::script::Script;
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -152,6 +152,50 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
        (12, OutdatedChannelManager) => {},
 );
 
+/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
+#[derive(Clone, Debug, PartialEq)]
+pub enum HTLCDestination {
+       /// We tried forwarding to a channel but failed to do so. An example of such an instance is when
+       /// there is insufficient capacity in our outbound channel.
+       NextHopChannel {
+               /// The `node_id` of the next node. For backwards compatibility, this field is
+               /// marked as optional, versions prior to 0.0.110 may not always be able to provide
+               /// counterparty node information.
+               node_id: Option<PublicKey>,
+               /// The outgoing `channel_id` between us and the next node.
+               channel_id: [u8; 32],
+       },
+       /// Scenario where we are unsure of the next node to forward the HTLC to.
+       UnknownNextHop {
+               /// 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.
+       ///
+       /// Some of the reasons may include:
+       /// * HTLC Timeouts
+       /// * Expected MPP amount to claim does not equal HTLC total
+       /// * Claimable amount does not match expected amount
+       FailedPayment {
+               /// The payment hash of the payment we attempted to process.
+               payment_hash: PaymentHash
+       },
+}
+
+impl_writeable_tlv_based_enum_upgradable!(HTLCDestination,
+       (0, NextHopChannel) => {
+               (0, node_id, required),
+               (2, channel_id, required),
+       },
+       (2, UnknownNextHop) => {
+               (0, requested_forward_scid, required),
+       },
+       (4, FailedPayment) => {
+               (0, payment_hash, 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
@@ -382,6 +426,38 @@ pub enum Event {
 #[cfg(test)]
                error_data: Option<Vec<u8>>,
        },
+       /// Indicates that a probe payment we sent returned successful, i.e., only failed at the destination.
+       ProbeSuccessful {
+               /// The id returned by [`ChannelManager::send_probe`].
+               ///
+               /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe
+               payment_id: PaymentId,
+               /// The hash generated by [`ChannelManager::send_probe`].
+               ///
+               /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe
+               payment_hash: PaymentHash,
+               /// The payment path that was successful.
+               path: Vec<RouteHop>,
+       },
+       /// Indicates that a probe payment we sent failed at an intermediary node on the path.
+       ProbeFailed {
+               /// The id returned by [`ChannelManager::send_probe`].
+               ///
+               /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe
+               payment_id: PaymentId,
+               /// The hash generated by [`ChannelManager::send_probe`].
+               ///
+               /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe
+               payment_hash: PaymentHash,
+               /// The payment path that failed.
+               path: Vec<RouteHop>,
+               /// The channel responsible for the failed probe.
+               ///
+               /// Note that for route hints or for the first hop in a path this may be an SCID alias and
+               /// may not refer to a channel in the public network graph. These aliases may also collide
+               /// with channels in the public network graph.
+               short_channel_id: Option<u64>,
+       },
        /// Used to indicate that [`ChannelManager::process_pending_htlc_forwards`] should be called at
        /// a time in the future.
        ///
@@ -508,6 +584,24 @@ pub enum Event {
                /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
                channel_type: ChannelTypeFeatures,
        },
+       /// Indicates that the HTLC was accepted, but could not be processed when or after attempting to
+       /// forward it.
+       ///
+       /// Some scenarios where this event may be sent include:
+       /// * Insufficient capacity in the outbound channel
+       /// * While waiting to forward the HTLC, the channel it is meant to be forwarded through closes
+       /// * When an unknown SCID is requested for forwarding a payment.
+       /// * Claiming an amount for an MPP payment that exceeds the HTLC total
+       /// * The HTLC has timed out
+       ///
+       /// This event, however, does not get generated if an HTLC fails to meet the forwarding
+       /// requirements (i.e. insufficient fees paid, or a CLTV that is too soon).
+       HTLCHandlingFailed {
+               /// The channel over which the HTLC was received.
+               prev_channel_id: [u8; 32],
+               /// Destination of the HTLC that failed to be processed.
+               failed_next_destination: HTLCDestination,
+       },
 }
 
 impl Writeable for Event {
@@ -635,6 +729,30 @@ impl Writeable for Event {
                                        (4, amount_msat, required),
                                });
                        },
+                       &Event::ProbeSuccessful { ref payment_id, ref payment_hash, ref path } => {
+                               21u8.write(writer)?;
+                               write_tlv_fields!(writer, {
+                                       (0, payment_id, required),
+                                       (2, payment_hash, required),
+                                       (4, path, vec_type)
+                               })
+                       },
+                       &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => {
+                               23u8.write(writer)?;
+                               write_tlv_fields!(writer, {
+                                       (0, payment_id, required),
+                                       (2, payment_hash, required),
+                                       (4, path, vec_type),
+                                       (6, short_channel_id, option),
+                               })
+                       },
+                       &Event::HTLCHandlingFailed { ref prev_channel_id, ref failed_next_destination } => {
+                               25u8.write(writer)?;
+                               write_tlv_fields!(writer, {
+                                       (0, prev_channel_id, required),
+                                       (2, failed_next_destination, 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`.
@@ -789,7 +907,7 @@ impl MaybeReadable for Event {
                        11u8 => {
                                let f = || {
                                        let mut channel_id = [0; 32];
-                                       let mut transaction = Transaction{ version: 2, lock_time: 0, input: Vec::new(), output: Vec::new() };
+                                       let mut transaction = Transaction{ version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
                                                (2, transaction, required),
@@ -854,6 +972,45 @@ impl MaybeReadable for Event {
                                };
                                f()
                        },
+                       21u8 => {
+                               let f = || {
+                                       let mut payment_id = PaymentId([0; 32]);
+                                       let mut payment_hash = PaymentHash([0; 32]);
+                                       let mut path: Option<Vec<RouteHop>> = Some(vec![]);
+                                       read_tlv_fields!(reader, {
+                                               (0, payment_id, required),
+                                               (2, payment_hash, required),
+                                               (4, path, vec_type),
+                                       });
+                                       Ok(Some(Event::ProbeSuccessful {
+                                               payment_id,
+                                               payment_hash,
+                                               path: path.unwrap(),
+                                       }))
+                               };
+                               f()
+                       },
+                       23u8 => {
+                               let f = || {
+                                       let mut payment_id = PaymentId([0; 32]);
+                                       let mut payment_hash = PaymentHash([0; 32]);
+                                       let mut path: Option<Vec<RouteHop>> = Some(vec![]);
+                                       let mut short_channel_id = None;
+                                       read_tlv_fields!(reader, {
+                                               (0, payment_id, required),
+                                               (2, payment_hash, required),
+                                               (4, path, vec_type),
+                                               (6, short_channel_id, option),
+                                       });
+                                       Ok(Some(Event::ProbeFailed{
+                                               payment_id,
+                                               payment_hash,
+                                               path: path.unwrap(),
+                                               short_channel_id,
+                                       }))
+                               };
+                               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
                        // reads.
@@ -1038,6 +1195,12 @@ pub trait MessageSendEventsProvider {
        fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent>;
 }
 
+/// A trait indicating an object may generate onion messages to send
+pub trait OnionMessageProvider {
+       /// Gets the next pending onion message for the peer with the given node id.
+       fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<msgs::OnionMessage>;
+}
+
 /// A trait indicating an object may generate events.
 ///
 /// Events are processed by passing an [`EventHandler`] to [`process_pending_events`].