From dc0db2fdd7efd69413db09ecc36ae42b83094b0a Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Thu, 27 Mar 2025 19:47:22 +0100 Subject: [PATCH] eth: add per-peer metrics Signed-off-by: Csaba Kiraly --- eth/fetcher/tx_fetcher.go | 1 + eth/protocols/eth/handlers.go | 1 + eth/protocols/eth/peer.go | 3 +++ eth/protocols/eth/peer_metrics.go | 42 +++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 eth/protocols/eth/peer_metrics.go diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 98a1c6e9a6..cb3ba46372 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -310,6 +310,7 @@ func (f *TxFetcher) isKnownUnderpriced(hash common.Hash) bool { // direct request replies. The differentiation is important so the fetcher can // re-schedule missing transactions as soon as possible. func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) error { + // TODO: add peer metrics here var ( inMeter = txReplyInMeter knownMeter = txReplyKnownMeter diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index 15ad048bcf..012b75ec3c 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -501,6 +501,7 @@ func handleTransactions(backend Backend, msg Decoder, peer *Peer) error { } peer.markTransaction(tx.Hash()) } + peer.meters.txReceived.Mark(int64(len(txs))) return backend.Handle(peer, &txs) } diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 40c54a3570..79edc7d77c 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -59,6 +59,8 @@ type Peer struct { reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them resDispatch chan *response // Dispatch channel to fulfil pending requests and untrack them + meters *peerMeters // Peer-specific metrics for diagnositics and to use in decision logic + term chan struct{} // Termination channel to stop the broadcasters } @@ -77,6 +79,7 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Pe reqCancel: make(chan *cancel), resDispatch: make(chan *response), txpool: txpool, + meters: newPeerMeters("peers/"+p.ID().String(), nil), term: make(chan struct{}), } // Start up all the broadcasters diff --git a/eth/protocols/eth/peer_metrics.go b/eth/protocols/eth/peer_metrics.go new file mode 100644 index 0000000000..7716b2a682 --- /dev/null +++ b/eth/protocols/eth/peer_metrics.go @@ -0,0 +1,42 @@ +// 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 . + +package eth + +import "github.com/ethereum/go-ethereum/metrics" + +type peerMeters struct { + txReceived *metrics.Meter + txSent *metrics.Meter + + txReplyInMeter *metrics.Meter + txReplyKnownMeter *metrics.Meter + txReplyUnderpricedMeter *metrics.Meter + txReplyOtherRejectMeter *metrics.Meter +} + +// newPeerMeters registers and returns peer-level meters. +func newPeerMeters(base string, r metrics.Registry) *peerMeters { + return &peerMeters{ + txReceived: metrics.NewRegisteredMeter(base+"/txReceived", r), + txSent: metrics.NewRegisteredMeter(base+"/txSent", r), + + txReplyInMeter: metrics.NewRegisteredMeter(base+"/eth/fetcher/transaction/replies/in", nil), + txReplyKnownMeter: metrics.NewRegisteredMeter(base+"/eth/fetcher/transaction/replies/known", nil), + txReplyUnderpricedMeter: metrics.NewRegisteredMeter(base+"/eth/fetcher/transaction/replies/underpriced", nil), + txReplyOtherRejectMeter: metrics.NewRegisteredMeter(base+"/eth/fetcher/transaction/replies/otherreject", nil), + } +}