From bc87a7b426a3ed66b8d0e559e89e9d70f0cdd035 Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Wed, 23 Aug 2023 00:24:38 +0300 Subject: [PATCH 01/11] feat(cmd/rpc): add commands for p2p module --- cmd/celestia/blob.go | 43 +-- cmd/celestia/p2p.go | 601 +++++++++++++++++++++++++++++++++++++++++ cmd/celestia/rpc.go | 25 ++ nodebuilder/p2p/p2p.go | 12 +- 4 files changed, 646 insertions(+), 35 deletions(-) create mode 100644 cmd/celestia/p2p.go diff --git a/cmd/celestia/blob.go b/cmd/celestia/blob.go index 28d05b3b42..34868ef112 100644 --- a/cmd/celestia/blob.go +++ b/cmd/celestia/blob.go @@ -2,9 +2,7 @@ package main import ( "encoding/base64" - "encoding/json" "fmt" - "os" "reflect" "strconv" @@ -66,7 +64,12 @@ var getCmd = &cobra.Command{ blob, err := client.Blob.Get(cmd.Context(), height, namespace, commitment) - printOutput(blob, err) + formatter := formatData + if base64Flag || err != nil { + formatter = nil + } + + printOutput(blob, err, formatter) return nil }, } @@ -93,7 +96,12 @@ var getAllCmd = &cobra.Command{ blobs, err := client.Blob.GetAll(cmd.Context(), height, []share.Namespace{namespace}) - printOutput(blobs, err) + formatter := formatData + if base64Flag || err != nil { + formatter = nil + } + + printOutput(blobs, err, formatter) return nil }, } @@ -128,7 +136,7 @@ var submitCmd = &cobra.Command{ Commitment: parsedBlob.Commitment, } - printOutput(response, err) + printOutput(response, err, nil) return nil }, } @@ -160,34 +168,11 @@ var getProofCmd = &cobra.Command{ proof, err := client.Blob.GetProof(cmd.Context(), height, namespace, commitment) - printOutput(proof, err) + printOutput(proof, err, nil) return nil }, } -func printOutput(data interface{}, err error) { - if err != nil { - data = err - } - - if !base64Flag && err == nil { - data = formatData(data) - } - - resp := struct { - Result interface{} `json:"result"` - }{ - Result: data, - } - - bytes, err := json.MarshalIndent(resp, "", " ") - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - fmt.Fprintln(os.Stdout, string(bytes)) -} - func formatData(data interface{}) interface{} { type tempBlob struct { Namespace []byte `json:"namespace"` diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go new file mode 100644 index 0000000000..79a0aa90fe --- /dev/null +++ b/cmd/celestia/p2p.go @@ -0,0 +1,601 @@ +package main + +import ( + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + ma2 "github.com/multiformats/go-multiaddr" + "github.com/spf13/cobra" +) + +type peerInfo struct { + ID string `json:"id"` + PeerAddr []string `json:"peer_addr"` +} + +func init() { + p2pCmd.AddCommand(infoCmd, + peersCmd, + peerInfoCmd, + connectCmd, + closePeerCmd, + connectednessCmd, + natStatusCmd, + blockPeerCmd, + unblockPeerCmd, + blockedPeersCmd, + protectCmd, + unprotectCmd, + protectedCmd, + bandwidthStatsCmd, + peerBandwidthCmd, + bandwidthForProtocolCmd, + pubsubPeersCmd, + ) +} + +var p2pCmd = &cobra.Command{ + Use: "p2p [command]", + Short: "Allows to interact with the P2P Module via JSON-RPC", + Args: cobra.NoArgs, +} + +var infoCmd = &cobra.Command{ + Use: "info", + Short: "Allows to get the node's Peer Info", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + info, err := client.P2P.Info(cmd.Context()) + + formatter := func(data interface{}) interface{} { + peerAdd, ok := data.(peer.AddrInfo) + if !ok { + return peerAdd + } + + ma := make([]string, len(info.Addrs)) + for i := range peerAdd.Addrs { + ma[i] = peerAdd.Addrs[i].String() + } + + return peerInfo{ + ID: peerAdd.ID.String(), + PeerAddr: ma, + } + } + + printOutput(info, err, formatter) + return nil + }, +} + +var peersCmd = &cobra.Command{ + Use: "peers", + Short: "Allows to get the list of peers we are connected to", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + result, err := client.P2P.Peers(cmd.Context()) + peers := make([]string, len(result)) + for i, peer := range result { + peers[i] = peer.String() + } + + formatter := func(data interface{}) interface{} { + conPeers, ok := data.([]string) + if !ok { + return conPeers + } + return struct { + Peers []string `json:"peers"` + }{ + Peers: conPeers, + } + } + + printOutput(peers, err, formatter) + return nil + }, +} + +var peerInfoCmd = &cobra.Command{ + Use: "peer-info [param]", + Short: "Allows to get a PeerInfo struct for a given peer", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + info, err := client.P2P.PeerInfo(cmd.Context(), pid) + formatter := func(data interface{}) interface{} { + peerAdd, ok := data.(peer.AddrInfo) + if !ok { + return peerAdd + } + + ma := make([]string, len(info.Addrs)) + for i := range peerAdd.Addrs { + ma[i] = peerAdd.Addrs[i].String() + } + + return peerInfo{ + ID: peerAdd.ID.String(), + PeerAddr: ma, + } + } + + printOutput(info, err, formatter) + return nil + }, +} + +var connectCmd = &cobra.Command{ + Use: "connect [peer.ID, address]", + Short: "Allows to establish a connection with the given peer", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + ma, err := ma2.NewMultiaddr(args[1]) + if err != nil { + return err + } + + peerInfo := peer.AddrInfo{ + ID: pid, + Addrs: []ma2.Multiaddr{ma}, + } + + err = client.P2P.Connect(cmd.Context(), peerInfo) + if err != nil { + printOutput(nil, err, nil) + return nil + } + return connectednessCmd.RunE(cmd, args) + }, +} + +var closePeerCmd = &cobra.Command{ + Use: "close-peer [peer.ID]", + Short: "Allows to close the connection with the given peer", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + err = client.P2P.ClosePeer(cmd.Context(), pid) + if err != nil { + printOutput(nil, err, nil) + return nil + } + return connectednessCmd.RunE(cmd, args) + }, +} + +var connectednessCmd = &cobra.Command{ + Use: "connectedness [peer.ID]", + Short: "Allows to check the connection state between current and given peers", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + con, err := client.P2P.Connectedness(cmd.Context(), pid) + + formatter := func(data interface{}) interface{} { + conn := data.(network.Connectedness) + return struct { + ConnectionState string `json:"connection_state"` + }{ + ConnectionState: conn.String(), + } + } + + printOutput(con, err, formatter) + return nil + }, +} + +var natStatusCmd = &cobra.Command{ + Use: "nat-status", + Short: "Allows to check the current NAT status", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + r, err := client.P2P.NATStatus(cmd.Context()) + + formatter := func(data interface{}) interface{} { + rr := data.(network.Reachability) + return struct { + Reachability string `json:"reachability"` + }{ + Reachability: rr.String(), + } + } + + printOutput(r, err, formatter) + return nil + }, +} + +var blockPeerCmd = &cobra.Command{ + Use: "block-peer [peer.ID]", + Short: "Allows to block a given peer", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + err = client.P2P.BlockPeer(cmd.Context(), pid) + + formatter := func(data interface{}) interface{} { + err, ok := data.(error) + blocked := false + if !ok { + blocked = true + } + return struct { + Blocked bool `json:"blocked"` + Peer string `json:"peer"` + Reason error `json:"reason,omitempty"` + }{ + Blocked: blocked, + Peer: args[0], + Reason: err, + } + } + + printOutput(nil, err, formatter) + return nil + }, +} + +var unblockPeerCmd = &cobra.Command{ + Use: "unblock-peer [peer.ID]", + Short: "Allows to unblock a given peer", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + err = client.P2P.UnblockPeer(cmd.Context(), pid) + + formatter := func(data interface{}) interface{} { + err, ok := data.(error) + unblocked := false + if !ok { + unblocked = true + } + + return struct { + Unblocked bool `json:"unblocked"` + Peer string `json:"peer"` + Reason error `json:"reason,omitempty"` + }{ + Unblocked: unblocked, + Peer: args[0], + Reason: err, + } + } + + printOutput(nil, err, formatter) + return nil + }, +} + +var blockedPeersCmd = &cobra.Command{ + Use: "blocked-peers", + Short: "Allows to get a list of the blocked peers", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + list, err := client.P2P.ListBlockedPeers(cmd.Context()) + + pids := make([]string, len(list)) + for i, peer := range list { + pids[i] = peer.String() + } + + formatter := func(data interface{}) interface{} { + peers := data.([]string) + return struct { + Peers []string `json:"peers"` + }{ + Peers: peers, + } + } + + printOutput(pids, err, formatter) + return nil + }, +} + +var protectCmd = &cobra.Command{ + Use: "protect [peer.ID, tag]", + Short: "Allows to protect a given peer from being pruned by the given tag", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + err = client.P2P.Protect(cmd.Context(), pid, args[1]) + + formatter := func(data interface{}) interface{} { + err, ok := data.(error) + protected := false + if !ok { + protected = true + } + return struct { + Protected bool `json:"protected"` + Peer string `json:"peer"` + Reason error `json:"reason,omitempty"` + }{ + Protected: protected, + Peer: args[0], + Reason: err, + } + } + + printOutput(nil, err, formatter) + return nil + }, +} + +var unprotectCmd = &cobra.Command{ + Use: "unprotect [peer.ID, tag]", + Short: "Removes a protection that may have been placed on a peer, under the specified tag." + + "The return value indicates whether the peer continues to be protected after this call, by way of a different tag", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + result, err := client.P2P.Unprotect(cmd.Context(), pid, args[1]) + + formatter := func(data interface{}) interface{} { + err, ok := data.(error) + unprotected := false + if !ok { + unprotected = true + } + return struct { + Unprotected bool `json:"unprotected"` + Peer string `json:"peer"` + Reason error `json:"reason,omitempty"` + }{ + Unprotected: unprotected, + Peer: args[0], + Reason: err, + } + } + + printOutput(result, err, formatter) + return nil + }, +} + +var protectedCmd = &cobra.Command{ + Use: "protected [peer.ID, tag]", + Short: "Ensures that a given peer is protected under a specific tag", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + result, err := client.P2P.IsProtected(cmd.Context(), pid, args[1]) + + printOutput(result, err, nil) + return nil + }, +} + +type bandwidthStats struct { + TotalIn int64 `json:"total_in"` + TotalOut int64 `json:"total_out"` + RateIn float64 `json:"rate_in"` + RateOut float64 `json:"rate_out"` +} + +var bandwidthStatsCmd = &cobra.Command{ + Use: "bandwidth-stats", + Short: "Allows to get stats struct with bandwidth metrics for all data sent/" + + "received by the local peer, regardless of protocol or remote peer IDs", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + result, err := client.P2P.BandwidthStats(cmd.Context()) + + formatter := func(data interface{}) interface{} { + stats := data.(metrics.Stats) + return bandwidthStats{ + TotalIn: stats.TotalIn, + TotalOut: stats.TotalOut, + RateIn: stats.RateIn, + RateOut: stats.RateOut, + } + } + + printOutput(result, err, formatter) + return nil + }, +} + +var peerBandwidthCmd = &cobra.Command{ + Use: "peer-bandwidth [peer.ID]", + Short: "Allows to get stats struct with bandwidth metrics associated with the given peer.ID", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + pid, err := peer.Decode(args[0]) + if err != nil { + return err + } + + result, err := client.P2P.BandwidthForPeer(cmd.Context(), pid) + + formatter := func(data interface{}) interface{} { + stats := data.(metrics.Stats) + return bandwidthStats{ + TotalIn: stats.TotalIn, + TotalOut: stats.TotalOut, + RateIn: stats.RateIn, + RateOut: stats.RateOut, + } + } + + printOutput(result, err, formatter) + return nil + }, +} + +var bandwidthForProtocolCmd = &cobra.Command{ + Use: "protocol-bandwidth [protocol.ID]", + Short: "Allows to get stats struct with bandwidth metrics associated with the given peer.ID", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + result, err := client.P2P.BandwidthForProtocol(cmd.Context(), protocol.ID(args[0])) + + formatter := func(data interface{}) interface{} { + stats := data.(metrics.Stats) + return bandwidthStats{ + TotalIn: stats.TotalIn, + TotalOut: stats.TotalOut, + RateIn: stats.RateIn, + RateOut: stats.RateOut, + } + } + + printOutput(result, err, formatter) + return nil + }, +} + +var pubsubPeersCmd = &cobra.Command{ + Use: "pubsub-peers [topic]", + Short: "Allows to get a list of peers we are connected to in the given topic", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + //TODO: check + result, err := client.P2P.PubSubPeers(cmd.Context(), args[0]) + peers := make([]string, len(result)) + + for i, peer := range result { + peers[i] = peer.String() + } + + formatter := func(data interface{}) interface{} { + conPeers, ok := data.([]string) + if !ok { + return data + } + return struct { + Peers []string `json:"peers"` + }{ + Peers: conPeers, + } + } + + printOutput(peers, err, formatter) + return nil + }, +} diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index dd50f07fc2..d3ccf0823a 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -61,7 +61,9 @@ func init() { "Print JSON-RPC request along with the response", ) rpcCmd.AddCommand(blobCmd) + rpcCmd.AddCommand(p2pCmd) rootCmd.AddCommand(rpcCmd) + } var rpcCmd = &cobra.Command{ @@ -399,3 +401,26 @@ func rpcClient(ctx context.Context) (*client.Client, error) { } return client, nil } + +func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) { + if err != nil { + data = err + } + + if formatData != nil { + data = formatData(data) + } + + resp := struct { + Result interface{} `json:"result"` + }{ + Result: data, + } + + bytes, err := json.MarshalIndent(resp, "", " ") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + fmt.Fprintln(os.Stdout, string(bytes)) +} diff --git a/nodebuilder/p2p/p2p.go b/nodebuilder/p2p/p2p.go index a418eaf4d8..6a1d256250 100644 --- a/nodebuilder/p2p/p2p.go +++ b/nodebuilder/p2p/p2p.go @@ -194,24 +194,24 @@ func (m *module) PubSubPeers(_ context.Context, topic string) ([]peer.ID, error) //nolint:dupl type API struct { Internal struct { - Info func(context.Context) (peer.AddrInfo, error) `perm:"admin"` - Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` + Info func(context.Context) (peer.AddrInfo, error) `perm:"public"` + Peers func(context.Context) ([]peer.ID, error) `perm:"read"` PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` - Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"admin"` + Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"read"` NATStatus func(context.Context) (network.Reachability, error) `perm:"admin"` BlockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` UnblockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` - ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"admin"` + ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"read"` Protect func(ctx context.Context, id peer.ID, tag string) error `perm:"admin"` Unprotect func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` - IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` + IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"read"` BandwidthStats func(context.Context) (metrics.Stats, error) `perm:"admin"` BandwidthForPeer func(ctx context.Context, id peer.ID) (metrics.Stats, error) `perm:"admin"` BandwidthForProtocol func(ctx context.Context, proto protocol.ID) (metrics.Stats, error) `perm:"admin"` ResourceState func(context.Context) (rcmgr.ResourceManagerStat, error) `perm:"admin"` - PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"admin"` + PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"read"` } } From 389fa41da4cde64254613435ccda11c190fc415f Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 11:07:56 +0300 Subject: [PATCH 02/11] change permission for peers --- nodebuilder/p2p/p2p.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodebuilder/p2p/p2p.go b/nodebuilder/p2p/p2p.go index 6a1d256250..c0793b55f0 100644 --- a/nodebuilder/p2p/p2p.go +++ b/nodebuilder/p2p/p2p.go @@ -195,7 +195,7 @@ func (m *module) PubSubPeers(_ context.Context, topic string) ([]peer.ID, error) type API struct { Internal struct { Info func(context.Context) (peer.AddrInfo, error) `perm:"public"` - Peers func(context.Context) ([]peer.ID, error) `perm:"read"` + Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` From b1ebd187749353c9f43341d521e06d9e5c2c0c5a Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Thu, 31 Aug 2023 11:09:13 +0300 Subject: [PATCH 03/11] apply suggestions Co-authored-by: Ryan --- cmd/celestia/p2p.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go index 79a0aa90fe..8c053f8449 100644 --- a/cmd/celestia/p2p.go +++ b/cmd/celestia/p2p.go @@ -43,7 +43,7 @@ var p2pCmd = &cobra.Command{ var infoCmd = &cobra.Command{ Use: "info", - Short: "Allows to get the node's Peer Info", + Short: "Gets the node's peer info (peer id and multiaddresses)", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -77,7 +77,7 @@ var infoCmd = &cobra.Command{ var peersCmd = &cobra.Command{ Use: "peers", - Short: "Allows to get the list of peers we are connected to", + Short: "Lists the peers we are connected to", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -110,7 +110,7 @@ var peersCmd = &cobra.Command{ var peerInfoCmd = &cobra.Command{ Use: "peer-info [param]", - Short: "Allows to get a PeerInfo struct for a given peer", + Short: "Gets PeerInfo for a given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -147,7 +147,7 @@ var peerInfoCmd = &cobra.Command{ var connectCmd = &cobra.Command{ Use: "connect [peer.ID, address]", - Short: "Allows to establish a connection with the given peer", + Short: "Establishes a connection with the given peer", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -181,7 +181,7 @@ var connectCmd = &cobra.Command{ var closePeerCmd = &cobra.Command{ Use: "close-peer [peer.ID]", - Short: "Allows to close the connection with the given peer", + Short: "Closes the connection with the given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -205,7 +205,7 @@ var closePeerCmd = &cobra.Command{ var connectednessCmd = &cobra.Command{ Use: "connectedness [peer.ID]", - Short: "Allows to check the connection state between current and given peers", + Short: "Checks the connection state between current and given peers", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -236,7 +236,7 @@ var connectednessCmd = &cobra.Command{ var natStatusCmd = &cobra.Command{ Use: "nat-status", - Short: "Allows to check the current NAT status", + Short: "Gets the currrent NAT status", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -262,7 +262,7 @@ var natStatusCmd = &cobra.Command{ var blockPeerCmd = &cobra.Command{ Use: "block-peer [peer.ID]", - Short: "Allows to block a given peer", + Short: "Blocks the given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -301,7 +301,7 @@ var blockPeerCmd = &cobra.Command{ var unblockPeerCmd = &cobra.Command{ Use: "unblock-peer [peer.ID]", - Short: "Allows to unblock a given peer", + Short: "Unblocks the given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -341,7 +341,7 @@ var unblockPeerCmd = &cobra.Command{ var blockedPeersCmd = &cobra.Command{ Use: "blocked-peers", - Short: "Allows to get a list of the blocked peers", + Short: "Lists the node's blocked peers", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -372,7 +372,7 @@ var blockedPeersCmd = &cobra.Command{ var protectCmd = &cobra.Command{ Use: "protect [peer.ID, tag]", - Short: "Allows to protect a given peer from being pruned by the given tag", + Short: "Protects the given peer from being pruned by the given tag", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -480,7 +480,7 @@ type bandwidthStats struct { var bandwidthStatsCmd = &cobra.Command{ Use: "bandwidth-stats", - Short: "Allows to get stats struct with bandwidth metrics for all data sent/" + + Short: "Get stats struct with bandwidth metrics for all data sent/" + "received by the local peer, regardless of protocol or remote peer IDs", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { @@ -508,7 +508,7 @@ var bandwidthStatsCmd = &cobra.Command{ var peerBandwidthCmd = &cobra.Command{ Use: "peer-bandwidth [peer.ID]", - Short: "Allows to get stats struct with bandwidth metrics associated with the given peer.ID", + Short: "Gets stats struct with bandwidth metrics associated with the given peer.ID", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -540,7 +540,7 @@ var peerBandwidthCmd = &cobra.Command{ var bandwidthForProtocolCmd = &cobra.Command{ Use: "protocol-bandwidth [protocol.ID]", - Short: "Allows to get stats struct with bandwidth metrics associated with the given peer.ID", + Short: "Gets stats struct with bandwidth metrics associated with the given protocol.ID", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) @@ -567,7 +567,7 @@ var bandwidthForProtocolCmd = &cobra.Command{ var pubsubPeersCmd = &cobra.Command{ Use: "pubsub-peers [topic]", - Short: "Allows to get a list of peers we are connected to in the given topic", + Short: "Lists the peers we are connected to in the given topic", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpcClient(cmd.Context()) From a0e21a9efd077d270cf2eac4242e19398d0c4ec3 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Thu, 31 Aug 2023 15:58:21 +0300 Subject: [PATCH 04/11] apply suggestions Co-authored-by: rene <41963722+renaynay@users.noreply.github.com> --- cmd/celestia/p2p.go | 2 +- cmd/celestia/rpc.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go index 8c053f8449..af403589d7 100644 --- a/cmd/celestia/p2p.go +++ b/cmd/celestia/p2p.go @@ -37,7 +37,7 @@ func init() { var p2pCmd = &cobra.Command{ Use: "p2p [command]", - Short: "Allows to interact with the P2P Module via JSON-RPC", + Short: "Allows interaction with the P2P Module via JSON-RPC", Args: cobra.NoArgs, } diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index d3ccf0823a..c7ac538bc2 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -63,7 +63,6 @@ func init() { rpcCmd.AddCommand(blobCmd) rpcCmd.AddCommand(p2pCmd) rootCmd.AddCommand(rpcCmd) - } var rpcCmd = &cobra.Command{ From 6c4b334c9794f2529f95200708ba96d4acada19f Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 16:34:01 +0300 Subject: [PATCH 05/11] fix permissions --- nodebuilder/p2p/p2p.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nodebuilder/p2p/p2p.go b/nodebuilder/p2p/p2p.go index c0793b55f0..a418eaf4d8 100644 --- a/nodebuilder/p2p/p2p.go +++ b/nodebuilder/p2p/p2p.go @@ -194,24 +194,24 @@ func (m *module) PubSubPeers(_ context.Context, topic string) ([]peer.ID, error) //nolint:dupl type API struct { Internal struct { - Info func(context.Context) (peer.AddrInfo, error) `perm:"public"` + Info func(context.Context) (peer.AddrInfo, error) `perm:"admin"` Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` - Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"read"` + Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"admin"` NATStatus func(context.Context) (network.Reachability, error) `perm:"admin"` BlockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` UnblockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` - ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"read"` + ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"admin"` Protect func(ctx context.Context, id peer.ID, tag string) error `perm:"admin"` Unprotect func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` - IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"read"` + IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` BandwidthStats func(context.Context) (metrics.Stats, error) `perm:"admin"` BandwidthForPeer func(ctx context.Context, id peer.ID) (metrics.Stats, error) `perm:"admin"` BandwidthForProtocol func(ctx context.Context, proto protocol.ID) (metrics.Stats, error) `perm:"admin"` ResourceState func(context.Context) (rcmgr.ResourceManagerStat, error) `perm:"admin"` - PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"read"` + PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"admin"` } } From 88e8e70da5acd267cfbdd0d36c13bd2fa76aa056 Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 16:45:26 +0300 Subject: [PATCH 06/11] rework printOutput --- cmd/celestia/p2p.go | 33 +++++++++------------------------ cmd/celestia/rpc.go | 8 ++++---- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go index af403589d7..ade2ba5627 100644 --- a/cmd/celestia/p2p.go +++ b/cmd/celestia/p2p.go @@ -54,11 +54,7 @@ var infoCmd = &cobra.Command{ info, err := client.P2P.Info(cmd.Context()) formatter := func(data interface{}) interface{} { - peerAdd, ok := data.(peer.AddrInfo) - if !ok { - return peerAdd - } - + peerAdd := data.(peer.AddrInfo) ma := make([]string, len(info.Addrs)) for i := range peerAdd.Addrs { ma[i] = peerAdd.Addrs[i].String() @@ -92,10 +88,7 @@ var peersCmd = &cobra.Command{ } formatter := func(data interface{}) interface{} { - conPeers, ok := data.([]string) - if !ok { - return conPeers - } + conPeers := data.([]string) return struct { Peers []string `json:"peers"` }{ @@ -124,11 +117,7 @@ var peerInfoCmd = &cobra.Command{ } info, err := client.P2P.PeerInfo(cmd.Context(), pid) formatter := func(data interface{}) interface{} { - peerAdd, ok := data.(peer.AddrInfo) - if !ok { - return peerAdd - } - + peerAdd := data.(peer.AddrInfo) ma := make([]string, len(info.Addrs)) for i := range peerAdd.Addrs { ma[i] = peerAdd.Addrs[i].String() @@ -294,7 +283,7 @@ var blockPeerCmd = &cobra.Command{ } } - printOutput(nil, err, formatter) + printOutput(err, nil, formatter) return nil }, } @@ -334,7 +323,7 @@ var unblockPeerCmd = &cobra.Command{ } } - printOutput(nil, err, formatter) + printOutput(err, nil, formatter) return nil }, } @@ -404,7 +393,7 @@ var protectCmd = &cobra.Command{ } } - printOutput(nil, err, formatter) + printOutput(err, nil, formatter) return nil }, } @@ -425,7 +414,7 @@ var unprotectCmd = &cobra.Command{ return err } - result, err := client.P2P.Unprotect(cmd.Context(), pid, args[1]) + _, err = client.P2P.Unprotect(cmd.Context(), pid, args[1]) formatter := func(data interface{}) interface{} { err, ok := data.(error) @@ -444,7 +433,7 @@ var unprotectCmd = &cobra.Command{ } } - printOutput(result, err, formatter) + printOutput(err, nil, formatter) return nil }, } @@ -575,7 +564,6 @@ var pubsubPeersCmd = &cobra.Command{ return err } - //TODO: check result, err := client.P2P.PubSubPeers(cmd.Context(), args[0]) peers := make([]string, len(result)) @@ -584,10 +572,7 @@ var pubsubPeersCmd = &cobra.Command{ } formatter := func(data interface{}) interface{} { - conPeers, ok := data.([]string) - if !ok { - return data - } + conPeers := data.([]string) return struct { Peers []string `json:"peers"` }{ diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index c7ac538bc2..049a5771e5 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -404,10 +404,10 @@ func rpcClient(ctx context.Context) (*client.Client, error) { func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) { if err != nil { data = err - } - - if formatData != nil { - data = formatData(data) + } else { + if formatData != nil { + data = formatData(data) + } } resp := struct { From 0dbf95affe7b0325f7f926b4daea03d6353d5d1a Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 16:48:23 +0300 Subject: [PATCH 07/11] update formatter in blob cmd --- cmd/celestia/blob.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cmd/celestia/blob.go b/cmd/celestia/blob.go index 34868ef112..7827c8a49c 100644 --- a/cmd/celestia/blob.go +++ b/cmd/celestia/blob.go @@ -182,11 +182,7 @@ func formatData(data interface{}) interface{} { } if reflect.TypeOf(data).Kind() == reflect.Slice { - blobs, ok := data.([]*blob.Blob) - if !ok { - return data - } - + blobs := data.([]*blob.Blob) result := make([]tempBlob, len(blobs)) for i, b := range blobs { result[i] = tempBlob{ @@ -199,10 +195,7 @@ func formatData(data interface{}) interface{} { return result } - b, ok := data.(*blob.Blob) - if !ok { - return data - } + b := data.(*blob.Blob) return tempBlob{ Namespace: b.Namespace(), Data: string(b.Data), From 07f429636de01daf5c3ad6740797301acce0a3fd Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 16:56:32 +0300 Subject: [PATCH 08/11] add switch --- cmd/celestia/rpc.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 049a5771e5..28c3379e17 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -402,12 +402,13 @@ func rpcClient(ctx context.Context) (*client.Client, error) { } func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) { - if err != nil { - data = err - } else { + switch err { + case nil: if formatData != nil { data = formatData(data) } + default: + data = err } resp := struct { From 31ee741f38c3fe4800e96dc2d0463cb5aa9b029e Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Thu, 31 Aug 2023 17:03:28 +0300 Subject: [PATCH 09/11] rework switch --- cmd/celestia/rpc.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 28c3379e17..11e187bc1d 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -402,13 +402,11 @@ func rpcClient(ctx context.Context) (*client.Client, error) { } func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) { - switch err { - case nil: - if formatData != nil { - data = formatData(data) - } - default: + switch { + case err != nil: data = err + case formatData != nil: + data = formatData(data) } resp := struct { From 6991d2d516fcee66ea9ddc613f299e09de124a63 Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Mon, 4 Sep 2023 14:03:45 +0300 Subject: [PATCH 10/11] rework error handling in printOutput --- cmd/celestia/blob.go | 16 +++------ cmd/celestia/p2p.go | 66 ++++++++++--------------------------- cmd/celestia/rpc.go | 6 ++-- share/eds/retriever.go | 1 - share/eds/retriever_test.go | 4 +++ 5 files changed, 28 insertions(+), 65 deletions(-) diff --git a/cmd/celestia/blob.go b/cmd/celestia/blob.go index 7827c8a49c..3325dbb07f 100644 --- a/cmd/celestia/blob.go +++ b/cmd/celestia/blob.go @@ -68,9 +68,7 @@ var getCmd = &cobra.Command{ if base64Flag || err != nil { formatter = nil } - - printOutput(blob, err, formatter) - return nil + return printOutput(blob, err, formatter) }, } @@ -100,9 +98,7 @@ var getAllCmd = &cobra.Command{ if base64Flag || err != nil { formatter = nil } - - printOutput(blobs, err, formatter) - return nil + return printOutput(blobs, err, formatter) }, } @@ -135,9 +131,7 @@ var submitCmd = &cobra.Command{ Height: height, Commitment: parsedBlob.Commitment, } - - printOutput(response, err, nil) - return nil + return printOutput(response, err, nil) }, } @@ -167,9 +161,7 @@ var getProofCmd = &cobra.Command{ } proof, err := client.Blob.GetProof(cmd.Context(), height, namespace, commitment) - - printOutput(proof, err, nil) - return nil + return printOutput(proof, err, nil) }, } diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go index ade2ba5627..d0b6549f6c 100644 --- a/cmd/celestia/p2p.go +++ b/cmd/celestia/p2p.go @@ -65,9 +65,7 @@ var infoCmd = &cobra.Command{ PeerAddr: ma, } } - - printOutput(info, err, formatter) - return nil + return printOutput(info, err, formatter) }, } @@ -95,9 +93,7 @@ var peersCmd = &cobra.Command{ Peers: conPeers, } } - - printOutput(peers, err, formatter) - return nil + return printOutput(peers, err, formatter) }, } @@ -128,9 +124,7 @@ var peerInfoCmd = &cobra.Command{ PeerAddr: ma, } } - - printOutput(info, err, formatter) - return nil + return printOutput(info, err, formatter) }, } @@ -161,8 +155,7 @@ var connectCmd = &cobra.Command{ err = client.P2P.Connect(cmd.Context(), peerInfo) if err != nil { - printOutput(nil, err, nil) - return nil + return printOutput(nil, err, nil) } return connectednessCmd.RunE(cmd, args) }, @@ -185,8 +178,7 @@ var closePeerCmd = &cobra.Command{ err = client.P2P.ClosePeer(cmd.Context(), pid) if err != nil { - printOutput(nil, err, nil) - return nil + return printOutput(nil, err, nil) } return connectednessCmd.RunE(cmd, args) }, @@ -217,9 +209,7 @@ var connectednessCmd = &cobra.Command{ ConnectionState: conn.String(), } } - - printOutput(con, err, formatter) - return nil + return printOutput(con, err, formatter) }, } @@ -243,9 +233,7 @@ var natStatusCmd = &cobra.Command{ Reachability: rr.String(), } } - - printOutput(r, err, formatter) - return nil + return printOutput(r, err, formatter) }, } @@ -282,9 +270,7 @@ var blockPeerCmd = &cobra.Command{ Reason: err, } } - - printOutput(err, nil, formatter) - return nil + return printOutput(err, nil, formatter) }, } @@ -322,9 +308,7 @@ var unblockPeerCmd = &cobra.Command{ Reason: err, } } - - printOutput(err, nil, formatter) - return nil + return printOutput(err, nil, formatter) }, } @@ -353,9 +337,7 @@ var blockedPeersCmd = &cobra.Command{ Peers: peers, } } - - printOutput(pids, err, formatter) - return nil + return printOutput(pids, err, formatter) }, } @@ -392,9 +374,7 @@ var protectCmd = &cobra.Command{ Reason: err, } } - - printOutput(err, nil, formatter) - return nil + return printOutput(err, nil, formatter) }, } @@ -432,9 +412,7 @@ var unprotectCmd = &cobra.Command{ Reason: err, } } - - printOutput(err, nil, formatter) - return nil + return printOutput(err, nil, formatter) }, } @@ -454,9 +432,7 @@ var protectedCmd = &cobra.Command{ } result, err := client.P2P.IsProtected(cmd.Context(), pid, args[1]) - - printOutput(result, err, nil) - return nil + return printOutput(result, err, nil) }, } @@ -489,9 +465,7 @@ var bandwidthStatsCmd = &cobra.Command{ RateOut: stats.RateOut, } } - - printOutput(result, err, formatter) - return nil + return printOutput(result, err, formatter) }, } @@ -521,9 +495,7 @@ var peerBandwidthCmd = &cobra.Command{ RateOut: stats.RateOut, } } - - printOutput(result, err, formatter) - return nil + return printOutput(result, err, formatter) }, } @@ -548,9 +520,7 @@ var bandwidthForProtocolCmd = &cobra.Command{ RateOut: stats.RateOut, } } - - printOutput(result, err, formatter) - return nil + return printOutput(result, err, formatter) }, } @@ -579,8 +549,6 @@ var pubsubPeersCmd = &cobra.Command{ Peers: conPeers, } } - - printOutput(peers, err, formatter) - return nil + return printOutput(peers, err, formatter) }, } diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 11e187bc1d..7e24e3c6ed 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -401,7 +401,7 @@ func rpcClient(ctx context.Context) (*client.Client, error) { return client, nil } -func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) { +func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) error { switch { case err != nil: data = err @@ -417,8 +417,8 @@ func printOutput(data interface{}, err error, formatData func(interface{}) inter bytes, err := json.MarshalIndent(resp, "", " ") if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) + return err } fmt.Fprintln(os.Stdout, string(bytes)) + return nil } diff --git a/share/eds/retriever.go b/share/eds/retriever.go index a870e07e22..56d2bc4e50 100644 --- a/share/eds/retriever.go +++ b/share/eds/retriever.go @@ -90,7 +90,6 @@ func (r *Retriever) Retrieve(ctx context.Context, dah *da.DataAvailabilityHeader span.RecordError(err) return nil, byzantine.NewErrByzantine(ctx, r.bServ, dah, errByz) } - log.Warnw("not enough shares to reconstruct data square, requesting more...", "err", err) case <-ctx.Done(): return nil, ctx.Err() diff --git a/share/eds/retriever_test.go b/share/eds/retriever_test.go index ebccf0e384..c81a327fe4 100644 --- a/share/eds/retriever_test.go +++ b/share/eds/retriever_test.go @@ -100,6 +100,10 @@ func TestRetriever_ByzantineError(t *testing.T) { _, err = r.Retrieve(ctx, &dah) var errByz *byzantine.ErrByzantine require.ErrorAs(t, err, &errByz) + + if errors.Is(err, errByz) { + t.Fatal("WTF") + } } // TestRetriever_MultipleRandQuadrants asserts that reconstruction succeeds From 50b344dbc52b1d3d812424c1dcef115cd79854ec Mon Sep 17 00:00:00 2001 From: Viacheslav Gonkivskyi Date: Mon, 4 Sep 2023 15:00:06 +0300 Subject: [PATCH 11/11] fix ooops --- share/eds/retriever.go | 1 + share/eds/retriever_test.go | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/share/eds/retriever.go b/share/eds/retriever.go index 56d2bc4e50..a870e07e22 100644 --- a/share/eds/retriever.go +++ b/share/eds/retriever.go @@ -90,6 +90,7 @@ func (r *Retriever) Retrieve(ctx context.Context, dah *da.DataAvailabilityHeader span.RecordError(err) return nil, byzantine.NewErrByzantine(ctx, r.bServ, dah, errByz) } + log.Warnw("not enough shares to reconstruct data square, requesting more...", "err", err) case <-ctx.Done(): return nil, ctx.Err() diff --git a/share/eds/retriever_test.go b/share/eds/retriever_test.go index c81a327fe4..ebccf0e384 100644 --- a/share/eds/retriever_test.go +++ b/share/eds/retriever_test.go @@ -100,10 +100,6 @@ func TestRetriever_ByzantineError(t *testing.T) { _, err = r.Retrieve(ctx, &dah) var errByz *byzantine.ErrByzantine require.ErrorAs(t, err, &errByz) - - if errors.Is(err, errByz) { - t.Fatal("WTF") - } } // TestRetriever_MultipleRandQuadrants asserts that reconstruction succeeds