HTTP Beacon APIs for node (#13010)

This commit is contained in:
Radosław Kapka
2023-10-11 22:18:49 +02:00
committed by GitHub
parent c5501f8775
commit a536612c39
32 changed files with 1093 additions and 3011 deletions

View File

@@ -52,7 +52,6 @@ func DefaultConfig(enableDebugRPCEndpoints bool, httpModules string) MuxConfig {
}
if flags.EnableHTTPEthAPI(httpModules) {
ethRegistrations := []gateway.PbHandlerRegistration{
ethpbservice.RegisterBeaconNodeHandler,
ethpbservice.RegisterBeaconChainHandler,
ethpbservice.RegisterBeaconValidatorHandler,
ethpbservice.RegisterEventsHandler,

View File

@@ -15,7 +15,7 @@ func TestDefaultConfig(t *testing.T) {
require.Equal(t, 2, len(cfg.EthPbMux.Patterns))
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, "/internal/eth/v2/", cfg.EthPbMux.Patterns[1])
assert.Equal(t, 4, len(cfg.EthPbMux.Registrations))
assert.Equal(t, 3, len(cfg.EthPbMux.Registrations))
assert.NotNil(t, cfg.V1AlphaPbMux.Mux)
require.Equal(t, 2, len(cfg.V1AlphaPbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1AlphaPbMux.Patterns[0])
@@ -29,7 +29,7 @@ func TestDefaultConfig(t *testing.T) {
require.Equal(t, 2, len(cfg.EthPbMux.Patterns))
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, "/internal/eth/v2/", cfg.EthPbMux.Patterns[1])
assert.Equal(t, 5, len(cfg.EthPbMux.Registrations))
assert.Equal(t, 4, len(cfg.EthPbMux.Registrations))
assert.NotNil(t, cfg.V1AlphaPbMux.Mux)
require.Equal(t, 2, len(cfg.V1AlphaPbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1AlphaPbMux.Patterns[0])
@@ -41,7 +41,7 @@ func TestDefaultConfig(t *testing.T) {
assert.NotNil(t, cfg.EthPbMux.Mux)
require.Equal(t, 2, len(cfg.EthPbMux.Patterns))
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, 5, len(cfg.EthPbMux.Registrations))
assert.Equal(t, 4, len(cfg.EthPbMux.Registrations))
assert.Equal(t, (*gateway.PbMux)(nil), cfg.V1AlphaPbMux)
})
t.Run("Without Eth API", func(t *testing.T) {

View File

@@ -16,7 +16,6 @@ go_library(
"//api/gateway/apimiddleware:go_default_library",
"//api/grpc:go_default_library",
"//beacon-chain/rpc/eth/events:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
"//network/http:go_default_library",

View File

@@ -27,12 +27,6 @@ func (_ *BeaconEndpointFactory) Paths() []string {
"/eth/v1/beacon/pool/attester_slashings",
"/eth/v1/beacon/pool/proposer_slashings",
"/eth/v1/beacon/weak_subjectivity",
"/eth/v1/node/identity",
"/eth/v1/node/peers",
"/eth/v1/node/peers/{peer_id}",
"/eth/v1/node/peer_count",
"/eth/v1/node/version",
"/eth/v1/node/health",
"/eth/v1/debug/beacon/states/{state_id}",
"/eth/v2/debug/beacon/states/{state_id}",
"/eth/v1/debug/beacon/heads",
@@ -87,20 +81,6 @@ func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, er
endpoint.GetResponse = &ProposerSlashingsPoolResponseJson{}
case "/eth/v1/beacon/weak_subjectivity":
endpoint.GetResponse = &WeakSubjectivityResponse{}
case "/eth/v1/node/identity":
endpoint.GetResponse = &IdentityResponseJson{}
case "/eth/v1/node/peers":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "state", Enum: true}, {Name: "direction", Enum: true}}
endpoint.GetResponse = &PeersResponseJson{}
case "/eth/v1/node/peers/{peer_id}":
endpoint.RequestURLLiterals = []string{"peer_id"}
endpoint.GetResponse = &PeerResponseJson{}
case "/eth/v1/node/peer_count":
endpoint.GetResponse = &PeerCountResponseJson{}
case "/eth/v1/node/version":
endpoint.GetResponse = &VersionResponseJson{}
case "/eth/v1/node/health":
// Use default endpoint
case "/eth/v1/debug/beacon/states/{state_id}":
endpoint.GetResponse = &BeaconStateResponseJson{}
endpoint.CustomHandlers = []apimiddleware.CustomHandler{handleGetBeaconStateSSZ}

View File

@@ -4,7 +4,6 @@ import (
"strings"
"github.com/prysmaticlabs/prysm/v4/api/gateway/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
)
@@ -83,37 +82,6 @@ type ProposerSlashingsPoolResponseJson struct {
Data []*ProposerSlashingJson `json:"data"`
}
type IdentityResponseJson struct {
Data *IdentityJson `json:"data"`
}
type PeersResponseJson struct {
Data []*PeerJson `json:"data"`
}
type PeerResponseJson struct {
Data *PeerJson `json:"data"`
}
type PeerCountResponseJson struct {
Data PeerCountResponse_PeerCountJson `json:"data"`
}
type PeerCountResponse_PeerCountJson struct {
Disconnected string `json:"disconnected"`
Connecting string `json:"connecting"`
Connected string `json:"connected"`
Disconnecting string `json:"disconnecting"`
}
type VersionResponseJson struct {
Data *VersionJson `json:"data"`
}
type SyncingResponseJson struct {
Data *shared.SyncDetails `json:"data"`
}
type BeaconStateResponseJson struct {
Data *BeaconStateJson `json:"data"`
}
@@ -726,31 +694,6 @@ type VoluntaryExitJson struct {
ValidatorIndex string `json:"validator_index"`
}
type IdentityJson struct {
PeerId string `json:"peer_id"`
Enr string `json:"enr"`
P2PAddresses []string `json:"p2p_addresses"`
DiscoveryAddresses []string `json:"discovery_addresses"`
Metadata *MetadataJson `json:"metadata"`
}
type MetadataJson struct {
SeqNumber string `json:"seq_number"`
Attnets string `json:"attnets" hex:"true"`
}
type PeerJson struct {
PeerId string `json:"peer_id"`
Enr string `json:"enr"`
Address string `json:"last_seen_p2p_address"`
State string `json:"state" enum:"true"`
Direction string `json:"direction" enum:"true"`
}
type VersionJson struct {
Version string `json:"version" enum:"true"`
}
type WithdrawalJson struct {
WithdrawalIndex string `json:"index"`
ValidatorIndex string `json:"validator_index"`

View File

@@ -4,47 +4,43 @@ go_library(
name = "go_default_library",
srcs = [
"handlers.go",
"node.go",
"handlers_peers.go",
"server.go",
"structs.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node",
visibility = ["//beacon-chain:__subpackages__"],
visibility = ["//visibility:public"],
deps = [
"//api/grpc:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/execution:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/p2p/peers:go_default_library",
"//beacon-chain/p2p/peers/peerdata:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/sync:go_default_library",
"//network/http:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/migration:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_libp2p_go_libp2p//core/peer:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"handlers_peers_test.go",
"handlers_test.go",
"node_test.go",
"server_test.go",
],
embed = [":go_default_library"],
deps = [
"//api/grpc:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/p2p/peers:go_default_library",
@@ -53,8 +49,7 @@ go_test(
"//beacon-chain/sync/initial-sync/testing:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/wrapper:go_default_library",
"//proto/eth/service:go_default_library",
"//proto/eth/v1:go_default_library",
"//network/http:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
@@ -62,13 +57,11 @@ go_test(
"//testing/util:go_default_library",
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_libp2p_go_libp2p//core/network:go_default_library",
"@com_github_libp2p_go_libp2p//core/peer:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/host/peerstore/test:go_default_library",
"@com_github_multiformats_go_multiaddr//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
],
)

View File

@@ -1,13 +1,29 @@
package node
import (
"fmt"
"net/http"
"runtime"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"go.opencensus.io/trace"
)
var (
stateConnecting = ethpb.ConnectionState_CONNECTING.String()
stateConnected = ethpb.ConnectionState_CONNECTED.String()
stateDisconnecting = ethpb.ConnectionState_DISCONNECTING.String()
stateDisconnected = ethpb.ConnectionState_DISCONNECTED.String()
directionInbound = ethpb.PeerDirection_INBOUND.String()
directionOutbound = ethpb.PeerDirection_OUTBOUND.String()
)
// GetSyncStatus requests the beacon node to describe if it's currently syncing or not, and
// if it is, what block it is up to.
func (s *Server) GetSyncStatus(w http.ResponseWriter, r *http.Request) {
@@ -32,3 +48,86 @@ func (s *Server) GetSyncStatus(w http.ResponseWriter, r *http.Request) {
}
http2.WriteJson(w, response)
}
// GetIdentity retrieves data about the node's network presence.
func (s *Server) GetIdentity(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.GetIdentity")
defer span.End()
peerId := s.PeerManager.PeerID().String()
sourcep2p := s.PeerManager.Host().Addrs()
p2pAddresses := make([]string, len(sourcep2p))
for i := range sourcep2p {
p2pAddresses[i] = sourcep2p[i].String() + "/p2p/" + peerId
}
sourceDisc, err := s.PeerManager.DiscoveryAddresses()
if err != nil {
http2.HandleError(w, "Could not obtain discovery address: "+err.Error(), http.StatusInternalServerError)
return
}
discoveryAddresses := make([]string, len(sourceDisc))
for i := range sourceDisc {
discoveryAddresses[i] = sourceDisc[i].String()
}
serializedEnr, err := p2p.SerializeENR(s.PeerManager.ENR())
if err != nil {
http2.HandleError(w, "Could not obtain enr: "+err.Error(), http.StatusInternalServerError)
return
}
resp := &GetIdentityResponse{
Data: &Identity{
PeerId: peerId,
Enr: "enr:" + serializedEnr,
P2PAddresses: p2pAddresses,
DiscoveryAddresses: discoveryAddresses,
Metadata: &Metadata{
SeqNumber: strconv.FormatUint(s.MetadataProvider.MetadataSeq(), 10),
Attnets: hexutil.Encode(s.MetadataProvider.Metadata().AttnetsBitfield()),
},
},
}
http2.WriteJson(w, resp)
}
// GetVersion requests that the beacon node identify information about its implementation in a
// format similar to a HTTP User-Agent field.
func (*Server) GetVersion(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.GetVersion")
defer span.End()
v := fmt.Sprintf("Prysm/%s (%s %s)", version.SemanticVersion(), runtime.GOOS, runtime.GOARCH)
resp := &GetVersionResponse{
Data: &Version{
Version: v,
},
}
http2.WriteJson(w, resp)
}
// GetHealth returns node health status in http status codes. Useful for load balancers.
func (s *Server) GetHealth(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.GetHealth")
defer span.End()
ok, rawSyncingStatus, syncingStatus := shared.UintFromQuery(w, r, "syncing_status")
// lint:ignore uintcast -- custom syncing status being outside of range is harmless
intSyncingStatus := int(syncingStatus)
if !ok || (rawSyncingStatus != "" && http.StatusText(intSyncingStatus) == "") {
http2.HandleError(w, "syncing_status is not a valid HTTP status code", http.StatusBadRequest)
return
}
if s.SyncChecker.Synced() {
return
}
if s.SyncChecker.Syncing() || s.SyncChecker.Initialized() {
if rawSyncingStatus != "" {
w.WriteHeader(intSyncingStatus)
} else {
w.WriteHeader(http.StatusPartialContent)
}
return
}
w.WriteHeader(http.StatusServiceUnavailable)
}

View File

@@ -0,0 +1,279 @@
package node
import (
"net/http"
"strconv"
"strings"
"github.com/gorilla/mux"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers/peerdata"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"go.opencensus.io/trace"
)
// GetPeer retrieves data about the given peer.
func (s *Server) GetPeer(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.GetPeer")
defer span.End()
rawId := mux.Vars(r)["peer_id"]
if rawId == "" {
http2.HandleError(w, "peer_id is required in URL params", http.StatusBadRequest)
return
}
peerStatus := s.PeersFetcher.Peers()
id, err := peer.Decode(rawId)
if err != nil {
http2.HandleError(w, "Invalid peer ID: "+err.Error(), http.StatusBadRequest)
return
}
enr, err := peerStatus.ENR(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
http2.HandleError(w, "Peer not found: "+err.Error(), http.StatusNotFound)
return
}
http2.HandleError(w, "Could not obtain ENR: "+err.Error(), http.StatusInternalServerError)
return
}
serializedEnr, err := p2p.SerializeENR(enr)
if err != nil {
http2.HandleError(w, "Could not obtain ENR: "+err.Error(), http.StatusInternalServerError)
return
}
p2pAddress, err := peerStatus.Address(id)
if err != nil {
http2.HandleError(w, "Could not obtain address: "+err.Error(), http.StatusInternalServerError)
return
}
state, err := peerStatus.ConnectionState(id)
if err != nil {
http2.HandleError(w, "Could not obtain connection state: "+err.Error(), http.StatusInternalServerError)
return
}
direction, err := peerStatus.Direction(id)
if err != nil {
http2.HandleError(w, "Could not obtain direction: "+err.Error(), http.StatusInternalServerError)
return
}
if eth.PeerDirection(direction) == eth.PeerDirection_UNKNOWN {
http2.HandleError(w, "Peer not found", http.StatusNotFound)
return
}
v1ConnState := migration.V1Alpha1ConnectionStateToV1(eth.ConnectionState(state))
v1PeerDirection, err := migration.V1Alpha1PeerDirectionToV1(eth.PeerDirection(direction))
if err != nil {
http2.HandleError(w, "Could not handle peer direction: "+err.Error(), http.StatusInternalServerError)
return
}
resp := &GetPeerResponse{
Data: &Peer{
PeerId: rawId,
Enr: "enr:" + serializedEnr,
LastSeenP2PAddress: p2pAddress.String(),
State: strings.ToLower(v1ConnState.String()),
Direction: strings.ToLower(v1PeerDirection.String()),
},
}
http2.WriteJson(w, resp)
}
// GetPeers retrieves data about the node's network peers.
func (s *Server) GetPeers(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.GetPeers")
defer span.End()
states := r.URL.Query()["state"]
directions := r.URL.Query()["direction"]
peerStatus := s.PeersFetcher.Peers()
emptyStateFilter, emptyDirectionFilter := handleEmptyFilters(states, directions)
if emptyStateFilter && emptyDirectionFilter {
allIds := peerStatus.All()
allPeers := make([]*Peer, 0, len(allIds))
for _, id := range allIds {
p, err := peerInfo(peerStatus, id)
if err != nil {
http2.HandleError(w, "Could not get peer info: "+err.Error(), http.StatusInternalServerError)
return
}
if p == nil {
continue
}
allPeers = append(allPeers, p)
}
resp := &GetPeersResponse{Data: allPeers}
http2.WriteJson(w, resp)
return
}
var stateIds []peer.ID
if emptyStateFilter {
stateIds = peerStatus.All()
} else {
for _, stateFilter := range states {
switch strings.ToUpper(stateFilter) {
case stateConnecting:
ids := peerStatus.Connecting()
stateIds = append(stateIds, ids...)
case stateConnected:
ids := peerStatus.Connected()
stateIds = append(stateIds, ids...)
case stateDisconnecting:
ids := peerStatus.Disconnecting()
stateIds = append(stateIds, ids...)
case stateDisconnected:
ids := peerStatus.Disconnected()
stateIds = append(stateIds, ids...)
}
}
}
var directionIds []peer.ID
if emptyDirectionFilter {
directionIds = peerStatus.All()
} else {
for _, directionFilter := range directions {
switch strings.ToUpper(directionFilter) {
case directionInbound:
ids := peerStatus.Inbound()
directionIds = append(directionIds, ids...)
case directionOutbound:
ids := peerStatus.Outbound()
directionIds = append(directionIds, ids...)
}
}
}
var filteredIds []peer.ID
for _, stateId := range stateIds {
for _, directionId := range directionIds {
if stateId.String() == directionId.String() {
filteredIds = append(filteredIds, stateId)
break
}
}
}
filteredPeers := make([]*Peer, 0, len(filteredIds))
for _, id := range filteredIds {
p, err := peerInfo(peerStatus, id)
if err != nil {
http2.HandleError(w, "Could not get peer info: "+err.Error(), http.StatusInternalServerError)
return
}
if p == nil {
continue
}
filteredPeers = append(filteredPeers, p)
}
resp := &GetPeersResponse{Data: filteredPeers}
http2.WriteJson(w, resp)
}
// GetPeerCount retrieves number of known peers.
func (s *Server) GetPeerCount(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "node.PeerCount")
defer span.End()
peerStatus := s.PeersFetcher.Peers()
resp := &GetPeerCountResponse{
Data: &PeerCount{
Disconnected: strconv.FormatInt(int64(len(peerStatus.Disconnected())), 10),
Connecting: strconv.FormatInt(int64(len(peerStatus.Connecting())), 10),
Connected: strconv.FormatInt(int64(len(peerStatus.Connected())), 10),
Disconnecting: strconv.FormatInt(int64(len(peerStatus.Disconnecting())), 10),
},
}
http2.WriteJson(w, resp)
}
func handleEmptyFilters(states []string, directions []string) (emptyState, emptyDirection bool) {
emptyState = true
for _, stateFilter := range states {
normalized := strings.ToUpper(stateFilter)
filterValid := normalized == stateConnecting || normalized == stateConnected ||
normalized == stateDisconnecting || normalized == stateDisconnected
if filterValid {
emptyState = false
break
}
}
emptyDirection = true
for _, directionFilter := range directions {
normalized := strings.ToUpper(directionFilter)
filterValid := normalized == directionInbound || normalized == directionOutbound
if filterValid {
emptyDirection = false
break
}
}
return emptyState, emptyDirection
}
func peerInfo(peerStatus *peers.Status, id peer.ID) (*Peer, error) {
enr, err := peerStatus.ENR(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain ENR")
}
var serializedEnr string
if enr != nil {
serializedEnr, err = p2p.SerializeENR(enr)
if err != nil {
return nil, errors.Wrap(err, "could not serialize ENR")
}
}
address, err := peerStatus.Address(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain address")
}
connectionState, err := peerStatus.ConnectionState(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain connection state")
}
direction, err := peerStatus.Direction(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain direction")
}
if eth.PeerDirection(direction) == eth.PeerDirection_UNKNOWN {
return nil, nil
}
p := &Peer{
PeerId: id.String(),
State: strings.ToLower(eth.ConnectionState(connectionState).String()),
Direction: strings.ToLower(eth.PeerDirection(direction).String()),
}
if address != nil {
p.LastSeenP2PAddress = address.String()
}
if serializedEnr != "" {
p.Enr = "enr:" + serializedEnr
}
return p, nil
}

View File

@@ -0,0 +1,346 @@
package node
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/gorilla/mux"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
libp2ptest "github.com/libp2p/go-libp2p/p2p/host/peerstore/test"
ma "github.com/multiformats/go-multiaddr"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers"
mockp2p "github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/testing"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
func TestGetPeer(t *testing.T) {
const rawId = "16Uiu2HAkvyYtoQXZNTsthjgLHjEnv7kvwzEmjvsJjWXpbhtqpSUN"
decodedId, err := peer.Decode(rawId)
require.NoError(t, err)
enrRecord := &enr.Record{}
err = enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
const p2pAddr = "/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
peerFetcher := &mockp2p.MockPeersProvider{}
s := Server{PeersFetcher: peerFetcher}
peerFetcher.Peers().Add(enrRecord, decodedId, p2pMultiAddr, network.DirInbound)
t.Run("OK", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers/{peer_id}", nil)
request = mux.SetURLVars(request, map[string]string{"peer_id": rawId})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeer(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetPeerResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, rawId, resp.Data.PeerId)
assert.Equal(t, p2pAddr, resp.Data.LastSeenP2PAddress)
assert.Equal(t, "enr:yoABgmlwhAcHBwc", resp.Data.Enr)
assert.Equal(t, "disconnected", resp.Data.State)
assert.Equal(t, "inbound", resp.Data.Direction)
})
t.Run("Invalid ID", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers/{peer_id}", nil)
request = mux.SetURLVars(request, map[string]string{"peer_id": "foo"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeer(writer, request)
require.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "Invalid peer ID", e.Message)
})
t.Run("Peer not found", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers/{peer_id}", nil)
request = mux.SetURLVars(request, map[string]string{"peer_id": "16Uiu2HAmQqFdEcHbSmQTQuLoAhnMUrgoWoraKK4cUJT6FuuqHqTU"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeer(writer, request)
require.Equal(t, http.StatusNotFound, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusNotFound, e.Code)
assert.StringContains(t, "Peer not found", e.Message)
})
}
func TestGetPeers(t *testing.T) {
ids := libp2ptest.GeneratePeerIDs(9)
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
peerStatus := peerFetcher.Peers()
for i, id := range ids {
// Make last peer undiscovered
if i == len(ids)-1 {
peerStatus.Add(nil, id, nil, network.DirUnknown)
} else {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{127, 0, 0, byte(i)})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
var p2pAddr = "/ip4/127.0.0." + strconv.Itoa(i) + "/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
var direction network.Direction
if i%2 == 0 {
direction = network.DirInbound
} else {
direction = network.DirOutbound
}
peerStatus.Add(enrRecord, id, p2pMultiAddr, direction)
switch i {
case 0, 1:
peerStatus.SetConnectionState(id, peers.PeerConnecting)
case 2, 3:
peerStatus.SetConnectionState(id, peers.PeerConnected)
case 4, 5:
peerStatus.SetConnectionState(id, peers.PeerDisconnecting)
case 6, 7:
peerStatus.SetConnectionState(id, peers.PeerDisconnected)
default:
t.Fatalf("Failed to set connection state for peer")
}
}
}
s := Server{PeersFetcher: peerFetcher}
t.Run("OK", func(t *testing.T) {
// We will check the first peer from the list.
expectedId := ids[0]
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers?state=connecting&direction=inbound", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeers(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetPeersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 1, len(resp.Data))
returnedPeer := resp.Data[0]
assert.Equal(t, expectedId.Pretty(), returnedPeer.PeerId)
expectedEnr, err := peerStatus.ENR(expectedId)
require.NoError(t, err)
serializedEnr, err := p2p.SerializeENR(expectedEnr)
require.NoError(t, err)
assert.Equal(t, "enr:"+serializedEnr, returnedPeer.Enr)
expectedP2PAddr, err := peerStatus.Address(expectedId)
require.NoError(t, err)
assert.Equal(t, expectedP2PAddr.String(), returnedPeer.LastSeenP2PAddress)
assert.Equal(t, "connecting", returnedPeer.State)
assert.Equal(t, "inbound", returnedPeer.Direction)
})
filterTests := []struct {
name string
states []string
directions []string
wantIds []peer.ID
}{
{
name: "No filters - return all peers",
states: []string{},
directions: []string{},
wantIds: ids[:len(ids)-1], // Excluding last peer as it is not connected.
},
{
name: "State filter empty - return peers for all states",
states: []string{},
directions: []string{"inbound"},
wantIds: []peer.ID{ids[0], ids[2], ids[4], ids[6]},
},
{
name: "Direction filter empty - return peers for all directions",
states: []string{"connected"},
directions: []string{},
wantIds: []peer.ID{ids[2], ids[3]},
},
{
name: "One state and direction",
states: []string{"disconnected"},
directions: []string{"inbound"},
wantIds: []peer.ID{ids[6]},
},
{
name: "Multiple states and directions",
states: []string{"connecting", "disconnecting"},
directions: []string{"inbound", "outbound"},
wantIds: []peer.ID{ids[0], ids[1], ids[4], ids[5]},
},
{
name: "Unknown filter is ignored",
states: []string{"connected", "foo"},
directions: []string{"outbound", "foo"},
wantIds: []peer.ID{ids[3]},
},
{
name: "Only unknown filters - return all peers",
states: []string{"foo"},
directions: []string{"foo"},
wantIds: ids[:len(ids)-1], // Excluding last peer as it is not connected.
},
}
for _, tt := range filterTests {
t.Run(tt.name, func(t *testing.T) {
states := strings.Join(tt.states, "&state=")
statesQuery := ""
if states != "" {
statesQuery = "state=" + states
}
directions := strings.Join(tt.directions, "&direction=")
directionsQuery := ""
if directions != "" {
directionsQuery = "direction=" + directions
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers?"+statesQuery+"&"+directionsQuery, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeers(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetPeersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, len(tt.wantIds), len(resp.Data), "Wrong number of peers returned")
for _, id := range tt.wantIds {
expectedId := id.Pretty()
found := false
for _, returnedPeer := range resp.Data {
if returnedPeer.PeerId == expectedId {
found = true
break
}
}
if !found {
t.Errorf("Expected ID '" + expectedId + "' not found")
}
}
})
}
}
func TestGetPeers_NoPeersReturnsEmptyArray(t *testing.T) {
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
s := Server{PeersFetcher: peerFetcher}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers?state=connecting&state=connected", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeers(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetPeersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 0, len(resp.Data))
}
func TestGetPeerCount(t *testing.T) {
ids := libp2ptest.GeneratePeerIDs(10)
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
peerStatus := peerFetcher.Peers()
for i, id := range ids {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{127, 0, 0, byte(i)})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
var p2pAddr = "/ip4/127.0.0." + strconv.Itoa(i) + "/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
var direction network.Direction
if i%2 == 0 {
direction = network.DirInbound
} else {
direction = network.DirOutbound
}
peerStatus.Add(enrRecord, id, p2pMultiAddr, direction)
switch i {
case 0:
peerStatus.SetConnectionState(id, peers.PeerConnecting)
case 1, 2:
peerStatus.SetConnectionState(id, peers.PeerConnected)
case 3, 4, 5:
peerStatus.SetConnectionState(id, peers.PeerDisconnecting)
case 6, 7, 8, 9:
peerStatus.SetConnectionState(id, peers.PeerDisconnected)
default:
t.Fatalf("Failed to set connection state for peer")
}
}
s := Server{PeersFetcher: peerFetcher}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peer_count", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeerCount(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetPeerCountResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "1", resp.Data.Connecting, "Wrong number of connecting peers")
assert.Equal(t, "2", resp.Data.Connected, "Wrong number of connected peers")
assert.Equal(t, "3", resp.Data.Disconnecting, "Wrong number of disconnecting peers")
assert.Equal(t, "4", resp.Data.Disconnected, "Wrong number of disconnected peers")
}
func BenchmarkGetPeers(b *testing.B) {
// We simulate having a lot of peers.
ids := libp2ptest.GeneratePeerIDs(2000)
peerFetcher := &mockp2p.MockPeersProvider{}
for _, id := range ids {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(b, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(b, err)
const p2pAddr = "/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(b, err)
peerFetcher.Peers().Add(enrRecord, id, p2pMultiAddr, network.DirInbound)
}
s := Server{PeersFetcher: peerFetcher}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/peers", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetPeers(writer, request)
b.ResetTimer()
for i := 0; i < b.N; i++ {
s.GetPeers(writer, request)
}
}

View File

@@ -3,19 +3,37 @@ package node
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"runtime"
"testing"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
"github.com/prysmaticlabs/go-bitfield"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
mockp2p "github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
syncmock "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/wrapper"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
type dummyIdentity enode.ID
func (_ dummyIdentity) Verify(_ *enr.Record, _ []byte) error { return nil }
func (id dummyIdentity) NodeAddr(_ *enr.Record) []byte { return id[:] }
func TestSyncStatus(t *testing.T) {
currentSlot := new(primitives.Slot)
*currentSlot = 110
@@ -50,3 +68,164 @@ func TestSyncStatus(t *testing.T) {
assert.Equal(t, true, resp.Data.IsOptimistic)
assert.Equal(t, false, resp.Data.ElOffline)
}
func TestGetVersion(t *testing.T) {
semVer := version.SemanticVersion()
os := runtime.GOOS
arch := runtime.GOARCH
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/version", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s := &Server{}
s.GetVersion(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetVersionResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.StringContains(t, semVer, resp.Data.Version)
assert.StringContains(t, os, resp.Data.Version)
assert.StringContains(t, arch, resp.Data.Version)
}
func TestGetHealth(t *testing.T) {
checker := &syncmock.Sync{}
s := &Server{
SyncChecker: checker,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/health", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetHealth(writer, request)
assert.Equal(t, http.StatusServiceUnavailable, writer.Code)
checker.IsInitialized = true
request = httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/health", nil)
writer = httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetHealth(writer, request)
assert.Equal(t, http.StatusPartialContent, writer.Code)
request = httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://example.com/eth/v1/node/health?syncing_status=%d", http.StatusPaymentRequired), nil)
writer = httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetHealth(writer, request)
assert.Equal(t, http.StatusPaymentRequired, writer.Code)
checker.IsSynced = true
request = httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/health", nil)
writer = httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetHealth(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
}
func TestGetIdentity(t *testing.T) {
p2pAddr, err := ma.NewMultiaddr("/ip4/7.7.7.7/udp/30303")
require.NoError(t, err)
discAddr1, err := ma.NewMultiaddr("/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
require.NoError(t, err)
discAddr2, err := ma.NewMultiaddr("/ip6/1:2:3:4:5:6:7:8/udp/20202/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
require.NoError(t, err)
enrRecord := &enr.Record{}
err = enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
attnets := bitfield.NewBitvector64()
attnets.SetBitAt(1, true)
metadataProvider := &mockp2p.MockMetadataProvider{Data: wrapper.WrappedMetadataV0(&pb.MetaDataV0{SeqNumber: 1, Attnets: attnets})}
t.Run("OK", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: enrRecord,
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/identity", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetIdentity(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetIdentityResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
expectedID := peer.ID("foo").Pretty()
assert.Equal(t, expectedID, resp.Data.PeerId)
expectedEnr, err := p2p.SerializeENR(enrRecord)
require.NoError(t, err)
assert.Equal(t, fmt.Sprint("enr:", expectedEnr), resp.Data.Enr)
require.Equal(t, 1, len(resp.Data.P2PAddresses))
assert.Equal(t, p2pAddr.String()+"/p2p/"+expectedID, resp.Data.P2PAddresses[0])
require.Equal(t, 2, len(resp.Data.DiscoveryAddresses))
ipv4Found, ipv6Found := false, false
for _, address := range resp.Data.DiscoveryAddresses {
if address == discAddr1.String() {
ipv4Found = true
} else if address == discAddr2.String() {
ipv6Found = true
}
}
assert.Equal(t, true, ipv4Found, "IPv4 discovery address not found")
assert.Equal(t, true, ipv6Found, "IPv6 discovery address not found")
assert.Equal(t, discAddr1.String(), resp.Data.DiscoveryAddresses[0])
assert.Equal(t, discAddr2.String(), resp.Data.DiscoveryAddresses[1])
})
t.Run("ENR failure", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: &enr.Record{},
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/identity", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetIdentity(writer, request)
require.Equal(t, http.StatusInternalServerError, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusInternalServerError, e.Code)
assert.StringContains(t, "Could not obtain enr", e.Message)
})
t.Run("Discovery addresses failure", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: enrRecord,
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
FailDiscoveryAddr: true,
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/node/identity", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetIdentity(writer, request)
require.Equal(t, http.StatusInternalServerError, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusInternalServerError, e.Code)
assert.StringContains(t, "Could not obtain discovery address", e.Message)
})
}

View File

@@ -1,371 +0,0 @@
package node
import (
"context"
"fmt"
"net/http"
"runtime"
"strconv"
"strings"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/pkg/errors"
grpcutil "github.com/prysmaticlabs/prysm/v4/api/grpc"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers/peerdata"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"go.opencensus.io/trace"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
var (
stateConnecting = ethpb.ConnectionState_CONNECTING.String()
stateConnected = ethpb.ConnectionState_CONNECTED.String()
stateDisconnecting = ethpb.ConnectionState_DISCONNECTING.String()
stateDisconnected = ethpb.ConnectionState_DISCONNECTED.String()
directionInbound = ethpb.PeerDirection_INBOUND.String()
directionOutbound = ethpb.PeerDirection_OUTBOUND.String()
)
// GetIdentity retrieves data about the node's network presence.
func (ns *Server) GetIdentity(ctx context.Context, _ *emptypb.Empty) (*ethpb.IdentityResponse, error) {
ctx, span := trace.StartSpan(ctx, "node.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()
}
meta := &ethpb.Metadata{
SeqNumber: ns.MetadataProvider.MetadataSeq(),
Attnets: ns.MetadataProvider.Metadata().AttnetsBitfield(),
}
return &ethpb.IdentityResponse{
Data: &ethpb.Identity{
PeerId: peerId,
Enr: enr,
P2PAddresses: p2pAddresses,
DiscoveryAddresses: discoveryAddresses,
Metadata: meta,
},
}, nil
}
// GetPeer retrieves data about the given peer.
func (ns *Server) GetPeer(ctx context.Context, req *ethpb.PeerRequest) (*ethpb.PeerResponse, error) {
ctx, span := trace.StartSpan(ctx, "node.GetPeer")
defer span.End()
peerStatus := ns.PeersFetcher.Peers()
id, err := peer.Decode(req.PeerId)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Invalid peer ID: %v", err)
}
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 connection state: %v", err)
}
direction, err := peerStatus.Direction(id)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not obtain direction: %v", err)
}
if eth.PeerDirection(direction) == eth.PeerDirection_UNKNOWN {
return nil, status.Error(codes.NotFound, "Peer not found")
}
v1ConnState := migration.V1Alpha1ConnectionStateToV1(eth.ConnectionState(state))
v1PeerDirection, err := migration.V1Alpha1PeerDirectionToV1(eth.PeerDirection(direction))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not handle peer direction: %v", err)
}
return &ethpb.PeerResponse{
Data: &ethpb.Peer{
PeerId: req.PeerId,
Enr: "enr:" + serializedEnr,
LastSeenP2PAddress: p2pAddress.String(),
State: v1ConnState,
Direction: v1PeerDirection,
},
}, nil
}
// ListPeers retrieves data about the node's network peers.
func (ns *Server) ListPeers(ctx context.Context, req *ethpb.PeersRequest) (*ethpb.PeersResponse, error) {
ctx, span := trace.StartSpan(ctx, "node.ListPeers")
defer span.End()
peerStatus := ns.PeersFetcher.Peers()
emptyStateFilter, emptyDirectionFilter := handleEmptyFilters(req)
if emptyStateFilter && emptyDirectionFilter {
allIds := peerStatus.All()
allPeers := make([]*ethpb.Peer, 0, len(allIds))
for _, id := range allIds {
p, err := peerInfo(peerStatus, id)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get peer info: %v", err)
}
if p == nil {
continue
}
allPeers = append(allPeers, p)
}
return &ethpb.PeersResponse{Data: allPeers}, nil
}
var stateIds []peer.ID
if emptyStateFilter {
stateIds = peerStatus.All()
} else {
for _, stateFilter := range req.State {
normalized := strings.ToUpper(stateFilter.String())
if normalized == stateConnecting {
ids := peerStatus.Connecting()
stateIds = append(stateIds, ids...)
continue
}
if normalized == stateConnected {
ids := peerStatus.Connected()
stateIds = append(stateIds, ids...)
continue
}
if normalized == stateDisconnecting {
ids := peerStatus.Disconnecting()
stateIds = append(stateIds, ids...)
continue
}
if normalized == stateDisconnected {
ids := peerStatus.Disconnected()
stateIds = append(stateIds, ids...)
continue
}
}
}
var directionIds []peer.ID
if emptyDirectionFilter {
directionIds = peerStatus.All()
} else {
for _, directionFilter := range req.Direction {
normalized := strings.ToUpper(directionFilter.String())
if normalized == directionInbound {
ids := peerStatus.Inbound()
directionIds = append(directionIds, ids...)
continue
}
if normalized == directionOutbound {
ids := peerStatus.Outbound()
directionIds = append(directionIds, ids...)
continue
}
}
}
var filteredIds []peer.ID
for _, stateId := range stateIds {
for _, directionId := range directionIds {
if stateId.Pretty() == directionId.Pretty() {
filteredIds = append(filteredIds, stateId)
break
}
}
}
filteredPeers := make([]*ethpb.Peer, 0, len(filteredIds))
for _, id := range filteredIds {
p, err := peerInfo(peerStatus, id)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get peer info: %v", err)
}
if p == nil {
continue
}
filteredPeers = append(filteredPeers, p)
}
return &ethpb.PeersResponse{Data: filteredPeers}, nil
}
// PeerCount retrieves number of known peers.
func (ns *Server) PeerCount(ctx context.Context, _ *emptypb.Empty) (*ethpb.PeerCountResponse, error) {
ctx, span := trace.StartSpan(ctx, "node.PeerCount")
defer span.End()
peerStatus := ns.PeersFetcher.Peers()
return &ethpb.PeerCountResponse{
Data: &ethpb.PeerCountResponse_PeerCount{
Disconnected: uint64(len(peerStatus.Disconnected())),
Connecting: uint64(len(peerStatus.Connecting())),
Connected: uint64(len(peerStatus.Connected())),
Disconnecting: uint64(len(peerStatus.Disconnecting())),
},
}, nil
}
// GetVersion requests that the beacon node identify information about its implementation in a
// format similar to a HTTP User-Agent field.
func (_ *Server) GetVersion(ctx context.Context, _ *emptypb.Empty) (*ethpb.VersionResponse, error) {
ctx, span := trace.StartSpan(ctx, "node.GetVersion")
defer span.End()
v := fmt.Sprintf("Prysm/%s (%s %s)", version.SemanticVersion(), runtime.GOOS, runtime.GOARCH)
return &ethpb.VersionResponse{
Data: &ethpb.Version{
Version: v,
},
}, nil
}
// 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, _ *emptypb.Empty) (*emptypb.Empty, error) {
ctx, span := trace.StartSpan(ctx, "node.GetHealth")
defer span.End()
if ns.SyncChecker.Synced() {
return &emptypb.Empty{}, nil
}
if ns.SyncChecker.Syncing() || ns.SyncChecker.Initialized() {
if err := grpc.SetHeader(ctx, metadata.Pairs(grpcutil.HttpCodeMetadataKey, strconv.Itoa(http.StatusPartialContent))); err != nil {
// We return a positive result because failing to set a non-gRPC related header should not cause the gRPC call to fail.
//nolint:nilerr
return &emptypb.Empty{}, nil
}
return &emptypb.Empty{}, nil
}
return &emptypb.Empty{}, status.Error(codes.Internal, "Node not initialized or having issues")
}
func handleEmptyFilters(req *ethpb.PeersRequest) (emptyState, emptyDirection bool) {
emptyState = true
for _, stateFilter := range req.State {
normalized := strings.ToUpper(stateFilter.String())
filterValid := normalized == stateConnecting || normalized == stateConnected ||
normalized == stateDisconnecting || normalized == stateDisconnected
if filterValid {
emptyState = false
break
}
}
emptyDirection = true
for _, directionFilter := range req.Direction {
normalized := strings.ToUpper(directionFilter.String())
filterValid := normalized == directionInbound || normalized == directionOutbound
if filterValid {
emptyDirection = false
break
}
}
return emptyState, emptyDirection
}
func peerInfo(peerStatus *peers.Status, id peer.ID) (*ethpb.Peer, error) {
enr, err := peerStatus.ENR(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain ENR")
}
var serializedEnr string
if enr != nil {
serializedEnr, err = p2p.SerializeENR(enr)
if err != nil {
return nil, errors.Wrap(err, "could not serialize ENR")
}
}
address, err := peerStatus.Address(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain address")
}
connectionState, err := peerStatus.ConnectionState(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain connection state")
}
direction, err := peerStatus.Direction(id)
if err != nil {
if errors.Is(err, peerdata.ErrPeerUnknown) {
return nil, nil
}
return nil, errors.Wrap(err, "could not obtain direction")
}
if eth.PeerDirection(direction) == eth.PeerDirection_UNKNOWN {
return nil, nil
}
v1ConnState := migration.V1Alpha1ConnectionStateToV1(eth.ConnectionState(connectionState))
v1PeerDirection, err := migration.V1Alpha1PeerDirectionToV1(eth.PeerDirection(direction))
if err != nil {
return nil, errors.Wrapf(err, "could not handle peer direction")
}
p := ethpb.Peer{
PeerId: id.Pretty(),
State: v1ConnState,
Direction: v1PeerDirection,
}
if address != nil {
p.LastSeenP2PAddress = address.String()
}
if serializedEnr != "" {
p.Enr = "enr:" + serializedEnr
}
return &p, nil
}

View File

@@ -1,433 +0,0 @@
package node
import (
"context"
"fmt"
"net/http"
"runtime"
"strconv"
"strings"
"testing"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
grpcruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
libp2ptest "github.com/libp2p/go-libp2p/p2p/host/peerstore/test"
ma "github.com/multiformats/go-multiaddr"
"github.com/prysmaticlabs/go-bitfield"
grpcutil "github.com/prysmaticlabs/prysm/v4/api/grpc"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/peers"
mockp2p "github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/testing"
syncmock "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
"github.com/prysmaticlabs/prysm/v4/consensus-types/wrapper"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
)
type dummyIdentity enode.ID
func (_ dummyIdentity) Verify(_ *enr.Record, _ []byte) error { return nil }
func (id dummyIdentity) NodeAddr(_ *enr.Record) []byte { return id[:] }
func TestGetVersion(t *testing.T) {
semVer := version.SemanticVersion()
os := runtime.GOOS
arch := runtime.GOARCH
res, err := (&Server{}).GetVersion(context.Background(), &emptypb.Empty{})
require.NoError(t, err)
v := res.Data.Version
assert.Equal(t, true, strings.Contains(v, semVer))
assert.Equal(t, true, strings.Contains(v, os))
assert.Equal(t, true, strings.Contains(v, arch))
}
func TestGetHealth(t *testing.T) {
ctx := grpc.NewContextWithServerTransportStream(context.Background(), &grpcruntime.ServerTransportStream{})
checker := &syncmock.Sync{}
s := &Server{
SyncChecker: checker,
}
_, err := s.GetHealth(ctx, &emptypb.Empty{})
require.ErrorContains(t, "Node not initialized or having issues", err)
checker.IsInitialized = true
_, err = s.GetHealth(ctx, &emptypb.Empty{})
require.NoError(t, err)
stream, ok := grpc.ServerTransportStreamFromContext(ctx).(*grpcruntime.ServerTransportStream)
require.Equal(t, true, ok, "type assertion failed")
assert.Equal(t, stream.Header()[strings.ToLower(grpcutil.HttpCodeMetadataKey)][0], strconv.Itoa(http.StatusPartialContent))
checker.IsSynced = true
_, err = s.GetHealth(ctx, &emptypb.Empty{})
require.NoError(t, err)
}
func TestGetIdentity(t *testing.T) {
ctx := context.Background()
p2pAddr, err := ma.NewMultiaddr("/ip4/7.7.7.7/udp/30303")
require.NoError(t, err)
discAddr1, err := ma.NewMultiaddr("/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
require.NoError(t, err)
discAddr2, err := ma.NewMultiaddr("/ip6/1:2:3:4:5:6:7:8/udp/20202/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
require.NoError(t, err)
enrRecord := &enr.Record{}
err = enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
attnets := bitfield.NewBitvector64()
attnets.SetBitAt(1, true)
metadataProvider := &mockp2p.MockMetadataProvider{Data: wrapper.WrappedMetadataV0(&pb.MetaDataV0{SeqNumber: 1, Attnets: attnets})}
t.Run("OK", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: enrRecord,
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
resp, err := s.GetIdentity(ctx, &emptypb.Empty{})
require.NoError(t, err)
expectedID := peer.ID("foo").Pretty()
assert.Equal(t, expectedID, resp.Data.PeerId)
expectedEnr, err := p2p.SerializeENR(enrRecord)
require.NoError(t, err)
assert.Equal(t, fmt.Sprint("enr:", expectedEnr), resp.Data.Enr)
require.Equal(t, 1, len(resp.Data.P2PAddresses))
assert.Equal(t, p2pAddr.String()+"/p2p/"+expectedID, resp.Data.P2PAddresses[0])
require.Equal(t, 2, len(resp.Data.DiscoveryAddresses))
ipv4Found, ipv6Found := false, false
for _, address := range resp.Data.DiscoveryAddresses {
if address == discAddr1.String() {
ipv4Found = true
} else if address == discAddr2.String() {
ipv6Found = true
}
}
assert.Equal(t, true, ipv4Found, "IPv4 discovery address not found")
assert.Equal(t, true, ipv6Found, "IPv6 discovery address not found")
assert.Equal(t, discAddr1.String(), resp.Data.DiscoveryAddresses[0])
assert.Equal(t, discAddr2.String(), resp.Data.DiscoveryAddresses[1])
})
t.Run("ENR failure", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: &enr.Record{},
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
_, err = s.GetIdentity(ctx, &emptypb.Empty{})
assert.ErrorContains(t, "Could not obtain enr", err)
})
t.Run("Discovery addresses failure", func(t *testing.T) {
peerManager := &mockp2p.MockPeerManager{
Enr: enrRecord,
PID: "foo",
BHost: &mockp2p.MockHost{Addresses: []ma.Multiaddr{p2pAddr}},
DiscoveryAddr: []ma.Multiaddr{discAddr1, discAddr2},
FailDiscoveryAddr: true,
}
s := &Server{
PeerManager: peerManager,
MetadataProvider: metadataProvider,
}
_, err = s.GetIdentity(ctx, &emptypb.Empty{})
assert.ErrorContains(t, "Could not obtain discovery address", err)
})
}
func TestGetPeer(t *testing.T) {
const rawId = "16Uiu2HAkvyYtoQXZNTsthjgLHjEnv7kvwzEmjvsJjWXpbhtqpSUN"
ctx := context.Background()
decodedId, err := peer.Decode(rawId)
require.NoError(t, err)
enrRecord := &enr.Record{}
err = enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
const p2pAddr = "/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
peerFetcher := &mockp2p.MockPeersProvider{}
s := Server{PeersFetcher: peerFetcher}
peerFetcher.Peers().Add(enrRecord, decodedId, p2pMultiAddr, network.DirInbound)
t.Run("OK", func(t *testing.T) {
resp, err := s.GetPeer(ctx, &ethpb.PeerRequest{PeerId: rawId})
require.NoError(t, err)
assert.Equal(t, rawId, resp.Data.PeerId)
assert.Equal(t, p2pAddr, resp.Data.LastSeenP2PAddress)
assert.Equal(t, "enr:yoABgmlwhAcHBwc", resp.Data.Enr)
assert.Equal(t, ethpb.ConnectionState_DISCONNECTED, resp.Data.State)
assert.Equal(t, ethpb.PeerDirection_INBOUND, resp.Data.Direction)
})
t.Run("Invalid ID", func(t *testing.T) {
_, err = s.GetPeer(ctx, &ethpb.PeerRequest{PeerId: "foo"})
assert.ErrorContains(t, "Invalid peer ID", err)
})
t.Run("Peer not found", func(t *testing.T) {
generatedId := "16Uiu2HAmQqFdEcHbSmQTQuLoAhnMUrgoWoraKK4cUJT6FuuqHqTU"
_, err = s.GetPeer(ctx, &ethpb.PeerRequest{PeerId: generatedId})
assert.ErrorContains(t, "Peer not found", err)
})
}
func TestListPeers(t *testing.T) {
ids := libp2ptest.GeneratePeerIDs(9)
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
peerStatus := peerFetcher.Peers()
for i, id := range ids {
// Make last peer undiscovered
if i == len(ids)-1 {
peerStatus.Add(nil, id, nil, network.DirUnknown)
} else {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{127, 0, 0, byte(i)})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
var p2pAddr = "/ip4/127.0.0." + strconv.Itoa(i) + "/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
var direction network.Direction
if i%2 == 0 {
direction = network.DirInbound
} else {
direction = network.DirOutbound
}
peerStatus.Add(enrRecord, id, p2pMultiAddr, direction)
switch i {
case 0, 1:
peerStatus.SetConnectionState(id, peers.PeerConnecting)
case 2, 3:
peerStatus.SetConnectionState(id, peers.PeerConnected)
case 4, 5:
peerStatus.SetConnectionState(id, peers.PeerDisconnecting)
case 6, 7:
peerStatus.SetConnectionState(id, peers.PeerDisconnected)
default:
t.Fatalf("Failed to set connection state for peer")
}
}
}
s := Server{PeersFetcher: peerFetcher}
t.Run("Peer data OK", func(t *testing.T) {
// We will check the first peer from the list.
expectedId := ids[0]
resp, err := s.ListPeers(context.Background(), &ethpb.PeersRequest{
State: []ethpb.ConnectionState{ethpb.ConnectionState_CONNECTING},
Direction: []ethpb.PeerDirection{ethpb.PeerDirection_INBOUND},
})
require.NoError(t, err)
require.Equal(t, 1, len(resp.Data))
returnedPeer := resp.Data[0]
assert.Equal(t, expectedId.Pretty(), returnedPeer.PeerId)
expectedEnr, err := peerStatus.ENR(expectedId)
require.NoError(t, err)
serializedEnr, err := p2p.SerializeENR(expectedEnr)
require.NoError(t, err)
assert.Equal(t, "enr:"+serializedEnr, returnedPeer.Enr)
expectedP2PAddr, err := peerStatus.Address(expectedId)
require.NoError(t, err)
assert.Equal(t, expectedP2PAddr.String(), returnedPeer.LastSeenP2PAddress)
assert.Equal(t, ethpb.ConnectionState_CONNECTING, returnedPeer.State)
assert.Equal(t, ethpb.PeerDirection_INBOUND, returnedPeer.Direction)
})
filterTests := []struct {
name string
states []ethpb.ConnectionState
directions []ethpb.PeerDirection
wantIds []peer.ID
}{
{
name: "No filters - return all peers",
states: []ethpb.ConnectionState{},
directions: []ethpb.PeerDirection{},
wantIds: ids[:len(ids)-1], // Excluding last peer as it is not connected.
},
{
name: "State filter empty - return peers for all states",
states: []ethpb.ConnectionState{},
directions: []ethpb.PeerDirection{ethpb.PeerDirection_INBOUND},
wantIds: []peer.ID{ids[0], ids[2], ids[4], ids[6]},
},
{
name: "Direction filter empty - return peers for all directions",
states: []ethpb.ConnectionState{ethpb.ConnectionState_CONNECTED},
directions: []ethpb.PeerDirection{},
wantIds: []peer.ID{ids[2], ids[3]},
},
{
name: "One state and direction",
states: []ethpb.ConnectionState{ethpb.ConnectionState_DISCONNECTED},
directions: []ethpb.PeerDirection{ethpb.PeerDirection_INBOUND},
wantIds: []peer.ID{ids[6]},
},
{
name: "Multiple states and directions",
states: []ethpb.ConnectionState{ethpb.ConnectionState_CONNECTING, ethpb.ConnectionState_DISCONNECTING},
directions: []ethpb.PeerDirection{ethpb.PeerDirection_INBOUND, ethpb.PeerDirection_OUTBOUND},
wantIds: []peer.ID{ids[0], ids[1], ids[4], ids[5]},
},
{
name: "Unknown filter is ignored",
states: []ethpb.ConnectionState{ethpb.ConnectionState_CONNECTED, 99},
directions: []ethpb.PeerDirection{ethpb.PeerDirection_OUTBOUND, 99},
wantIds: []peer.ID{ids[3]},
},
{
name: "Only unknown filters - return all peers",
states: []ethpb.ConnectionState{99},
directions: []ethpb.PeerDirection{99},
wantIds: ids[:len(ids)-1], // Excluding last peer as it is not connected.
},
}
for _, tt := range filterTests {
t.Run(tt.name, func(t *testing.T) {
resp, err := s.ListPeers(context.Background(), &ethpb.PeersRequest{
State: tt.states,
Direction: tt.directions,
})
require.NoError(t, err)
assert.Equal(t, len(tt.wantIds), len(resp.Data), "Wrong number of peers returned")
for _, id := range tt.wantIds {
expectedId := id.Pretty()
found := false
for _, returnedPeer := range resp.Data {
if returnedPeer.PeerId == expectedId {
found = true
break
}
}
if !found {
t.Errorf("Expected ID '" + expectedId + "' not found")
}
}
})
}
}
func TestListPeers_NoPeersReturnsEmptyArray(t *testing.T) {
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
s := Server{PeersFetcher: peerFetcher}
resp, err := s.ListPeers(context.Background(), &ethpb.PeersRequest{
State: []ethpb.ConnectionState{ethpb.ConnectionState_CONNECTED},
})
require.NoError(t, err)
require.NotNil(t, resp.Data)
assert.Equal(t, 0, len(resp.Data))
}
func TestPeerCount(t *testing.T) {
ids := libp2ptest.GeneratePeerIDs(10)
peerFetcher := &mockp2p.MockPeersProvider{}
peerFetcher.ClearPeers()
peerStatus := peerFetcher.Peers()
for i, id := range ids {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(t, err)
enrRecord.Set(enr.IPv4{127, 0, 0, byte(i)})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(t, err)
var p2pAddr = "/ip4/127.0.0." + strconv.Itoa(i) + "/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(t, err)
var direction network.Direction
if i%2 == 0 {
direction = network.DirInbound
} else {
direction = network.DirOutbound
}
peerStatus.Add(enrRecord, id, p2pMultiAddr, direction)
switch i {
case 0:
peerStatus.SetConnectionState(id, peers.PeerConnecting)
case 1, 2:
peerStatus.SetConnectionState(id, peers.PeerConnected)
case 3, 4, 5:
peerStatus.SetConnectionState(id, peers.PeerDisconnecting)
case 6, 7, 8, 9:
peerStatus.SetConnectionState(id, peers.PeerDisconnected)
default:
t.Fatalf("Failed to set connection state for peer")
}
}
s := Server{PeersFetcher: peerFetcher}
resp, err := s.PeerCount(context.Background(), &emptypb.Empty{})
require.NoError(t, err)
assert.Equal(t, uint64(1), resp.Data.Connecting, "Wrong number of connecting peers")
assert.Equal(t, uint64(2), resp.Data.Connected, "Wrong number of connected peers")
assert.Equal(t, uint64(3), resp.Data.Disconnecting, "Wrong number of disconnecting peers")
assert.Equal(t, uint64(4), resp.Data.Disconnected, "Wrong number of disconnected peers")
}
func BenchmarkListPeers(b *testing.B) {
// We simulate having a lot of peers.
ids := libp2ptest.GeneratePeerIDs(2000)
peerFetcher := &mockp2p.MockPeersProvider{}
for _, id := range ids {
enrRecord := &enr.Record{}
err := enrRecord.SetSig(dummyIdentity{1}, []byte{42})
require.NoError(b, err)
enrRecord.Set(enr.IPv4{7, 7, 7, 7})
err = enrRecord.SetSig(dummyIdentity{}, []byte{})
require.NoError(b, err)
const p2pAddr = "/ip4/7.7.7.7/udp/30303/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N"
p2pMultiAddr, err := ma.NewMultiaddr(p2pAddr)
require.NoError(b, err)
peerFetcher.Peers().Add(enrRecord, id, p2pMultiAddr, network.DirInbound)
}
s := Server{PeersFetcher: peerFetcher}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := s.ListPeers(context.Background(), &ethpb.PeersRequest{
State: []ethpb.ConnectionState{},
Direction: []ethpb.PeerDirection{},
})
require.NoError(b, err)
}
}

View File

@@ -1,7 +0,0 @@
package node
import (
ethpbservice "github.com/prysmaticlabs/prysm/v4/proto/eth/service"
)
var _ ethpbservice.BeaconNodeServer = (*Server)(nil)

View File

@@ -11,3 +11,55 @@ type SyncStatusResponseData struct {
IsOptimistic bool `json:"is_optimistic"`
ElOffline bool `json:"el_offline"`
}
type GetIdentityResponse struct {
Data *Identity `json:"data"`
}
type Identity struct {
PeerId string `json:"peer_id"`
Enr string `json:"enr"`
P2PAddresses []string `json:"p2p_addresses"`
DiscoveryAddresses []string `json:"discovery_addresses"`
Metadata *Metadata `json:"metadata"`
}
type Metadata struct {
SeqNumber string `json:"seq_number"`
Attnets string `json:"attnets"`
}
type GetPeerResponse struct {
Data *Peer `json:"data"`
}
type GetPeersResponse struct {
Data []*Peer `json:"data"`
}
type Peer struct {
PeerId string `json:"peer_id"`
Enr string `json:"enr"`
LastSeenP2PAddress string `json:"last_seen_p2p_address"`
State string `json:"state"`
Direction string `json:"direction"`
}
type GetPeerCountResponse struct {
Data *PeerCount `json:"data"`
}
type PeerCount struct {
Disconnected string `json:"disconnected"`
Connecting string `json:"connecting"`
Connected string `json:"connected"`
Disconnecting string `json:"disconnecting"`
}
type GetVersionResponse struct {
Data *Version `json:"data"`
}
type Version struct {
Version string `json:"version"`
}

View File

@@ -351,6 +351,12 @@ func (s *Service) Start() {
}
s.cfg.Router.HandleFunc("/eth/v1/node/syncing", nodeServerEth.GetSyncStatus).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/identity", nodeServerEth.GetIdentity).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/peers/{peer_id}", nodeServerEth.GetPeer).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/peers", nodeServerEth.GetPeers).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/peer_count", nodeServerEth.GetPeerCount).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/version", nodeServerEth.GetVersion).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/node/health", nodeServerEth.GetHealth).Methods(http.MethodGet)
nodeServerPrysm := &nodeprysm.Server{
BeaconDB: s.cfg.BeaconDB,
@@ -455,7 +461,6 @@ func (s *Service) Start() {
s.cfg.Router.HandleFunc("/eth/v1/beacon/states/{state_id}/validator_balances", beaconChainServerV1.GetValidatorBalances).Methods(http.MethodGet)
ethpbv1alpha1.RegisterNodeServer(s.grpcServer, nodeServer)
ethpbservice.RegisterBeaconNodeServer(s.grpcServer, nodeServerEth)
ethpbv1alpha1.RegisterHealthServer(s.grpcServer, nodeServer)
ethpbv1alpha1.RegisterBeaconChainServer(s.grpcServer, beaconChainServer)
ethpbservice.RegisterBeaconChainServer(s.grpcServer, beaconChainServerV1)

View File

@@ -10,7 +10,6 @@ proto_library(
"beacon_chain_service.proto",
"beacon_debug_service.proto",
"events_service.proto",
"node_service.proto",
"validator_service.proto",
"key_management.proto",
],

View File

@@ -1,412 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.23.3
// source: proto/eth/service/node_service.proto
package service
import (
context "context"
reflect "reflect"
v1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/descriptorpb"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var File_proto_eth_service_node_service_proto protoreflect.FileDescriptor
var file_proto_eth_service_node_service_proto_rawDesc = []byte{
0x0a, 0x24, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x1c, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d,
0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x32, 0xab, 0x05, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4e, 0x6f, 0x64,
0x65, 0x12, 0x70, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65,
0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x74, 0x79, 0x12, 0x6f, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73,
0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70,
0x65, 0x65, 0x72, 0x73, 0x12, 0x75, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12,
0x1c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e,
0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x65, 0x65, 0x72,
0x73, 0x2f, 0x7b, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x71, 0x0a, 0x09, 0x50,
0x65, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x1a, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e,
0x6f, 0x64, 0x65, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x6d,
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31,
0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x61, 0x0a,
0x09, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68,
0x42, 0x91, 0x01, 0x0a, 0x18, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x10, 0x4e,
0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72,
0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xaa, 0x02, 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xca, 0x02, 0x14,
0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_proto_eth_service_node_service_proto_goTypes = []interface{}{
(*emptypb.Empty)(nil), // 0: google.protobuf.Empty
(*v1.PeersRequest)(nil), // 1: ethereum.eth.v1.PeersRequest
(*v1.PeerRequest)(nil), // 2: ethereum.eth.v1.PeerRequest
(*v1.IdentityResponse)(nil), // 3: ethereum.eth.v1.IdentityResponse
(*v1.PeersResponse)(nil), // 4: ethereum.eth.v1.PeersResponse
(*v1.PeerResponse)(nil), // 5: ethereum.eth.v1.PeerResponse
(*v1.PeerCountResponse)(nil), // 6: ethereum.eth.v1.PeerCountResponse
(*v1.VersionResponse)(nil), // 7: ethereum.eth.v1.VersionResponse
}
var file_proto_eth_service_node_service_proto_depIdxs = []int32{
0, // 0: ethereum.eth.service.BeaconNode.GetIdentity:input_type -> google.protobuf.Empty
1, // 1: ethereum.eth.service.BeaconNode.ListPeers:input_type -> ethereum.eth.v1.PeersRequest
2, // 2: ethereum.eth.service.BeaconNode.GetPeer:input_type -> ethereum.eth.v1.PeerRequest
0, // 3: ethereum.eth.service.BeaconNode.PeerCount:input_type -> google.protobuf.Empty
0, // 4: ethereum.eth.service.BeaconNode.GetVersion:input_type -> google.protobuf.Empty
0, // 5: ethereum.eth.service.BeaconNode.GetHealth:input_type -> google.protobuf.Empty
3, // 6: ethereum.eth.service.BeaconNode.GetIdentity:output_type -> ethereum.eth.v1.IdentityResponse
4, // 7: ethereum.eth.service.BeaconNode.ListPeers:output_type -> ethereum.eth.v1.PeersResponse
5, // 8: ethereum.eth.service.BeaconNode.GetPeer:output_type -> ethereum.eth.v1.PeerResponse
6, // 9: ethereum.eth.service.BeaconNode.PeerCount:output_type -> ethereum.eth.v1.PeerCountResponse
7, // 10: ethereum.eth.service.BeaconNode.GetVersion:output_type -> ethereum.eth.v1.VersionResponse
0, // 11: ethereum.eth.service.BeaconNode.GetHealth:output_type -> google.protobuf.Empty
6, // [6:12] is the sub-list for method output_type
0, // [0:6] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_proto_eth_service_node_service_proto_init() }
func file_proto_eth_service_node_service_proto_init() {
if File_proto_eth_service_node_service_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_eth_service_node_service_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_eth_service_node_service_proto_goTypes,
DependencyIndexes: file_proto_eth_service_node_service_proto_depIdxs,
}.Build()
File_proto_eth_service_node_service_proto = out.File
file_proto_eth_service_node_service_proto_rawDesc = nil
file_proto_eth_service_node_service_proto_goTypes = nil
file_proto_eth_service_node_service_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// BeaconNodeClient is the client API for BeaconNode service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type BeaconNodeClient interface {
GetIdentity(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.IdentityResponse, error)
ListPeers(ctx context.Context, in *v1.PeersRequest, opts ...grpc.CallOption) (*v1.PeersResponse, error)
GetPeer(ctx context.Context, in *v1.PeerRequest, opts ...grpc.CallOption) (*v1.PeerResponse, error)
PeerCount(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.PeerCountResponse, error)
GetVersion(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.VersionResponse, error)
GetHealth(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error)
}
type beaconNodeClient struct {
cc grpc.ClientConnInterface
}
func NewBeaconNodeClient(cc grpc.ClientConnInterface) BeaconNodeClient {
return &beaconNodeClient{cc}
}
func (c *beaconNodeClient) GetIdentity(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.IdentityResponse, error) {
out := new(v1.IdentityResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/GetIdentity", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *beaconNodeClient) ListPeers(ctx context.Context, in *v1.PeersRequest, opts ...grpc.CallOption) (*v1.PeersResponse, error) {
out := new(v1.PeersResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/ListPeers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *beaconNodeClient) GetPeer(ctx context.Context, in *v1.PeerRequest, opts ...grpc.CallOption) (*v1.PeerResponse, error) {
out := new(v1.PeerResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/GetPeer", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *beaconNodeClient) PeerCount(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.PeerCountResponse, error) {
out := new(v1.PeerCountResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/PeerCount", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *beaconNodeClient) GetVersion(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*v1.VersionResponse, error) {
out := new(v1.VersionResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/GetVersion", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *beaconNodeClient) GetHealth(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconNode/GetHealth", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// BeaconNodeServer is the server API for BeaconNode service.
type BeaconNodeServer interface {
GetIdentity(context.Context, *emptypb.Empty) (*v1.IdentityResponse, error)
ListPeers(context.Context, *v1.PeersRequest) (*v1.PeersResponse, error)
GetPeer(context.Context, *v1.PeerRequest) (*v1.PeerResponse, error)
PeerCount(context.Context, *emptypb.Empty) (*v1.PeerCountResponse, error)
GetVersion(context.Context, *emptypb.Empty) (*v1.VersionResponse, error)
GetHealth(context.Context, *emptypb.Empty) (*emptypb.Empty, error)
}
// UnimplementedBeaconNodeServer can be embedded to have forward compatible implementations.
type UnimplementedBeaconNodeServer struct {
}
func (*UnimplementedBeaconNodeServer) GetIdentity(context.Context, *emptypb.Empty) (*v1.IdentityResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetIdentity not implemented")
}
func (*UnimplementedBeaconNodeServer) ListPeers(context.Context, *v1.PeersRequest) (*v1.PeersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListPeers not implemented")
}
func (*UnimplementedBeaconNodeServer) GetPeer(context.Context, *v1.PeerRequest) (*v1.PeerResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPeer not implemented")
}
func (*UnimplementedBeaconNodeServer) PeerCount(context.Context, *emptypb.Empty) (*v1.PeerCountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PeerCount not implemented")
}
func (*UnimplementedBeaconNodeServer) GetVersion(context.Context, *emptypb.Empty) (*v1.VersionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
}
func (*UnimplementedBeaconNodeServer) GetHealth(context.Context, *emptypb.Empty) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetHealth not implemented")
}
func RegisterBeaconNodeServer(s *grpc.Server, srv BeaconNodeServer) {
s.RegisterService(&_BeaconNode_serviceDesc, srv)
}
func _BeaconNode_GetIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).GetIdentity(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/GetIdentity",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).GetIdentity(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _BeaconNode_ListPeers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(v1.PeersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).ListPeers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/ListPeers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).ListPeers(ctx, req.(*v1.PeersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BeaconNode_GetPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(v1.PeerRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).GetPeer(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/GetPeer",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).GetPeer(ctx, req.(*v1.PeerRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BeaconNode_PeerCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).PeerCount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/PeerCount",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).PeerCount(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _BeaconNode_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).GetVersion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/GetVersion",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).GetVersion(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _BeaconNode_GetHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BeaconNodeServer).GetHealth(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.service.BeaconNode/GetHealth",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BeaconNodeServer).GetHealth(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
var _BeaconNode_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.eth.service.BeaconNode",
HandlerType: (*BeaconNodeServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetIdentity",
Handler: _BeaconNode_GetIdentity_Handler,
},
{
MethodName: "ListPeers",
Handler: _BeaconNode_ListPeers_Handler,
},
{
MethodName: "GetPeer",
Handler: _BeaconNode_GetPeer_Handler,
},
{
MethodName: "PeerCount",
Handler: _BeaconNode_PeerCount_Handler,
},
{
MethodName: "GetVersion",
Handler: _BeaconNode_GetVersion_Handler,
},
{
MethodName: "GetHealth",
Handler: _BeaconNode_GetHealth_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/eth/service/node_service.proto",
}

View File

@@ -1,535 +0,0 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: proto/eth/service/node_service.proto
/*
Package service is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package service
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
v1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/emptypb"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
var _ = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch(0)
var _ = emptypb.Empty{}
func request_BeaconNode_GetIdentity_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.GetIdentity(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_GetIdentity_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.GetIdentity(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconNode_ListPeers_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconNode_ListPeers_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.PeersRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconNode_ListPeers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListPeers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_ListPeers_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.PeersRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconNode_ListPeers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListPeers(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconNode_GetPeer_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.PeerRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["peer_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_id")
}
peer_id, err := runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_id", err)
}
protoReq.PeerId = (peer_id)
msg, err := client.GetPeer(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_GetPeer_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.PeerRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["peer_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_id")
}
peer_id, err := runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_id", err)
}
protoReq.PeerId = (peer_id)
msg, err := server.GetPeer(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconNode_PeerCount_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.PeerCount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_PeerCount_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.PeerCount(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconNode_GetVersion_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.GetVersion(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_GetVersion_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.GetVersion(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconNode_GetHealth_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconNodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.GetHealth(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconNode_GetHealth_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconNodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.GetHealth(ctx, &protoReq)
return msg, metadata, err
}
// RegisterBeaconNodeHandlerServer registers the http handlers for service BeaconNode to "mux".
// UnaryRPC :call BeaconNodeServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterBeaconNodeHandlerFromEndpoint instead.
func RegisterBeaconNodeHandlerServer(ctx context.Context, mux *runtime.ServeMux, server BeaconNodeServer) error {
mux.Handle("GET", pattern_BeaconNode_GetIdentity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetIdentity")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_GetIdentity_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetIdentity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_ListPeers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/ListPeers")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_ListPeers_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_ListPeers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetPeer_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetPeer")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_GetPeer_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetPeer_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_PeerCount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/PeerCount")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_PeerCount_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_PeerCount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetVersion")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_GetVersion_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetVersion_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetHealth_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetHealth")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconNode_GetHealth_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetHealth_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterBeaconNodeHandlerFromEndpoint is same as RegisterBeaconNodeHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterBeaconNodeHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterBeaconNodeHandler(ctx, mux, conn)
}
// RegisterBeaconNodeHandler registers the http handlers for service BeaconNode to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterBeaconNodeHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterBeaconNodeHandlerClient(ctx, mux, NewBeaconNodeClient(conn))
}
// RegisterBeaconNodeHandlerClient registers the http handlers for service BeaconNode
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "BeaconNodeClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "BeaconNodeClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "BeaconNodeClient" to call the correct interceptors.
func RegisterBeaconNodeHandlerClient(ctx context.Context, mux *runtime.ServeMux, client BeaconNodeClient) error {
mux.Handle("GET", pattern_BeaconNode_GetIdentity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetIdentity")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_GetIdentity_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetIdentity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_ListPeers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/ListPeers")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_ListPeers_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_ListPeers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetPeer_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetPeer")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_GetPeer_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetPeer_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_PeerCount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/PeerCount")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_PeerCount_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_PeerCount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetVersion")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_GetVersion_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetVersion_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconNode_GetHealth_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconNode/GetHealth")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconNode_GetHealth_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconNode_GetHealth_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_BeaconNode_GetIdentity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "node", "identity"}, ""))
pattern_BeaconNode_ListPeers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "node", "peers"}, ""))
pattern_BeaconNode_GetPeer_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"internal", "eth", "v1", "node", "peers", "peer_id"}, ""))
pattern_BeaconNode_PeerCount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "node", "peer_count"}, ""))
pattern_BeaconNode_GetVersion_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "node", "version"}, ""))
pattern_BeaconNode_GetHealth_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "node", "health"}, ""))
)
var (
forward_BeaconNode_GetIdentity_0 = runtime.ForwardResponseMessage
forward_BeaconNode_ListPeers_0 = runtime.ForwardResponseMessage
forward_BeaconNode_GetPeer_0 = runtime.ForwardResponseMessage
forward_BeaconNode_PeerCount_0 = runtime.ForwardResponseMessage
forward_BeaconNode_GetVersion_0 = runtime.ForwardResponseMessage
forward_BeaconNode_GetHealth_0 = runtime.ForwardResponseMessage
)

View File

@@ -1,84 +0,0 @@
// Copyright 2020 Prysmatic Labs.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package ethereum.eth.service;
import "google/api/annotations.proto";
import "google/protobuf/descriptor.proto";
import "google/protobuf/empty.proto";
import "proto/eth/v1/node.proto";
option csharp_namespace = "Ethereum.Eth.Service";
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/eth/service";
option java_multiple_files = true;
option java_outer_classname = "NodeServiceProto";
option java_package = "org.ethereum.eth.service";
option php_namespace = "Ethereum\\Eth\\Service";
// Beacon chain node API
//
// The beacon chain node API is a set of endpoints to query node information.
service BeaconNode {
// GetIdentity retrieves data about the node's network presence.
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getNetworkIdentity
rpc GetIdentity(google.protobuf.Empty) returns (v1.IdentityResponse) {
option (google.api.http) = {get: "/internal/eth/v1/node/identity"};
}
// ListPeers retrieves data about the node's network peers.
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getPeers
rpc ListPeers(v1.PeersRequest) returns (v1.PeersResponse) {
option (google.api.http) = {get: "/internal/eth/v1/node/peers"};
}
// GetPeer retrieves data about the given peer.
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getPeer
rpc GetPeer(v1.PeerRequest) returns (v1.PeerResponse) {
option (google.api.http) = {get: "/internal/eth/v1/node/peers/{peer_id}"};
}
// PeerCount retrieves number of known peers.
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getPeerCount
rpc PeerCount(google.protobuf.Empty) returns (v1.PeerCountResponse) {
option (google.api.http) = {get: "/internal/eth/v1/node/peer_count"};
}
// GetVersion requests that the beacon node identify information about its implementation in a
// format similar to a HTTP User-Agent field.
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getNodeVersion
rpc GetVersion(google.protobuf.Empty) returns (v1.VersionResponse) {
option (google.api.http) = {get: "/internal/eth/v1/node/version"};
}
// 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
//
// Spec: https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.3.0#/Node/getHealth
rpc GetHealth(google.protobuf.Empty) returns (google.protobuf.Empty) {
option (google.api.http) = {get: "/internal/eth/v1/node/health"};
}
}

971
proto/eth/v1/node.pb.go generated

File diff suppressed because it is too large Load Diff

View File

@@ -26,71 +26,6 @@ option java_outer_classname = "BeaconNodeProto";
option java_package = "org.ethereum.eth.v1";
option php_namespace = "Ethereum\\Eth\\v1";
message IdentityResponse {
Identity data = 1;
}
message Identity {
// The peer id of the node.
string peer_id = 1;
// The latest ENR of the node.
string enr = 2;
// All the p2p multiaddresses of the peer, specified as a full multiaddr.
repeated string p2p_addresses = 3;
// All the discv5 multiaddresses of the peer, specified as a full multiaddr.
repeated string discovery_addresses = 4;
// Additional metadata that the node would like to provide. Includes extra networking information.
Metadata metadata = 5;
}
message Metadata {
// Sequence number starts at 0 used to version the node's metadata. If any other field in the local MetaData changes,
// the node MUST increment seq_number by 1.
uint64 seq_number = 1;
// Attnets is a bitvector representing the node's persistent attestation subnet subscriptions.
bytes attnets = 2 [(ethereum.eth.ext.ssz_size) = "8", (ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/go-bitfield.Bitvector64"];
}
message PeerRequest {
// Peer id of the peer requested.
string peer_id = 1;
}
message PeersRequest {
// Requested peer states (available values: disconnected, connecting, connected, disconnecting).
repeated ConnectionState state = 1;
// Requested peer directions (available values: inbound, outbound).
repeated PeerDirection direction = 2;
}
message PeerResponse {
Peer data = 1;
Meta meta = 2;
message Meta {
uint64 count = 1;
}
}
message PeersResponse {
repeated Peer data = 1;
}
message PeerCountResponse {
PeerCount data = 1;
message PeerCount {
// The number of disconnected peers.
uint64 disconnected = 1;
// The number of connecting peers.
uint64 connecting = 2;
// The number of connected peers.
uint64 connected = 3;
// The number of disconnecting peers.
uint64 disconnecting = 4;
}
}
// Peer provides details of a peer on the network.
message Peer {
// The peer id of the peer.
@@ -119,13 +54,3 @@ enum ConnectionState {
CONNECTED = 2;
DISCONNECTING = 3;
}
message VersionResponse {
Version data = 1;
}
// Information about the node version.
message Version {
// A string that uniquely identifies the node and its version.
string version = 1;
}

View File

@@ -13,6 +13,7 @@ go_library(
deps = [
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/eth/beacon:go_default_library",
"//beacon-chain/rpc/eth/node:go_default_library",
"//beacon-chain/rpc/eth/validator:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",

View File

@@ -13,6 +13,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -207,17 +208,17 @@ var beaconPathsAndObjects = map[string]metadata{
return []string{}
},
prysmResps: map[string]interface{}{
"json": &apimiddleware.IdentityResponseJson{},
"json": &node.GetIdentityResponse{},
},
lighthouseResps: map[string]interface{}{
"json": &apimiddleware.IdentityResponseJson{},
"json": &node.GetIdentityResponse{},
},
customEvaluation: func(prysmResp interface{}, lhouseResp interface{}) error {
castedp, ok := prysmResp.(*apimiddleware.IdentityResponseJson)
castedp, ok := prysmResp.(*node.GetIdentityResponse)
if !ok {
return errors.New("failed to cast type")
}
castedl, ok := lhouseResp.(*apimiddleware.IdentityResponseJson)
castedl, ok := lhouseResp.(*node.GetIdentityResponse)
if !ok {
return errors.New("failed to cast type")
}
@@ -236,17 +237,17 @@ var beaconPathsAndObjects = map[string]metadata{
return []string{}
},
prysmResps: map[string]interface{}{
"json": &apimiddleware.PeersResponseJson{},
"json": &node.GetPeersResponse{},
},
lighthouseResps: map[string]interface{}{
"json": &apimiddleware.PeersResponseJson{},
"json": &node.GetPeersResponse{},
},
customEvaluation: func(prysmResp interface{}, lhouseResp interface{}) error {
castedp, ok := prysmResp.(*apimiddleware.PeersResponseJson)
castedp, ok := prysmResp.(*node.GetPeersResponse)
if !ok {
return errors.New("failed to cast type")
}
castedl, ok := lhouseResp.(*apimiddleware.PeersResponseJson)
castedl, ok := lhouseResp.(*node.GetPeersResponse)
if !ok {
return errors.New("failed to cast type")
}

View File

@@ -44,6 +44,7 @@ go_library(
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/eth/beacon:go_default_library",
"//beacon-chain/rpc/eth/node:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/validator:go_default_library",
"//beacon-chain/rpc/prysm/validator:go_default_library",
@@ -115,6 +116,7 @@ go_test(
"//api/gateway/apimiddleware:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/eth/beacon:go_default_library",
"//beacon-chain/rpc/eth/node:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
"//beacon-chain/rpc/eth/validator:go_default_library",

View File

@@ -10,8 +10,8 @@ import (
"strconv"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -100,10 +100,10 @@ func (c *beaconApiValidatorClient) getLiveness(ctx context.Context, epoch primit
return livenessResponseJson, nil
}
func (c *beaconApiValidatorClient) getSyncing(ctx context.Context) (*apimiddleware.SyncingResponseJson, error) {
func (c *beaconApiValidatorClient) getSyncing(ctx context.Context) (*node.SyncStatusResponse, error) {
const endpoint = "/eth/v1/node/syncing"
syncingResponseJson := &apimiddleware.SyncingResponseJson{}
syncingResponseJson := &node.SyncStatusResponse{}
if _, err := c.jsonRestHandler.GetRestJsonResponse(
ctx,

View File

@@ -9,8 +9,8 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -321,11 +321,11 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
syncingResponseJson := apimiddleware.SyncingResponseJson{}
syncingResponseJson := node.SyncStatusResponse{}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
expected := apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
expected := node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: testCase.isSyncing,
},
}
@@ -359,7 +359,7 @@ func TestGetIsSyncing_Invalid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
syncingResponseJson := apimiddleware.SyncingResponseJson{}
syncingResponseJson := node.SyncStatusResponse{}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
ctx := context.Background()

View File

@@ -10,6 +10,7 @@ import (
"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
"google.golang.org/protobuf/types/known/timestamppb"
@@ -22,7 +23,7 @@ type beaconApiNodeClient struct {
}
func (c *beaconApiNodeClient) GetSyncStatus(ctx context.Context, _ *empty.Empty) (*ethpb.SyncStatus, error) {
syncingResponse := apimiddleware.SyncingResponseJson{}
syncingResponse := node.SyncStatusResponse{}
if _, err := c.jsonRestHandler.GetRestJsonResponse(ctx, "/eth/v1/node/syncing", &syncingResponse); err != nil {
return nil, errors.Wrap(err, "failed to get sync status")
}
@@ -76,7 +77,7 @@ func (c *beaconApiNodeClient) GetGenesis(ctx context.Context, _ *empty.Empty) (*
}
func (c *beaconApiNodeClient) GetVersion(ctx context.Context, _ *empty.Empty) (*ethpb.Version, error) {
var versionResponse apimiddleware.VersionResponseJson
var versionResponse node.GetVersionResponse
if _, err := c.jsonRestHandler.GetRestJsonResponse(ctx, "/eth/v1/node/version", &versionResponse); err != nil {
return nil, errors.Wrapf(err, "failed to query node version")
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
@@ -159,7 +159,7 @@ func TestGetSyncStatus(t *testing.T) {
testCases := []struct {
name string
restEndpointResponse apimiddleware.SyncingResponseJson
restEndpointResponse node.SyncStatusResponse
restEndpointError error
expectedResponse *ethpb.SyncStatus
expectedError string
@@ -171,13 +171,13 @@ func TestGetSyncStatus(t *testing.T) {
},
{
name: "returns nil syncing data",
restEndpointResponse: apimiddleware.SyncingResponseJson{Data: nil},
restEndpointResponse: node.SyncStatusResponse{Data: nil},
expectedError: "syncing data is nil",
},
{
name: "returns false syncing status",
restEndpointResponse: apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
restEndpointResponse: node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: false,
},
},
@@ -187,8 +187,8 @@ func TestGetSyncStatus(t *testing.T) {
},
{
name: "returns true syncing status",
restEndpointResponse: apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
restEndpointResponse: node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: true,
},
},
@@ -204,7 +204,7 @@ func TestGetSyncStatus(t *testing.T) {
defer ctrl.Finish()
ctx := context.Background()
syncingResponse := apimiddleware.SyncingResponseJson{}
syncingResponse := node.SyncStatusResponse{}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
@@ -235,7 +235,7 @@ func TestGetVersion(t *testing.T) {
testCases := []struct {
name string
restEndpointResponse apimiddleware.VersionResponseJson
restEndpointResponse node.GetVersionResponse
restEndpointError error
expectedResponse *ethpb.Version
expectedError string
@@ -247,13 +247,13 @@ func TestGetVersion(t *testing.T) {
},
{
name: "returns nil version data",
restEndpointResponse: apimiddleware.VersionResponseJson{Data: nil},
restEndpointResponse: node.GetVersionResponse{Data: nil},
expectedError: "empty version response",
},
{
name: "returns proper version response",
restEndpointResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{
restEndpointResponse: node.GetVersionResponse{
Data: &node.Version{
Version: "prysm/local",
},
},
@@ -269,7 +269,7 @@ func TestGetVersion(t *testing.T) {
defer ctrl.Finish()
ctx := context.Background()
var versionResponse apimiddleware.VersionResponseJson
var versionResponse node.GetVersionResponse
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,

View File

@@ -9,8 +9,8 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
@@ -49,7 +49,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
name string
doppelGangerInput *ethpb.DoppelGangerRequest
doppelGangerExpectedOutput *ethpb.DoppelGangerResponse
getSyncingOutput *apimiddleware.SyncingResponseJson
getSyncingOutput *node.SyncStatusResponse
getForkOutput *beacon.GetStateForkResponse
getHeadersOutput *beacon.GetBlockHeadersResponse
getStateValidatorsInterface *struct {
@@ -109,8 +109,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
{PublicKey: pubKey6, DuplicateExists: false},
},
},
getSyncingOutput: &apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
getSyncingOutput: &node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: false,
},
},
@@ -144,8 +144,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
{PublicKey: pubKey6, DuplicateExists: false},
},
},
getSyncingOutput: &apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
getSyncingOutput: &node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: false,
},
},
@@ -190,8 +190,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
{PublicKey: pubKey6, DuplicateExists: false}, // not recent - not duplicate
},
},
getSyncingOutput: &apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
getSyncingOutput: &node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: false,
},
},
@@ -297,7 +297,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
ctx := context.Background()
if testCase.getSyncingOutput != nil {
syncingResponseJson := apimiddleware.SyncingResponseJson{}
syncingResponseJson := node.SyncStatusResponse{}
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
@@ -409,8 +409,8 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
},
}
standardGetSyncingOutput := &apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
standardGetSyncingOutput := &node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: false,
},
}
@@ -455,7 +455,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
name string
expectedErrorMessage string
inputValidatorRequests []*ethpb.DoppelGangerRequest_ValidatorRequest
getSyncingOutput *apimiddleware.SyncingResponseJson
getSyncingOutput *node.SyncStatusResponse
getSyncingError error
getForkOutput *beacon.GetStateForkResponse
getForkError error
@@ -489,8 +489,8 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
name: "beacon node not synced",
expectedErrorMessage: "beacon node not synced",
inputValidatorRequests: standardInputValidatorRequests,
getSyncingOutput: &apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
getSyncingOutput: &node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsSyncing: true,
},
},
@@ -737,7 +737,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
ctx := context.Background()
if testCase.getSyncingOutput != nil {
syncingResponseJson := apimiddleware.SyncingResponseJson{}
syncingResponseJson := node.SyncStatusResponse{}
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,

View File

@@ -6,7 +6,7 @@ import (
"fmt"
"testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
validator2 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
@@ -65,7 +65,7 @@ func TestValidatorStatus_Nominal(t *testing.T) {
}
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",
@@ -173,7 +173,7 @@ func TestMultipleValidatorStatus_Nominal(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",
@@ -335,7 +335,7 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T)
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",
@@ -345,7 +345,7 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T)
nil,
).SetArg(
2,
apimiddleware.VersionResponseJson{Data: &apimiddleware.VersionJson{Version: "prysm/v0.0.1"}},
node.GetVersionResponse{Data: &node.Version{Version: "prysm/v0.0.1"}},
).Times(1)
var validatorCountResponse validator2.ValidatorCountResponse
@@ -485,7 +485,7 @@ func TestGetValidatorsStatusResponse_Nominal_NoActiveValidators(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",
@@ -725,7 +725,7 @@ func TestValidatorStatusResponse_InvalidData(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",

View File

@@ -12,7 +12,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
@@ -161,11 +161,11 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
syncingEndpoint,
&apimiddleware.SyncingResponseJson{},
&node.SyncStatusResponse{},
).SetArg(
2,
apimiddleware.SyncingResponseJson{
Data: &shared.SyncDetails{
node.SyncStatusResponse{
Data: &node.SyncStatusResponseData{
IsOptimistic: test.isOptimistic,
},
},

View File

@@ -6,7 +6,7 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
validator2 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
"github.com/prysmaticlabs/prysm/v4/testing/require"
@@ -21,7 +21,7 @@ func TestGetValidatorCount(t *testing.T) {
name string
versionEndpointError error
validatorCountEndpointError error
versionResponse apimiddleware.VersionResponseJson
versionResponse node.GetVersionResponse
validatorCountResponse validator2.ValidatorCountResponse
validatorCountCalled int
expectedResponse []iface.ValidatorCount
@@ -29,8 +29,8 @@ func TestGetValidatorCount(t *testing.T) {
}{
{
name: "success",
versionResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{Version: nodeVersion},
versionResponse: node.GetVersionResponse{
Data: &node.Version{Version: nodeVersion},
},
validatorCountResponse: validator2.ValidatorCountResponse{
ExecutionOptimistic: "false",
@@ -52,8 +52,8 @@ func TestGetValidatorCount(t *testing.T) {
},
{
name: "not supported beacon node",
versionResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{Version: "lighthouse/v0.0.1"},
versionResponse: node.GetVersionResponse{
Data: &node.Version{Version: "lighthouse/v0.0.1"},
},
expectedError: "endpoint not supported",
},
@@ -64,8 +64,8 @@ func TestGetValidatorCount(t *testing.T) {
},
{
name: "fails to get validator count",
versionResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{Version: nodeVersion},
versionResponse: node.GetVersionResponse{
Data: &node.Version{Version: nodeVersion},
},
validatorCountEndpointError: errors.New("foo error"),
validatorCountCalled: 1,
@@ -73,8 +73,8 @@ func TestGetValidatorCount(t *testing.T) {
},
{
name: "nil validator count data",
versionResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{Version: nodeVersion},
versionResponse: node.GetVersionResponse{
Data: &node.Version{Version: nodeVersion},
},
validatorCountResponse: validator2.ValidatorCountResponse{
ExecutionOptimistic: "false",
@@ -86,8 +86,8 @@ func TestGetValidatorCount(t *testing.T) {
},
{
name: "invalid validator count",
versionResponse: apimiddleware.VersionResponseJson{
Data: &apimiddleware.VersionJson{Version: nodeVersion},
versionResponse: node.GetVersionResponse{
Data: &node.Version{Version: nodeVersion},
},
validatorCountResponse: validator2.ValidatorCountResponse{
ExecutionOptimistic: "false",
@@ -117,7 +117,7 @@ func TestGetValidatorCount(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse apimiddleware.VersionResponseJson
var nodeVersionResponse node.GetVersionResponse
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
"/eth/v1/node/version",