You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Send bogus ChannelReestablish for unknown channels
Unfortunately, lnd doesn't force close on errors
(https://github.com/lightningnetwork/lnd/blob/abb1e3463f3a83bbb843d5c399869dbe930ad94f/htlcswitch/link.go#L2119).
One of the few ways to get an lnd counterparty to force close is by
replicating what they do when restoring static channel backups (SCBs).
They send an invalid `ChannelReestablish` with `0` commitment numbers
and an invalid `your_last_per_commitment_secret`.
Since we received a `ChannelReestablish` for a channel that doesn't
exist, we can assume it's likely the channel closed from our point of
view, but it remains open on the counterparty's side. By sending this
bogus `ChannelReestablish` message now as a response to theirs, we
trigger them to force close broadcasting their latest state. If the
closing transaction from our point of view remains unconfirmed, it'll
enter a race with the counterparty's to-be-broadcast latest commitment
transaction.
Copy file name to clipboardExpand all lines: lightning/src/ln/channelmanager.rs
+96-2
Original file line number
Diff line number
Diff line change
@@ -6785,7 +6785,10 @@ where
6785
6785
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
6786
6786
.ok_or_else(|| {
6787
6787
debug_assert!(false);
6788
-
MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
6788
+
MsgHandleErrInternal::send_err_msg_no_close(
6789
+
format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id),
6790
+
msg.channel_id
6791
+
)
6789
6792
})?;
6790
6793
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
6791
6794
let peer_state = &mut *peer_state_lock;
@@ -6829,7 +6832,41 @@ where
6829
6832
"Got a channel_reestablish message for an unfunded channel!".into())), chan_phase_entry);
6830
6833
}
6831
6834
},
6832
-
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
6835
+
hash_map::Entry::Vacant(_) => {
6836
+
log_debug!(self.logger, "Sending bogus ChannelReestablish for unknown channel {} to force channel closure",
6837
+
log_bytes!(msg.channel_id.0));
6838
+
// Unfortunately, lnd doesn't force close on errors
assert_eq!(msg.data, format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}",&nodes[1].node.get_our_node_id()));
assert_eq!(msg.data, format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}",&nodes[1].node.get_our_node_id()));
0 commit comments