Skip to content

Commit

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

Only messages from the disconnected peer are removed from the message queue. This prevents the dlc message handler from processing outdated messages due to retry logic.

The default implementation of the `OnionMessageHandler` and the `OnionMessageProvider` are copied from the `IgnoringMessageHandler`.
  • Loading branch information
holzeis committed Jun 28, 2023
1 parent 11c746f commit 51c3c3f
Show file tree
Hide file tree
Showing 2 changed files with 31 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
30 changes: 30 additions & 0 deletions dlc-messages/src/message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ 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) {
// In case the the peer is disconnected, but messages have already been received. It could happen that our retry logic interferes with
// pending unprocessed messages. see also https://github.com/get10101/10101/issues/792. To be on the safe side we are clearing any
// received, but unprocessed messages for that peer upon a disconnected.
self.clear_received_messages_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 +75,17 @@ impl MessageHandler {
ret
}

/// Clears all messages received by the given node.
pub fn clear_received_messages_by_node(&self, node: &PublicKey) {
let messages = &mut *self.msg_received.lock().unwrap();
let before = messages.len();
messages.retain(|(pubkey, message) | {
!(pubkey.eq(node) && (matches!(message, Message::SubChannel(SubChannelMessage::Confirm(_))) || matches!(message, Message::SubChannel(SubChannelMessage::CloseConfirm(_)))))
});
let message_count = before - messages.len();
log::warn!("Cleared {message_count} received messages from node: {node} after disconnect.");
}

/// 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 51c3c3f

Please sign in to comment.