From 86ce276a9015fdd17e969a918a2e514cfbd87996 Mon Sep 17 00:00:00 2001 From: Chrysostomos Nanakos Date: Mon, 3 Nov 2025 16:49:31 +0200 Subject: [PATCH] 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 --- codex/blockexchange/engine/engine.nim | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/codex/blockexchange/engine/engine.nim b/codex/blockexchange/engine/engine.nim index 8cf9cb19..81af03f4 100644 --- a/codex/blockexchange/engine/engine.nim +++ b/codex/blockexchange/engine/engine.nim @@ -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