@@ -72,7 +72,12 @@ const MAX_EXCESS_BYTES_FOR_RELAY: usize = 1024;
7272/// This value ensures a reply fits within the 65k payload limit and is consistent with other implementations.
7373const MAX_SCIDS_PER_REPLY : usize = 8000 ;
7474
75- /// Represents the compressed public key of a node
75+ /// A compressed pubkey which a node uses to sign announcements and decode HTLCs routed through it.
76+ ///
77+ /// This type stores a simple byte array which is not checked for validity (i.e. that it describes
78+ /// a point which lies on the secp256k1 curve), unlike [`PublicKey`], as validity checking would
79+ /// otherwise represent a large portion of [`NetworkGraph`] deserialization time (and RGS
80+ /// application).
7681#[ derive( Clone , Copy , PartialEq , Eq ) ]
7782pub struct NodeId ( [ u8 ; PUBLIC_KEY_SIZE ] ) ;
7883
@@ -1660,8 +1665,7 @@ where
16601665
16611666 let chain_hash: ChainHash = Readable :: read ( reader) ?;
16621667 let channels_count: u64 = Readable :: read ( reader) ?;
1663- // In Nov, 2023 there were about 15,000 nodes; we cap allocations to 1.5x that.
1664- let mut channels = IndexedMap :: with_capacity ( cmp:: min ( channels_count as usize , 22500 ) ) ;
1668+ let mut channels = IndexedMap :: with_capacity ( CHAN_COUNT_ESTIMATE ) ;
16651669 for _ in 0 ..channels_count {
16661670 let chan_id: u64 = Readable :: read ( reader) ?;
16671671 let chan_info: ChannelInfo = Readable :: read ( reader) ?;
@@ -1673,8 +1677,7 @@ where
16731677 if nodes_count > u32:: max_value ( ) as u64 / 2 {
16741678 return Err ( DecodeError :: InvalidValue ) ;
16751679 }
1676- // In Nov, 2023 there were about 69K channels; we cap allocations to 1.5x that.
1677- let mut nodes = IndexedMap :: with_capacity ( cmp:: min ( nodes_count as usize , 103500 ) ) ;
1680+ let mut nodes = IndexedMap :: with_capacity ( NODE_COUNT_ESTIMATE ) ;
16781681 for i in 0 ..nodes_count {
16791682 let node_id = Readable :: read ( reader) ?;
16801683 let mut node_info: NodeInfo = Readable :: read ( reader) ?;
@@ -1750,6 +1753,15 @@ where
17501753 }
17511754}
17521755
1756+ // In Jan, 2025 there were about 49K channels.
1757+ // We over-allocate by a bit because 20% more is better than the double we get if we're slightly
1758+ // too low
1759+ const CHAN_COUNT_ESTIMATE : usize = 60_000 ;
1760+ // In Jan, 2025 there were about 15K nodes
1761+ // We over-allocate by a bit because 33% more is better than the double we get if we're slightly
1762+ // too low
1763+ const NODE_COUNT_ESTIMATE : usize = 20_000 ;
1764+
17531765impl < L : Deref > NetworkGraph < L >
17541766where
17551767 L :: Target : Logger ,
@@ -1760,8 +1772,8 @@ where
17601772 secp_ctx : Secp256k1 :: verification_only ( ) ,
17611773 chain_hash : ChainHash :: using_genesis_block ( network) ,
17621774 logger,
1763- channels : RwLock :: new ( IndexedMap :: new ( ) ) ,
1764- nodes : RwLock :: new ( IndexedMap :: new ( ) ) ,
1775+ channels : RwLock :: new ( IndexedMap :: with_capacity ( CHAN_COUNT_ESTIMATE ) ) ,
1776+ nodes : RwLock :: new ( IndexedMap :: with_capacity ( NODE_COUNT_ESTIMATE ) ) ,
17651777 next_node_counter : AtomicUsize :: new ( 0 ) ,
17661778 removed_node_counters : Mutex :: new ( Vec :: new ( ) ) ,
17671779 last_rapid_gossip_sync_timestamp : Mutex :: new ( None ) ,
@@ -1992,8 +2004,8 @@ where
19922004 ///
19932005 /// All other parameters as used in [`msgs::UnsignedChannelAnnouncement`] fields.
19942006 pub fn add_channel_from_partial_announcement (
1995- & self , short_channel_id : u64 , timestamp : u64 , features : ChannelFeatures ,
1996- node_id_1 : PublicKey , node_id_2 : PublicKey ,
2007+ & self , short_channel_id : u64 , timestamp : u64 , features : ChannelFeatures , node_id_1 : NodeId ,
2008+ node_id_2 : NodeId ,
19972009 ) -> Result < ( ) , LightningError > {
19982010 if node_id_1 == node_id_2 {
19992011 return Err ( LightningError {
@@ -2002,13 +2014,11 @@ where
20022014 } ) ;
20032015 } ;
20042016
2005- let node_1 = NodeId :: from_pubkey ( & node_id_1) ;
2006- let node_2 = NodeId :: from_pubkey ( & node_id_2) ;
20072017 let channel_info = ChannelInfo {
20082018 features,
2009- node_one : node_1 . clone ( ) ,
2019+ node_one : node_id_1 ,
20102020 one_to_two : None ,
2011- node_two : node_2 . clone ( ) ,
2021+ node_two : node_id_2 ,
20122022 two_to_one : None ,
20132023 capacity_sats : None ,
20142024 announcement_message : None ,
@@ -2537,7 +2547,7 @@ where
25372547 }
25382548 } ;
25392549
2540- let node_pubkey;
2550+ let mut node_pubkey = None ;
25412551 {
25422552 let channels = self . channels . read ( ) . unwrap ( ) ;
25432553 match channels. get ( & msg. short_channel_id ) {
@@ -2556,16 +2566,31 @@ where
25562566 } else {
25572567 channel. node_one . as_slice ( )
25582568 } ;
2559- node_pubkey = PublicKey :: from_slice ( node_id) . map_err ( |_| LightningError {
2560- err : "Couldn't parse source node pubkey" . to_owned ( ) ,
2561- action : ErrorAction :: IgnoreAndLog ( Level :: Debug ) ,
2562- } ) ?;
2569+ if sig. is_some ( ) {
2570+ // PublicKey parsing isn't entirely trivial as it requires that we check
2571+ // that the provided point is on the curve. Thus, if we don't have a
2572+ // signature to verify, we want to skip the parsing step entirely.
2573+ // This represents a substantial speedup in applying RGS snapshots.
2574+ node_pubkey =
2575+ Some ( PublicKey :: from_slice ( node_id) . map_err ( |_| LightningError {
2576+ err : "Couldn't parse source node pubkey" . to_owned ( ) ,
2577+ action : ErrorAction :: IgnoreAndLog ( Level :: Debug ) ,
2578+ } ) ?) ;
2579+ }
25632580 } ,
25642581 }
25652582 }
25662583
2567- let msg_hash = hash_to_message ! ( & message_sha256d_hash( & msg) [ ..] ) ;
25682584 if let Some ( sig) = sig {
2585+ let msg_hash = hash_to_message ! ( & message_sha256d_hash( & msg) [ ..] ) ;
2586+ let node_pubkey = if let Some ( pubkey) = node_pubkey {
2587+ pubkey
2588+ } else {
2589+ debug_assert ! ( false , "node_pubkey should have been decoded above" ) ;
2590+ let err = "node_pubkey wasn't decoded but we need it to check a sig" . to_owned ( ) ;
2591+ let action = ErrorAction :: IgnoreAndLog ( Level :: Error ) ;
2592+ return Err ( LightningError { err, action } ) ;
2593+ } ;
25692594 secp_verify_sig ! ( self . secp_ctx, & msg_hash, & sig, & node_pubkey, "channel_update" ) ;
25702595 }
25712596
0 commit comments