Re-broadcast channel_announcements 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
This commit is contained in:
Matt Corallo 2024-10-13 17:14:23 +00:00
parent ad19d93180
commit 948f1794a2
2 changed files with 37 additions and 12 deletions

View file

@ -10216,22 +10216,47 @@ where
emit_channel_ready_event!(pending_events, channel);
}
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 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 let Some(height) = height_opt {
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.
update_msg: Some(self.get_channel_update_for_broadcast(channel).unwrap()),
});
}
}
}
if channel.is_our_channel_ready() {
if let Some(real_scid) = channel.context.get_short_channel_id() {

View 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"); };