Handle monitor update failures during funding on the funder side
[rust-lightning] / src / ln / channelmanager.rs
index 10c5ce0a11cb2a8985f5e1e5d4f39a15e7b2e706..3336aa31d1b524df61d6d23f25d3d717cef43e50 100644 (file)
@@ -1131,7 +1131,7 @@ impl ChannelManager {
        pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
                let _ = self.total_consistency_lock.read().unwrap();
 
-               let (chan, msg, chan_monitor) = {
+               let (mut chan, msg, chan_monitor) = {
                        let (res, chan) = {
                                let mut channel_state = self.channel_state.lock().unwrap();
                                match channel_state.by_id.remove(temporary_channel_id) {
@@ -1162,8 +1162,30 @@ impl ChannelManager {
                };
                // Because we have exclusive ownership of the channel here we can release the channel_state
                // lock before add_update_monitor
-               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
-                       unimplemented!();
+               if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                       match e {
+                               ChannelMonitorUpdateErr::PermanentFailure => {
+                                       match handle_error!(self, Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", *temporary_channel_id, chan.force_shutdown(), None))) {
+                                               Err(e) => {
+                                                       log_error!(self, "Failed to store ChannelMonitor update for funding tx generation");
+                                                       let mut channel_state = self.channel_state.lock().unwrap();
+                                                       channel_state.pending_msg_events.push(events::MessageSendEvent::HandleError {
+                                                               node_id: chan.get_their_node_id(),
+                                                               action: e.action,
+                                                       });
+                                                       return;
+                                               },
+                                               Ok(()) => unreachable!(),
+                                       }
+                               },
+                               ChannelMonitorUpdateErr::TemporaryFailure => {
+                                       // Its completely fine to continue with a FundingCreated until the monitor
+                                       // update is persisted, as long as we don't generate the FundingBroadcastSafe
+                                       // until the monitor has been safely persisted (as funding broadcast is not,
+                                       // in fact, safe).
+                                       chan.monitor_update_failed(false, false, Vec::new(), Vec::new());
+                               },
+                       }
                }
 
                let mut channel_state = self.channel_state.lock().unwrap();
@@ -1627,6 +1649,7 @@ impl ChannelManager {
                let mut close_results = Vec::new();
                let mut htlc_forwards = Vec::new();
                let mut htlc_failures = Vec::new();
+               let mut pending_events = Vec::new();
                let _ = self.total_consistency_lock.read().unwrap();
 
                {
@@ -1661,7 +1684,7 @@ impl ChannelManager {
                                                        ChannelMonitorUpdateErr::TemporaryFailure => true,
                                                }
                                        } else {
-                                               let (raa, commitment_update, order, pending_forwards, mut pending_failures) = channel.monitor_updating_restored();
+                                               let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe) = channel.monitor_updating_restored();
                                                if !pending_forwards.is_empty() {
                                                        htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards));
                                                }
@@ -1693,12 +1716,20 @@ impl ChannelManager {
                                                                handle_cs!();
                                                        },
                                                }
+                                               if needs_broadcast_safe {
+                                                       pending_events.push(events::Event::FundingBroadcastSafe {
+                                                               funding_txo: channel.get_funding_txo().unwrap(),
+                                                               user_channel_id: channel.get_user_id(),
+                                                       });
+                                               }
                                                true
                                        }
                                } else { true }
                        });
                }
 
+               self.pending_events.lock().unwrap().append(&mut pending_events);
+
                for failure in htlc_failures.drain(..) {
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2);
                }
@@ -1806,8 +1837,8 @@ impl ChannelManager {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
                                        }
                                        let chan_monitor = try_chan_entry!(self, chan.get_mut().funding_signed(&msg), channel_state, chan);
-                                       if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
-                                               unimplemented!();
+                                       if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                                               return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false);
                                        }
                                        (chan.get().get_funding_txo().unwrap(), chan.get().get_user_id())
                                },