Add timer_chan_freshness_every_min
authorAntoine Riard <ariard@student.42.fr>
Mon, 18 Nov 2019 05:43:13 +0000 (00:43 -0500)
committerAntoine Riard <ariard@student.42.fr>
Fri, 29 Nov 2019 23:12:40 +0000 (18:12 -0500)
Latency/peer disconnection may trigger us to mark as disabled
some of our channels. After some time, if channels are still
disabled we need to broadcast ChannelUpdate to inform other network
peers about the uselessness of these channels.

lightning/src/ln/channelmanager.rs

index 0058eccd34a30e92e2237839a2ae9dcd18c96d0e..32ae66c7353970342bbc7d7ce442b65b35a8a70f 100644 (file)
@@ -318,6 +318,13 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum
 /// the "reorg path" (ie call block_disconnected() until you get to a common block and then call
 /// block_connected() to step towards your best block) upon deserialization before using the
 /// object!
+///
+/// Note that ChannelManager is responsible of tracking liveness of its channels and by so
+/// to generate ChannelUpdate messages intended to be broadcast on the gossip layer. To avoid
+/// spam due to quick connection/reconnection, updates should be first stagged then after a period
+/// of 1 min flushed to the network through call to timer_chan_freshness_every_min. You may
+/// delay or anticipate call to this method to suit your announcements requirements different than
+/// the 1 min period.
 pub struct ChannelManager<'a> {
        default_configuration: UserConfig,
        genesis_hash: Sha256dHash,
@@ -1487,6 +1494,30 @@ impl<'a> ChannelManager<'a> {
                events.append(&mut new_events);
        }
 
+       /// Latency/peer disconnection may trigger us to mark as disabled some
+       /// of our channels. After some time, if channels are still disabled
+       /// we need to broadcast ChannelUpdate to inform other network peers
+       /// about the uselessness of this channels.
+       pub fn timer_chan_freshness_every_min(&self) {
+               let _ = self.total_consistency_lock.read().unwrap();
+               let mut channel_state_lock = self.channel_state.lock().unwrap();
+               let channel_state = channel_state_lock.borrow_parts();
+               for (_, chan) in channel_state.by_id {
+                       if chan.is_disabled_staged() && !chan.is_live() {
+                               if let Ok(update) = self.get_channel_update(&chan) {
+                                       channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+                                               msg: update
+                                       });
+                               }
+                               chan.to_fresh();
+                       } else if chan.is_disabled_staged() && chan.is_live() {
+                               chan.to_fresh();
+                       } else if chan.is_disabled_marked() {
+                               chan.to_disabled_staged();
+                       }
+               }
+       }
+
        /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
        /// after a PaymentReceived event, failing the HTLC back to its origin and freeing resources
        /// along the path (including in our own channel on which we received it).
@@ -2795,8 +2826,8 @@ impl<'a> ChannelMessageHandler for ChannelManager<'a> {
                                log_debug!(self, "Marking channels with {} disconnected and generating channel_updates", log_pubkey!(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.remove_uncommitted_htlcs_and_mark_paused();
+                                               chan.to_disabled_marked();
                                                if !failed_adds.is_empty() {
                                                        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));