X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=abd8f6b105fcdda900518efbd3c59ea2c52c14cf;hb=0dd987fc41240d96a13f2011cb0679eb6abdb3b1;hp=bde7d8c441301251cd8d2278c3837348ce2e3cbc;hpb=eff9a47075445a3d4f3bf15ef68723c2ea6348e8;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index bde7d8c4..abd8f6b1 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -16,6 +16,7 @@ use chain::keysinterface::SpendableOutputDescriptor; use ln::msgs; +use ln::msgs::DecodeError; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use routing::network_graph::NetworkUpdate; use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper}; @@ -68,6 +69,47 @@ pub enum PaymentPurpose { SpontaneousPayment(PaymentPreimage), } +#[derive(Clone, Debug)] +pub enum ClosureDescriptor { + ForceClosed, + UserInitiated, + CounterpartyInitiated, + CooperativeClosure, + UnknownOnchainCommitment, + ProcessingError, + DisconnectedPeer, +} + +impl Writeable for ClosureDescriptor { + fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + match self { + ClosureDescriptor::ForceClosed => 0u8.write(writer)?, + ClosureDescriptor::UserInitiated => 1u8.write(writer)?, + ClosureDescriptor::CounterpartyInitiated => 2u8.write(writer)?, + ClosureDescriptor::CooperativeClosure => 3u8.write(writer)?, + ClosureDescriptor::UnknownOnchainCommitment => 4u8.write(writer)?, + ClosureDescriptor::ProcessingError => 5u8.write(writer)?, + ClosureDescriptor::DisconnectedPeer => 6u8.write(writer)?, + } + Ok(()) + } +} + +impl Readable for ClosureDescriptor { + fn read(reader: &mut R) -> Result { + Ok(match ::read(reader)? { + 0 => ClosureDescriptor::ForceClosed, + 1 => ClosureDescriptor::UserInitiated, + 2 => ClosureDescriptor::CounterpartyInitiated, + 3 => ClosureDescriptor::CooperativeClosure, + 4 => ClosureDescriptor::UnknownOnchainCommitment, + 5 => ClosureDescriptor::ProcessingError, + 6 => ClosureDescriptor::DisconnectedPeer, + _ => return Err(DecodeError::InvalidValue), + }) + } +} + /// 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 @@ -112,8 +154,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 +175,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, + /// 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, #[cfg(test)] @@ -179,6 +231,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 machine-readable error message + err: ClosureDescriptor + } } impl Writeable for Event { @@ -218,7 +278,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 +293,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 +315,12 @@ 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.write(writer)?; + write_tlv_fields!(writer, {}); + }, } Ok(()) } @@ -316,15 +383,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 +436,15 @@ 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 = Readable::read(reader)?; + read_tlv_fields!(reader, {}); + Ok(Some(Event::ChannelClosed { channel_id, err})) + }; + f() + }, _ => Err(msgs::DecodeError::InvalidValue) } }