From 843333afa6980cbd2842dfc5b15a3a1c88065702 Mon Sep 17 00:00:00 2001 From: healthykim Date: Sun, 19 Oct 2025 17:03:15 +0900 Subject: [PATCH 1/2] chore: add metrics for slow peer --- eth/fetcher/tx_fetcher.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 3e050320e905..88eba6da3791 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -107,6 +107,15 @@ var ( txFetcherQueueingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/queueing/hashes", nil) txFetcherFetchingPeers = metrics.NewRegisteredGauge("eth/fetcher/transaction/fetching/peers", nil) txFetcherFetchingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/fetching/hashes", nil) + + txFetcherSlowPeers = metrics.NewRegisteredGauge("eth/fetcher/transaction/slow/peers", nil) + // Note: this metric does not mean that the fetching of a transaction + // was blocked by a specific peer during this period, since we request + // another peer to fetch the same transaction hash. + // The purpose of this metric is to measure how long it takes for a slow peer + // to become "unfrozen", either by eventually replying to the request + // or by being dropped, measuring from the moment the request was sent. + txFetcherSlowWait = metrics.NewRegisteredHistogram("eth/fetcher/transaction/slow/wait", nil, metrics.NewExpDecaySample(1028, 0.015)) ) var errTerminated = errors.New("terminated") @@ -635,6 +644,7 @@ func (f *TxFetcher) loop() { } // Keep track of the request as dangling, but never expire f.requests[peer].hashes = nil + txFetcherSlowPeers.Inc(1) } } // Schedule a new transaction retrieval @@ -728,6 +738,10 @@ func (f *TxFetcher) loop() { log.Warn("Unexpected transaction delivery", "peer", delivery.origin) break } + if req.hashes == nil { + txFetcherSlowPeers.Dec(1) + txFetcherSlowWait.Update(time.Duration(f.clock.Now() - req.time).Nanoseconds()) + } delete(f.requests, delivery.origin) // Anything not delivered should be re-scheduled (with or without @@ -807,6 +821,10 @@ func (f *TxFetcher) loop() { } delete(f.fetching, hash) } + if request.hashes == nil { + txFetcherSlowPeers.Dec(1) + txFetcherSlowWait.Update(time.Duration(f.clock.Now() - request.time).Nanoseconds()) + } delete(f.requests, drop.peer) } // Clean up general announcement tracking From 542273ec8ef6c7a517458bd710f4e37902bda6ad Mon Sep 17 00:00:00 2001 From: healthykim Date: Sun, 19 Oct 2025 17:10:26 +0900 Subject: [PATCH 2/2] chore: move metrics to metrics.go --- eth/fetcher/metrics.go | 59 +++++++++++++++++++++++++++++++++++++++ eth/fetcher/tx_fetcher.go | 39 -------------------------- 2 files changed, 59 insertions(+), 39 deletions(-) create mode 100644 eth/fetcher/metrics.go diff --git a/eth/fetcher/metrics.go b/eth/fetcher/metrics.go new file mode 100644 index 000000000000..fd1678dd3060 --- /dev/null +++ b/eth/fetcher/metrics.go @@ -0,0 +1,59 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see