Skip to content

Commit 4281e49

Browse files
authored
Merge pull request #4306 from tnull/2026-01-allow-empty-network-graph
`NetworkGraph`: Update chan/node estimation numbers, determine pre-allocation dynamically on read
2 parents 5a81e17 + 39ca7cb commit 4281e49

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

lightning/src/routing/gossip.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,9 +1682,17 @@ where
16821682
fn read<R: io::Read>(reader: &mut R, logger: L) -> Result<NetworkGraph<L>, DecodeError> {
16831683
let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
16841684

1685+
const MAX_CHAN_COUNT_LIMIT: usize = 100_000_000;
1686+
const MAX_NODE_COUNT_LIMIT: usize = 10_000_000;
1687+
16851688
let chain_hash: ChainHash = Readable::read(reader)?;
16861689
let channels_count: u64 = Readable::read(reader)?;
1687-
let mut channels = IndexedMap::with_capacity(CHAN_COUNT_ESTIMATE);
1690+
// Pre-allocate 115% of the known channel count to avoid unnecessary reallocations.
1691+
let channels_map_capacity = (channels_count as u128 * 115 / 100)
1692+
.try_into()
1693+
.map(|v: usize| v.min(MAX_CHAN_COUNT_LIMIT))
1694+
.map_err(|_| DecodeError::InvalidValue)?;
1695+
let mut channels = IndexedMap::with_capacity(channels_map_capacity);
16881696
for _ in 0..channels_count {
16891697
let chan_id: u64 = Readable::read(reader)?;
16901698
let chan_info: ChannelInfo = Readable::read(reader)?;
@@ -1696,7 +1704,12 @@ where
16961704
if nodes_count > u32::max_value() as u64 / 2 {
16971705
return Err(DecodeError::InvalidValue);
16981706
}
1699-
let mut nodes = IndexedMap::with_capacity(NODE_COUNT_ESTIMATE);
1707+
// Pre-allocate 115% of the known channel count to avoid unnecessary reallocations.
1708+
let nodes_map_capacity: usize = (nodes_count as u128 * 115 / 100)
1709+
.try_into()
1710+
.map(|v: usize| v.min(MAX_NODE_COUNT_LIMIT))
1711+
.map_err(|_| DecodeError::InvalidValue)?;
1712+
let mut nodes = IndexedMap::with_capacity(nodes_map_capacity);
17001713
for i in 0..nodes_count {
17011714
let node_id = Readable::read(reader)?;
17021715
let mut node_info: NodeInfo = Readable::read(reader)?;
@@ -1772,13 +1785,15 @@ where
17721785
}
17731786
}
17741787

1775-
// In Jan, 2025 there were about 49K channels.
1776-
// We over-allocate by a bit because 20% more is better than the double we get if we're slightly
1777-
// too low
1778-
const CHAN_COUNT_ESTIMATE: usize = 60_000;
1779-
// In Jan, 2025 there were about 15K nodes
1780-
// We over-allocate by a bit because 33% more is better than the double we get if we're slightly
1781-
// too low
1788+
/// In Jan, 2026 there were about 54K channels.
1789+
///
1790+
/// We over-allocate by a bit because ~15% more is better than the double we get if we're slightly
1791+
/// too low.
1792+
const CHAN_COUNT_ESTIMATE: usize = 63_000;
1793+
/// In Jan, 2026 there were about 17K nodes
1794+
///
1795+
/// We over-allocate by a bit because 15% more is better than the double we get if we're slightly
1796+
/// too low.
17821797
const NODE_COUNT_ESTIMATE: usize = 20_000;
17831798

17841799
impl<L: Deref> NetworkGraph<L>
@@ -1787,12 +1802,18 @@ where
17871802
{
17881803
/// Creates a new, empty, network graph.
17891804
pub fn new(network: Network, logger: L) -> NetworkGraph<L> {
1805+
let (node_map_cap, chan_map_cap) = if matches!(network, Network::Bitcoin) {
1806+
(NODE_COUNT_ESTIMATE, CHAN_COUNT_ESTIMATE)
1807+
} else {
1808+
(0, 0)
1809+
};
1810+
17901811
Self {
17911812
secp_ctx: Secp256k1::verification_only(),
17921813
chain_hash: ChainHash::using_genesis_block(network),
17931814
logger,
1794-
channels: RwLock::new(IndexedMap::with_capacity(CHAN_COUNT_ESTIMATE)),
1795-
nodes: RwLock::new(IndexedMap::with_capacity(NODE_COUNT_ESTIMATE)),
1815+
channels: RwLock::new(IndexedMap::with_capacity(chan_map_cap)),
1816+
nodes: RwLock::new(IndexedMap::with_capacity(node_map_cap)),
17961817
next_node_counter: AtomicUsize::new(0),
17971818
removed_node_counters: Mutex::new(Vec::new()),
17981819
last_rapid_gossip_sync_timestamp: Mutex::new(None),

0 commit comments

Comments
 (0)