From: Matt Corallo Date: Wed, 31 Oct 2018 01:47:56 +0000 (-0400) Subject: Fail incoming HTLCs sent after we start shutdown, not the chan X-Git-Tag: v0.0.12~278^2~3 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=78232f2aeded08b32fa4ebfeb0b77d80b337518d;p=rust-lightning Fail incoming HTLCs sent after we start shutdown, not the chan --- diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 9d58caf9a..e0768e37c 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -1553,6 +1553,12 @@ impl Channel { //TODO: Check msg.cltv_expiry further? Do this in channel manager? + if self.channel_state & ChannelState::LocalShutdownSent as u32 != 0 { + if let PendingHTLCStatus::Forward(_) = pending_forward_state { + panic!("ChannelManager shouldn't be trying to add a forwardable HTLC after we've started closing"); + } + } + // Now update local state: self.next_remote_htlc_id += 1; self.pending_inbound_htlcs.push(InboundHTLCOutput { diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 28444d75a..80f0d9635 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1929,7 +1929,7 @@ impl ChannelManager { //encrypted with the same key. Its not immediately obvious how to usefully exploit that, //but we should prevent it anyway. - let (pending_forward_info, mut channel_state_lock) = self.decode_update_add_htlc_onion(msg); + let (mut pending_forward_info, mut channel_state_lock) = self.decode_update_add_htlc_onion(msg); let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.get_mut(&msg.channel_id) { @@ -1939,7 +1939,16 @@ impl ChannelManager { return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); } if !chan.is_usable() { - return Err(MsgHandleErrInternal::from_no_close(HandleError{err: "Channel not yet available for receiving HTLCs", action: Some(msgs::ErrorAction::IgnoreError)})); + // If the update_add is completely bogus, the call will Err and we will close, + // but if we've sent a shutdown and they haven't acknowledged it yet, we just + // want to reject the new HTLC and fail it backwards instead of forwarding. + if let PendingHTLCStatus::Forward(PendingForwardHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info { + pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { + channel_id: msg.channel_id, + htlc_id: msg.htlc_id, + reason: ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &self.get_channel_update(chan).unwrap().encode_with_len()[..]), + })); + } } chan.update_add_htlc(&msg, pending_forward_info).map_err(|e| MsgHandleErrInternal::from_maybe_close(e)) },