From 57872b9cff8f629d48bb7fee06c3b2f857c7e737 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 21 Jul 2025 11:51:37 -0500 Subject: [PATCH] discovery: make gossip filter semaphore capacity configurable In this commit, we make the gossip filter semaphore capacity configurable through a new FilterConcurrency field. This change allows node operators to tune the number of concurrent gossip filter applications based on their node's resources and network position. The previous hard-coded limit of 5 concurrent filter applications could become a bottleneck when multiple peers attempt to synchronize simultaneously. By making this value configurable via the new gossip.filter-concurrency option, operators can increase this limit for better performance on well-resourced nodes or maintain conservative values on resource-constrained systems. We keep the default value at 5 to maintain backward compatibility and avoid unexpected resource usage increases for existing deployments. The sample configuration file is updated to document this new option. --- discovery/sync_manager.go | 18 ++++++++++++++---- lncfg/gossip.go | 3 +++ sample-lnd.conf | 6 ++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/discovery/sync_manager.go b/discovery/sync_manager.go index 4dbc0d96d..c52fec8a2 100644 --- a/discovery/sync_manager.go +++ b/discovery/sync_manager.go @@ -25,8 +25,9 @@ const ( // network as possible. DefaultHistoricalSyncInterval = time.Hour - // filterSemaSize is the capacity of gossipFilterSema. - filterSemaSize = 5 + // DefaultFilterConcurrency is the default maximum number of concurrent + // gossip filter applications that can be processed. + DefaultFilterConcurrency = 5 // DefaultMsgBytesBurst is the allotted burst in bytes we'll permit. // This is the most that can be sent in a given go. Requests beyond @@ -136,6 +137,10 @@ type SyncManagerCfg struct { // AllotedMsgBytesBurst is the amount of burst bytes we'll permit, if // we've exceeded the hard upper limit. AllotedMsgBytesBurst uint64 + + // FilterConcurrency is the maximum number of concurrent gossip filter + // applications that can be processed. If not set, defaults to 5. + FilterConcurrency int } // SyncManager is a subsystem of the gossiper that manages the gossip syncers @@ -207,8 +212,13 @@ type SyncManager struct { // newSyncManager constructs a new SyncManager backed by the given config. func newSyncManager(cfg *SyncManagerCfg) *SyncManager { - filterSema := make(chan struct{}, filterSemaSize) - for i := 0; i < filterSemaSize; i++ { + filterConcurrency := cfg.FilterConcurrency + if filterConcurrency == 0 { + filterConcurrency = DefaultFilterConcurrency + } + + filterSema := make(chan struct{}, filterConcurrency) + for i := 0; i < filterConcurrency; i++ { filterSema <- struct{}{} } diff --git a/lncfg/gossip.go b/lncfg/gossip.go index 3c49001c4..0c297e324 100644 --- a/lncfg/gossip.go +++ b/lncfg/gossip.go @@ -37,9 +37,12 @@ type Gossip struct { MsgRateBytes uint64 `long:"msg-rate-bytes" description:"The total rate of outbound gossip messages, expressed in bytes per second. This setting controls the long-term average speed of gossip traffic sent from your node. The rate limit is applied globally across all peers, not per-peer. If the rate of outgoing messages exceeds this value, lnd will start to queue and delay messages to stay within the limit."` MsgBurstBytes uint64 `long:"msg-burst-bytes" description:"The maximum burst of outbound gossip data, in bytes, that can be sent at once. This works in conjunction with gossip.msg-rate-bytes as part of a token bucket rate-limiting scheme. This value represents the size of the token bucket. It allows for short, high-speed bursts of traffic, with the long-term rate controlled by gossip.msg-rate-bytes. This value must be larger than the maximum lightning message size (~65KB) to allow sending large gossip messages."` + + FilterConcurrency int `long:"filter-concurrency" description:"The maximum number of concurrent gossip filter applications that can be processed. If not set, defaults to 5."` } // Parse the pubkeys for the pinned syncers. + func (g *Gossip) Parse() error { pinnedSyncers := make(discovery.PinnedSyncers) for _, pubkeyStr := range g.PinnedSyncersRaw { diff --git a/sample-lnd.conf b/sample-lnd.conf index 93c96b8f6..e764cbf10 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -1776,6 +1776,12 @@ ; maximum lightning message size (~65KB) to allow sending large gossip messages. ; gossip.msg-burst-bytes=2048000 +; The maximum number of concurrent gossip filter applications that can be +; processed. Increase this value to handle more simultaneous peer +; synchronizations at the cost of additional resource usage. +; See docs/gossip_rate_limiting.md for mor information. +; gossip.filter-concurrency=5 + [invoices] ; If a hold invoice has accepted htlcs that reach their expiry height and are