Check we won't overflow `max_dust_htlc_exposure_msat` at outbound feerate update
[rust-lightning] / lightning / src / util / events.rs
index e9f456cfe69750743fc21b787272ddf41814ee87..6bbd6b9946ccc49e18ae7b85a715b23d2478f4ad 100644 (file)
@@ -16,6 +16,7 @@
 
 use chain::keysinterface::SpendableOutputDescriptor;
 use ln::channelmanager::PaymentId;
+use ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
 use ln::msgs;
 use ln::msgs::DecodeError;
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
@@ -23,6 +24,7 @@ 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;
@@ -32,7 +34,7 @@ use io;
 use prelude::*;
 use core::time::Duration;
 use core::ops::Deref;
-use bitcoin::Transaction;
+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.
@@ -100,6 +102,8 @@ pub enum ClosureReason {
        /// commitment transaction came from our counterparty, but it may also have come from
        /// a copy of our own `ChannelMonitor`.
        CommitmentTxConfirmed,
+       /// The funding transaction failed to confirm in a timely manner on an inbound channel.
+       FundingTimedOut,
        /// Closure generated from processing an event, likely a HTLC forward/relay/reception.
        ProcessingError {
                /// A developer-readable error message which we generated.
@@ -117,8 +121,31 @@ pub enum ClosureReason {
        OutdatedChannelManager
 }
 
+impl core::fmt::Display for ClosureReason {
+       fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+               f.write_str("Channel closed because ")?;
+               match self {
+                       ClosureReason::CounterpartyForceClosed { peer_msg } => {
+                               f.write_str("counterparty force-closed with message ")?;
+                               f.write_str(&peer_msg)
+                       },
+                       ClosureReason::HolderForceClosed => f.write_str("user manually force-closed the channel"),
+                       ClosureReason::CooperativeClosure => f.write_str("the channel was cooperatively closed"),
+                       ClosureReason::CommitmentTxConfirmed => f.write_str("commitment or closing transaction was confirmed on chain."),
+                       ClosureReason::FundingTimedOut => write!(f, "funding transaction failed to confirm within {} blocks", FUNDING_CONF_DEADLINE_BLOCKS),
+                       ClosureReason::ProcessingError { err } => {
+                               f.write_str("of an exception: ")?;
+                               f.write_str(&err)
+                       },
+                       ClosureReason::DisconnectedPeer => f.write_str("the peer disconnected prior to the channel being funded"),
+                       ClosureReason::OutdatedChannelManager => f.write_str("the ChannelManager read from disk was stale compared to ChannelMonitor(s)"),
+               }
+       }
+}
+
 impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
        (0, CounterpartyForceClosed) => { (1, peer_msg, required) },
+       (1, FundingTimedOut) => {},
        (2, HolderForceClosed) => {},
        (6, CommitmentTxConfirmed) => {},
        (4, CooperativeClosure) => {},
@@ -193,6 +220,16 @@ pub enum Event {
                ///
                /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
                payment_hash: PaymentHash,
+               /// The total fee which was spent at intermediate hops in this payment, across all paths.
+               ///
+               /// Note that, like [`Route::get_total_fees`] this does *not* include any potential
+               /// overpayment to the recipient node.
+               ///
+               /// If the recipient or an intermediate node misbehaves and gives us free money, this may
+               /// overstate the amount paid, though this is unlikely.
+               ///
+               /// [`Route::get_total_fees`]: crate::routing::router::Route::get_total_fees
+               fee_paid_msat: Option<u64>,
        },
        /// Indicates an outbound payment we made failed. Probably some intermediary node dropped
        /// something. You may wish to retry with a different route.
@@ -335,12 +372,13 @@ impl Writeable for Event {
                                        (8, payment_preimage, option),
                                });
                        },
-                       &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash} => {
+                       &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
                                2u8.write(writer)?;
                                write_tlv_fields!(writer, {
                                        (0, payment_preimage, required),
                                        (1, payment_hash, required),
                                        (3, payment_id, option),
+                                       (5, fee_paid_msat, option),
                                });
                        },
                        &Event::PaymentPathFailed {
@@ -451,10 +489,12 @@ impl MaybeReadable for Event {
                                        let mut payment_preimage = PaymentPreimage([0; 32]);
                                        let mut payment_hash = None;
                                        let mut payment_id = None;
+                                       let mut fee_paid_msat = None;
                                        read_tlv_fields!(reader, {
                                                (0, payment_preimage, required),
                                                (1, payment_hash, option),
                                                (3, payment_id, option),
+                                               (5, fee_paid_msat, option),
                                        });
                                        if payment_hash.is_none() {
                                                payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()));
@@ -463,6 +503,7 @@ impl MaybeReadable for Event {
                                                payment_id,
                                                payment_preimage,
                                                payment_hash: payment_hash.unwrap(),
+                                               fee_paid_msat,
                                        }))
                                };
                                f()
@@ -781,3 +822,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)
+       }
+}