From: Matt Corallo Date: Thu, 17 Mar 2022 22:14:43 +0000 (+0000) Subject: Send a `gossip_timestamp_filter` on connect to enable gossip sync X-Git-Tag: v0.0.106~18^2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=3cca221f8b41e9a42df748f972d14d851c826626;p=rust-lightning Send a `gossip_timestamp_filter` on connect to enable gossip sync On connection, if our peer supports gossip queries, and we never send a `gossip_timestamp_filter`, our peer is supposed to never send us gossip outside of explicit queries. Thus, we'll end up always having stale gossip information after the first few connections we make to peers. The solution is to send a dummy `gossip_timestamp_filter` immediately after connecting to peers. --- diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index f3913c51..3214bd4d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -5893,6 +5893,7 @@ impl &events::MessageSendEvent::SendChannelRangeQuery { .. } => false, &events::MessageSendEvent::SendShortIdsQuery { .. } => false, &events::MessageSendEvent::SendReplyChannelRange { .. } => false, + &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false, } }); } diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 9d79c638..4c4e22c0 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -1477,6 +1477,9 @@ impl P msg.sync_complete); self.enqueue_message(get_peer_for_forwarding!(node_id), msg); } + MessageSendEvent::SendGossipTimestampFilter { ref node_id, ref msg } => { + self.enqueue_message(get_peer_for_forwarding!(node_id), msg); + } } } diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 8f3511d6..e7c8271b 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -25,7 +25,7 @@ use chain; use chain::Access; use ln::features::{ChannelFeatures, NodeFeatures}; use ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT}; -use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, OptionalField}; +use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, OptionalField, GossipTimestampFilter}; use ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd}; use ln::msgs; use util::ser::{Writeable, Readable, Writer}; @@ -401,6 +401,22 @@ where C::Target: chain::Access, L::Target: Logger return (); } + // Send a gossip_timestamp_filter to enable gossip message receipt. Note that we have to + // use a "all timestamps" filter as sending the current timestamp would result in missing + // gossip messages that are simply sent late. We could calculate the intended filter time + // by looking at the current time and subtracting two weeks (before which we'll reject + // messages), but there's not a lot of reason to bother - our peers should be discarding + // the same messages. + let mut pending_events = self.pending_events.lock().unwrap(); + pending_events.push(MessageSendEvent::SendGossipTimestampFilter { + node_id: their_node_id.clone(), + msg: GossipTimestampFilter { + chain_hash: self.network_graph.genesis_hash, + first_timestamp: 0, + timestamp_range: u32::max_value(), + }, + }); + // Check if we need to perform a full synchronization with this peer if !self.should_request_full_sync(&their_node_id) { return (); @@ -409,7 +425,6 @@ where C::Target: chain::Access, L::Target: Logger let first_blocknum = 0; let number_of_blocks = 0xffffffff; log_debug!(self.logger, "Sending query_channel_range peer={}, first_blocknum={}, number_of_blocks={}", log_pubkey!(their_node_id), first_blocknum, number_of_blocks); - let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(MessageSendEvent::SendChannelRangeQuery { node_id: their_node_id.clone(), msg: QueryChannelRange { @@ -2280,8 +2295,17 @@ mod tests { let init_msg = Init { features: InitFeatures::known() }; net_graph_msg_handler.peer_connected(&node_id_1, &init_msg); let events = net_graph_msg_handler.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 1); + assert_eq!(events.len(), 2); match &events[0] { + MessageSendEvent::SendGossipTimestampFilter{ node_id, msg } => { + assert_eq!(node_id, &node_id_1); + assert_eq!(msg.chain_hash, chain_hash); + assert_eq!(msg.first_timestamp, 0); + assert_eq!(msg.timestamp_range, u32::max_value()); + }, + _ => panic!("Expected MessageSendEvent::SendChannelRangeQuery") + }; + match &events[1] { MessageSendEvent::SendChannelRangeQuery{ node_id, msg } => { assert_eq!(node_id, &node_id_1); assert_eq!(msg.chain_hash, chain_hash); @@ -2305,9 +2329,11 @@ mod tests { net_graph_msg_handler.peer_connected(&node_id, &init_msg); let events = net_graph_msg_handler.get_and_clear_pending_msg_events(); if n <= 5 { - assert_eq!(events.len(), 1); + assert_eq!(events.len(), 2); } else { - assert_eq!(events.len(), 0); + // Even after the we stop sending the explicit query, we should still send a + // gossip_timestamp_filter on each new connection. + assert_eq!(events.len(), 1); } } diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 3b90015c..623b2ea0 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -909,7 +909,15 @@ pub enum MessageSendEvent { node_id: PublicKey, /// The reply_channel_range which should be sent. msg: msgs::ReplyChannelRange, - } + }, + /// Sends a timestamp filter for inbound gossip. This should be sent on each new connection to + /// enable receiving gossip messages from the peer. + SendGossipTimestampFilter { + /// The node_id of this message recipient + node_id: PublicKey, + /// The gossip_timestamp_filter which should be sent. + msg: msgs::GossipTimestampFilter, + }, } /// A trait indicating an object may generate message send events