]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Re-broadcast `channel_announcement`s every six blocks for a week 2024-10-rebroadcast-chan-announcements
authorMatt Corallo <git@bluematt.me>
Sun, 13 Oct 2024 17:14:23 +0000 (17:14 +0000)
committerMatt Corallo <git@bluematt.me>
Sun, 13 Oct 2024 17:17:29 +0000 (17:17 +0000)
When we first get a public channel confirmed at six blocks, we
broadcast a `channel_announcement` once and then move on. As long
as it makes it into our local network graph that should be okay, as
we should send peers our network graph contents as they seek to
sync, however its possible an ill-timed shutdown could cause this
to fail, and relying on peers to do a full historical sync from us
may delay `channel_announcement` propagation.

Instead, here, we re-broadcast our `channel_announcement`s every
six blocks for a week, which should be way more than robust enough
to get them properly across the P2P network.

Fixes #2418

lightning/src/ln/channelmanager.rs
lightning/src/ln/priv_short_conf_tests.rs

index bdf67b5da7ce901d201d01ad43bbea5aee3f721d..bc262a61941a2a60865a65ef79373cf4fcd7b761 100644 (file)
@@ -10216,23 +10216,46 @@ where
                                                                        emit_channel_ready_event!(pending_events, channel);
                                                                }
 
-                                                               if let Some(announcement_sigs) = announcement_sigs {
-                                                                       log_trace!(logger, "Sending announcement_signatures for channel {}", channel.context.channel_id());
-                                                                       pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
-                                                                               node_id: channel.context.get_counterparty_node_id(),
-                                                                               msg: announcement_sigs,
-                                                                       });
-                                                                       if let Some(height) = height_opt {
-                                                                               if let Some(announcement) = channel.get_signed_channel_announcement(&self.node_signer, self.chain_hash, height, &self.default_configuration) {
+                                                               if let Some(height) = height_opt {
+                                                                       // (re-)broadcast signed `channel_announcement`s and
+                                                                       // `channel_update`s for any channels less than a week old.
+                                                                       let funding_conf_height =
+                                                                               channel.context.get_funding_tx_confirmation_height().unwrap_or(height);
+                                                                       let mut should_announce = announcement_sigs.is_some() || funding_conf_height < height + 1008;
+                                                                       // To avoid broadcast storms after each block, only
+                                                                       // re-broadcast every hour (6 blocks) after the initial
+                                                                       // broadcast, or if this is the first time we're ready to
+                                                                       // broadcast this channel.
+                                                                       should_announce &= announcement_sigs.is_some() || funding_conf_height % 6 == height % 6;
+                                                                       // Most of our tests were written when we only broadcasted
+                                                                       // `channel_announcement`s once and then never re-broadcasted
+                                                                       // them again, so disable the re-broadcasting entirely in tests
+                                                                       #[cfg(test)]
+                                                                       {
+                                                                               should_announce &= announcement_sigs.is_some();
+                                                                       }
+                                                                       if should_announce {
+                                                                               if let Some(announcement) = channel.get_signed_channel_announcement(
+                                                                                       &self.node_signer, self.chain_hash, height, &self.default_configuration,
+                                                                               ) {
                                                                                        pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
                                                                                                msg: announcement,
-                                                                                               // Note that announcement_signatures fails if the channel cannot be announced,
-                                                                                               // so get_channel_update_for_broadcast will never fail by the time we get here.
+                                                                                               // Note that get_signed_channel_announcement fails
+                                                                                               // if the channel cannot be announced, so
+                                                                                               // get_channel_update_for_broadcast will never fail
+                                                                                               // by the time we get here.
                                                                                                update_msg: Some(self.get_channel_update_for_broadcast(channel).unwrap()),
                                                                                        });
                                                                                }
                                                                        }
                                                                }
+                                                               if let Some(announcement_sigs) = announcement_sigs {
+                                                                       log_trace!(logger, "Sending announcement_signatures for channel {}", channel.context.channel_id());
+                                                                       pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
+                                                                               node_id: channel.context.get_counterparty_node_id(),
+                                                                               msg: announcement_sigs,
+                                                                       });
+                                                               }
                                                                if channel.is_our_channel_ready() {
                                                                        if let Some(real_scid) = channel.context.get_short_channel_id() {
                                                                                // If we sent a 0conf channel_ready, and now have an SCID, we add it
index 22854952c58fcc4ba1c4316ce4ef04e5a5390729..5e0bb25b627c65970b8b3e24ffaa47745697442e 100644 (file)
@@ -190,11 +190,11 @@ fn do_test_1_conf_open(connect_style: ConnectStyle) {
        connect_blocks(&nodes[1], 5);
        let bs_announce_events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(bs_announce_events.len(), 2);
-       let bs_announcement_sigs = if let MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } = bs_announce_events[0] {
+       let bs_announcement_sigs = if let MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } = bs_announce_events[1] {
                assert_eq!(*node_id, nodes[0].node.get_our_node_id());
                msg.clone()
        } else { panic!("Unexpected event"); };
-       let (bs_announcement, bs_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = bs_announce_events[1] {
+       let (bs_announcement, bs_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = bs_announce_events[0] {
                (msg.clone(), update_msg.clone().unwrap())
        } else { panic!("Unexpected event"); };