X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=d4453d9f26921d5d0ff86c6bbadead84634cd76e;hb=1ad3eae91c641e7ace4bb01f5fddabe6b78904ce;hp=df4d9037307c30cb20e32c9b36a07ff6c10cd4b5;hpb=831f124721413323c32e523378969d119dd16526;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index df4d9037..d4453d9f 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,95 @@ pub enum PaymentPurpose { SpontaneousPayment(PaymentPreimage), } +#[derive(Clone, Debug)] +pub enum ClosureDescriptor { + /// Closure generated from ChannelManager::force_close_channel or receiving a peer error + /// message by ChannelManager::handle_error + ForceClosed { + /// If the error is coming from the peer, there should be a human-readable msg + peer_msg: Option, + }, + /// Closure generated from receiving a peer's ClosingSigned message. Note the shutdown + /// sequence might have been initially initiated by us. + CooperativeClosure, + /// Closure generated from receiving chain::Watch's CommitmentTxBroadcast event. + CommitmentTxBroadcasted, + /// Closure generated from processing an event, likely a HTLC forward/relay/reception. + ProcessingError { + err: String, + }, + /// Closure generated from ChannelManager::peer_disconnected. + DisconnectedPeer, +} + +impl Writeable for ClosureDescriptor { + fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + match self { + ClosureDescriptor::ForceClosed { peer_msg } => { + 0u8.write(writer)?; + if let Some(peer_msg) = peer_msg { + 0u8.write(writer)?; + let bytes = peer_msg.clone().into_bytes(); + (bytes.len() as u64).write(writer)?; + for b in bytes.iter() { + b.write(writer)?; + } + } else { + 1u8.write(writer)?; + } + } + ClosureDescriptor::CooperativeClosure => 1u8.write(writer)?, + ClosureDescriptor::CommitmentTxBroadcasted => 2u8.write(writer)?, + ClosureDescriptor::ProcessingError { err } => { + 3u8.write(writer)?; + let bytes = err.clone().into_bytes(); + (bytes.len() as u64).write(writer)?; + for b in bytes.iter() { + b.write(writer)?; + } + }, + ClosureDescriptor::DisconnectedPeer => 4u8.write(writer)?, + } + Ok(()) + } +} + +impl Readable for ClosureDescriptor { + fn read(reader: &mut R) -> Result { + Ok(match ::read(reader)? { + 0 => { + let peer_msg = match ::read(reader)? { + 0 => { + let bytes_len: u64 = Readable::read(reader)?; + let mut bytes: Vec = Vec::with_capacity(bytes_len as usize); + for _ in 0..bytes_len { + bytes.push(Readable::read(reader)?); + } + let err = String::from_utf8(bytes).unwrap(); + Some(err) + }, + 1 => None, + _ => return Err(DecodeError::InvalidValue), + }; + ClosureDescriptor::ForceClosed { peer_msg } + }, + 1 => ClosureDescriptor::CooperativeClosure, + 2 => ClosureDescriptor::CommitmentTxBroadcasted, + 3 => { + let bytes_len: u64 = Readable::read(reader)?; + let mut bytes: Vec = Vec::with_capacity(bytes_len as usize); + for _ in 0..bytes_len { + bytes.push(Readable::read(reader)?); + } + let err = String::from_utf8(bytes).unwrap(); + ClosureDescriptor::ProcessingError { err } + }, + 4 => 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 @@ -189,6 +279,18 @@ pub enum Event { /// transaction. claim_from_onchain_tx: bool, }, + /// Used to indicate that a channel with the given `channel_id` is in the process of closure. + /// Note that if you try to force-close multiple times a channel through + /// [`ChannelManager::force_close_channel`] before receiving the corresponding monitor + /// event for the broadcast of the commitment transaction, multiple `ChannelClosed` events + /// can be generated. + 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 { @@ -265,6 +367,12 @@ impl Writeable for Event { (2, claim_from_onchain_tx, required), }); }, + &Event::ChannelClosed { ref channel_id, ref err } => { + 9u8.write(writer)?; + channel_id.write(writer)?; + err.write(writer)?; + write_tlv_fields!(writer, {}); + }, } Ok(()) } @@ -378,6 +486,12 @@ impl MaybeReadable for Event { }; f() }, + 9u8 => { + let channel_id = Readable::read(reader)?; + let err = Readable::read(reader)?; + read_tlv_fields!(reader, {}); + Ok(Some(Event::ChannelClosed { channel_id, err})) + }, // 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)