From c578e4a346efb4361b53d18525bdb74de07cbae8 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 4 Sep 2018 20:16:06 -0400 Subject: [PATCH] Add ChannelManager-specific HandleError type and macro to use it Original macro is from Antoine Riard , the error type and additional mappings are from Matt Corallo --- src/ln/channelmanager.rs | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 956a08c98..f12c3f7ac 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -120,6 +120,32 @@ enum PendingOutboundHTLC { } } +struct MsgHandleErrInternal { + err: msgs::HandleError, + needs_channel_force_close: bool, +} +impl MsgHandleErrInternal { + #[inline] + fn send_err_msg_no_close(err: &'static str, channel_id: [u8; 32]) -> Self { + Self { + err: HandleError { + err, + action: Some(msgs::ErrorAction::SendErrorMessage { + msg: msgs::ErrorMessage { + channel_id, + data: err.to_string() + }, + }), + }, + needs_channel_force_close: false, + } + } + #[inline] + fn from_no_close(err: msgs::HandleError) -> Self { + Self { err, needs_channel_force_close: false } + } +} + /// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This /// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second /// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could @@ -1483,6 +1509,38 @@ impl ChainListener for ChannelManager { } } +macro_rules! handle_error { + ($self: ident, $internal: expr, $their_node_id: expr) => { + match $internal { + Ok(msg) => Ok(msg), + Err(MsgHandleErrInternal { err, needs_channel_force_close }) => { + if needs_channel_force_close { + match &err.action { + &Some(msgs::ErrorAction::DisconnectPeer { msg: Some(ref msg) }) => { + if msg.channel_id == [0; 32] { + $self.peer_disconnected(&$their_node_id, true); + } else { + $self.force_close_channel(&msg.channel_id); + } + }, + &Some(msgs::ErrorAction::DisconnectPeer { msg: None }) => {}, + &Some(msgs::ErrorAction::IgnoreError) => {}, + &Some(msgs::ErrorAction::SendErrorMessage { ref msg }) => { + if msg.channel_id == [0; 32] { + $self.peer_disconnected(&$their_node_id, true); + } else { + $self.force_close_channel(&msg.channel_id); + } + }, + &None => {}, + } + } + Err(err) + }, + } + } +} + impl ChannelMessageHandler for ChannelManager { //TODO: Handle errors and close channel (or so) fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result { -- 2.39.5