Merge pull request #1524 from ViktorTigerstrom/2022-06-update-fail-holding-cell-htlcs...
[rust-lightning] / lightning / src / ln / channelmanager.rs
index 1d43fa0a460f96ec33a9a5d094a72fb9884ac53c..3fa136e9af862403f5957dd245c53d6951ccf3b1 100644 (file)
@@ -3620,7 +3620,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        // Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be
        // failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to
        // be surfaced to the user.
-       fn fail_holding_cell_htlcs(&self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32]) {
+       fn fail_holding_cell_htlcs(
+               &self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32],
+               _counterparty_node_id: &PublicKey
+       ) {
                for (htlc_src, payment_hash) in htlcs_to_fail.drain(..) {
                        match htlc_src {
                                HTLCSource::PreviousHopData(HTLCPreviousHopData { .. }) => {
@@ -4214,6 +4217,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
        /// with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call.
        ///
+       /// Note that this method will return an error and reject the channel, if it requires support
+       /// for zero confirmations. Instead, `accept_inbound_channel_from_trusted_peer_0conf` must be
+       /// used to accept such channels.
+       ///
        /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
        /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
        pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
@@ -4255,7 +4262,20 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                if *counterparty_node_id != channel.get().get_counterparty_node_id() {
                                        return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() });
                                }
-                               if accept_0conf { channel.get_mut().set_0conf(); }
+                               if accept_0conf {
+                                       channel.get_mut().set_0conf();
+                               } else if channel.get().get_channel_type().requires_zero_conf() {
+                                       let send_msg_err_event = events::MessageSendEvent::HandleError {
+                                               node_id: channel.get().get_counterparty_node_id(),
+                                               action: msgs::ErrorAction::SendErrorMessage{
+                                                       msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), }
+                                               }
+                                       };
+                                       channel_state.pending_msg_events.push(send_msg_err_event);
+                                       let _ = remove_channel!(self, channel_state, channel);
+                                       return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() });
+                               }
+
                                channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                        node_id: channel.get().get_counterparty_node_id(),
                                        msg: channel.get_mut().accept_inbound_channel(user_channel_id),
@@ -4297,6 +4317,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        },
                        hash_map::Entry::Vacant(entry) => {
                                if !self.default_configuration.manually_accept_inbound_channels {
+                                       if channel.get_channel_type().requires_zero_conf() {
+                                               return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
+                                       }
                                        channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                                node_id: counterparty_node_id.clone(),
                                                msg: channel.accept_inbound_channel(0),
@@ -4808,7 +4831,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
                        }
                };
-               self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id);
+               self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
                match res {
                        Ok((pending_forwards, mut pending_failures, finalized_claim_htlcs,
                                short_channel_id, channel_outpoint)) =>
@@ -4948,7 +4971,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        }
                };
                post_handle_chan_restoration!(self, chan_restoration_res);
-               self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id);
+               self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id, counterparty_node_id);
 
                if let Some(channel_ready_msg) = need_lnd_workaround {
                        self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?;
@@ -5046,7 +5069,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                match chan.maybe_free_holding_cell_htlcs(&self.logger) {
                                        Ok((commitment_opt, holding_cell_failed_htlcs)) => {
                                                if !holding_cell_failed_htlcs.is_empty() {
-                                                       failed_htlcs.push((holding_cell_failed_htlcs, *channel_id));
+                                                       failed_htlcs.push((
+                                                               holding_cell_failed_htlcs,
+                                                               *channel_id,
+                                                               chan.get_counterparty_node_id()
+                                                       ));
                                                }
                                                if let Some((commitment_update, monitor_update)) = commitment_opt {
                                                        if let Err(e) = self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
@@ -5074,8 +5101,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                }
 
                let has_update = has_monitor_update || !failed_htlcs.is_empty() || !handle_errors.is_empty();
-               for (failures, channel_id) in failed_htlcs.drain(..) {
-                       self.fail_holding_cell_htlcs(failures, channel_id);
+               for (failures, channel_id, counterparty_node_id) in failed_htlcs.drain(..) {
+                       self.fail_holding_cell_htlcs(failures, channel_id, &counterparty_node_id);
                }
 
                for (counterparty_node_id, err) in handle_errors.drain(..) {
@@ -7338,8 +7365,8 @@ mod tests {
                        final_cltv_expiry_delta: TEST_FINAL_CLTV,
                };
                let route = find_route(
-                       &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None,
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(),
+                       None, nodes[0].logger, &scorer, &random_seed_bytes
                ).unwrap();
                nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
                check_added_monitors!(nodes[0], 1);
@@ -7369,8 +7396,8 @@ mod tests {
                // To start (2), send a keysend payment but don't claim it.
                let payment_preimage = PaymentPreimage([42; 32]);
                let route = find_route(
-                       &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None,
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(),
+                       None, nodes[0].logger, &scorer, &random_seed_bytes
                ).unwrap();
                let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
                check_added_monitors!(nodes[0], 1);
@@ -7433,8 +7460,9 @@ mod tests {
                let scorer = test_utils::TestScorer::with_penalty(0);
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
-                       &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &payer_pubkey, &route_params, &network_graph.read_only(),
+                       Some(&first_hops.iter().collect::<Vec<_>>()), nodes[0].logger, &scorer,
+                       &random_seed_bytes
                ).unwrap();
 
                let test_preimage = PaymentPreimage([42; 32]);
@@ -7477,8 +7505,9 @@ mod tests {
                let scorer = test_utils::TestScorer::with_penalty(0);
                let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
                let route = find_route(
-                       &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &payer_pubkey, &route_params, &network_graph.read_only(),
+                       Some(&first_hops.iter().collect::<Vec<_>>()), nodes[0].logger, &scorer,
+                       &random_seed_bytes
                ).unwrap();
 
                let test_preimage = PaymentPreimage([42; 32]);
@@ -7670,7 +7699,7 @@ pub mod bench {
                        _ => panic!(),
                }
 
-               let dummy_graph = NetworkGraph::new(genesis_hash);
+               let dummy_graph = NetworkGraph::new(genesis_hash, &logger_a);
 
                let mut payment_count: u64 = 0;
                macro_rules! send_payment {