dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months. We're about to remove the dashboard, but decided that we should get all the recent work in first in case anyone wants to pick up this project later on. * cmd, dashboard, eth, p2p: send peer info to the dashboard * dashboard: update npm packages, improve UI, rebase * dashboard, p2p: remove println, change doc * cmd, dashboard, eth, p2p: cleanup after review * dashboard: send current block to the dashboard client
This commit is contained in:
committed by
Felix Lange
parent
6f1a600f6c
commit
4ea9b62b5c
@@ -304,7 +304,7 @@ func (t *dialTask) dial(srv *Server, dest *enode.Node) error {
|
||||
if err != nil {
|
||||
return &dialError{err}
|
||||
}
|
||||
mfd := newMeteredConn(fd, false, dest.IP())
|
||||
mfd := newMeteredConn(fd, false, &net.TCPAddr{IP: dest.IP(), Port: dest.TCP()})
|
||||
return srv.SetupConn(mfd, t.flags, dest)
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,6 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -28,7 +27,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -58,24 +56,24 @@ var (
|
||||
type MeteredPeerEventType int
|
||||
|
||||
const (
|
||||
// PeerConnected is the type of event emitted when a peer successfully
|
||||
// made the handshake.
|
||||
PeerConnected MeteredPeerEventType = iota
|
||||
// PeerHandshakeSucceeded is the type of event
|
||||
// emitted when a peer successfully makes the handshake.
|
||||
PeerHandshakeSucceeded MeteredPeerEventType = iota
|
||||
|
||||
// PeerHandshakeFailed is the type of event emitted when a peer fails to
|
||||
// make the handshake or disconnects before it.
|
||||
PeerHandshakeFailed
|
||||
|
||||
// PeerDisconnected is the type of event emitted when a peer disconnects.
|
||||
PeerDisconnected
|
||||
|
||||
// PeerHandshakeFailed is the type of event emitted when a peer fails to
|
||||
// make the handshake or disconnects before the handshake.
|
||||
PeerHandshakeFailed
|
||||
)
|
||||
|
||||
// MeteredPeerEvent is an event emitted when peers connect or disconnect.
|
||||
type MeteredPeerEvent struct {
|
||||
Type MeteredPeerEventType // Type of peer event
|
||||
IP net.IP // IP address of the peer
|
||||
ID enode.ID // NodeID of the peer
|
||||
Addr string // TCP address of the peer
|
||||
Elapsed time.Duration // Time elapsed between the connection and the handshake/disconnection
|
||||
Peer *Peer // Connected remote node instance
|
||||
Ingress uint64 // Ingress count at the moment of the event
|
||||
Egress uint64 // Egress count at the moment of the event
|
||||
}
|
||||
@@ -91,9 +89,9 @@ func SubscribeMeteredPeerEvent(ch chan<- MeteredPeerEvent) event.Subscription {
|
||||
type meteredConn struct {
|
||||
net.Conn // Network connection to wrap with metering
|
||||
|
||||
connected time.Time // Connection time of the peer
|
||||
ip net.IP // IP address of the peer
|
||||
id enode.ID // NodeID of the peer
|
||||
connected time.Time // Connection time of the peer
|
||||
addr *net.TCPAddr // TCP address of the peer
|
||||
peer *Peer // Peer instance
|
||||
|
||||
// trafficMetered denotes if the peer is registered in the traffic registries.
|
||||
// Its value is true if the metered peer count doesn't reach the limit in the
|
||||
@@ -109,13 +107,13 @@ type meteredConn struct {
|
||||
// connection meter and also increases the metered peer count. If the metrics
|
||||
// system is disabled or the IP address is unspecified, this function returns
|
||||
// the original object.
|
||||
func newMeteredConn(conn net.Conn, ingress bool, ip net.IP) net.Conn {
|
||||
func newMeteredConn(conn net.Conn, ingress bool, addr *net.TCPAddr) net.Conn {
|
||||
// Short circuit if metrics are disabled
|
||||
if !metrics.Enabled {
|
||||
return conn
|
||||
}
|
||||
if ip.IsUnspecified() {
|
||||
log.Warn("Peer IP is unspecified")
|
||||
if addr == nil || addr.IP.IsUnspecified() {
|
||||
log.Warn("Peer address is unspecified")
|
||||
return conn
|
||||
}
|
||||
// Bump the connection counters and wrap the connection
|
||||
@@ -128,7 +126,7 @@ func newMeteredConn(conn net.Conn, ingress bool, ip net.IP) net.Conn {
|
||||
|
||||
return &meteredConn{
|
||||
Conn: conn,
|
||||
ip: ip,
|
||||
addr: addr,
|
||||
connected: time.Now(),
|
||||
}
|
||||
}
|
||||
@@ -159,30 +157,27 @@ func (c *meteredConn) Write(b []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
// handshakeDone is called when a peer handshake is done. Registers the peer to
|
||||
// the ingress and the egress traffic registries using the peer's IP and node ID,
|
||||
// also emits connect event.
|
||||
func (c *meteredConn) handshakeDone(id enode.ID) {
|
||||
// TODO (kurkomisi): use the node URL instead of the pure node ID. (the String() method of *Node)
|
||||
// handshakeDone is called after the connection passes the handshake.
|
||||
func (c *meteredConn) handshakeDone(peer *Peer) {
|
||||
if atomic.AddInt32(&meteredPeerCount, 1) >= MeteredPeerLimit {
|
||||
// Don't register the peer in the traffic registries.
|
||||
atomic.AddInt32(&meteredPeerCount, -1)
|
||||
c.lock.Lock()
|
||||
c.id, c.trafficMetered = id, false
|
||||
c.peer, c.trafficMetered = peer, false
|
||||
c.lock.Unlock()
|
||||
log.Warn("Metered peer count reached the limit")
|
||||
} else {
|
||||
key := fmt.Sprintf("%s/%s", c.ip, id.String())
|
||||
enode := peer.Node().String()
|
||||
c.lock.Lock()
|
||||
c.id, c.trafficMetered = id, true
|
||||
c.ingressMeter = metrics.NewRegisteredMeter(key, PeerIngressRegistry)
|
||||
c.egressMeter = metrics.NewRegisteredMeter(key, PeerEgressRegistry)
|
||||
c.peer, c.trafficMetered = peer, true
|
||||
c.ingressMeter = metrics.NewRegisteredMeter(enode, PeerIngressRegistry)
|
||||
c.egressMeter = metrics.NewRegisteredMeter(enode, PeerEgressRegistry)
|
||||
c.lock.Unlock()
|
||||
}
|
||||
meteredPeerFeed.Send(MeteredPeerEvent{
|
||||
Type: PeerConnected,
|
||||
IP: c.ip,
|
||||
ID: id,
|
||||
Type: PeerHandshakeSucceeded,
|
||||
Addr: c.addr.String(),
|
||||
Peer: peer,
|
||||
Elapsed: time.Since(c.connected),
|
||||
})
|
||||
}
|
||||
@@ -192,44 +187,43 @@ func (c *meteredConn) handshakeDone(id enode.ID) {
|
||||
func (c *meteredConn) Close() error {
|
||||
err := c.Conn.Close()
|
||||
c.lock.RLock()
|
||||
if c.id == (enode.ID{}) {
|
||||
// If the peer disconnects before the handshake.
|
||||
if c.peer == nil {
|
||||
// If the peer disconnects before/during the handshake.
|
||||
c.lock.RUnlock()
|
||||
meteredPeerFeed.Send(MeteredPeerEvent{
|
||||
Type: PeerHandshakeFailed,
|
||||
IP: c.ip,
|
||||
Addr: c.addr.String(),
|
||||
Elapsed: time.Since(c.connected),
|
||||
})
|
||||
activePeerGauge.Dec(1)
|
||||
return err
|
||||
}
|
||||
id := c.id
|
||||
peer := c.peer
|
||||
if !c.trafficMetered {
|
||||
// If the peer isn't registered in the traffic registries.
|
||||
c.lock.RUnlock()
|
||||
meteredPeerFeed.Send(MeteredPeerEvent{
|
||||
Type: PeerDisconnected,
|
||||
IP: c.ip,
|
||||
ID: id,
|
||||
Addr: c.addr.String(),
|
||||
Peer: peer,
|
||||
})
|
||||
activePeerGauge.Dec(1)
|
||||
return err
|
||||
}
|
||||
ingress, egress := uint64(c.ingressMeter.Count()), uint64(c.egressMeter.Count())
|
||||
ingress, egress, enode := uint64(c.ingressMeter.Count()), uint64(c.egressMeter.Count()), c.peer.Node().String()
|
||||
c.lock.RUnlock()
|
||||
|
||||
// Decrement the metered peer count
|
||||
atomic.AddInt32(&meteredPeerCount, -1)
|
||||
|
||||
// Unregister the peer from the traffic registries
|
||||
key := fmt.Sprintf("%s/%s", c.ip, id)
|
||||
PeerIngressRegistry.Unregister(key)
|
||||
PeerEgressRegistry.Unregister(key)
|
||||
PeerIngressRegistry.Unregister(enode)
|
||||
PeerEgressRegistry.Unregister(enode)
|
||||
|
||||
meteredPeerFeed.Send(MeteredPeerEvent{
|
||||
Type: PeerDisconnected,
|
||||
IP: c.ip,
|
||||
ID: id,
|
||||
Addr: c.addr.String(),
|
||||
Peer: peer,
|
||||
Ingress: ingress,
|
||||
Egress: egress,
|
||||
})
|
||||
|
@@ -779,6 +779,9 @@ running:
|
||||
if p.Inbound() {
|
||||
inboundCount++
|
||||
}
|
||||
if conn, ok := c.fd.(*meteredConn); ok {
|
||||
conn.handshakeDone(p)
|
||||
}
|
||||
}
|
||||
// The dialer logic relies on the assumption that
|
||||
// dial tasks complete after the peer has been added or
|
||||
@@ -902,9 +905,13 @@ func (srv *Server) listenLoop() {
|
||||
continue
|
||||
}
|
||||
if remoteIP != nil {
|
||||
fd = newMeteredConn(fd, true, remoteIP)
|
||||
var addr *net.TCPAddr
|
||||
if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok {
|
||||
addr = tcp
|
||||
}
|
||||
fd = newMeteredConn(fd, true, addr)
|
||||
srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr())
|
||||
}
|
||||
srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr())
|
||||
go func() {
|
||||
srv.SetupConn(fd, inboundConn, nil)
|
||||
slots <- struct{}{}
|
||||
@@ -974,9 +981,6 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro
|
||||
} else {
|
||||
c.node = nodeFromConn(remotePubkey, c.fd)
|
||||
}
|
||||
if conn, ok := c.fd.(*meteredConn); ok {
|
||||
conn.handshakeDone(c.node.ID())
|
||||
}
|
||||
clog := srv.log.New("id", c.node.ID(), "addr", c.fd.RemoteAddr(), "conn", c.flags)
|
||||
err = srv.checkpoint(c, srv.checkpointPostHandshake)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user