Skip to content

Commit f530de5

Browse files
committed
Track peer-disconnection in Channel and handle channel_reestablish
1 parent 9feb827 commit f530de5

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
@@ -1818,7 +1818,9 @@ impl Channel {
18181818
/// HTLCs that we intended to add but haven't as we were waiting on a remote revoke.
18191819
/// Returns the set of PendingHTLCStatuses from remote uncommitted HTLCs (which we're
18201820
/// implicitly dropping) and the payment_hashes of HTLCs we tried to add but are dropping.
1821-
pub fn remove_uncommitted_htlcs(&mut self) -> Vec<(HTLCSource, [u8; 32])> {
1821+
/// No further message handling calls may be made until a channel_reestablish dance has
1822+
/// completed.
1823+
pub fn remove_uncommitted_htlcs_and_mark_paused(&mut self) -> Vec<(HTLCSource, [u8; 32])> {
18221824
let mut outbound_drops = Vec::new();
18231825

18241826
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
@@ -1827,12 +1829,14 @@ impl Channel {
18271829
return outbound_drops;
18281830
}
18291831

1832+
let mut inbound_drop_count = 0;
18301833
self.pending_inbound_htlcs.retain(|htlc| {
18311834
match htlc.state {
18321835
InboundHTLCState::RemoteAnnounced => {
18331836
// They sent us an update_add_htlc but we never got the commitment_signed.
18341837
// We'll tell them what commitment_signed we're expecting next and they'll drop
18351838
// this HTLC accordingly
1839+
inbound_drop_count += 1;
18361840
false
18371841
},
18381842
InboundHTLCState::AwaitingRemoteRevokeToAnnounce|InboundHTLCState::AwaitingAnnouncedRemoteRevoke => {
@@ -1871,6 +1875,8 @@ impl Channel {
18711875
&HTLCUpdateAwaitingACK::ClaimHTLC {..} | &HTLCUpdateAwaitingACK::FailHTLC {..} => true,
18721876
}
18731877
});
1878+
self.channel_state |= ChannelState::PeerDisconnected as u32;
1879+
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()));
18741880
outbound_drops
18751881
}
18761882

@@ -1887,6 +1893,83 @@ impl Channel {
18871893
Ok(())
18881894
}
18891895

1896+
/// May panic if some calls other than message-handling calls (which will all Err immediately)
1897+
/// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
1898+
pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option<msgs::FundingLocked>, Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, Option<ChannelMonitor>), HandleError> {
1899+
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
1900+
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}})});
1901+
}
1902+
1903+
if msg.next_local_commitment_number == 0 || msg.next_local_commitment_number >= 0xffffffffffff ||
1904+
msg.next_remote_commitment_number == 0 || msg.next_remote_commitment_number >= 0xffffffffffff {
1905+
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}})});
1906+
}
1907+
1908+
// Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all
1909+
// remaining cases either succeed or ErrorMessage-fail).
1910+
self.channel_state &= !(ChannelState::PeerDisconnected as u32);
1911+
1912+
let mut required_revoke = None;
1913+
if msg.next_remote_commitment_number == 0xffffffffffff - self.cur_local_commitment_transaction_number {
1914+
} else if msg.next_remote_commitment_number == 0xfffffffffffe - self.cur_local_commitment_transaction_number {
1915+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number));
1916+
let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 2);
1917+
required_revoke = Some(msgs::RevokeAndACK {
1918+
channel_id: self.channel_id,
1919+
per_commitment_secret,
1920+
next_per_commitment_point,
1921+
});
1922+
} else {
1923+
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}})});
1924+
}
1925+
1926+
if msg.next_local_commitment_number == 0xffffffffffff - self.cur_remote_commitment_transaction_number {
1927+
if msg.next_remote_commitment_number == 0xffffffffffff - self.cur_local_commitment_transaction_number {
1928+
log_debug!(self, "Reconnected channel {} with no lost commitment txn", log_bytes!(self.channel_id()));
1929+
if msg.next_local_commitment_number == 1 && msg.next_remote_commitment_number == 1 {
1930+
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
1931+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
1932+
return Ok((Some(msgs::FundingLocked {
1933+
channel_id: self.channel_id(),
1934+
next_per_commitment_point: next_per_commitment_point,
1935+
}), None, None, None));
1936+
}
1937+
}
1938+
1939+
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
1940+
// We're up-to-date and not waiting on a remote revoke (if we are our
1941+
// channel_reestablish should result in them sending a revoke_and_ack), but we may
1942+
// have received some updates while we were disconnected. Free the holding cell
1943+
// now!
1944+
match self.free_holding_cell_htlcs() {
1945+
Err(e) => {
1946+
if let &Some(msgs::ErrorAction::DisconnectPeer{msg: Some(_)}) = &e.action {
1947+
} else if let &Some(msgs::ErrorAction::SendErrorMessage{msg: _}) = &e.action {
1948+
} else {
1949+
panic!("Got non-channel-failing result from free_holding_cell_htlcs");
1950+
}
1951+
return Err(e);
1952+
},
1953+
Ok(Some((commitment_update, channel_monitor))) => return Ok((None, required_revoke, Some(commitment_update), Some(channel_monitor))),
1954+
Ok(None) => return Ok((None, required_revoke, None, None)),
1955+
}
1956+
} else {
1957+
return Ok((None, required_revoke, None, None));
1958+
}
1959+
} else if msg.next_local_commitment_number == 0xfffffffffffe - self.cur_remote_commitment_transaction_number {
1960+
return Ok((None, required_revoke,
1961+
Some(msgs::CommitmentUpdate {
1962+
update_add_htlcs: Vec::new(),
1963+
update_fulfill_htlcs: Vec::new(),
1964+
update_fail_htlcs: Vec::new(),
1965+
update_fail_malformed_htlcs: Vec::new(),
1966+
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,
1967+
}), None));
1968+
} else {
1969+
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}})});
1970+
}
1971+
}
1972+
18901973
pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, [u8; 32])>), HandleError> {
18911974
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
18921975
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}})});
@@ -2159,6 +2242,11 @@ impl Channel {
21592242
res as u32
21602243
}
21612244

2245+
/// Returns true if we've ever received a message from the remote end for this Channel
2246+
pub fn have_received_message(&self) -> bool {
2247+
self.channel_state > (ChannelState::OurInitSent as u32)
2248+
}
2249+
21622250
/// Returns true if this channel is fully established and not known to be closing.
21632251
/// Allowed in any state (including after shutdown)
21642252
pub fn is_usable(&self) -> bool {
@@ -2449,6 +2537,18 @@ impl Channel {
24492537
Ok((msg, sig))
24502538
}
24512539

2540+
/// May panic if called on a channel that wasn't immediately-previously
2541+
/// self.remove_uncommitted_htlcs_and_mark_paused()'d
2542+
pub fn get_channel_reestablish(&self) -> msgs::ChannelReestablish {
2543+
assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32);
2544+
msgs::ChannelReestablish {
2545+
channel_id: self.channel_id(),
2546+
next_local_commitment_number: 0xffffffffffff - self.cur_local_commitment_transaction_number,
2547+
next_remote_commitment_number: 0xffffffffffff - self.cur_remote_commitment_transaction_number,
2548+
data_loss_protect: None,
2549+
}
2550+
}
2551+
24522552

24532553
// Send stuff to our remote peers:
24542554

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)