Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client pages: multiple improvements #117

Merged
merged 13 commits into from
Sep 9, 2024
Merged
3 changes: 2 additions & 1 deletion .hack/devnet/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ frontend:
siteName: "Dora the Explorer"
siteSubtitle: "$ENCLAVE_NAME - Kurtosis"
ethExplorerLink: ""
showSensitivePeerInfos: true
beaconapi:
localCacheSize: 10
redisCacheAddr: ""
Expand Down Expand Up @@ -81,4 +82,4 @@ Dora config at ${__dir}/generated-dora-config.yaml
Chain config at ${__dir}/generated-chain-config.yaml
Database at ${__dir}/generated-database.sqlite
============================================================================================================
EOF
EOF
7 changes: 4 additions & 3 deletions clients/consensus/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/ethpandaops/dora/clients/consensus/rpc"
"github.com/ethpandaops/dora/clients/sshtunnel"
"github.com/ethpandaops/dora/types"
)

type ClientConfig struct {
Expand All @@ -33,7 +34,7 @@ type Client struct {
isSyncing bool
isOptimistic bool
versionStr string
peerId string
nodeIdentity *types.NodeIdentity
clientType ClientType
lastEvent time.Time
retryCounter uint64
Expand Down Expand Up @@ -112,8 +113,8 @@ func (client *Client) GetVersion() string {
return client.versionStr
}

func (client *Client) GetPeerID() string {
return client.peerId
func (client *Client) GetNodeIdentity() *types.NodeIdentity {
return client.nodeIdentity
}

func (client *Client) GetEndpointConfig() *ClientConfig {
Expand Down
2 changes: 1 addition & 1 deletion clients/consensus/clientlogic.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func (client *Client) updateNodePeers(ctx context.Context) error {
defer cancel()

var err error
client.peerId, err = client.rpcClient.GetNodePeerId(ctx)
client.nodeIdentity, err = client.rpcClient.GetNodeIdentity(ctx)
if err != nil {
return fmt.Errorf("could not get node peer id: %v", err)
}
Expand Down
15 changes: 7 additions & 8 deletions clients/consensus/rpc/beaconapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"golang.org/x/crypto/ssh"

"github.com/ethpandaops/dora/clients/sshtunnel"
"github.com/ethpandaops/dora/types"
)

type BeaconClient struct {
Expand Down Expand Up @@ -470,18 +471,16 @@ func (bc *BeaconClient) GetNodePeers(ctx context.Context) ([]*v1.Peer, error) {
return result.Data, nil
}

func (bc *BeaconClient) GetNodePeerId(ctx context.Context) (string, error) {
nodeIdentity := struct {
Data struct {
PeerId string `json:"peer_id"`
} `json:"data"`
func (bc *BeaconClient) GetNodeIdentity(ctx context.Context) (*types.NodeIdentity, error) {
response := struct {
Data *types.NodeIdentity `json:"data"`
}{}

err := bc.getJSON(ctx, fmt.Sprintf("%s/eth/v1/node/identity", bc.endpoint), &nodeIdentity)
err := bc.getJSON(ctx, fmt.Sprintf("%s/eth/v1/node/identity", bc.endpoint), &response)
if err != nil {
return "", fmt.Errorf("error retrieving node identity: %v", err)
return nil, fmt.Errorf("error retrieving node identity: %v", err)
}
return nodeIdentity.Data.PeerId, nil
return response.Data, nil
}

func (bc *BeaconClient) SubmitBLSToExecutionChanges(ctx context.Context, blsChanges []*capella.SignedBLSToExecutionChange) error {
Expand Down
2 changes: 0 additions & 2 deletions cmd/dora-explorer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ func startFrontend(webserver *http.Server) {
router.HandleFunc("/validator/{idxOrPubKey}", handlers.Validator).Methods("GET")
router.HandleFunc("/validator/{index}/slots", handlers.ValidatorSlots).Methods("GET")

router.HandleFunc("/identicon", handlers.Identicon).Methods("GET")

if utils.Config.Frontend.Pprof {
// add pprof handler
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ require (
github.com/juliangruber/go-intersect v1.1.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/lib/pq v1.10.9
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mashingan/smapping v0.1.19
github.com/mitchellh/mapstructure v1.5.0
github.com/pk910/dynamic-ssz v0.0.5
Expand All @@ -27,7 +26,6 @@ require (
github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15
github.com/rs/zerolog v1.33.0
github.com/sirupsen/logrus v1.9.3
github.com/stdatiks/jdenticon-go v0.1.0
github.com/tdewolff/minify v2.3.6+incompatible
github.com/urfave/negroni v1.0.0
golang.org/x/crypto v0.26.0
Expand Down
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
Expand Down Expand Up @@ -273,9 +272,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lightclient/go-ethereum v0.0.0-20240726203109-4a0622f95d30 h1:mhkIkcs3GhL1kZyyCko1gUlnwCpfYpfYckqiz20k8HU=
github.com/lightclient/go-ethereum v0.0.0-20240726203109-4a0622f95d30/go.mod h1:RKrX5zEFmD/CQ8XLRxc3eOEcqqwN4no8ZzuNkVxEFFY=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mashingan/smapping v0.1.19 h1:SsEtuPn2UcM1croIupPtGLgWgpYRuS0rSQMvKD9g2BQ=
github.com/mashingan/smapping v0.1.19/go.mod h1:FjfiwFxGOuNxL/OT1WcrNAwTPx0YJeg5JiXwBB1nyig=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
Expand Down Expand Up @@ -385,8 +381,6 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
github.com/stdatiks/jdenticon-go v0.1.0 h1:yf0xbl3OIu1oafVmgqGaB6m7QMNOaNkwsW/omzSyN5g=
github.com/stdatiks/jdenticon-go v0.1.0/go.mod h1:hzZIjAw3ZhYi3S5IOjIvC7C/dsc17L8Kc3AtEnP0ucw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
Expand Down
105 changes: 77 additions & 28 deletions handlers/clients_cl.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethpandaops/dora/services"
"github.com/ethpandaops/dora/templates"
"github.com/ethpandaops/dora/types/models"
"github.com/ethpandaops/dora/utils"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -65,22 +67,28 @@ func buildCLPeerMapData() *models.ClientCLPageDataPeerMap {
edges := make(map[string]*models.ClientCLDataMapPeerMapEdge)

for _, client := range services.GlobalBeaconService.GetConsensusClients() {
peerID := client.GetPeerID()
id := client.GetNodeIdentity()
if id == nil {
continue
}
peerID := id.PeerID
if _, ok := nodes[peerID]; !ok {
node := models.ClientCLPageDataPeerMapNode{
ID: peerID,
Label: client.GetName(),
Group: "internal",
Image: fmt.Sprintf("/identicon?key=%s", peerID),
Shape: "circularImage",
}
nodes[peerID] = &node
peerMap.ClientPageDataMapNode = append(peerMap.ClientPageDataMapNode, &node)
}
}

for _, client := range services.GlobalBeaconService.GetConsensusClients() {
peerId := client.GetPeerID()
id := client.GetNodeIdentity()
if id == nil {
continue
}
peerId := id.PeerID
peers := client.GetNodePeers()
for _, peer := range peers {
peerId := peerId
Expand All @@ -90,8 +98,6 @@ func buildCLPeerMapData() *models.ClientCLPageDataPeerMap {
ID: peer.PeerID,
Label: fmt.Sprintf("%s...%s", peer.PeerID[0:5], peer.PeerID[len(peer.PeerID)-5:]),
Group: "external",
Image: fmt.Sprintf("/identicon?key=%s", peer.PeerID),
Shape: "circularImage",
}
nodes[peer.PeerID] = &node
peerMap.ClientPageDataMapNode = append(peerMap.ClientPageDataMapNode, &node)
Expand All @@ -110,9 +116,8 @@ func buildCLPeerMapData() *models.ClientCLPageDataPeerMap {
p2.Value++

if _, ok := edges[idx]; !ok {
edge := models.ClientCLDataMapPeerMapEdge{}
if nodes[peer.PeerID].Group == "external" {
edge.Dashes = true
edge := models.ClientCLDataMapPeerMapEdge{
Interaction: nodes[peer.PeerID].Group,
}
if peer.Direction == "inbound" {
edge.From = peer.PeerID
Expand All @@ -133,8 +138,9 @@ func buildCLPeerMapData() *models.ClientCLPageDataPeerMap {
func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) {
logrus.Debugf("clients page called")
pageData := &models.ClientsCLPageData{
Clients: []*models.ClientsCLPageDataClient{},
PeerMap: buildCLPeerMapData(),
Clients: []*models.ClientsCLPageDataClient{},
PeerMap: buildCLPeerMapData(),
ShowSensitivePeerInfos: utils.Config.Frontend.ShowSensitivePeerInfos,
}
chainState := services.GlobalBeaconService.GetChainState()

Expand All @@ -147,7 +153,11 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) {

aliases := map[string]string{}
for _, client := range services.GlobalBeaconService.GetConsensusClients() {
aliases[client.GetPeerID()] = client.GetName()
id := client.GetNodeIdentity()
if id == nil {
continue
}
aliases[id.PeerID] = client.GetName()
}

for _, client := range services.GlobalBeaconService.GetConsensusClients() {
Expand All @@ -164,12 +174,30 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) {
peerAlias = alias
peerType = "internal"
}

enrKeyValues := map[string]interface{}{}
var nodeID string

if peer.Enr != "" { // Some clients might not announce the ENR of their peers
parsedEnr, err := utils.DecodeENR(peer.Enr)
if err != nil {
logrus.WithFields(logrus.Fields{"client": client.GetName(), "peer_enr": peer.Enr}).Error("failed to decode peer enr. ", err)
parsedEnr = &enr.Record{}
}
enrKeyValues = utils.GetKeyValuesFromENR(parsedEnr)
nodeID = utils.GetNodeIDFromENR(parsedEnr)
}

resPeers = append(resPeers, &models.ClientCLPageDataClientPeers{
ID: peer.PeerID,
State: peer.State,
Direction: peer.Direction,
Alias: peerAlias,
Type: peerType,
ID: peer.PeerID,
State: peer.State,
Direction: peer.Direction,
Alias: peerAlias,
Type: peerType,
ENR: peer.Enr,
ENRKeyValues: enrKeyValues,
NodeID: nodeID,
LastSeenP2PAddress: peer.LastSeenP2PAddress,
})

if peer.Direction == "inbound" {
Expand All @@ -185,18 +213,39 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) {
return resPeers[i].Type > resPeers[j].Type
})

id := client.GetNodeIdentity()
if id == nil {
continue
}

rec, err := utils.DecodeENR(id.Enr)
if err != nil {
logrus.WithFields(logrus.Fields{"client": client.GetName(), "enr": id.Enr}).Error("failed to decode enr. ", err)
rec = &enr.Record{}
}

enrkv := utils.GetKeyValuesFromENR(rec)

nodeID := utils.GetNodeIDFromENR(rec)

resClient := &models.ClientsCLPageDataClient{
Index: int(client.GetIndex()) + 1,
Name: client.GetName(),
Version: client.GetVersion(),
Peers: resPeers,
PeerID: client.GetPeerID(),
PeersInboundCounter: inPeerCount,
PeersOutboundCounter: outPeerCount,
HeadSlot: uint64(lastHeadSlot),
HeadRoot: lastHeadRoot[:],
Status: client.GetStatus().String(),
LastRefresh: client.GetLastEventTime(),
Index: int(client.GetIndex()) + 1,
Name: client.GetName(),
Version: client.GetVersion(),
Peers: resPeers,
PeerID: id.PeerID,
ENR: id.Enr,
ENRKeyValues: enrkv,
NodeID: nodeID,
P2PAddresses: id.P2PAddresses,
DisoveryAddresses: id.DiscoveryAddresses,
AttestationSubnetSubs: id.Metadata.Attnets,
PeersInboundCounter: inPeerCount,
PeersOutboundCounter: outPeerCount,
HeadSlot: uint64(lastHeadSlot),
HeadRoot: lastHeadRoot[:],
Status: client.GetStatus().String(),
LastRefresh: client.GetLastEventTime(),
}

lastError := client.GetLastClientError()
Expand Down
Loading
Loading