github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/debug/p2p.go (about)

     1  package debug
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/golang/protobuf/ptypes/empty"
     7  	"github.com/libp2p/go-libp2p-core/network"
     8  	"github.com/libp2p/go-libp2p-core/peer"
     9  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
    10  	pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
    11  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    12  	"google.golang.org/grpc/codes"
    13  	"google.golang.org/grpc/status"
    14  )
    15  
    16  // GetPeer returns the data known about the peer defined by the provided peer id.
    17  func (ds *Server) GetPeer(_ context.Context, peerReq *ethpb.PeerRequest) (*pbrpc.DebugPeerResponse, error) {
    18  	pid, err := peer.Decode(peerReq.PeerId)
    19  	if err != nil {
    20  		return nil, status.Errorf(codes.InvalidArgument, "Unable to parse provided peer id: %v", err)
    21  	}
    22  	return ds.getPeer(pid)
    23  }
    24  
    25  // ListPeers returns all peers known to the host node, irregardless of if they are connected/
    26  // disconnected.
    27  func (ds *Server) ListPeers(_ context.Context, _ *empty.Empty) (*pbrpc.DebugPeerResponses, error) {
    28  	var responses []*pbrpc.DebugPeerResponse
    29  	for _, pid := range ds.PeersFetcher.Peers().All() {
    30  		resp, err := ds.getPeer(pid)
    31  		if err != nil {
    32  			return nil, err
    33  		}
    34  		responses = append(responses, resp)
    35  	}
    36  	return &pbrpc.DebugPeerResponses{Responses: responses}, nil
    37  }
    38  
    39  func (ds *Server) getPeer(pid peer.ID) (*pbrpc.DebugPeerResponse, error) {
    40  	peers := ds.PeersFetcher.Peers()
    41  	peerStore := ds.PeerManager.Host().Peerstore()
    42  	addr, err := peers.Address(pid)
    43  	if err != nil {
    44  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    45  	}
    46  	dir, err := peers.Direction(pid)
    47  	if err != nil {
    48  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    49  	}
    50  	pbDirection := ethpb.PeerDirection_UNKNOWN
    51  	switch dir {
    52  	case network.DirInbound:
    53  		pbDirection = ethpb.PeerDirection_INBOUND
    54  	case network.DirOutbound:
    55  		pbDirection = ethpb.PeerDirection_OUTBOUND
    56  	}
    57  	connState, err := peers.ConnectionState(pid)
    58  	if err != nil {
    59  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    60  	}
    61  	record, err := peers.ENR(pid)
    62  	if err != nil {
    63  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    64  	}
    65  	enr := ""
    66  	if record != nil {
    67  		enr, err = p2p.SerializeENR(record)
    68  		if err != nil {
    69  			return nil, status.Errorf(codes.Internal, "Unable to serialize enr: %v", err)
    70  		}
    71  	}
    72  	metadata, err := peers.Metadata(pid)
    73  	if err != nil {
    74  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    75  	}
    76  	protocols, err := peerStore.GetProtocols(pid)
    77  	if err != nil {
    78  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    79  	}
    80  	resp, err := peers.Scorers().BadResponsesScorer().Count(pid)
    81  	if err != nil {
    82  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
    83  	}
    84  
    85  	rawPversion, err := peerStore.Get(pid, "ProtocolVersion")
    86  	pVersion, ok := rawPversion.(string)
    87  	if err != nil || !ok {
    88  		pVersion = ""
    89  	}
    90  	rawAversion, err := peerStore.Get(pid, "AgentVersion")
    91  	aVersion, ok := rawAversion.(string)
    92  	if err != nil || !ok {
    93  		aVersion = ""
    94  	}
    95  	peerInfo := &pbrpc.DebugPeerResponse_PeerInfo{
    96  		Protocols:       protocols,
    97  		FaultCount:      uint64(resp),
    98  		ProtocolVersion: pVersion,
    99  		AgentVersion:    aVersion,
   100  		PeerLatency:     uint64(peerStore.LatencyEWMA(pid).Milliseconds()),
   101  	}
   102  	if metadata != nil && !metadata.IsNil() {
   103  		switch {
   104  		case metadata.MetadataObjV0() != nil:
   105  			peerInfo.MetadataV0 = metadata.MetadataObjV0()
   106  		case metadata.MetadataObjV1() != nil:
   107  			peerInfo.MetadataV1 = metadata.MetadataObjV1()
   108  		}
   109  	}
   110  	addresses := peerStore.Addrs(pid)
   111  	var stringAddrs []string
   112  	if addr != nil {
   113  		stringAddrs = append(stringAddrs, addr.String())
   114  	}
   115  	for _, a := range addresses {
   116  		// Do not double count address
   117  		if addr != nil && addr.String() == a.String() {
   118  			continue
   119  		}
   120  		stringAddrs = append(stringAddrs, a.String())
   121  	}
   122  	pStatus, err := peers.ChainState(pid)
   123  	if err != nil {
   124  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
   125  	}
   126  	lastUpdated, err := peers.ChainStateLastUpdated(pid)
   127  	if err != nil {
   128  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
   129  	}
   130  	unixTime := uint64(0)
   131  	if !lastUpdated.IsZero() {
   132  		unixTime = uint64(lastUpdated.Unix())
   133  	}
   134  	gScore, bPenalty, topicMaps, err := peers.Scorers().GossipScorer().GossipData(pid)
   135  	if err != nil {
   136  		return nil, status.Errorf(codes.NotFound, "Requested peer does not exist: %v", err)
   137  	}
   138  	scoreInfo := &pbrpc.ScoreInfo{
   139  		OverallScore:       float32(peers.Scorers().Score(pid)),
   140  		ProcessedBlocks:    peers.Scorers().BlockProviderScorer().ProcessedBlocks(pid),
   141  		BlockProviderScore: float32(peers.Scorers().BlockProviderScorer().Score(pid)),
   142  		TopicScores:        topicMaps,
   143  		GossipScore:        float32(gScore),
   144  		BehaviourPenalty:   float32(bPenalty),
   145  		ValidationError:    errorToString(peers.Scorers().ValidationError(pid)),
   146  	}
   147  	return &pbrpc.DebugPeerResponse{
   148  		ListeningAddresses: stringAddrs,
   149  		Direction:          pbDirection,
   150  		ConnectionState:    ethpb.ConnectionState(connState),
   151  		PeerId:             pid.String(),
   152  		Enr:                enr,
   153  		PeerInfo:           peerInfo,
   154  		PeerStatus:         pStatus,
   155  		LastUpdated:        unixTime,
   156  		ScoreInfo:          scoreInfo,
   157  	}, nil
   158  }
   159  
   160  func errorToString(err error) string {
   161  	if err == nil {
   162  		return ""
   163  	}
   164  	return err.Error()
   165  }