Add Event::ChannelClosed generation at channel shutdown
[rust-lightning] / lightning / src / util / events.rs
index bde7d8c441301251cd8d2278c3837348ce2e3cbc..c6691826ee6457615d6597fcfb5f899c3d79e1fe 100644 (file)
@@ -26,6 +26,7 @@ use bitcoin::secp256k1::key::PublicKey;
 
 use io;
 use prelude::*;
+use core::cmp;
 use core::time::Duration;
 use core::ops::Deref;
 
@@ -112,8 +113,11 @@ pub enum Event {
                /// payment is to pay an invoice or to send a spontaneous payment.
                purpose: PaymentPurpose,
        },
-       /// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
+       /// 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.
        PaymentSent {
                /// 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
@@ -130,11 +134,18 @@ pub enum Event {
                /// retry the payment via a different route.
                rejected_by_dest: bool,
                /// Any failure information conveyed via the Onion return packet by a node along the failed
-               /// payment route. Should be applied to the [`NetworkGraph`] so that routing decisions can
-               /// take into account the update.
+               /// payment route.
+               ///
+               /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into
+               /// account the update. [`NetGraphMsgHandler`] is capable of doing this.
                ///
                /// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph
+               /// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
                network_update: Option<NetworkUpdate>,
+               /// For both single-path and multi-path payments, this is set if all paths of the payment have
+               /// 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,
 #[cfg(test)]
                error_code: Option<u16>,
 #[cfg(test)]
@@ -179,6 +190,14 @@ pub enum Event {
                /// transaction.
                claim_from_onchain_tx: bool,
        },
+       /// Used to indicate that a channel was closed at the given timestamp.
+       ChannelClosed  {
+               /// The channel_id which has been barren from further off-chain updates but
+               /// funding output might still be not resolved yet.
+               channel_id: [u8; 32],
+               /// A human-readable error message
+               err: String
+       }
 }
 
 impl Writeable for Event {
@@ -218,7 +237,7 @@ impl Writeable for Event {
                                        (0, payment_preimage, required),
                                });
                        },
-                       &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update,
+                       &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref all_paths_failed,
                                #[cfg(test)]
                                ref error_code,
                                #[cfg(test)]
@@ -233,6 +252,7 @@ impl Writeable for Event {
                                        (0, payment_hash, required),
                                        (1, network_update, option),
                                        (2, rejected_by_dest, required),
+                                       (3, all_paths_failed, required),
                                });
                        },
                        &Event::PendingHTLCsForwardable { time_forwardable: _ } => {
@@ -254,6 +274,13 @@ impl Writeable for Event {
                                        (2, claim_from_onchain_tx, required),
                                });
                        },
+                       &Event::ChannelClosed { ref channel_id, ref err } => {
+                               6u8.write(writer)?;
+                               channel_id.write(writer)?;
+                               (err.len() as u16).write(writer)?;
+                               writer.write_all(err.as_bytes())?;
+                               write_tlv_fields!(writer, {});
+                       },
                }
                Ok(())
        }
@@ -316,15 +343,18 @@ impl MaybeReadable for Event {
                                        let mut payment_hash = PaymentHash([0; 32]);
                                        let mut rejected_by_dest = false;
                                        let mut network_update = None;
+                                       let mut all_paths_failed = Some(true);
                                        read_tlv_fields!(reader, {
                                                (0, payment_hash, required),
                                                (1, network_update, ignorable),
                                                (2, rejected_by_dest, required),
+                                               (3, all_paths_failed, option),
                                        });
                                        Ok(Some(Event::PaymentFailed {
                                                payment_hash,
                                                rejected_by_dest,
                                                network_update,
+                                               all_paths_failed: all_paths_failed.unwrap(),
                                                #[cfg(test)]
                                                error_code,
                                                #[cfg(test)]
@@ -366,6 +396,24 @@ impl MaybeReadable for Event {
                        },
                        // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
                        x if x % 2 == 1 => Ok(None),
+                       6u8 => {
+                               let f = || {
+                                       let channel_id = Readable::read(reader)?;
+                                       let err = {
+                                               let mut size: usize = <u16 as Readable>::read(reader)? as usize;
+                                               let mut data = vec![];
+                                               let data_len = reader.read_to_end(&mut data)?;
+                                               size = cmp::min(data_len, size);
+                                               match String::from_utf8(data[..size as usize].to_vec()) {
+                                                       Ok(s) => s,
+                                                       Err(_) => return Err(msgs::DecodeError::InvalidValue),
+                                               }
+                                       };
+                                       read_tlv_fields!(reader, {});
+                                       Ok(Some(Event::ChannelClosed { channel_id, err: err }))
+                               };
+                               f()
+                       },
                        _ => Err(msgs::DecodeError::InvalidValue)
                }
        }