Handle monitor update failure during funding on the fundee side
[rust-lightning] / src / ln / channelmanager.rs
index 3336aa31d1b524df61d6d23f25d3d717cef43e50..afabcd7cc6bb30a294dcf8326d721ac718952e2d 100644 (file)
@@ -1684,7 +1684,7 @@ impl ChannelManager {
                                                        ChannelMonitorUpdateErr::TemporaryFailure => true,
                                                }
                                        } else {
-                                               let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe) = channel.monitor_updating_restored();
+                                               let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = 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));
                                                }
@@ -1722,6 +1722,19 @@ impl ChannelManager {
                                                                user_channel_id: channel.get_user_id(),
                                                        });
                                                }
+                                               if let Some(msg) = funding_locked {
+                                                       pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
+                                                               node_id: channel.get_their_node_id(),
+                                                               msg,
+                                                       });
+                                                       if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
+                                                               pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
+                                                                       node_id: channel.get_their_node_id(),
+                                                                       msg: announcement_sigs,
+                                                               });
+                                                       }
+                                                       short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
+                                               }
                                                true
                                        }
                                } else { true }
@@ -1790,7 +1803,7 @@ impl ChannelManager {
        }
 
        fn internal_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
-               let ((funding_msg, monitor_update), chan) = {
+               let ((funding_msg, monitor_update), mut chan) = {
                        let mut channel_lock = self.channel_state.lock().unwrap();
                        let channel_state = channel_lock.borrow_parts();
                        match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
@@ -1806,8 +1819,23 @@ 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(monitor_update.get_funding_txo().unwrap(), monitor_update) {
-                       unimplemented!();
+               if let Err(e) = self.monitor.add_update_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
+                       match e {
+                               ChannelMonitorUpdateErr::PermanentFailure => {
+                                       // Note that we reply with the new channel_id in error messages if we gave up on the
+                                       // channel, not the temporary_channel_id. This is compatible with ourselves, but the
+                                       // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
+                                       // any messages referencing a previously-closed channel anyway.
+                                       return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", funding_msg.channel_id, chan.force_shutdown(), None));
+                               },
+                               ChannelMonitorUpdateErr::TemporaryFailure => {
+                                       // There's no problem signing a counterparty's funding transaction if our monitor
+                                       // hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
+                                       // accepted payment from yet. We do, however, need to wait to send our funding_locked
+                                       // until we have persisted our monitor.
+                                       chan.monitor_update_failed(false, false, Vec::new(), Vec::new());
+                               },
+                       }
                }
                let mut channel_state_lock = self.channel_state.lock().unwrap();
                let channel_state = channel_state_lock.borrow_parts();