Skip to content

Commit 48d78fc

Browse files
committed
Track peer-disconnection in Channel and handle channel_reestablish
1 parent 96a6420 commit 48d78fc

File tree

2 files changed

+143
-6
lines changed

2 files changed

+143
-6
lines changed

src/ln/channel.rs

+101-1
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,9 @@ impl Channel {
18261826
/// HTLCs that we intended to add but haven't as we were waiting on a remote revoke.
18271827
/// Returns the set of PendingHTLCStatuses from remote uncommitted HTLCs (which we're
18281828
/// implicitly dropping) and the payment_hashes of HTLCs we tried to add but are dropping.
1829-
pub fn remove_uncommitted_htlcs(&mut self) -> Vec<(HTLCSource, [u8; 32])> {
1829+
/// No further message handling calls may be made until a channel_reestablish dance has
1830+
/// completed.
1831+
pub fn remove_uncommitted_htlcs_and_mark_paused(&mut self) -> Vec<(HTLCSource, [u8; 32])> {
18301832
let mut outbound_drops = Vec::new();
18311833

18321834
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
@@ -1835,12 +1837,14 @@ impl Channel {
18351837
return outbound_drops;
18361838
}
18371839

1840+
let mut inbound_drop_count = 0;
18381841
self.pending_inbound_htlcs.retain(|htlc| {
18391842
match htlc.state {
18401843
InboundHTLCState::RemoteAnnounced => {
18411844
// They sent us an update_add_htlc but we never got the commitment_signed.
18421845
// We'll tell them what commitment_signed we're expecting next and they'll drop
18431846
// this HTLC accordingly
1847+
inbound_drop_count += 1;
18441848
false
18451849
},
18461850
InboundHTLCState::AwaitingRemoteRevokeToAnnounce|InboundHTLCState::AwaitingAnnouncedRemoteRevoke => {
@@ -1879,6 +1883,8 @@ impl Channel {
18791883
&HTLCUpdateAwaitingACK::ClaimHTLC {..} | &HTLCUpdateAwaitingACK::FailHTLC {..} => true,
18801884
}
18811885
});
1886+
self.channel_state |= ChannelState::PeerDisconnected as u32;
1887+
log_debug!(self, "Peer disconnection resulted in {} remote-announced HTLC drops and {} waiting-to-locally-announced HTLC drops on channel {}", outbound_drops.len(), inbound_drop_count, log_bytes!(self.channel_id()));
18821888
outbound_drops
18831889
}
18841890

@@ -1895,6 +1901,83 @@ impl Channel {
18951901
Ok(())
18961902
}
18971903

1904+
/// May panic if some calls other than message-handling calls (which will all Err immediately)
1905+
/// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
1906+
pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, Option<ChannelMonitor>), HandleError> {
1907+
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
1908+
return Err(HandleError{err: "Peer sent a loose channel_reestablish not after reconnect", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent a loose channel_reestablish not after reconnect".to_string(), channel_id: msg.channel_id}})});
1909+
}
1910+
1911+
if msg.next_local_commitment_number == 0 || msg.next_local_commitment_number >= 0xffffffffffff ||
1912+
msg.next_remote_commitment_number == 0 || msg.next_remote_commitment_number >= 0xffffffffffff {
1913+
return Err(HandleError{err: "Peer send garbage channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer send garbage channel_reestablish".to_string(), channel_id: msg.channel_id}})});
1914+
}
1915+
1916+
// Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all
1917+
// remaining cases either succeed or ErrorMessage-fail).
1918+
self.channel_state &= !(ChannelState::PeerDisconnected as u32);
1919+
1920+
let mut required_revoke = None;
1921+
if msg.next_remote_commitment_number == 0xffffffffffff - self.cur_local_commitment_transaction_number {
1922+
} else if msg.next_remote_commitment_number == 0xfffffffffffe - self.cur_local_commitment_transaction_number {
1923+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number));
1924+
let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 2);
1925+
required_revoke = Some(msgs::RevokeAndACK {
1926+
channel_id: self.channel_id,
1927+
per_commitment_secret,
1928+
next_per_commitment_point,
1929+
});
1930+
} else {
1931+
return Err(HandleError{err: "Peer attempted to reestablish channel with a very old local commitment transaction", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer attempted to reestablish channel with a very old remote commitment transaction".to_string(), channel_id: msg.channel_id}})});
1932+
}
1933+
1934+
if msg.next_local_commitment_number == 0xffffffffffff - self.cur_remote_commitment_transaction_number {
1935+
if msg.next_remote_commitment_number == 0xffffffffffff - self.cur_local_commitment_transaction_number {
1936+
log_debug!(self, "Reconnected channel {} with no lost commitment txn", log_bytes!(self.channel_id()));
1937+
if msg.next_local_commitment_number == 1 && msg.next_remote_commitment_number == 1 {
1938+
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
1939+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
1940+
return Ok((Some(msgs::FundingLocked {
1941+
channel_id: self.channel_id(),
1942+
next_per_commitment_point: next_per_commitment_point,
1943+
}), None, None, None));
1944+
}
1945+
}
1946+
1947+
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
1948+
// We're up-to-date and not waiting on a remote revoke (if we are our
1949+
// channel_reestablish should result in them sending a revoke_and_ack), but we may
1950+
// have received some updates while we were disconnected. Free the holding cell
1951+
// now!
1952+
match self.free_holding_cell_htlcs() {
1953+
Err(e) => {
1954+
if let &Some(msgs::ErrorAction::DisconnectPeer{msg: Some(_)}) = &e.action {
1955+
} else if let &Some(msgs::ErrorAction::SendErrorMessage{msg: _}) = &e.action {
1956+
} else {
1957+
panic!("Got non-channel-failing result from free_holding_cell_htlcs");
1958+
}
1959+
return Err(e);
1960+
},
1961+
Ok(Some((commitment_update, channel_monitor))) => return Ok((None, required_revoke, Some(commitment_update), Some(channel_monitor))),
1962+
Ok(None) => return Ok((None, required_revoke, None, None)),
1963+
}
1964+
} else {
1965+
return Ok((None, required_revoke, None, None));
1966+
}
1967+
} else if msg.next_local_commitment_number == 0xfffffffffffe - self.cur_remote_commitment_transaction_number {
1968+
return Ok((None, required_revoke,
1969+
Some(msgs::CommitmentUpdate {
1970+
update_add_htlcs: Vec::new(),
1971+
update_fulfill_htlcs: Vec::new(),
1972+
update_fail_htlcs: Vec::new(),
1973+
update_fail_malformed_htlcs: Vec::new(),
1974+
commitment_signed: self.send_commitment_no_state_update().expect("It looks like we failed to re-generate a commitment_signed we had previously sent?").0,
1975+
}), None));
1976+
} else {
1977+
return Err(HandleError{err: "Peer attempted to reestablish channel with a very old remote commitment transaction", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer attempted to reestablish channel with a very old remote commitment transaction".to_string(), channel_id: msg.channel_id}})});
1978+
}
1979+
}
1980+
18981981
pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, [u8; 32])>), HandleError> {
18991982
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
19001983
return Err(HandleError{err: "Peer sent shutdown when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent shutdown when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})});
@@ -2167,6 +2250,11 @@ impl Channel {
21672250
res as u32
21682251
}
21692252

2253+
/// Returns true if we've ever received a message from the remote end for this Channel
2254+
pub fn have_received_message(&self) -> bool {
2255+
self.channel_state > (ChannelState::OurInitSent as u32)
2256+
}
2257+
21702258
/// Returns true if this channel is fully established and not known to be closing.
21712259
/// Allowed in any state (including after shutdown)
21722260
pub fn is_usable(&self) -> bool {
@@ -2457,6 +2545,18 @@ impl Channel {
24572545
Ok((msg, sig))
24582546
}
24592547

2548+
/// May panic if called on a channel that wasn't immediately-previously
2549+
/// self.remove_uncommitted_htlcs_and_mark_paused()'d
2550+
pub fn get_channel_reestablish(&self) -> msgs::ChannelReestablish {
2551+
assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32);
2552+
msgs::ChannelReestablish {
2553+
channel_id: self.channel_id(),
2554+
next_local_commitment_number: 0xffffffffffff - self.cur_local_commitment_transaction_number,
2555+
next_remote_commitment_number: 0xffffffffffff - self.cur_remote_commitment_transaction_number,
2556+
data_loss_protect: None,
2557+
}
2558+
}
2559+
24602560

24612561
// Send stuff to our remote peers:
24622562

src/ln/channelmanager.rs

+42-5
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,27 @@ impl ChannelManager {
19021902
Ok(())
19031903
}
19041904

1905-
1905+
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>), MsgHandleErrInternal> {
1906+
let (res, chan_monitor) = {
1907+
let mut channel_state = self.channel_state.lock().unwrap();
1908+
match channel_state.by_id.get_mut(&msg.channel_id) {
1909+
Some(chan) => {
1910+
if chan.get_their_node_id() != *their_node_id {
1911+
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
1912+
}
1913+
let (funding_locked, revoke_and_ack, commitment_update, channel_monitor) = chan.channel_reestablish(msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?;
1914+
(Ok((funding_locked, revoke_and_ack, commitment_update)), channel_monitor)
1915+
},
1916+
None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
1917+
}
1918+
};
1919+
if let Some(monitor) = chan_monitor {
1920+
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
1921+
unimplemented!();
1922+
}
1923+
}
1924+
res
1925+
}
19061926
}
19071927

19081928
impl events::EventsProvider for ChannelManager {
@@ -2124,7 +2144,7 @@ impl ChannelMessageHandler for ChannelManager {
21242144
}
21252145

21262146
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>), HandleError> {
2127-
Ok((None, None, None))
2147+
handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id)
21282148
}
21292149

21302150
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
@@ -2156,7 +2176,7 @@ impl ChannelMessageHandler for ChannelManager {
21562176
channel_state.by_id.retain(|_, chan| {
21572177
if chan.get_their_node_id() == *their_node_id {
21582178
//TODO: mark channel disabled (and maybe announce such after a timeout).
2159-
let failed_adds = chan.remove_uncommitted_htlcs();
2179+
let failed_adds = chan.remove_uncommitted_htlcs_and_mark_paused();
21602180
if !failed_adds.is_empty() {
21612181
let chan_update = self.get_channel_update(&chan).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
21622182
failed_payments.push((chan_update, failed_adds));
@@ -2188,8 +2208,25 @@ impl ChannelMessageHandler for ChannelManager {
21882208
}
21892209
}
21902210

2191-
fn peer_connected(&self, _their_node_id: &PublicKey) -> Vec<msgs::ChannelReestablish> {
2192-
Vec::new()
2211+
fn peer_connected(&self, their_node_id: &PublicKey) -> Vec<msgs::ChannelReestablish> {
2212+
let mut res = Vec::new();
2213+
let mut channel_state = self.channel_state.lock().unwrap();
2214+
channel_state.by_id.retain(|_, chan| {
2215+
if chan.get_their_node_id() == *their_node_id {
2216+
if !chan.have_received_message() {
2217+
// If we created this (outbound) channel while we were disconnected from the
2218+
// peer we probably failed to send the open_channel message, which is now
2219+
// lost. We can't have had anything pending related to this channel, so we just
2220+
// drop it.
2221+
false
2222+
} else {
2223+
res.push(chan.get_channel_reestablish());
2224+
true
2225+
}
2226+
} else { true }
2227+
});
2228+
//TODO: Also re-broadcast announcement_signatures
2229+
res
21932230
}
21942231

21952232
fn handle_error(&self, their_node_id: &PublicKey, msg: &msgs::ErrorMessage) {

0 commit comments

Comments
 (0)