forked from ledgerwatch/erigon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
peers.go
150 lines (127 loc) · 4.6 KB
/
peers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package diagnostics
import (
"encoding/json"
"net/http"
diagnint "github.com/nebojsa94/erigon/erigon-lib/diagnostics"
"github.com/nebojsa94/erigon/turbo/node"
"github.com/urfave/cli/v2"
)
type PeerNetworkInfo struct {
LocalAddress string `json:"localAddress"` // Local endpoint of the TCP data connection
RemoteAddress string `json:"remoteAddress"` // Remote endpoint of the TCP data connection
Inbound bool `json:"inbound"`
Trusted bool `json:"trusted"`
Static bool `json:"static"`
BytesIn uint64 `json:"bytesIn"`
BytesOut uint64 `json:"bytesOut"`
CapBytesIn map[string]uint64 `json:"capBytesIn"`
CapBytesOut map[string]uint64 `json:"capBytesOut"`
TypeBytesIn map[string]uint64 `json:"typeBytesIn"`
TypeBytesOut map[string]uint64 `json:"typeBytesOut"`
}
type PeerResponse struct {
ENR string `json:"enr,omitempty"` // Ethereum Node Record
Enode string `json:"enode"` // Node URL
ID string `json:"id"` // Unique node identifier
Name string `json:"name"` // Name of the node, including client type, version, OS, custom data
ErrorCount int `json:"errorCount"` // Number of errors
LastSeenError string `json:"lastSeenError"` // Last seen error
Type string `json:"type"` // Type of connection
Caps []string `json:"caps"` // Protocols advertised by this peer
Network PeerNetworkInfo `json:"network"`
Protocols map[string]interface{} `json:"protocols"` // Sub-protocol specific metadata fields
}
func SetupPeersAccess(ctxclient *cli.Context, metricsMux *http.ServeMux, node *node.ErigonNode) {
metricsMux.HandleFunc("/peers", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/json")
writePeers(w, ctxclient, node)
})
}
func writePeers(w http.ResponseWriter, ctx *cli.Context, node *node.ErigonNode) {
sentinelPeers, err := sentinelPeers(node)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sentryPeers, err := sentryPeers(node)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
allPeers := append(sentryPeers, sentinelPeers...)
json.NewEncoder(w).Encode(allPeers)
}
func sentinelPeers(node *node.ErigonNode) ([]*PeerResponse, error) {
if diag, ok := node.Backend().Sentinel().(diagnint.PeerStatisticsGetter); ok {
statisticsArray := diag.GetPeersStatistics()
peers := make([]*PeerResponse, 0, len(statisticsArray))
for key, value := range statisticsArray {
peer := PeerResponse{
ENR: "", //TODO: find a way how to get missing data
Enode: "",
ID: key,
Name: "",
Type: "Sentinel",
Caps: []string{},
Network: PeerNetworkInfo{
LocalAddress: "",
RemoteAddress: "",
Inbound: false,
Trusted: false,
Static: false,
BytesIn: value.BytesIn,
BytesOut: value.BytesOut,
CapBytesIn: value.CapBytesIn,
CapBytesOut: value.CapBytesOut,
TypeBytesIn: value.TypeBytesIn,
TypeBytesOut: value.TypeBytesOut,
},
Protocols: nil,
}
peers = append(peers, &peer)
}
return peers, nil
} else {
return []*PeerResponse{}, nil
}
}
func sentryPeers(node *node.ErigonNode) ([]*PeerResponse, error) {
statisticsArray := node.Backend().DiagnosticsPeersData()
peers := make([]*PeerResponse, 0, len(statisticsArray))
for key, value := range statisticsArray {
peer := PeerResponse{
ENR: "", //TODO: find a way how to get missing data
Enode: "",
ID: key,
Name: "",
Type: "Sentry",
Caps: []string{},
Network: PeerNetworkInfo{
LocalAddress: "",
RemoteAddress: "",
Inbound: false,
Trusted: false,
Static: false,
BytesIn: value.BytesIn,
BytesOut: value.BytesOut,
CapBytesIn: value.CapBytesIn,
CapBytesOut: value.CapBytesOut,
TypeBytesIn: value.TypeBytesIn,
TypeBytesOut: value.TypeBytesOut,
},
Protocols: nil,
}
peers = append(peers, &peer)
}
return filterPeersWithoutBytesIn(peers), nil
}
func filterPeersWithoutBytesIn(peers []*PeerResponse) []*PeerResponse {
filteredPeers := make([]*PeerResponse, 0, len(peers))
for _, peer := range peers {
if peer.Network.BytesIn > 0 {
filteredPeers = append(filteredPeers, peer)
}
}
return filteredPeers
}