fix(blockexchange): cleanup stale lastSentWants entries to prevent memory leak

Stale entries in peer.lastSentWants were not removed when blocks were
resolved or cancelled, causing unbounded memory growth. This adds
incremental cleanup during refreshBlockKnowledge, removing up to 2048
stale entries per refresh cycle with proper event loop yielding.

Part of https://github.com/codex-storage/nim-codex/issues/974

Signed-off-by: Chrysostomos Nanakos <chris@include.gr>
This commit is contained in:
Chrysostomos Nanakos 2025-11-03 16:49:31 +02:00
parent ff7ac829c4
commit 86ce276a90
No known key found for this signature in database

View File

@ -93,6 +93,7 @@ const
DefaultPeerActivityTimeout = 1.minutes
# Match MaxWantListBatchSize to efficiently respond to incoming WantLists
PresenceBatchSize = MaxWantListBatchSize
CleanupBatchSize = 2048
type
TaskHandler* = proc(task: BlockExcPeerCtx): Future[void] {.gcsafe.}
@ -186,6 +187,20 @@ proc sendWantBlock(
proc refreshBlockKnowledge(
self: BlockExcEngine, peer: BlockExcPeerCtx, skipDelta = false, resetBackoff = false
) {.async: (raises: [CancelledError]).} =
if peer.lastSentWants.len > 0:
var toRemove: seq[BlockAddress]
for address in peer.lastSentWants:
if address notin self.pendingBlocks:
toRemove.add(address)
if toRemove.len >= CleanupBatchSize:
await idleAsync()
break
for addr in toRemove:
peer.lastSentWants.excl(addr)
if self.pendingBlocks.wantListLen == 0:
if peer.lastSentWants.len > 0:
trace "Clearing want list tracking, no pending blocks", peer = peer.id