},
}),
},
+ ChannelError::CloseDelayBroadcast { msg, .. } => HandleError {
+ err: msg,
+ action: Some(msgs::ErrorAction::SendErrorMessage {
+ msg: msgs::ErrorMessage {
+ channel_id,
+ data: msg.to_string()
+ },
+ }),
+ },
},
shutdown_finish: None,
}
}
break Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
},
+ Err(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"); }
}
}
}
}
return Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
},
+ Err(ChannelError::CloseDelayBroadcast { msg, update }) => {
+ log_error!($self, "Channel {} need to be shutdown but closing transactions not broadcast due to {}", log_bytes!($entry.key()[..]), msg);
+ let (channel_id, mut chan) = $entry.remove_entry();
+ if let Some(short_id) = chan.get_short_channel_id() {
+ $channel_state.short_to_id.remove(&short_id);
+ }
+ if let Some(update) = update {
+ if let Err(e) = $self.monitor.add_update_monitor(update.get_funding_txo().unwrap(), update) {
+ match e {
+ // Upstream channel is dead, but we want at least to fail backward HTLCs to save
+ // downstream channels. In case of PermanentFailure, we are not going to be able
+ // to claim back to_remote output on remote commitment transaction. Doesn't
+ // make a difference here, we are concern about HTLCs circuit, not onchain funds.
+ ChannelMonitorUpdateErr::PermanentFailure => {},
+ ChannelMonitorUpdateErr::TemporaryFailure => {},
+ }
+ }
+ }
+ 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()))
+ }
}
}
}
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)));