Added more information to the admin.peers rpc

This commit is contained in:
StephenButtolph 2020-05-30 14:23:08 -04:00
parent d7e67f00b7
commit 72f203fa0e
5 changed files with 53 additions and 45 deletions

View File

@ -1,27 +0,0 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package admin
import (
"sort"
"github.com/ava-labs/gecko/utils"
)
// Peerable can return a group of peers
type Peerable interface{ IPs() []utils.IPDesc }
// Networking provides helper methods for tracking the current network state
type Networking struct{ peers Peerable }
// Peers returns the current peers
func (n *Networking) Peers() ([]string, error) {
ipDescs := n.peers.IPs()
ips := make([]string, len(ipDescs))
for i, ipDesc := range ipDescs {
ips[i] = ipDesc.String()
}
sort.Strings(ips)
return ips, nil
}

View File

@ -11,6 +11,7 @@ import (
"github.com/ava-labs/gecko/api"
"github.com/ava-labs/gecko/chains"
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/network"
"github.com/ava-labs/gecko/snow/engine/common"
"github.com/ava-labs/gecko/utils/logging"
@ -22,14 +23,14 @@ type Admin struct {
nodeID ids.ShortID
networkID uint32
log logging.Logger
networking Networking
networking network.Network
performance Performance
chainManager chains.Manager
httpServer *api.Server
}
// NewService returns a new admin API service
func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers Peerable, httpServer *api.Server) *common.HTTPHandler {
func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler {
newServer := rpc.NewServer()
codec := cjson.NewCodec()
newServer.RegisterCodec(codec, "application/json")
@ -39,10 +40,8 @@ func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainM
networkID: networkID,
log: log,
chainManager: chainManager,
networking: Networking{
peers: peers,
},
httpServer: httpServer,
networking: peers,
httpServer: httpServer,
}, "admin")
return &common.HTTPHandler{Handler: newServer}
}
@ -103,16 +102,14 @@ type PeersArgs struct{}
// PeersReply are the results from calling Peers
type PeersReply struct {
Peers []string `json:"peers"`
Peers []network.PeerID `json:"peers"`
}
// Peers returns the list of current validators
func (service *Admin) Peers(r *http.Request, args *PeersArgs, reply *PeersReply) error {
service.log.Debug("Admin: Peers called")
peers, err := service.networking.Peers()
reply.Peers = peers
return err
reply.Peers = service.networking.Peers()
return nil
}
// StartCPUProfilerArgs are the arguments for calling StartCPUProfiler

View File

@ -70,9 +70,9 @@ type Network interface {
// The handler will initially be called with this local node's ID.
RegisterHandler(h Handler)
// Returns the IPs of nodes this network is currently connected to
// externally. Thread safety must be managed internally to the network.
IPs() []utils.IPDesc
// Returns the description of the nodes this network is currently connected
// to externally. Thread safety must be managed internally to the network.
Peers() []PeerID
// Close this network and all existing connections it has. Thread safety
// must be managed internally to the network. Calling close multiple times
@ -511,17 +511,24 @@ func (n *network) RegisterHandler(h Handler) {
}
// IPs implements the Network interface
func (n *network) IPs() []utils.IPDesc {
func (n *network) Peers() []PeerID {
n.stateLock.Lock()
defer n.stateLock.Unlock()
ips := []utils.IPDesc(nil)
peers := []PeerID{}
for _, peer := range n.peers {
if peer.connected {
ips = append(ips, peer.ip)
peers = append(peers, PeerID{
IP: peer.conn.RemoteAddr().String(),
PublicIP: peer.ip.String(),
ID: peer.id,
Version: peer.versionStr,
LastSent: time.Unix(atomic.LoadInt64(&peer.lastSent), 0),
LastReceived: time.Unix(atomic.LoadInt64(&peer.lastReceived), 0),
})
}
}
return ips
return peers
}
// Close implements the Network interface

View File

@ -8,6 +8,7 @@ import (
"math"
"net"
"sync"
"sync/atomic"
"time"
"github.com/ava-labs/gecko/ids"
@ -43,6 +44,12 @@ type peer struct {
// the connection object that is used to read/write messages from
conn net.Conn
// version that the peer reported during the handshake
versionStr string
// unix time of the last message sent and received respectively
lastSent, lastReceived int64
}
// assume the stateLock is held
@ -159,6 +166,7 @@ func (p *peer) WriteMessages() {
}
msg = msg[written:]
}
atomic.StoreInt64(&p.lastSent, p.net.clock.Time().Unix())
}
}
@ -188,6 +196,7 @@ func (p *peer) send(msg Msg) bool {
// assumes the stateLock is not held
func (p *peer) handle(msg Msg) {
p.net.heartbeat()
atomic.StoreInt64(&p.lastReceived, p.net.clock.Time().Unix())
op := msg.Op()
msgMetrics := p.net.message(op)
@ -415,6 +424,8 @@ func (p *peer) version(msg Msg) {
return
}
p.versionStr = peerVersion.String()
p.connected = true
p.net.connected(p)
}

20
network/peer_id.go Normal file
View File

@ -0,0 +1,20 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package network
import (
"time"
"github.com/ava-labs/gecko/ids"
)
// PeerID ...
type PeerID struct {
IP string `json:"ip"`
PublicIP string `json:"publicIP"`
ID ids.ShortID `json:"id"`
Version string `json:"version"`
LastSent time.Time `json:"lastSent"`
LastReceived time.Time `json:"lastReceived"`
}