Drop channels on disconnection if we haven't funded them yet 2018-09-initial-disconnect-drops
authorMatt Corallo <git@bluematt.me>
Fri, 7 Sep 2018 19:11:52 +0000 (15:11 -0400)
committerMatt Corallo <git@bluematt.me>
Wed, 12 Sep 2018 17:22:42 +0000 (13:22 -0400)
src/ln/channel.rs
src/ln/channelmanager.rs

index 51c92e80df04d096b728ca8d6a483e32a3f2825e..6d0329793d81eed3a98d62456e1b57e089c89f7e 100644 (file)
@@ -1771,6 +1771,13 @@ impl Channel {
        /// Returns the set of PendingHTLCStatuses from remote uncommitted HTLCs (which we're
        /// implicitly dropping) and the payment_hashes of HTLCs we tried to add but are dropping.
        pub fn remove_uncommitted_htlcs(&mut self) -> Vec<(HTLCSource, [u8; 32])> {
+               let mut outbound_drops = Vec::new();
+
+               if self.channel_state < ChannelState::FundingSent as u32 {
+                       self.channel_state = ChannelState::ShutdownComplete as u32;
+                       return outbound_drops;
+               }
+
                self.pending_inbound_htlcs.retain(|htlc| {
                        match htlc.state {
                                InboundHTLCState::RemoteAnnounced => {
@@ -1806,7 +1813,6 @@ impl Channel {
                        }
                }
 
-               let mut outbound_drops = Vec::new();
                self.holding_cell_htlc_updates.retain(|htlc_update| {
                        match htlc_update {
                                &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => {
index 89b297212f4c255715e3c756127aa646c11dea05..857f2f8c1d4b234a59ad56fdce158b3842c4c10d 100644 (file)
@@ -2149,16 +2149,23 @@ impl ChannelMessageHandler for ChannelManager {
                                        }
                                });
                        } else {
-                               for chan in channel_state.by_id {
-                                       if chan.1.get_their_node_id() == *their_node_id {
+                               channel_state.by_id.retain(|_, chan| {
+                                       if chan.get_their_node_id() == *their_node_id {
                                                //TODO: mark channel disabled (and maybe announce such after a timeout).
-                                               let failed_adds = chan.1.remove_uncommitted_htlcs();
+                                               let failed_adds = chan.remove_uncommitted_htlcs();
                                                if !failed_adds.is_empty() {
-                                                       let chan_update = self.get_channel_update(&chan.1).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
+                                                       let chan_update = self.get_channel_update(&chan).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
                                                        failed_payments.push((chan_update, failed_adds));
                                                }
+                                               if chan.is_shutdown() {
+                                                       if let Some(short_id) = chan.get_short_channel_id() {
+                                                               short_to_id.remove(&short_id);
+                                                       }
+                                                       return false;
+                                               }
                                        }
-                               }
+                                       true
+                               })
                        }
                }
                for failure in failed_channels.drain(..) {