Merge pull request #2492 from optout21/payment-hash-display
[rust-lightning] / lightning / src / routing / gossip.rs
index 5ac2f9ed6979c6509ca9b070d2f5a8f658a0081f..c15a7547b996e455bfc752b8befae2ab83b86c84 100644 (file)
@@ -10,7 +10,7 @@
 //! The [`NetworkGraph`] stores the network gossip and [`P2PGossipSync`] fetches it from peers
 
 use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
-use bitcoin::secp256k1::PublicKey;
+use bitcoin::secp256k1::{PublicKey, Verification};
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::secp256k1;
 
@@ -88,12 +88,12 @@ impl NodeId {
 
 impl fmt::Debug for NodeId {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-               write!(f, "NodeId({})", log_bytes!(self.0))
+               write!(f, "NodeId({})", crate::util::logger::DebugBytes(&self.0))
        }
 }
 impl fmt::Display for NodeId {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-               write!(f, "{}", log_bytes!(self.0))
+               crate::util::logger::DebugBytes(&self.0).fmt(f)
        }
 }
 
@@ -409,6 +409,29 @@ macro_rules! get_pubkey_from_node_id {
        }
 }
 
+/// Verifies the signature of a [`NodeAnnouncement`].
+///
+/// Returns an error if it is invalid.
+pub fn verify_node_announcement<C: Verification>(msg: &NodeAnnouncement, secp_ctx: &Secp256k1<C>) -> Result<(), LightningError> {
+       let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
+       secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &get_pubkey_from_node_id!(msg.contents.node_id, "node_announcement"), "node_announcement");
+
+       Ok(())
+}
+
+/// Verifies all signatures included in a [`ChannelAnnouncement`].
+///
+/// Returns an error if one of the signatures is invalid.
+pub fn verify_channel_announcement<C: Verification>(msg: &ChannelAnnouncement, secp_ctx: &Secp256k1<C>) -> Result<(), LightningError> {
+       let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
+       secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &get_pubkey_from_node_id!(msg.contents.node_id_1, "channel_announcement"), "channel_announcement");
+       secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &get_pubkey_from_node_id!(msg.contents.node_id_2, "channel_announcement"), "channel_announcement");
+       secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_1, "channel_announcement"), "channel_announcement");
+       secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_2, "channel_announcement"), "channel_announcement");
+
+       Ok(())
+}
+
 impl<G: Deref<Target=NetworkGraph<L>>, U: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, U, L>
 where U::Target: UtxoLookup, L::Target: Logger
 {
@@ -876,7 +899,7 @@ impl ChannelInfo {
 impl fmt::Display for ChannelInfo {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                write!(f, "features: {}, node_one: {}, one_to_two: {:?}, node_two: {}, two_to_one: {:?}",
-                  log_bytes!(self.features.encode()), log_bytes!(self.node_one.as_slice()), self.one_to_two, log_bytes!(self.node_two.as_slice()), self.two_to_one)?;
+                  log_bytes!(self.features.encode()), &self.node_one, self.one_to_two, &self.node_two, self.two_to_one)?;
                Ok(())
        }
 }
@@ -970,7 +993,7 @@ impl<'a> DirectedChannelInfo<'a> {
                                htlc_maximum_msat = cmp::min(htlc_maximum_msat, capacity_msat);
                                EffectiveCapacity::Total { capacity_msat, htlc_maximum_msat: htlc_maximum_msat }
                        },
-                       None => EffectiveCapacity::MaximumHTLC { amount_msat: htlc_maximum_msat },
+                       None => EffectiveCapacity::AdvertisedMaxHTLC { amount_msat: htlc_maximum_msat },
                };
 
                Self {
@@ -1024,7 +1047,7 @@ pub enum EffectiveCapacity {
                liquidity_msat: u64,
        },
        /// The maximum HTLC amount in one direction as advertised on the gossip network.
-       MaximumHTLC {
+       AdvertisedMaxHTLC {
                /// The maximum HTLC amount denominated in millisatoshi.
                amount_msat: u64,
        },
@@ -1038,6 +1061,11 @@ pub enum EffectiveCapacity {
        /// A capacity sufficient to route any payment, typically used for private channels provided by
        /// an invoice.
        Infinite,
+       /// The maximum HTLC amount as provided by an invoice route hint.
+       HintMaxHTLC {
+               /// The maximum HTLC amount denominated in millisatoshi.
+               amount_msat: u64,
+       },
        /// A capacity that is unknown possibly because either the chain state is unavailable to know
        /// the total capacity or the `htlc_maximum_msat` was not advertised on the gossip network.
        Unknown,
@@ -1052,8 +1080,9 @@ impl EffectiveCapacity {
        pub fn as_msat(&self) -> u64 {
                match self {
                        EffectiveCapacity::ExactLiquidity { liquidity_msat } => *liquidity_msat,
-                       EffectiveCapacity::MaximumHTLC { amount_msat } => *amount_msat,
+                       EffectiveCapacity::AdvertisedMaxHTLC { amount_msat } => *amount_msat,
                        EffectiveCapacity::Total { capacity_msat, .. } => *capacity_msat,
+                       EffectiveCapacity::HintMaxHTLC { amount_msat } => *amount_msat,
                        EffectiveCapacity::Infinite => u64::max_value(),
                        EffectiveCapacity::Unknown => UNKNOWN_CHANNEL_CAPACITY_MSAT,
                }
@@ -1114,26 +1143,26 @@ impl Writeable for NodeAnnouncementInfo {
                        (4, self.rgb, required),
                        (6, self.alias, required),
                        (8, self.announcement_message, option),
-                       (10, empty_addresses, vec_type), // Versions prior to 0.0.115 require this field
+                       (10, empty_addresses, required_vec), // Versions prior to 0.0.115 require this field
                });
                Ok(())
        }
 }
 
 impl Readable for NodeAnnouncementInfo {
-    fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
                _init_and_read_tlv_fields!(reader, {
                        (0, features, required),
                        (2, last_update, required),
                        (4, rgb, required),
                        (6, alias, required),
                        (8, announcement_message, option),
-                       (10, _addresses, vec_type), // deprecated, not used anymore
+                       (10, _addresses, optional_vec), // deprecated, not used anymore
                });
                let _: Option<Vec<NetAddress>> = _addresses;
                Ok(Self { features: features.0.unwrap(), last_update: last_update.0.unwrap(), rgb: rgb.0.unwrap(),
                        alias: alias.0.unwrap(), announcement_message })
-    }
+       }
 }
 
 /// A user-defined name for a node, which may be used when displaying the node in a graph.
@@ -1199,7 +1228,7 @@ impl Writeable for NodeInfo {
                write_tlv_fields!(writer, {
                        // Note that older versions of LDK wrote the lowest inbound fees here at type 0
                        (2, self.announcement_info, option),
-                       (4, self.channels, vec_type),
+                       (4, self.channels, required_vec),
                });
                Ok(())
        }
@@ -1230,19 +1259,17 @@ impl Readable for NodeInfo {
                // with zero inbound fees, causing that heuristic to provide little gain. Worse, because it
                // requires additional complexity and lookups during routing, it ends up being a
                // performance loss. Thus, we simply ignore the old field here and no longer track it.
-               let mut _lowest_inbound_channel_fees: Option<RoutingFees> = None;
-               let mut announcement_info_wrap: Option<NodeAnnouncementInfoDeserWrapper> = None;
-               _init_tlv_field_var!(channels, vec_type);
-
-               read_tlv_fields!(reader, {
+               _init_and_read_tlv_fields!(reader, {
                        (0, _lowest_inbound_channel_fees, option),
                        (2, announcement_info_wrap, upgradable_option),
-                       (4, channels, vec_type),
+                       (4, channels, required_vec),
                });
+               let _: Option<RoutingFees> = _lowest_inbound_channel_fees;
+               let announcement_info_wrap: Option<NodeAnnouncementInfoDeserWrapper> = announcement_info_wrap;
 
                Ok(NodeInfo {
                        announcement_info: announcement_info_wrap.map(|w| w.0),
-                       channels: _init_tlv_based_struct_field!(channels, vec_type),
+                       channels,
                })
        }
 }
@@ -1323,7 +1350,7 @@ impl<L: Deref> fmt::Display for NetworkGraph<L> where L::Target: Logger {
                }
                writeln!(f, "[Nodes]")?;
                for (&node_id, val) in self.nodes.read().unwrap().unordered_iter() {
-                       writeln!(f, " {}: {}", log_bytes!(node_id.as_slice()), val)?;
+                       writeln!(f, " {}: {}", &node_id, val)?;
                }
                Ok(())
        }
@@ -1397,8 +1424,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
        /// routing messages from a source using a protocol other than the lightning P2P protocol.
        pub fn update_node_from_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<(), LightningError> {
-               let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.signature, &get_pubkey_from_node_id!(msg.contents.node_id, "node_announcement"), "node_announcement");
+               verify_node_announcement(msg, &self.secp_ctx)?;
                self.update_node_from_announcement_intern(&msg.contents, Some(&msg))
        }
 
@@ -1461,11 +1487,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
        where
                U::Target: UtxoLookup,
        {
-               let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &get_pubkey_from_node_id!(msg.contents.node_id_1, "channel_announcement"), "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_2, &get_pubkey_from_node_id!(msg.contents.node_id_2, "channel_announcement"), "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_1, "channel_announcement"), "channel_announcement");
-               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_2, "channel_announcement"), "channel_announcement");
+               verify_channel_announcement(msg, &self.secp_ctx)?;
                self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), utxo_lookup)
        }
 
@@ -1531,6 +1553,8 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                let node_id_a = channel_info.node_one.clone();
                let node_id_b = channel_info.node_two.clone();
 
+               log_gossip!(self.logger, "Adding channel {} between nodes {} and {}", short_channel_id, node_id_a, node_id_b);
+
                match channels.entry(short_channel_id) {
                        IndexedMapEntry::Occupied(mut entry) => {
                                //TODO: because asking the blockchain if short_channel_id is valid is only optional
@@ -1585,7 +1609,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
 
                if msg.chain_hash != self.genesis_hash {
                        return Err(LightningError {
-                               err: "Channel announcement chain hash does not match genesis hash".to_owned(), 
+                               err: "Channel announcement chain hash does not match genesis hash".to_owned(),
                                action: ErrorAction::IgnoreAndLog(Level::Debug),
                        });
                }
@@ -1766,16 +1790,23 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                let mut scids_to_remove = Vec::new();
                for (scid, info) in channels.unordered_iter_mut() {
                        if info.one_to_two.is_some() && info.one_to_two.as_ref().unwrap().last_update < min_time_unix {
+                               log_gossip!(self.logger, "Removing directional update one_to_two (0) for channel {} due to its timestamp {} being below {}",
+                                       scid, info.one_to_two.as_ref().unwrap().last_update, min_time_unix);
                                info.one_to_two = None;
                        }
                        if info.two_to_one.is_some() && info.two_to_one.as_ref().unwrap().last_update < min_time_unix {
+                               log_gossip!(self.logger, "Removing directional update two_to_one (1) for channel {} due to its timestamp {} being below {}",
+                                       scid, info.two_to_one.as_ref().unwrap().last_update, min_time_unix);
                                info.two_to_one = None;
                        }
                        if info.one_to_two.is_none() || info.two_to_one.is_none() {
                                // We check the announcement_received_time here to ensure we don't drop
                                // announcements that we just received and are just waiting for our peer to send a
                                // channel_update for.
-                               if info.announcement_received_time < min_time_unix as u64 {
+                               let announcement_received_timestamp = info.announcement_received_time;
+                               if announcement_received_timestamp < min_time_unix as u64 {
+                                       log_gossip!(self.logger, "Removing channel {} because both directional updates are missing and its announcement timestamp {} being below {}",
+                                               scid, announcement_received_timestamp, min_time_unix);
                                        scids_to_remove.push(*scid);
                                }
                        }
@@ -1856,6 +1887,8 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        }
                }
 
+               log_gossip!(self.logger, "Updating channel {} in direction {} with timestamp {}", msg.short_channel_id, msg.flags & 1, msg.timestamp);
+
                let mut channels = self.channels.write().unwrap();
                match channels.get_mut(&msg.short_channel_id) {
                        None => {
@@ -2895,7 +2928,7 @@ pub(crate) mod tests {
 
                // It should ignore if gossip_queries feature is not enabled
                {
-                       let init_msg = Init { features: InitFeatures::empty(), remote_network_address: None };
+                       let init_msg = Init { features: InitFeatures::empty(), networks: None, remote_network_address: None };
                        gossip_sync.peer_connected(&node_id_1, &init_msg, true).unwrap();
                        let events = gossip_sync.get_and_clear_pending_msg_events();
                        assert_eq!(events.len(), 0);
@@ -2905,7 +2938,7 @@ pub(crate) mod tests {
                {
                        let mut features = InitFeatures::empty();
                        features.set_gossip_queries_optional();
-                       let init_msg = Init { features, remote_network_address: None };
+                       let init_msg = Init { features, networks: None, remote_network_address: None };
                        gossip_sync.peer_connected(&node_id_1, &init_msg, true).unwrap();
                        let events = gossip_sync.get_and_clear_pending_msg_events();
                        assert_eq!(events.len(), 1);
@@ -3396,6 +3429,12 @@ pub(crate) mod tests {
                // This serialized info has an address field but no announcement_message, therefore the addresses returned by our function will still be empty
                assert!(ann_info_with_addresses.addresses().is_empty());
        }
+
+       #[test]
+       fn test_node_id_display() {
+               let node_id = NodeId([42; 33]);
+               assert_eq!(format!("{}", &node_id), "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a");
+       }
 }
 
 #[cfg(ldk_bench)]