Add gossip_queries feature flag
authorbmancini55 <bmancini@gmail.com>
Wed, 21 Oct 2020 20:31:22 +0000 (16:31 -0400)
committerbmancini55 <bmancini@gmail.com>
Tue, 1 Dec 2020 22:18:24 +0000 (17:18 -0500)
Support for the gossip_queries feature flag (bits 6/7) is added to the
Features struct. This feature is available in the Init and Node
contexts. The gossip_queries feature is not fully implemented so this
feature is disabled when sent to peers in the Init message.

lightning/src/ln/features.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/wire.rs

index f573ac4c43abd910c96764e123913901a3af1f2e..0c3c360189f3049fe0b3b55e18b63293061b7775 100644 (file)
@@ -104,7 +104,7 @@ mod sealed {
                ],
                optional_features: [
                        // Byte 0
-                       DataLossProtect | InitialRoutingSync | UpfrontShutdownScript,
+                       DataLossProtect | InitialRoutingSync | UpfrontShutdownScript | GossipQueries,
                        // Byte 1
                        VariableLengthOnion | PaymentSecret,
                        // Byte 2
@@ -122,7 +122,7 @@ mod sealed {
                ],
                optional_features: [
                        // Byte 0
-                       DataLossProtect | UpfrontShutdownScript,
+                       DataLossProtect | UpfrontShutdownScript | GossipQueries,
                        // Byte 1
                        VariableLengthOnion | PaymentSecret,
                        // Byte 2
@@ -243,6 +243,8 @@ mod sealed {
                "Feature flags for `initial_routing_sync`.");
        define_feature!(5, UpfrontShutdownScript, [InitContext, NodeContext],
                "Feature flags for `option_upfront_shutdown_script`.");
+       define_feature!(7, GossipQueries, [InitContext, NodeContext],
+               "Feature flags for `gossip_queries`.");
        define_feature!(9, VariableLengthOnion, [InitContext, NodeContext],
                "Feature flags for `var_onion_optin`.");
        define_feature!(13, StaticRemoteKey, [InitContext, NodeContext],
@@ -473,6 +475,21 @@ impl<T: sealed::UpfrontShutdownScript> Features<T> {
        }
 }
 
+
+impl<T: sealed::GossipQueries> Features<T> {
+       #[cfg(test)]
+       pub(crate) fn requires_gossip_queries(&self) -> bool {
+               <T as sealed::GossipQueries>::requires_feature(&self.flags)
+       }
+       pub(crate) fn supports_gossip_queries(&self) -> bool {
+               <T as sealed::GossipQueries>::supports_feature(&self.flags)
+       }
+       pub(crate) fn clear_gossip_queries(mut self) -> Self {
+               <T as sealed::GossipQueries>::clear_bits(&mut self.flags);
+               self
+       }
+}
+
 impl<T: sealed::VariableLengthOnion> Features<T> {
        #[cfg(test)]
        pub(crate) fn requires_variable_length_onion(&self) -> bool {
@@ -568,6 +585,11 @@ mod tests {
                assert!(!InitFeatures::known().requires_upfront_shutdown_script());
                assert!(!NodeFeatures::known().requires_upfront_shutdown_script());
 
+               assert!(InitFeatures::known().supports_gossip_queries());
+               assert!(NodeFeatures::known().supports_gossip_queries());
+               assert!(!InitFeatures::known().requires_gossip_queries());
+               assert!(!NodeFeatures::known().requires_gossip_queries());
+
                assert!(InitFeatures::known().supports_data_loss_protect());
                assert!(NodeFeatures::known().supports_data_loss_protect());
                assert!(!InitFeatures::known().requires_data_loss_protect());
@@ -620,9 +642,10 @@ mod tests {
 
        #[test]
        fn convert_to_context_with_relevant_flags() {
-               let init_features = InitFeatures::known().clear_upfront_shutdown_script();
+               let init_features = InitFeatures::known().clear_upfront_shutdown_script().clear_gossip_queries();
                assert!(init_features.initial_routing_sync());
                assert!(!init_features.supports_upfront_shutdown_script());
+               assert!(!init_features.supports_gossip_queries());
 
                let node_features: NodeFeatures = init_features.to_context();
                {
@@ -639,8 +662,10 @@ mod tests {
                // Check that cleared flags are kept blank when converting back:
                // - initial_routing_sync was not applicable to NodeContext
                // - upfront_shutdown_script was cleared before converting
+               // - gossip_queries was cleared before converting
                let features: InitFeatures = node_features.to_context_internal();
                assert!(!features.initial_routing_sync());
                assert!(!features.supports_upfront_shutdown_script());
+               assert!(!init_features.supports_gossip_queries());
        }
 }
index 6e997e53b156770d237bfbe615eff0096b77c17a..1e57177a0d626f32679472ebf7b60ade27b6fdaf 100644 (file)
@@ -584,7 +584,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<D
 
                                                                        peer.their_node_id = Some(their_node_id);
                                                                        insert_node_id!();
-                                                                       let mut features = InitFeatures::known();
+                                                                       let mut features = InitFeatures::known().clear_gossip_queries();
                                                                        if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) {
                                                                                features.clear_initial_routing_sync();
                                                                        }
@@ -694,10 +694,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<D
                                }
 
                                log_info!(
-                                       self.logger, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, static_remote_key: {}, unknown flags (local and global): {}",
+                                       self.logger, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, gossip_queries: {}, static_remote_key: {}, unknown flags (local and global): {}",
                                        if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"},
                                        if msg.features.initial_routing_sync() { "requested" } else { "not requested" },
                                        if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"},
+                                       if msg.features.supports_gossip_queries() { "supported" } else { "not supported" },
                                        if msg.features.supports_static_remote_key() { "supported" } else { "not supported"},
                                        if msg.features.supports_unknown_bits() { "present" } else { "none" }
                                );
@@ -712,7 +713,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<D
                                }
 
                                if !peer.outbound {
-                                       let mut features = InitFeatures::known();
+                                       let mut features = InitFeatures::known().clear_gossip_queries();
                                        if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) {
                                                features.clear_initial_routing_sync();
                                        }
index 86d8bfdd494e5ffad0bd7a67ff361009f4aa5bb5..6de11ea06d88930377384feed70f5eb2b026af14 100644 (file)
@@ -415,24 +415,25 @@ mod tests {
        fn read_lnd_init_msg() {
                // Taken from lnd v0.9.0-beta.
                let buffer = vec![0, 16, 0, 2, 34, 0, 0, 3, 2, 162, 161];
-               check_init_msg(buffer);
+               check_init_msg(buffer, false);
        }
 
        #[test]
        fn read_clightning_init_msg() {
                // Taken from c-lightning v0.8.0.
                let buffer = vec![0, 16, 0, 2, 34, 0, 0, 3, 2, 170, 162, 1, 32, 6, 34, 110, 70, 17, 26, 11, 89, 202, 175, 18, 96, 67, 235, 91, 191, 40, 195, 79, 58, 94, 51, 42, 31, 199, 178, 183, 60, 241, 136, 145, 15];
-               check_init_msg(buffer);
+               check_init_msg(buffer, true);
        }
 
-       fn check_init_msg(buffer: Vec<u8>) {
+       fn check_init_msg(buffer: Vec<u8>, expect_unknown: bool) {
                let mut reader = ::std::io::Cursor::new(buffer);
                let decoded_msg = read(&mut reader).unwrap();
                match decoded_msg {
                        Message::Init(msgs::Init { features }) => {
                                assert!(features.supports_variable_length_onion());
                                assert!(features.supports_upfront_shutdown_script());
-                               assert!(features.supports_unknown_bits());
+                               assert!(features.supports_gossip_queries());
+                               assert_eq!(expect_unknown, features.supports_unknown_bits());
                                assert!(!features.requires_unknown_bits());
                                assert!(!features.initial_routing_sync());
                        },
@@ -450,7 +451,7 @@ mod tests {
                        Message::NodeAnnouncement(msgs::NodeAnnouncement { contents: msgs::UnsignedNodeAnnouncement { features, ..}, ..}) => {
                                assert!(features.supports_variable_length_onion());
                                assert!(features.supports_upfront_shutdown_script());
-                               assert!(features.supports_unknown_bits());
+                               assert!(features.supports_gossip_queries());
                                assert!(!features.requires_unknown_bits());
                        },
                        _ => panic!("Expected node announcement, found message type: {}", decoded_msg.type_id())