From a3247abb4e9a13bf6b4817c7ce7a571d1d3e0063 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 25 Aug 2018 14:48:18 -0400 Subject: [PATCH] Handle Error messages by closing channels as required by BOLT 1 --- src/ln/channelmanager.rs | 12 ++++++++++++ src/ln/msgs.rs | 4 +++- src/ln/peer_handler.rs | 19 ++++++++++++++++++- src/util/test_utils.rs | 1 + 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index a360c376..3a98cd5a 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -2053,6 +2053,18 @@ impl ChannelMessageHandler for ChannelManager { } } } + + fn handle_error(&self, their_node_id: &PublicKey, msg: &msgs::ErrorMessage) { + if msg.channel_id == [0; 32] { + for chan in self.list_channels() { + if chan.remote_network_id == *their_node_id { + self.force_close_channel(&chan.channel_id); + } + } + } else { + self.force_close_channel(&msg.channel_id); + } + } } #[cfg(test)] diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index c3b99756..4500ee2f 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -439,12 +439,14 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync { // Channel-to-announce: fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>; - // Informational: + // Error conditions: /// Indicates a connection to the peer failed/an existing connection was lost. If no connection /// is believed to be possible in the future (eg they're sending us messages we don't /// understand or indicate they require unknown feature bits), no_connection_possible is set /// and any outstanding channels should be failed. fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool); + + fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage); } pub trait RoutingMessageHandler : Send + Sync { diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 53788b3f..f941f47d 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -431,7 +431,24 @@ impl PeerManager { } }, 17 => { - // Error msg + let msg = try_potential_decodeerror!(msgs::ErrorMessage::decode(&msg_data[2..])); + let mut data_is_printable = true; + for b in msg.data.bytes() { + if b < 32 || b > 126 { + data_is_printable = false; + break; + } + } + + if data_is_printable { + log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); + } else { + log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); + } + self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); + if msg.channel_id == [0; 32] { + return Err(PeerHandleError{ no_connection_possible: true }); + } }, 18 => { diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index aff84735..dc158230 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -115,6 +115,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { Err(HandleError { err: "", action: None }) } fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {} + fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {} } impl events::EventsProvider for TestChannelMessageHandler { -- 2.30.2