From a667a22c827ab720a8b2f78053a1f03f2483f653 Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Fri, 10 Apr 2026 10:35:28 +0200 Subject: [PATCH] eth/txtracker: prune peer stats on disconnect Peer stats were never pruned, so the peers map grew with every peer ever seen. The EMA decay loop and stats copy iterated all historical peers on every block/query. Add NotifyPeerDrop(peer) that deletes the peer's stats entry. Called from handler.unregisterPeer alongside txFetcher.Drop. --- eth/handler.go | 1 + eth/txtracker/tracker.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/eth/handler.go b/eth/handler.go index 8ebaa5d700..6770764629 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -406,6 +406,7 @@ func (h *handler) unregisterPeer(id string) { } h.downloader.UnregisterPeer(id) h.txFetcher.Drop(id) + h.txTracker.NotifyPeerDrop(id) if err := h.peers.unregisterPeer(id); err != nil { logger.Error("Ethereum peer removal failed", "err", err) diff --git a/eth/txtracker/tracker.go b/eth/txtracker/tracker.go index 8458c8253d..28f7f27aab 100644 --- a/eth/txtracker/tracker.go +++ b/eth/txtracker/tracker.go @@ -85,6 +85,14 @@ func (t *Tracker) Start(chain Chain) { go t.loop() } +// NotifyPeerDrop removes a disconnected peer's stats to prevent unbounded +// growth. Safe to call from any goroutine. +func (t *Tracker) NotifyPeerDrop(peer string) { + t.mu.Lock() + defer t.mu.Unlock() + delete(t.peers, peer) +} + // Stop shuts down the tracker. func (t *Tracker) Stop() { t.sub.Unsubscribe()