Skip to content

Commit

Permalink
Also return non-connected known peers
Browse files Browse the repository at this point in the history
  • Loading branch information
muXxer committed Mar 26, 2024
1 parent 9c61b05 commit 7f3cb3a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 53 deletions.
2 changes: 1 addition & 1 deletion components/dashboard/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func neighborMetrics() []neighbormetric {
}

// gossip plugin might be disabled
neighbors := deps.NetworkManager.AllNeighbors()
neighbors := deps.NetworkManager.Neighbors()
if neighbors == nil {
return []neighbormetric{}
}
Expand Down
78 changes: 35 additions & 43 deletions components/restapi/management/peers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package management

import (
"sort"

"github.com/labstack/echo/v4"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
Expand Down Expand Up @@ -29,7 +31,7 @@ func parsePeerIDParam(c echo.Context) (peer.ID, error) {
return peerID, nil
}

// getPeerInfoFromNeighbor returns the peer info for the given neighbor.
// getPeerInfoFromNeighbor returns the peer info for the given peer.
func getPeerInfoFromPeer(peer *network.Peer) *api.PeerInfo {
multiAddresses := make([]iotago.PrefixedStringUint8, len(peer.PeerAddresses))
for i, multiAddress := range peer.PeerAddresses {
Expand All @@ -49,8 +51,7 @@ func getPeerInfoFromPeer(peer *network.Peer) *api.PeerInfo {
packetsReceived := uint32(0)
packetsSent := uint32(0)

neighbor, err := deps.NetworkManager.Neighbor(peer.ID)
if err == nil {
if neighbor, err := deps.NetworkManager.Neighbor(peer.ID); err == nil {
packetsReceived = uint32(neighbor.PacketsRead())
packetsSent = uint32(neighbor.PacketsWritten())
}
Expand All @@ -68,46 +69,20 @@ func getPeerInfoFromPeer(peer *network.Peer) *api.PeerInfo {
}
}

// getPeerInfoFromNeighbor returns the peer info for the given neighbor.
func getPeerInfoFromNeighbor(neighbor network.Neighbor) *api.PeerInfo {
peer := neighbor.Peer()

multiAddresses := make([]iotago.PrefixedStringUint8, len(peer.PeerAddresses))
for i, multiAddress := range peer.PeerAddresses {
multiAddresses[i] = iotago.PrefixedStringUint8(multiAddress.String())
}

var alias string
relation := PeerRelationAutopeered

if peerConfigItem := deps.PeeringConfigManager.Peer(neighbor.Peer().ID); peerConfigItem != nil {
alias = peerConfigItem.Alias

// if the peer exists in the config, it is a manual peered peer
relation = PeerRelationManual
}

return &api.PeerInfo{
ID: peer.ID.String(),
MultiAddresses: multiAddresses,
Alias: alias,
Relation: relation,
Connected: peer.ConnStatus.Load() == network.ConnStatusConnected,
GossipMetrics: &api.PeerGossipMetrics{
PacketsReceived: uint32(neighbor.PacketsRead()),
PacketsSent: uint32(neighbor.PacketsWritten()),
},
}
}

// getPeer returns the peer info for the given peerID in the request.
func getPeer(c echo.Context) (*api.PeerInfo, error) {
peerID, err := parsePeerIDParam(c)
if err != nil {
return nil, err
}

neighbor, err := deps.NetworkManager.Neighbor(peerID)
// check connected neighbors first
if neighbor, err := deps.NetworkManager.Neighbor(peerID); err == nil {
return getPeerInfoFromPeer(neighbor.Peer()), nil
}

// if the peer is not connected, check the manual peers
peer, err := deps.NetworkManager.ManualPeer(peerID)
if err != nil {
if ierrors.Is(err, network.ErrUnknownPeer) {
return nil, ierrors.WithMessagef(echo.ErrNotFound, "peer not found, peerID: %s", peerID.String())
Expand All @@ -116,7 +91,7 @@ func getPeer(c echo.Context) (*api.PeerInfo, error) {
return nil, ierrors.WithMessagef(echo.ErrInternalServerError, "failed to get peer: %w", err)
}

return getPeerInfoFromNeighbor(neighbor), nil
return getPeerInfoFromPeer(peer), nil
}

// removePeer drops the connection to the peer with the given peerID and removes it from the known peers.
Expand All @@ -134,17 +109,34 @@ func removePeer(c echo.Context) error {

// listPeers returns the list of all peers.
func listPeers() *api.PeersResponse {
allNeighbors := deps.NetworkManager.AllNeighbors()
// get all known manual peers
manualPeers := deps.NetworkManager.ManualPeers()

// get all connected neighbors
allNeighbors := deps.NetworkManager.Neighbors()

result := &api.PeersResponse{
Peers: make([]*api.PeerInfo, len(allNeighbors)),
peersMap := make(map[peer.ID]*network.Peer)
for _, peer := range manualPeers {
peersMap[peer.ID] = peer
}

for i, info := range allNeighbors {
result.Peers[i] = getPeerInfoFromNeighbor(info)
for _, neighbor := range allNeighbors {
// it's no problem if the peer is already in the map
peersMap[neighbor.Peer().ID] = neighbor.Peer()
}

return result
peers := make([]*api.PeerInfo, 0, len(peersMap))
for _, peer := range peersMap {
peers = append(peers, getPeerInfoFromPeer(peer))
}

sort.Slice(peers, func(i, j int) bool {
return peers[i].ID < peers[j].ID
})

return &api.PeersResponse{
Peers: peers,
}
}

// addPeer adds the peer with the given multiAddress to the manual peering layer.
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var (
// ErrNotRunning is returned when a peer is added to a stopped or not yet started network manager.
ErrNotRunning = ierrors.New("manager not running")
// ErrUnknownPeer is returned when the specified peer is not known to the network manager.
ErrUnknownPeer = ierrors.New("unknown neighbor")
ErrUnknownPeer = ierrors.New("unknown peer")
// ErrLoopbackPeer is returned when the own peer is added.
ErrLoopbackPeer = ierrors.New("loopback connection not allowed")
// ErrDuplicatePeer is returned when the same peer is added more than once.
Expand Down
10 changes: 6 additions & 4 deletions pkg/network/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ type Manager interface {
RemovePeer(peerID peer.ID) error
// AddManualPeer adds a manual peer to the list of known peers.
AddManualPeer(multiAddress multiaddr.Multiaddr) (*Peer, error)
// GetManualPeers returns all the manual peers.
GetManualPeers(onlyConnected ...bool) []*Peer
// ManualPeer returns the manual peer with the given ID.
ManualPeer(peerID peer.ID) (*Peer, error)
// ManualPeers returns all the manual peers.
ManualPeers(onlyConnected ...bool) []*Peer

// OnNeighborAdded registers a callback that gets triggered when a neighbor is added.
OnNeighborAdded(handler func(Neighbor)) *event.Hook[func(Neighbor)]
Expand All @@ -38,8 +40,8 @@ type Manager interface {
// DisconnectNeighbor disconnects the neighbor with the given ID.
DisconnectNeighbor(peerID peer.ID) error

// AllNeighbors returns all the neighbors that are currently connected.
AllNeighbors() []Neighbor
// Neighbors returns all the neighbors that are currently connected.
Neighbors() []Neighbor
// AutopeeringNeighbors returns all the neighbors that are currently connected via autopeering.
AutopeeringNeighbors() []Neighbor

Expand Down
12 changes: 8 additions & 4 deletions pkg/network/p2p/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ func (m *Manager) AddManualPeer(multiAddr multiaddr.Multiaddr) (*network.Peer, e
return m.manualPeering.AddPeer(multiAddr)
}

func (m *Manager) GetManualPeers(onlyConnected ...bool) []*network.Peer {
func (m *Manager) ManualPeer(id peer.ID) (*network.Peer, error) {
return m.manualPeering.Peer(id)
}

func (m *Manager) ManualPeers(onlyConnected ...bool) []*network.Peer {
return m.manualPeering.GetPeers(onlyConnected...)
}

Expand Down Expand Up @@ -256,8 +260,8 @@ func (m *Manager) Send(packet proto.Message, to ...peer.ID) {
}
}

// AllNeighbors returns all the neighbors that are currently connected.
func (m *Manager) AllNeighbors() []network.Neighbor {
// Neighbors returns all the neighbors that are currently connected.
func (m *Manager) Neighbors() []network.Neighbor {
neighbors := m.allNeighbors()
result := make([]network.Neighbor, len(neighbors))
for i, n := range neighbors {
Expand All @@ -274,7 +278,7 @@ func (m *Manager) allNeighbors() []*neighbor {

// AutopeeringNeighbors returns all the neighbors that are currently connected via autopeering.
func (m *Manager) AutopeeringNeighbors() []network.Neighbor {
return lo.Filter(m.AllNeighbors(), func(n network.Neighbor) bool {
return lo.Filter(m.Neighbors(), func(n network.Neighbor) bool {
return !m.manualPeering.IsPeerKnown(n.Peer().ID)
})
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/network/p2p/manualpeering/manualpeering.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ func (m *Manager) RemovePeer(peerID peer.ID) error {
return nil
}

func (m *Manager) Peer(peerID peer.ID) (*network.Peer, error) {
m.knownPeersMutex.RLock()
defer m.knownPeersMutex.RUnlock()

peer, exists := m.knownPeers[peerID]
if !exists {
return nil, network.ErrUnknownPeer
}

return peer, nil
}

// GetPeers returns the list of known peers.
func (m *Manager) GetPeers(onlyConnected ...bool) []*network.Peer {
m.knownPeersMutex.RLock()
Expand Down

0 comments on commit 7f3cb3a

Please sign in to comment.