Skip to content

Commit e32545a

Browse files
author
Antoine Riard
committed
Add Event::ChannelClosed generation at channel shutdown
1 parent 831f124 commit e32545a

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

lightning/src/util/events.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use chain::keysinterface::SpendableOutputDescriptor;
1818
use ln::msgs;
19+
use ln::msgs::DecodeError;
1920
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2021
use routing::network_graph::NetworkUpdate;
2122
use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
@@ -68,6 +69,60 @@ pub enum PaymentPurpose {
6869
SpontaneousPayment(PaymentPreimage),
6970
}
7071

72+
#[derive(Clone, Debug, PartialEq)]
73+
/// The reason the channel was closed. See individual variants more details.
74+
pub enum ClosureReason {
75+
/// Closure generated from receiving a peer error message.
76+
///
77+
/// Our counterparty may have broadcasted their latest commitment state, and we have
78+
/// as well.
79+
CounterpartyForceClosed {
80+
/// The error which the peer sent us.
81+
///
82+
/// The string should be sanitized before it is used (e.g emitted to logs
83+
/// or printed to stdout). Otherwise, a well crafted error message may exploit
84+
/// a security vulnerability in the terminal emulator or the logging subsystem.
85+
peer_msg: String,
86+
},
87+
/// Closure generated from [`ChannelManager::force_close_channel`], called by the user.
88+
///
89+
/// [`ChannelManager::force_close_channel`]: ln::channelmanager::ChannelManager::force_close_channel.
90+
HolderForceClosed,
91+
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
92+
/// the cooperative close transaction. Note the shutdown may have been initiated by us.
93+
//TODO: split between CounterpartyInitiated/LocallyInitiated
94+
CooperativeClosure,
95+
/// A commitment transaction was confirmed on chain, closing the channel. Most likely this
96+
/// commitment transaction came from our counterparty, but it may also have come from
97+
/// a copy of our own `ChannelMonitor`.
98+
CommitmentTxConfirmed,
99+
/// Closure generated from processing an event, likely a HTLC forward/relay/reception.
100+
ProcessingError {
101+
/// A developer-readable error message which we generated.
102+
err: String,
103+
},
104+
/// The `PeerManager` informed us that we've disconnected from the peer. We close channels
105+
/// if the `PeerManager` informed us that it is unlikely we'll be able to connect to the
106+
/// peer again in the future or if the peer disconnected before we finished negotiating
107+
/// the channel open. The first case may be caused by incompatible features which our
108+
/// counterparty, or we, require.
109+
//TODO: split between PeerUnconnectable/PeerDisconnected ?
110+
DisconnectedPeer,
111+
/// Closure generated from [`ChannelManager::read`] if the ChannelMonitor is newer than
112+
/// the ChannelManager deserialized.
113+
OutdatedChannelManager
114+
}
115+
116+
impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
117+
(0, CounterpartyForceClosed) => { (1, peer_msg, required) },
118+
(2, HolderForceClosed) => {},
119+
(6, CommitmentTxConfirmed) => {},
120+
(4, CooperativeClosure) => {},
121+
(8, ProcessingError) => { (1, err, required) },
122+
(10, DisconnectedPeer) => {},
123+
(12, OutdatedChannelManager) => {},
124+
);
125+
71126
/// An Event which you should probably take some action in response to.
72127
///
73128
/// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
@@ -189,6 +244,14 @@ pub enum Event {
189244
/// transaction.
190245
claim_from_onchain_tx: bool,
191246
},
247+
/// Used to indicate that a channel with the given `channel_id` is in the process of closure.
248+
ChannelClosed {
249+
/// The channel_id of the channel which has been closed. Note that on-chain transactions
250+
/// resolving the channel are likely still awaiting confirmation.
251+
channel_id: [u8; 32],
252+
/// The reason the channel was closed.
253+
reason: ClosureReason
254+
}
192255
}
193256

194257
impl Writeable for Event {
@@ -265,6 +328,13 @@ impl Writeable for Event {
265328
(2, claim_from_onchain_tx, required),
266329
});
267330
},
331+
&Event::ChannelClosed { ref channel_id, ref reason } => {
332+
9u8.write(writer)?;
333+
write_tlv_fields!(writer, {
334+
(0, channel_id, required),
335+
(2, reason, required)
336+
});
337+
},
268338
}
269339
Ok(())
270340
}
@@ -378,6 +448,16 @@ impl MaybeReadable for Event {
378448
};
379449
f()
380450
},
451+
9u8 => {
452+
let mut channel_id = [0; 32];
453+
let mut reason = None;
454+
read_tlv_fields!(reader, {
455+
(0, channel_id, required),
456+
(2, reason, ignorable),
457+
});
458+
if reason.is_none() { return Ok(None); }
459+
Ok(Some(Event::ChannelClosed { channel_id, reason: reason.unwrap() }))
460+
},
381461
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
382462
x if x % 2 == 1 => Ok(None),
383463
_ => Err(msgs::DecodeError::InvalidValue)

lightning/src/util/ser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,3 +897,20 @@ impl Readable for () {
897897
Ok(())
898898
}
899899
}
900+
901+
impl Writeable for String {
902+
#[inline]
903+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
904+
(self.len() as u16).write(w)?;
905+
w.write_all(self.as_bytes())
906+
}
907+
}
908+
909+
impl Readable for String {
910+
#[inline]
911+
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
912+
let v: Vec<u8> = Readable::read(r)?;
913+
let ret = String::from_utf8(v).map_err(|_| DecodeError::InvalidValue)?;
914+
Ok(ret)
915+
}
916+
}

0 commit comments

Comments
 (0)