-
Notifications
You must be signed in to change notification settings - Fork 261
Expand file tree
/
Copy pathp2p.go
More file actions
161 lines (134 loc) · 4.18 KB
/
p2p.go
File metadata and controls
161 lines (134 loc) · 4.18 KB
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
151
152
153
154
155
156
157
158
159
160
161
package cmd
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"text/tabwriter"
"connectrpc.com/connect"
pb "github.com/evstack/ev-node/types/pb/evnode/v1"
"github.com/spf13/cobra"
"google.golang.org/protobuf/types/known/emptypb"
rpc "github.com/evstack/ev-node/types/pb/evnode/v1/v1connect"
)
const (
flagOutput = "output"
)
func init() {
NetInfoCmd.Flags().StringP(flagOutput, "o", "text", "Output format (text|json)")
}
// NetInfoCmd returns information about the running node via RPC
var NetInfoCmd = &cobra.Command{
Use: "net-info",
Short: "Get information about a running node via RPC",
Long: "This command retrieves the node information via RPC from a running node in the specified directory (or current directory if not specified).",
RunE: func(cmd *cobra.Command, args []string) error {
nodeConfig, err := ParseConfig(cmd)
if err != nil {
return fmt.Errorf("error parsing config: %w", err)
}
rpcAddress := nodeConfig.RPC.Address
if rpcAddress == "" {
return fmt.Errorf("RPC address not found in node configuration")
}
// Create HTTP client
httpClient := http.Client{
Transport: http.DefaultTransport,
}
baseURL := rpcAddress
if !strings.HasPrefix(rpcAddress, "http://") && !strings.HasPrefix(rpcAddress, "https://") {
baseURL = "http://" + baseURL
}
// Create P2P client
p2pClient := rpc.NewP2PServiceClient(
&httpClient,
baseURL,
)
// Call GetNetInfo RPC
resp, err := p2pClient.GetNetInfo(
cmd.Context(),
connect.NewRequest(&emptypb.Empty{}),
)
if err != nil {
return fmt.Errorf("GetNetInfo RPC: %w", err)
}
netInfo := resp.Msg.NetInfo
peerResp, err := p2pClient.GetPeerInfo(
cmd.Context(),
connect.NewRequest(&emptypb.Empty{}),
)
if err != nil {
return fmt.Errorf("GetPeerInfo RPC: %w", err)
}
outputFormat, err := cmd.Flags().GetString(flagOutput)
if err != nil {
return err
}
if outputFormat == "json" {
return formatJson(cmd.OutOrStdout(), netInfo, peerResp)
}
nodeID := netInfo.Id
out := cmd.OutOrStdout()
w := tabwriter.NewWriter(out, 2, 0, 2, ' ', 0)
fmt.Fprintf(w, "%s", strings.Repeat("=", 50))
fmt.Fprintf(w, "📊 NODE INFORMATION")
fmt.Fprintf(w, "%s\n", strings.Repeat("=", 50))
fmt.Fprintf(w, "🆔 Node ID: \033[1;36m%s\033[0m\n", nodeID) // Print Node ID once
// Iterate through all listen addresses
fmt.Fprintf(w, "📡 Listen Addrs:")
for i, addr := range netInfo.ListenAddresses {
fullAddress := fmt.Sprintf("%s/p2p/%s", addr, nodeID)
fmt.Fprintf(w, " [%d] Addr: \033[1;36m%s\033[0m\n", i+1, addr)
fmt.Fprintf(w, " Full: \033[1;32m%s\033[0m\n", fullAddress)
}
fmt.Fprintf(w, "%s\n", strings.Repeat("-", 50))
// Print connected peers in a table-like format
peerCount := len(peerResp.Msg.Peers)
fmt.Fprintf(w, "👥 CONNECTED PEERS: \033[1;33m%d\033[0m\n", peerCount)
if peerCount > 0 {
fmt.Fprintf(w, "%s\n", strings.Repeat("-", 50))
fmt.Fprintf(w, "%-5s %-20s %s\n", "NO.", "PEER ID", "ADDRESS")
fmt.Fprintf(w, "%s\n", strings.Repeat("-", 50))
for i, peer := range peerResp.Msg.Peers {
// Truncate peer ID if it's too long for display
peerID := peer.Id
if len(peerID) > 18 {
peerID = peerID[:15] + "..."
}
fmt.Fprintf(w, "%-5d \033[1;34m%-20s\033[0m %s\n", i+1, peerID, peer.Address)
}
} else {
fmt.Fprintf(w, "\n\033[3;33mNo peers connected\033[0m")
}
fmt.Fprintf(w, "%s\n", strings.Repeat("=", 50))
w.Flush()
return nil
},
}
func formatJson(w io.Writer, netInfo *pb.NetInfo, peerResp *connect.Response[pb.GetPeerInfoResponse]) error {
type peerJSON struct {
ID string `json:"id"`
Address string `json:"address"`
}
type netInfoJSON struct {
NodeID string `json:"node_id"`
ListenAddresses []string `json:"listen_addresses"`
Peers []peerJSON `json:"peers"`
}
peers := make([]peerJSON, 0, len(peerResp.Msg.Peers))
for _, peer := range peerResp.Msg.Peers {
peers = append(peers, peerJSON{
ID: peer.Id,
Address: peer.Address,
})
}
out := netInfoJSON{
NodeID: netInfo.Id,
ListenAddresses: netInfo.ListenAddresses,
Peers: peers,
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
return enc.Encode(out)
}