Add Event::ChannelClosed generation at channel shutdown

This commit is contained in:
Antoine Riard 2021-07-13 13:04:54 -04:00
parent 831f124721
commit e64467f512
2 changed files with 97 additions and 0 deletions

View file

@ -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,60 @@ pub enum PaymentPurpose {
SpontaneousPayment(PaymentPreimage),
}
#[derive(Clone, Debug, PartialEq)]
/// The reason the channel was closed. See individual variants more details.
pub enum ClosureReason {
/// Closure generated from receiving a peer error message.
///
/// Our counterparty may have broadcasted their latest commitment state, and we have
/// as well.
CounterpartyForceClosed {
/// The error which the peer sent us.
///
/// The string should be sanitized before it is used (e.g emitted to logs
/// or printed to stdout). Otherwise, a well crafted error message may exploit
/// a security vulnerability in the terminal emulator or the logging subsystem.
peer_msg: String,
},
/// Closure generated from [`ChannelManager::force_close_channel`], called by the user.
///
/// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel.
HolderForceClosed,
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
/// the cooperative close transaction. Note the shutdown may have been initiated by us.
//TODO: split between CounterpartyInitiated/LocallyInitiated
CooperativeClosure,
/// A commitment transaction was confirmed on chain, closing the channel. Most likely this
/// commitment transaction came from our counterparty, but it may also have come from
/// a copy of our own `ChannelMonitor`.
CommitmentTxConfirmed,
/// Closure generated from processing an event, likely a HTLC forward/relay/reception.
ProcessingError {
/// A developer-readable error message which we generated.
err: String,
},
/// The `PeerManager` informed us that we've disconnected from the peer. We close channels
/// if the `PeerManager` informed us that it is unlikely we'll be able to connect to the
/// peer again in the future or if the peer disconnected before we finished negotiating
/// the channel open. The first case may be caused by incompatible features which our
/// counterparty, or we, require.
//TODO: split between PeerUnconnectable/PeerDisconnected ?
DisconnectedPeer,
/// Closure generated from `ChannelManager::read` if the ChannelMonitor is newer than
/// the ChannelManager deserialized.
OutdatedChannelManager
}
impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
(0, CounterpartyForceClosed) => { (1, peer_msg, required) },
(2, HolderForceClosed) => {},
(6, CommitmentTxConfirmed) => {},
(4, CooperativeClosure) => {},
(8, ProcessingError) => { (1, err, required) },
(10, DisconnectedPeer) => {},
(12, OutdatedChannelManager) => {},
);
/// 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 +244,14 @@ 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.
ChannelClosed {
/// The channel_id of the channel which has been closed. Note that on-chain transactions
/// resolving the channel are likely still awaiting confirmation.
channel_id: [u8; 32],
/// The reason the channel was closed.
reason: ClosureReason
}
}
impl Writeable for Event {
@ -265,6 +328,13 @@ impl Writeable for Event {
(2, claim_from_onchain_tx, required),
});
},
&Event::ChannelClosed { ref channel_id, ref reason } => {
9u8.write(writer)?;
write_tlv_fields!(writer, {
(0, channel_id, required),
(2, reason, required)
});
},
}
Ok(())
}
@ -378,6 +448,16 @@ impl MaybeReadable for Event {
};
f()
},
9u8 => {
let mut channel_id = [0; 32];
let mut reason = None;
read_tlv_fields!(reader, {
(0, channel_id, required),
(2, reason, ignorable),
});
if reason.is_none() { return Ok(None); }
Ok(Some(Event::ChannelClosed { channel_id, reason: reason.unwrap() }))
},
// 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)

View file

@ -897,3 +897,20 @@ impl Readable for () {
Ok(())
}
}
impl Writeable for String {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
(self.len() as u16).write(w)?;
w.write_all(self.as_bytes())
}
}
impl Readable for String {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let v: Vec<u8> = Readable::read(r)?;
let ret = String::from_utf8(v).map_err(|_| DecodeError::InvalidValue)?;
Ok(ret)
}
}