Delay creating outbound ChannelMonitor until funding_signed rcpt
[rust-lightning] / lightning / src / ln / channelmanager.rs
index f9ccc18a0c707b66773a7421e9115a3b329f57b9..0acc59df62e2ff33d1311bbf9be1e87846b70f39 100644 (file)
@@ -1412,7 +1412,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
        pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
                let _ = self.total_consistency_lock.read().unwrap();
 
-               let (mut chan, msg, chan_monitor) = {
+               let (chan, msg) = {
                        let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) {
                                Some(mut chan) => {
                                        (chan.get_outbound_funding_created(funding_txo)
@@ -1425,30 +1425,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                        };
                        match handle_error!(self, res, chan.get_their_node_id()) {
                                Ok(funding_msg) => {
-                                       (chan, funding_msg.0, funding_msg.1)
+                                       (chan, funding_msg)
                                },
                                Err(_) => { return; }
                        }
                };
-               // Because we have exclusive ownership of the channel here we can release the channel_state
-               // lock before add_monitor
-               if let Err(e) = self.monitor.add_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(true), None)), chan.get_their_node_id()) {
-                                               Err(_) => { 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();
                channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
@@ -1733,12 +1714,19 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                                        }
                                                                        if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat  {
                                                                                for htlc in htlcs.iter() {
+                                                                                       let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+                                                                                       htlc_msat_height_data.extend_from_slice(
+                                                                                               &byte_utils::be32_to_array(
+                                                                                                       self.latest_block_height.load(Ordering::Acquire)
+                                                                                                               as u32,
+                                                                                               ),
+                                                                                       );
                                                                                        failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                                        short_channel_id: htlc.prev_hop.short_channel_id,
                                                                                                        htlc_id: htlc.prev_hop.htlc_id,
                                                                                                        incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret,
                                                                                                }), payment_hash,
-                                                                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() }
+                                                                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }
                                                                                        ));
                                                                                }
                                                                        } else if total_value == data.total_msat {
@@ -1819,9 +1807,13 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                if let Some(mut sources) = removed_source {
                        for htlc in sources.drain(..) {
                                if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
+                               let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+                               htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
+                                       self.latest_block_height.load(Ordering::Acquire) as u32,
+                               ));
                                self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
                                                HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
-                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() });
+                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data });
                        }
                        true
                } else { false }
@@ -1845,9 +1837,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                match &onion_error {
                                        &HTLCFailReason::LightningError { ref err } => {
 #[cfg(test)]
-                                               let (channel_update, payment_retryable, onion_error_code) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+                                               let (channel_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
 #[cfg(not(test))]
-                                               let (channel_update, payment_retryable, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+                                               let (channel_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
                                                // TODO: If we decided to blame ourselves (or one of our channels) in
                                                // process_onion_failure we should close that channel as it implies our
                                                // next-hop is needlessly blaming us!
@@ -1863,13 +1855,17 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                                payment_hash: payment_hash.clone(),
                                                                rejected_by_dest: !payment_retryable,
 #[cfg(test)]
-                                                               error_code: onion_error_code
+                                                               error_code: onion_error_code,
+#[cfg(test)]
+                                                               error_data: onion_error_data
                                                        }
                                                );
                                        },
                                        &HTLCFailReason::Reason {
 #[cfg(test)]
                                                        ref failure_code,
+#[cfg(test)]
+                                                       ref data,
                                                        .. } => {
                                                // we get a fail_malformed_htlc from the first hop
                                                // TODO: We'd like to generate a PaymentFailureNetworkUpdate for temporary
@@ -1884,6 +1880,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                                rejected_by_dest: path.len() == 1,
 #[cfg(test)]
                                                                error_code: Some(*failure_code),
+#[cfg(test)]
+                                                               error_data: Some(data.clone()),
                                                        }
                                                );
                                        }
@@ -1982,12 +1980,13 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                        for htlc in sources.drain(..) {
                                if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
                                if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
-                                       let mut htlc_msat_data = byte_utils::be64_to_array(htlc.value).to_vec();
-                                       let mut height_data = byte_utils::be32_to_array(self.latest_block_height.load(Ordering::Acquire) as u32).to_vec();
-                                       htlc_msat_data.append(&mut height_data);
+                                       let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
+                                       htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
+                                               self.latest_block_height.load(Ordering::Acquire) as u32,
+                                       ));
                                        self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
                                                                         HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
-                                                                        HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_data });
+                                                                        HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data });
                                } else {
                                        match self.claim_funds_from_hop(channel_state.as_mut().unwrap(), htlc.prev_hop, payment_preimage) {
                                                Err(Some(e)) => {
@@ -2275,7 +2274,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                };
                // Because we have exclusive ownership of the channel here we can release the channel_state
                // lock before add_monitor
-               if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
+               if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo(), monitor_update) {
                        match e {
                                ChannelMonitorUpdateErr::PermanentFailure => {
                                        // Note that we reply with the new channel_id in error messages if we gave up on the
@@ -2319,17 +2318,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                        if chan.get().get_their_node_id() != *their_node_id {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
                                        }
-                                       let monitor_update = match chan.get_mut().funding_signed(&msg) {
-                                               Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan),
-                                               Err((Some(monitor_update), e)) => {
-                                                       assert!(chan.get().is_awaiting_monitor_update());
-                                                       let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update);
-                                                       try_chan_entry!(self, Err(e), channel_state, chan);
-                                                       unreachable!();
-                                               },
+                                       let monitor = match chan.get_mut().funding_signed(&msg) {
                                                Ok(update) => update,
+                                               Err(e) => try_chan_entry!(self, Err(e), channel_state, chan),
                                        };
-                                       if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
+                                       if let Err(e) = self.monitor.add_monitor(chan.get().get_funding_txo().unwrap(), monitor) {
                                                return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false);
                                        }
                                        (chan.get().get_funding_txo().unwrap(), chan.get().get_user_id())