From feb382bcb417a0b19b25627ce47929a33ec5fac2 Mon Sep 17 00:00:00 2001 From: Sahil Sojitra Date: Thu, 2 Jul 2026 16:12:59 +0530 Subject: [PATCH 1/5] fix: release query event channel lock before blocking write --- core/routing/query.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/core/routing/query.go b/core/routing/query.go index 0100c70870..ed111d3dd8 100644 --- a/core/routing/query.go +++ b/core/routing/query.go @@ -70,18 +70,23 @@ func (e *eventChannel) waitThenClose() { // the internal context expire. func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) { e.mu.Lock() - // Closed. - if e.ch == nil { + ch := e.ch + if ch == nil { e.mu.Unlock() return } + e.mu.Unlock() + + defer func() { + _ = recover() + }() + // in case the passed context is unrelated, wait on both. select { - case e.ch <- ev: + case ch <- ev: case <-e.ctx.Done(): case <-ctx.Done(): } - e.mu.Unlock() } // RegisterForQueryEvents registers a query event channel with the given From 0c74189c2bb93c6a80925485432338b088645c1e Mon Sep 17 00:00:00 2001 From: Sahil Sojitra Date: Thu, 2 Jul 2026 16:13:15 +0530 Subject: [PATCH 2/5] fix: track relay finder disconnected peer cleanup goroutine --- p2p/host/autorelay/relay_finder.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/p2p/host/autorelay/relay_finder.go b/p2p/host/autorelay/relay_finder.go index 7aa6348de8..7c115181f5 100644 --- a/p2p/host/autorelay/relay_finder.go +++ b/p2p/host/autorelay/relay_finder.go @@ -207,7 +207,9 @@ func (rf *relayFinder) background(ctx context.Context) { workTimer := rf.conf.clock.InstantTimer(rf.runScheduledWork(ctx, now, scheduledWork, peerSourceRateLimiter)) defer workTimer.Stop() - go rf.cleanupDisconnectedPeers(ctx) + rf.refCount.Go(func() { + rf.cleanupDisconnectedPeers(ctx) + }) // update addrs on starting the relay finder. rf.updateAddrs() From fb63dcaf888a28fe83a188a4a9fda6b405f2ec6f Mon Sep 17 00:00:00 2001 From: Sahil Sojitra Date: Thu, 2 Jul 2026 16:13:54 +0530 Subject: [PATCH 3/5] fix: clear metrics pool slices to prevent reference retention --- p2p/metricshelper/pool.go | 1 + 1 file changed, 1 insertion(+) diff --git a/p2p/metricshelper/pool.go b/p2p/metricshelper/pool.go index 3290ed5a03..d1e9193381 100644 --- a/p2p/metricshelper/pool.go +++ b/p2p/metricshelper/pool.go @@ -22,5 +22,6 @@ func PutStringSlice(s *[]string) { if c := cap(*s); c < capacity { panic(fmt.Sprintf("expected a string slice with capacity 8 or greater, got %d", c)) } + clear(*s) stringPool.Put(s) } From 5b767a3b11ae40a71033383ec8df16dea964067a Mon Sep 17 00:00:00 2001 From: Sahil Sojitra Date: Thu, 2 Jul 2026 16:39:08 +0530 Subject: [PATCH 4/5] fix: resolve query channel select race with RWMutex --- core/routing/query.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/core/routing/query.go b/core/routing/query.go index ed111d3dd8..30065ccab1 100644 --- a/core/routing/query.go +++ b/core/routing/query.go @@ -49,7 +49,7 @@ type QueryEvent struct { type routingQueryKey struct{} type eventChannel struct { - mu sync.Mutex + mu sync.RWMutex ctx context.Context ch chan<- *QueryEvent } @@ -59,34 +59,31 @@ type eventChannel struct { func (e *eventChannel) waitThenClose() { <-e.ctx.Done() e.mu.Lock() - close(e.ch) - // 1. Signals that we're done. - // 2. Frees memory (in case we end up hanging on to this for a while). - e.ch = nil + if e.ch != nil { + close(e.ch) + // 1. Signals that we're done. + // 2. Frees memory (in case we end up hanging on to this for a while). + e.ch = nil + } e.mu.Unlock() } // send sends an event on the event channel, aborting if either the passed or // the internal context expire. func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) { - e.mu.Lock() - ch := e.ch - if ch == nil { - e.mu.Unlock() + e.mu.RLock() + // Closed. + if e.ch == nil { + e.mu.RUnlock() return } - e.mu.Unlock() - - defer func() { - _ = recover() - }() - // in case the passed context is unrelated, wait on both. select { - case ch <- ev: + case e.ch <- ev: case <-e.ctx.Done(): case <-ctx.Done(): } + e.mu.RUnlock() } // RegisterForQueryEvents registers a query event channel with the given From b34e8826e427b75e023cef125d62b010e744b595 Mon Sep 17 00:00:00 2001 From: Sahil Sojitra Date: Thu, 2 Jul 2026 16:49:02 +0530 Subject: [PATCH 5/5] ci: update codecov-action to v4 to fix GPG verification EPIPE error --- .github/workflows/go-test-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-test-template.yml b/.github/workflows/go-test-template.yml index 1ff1477ef6..87ecc7367b 100644 --- a/.github/workflows/go-test-template.yml +++ b/.github/workflows/go-test-template.yml @@ -146,7 +146,7 @@ jobs: id: coverages run: echo "files=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT - name: Upload coverage to Codecov - uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 + uses: codecov/codecov-action@v4 with: files: ${{ steps.coverages.outputs.files }} env_vars: OS=${{ matrix.os }}, GO=${{ steps.go.outputs.version }}