github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/p2p/cmd/p2p.go (about) 1 package cmd 2 3 import ( 4 "github.com/libp2p/go-libp2p/core/metrics" 5 "github.com/libp2p/go-libp2p/core/network" 6 "github.com/libp2p/go-libp2p/core/peer" 7 "github.com/libp2p/go-libp2p/core/protocol" 8 ma2 "github.com/multiformats/go-multiaddr" 9 "github.com/spf13/cobra" 10 11 cmdnode "github.com/celestiaorg/celestia-node/cmd" 12 ) 13 14 type peerInfo struct { 15 ID string `json:"id"` 16 PeerAddr []string `json:"peer_addr"` 17 } 18 19 func init() { 20 Cmd.AddCommand(infoCmd, 21 peersCmd, 22 peerInfoCmd, 23 connectCmd, 24 closePeerCmd, 25 connectednessCmd, 26 natStatusCmd, 27 blockPeerCmd, 28 unblockPeerCmd, 29 blockedPeersCmd, 30 protectCmd, 31 unprotectCmd, 32 protectedCmd, 33 bandwidthStatsCmd, 34 peerBandwidthCmd, 35 bandwidthForProtocolCmd, 36 pubsubPeersCmd, 37 ) 38 } 39 40 var Cmd = &cobra.Command{ 41 Use: "p2p [command]", 42 Short: "Allows interaction with the P2P Module via JSON-RPC", 43 Args: cobra.NoArgs, 44 PersistentPreRunE: cmdnode.InitClient, 45 } 46 47 var infoCmd = &cobra.Command{ 48 Use: "info", 49 Short: "Gets the node's peer info (peer id and multiaddresses)", 50 Args: cobra.NoArgs, 51 RunE: func(cmd *cobra.Command, args []string) error { 52 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 53 if err != nil { 54 return err 55 } 56 defer client.Close() 57 58 info, err := client.P2P.Info(cmd.Context()) 59 60 formatter := func(data interface{}) interface{} { 61 peerAdd := data.(peer.AddrInfo) 62 ma := make([]string, len(info.Addrs)) 63 for i := range peerAdd.Addrs { 64 ma[i] = peerAdd.Addrs[i].String() 65 } 66 67 return peerInfo{ 68 ID: peerAdd.ID.String(), 69 PeerAddr: ma, 70 } 71 } 72 return cmdnode.PrintOutput(info, err, formatter) 73 }, 74 } 75 76 var peersCmd = &cobra.Command{ 77 Use: "peers", 78 Short: "Lists the peers we are connected to", 79 Args: cobra.NoArgs, 80 RunE: func(cmd *cobra.Command, args []string) error { 81 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 82 if err != nil { 83 return err 84 } 85 defer client.Close() 86 87 result, err := client.P2P.Peers(cmd.Context()) 88 peers := make([]string, len(result)) 89 for i, peer := range result { 90 peers[i] = peer.String() 91 } 92 93 formatter := func(data interface{}) interface{} { 94 conPeers := data.([]string) 95 return struct { 96 Peers []string `json:"peers"` 97 }{ 98 Peers: conPeers, 99 } 100 } 101 return cmdnode.PrintOutput(peers, err, formatter) 102 }, 103 } 104 105 var peerInfoCmd = &cobra.Command{ 106 Use: "peer-info [param]", 107 Short: "Gets PeerInfo for a given peer", 108 Args: cobra.ExactArgs(1), 109 RunE: func(cmd *cobra.Command, args []string) error { 110 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 111 if err != nil { 112 return err 113 } 114 defer client.Close() 115 116 pid, err := peer.Decode(args[0]) 117 if err != nil { 118 return err 119 } 120 info, err := client.P2P.PeerInfo(cmd.Context(), pid) 121 formatter := func(data interface{}) interface{} { 122 peerAdd := data.(peer.AddrInfo) 123 ma := make([]string, len(info.Addrs)) 124 for i := range peerAdd.Addrs { 125 ma[i] = peerAdd.Addrs[i].String() 126 } 127 128 return peerInfo{ 129 ID: peerAdd.ID.String(), 130 PeerAddr: ma, 131 } 132 } 133 return cmdnode.PrintOutput(info, err, formatter) 134 }, 135 } 136 137 var connectCmd = &cobra.Command{ 138 Use: "connect [peer.ID, address]", 139 Short: "Establishes a connection with the given peer", 140 Args: cobra.ExactArgs(2), 141 RunE: func(cmd *cobra.Command, args []string) error { 142 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 143 if err != nil { 144 return err 145 } 146 defer client.Close() 147 148 pid, err := peer.Decode(args[0]) 149 if err != nil { 150 return err 151 } 152 153 ma, err := ma2.NewMultiaddr(args[1]) 154 if err != nil { 155 return err 156 } 157 158 peerInfo := peer.AddrInfo{ 159 ID: pid, 160 Addrs: []ma2.Multiaddr{ma}, 161 } 162 163 err = client.P2P.Connect(cmd.Context(), peerInfo) 164 if err != nil { 165 return cmdnode.PrintOutput(nil, err, nil) 166 } 167 return connectednessCmd.RunE(cmd, args) 168 }, 169 } 170 171 var closePeerCmd = &cobra.Command{ 172 Use: "close-peer [peer.ID]", 173 Short: "Closes the connection with the given peer", 174 Args: cobra.ExactArgs(1), 175 RunE: func(cmd *cobra.Command, args []string) error { 176 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 177 if err != nil { 178 return err 179 } 180 defer client.Close() 181 182 pid, err := peer.Decode(args[0]) 183 if err != nil { 184 return err 185 } 186 187 err = client.P2P.ClosePeer(cmd.Context(), pid) 188 if err != nil { 189 return cmdnode.PrintOutput(nil, err, nil) 190 } 191 return connectednessCmd.RunE(cmd, args) 192 }, 193 } 194 195 var connectednessCmd = &cobra.Command{ 196 Use: "connectedness [peer.ID]", 197 Short: "Checks the connection state between current and given peers", 198 Args: cobra.ExactArgs(1), 199 RunE: func(cmd *cobra.Command, args []string) error { 200 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 201 if err != nil { 202 return err 203 } 204 defer client.Close() 205 206 pid, err := peer.Decode(args[0]) 207 if err != nil { 208 return err 209 } 210 211 con, err := client.P2P.Connectedness(cmd.Context(), pid) 212 213 formatter := func(data interface{}) interface{} { 214 conn := data.(network.Connectedness) 215 return struct { 216 ConnectionState string `json:"connection_state"` 217 }{ 218 ConnectionState: conn.String(), 219 } 220 } 221 return cmdnode.PrintOutput(con, err, formatter) 222 }, 223 } 224 225 var natStatusCmd = &cobra.Command{ 226 Use: "nat-status", 227 Short: "Gets the current NAT status", 228 Args: cobra.NoArgs, 229 RunE: func(cmd *cobra.Command, args []string) error { 230 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 231 if err != nil { 232 return err 233 } 234 defer client.Close() 235 236 r, err := client.P2P.NATStatus(cmd.Context()) 237 238 formatter := func(data interface{}) interface{} { 239 rr := data.(network.Reachability) 240 return struct { 241 Reachability string `json:"reachability"` 242 }{ 243 Reachability: rr.String(), 244 } 245 } 246 return cmdnode.PrintOutput(r, err, formatter) 247 }, 248 } 249 250 var blockPeerCmd = &cobra.Command{ 251 Use: "block-peer [peer.ID]", 252 Short: "Blocks the given peer", 253 Args: cobra.ExactArgs(1), 254 RunE: func(cmd *cobra.Command, args []string) error { 255 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 256 if err != nil { 257 return err 258 } 259 defer client.Close() 260 261 pid, err := peer.Decode(args[0]) 262 if err != nil { 263 return err 264 } 265 266 err = client.P2P.BlockPeer(cmd.Context(), pid) 267 268 formatter := func(data interface{}) interface{} { 269 err, ok := data.(error) 270 blocked := false 271 if !ok { 272 blocked = true 273 } 274 return struct { 275 Blocked bool `json:"blocked"` 276 Peer string `json:"peer"` 277 Reason error `json:"reason,omitempty"` 278 }{ 279 Blocked: blocked, 280 Peer: args[0], 281 Reason: err, 282 } 283 } 284 return cmdnode.PrintOutput(err, nil, formatter) 285 }, 286 } 287 288 var unblockPeerCmd = &cobra.Command{ 289 Use: "unblock-peer [peer.ID]", 290 Short: "Unblocks the given peer", 291 Args: cobra.ExactArgs(1), 292 RunE: func(cmd *cobra.Command, args []string) error { 293 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 294 if err != nil { 295 return err 296 } 297 defer client.Close() 298 299 pid, err := peer.Decode(args[0]) 300 if err != nil { 301 return err 302 } 303 304 err = client.P2P.UnblockPeer(cmd.Context(), pid) 305 306 formatter := func(data interface{}) interface{} { 307 err, ok := data.(error) 308 unblocked := false 309 if !ok { 310 unblocked = true 311 } 312 313 return struct { 314 Unblocked bool `json:"unblocked"` 315 Peer string `json:"peer"` 316 Reason error `json:"reason,omitempty"` 317 }{ 318 Unblocked: unblocked, 319 Peer: args[0], 320 Reason: err, 321 } 322 } 323 return cmdnode.PrintOutput(err, nil, formatter) 324 }, 325 } 326 327 var blockedPeersCmd = &cobra.Command{ 328 Use: "blocked-peers", 329 Short: "Lists the node's blocked peers", 330 Args: cobra.NoArgs, 331 RunE: func(cmd *cobra.Command, args []string) error { 332 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 333 if err != nil { 334 return err 335 } 336 defer client.Close() 337 338 list, err := client.P2P.ListBlockedPeers(cmd.Context()) 339 340 pids := make([]string, len(list)) 341 for i, peer := range list { 342 pids[i] = peer.String() 343 } 344 345 formatter := func(data interface{}) interface{} { 346 peers := data.([]string) 347 return struct { 348 Peers []string `json:"peers"` 349 }{ 350 Peers: peers, 351 } 352 } 353 return cmdnode.PrintOutput(pids, err, formatter) 354 }, 355 } 356 357 var protectCmd = &cobra.Command{ 358 Use: "protect [peer.ID, tag]", 359 Short: "Protects the given peer from being pruned by the given tag", 360 Args: cobra.ExactArgs(2), 361 RunE: func(cmd *cobra.Command, args []string) error { 362 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 363 if err != nil { 364 return err 365 } 366 defer client.Close() 367 368 pid, err := peer.Decode(args[0]) 369 if err != nil { 370 return err 371 } 372 373 err = client.P2P.Protect(cmd.Context(), pid, args[1]) 374 375 formatter := func(data interface{}) interface{} { 376 err, ok := data.(error) 377 protected := false 378 if !ok { 379 protected = true 380 } 381 return struct { 382 Protected bool `json:"protected"` 383 Peer string `json:"peer"` 384 Reason error `json:"reason,omitempty"` 385 }{ 386 Protected: protected, 387 Peer: args[0], 388 Reason: err, 389 } 390 } 391 return cmdnode.PrintOutput(err, nil, formatter) 392 }, 393 } 394 395 var unprotectCmd = &cobra.Command{ 396 Use: "unprotect [peer.ID, tag]", 397 Short: "Removes protection from the given peer.", 398 Long: "Removes a protection that may have been placed on a peer, under the specified tag." + 399 "The return value indicates whether the peer continues to be protected after this call, by way of a different tag", 400 Args: cobra.ExactArgs(2), 401 RunE: func(cmd *cobra.Command, args []string) error { 402 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 403 if err != nil { 404 return err 405 } 406 defer client.Close() 407 408 pid, err := peer.Decode(args[0]) 409 if err != nil { 410 return err 411 } 412 413 _, err = client.P2P.Unprotect(cmd.Context(), pid, args[1]) 414 415 formatter := func(data interface{}) interface{} { 416 err, ok := data.(error) 417 unprotected := false 418 if !ok { 419 unprotected = true 420 } 421 return struct { 422 Unprotected bool `json:"unprotected"` 423 Peer string `json:"peer"` 424 Reason error `json:"reason,omitempty"` 425 }{ 426 Unprotected: unprotected, 427 Peer: args[0], 428 Reason: err, 429 } 430 } 431 return cmdnode.PrintOutput(err, nil, formatter) 432 }, 433 } 434 435 var protectedCmd = &cobra.Command{ 436 Use: "protected [peer.ID, tag]", 437 Short: "Ensures that a given peer is protected under a specific tag", 438 Args: cobra.ExactArgs(2), 439 RunE: func(cmd *cobra.Command, args []string) error { 440 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 441 if err != nil { 442 return err 443 } 444 defer client.Close() 445 446 pid, err := peer.Decode(args[0]) 447 if err != nil { 448 return err 449 } 450 451 result, err := client.P2P.IsProtected(cmd.Context(), pid, args[1]) 452 return cmdnode.PrintOutput(result, err, nil) 453 }, 454 } 455 456 type bandwidthStats struct { 457 TotalIn int64 `json:"total_in"` 458 TotalOut int64 `json:"total_out"` 459 RateIn float64 `json:"rate_in"` 460 RateOut float64 `json:"rate_out"` 461 } 462 463 var bandwidthStatsCmd = &cobra.Command{ 464 Use: "bandwidth-stats", 465 Short: "Provides metrics for current peer.", 466 Long: "Get stats struct with bandwidth metrics for all data sent/" + 467 "received by the local peer, regardless of protocol or remote peer IDs", 468 Args: cobra.NoArgs, 469 RunE: func(cmd *cobra.Command, args []string) error { 470 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 471 if err != nil { 472 return err 473 } 474 defer client.Close() 475 476 result, err := client.P2P.BandwidthStats(cmd.Context()) 477 478 formatter := func(data interface{}) interface{} { 479 stats := data.(metrics.Stats) 480 return bandwidthStats{ 481 TotalIn: stats.TotalIn, 482 TotalOut: stats.TotalOut, 483 RateIn: stats.RateIn, 484 RateOut: stats.RateOut, 485 } 486 } 487 return cmdnode.PrintOutput(result, err, formatter) 488 }, 489 } 490 491 var peerBandwidthCmd = &cobra.Command{ 492 Use: "peer-bandwidth [peer.ID]", 493 Short: "Gets stats struct with bandwidth metrics associated with the given peer.ID", 494 Args: cobra.ExactArgs(1), 495 RunE: func(cmd *cobra.Command, args []string) error { 496 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 497 if err != nil { 498 return err 499 } 500 defer client.Close() 501 502 pid, err := peer.Decode(args[0]) 503 if err != nil { 504 return err 505 } 506 507 result, err := client.P2P.BandwidthForPeer(cmd.Context(), pid) 508 509 formatter := func(data interface{}) interface{} { 510 stats := data.(metrics.Stats) 511 return bandwidthStats{ 512 TotalIn: stats.TotalIn, 513 TotalOut: stats.TotalOut, 514 RateIn: stats.RateIn, 515 RateOut: stats.RateOut, 516 } 517 } 518 return cmdnode.PrintOutput(result, err, formatter) 519 }, 520 } 521 522 var bandwidthForProtocolCmd = &cobra.Command{ 523 Use: "protocol-bandwidth [protocol.ID]", 524 Short: "Gets stats struct with bandwidth metrics associated with the given protocol.ID", 525 Args: cobra.ExactArgs(1), 526 RunE: func(cmd *cobra.Command, args []string) error { 527 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 528 if err != nil { 529 return err 530 } 531 defer client.Close() 532 533 result, err := client.P2P.BandwidthForProtocol(cmd.Context(), protocol.ID(args[0])) 534 535 formatter := func(data interface{}) interface{} { 536 stats := data.(metrics.Stats) 537 return bandwidthStats{ 538 TotalIn: stats.TotalIn, 539 TotalOut: stats.TotalOut, 540 RateIn: stats.RateIn, 541 RateOut: stats.RateOut, 542 } 543 } 544 return cmdnode.PrintOutput(result, err, formatter) 545 }, 546 } 547 548 var pubsubPeersCmd = &cobra.Command{ 549 Use: "pubsub-peers [topic]", 550 Short: "Lists the peers we are connected to in the given topic", 551 Args: cobra.ExactArgs(1), 552 RunE: func(cmd *cobra.Command, args []string) error { 553 client, err := cmdnode.ParseClientFromCtx(cmd.Context()) 554 if err != nil { 555 return err 556 } 557 defer client.Close() 558 559 result, err := client.P2P.PubSubPeers(cmd.Context(), args[0]) 560 peers := make([]string, len(result)) 561 562 for i, peer := range result { 563 peers[i] = peer.String() 564 } 565 566 formatter := func(data interface{}) interface{} { 567 conPeers := data.([]string) 568 return struct { 569 Peers []string `json:"peers"` 570 }{ 571 Peers: conPeers, 572 } 573 } 574 return cmdnode.PrintOutput(peers, err, formatter) 575 }, 576 }