Skip to content

Commit

Permalink
fix: Clear certain unprocessed messages after peer disconnect
Browse files Browse the repository at this point in the history
The DLC message handler implements the `OnionMessageHandler` and
`OnionMessageProvider` to be able to hook onto the `peer_disconnected`
event. This allows for clearing certain `rust-dlc` messages precisely
when a disconnect happens.

We drop the `SubChannelConfirm` and `SubChannelCloseConfirm` messages
to avoid bugs such as the one reported here[1].

The rest of the implementations of `OnionMessageHandler` and
`OnionMessageProvider` is copied from the `IgnoringMessageHandler`.

[1]: get10101/10101#792.

Co-authored-by: Richard Holzeis <richard@holzeis.me>
  • Loading branch information
luckysori and holzeis committed Jul 17, 2023
1 parent 572afbb commit b32cc98
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions dlc-messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dlc = {version = "0.4.0", path = "../dlc"}
lightning = {version = "0.0.114"}
secp256k1-zkp = {version = "0.7.0", features = ["bitcoin_hashes", "rand", "rand-std"]}
serde = {version = "1.0", features = ["derive"], optional = true}
log = "0.4.14"

[dev-dependencies]
bitcoin = {version = "0.29.2"}
Expand Down
72 changes: 72 additions & 0 deletions dlc-messages/src/message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,46 @@ impl Default for MessageHandler {
}
}

impl lightning::util::events::OnionMessageProvider for MessageHandler {
fn next_onion_message_for_peer(
&self,
_peer_node_id: PublicKey,
) -> Option<lightning::ln::msgs::OnionMessage> {
None
}
}

impl lightning::ln::msgs::OnionMessageHandler for MessageHandler {
fn handle_onion_message(
&self,
_their_node_id: &PublicKey,
_msg: &lightning::ln::msgs::OnionMessage,
) {
}
fn peer_connected(
&self,
_their_node_id: &PublicKey,
_init: &lightning::ln::msgs::Init,
_inbound: bool,
) -> Result<(), ()> {
Ok(())
}

fn peer_disconnected(&self, their_node_id: &PublicKey) {
self.clear_pending_messages_sent_by_node(their_node_id);
}

fn provided_node_features(&self) -> lightning::ln::features::NodeFeatures {
lightning::ln::features::NodeFeatures::empty()
}
fn provided_init_features(
&self,
_their_node_id: &PublicKey,
) -> lightning::ln::features::InitFeatures {
lightning::ln::features::InitFeatures::empty()
}
}

impl MessageHandler {
/// Creates a new instance of a [`MessageHandler`]
pub fn new() -> Self {
Expand All @@ -56,6 +96,38 @@ impl MessageHandler {
ret
}

/// Drops certain pending messages sent by the remote node.
pub fn clear_pending_messages_sent_by_node(&self, disconnected_node_id: &PublicKey) {
let messages = &mut *self.msg_received.lock().unwrap();

messages.retain(|(node_id, message)| {
match message {
Message::SubChannel(SubChannelMessage::Confirm(message))
if node_id == disconnected_node_id =>
{
log::warn!(
"Dropping SubChannelConfirm message for channel {:?} \
after peer {node_id} disconnected",
message.channel_id
);
false
}
Message::SubChannel(SubChannelMessage::CloseConfirm(message))
if node_id == disconnected_node_id =>
{
log::warn!(
"Dropping SubChannelCloseConfirm message for channel {:?} \
after peer {node_id} disconnected",
message.channel_id
);
false
}
// Keep any other message
_ => true,
}
});
}

/// Send a message to the peer with given node id. Not that the message is not
/// sent right away, but only when the LDK
/// [`lightning::ln::peer_handler::PeerManager::process_events`] is next called.
Expand Down

0 comments on commit b32cc98

Please sign in to comment.