p2p, p2p/discover: add dial metrics (#27621)

This PR adds metrics for p2p dialing, which gives us visibility into the quality of the dial 
candidates  returned by our discovery methods.
This commit is contained in:
lightclient
2023-07-06 16:20:31 +02:00
committed by GitHub
parent ea782809f7
commit cbf2579691
13 changed files with 277 additions and 51 deletions
+8
View File
@@ -17,6 +17,7 @@
package discover
import (
"fmt"
"net"
"github.com/ethereum/go-ethereum/metrics"
@@ -32,10 +33,17 @@ const (
)
var (
bucketsCounter []metrics.Counter
ingressTrafficMeter = metrics.NewRegisteredMeter(ingressMeterName, nil)
egressTrafficMeter = metrics.NewRegisteredMeter(egressMeterName, nil)
)
func init() {
for i := 0; i < nBuckets; i++ {
bucketsCounter = append(bucketsCounter, metrics.NewRegisteredCounter(fmt.Sprintf("%s/bucket/%d/count", moduleName, i), nil))
}
}
// meteredConn is a wrapper around a net.UDPConn that meters both the
// inbound and outbound network traffic.
type meteredUdpConn struct {
+32 -4
View File
@@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/netutil"
)
@@ -80,7 +81,8 @@ type Table struct {
closeReq chan struct{}
closed chan struct{}
nodeAddedHook func(*node) // for testing
nodeAddedHook func(*bucket, *node)
nodeRemovedHook func(*bucket, *node)
}
// transport is implemented by the UDP transports.
@@ -98,6 +100,7 @@ type bucket struct {
entries []*node // live entries, sorted by time of last contact
replacements []*node // recently seen nodes to be used if revalidation fails
ips netutil.DistinctNetSet
index int
}
func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
@@ -119,7 +122,8 @@ func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
}
for i := range tab.buckets {
tab.buckets[i] = &bucket{
ips: netutil.DistinctNetSet{Subnet: bucketSubnet, Limit: bucketIPLimit},
index: i,
ips: netutil.DistinctNetSet{Subnet: bucketSubnet, Limit: bucketIPLimit},
}
}
tab.seedRand()
@@ -128,6 +132,22 @@ func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
return tab, nil
}
func newMeteredTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
tab, err := newTable(t, db, cfg)
if err != nil {
return nil, err
}
if metrics.Enabled {
tab.nodeAddedHook = func(b *bucket, n *node) {
bucketsCounter[b.index].Inc(1)
}
tab.nodeRemovedHook = func(b *bucket, n *node) {
bucketsCounter[b.index].Dec(1)
}
}
return tab, nil
}
// Nodes returns all nodes contained in the table.
func (tab *Table) Nodes() []*enode.Node {
if !tab.isInitDone() {
@@ -495,7 +515,7 @@ func (tab *Table) addSeenNode(n *node) {
n.addedAt = time.Now()
if tab.nodeAddedHook != nil {
tab.nodeAddedHook(n)
tab.nodeAddedHook(b, n)
}
}
@@ -539,7 +559,7 @@ func (tab *Table) addVerifiedNode(n *node) {
n.addedAt = time.Now()
if tab.nodeAddedHook != nil {
tab.nodeAddedHook(n)
tab.nodeAddedHook(b, n)
}
}
@@ -638,8 +658,16 @@ func (tab *Table) bumpInBucket(b *bucket, n *node) bool {
}
func (tab *Table) deleteInBucket(b *bucket, n *node) {
// Check if the node is actually in the bucket so the removed hook
// isn't called multiple times for the same node.
if !contains(b.entries, n.ID()) {
return
}
b.entries = deleteNode(b.entries, n)
tab.removeIP(b, n.IP())
if tab.nodeRemovedHook != nil {
tab.nodeRemovedHook(b, n)
}
}
func contains(ns []*node, id enode.ID) bool {
+1 -1
View File
@@ -142,7 +142,7 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
log: cfg.Log,
}
tab, err := newTable(t, ln.Database(), cfg)
tab, err := newMeteredTable(t, ln.Database(), cfg)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -394,7 +394,7 @@ func TestUDPv4_pingMatchIP(t *testing.T) {
func TestUDPv4_successfulPing(t *testing.T) {
test := newUDPTest(t)
added := make(chan *node, 1)
test.table.nodeAddedHook = func(n *node) { added <- n }
test.table.nodeAddedHook = func(b *bucket, n *node) { added <- n }
defer test.close()
// The remote side sends a ping packet to initiate the exchange.
+1 -1
View File
@@ -174,7 +174,7 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) {
cancelCloseCtx: cancelCloseCtx,
}
t.talk = newTalkSystem(t)
tab, err := newTable(t, t.db, cfg)
tab, err := newMeteredTable(t, t.db, cfg)
if err != nil {
return nil, err
}