Fulfill error handling for send_commitment in processing htlcs forward
[rust-lightning] / src / ln / channelmanager.rs
index 2b22cbd89d0ec060d95f9d1a15793e2c733f607a..2edde1135db524cd8ce7585146437c0b07258422 100644 (file)
@@ -494,7 +494,10 @@ macro_rules! try_chan_entry {
                                                }
                                        }
                                }
-                               let mut shutdown_res = chan.force_shutdown(); // We drop closing transactions as they are toxic datas and MUST NOT be broadcast
+                               let mut shutdown_res = chan.force_shutdown();
+                               if shutdown_res.0.len() >= 1 {
+                                       log_error!($self, "You have a toxic local commitment transaction {} avaible in channel monitor, read comment in ChannelMonitor::get_latest_local_commitment_txn to be informed of manual action to take", shutdown_res.0[0].txid());
+                               }
                                shutdown_res.0.clear();
                                return Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, shutdown_res, $self.get_channel_update(&chan).ok()))
                        }
@@ -1367,12 +1370,39 @@ impl ChannelManager {
                                                        let (commitment_msg, monitor) = match chan.get_mut().send_commitment() {
                                                                Ok(res) => res,
                                                                Err(e) => {
-                                                                       if let ChannelError::Ignore(_) = e {
-                                                                               panic!("Stated return value requirements in send_commitment() were not met");
+                                                                       // We surely failed send_commitment due to bad keys, in that case
+                                                                       // close channel and then send error message to peer.
+                                                                       let their_node_id = chan.get().get_their_node_id();
+                                                                       let err: Result<(), _>  = match e {
+                                                                               ChannelError::Ignore(_) => {
+                                                                                       panic!("Stated return value requirements in send_commitment() were not met");
+                                                                               },
+                                                                               ChannelError::Close(msg) => {
+                                                                                       log_trace!(self, "Closing channel {} due to Close-required error: {}", log_bytes!(chan.key()[..]), msg);
+                                                                                       let (channel_id, mut channel) = chan.remove_entry();
+                                                                                       if let Some(short_id) = channel.get_short_channel_id() {
+                                                                                               channel_state.short_to_id.remove(&short_id);
+                                                                                       }
+                                                                                       Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, channel.force_shutdown(), self.get_channel_update(&channel).ok()))
+                                                                               },
+                                                                               ChannelError::CloseDelayBroadcast { .. } => { panic!("Wait is only generated on receipt of channel_reestablish, which is handled by try_chan_entry, we don't bother to support it here"); }
+                                                                       };
+                                                                       match handle_error!(self, err) {
+                                                                               Ok(_) => unreachable!(),
+                                                                               Err(e) => {
+                                                                                       if let Some(msgs::ErrorAction::IgnoreError) = e.action {
+                                                                                       } else {
+                                                                                               log_error!(self, "Got bad keys: {}!", e.err);
+                                                                                               let mut channel_state = self.channel_state.lock().unwrap();
+                                                                                               channel_state.pending_msg_events.push(events::MessageSendEvent::HandleError {
+                                                                                                       node_id: their_node_id,
+                                                                                                       action: e.action,
+                                                                                               });
+                                                                                       }
+                                                                                       continue;
+                                                                               },
                                                                        }
-                                                                       //TODO: Handle...this is bad!
-                                                                       continue;
-                                                               },
+                                                               }
                                                        };
                                                        if let Err(e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
                                                                handle_errors.push((chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true)));