X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=d63dd88b76163c86fd16410e468eb03f7d95fcc6;hb=bb9df69d0d91cf5ea4cef6b81ab2edd9baddb6be;hp=876dfe6abb551f359a6c67c60fe05c1d104b81ed;hpb=d1e8d9ced595efe1dbcddde480fccc0d3f98184d;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 876dfe6a..d63dd88b 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -14,15 +14,17 @@ //! future, as well as generate and broadcast funding transactions handle payment preimages and a //! few other things. +use chain::keysinterface::SpendableOutputDescriptor; use ln::msgs; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; -use chain::keysinterface::SpendableOutputDescriptor; +use routing::network_graph::NetworkUpdate; use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper}; use bitcoin::blockdata::script::Script; use bitcoin::secp256k1::key::PublicKey; +use io; use prelude::*; use core::time::Duration; use core::ops::Deref; @@ -127,6 +129,15 @@ pub enum Event { /// the payment has failed, not just the route in question. If this is not set, you may /// 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. [`NetGraphMsgHandler`] is capable of doing this. + /// + /// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph + /// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler + network_update: Option, #[cfg(test)] error_code: Option, #[cfg(test)] @@ -150,10 +161,31 @@ pub enum Event { /// The outputs which you should store as spendable by you. outputs: Vec, }, + /// This event is generated when a payment has been successfully forwarded through us and a + /// forwarding fee earned. + PaymentForwarded { + /// The fee, in milli-satoshis, which was earned as a result of the payment. + /// + /// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC + /// was pending, the amount the next hop claimed will have been rounded down to the nearest + /// whole satoshi. Thus, the fee calculated here may be higher than expected as we still + /// claimed the full value in millisatoshis from the source. In this case, + /// `claim_from_onchain_tx` will be set. + /// + /// If the channel which sent us the payment has been force-closed, we will claim the funds + /// via an on-chain transaction. In that case we do not yet know the on-chain transaction + /// fees which we will spend and will instead set this to `None`. It is possible duplicate + /// `PaymentForwarded` events are generated for the same payment iff `fee_earned_msat` is + /// `None`. + fee_earned_msat: Option, + /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain + /// transaction. + claim_from_onchain_tx: bool, + }, } impl Writeable for Event { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { match self { &Event::FundingGenerationReady { .. } => { 0u8.write(writer)?; @@ -189,7 +221,7 @@ impl Writeable for Event { (0, payment_preimage, required), }); }, - &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, + &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, #[cfg(test)] ref error_code, #[cfg(test)] @@ -202,6 +234,7 @@ impl Writeable for Event { error_data.write(writer)?; write_tlv_fields!(writer, { (0, payment_hash, required), + (1, network_update, option), (2, rejected_by_dest, required), }); }, @@ -217,12 +250,19 @@ impl Writeable for Event { (0, VecWriteWrapper(outputs), required), }); }, + &Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx } => { + 7u8.write(writer)?; + write_tlv_fields!(writer, { + (0, fee_earned_msat, option), + (2, claim_from_onchain_tx, required), + }); + }, } Ok(()) } } impl MaybeReadable for Event { - fn read(reader: &mut R) -> Result, msgs::DecodeError> { + fn read(reader: &mut R) -> Result, msgs::DecodeError> { match Readable::read(reader)? { 0u8 => Ok(None), 1u8 => { @@ -278,13 +318,16 @@ impl MaybeReadable for Event { let error_data = Readable::read(reader)?; let mut payment_hash = PaymentHash([0; 32]); let mut rejected_by_dest = false; + let mut network_update = None; read_tlv_fields!(reader, { (0, payment_hash, required), + (1, network_update, ignorable), (2, rejected_by_dest, required), }); Ok(Some(Event::PaymentFailed { payment_hash, rejected_by_dest, + network_update, #[cfg(test)] error_code, #[cfg(test)] @@ -312,6 +355,20 @@ impl MaybeReadable for Event { }; f() }, + 7u8 => { + let f = || { + let mut fee_earned_msat = None; + let mut claim_from_onchain_tx = false; + read_tlv_fields!(reader, { + (0, fee_earned_msat, option), + (2, claim_from_onchain_tx, required), + }); + Ok(Some(Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx })) + }; + f() + }, + // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue. + x if x % 2 == 1 => Ok(None), _ => Err(msgs::DecodeError::InvalidValue) } } @@ -442,12 +499,6 @@ pub enum MessageSendEvent { /// The action which should be taken. action: msgs::ErrorAction }, - /// When a payment fails we may receive updates back from the hop where it failed. In such - /// cases this event is generated so that we can inform the network graph of this information. - PaymentFailureNetworkUpdate { - /// The channel/node update which should be sent to NetGraphMsgHandler - update: msgs::HTLCFailChannelUpdate, - }, /// Query a peer for channels with funding transaction UTXOs in a block range. SendChannelRangeQuery { /// The node_id of this message recipient @@ -518,11 +569,11 @@ pub trait EventHandler { /// Handles the given [`Event`]. /// /// See [`EventsProvider`] for details that must be considered when implementing this method. - fn handle_event(&self, event: Event); + fn handle_event(&self, event: &Event); } -impl EventHandler for F where F: Fn(Event) { - fn handle_event(&self, event: Event) { +impl EventHandler for F where F: Fn(&Event) { + fn handle_event(&self, event: &Event) { self(event) } }