Merge pull request #2942 from benthecarman/node-id-slice
authorElias Rohrer <dev@tnull.de>
Mon, 18 Mar 2024 09:13:00 +0000 (09:13 +0000)
committerGitHub <noreply@github.com>
Mon, 18 Mar 2024 09:13:00 +0000 (09:13 +0000)
Add NodeId::from_slice

1  2 
lightning/src/routing/gossip.rs

index 806aadd583c02491df9b87b1076a4166b65d71c1,281586edd36591f3bda4227fd70972d87c99a531..045772486ba7aa150636a1e7b5420a606e87ce64
@@@ -74,6 -74,16 +74,16 @@@ impl NodeId 
                NodeId(pubkey.serialize())
        }
  
+       /// Create a new NodeId from a slice of bytes
+       pub fn from_slice(bytes: &[u8]) -> Result<Self, DecodeError> {
+               if bytes.len() != PUBLIC_KEY_SIZE {
+                       return Err(DecodeError::InvalidValue);
+               }
+               let mut data = [0; PUBLIC_KEY_SIZE];
+               data.copy_from_slice(bytes);
+               Ok(NodeId(data))
+       }
        /// Get the public key slice from this NodeId
        pub fn as_slice(&self) -> &[u8] {
                &self.0
@@@ -1231,18 -1241,6 +1241,18 @@@ pub struct NodeInfo 
        pub announcement_info: Option<NodeAnnouncementInfo>
  }
  
 +impl NodeInfo {
 +      /// Returns whether the node has only announced Tor addresses.
 +      pub fn is_tor_only(&self) -> bool {
 +              self.announcement_info
 +                      .as_ref()
 +                      .map(|info| info.addresses())
 +                      .and_then(|addresses| (!addresses.is_empty()).then(|| addresses))
 +                      .map(|addresses| addresses.iter().all(|address| address.is_tor()))
 +                      .unwrap_or(false)
 +      }
 +}
 +
  impl fmt::Display for NodeInfo {
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                write!(f, " channels: {:?}, announcement_info: {:?}",
@@@ -2101,7 -2099,6 +2111,7 @@@ pub(crate) mod tests 
        use crate::ln::chan_utils::make_funding_redeemscript;
        #[cfg(feature = "std")]
        use crate::ln::features::InitFeatures;
 +      use crate::ln::msgs::SocketAddress;
        use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
        use crate::routing::utxo::{UtxoLookupError, UtxoResult};
        use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
                ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT};
        use crate::util::config::UserConfig;
        use crate::util::test_utils;
 -      use crate::util::ser::{ReadableArgs, Readable, Writeable};
 +      use crate::util::ser::{Hostname, ReadableArgs, Readable, Writeable};
        use crate::util::scid_utils::scid_from_parts;
  
        use crate::routing::gossip::REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS;
                let node_id = NodeId([42; 33]);
                assert_eq!(format!("{}", &node_id), "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a");
        }
 +
 +      #[test]
 +      fn is_tor_only_node() {
 +              let network_graph = create_network_graph();
 +              let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph);
 +
 +              let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
 +              let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
 +              let node_1_id = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey));
 +
 +              let announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
 +              gossip_sync.handle_channel_announcement(&announcement).unwrap();
 +
 +              let tcp_ip_v4 = SocketAddress::TcpIpV4 {
 +                      addr: [255, 254, 253, 252],
 +                      port: 9735
 +              };
 +              let tcp_ip_v6 = SocketAddress::TcpIpV6 {
 +                      addr: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
 +                      port: 9735
 +              };
 +              let onion_v2 = SocketAddress::OnionV2([255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 38, 7]);
 +              let onion_v3 = SocketAddress::OnionV3 {
 +                      ed25519_pubkey: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224],
 +                      checksum: 32,
 +                      version: 16,
 +                      port: 9735
 +              };
 +              let hostname = SocketAddress::Hostname {
 +                      hostname: Hostname::try_from(String::from("host")).unwrap(),
 +                      port: 9735,
 +              };
 +
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx);
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![
 +                                      tcp_ip_v4.clone(), tcp_ip_v6.clone(), onion_v2.clone(), onion_v3.clone(),
 +                                      hostname.clone()
 +                              ];
 +                              announcement.timestamp += 1000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![
 +                                      tcp_ip_v4.clone(), tcp_ip_v6.clone(), onion_v2.clone(), onion_v3.clone()
 +                              ];
 +                              announcement.timestamp += 2000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![
 +                                      tcp_ip_v6.clone(), onion_v2.clone(), onion_v3.clone()
 +                              ];
 +                              announcement.timestamp += 3000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![onion_v2.clone(), onion_v3.clone()];
 +                              announcement.timestamp += 4000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![onion_v2.clone()];
 +                              announcement.timestamp += 5000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +
 +              let announcement = get_signed_node_announcement(
 +                      |announcement| {
 +                              announcement.addresses = vec![tcp_ip_v4.clone()];
 +                              announcement.timestamp += 6000;
 +                      },
 +                      node_1_privkey, &secp_ctx
 +              );
 +              gossip_sync.handle_node_announcement(&announcement).unwrap();
 +              assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only());
 +      }
  }
  
  #[cfg(ldk_bench)]