2020-10-14 06:11:11 +00:00
|
|
|
package nodev1
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-01-05 21:06:51 +00:00
|
|
|
"fmt"
|
|
|
|
"runtime"
|
2020-10-14 06:11:11 +00:00
|
|
|
|
|
|
|
ptypes "github.com/gogo/protobuf/types"
|
2021-01-14 16:26:16 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2020-10-14 06:11:11 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1"
|
2021-01-14 16:26:16 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers/peerdata"
|
2021-01-05 21:06:51 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/version"
|
2021-01-06 20:11:20 +00:00
|
|
|
"go.opencensus.io/trace"
|
2021-01-12 16:20:20 +00:00
|
|
|
"google.golang.org/grpc/codes"
|
2021-01-06 20:11:20 +00:00
|
|
|
"google.golang.org/grpc/status"
|
2020-10-14 06:11:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// GetIdentity retrieves data about the node's network presence.
|
|
|
|
func (ns *Server) GetIdentity(ctx context.Context, _ *ptypes.Empty) (*ethpb.IdentityResponse, error) {
|
2021-01-14 20:48:40 +00:00
|
|
|
ctx, span := trace.StartSpan(ctx, "nodeV1.GetIdentity")
|
|
|
|
defer span.End()
|
|
|
|
|
|
|
|
peerId := ns.PeerManager.PeerID().Pretty()
|
|
|
|
|
|
|
|
serializedEnr, err := p2p.SerializeENR(ns.PeerManager.ENR())
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "could not obtain enr: %v", err)
|
|
|
|
}
|
|
|
|
enr := "enr:" + serializedEnr
|
|
|
|
|
|
|
|
sourcep2p := ns.PeerManager.Host().Addrs()
|
|
|
|
p2pAddresses := make([]string, len(sourcep2p))
|
|
|
|
for i := range sourcep2p {
|
|
|
|
p2pAddresses[i] = sourcep2p[i].String() + "/p2p/" + peerId
|
|
|
|
}
|
|
|
|
|
|
|
|
sourceDisc, err := ns.PeerManager.DiscoveryAddresses()
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "could not obtain discovery address: %v", err)
|
|
|
|
}
|
|
|
|
discoveryAddresses := make([]string, len(sourceDisc))
|
|
|
|
for i := range sourceDisc {
|
|
|
|
discoveryAddresses[i] = sourceDisc[i].String()
|
|
|
|
}
|
|
|
|
|
|
|
|
metadata := ðpb.Metadata{
|
|
|
|
SeqNumber: ns.MetadataProvider.MetadataSeq(),
|
|
|
|
Attnets: ns.MetadataProvider.Metadata().Attnets,
|
|
|
|
}
|
|
|
|
|
|
|
|
return ðpb.IdentityResponse{
|
|
|
|
Data: ðpb.Identity{
|
|
|
|
PeerId: peerId,
|
|
|
|
Enr: enr,
|
|
|
|
P2PAddresses: p2pAddresses,
|
|
|
|
DiscoveryAddresses: discoveryAddresses,
|
|
|
|
Metadata: metadata,
|
|
|
|
},
|
|
|
|
}, nil
|
2020-10-14 06:11:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetPeer retrieves data about the given peer.
|
|
|
|
func (ns *Server) GetPeer(ctx context.Context, req *ethpb.PeerRequest) (*ethpb.PeerResponse, error) {
|
2021-01-14 16:26:16 +00:00
|
|
|
ctx, span := trace.StartSpan(ctx, "nodev1.GetPeer")
|
|
|
|
defer span.End()
|
|
|
|
|
|
|
|
peerStatus := ns.PeersFetcher.Peers()
|
|
|
|
id, err := peer.IDFromString(req.PeerId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.InvalidArgument, "Invalid peer ID: "+req.PeerId)
|
|
|
|
}
|
|
|
|
enr, err := peerStatus.ENR(id)
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, peerdata.ErrPeerUnknown) {
|
|
|
|
return nil, status.Error(codes.NotFound, "Peer not found")
|
|
|
|
}
|
|
|
|
return nil, status.Errorf(codes.Internal, "Could not obtain ENR: %v", err)
|
|
|
|
}
|
|
|
|
serializedEnr, err := p2p.SerializeENR(enr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "Could not obtain ENR: %v", err)
|
|
|
|
}
|
|
|
|
p2pAddress, err := peerStatus.Address(id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "Could not obtain address: %v", err)
|
|
|
|
}
|
|
|
|
state, err := peerStatus.ConnectionState(id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "Could not obtain state: %v", err)
|
|
|
|
}
|
|
|
|
direction, err := peerStatus.Direction(id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "Could not obtain direction: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ðpb.PeerResponse{
|
|
|
|
Data: ðpb.Peer{
|
|
|
|
PeerId: req.PeerId,
|
|
|
|
Enr: "enr:" + serializedEnr,
|
|
|
|
Address: p2pAddress.String(),
|
|
|
|
State: ethpb.ConnectionState(state),
|
|
|
|
Direction: ethpb.PeerDirection(direction),
|
|
|
|
},
|
|
|
|
}, nil
|
2020-10-14 06:11:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ListPeers retrieves data about the node's network peers.
|
|
|
|
func (ns *Server) ListPeers(ctx context.Context, _ *ptypes.Empty) (*ethpb.PeersResponse, error) {
|
|
|
|
return nil, errors.New("unimplemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetVersion requests that the beacon node identify information about its implementation in a
|
|
|
|
// format similar to a HTTP User-Agent field.
|
2021-01-06 20:11:20 +00:00
|
|
|
func (ns *Server) GetVersion(ctx context.Context, _ *ptypes.Empty) (*ethpb.VersionResponse, error) {
|
|
|
|
ctx, span := trace.StartSpan(ctx, "nodev1.GetVersion")
|
|
|
|
defer span.End()
|
|
|
|
|
2021-01-05 21:06:51 +00:00
|
|
|
v := fmt.Sprintf("Prysm/%s (%s %s)", version.GetSemanticVersion(), runtime.GOOS, runtime.GOARCH)
|
|
|
|
return ðpb.VersionResponse{
|
|
|
|
Data: ðpb.Version{
|
|
|
|
Version: v,
|
|
|
|
},
|
|
|
|
}, nil
|
2020-10-14 06:11:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetSyncStatus requests the beacon node to describe if it's currently syncing or not, and
|
|
|
|
// if it is, what block it is up to.
|
2021-01-12 17:17:20 +00:00
|
|
|
func (ns *Server) GetSyncStatus(_ context.Context, _ *ptypes.Empty) (*ethpb.SyncingResponse, error) {
|
|
|
|
headSlot := ns.HeadFetcher.HeadSlot()
|
|
|
|
return ðpb.SyncingResponse{
|
|
|
|
Data: ðpb.SyncInfo{
|
|
|
|
HeadSlot: headSlot,
|
|
|
|
SyncDistance: ns.GenesisTimeFetcher.CurrentSlot() - headSlot,
|
|
|
|
},
|
|
|
|
}, nil
|
2020-10-14 06:11:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetHealth returns node health status in http status codes. Useful for load balancers.
|
|
|
|
// Response Usage:
|
|
|
|
// "200":
|
|
|
|
// description: Node is ready
|
|
|
|
// "206":
|
|
|
|
// description: Node is syncing but can serve incomplete data
|
|
|
|
// "503":
|
|
|
|
// description: Node not initialized or having issues
|
|
|
|
func (ns *Server) GetHealth(ctx context.Context, _ *ptypes.Empty) (*ptypes.Empty, error) {
|
2021-01-06 20:11:20 +00:00
|
|
|
ctx, span := trace.StartSpan(ctx, "nodev1.GetHealth")
|
|
|
|
defer span.End()
|
|
|
|
|
|
|
|
if ns.SyncChecker.Syncing() || ns.SyncChecker.Initialized() {
|
|
|
|
return &ptypes.Empty{}, nil
|
|
|
|
}
|
2021-01-14 16:26:16 +00:00
|
|
|
return &ptypes.Empty{}, status.Error(codes.Internal, "Node not initialized or having issues")
|
2020-10-14 06:11:11 +00:00
|
|
|
}
|