From: Matt Corallo Date: Sun, 13 Oct 2024 17:14:23 +0000 (+0000) Subject: Re-broadcast `channel_announcement`s every six blocks for a week X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=948f1794a21a048e42ba47dff4f10316d6310e51;p=rust-lightning Re-broadcast `channel_announcement`s every six blocks for a week 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 --- diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index bdf67b5da..e0b8bcd7a 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -10216,23 +10216,48 @@ 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); + // 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. + let rebroadcast_announcement = funding_conf_height < height + 1008 + && funding_conf_height % 6 == height % 6; + #[allow(unused_mut, unused_assignments)] + let mut should_announce = announcement_sigs.is_some() || rebroadcast_announcement; + // 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 diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 22854952c..5e0bb25b6 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -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"); };