From e6e840225c1b71d8dacf1150938364671bdb7858 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 4 Sep 2023 16:21:00 +0300 Subject: [PATCH 01/11] feat(cmd/rpc): add commands for the p2p module (#2599) --- cmd/celestia/blob.go | 58 ++--- cmd/celestia/p2p.go | 554 +++++++++++++++++++++++++++++++++++++++++++ cmd/celestia/rpc.go | 23 ++ 3 files changed, 591 insertions(+), 44 deletions(-) create mode 100644 cmd/celestia/p2p.go diff --git a/cmd/celestia/blob.go b/cmd/celestia/blob.go index 6d397525f5..9550f2c13a 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" @@ -85,8 +83,11 @@ var getCmd = &cobra.Command{ blob, err := client.Blob.Get(cmd.Context(), height, namespace, commitment) - printOutput(blob, err) - return nil + formatter := formatData + if base64Flag || err != nil { + formatter = nil + } + return printOutput(blob, err, formatter) }, } @@ -112,8 +113,11 @@ var getAllCmd = &cobra.Command{ blobs, err := client.Blob.GetAll(cmd.Context(), height, []share.Namespace{namespace}) - printOutput(blobs, err) - return nil + formatter := formatData + if base64Flag || err != nil { + formatter = nil + } + return printOutput(blobs, err, formatter) }, } @@ -150,9 +154,7 @@ var submitCmd = &cobra.Command{ Height: height, Commitment: parsedBlob.Commitment, } - - printOutput(response, err) - return nil + return printOutput(response, err, nil) }, } @@ -182,35 +184,10 @@ var getProofCmd = &cobra.Command{ } proof, err := client.Blob.GetProof(cmd.Context(), height, namespace, commitment) - - printOutput(proof, err) - return nil + return printOutput(proof, err, 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"` @@ -220,11 +197,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{ @@ -237,10 +210,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), diff --git a/cmd/celestia/p2p.go b/cmd/celestia/p2p.go new file mode 100644 index 0000000000..d0b6549f6c --- /dev/null +++ b/cmd/celestia/p2p.go @@ -0,0 +1,554 @@ +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 interaction with the P2P Module via JSON-RPC", + Args: cobra.NoArgs, +} + +var infoCmd = &cobra.Command{ + Use: "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()) + if err != nil { + return err + } + + info, err := client.P2P.Info(cmd.Context()) + + formatter := func(data interface{}) interface{} { + peerAdd := data.(peer.AddrInfo) + 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, + } + } + return printOutput(info, err, formatter) + }, +} + +var peersCmd = &cobra.Command{ + Use: "peers", + Short: "Lists the 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 := data.([]string) + return struct { + Peers []string `json:"peers"` + }{ + Peers: conPeers, + } + } + return printOutput(peers, err, formatter) + }, +} + +var peerInfoCmd = &cobra.Command{ + Use: "peer-info [param]", + Short: "Gets PeerInfo 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 := data.(peer.AddrInfo) + 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, + } + } + return printOutput(info, err, formatter) + }, +} + +var connectCmd = &cobra.Command{ + Use: "connect [peer.ID, address]", + 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()) + 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 { + return printOutput(nil, err, nil) + } + return connectednessCmd.RunE(cmd, args) + }, +} + +var closePeerCmd = &cobra.Command{ + Use: "close-peer [peer.ID]", + 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()) + 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 { + return printOutput(nil, err, nil) + } + return connectednessCmd.RunE(cmd, args) + }, +} + +var connectednessCmd = &cobra.Command{ + Use: "connectedness [peer.ID]", + 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()) + 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(), + } + } + return printOutput(con, err, formatter) + }, +} + +var natStatusCmd = &cobra.Command{ + Use: "nat-status", + Short: "Gets the currrent 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(), + } + } + return printOutput(r, err, formatter) + }, +} + +var blockPeerCmd = &cobra.Command{ + Use: "block-peer [peer.ID]", + Short: "Blocks 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.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, + } + } + return printOutput(err, nil, formatter) + }, +} + +var unblockPeerCmd = &cobra.Command{ + Use: "unblock-peer [peer.ID]", + Short: "Unblocks 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.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, + } + } + return printOutput(err, nil, formatter) + }, +} + +var blockedPeersCmd = &cobra.Command{ + Use: "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()) + 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, + } + } + return printOutput(pids, err, formatter) + }, +} + +var protectCmd = &cobra.Command{ + Use: "protect [peer.ID, 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()) + 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, + } + } + return printOutput(err, nil, formatter) + }, +} + +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 + } + + _, 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, + } + } + return printOutput(err, nil, formatter) + }, +} + +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]) + return printOutput(result, err, 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: "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, + } + } + return printOutput(result, err, formatter) + }, +} + +var peerBandwidthCmd = &cobra.Command{ + Use: "peer-bandwidth [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()) + 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, + } + } + return printOutput(result, err, formatter) + }, +} + +var bandwidthForProtocolCmd = &cobra.Command{ + Use: "protocol-bandwidth [protocol.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()) + 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, + } + } + return printOutput(result, err, formatter) + }, +} + +var pubsubPeersCmd = &cobra.Command{ + Use: "pubsub-peers [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()) + if err != nil { + return err + } + + 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 := data.([]string) + return struct { + Peers []string `json:"peers"` + }{ + Peers: conPeers, + } + } + return printOutput(peers, err, formatter) + }, +} diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index c263496b26..cc5ca059f7 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -62,6 +62,7 @@ func init() { ) rpcCmd.AddCommand(logCmd, logModuleCmd) rpcCmd.AddCommand(blobCmd) + rpcCmd.AddCommand(p2pCmd) rootCmd.AddCommand(rpcCmd) } @@ -400,3 +401,25 @@ func rpcClient(ctx context.Context) (*client.Client, error) { } return client, nil } + +func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) error { + switch { + case err != nil: + data = err + case formatData != nil: + data = formatData(data) + } + + resp := struct { + Result interface{} `json:"result"` + }{ + Result: data, + } + + bytes, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return err + } + fmt.Fprintln(os.Stdout, string(bytes)) + return nil +} From ae7a1d813c824d1725b888d7ca4bc7264dfe13f6 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Tue, 5 Sep 2023 12:49:38 +0300 Subject: [PATCH 02/11] feat(rpc): add daser cmd (#2651) --- cmd/celestia/das.go | 27 +++++++++++++++++++++++++++ cmd/celestia/rpc.go | 1 + 2 files changed, 28 insertions(+) create mode 100644 cmd/celestia/das.go diff --git a/cmd/celestia/das.go b/cmd/celestia/das.go new file mode 100644 index 0000000000..58c4a8362b --- /dev/null +++ b/cmd/celestia/das.go @@ -0,0 +1,27 @@ +package main + +import "github.com/spf13/cobra" + +func init() { + dasCmd.AddCommand(samplingStatsCmd) +} + +var dasCmd = &cobra.Command{ + Use: "das [command]", + Short: "Allows to interact with the Daser via JSON-RPC", + Args: cobra.NoArgs, +} + +var samplingStatsCmd = &cobra.Command{ + Use: "sampling-stats", + Short: "Returns the current statistics over the DA sampling process", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + stats, err := client.DAS.SamplingStats(cmd.Context()) + return printOutput(stats, err, nil) + }, +} diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index cc5ca059f7..c5d0a71343 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -63,6 +63,7 @@ func init() { rpcCmd.AddCommand(logCmd, logModuleCmd) rpcCmd.AddCommand(blobCmd) rpcCmd.AddCommand(p2pCmd) + rpcCmd.AddCommand(dasCmd) rootCmd.AddCommand(rpcCmd) } From c89ada18e986f7c9d16f2d65d817c428e870de5d Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Wed, 6 Sep 2023 16:19:53 +0300 Subject: [PATCH 03/11] cmd(rpc): add header cmd (#2658) --- cmd/celestia/header.go | 109 +++++++++++++++++++++++++++++++++++++++++ cmd/celestia/rpc.go | 1 + 2 files changed, 110 insertions(+) create mode 100644 cmd/celestia/header.go diff --git a/cmd/celestia/header.go b/cmd/celestia/header.go new file mode 100644 index 0000000000..1d8dc6d01b --- /dev/null +++ b/cmd/celestia/header.go @@ -0,0 +1,109 @@ +package main + +import ( + "encoding/hex" + "fmt" + "strconv" + + "github.com/spf13/cobra" +) + +func init() { + headerCmd.AddCommand( + localHeadCmd, + networkHeadCmd, + getByHashCmd, + getByHeightCmd, + syncStateCmd, + ) +} + +var headerCmd = &cobra.Command{ + Use: "header [command]", + Short: "Allows interaction with the Header Module via JSON-RPC", + Args: cobra.NoArgs, +} + +var localHeadCmd = &cobra.Command{ + Use: "local-head", + Short: "Returns the ExtendedHeader from the chain head.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + header, err := client.Header.LocalHead(cmd.Context()) + return printOutput(header, err, nil) + }, +} + +var networkHeadCmd = &cobra.Command{ + Use: "network-head", + Short: "Provides the Syncer's view of the current network head.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + header, err := client.Header.NetworkHead(cmd.Context()) + return printOutput(header, err, nil) + }, +} + +var getByHashCmd = &cobra.Command{ + Use: "get-by-hash", + Short: "Returns the header of the given hash from the node's header store.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + hash, err := hex.DecodeString(args[0]) + if err != nil { + return fmt.Errorf("error decoding a hash: expected a hex encoded string:%v", err) + } + header, err := client.Header.GetByHash(cmd.Context(), hash) + return printOutput(header, err, nil) + }, +} + +var getByHeightCmd = &cobra.Command{ + Use: "get-by-height", + Short: "Returns the ExtendedHeader at the given height if it is currently available.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + height, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a height:%v", err) + } + + header, err := client.Header.GetByHeight(cmd.Context(), height) + return printOutput(header, err, nil) + }, +} + +var syncStateCmd = &cobra.Command{ + Use: "sync-state", + Short: "Returns the current state of the header Syncer.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + header, err := client.Header.SyncState(cmd.Context()) + return printOutput(header, err, nil) + }, +} diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index c5d0a71343..4425aa9ae5 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -64,6 +64,7 @@ func init() { rpcCmd.AddCommand(blobCmd) rpcCmd.AddCommand(p2pCmd) rpcCmd.AddCommand(dasCmd) + rpcCmd.AddCommand(headerCmd) rootCmd.AddCommand(rpcCmd) } From e21654401bbb80a9a8d672f84e74b414f4474d8c Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Wed, 13 Sep 2023 12:24:32 +0300 Subject: [PATCH 04/11] feat(rpc): add share cmd (#2664) --- cmd/celestia/rpc.go | 1 + cmd/celestia/share.go | 196 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 cmd/celestia/share.go diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 4425aa9ae5..1516211c3e 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -65,6 +65,7 @@ func init() { rpcCmd.AddCommand(p2pCmd) rpcCmd.AddCommand(dasCmd) rpcCmd.AddCommand(headerCmd) + rpcCmd.AddCommand(shareCmd) rootCmd.AddCommand(rpcCmd) } diff --git a/cmd/celestia/share.go b/cmd/celestia/share.go new file mode 100644 index 0000000000..2f84871d80 --- /dev/null +++ b/cmd/celestia/share.go @@ -0,0 +1,196 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "strconv" + + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-app/pkg/da" + + "github.com/celestiaorg/celestia-node/share" +) + +func init() { + shareCmd.AddCommand( + sharesAvailableCmd, + probabilityOfAvailabilityCmd, + getSharesByNamespaceCmd, + getShare, + getEDS, + ) +} + +var shareCmd = &cobra.Command{ + Use: "share [command]", + Short: "Allows interaction with the Share Module via JSON-RPC", + Args: cobra.NoArgs, +} + +var sharesAvailableCmd = &cobra.Command{ + Use: "available", + Short: "Subjectively validates if Shares committed to the given Root are available on the Network.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + raw, err := parseJSON(args[0]) + if err != nil { + return err + } + + root := da.MinDataAvailabilityHeader() + err = json.Unmarshal(raw, &root) + if err != nil { + return err + } + + err = client.Share.SharesAvailable(cmd.Context(), &root) + formatter := func(data interface{}) interface{} { + err, ok := data.(error) + available := false + if !ok { + available = true + } + return struct { + Available bool `json:"available"` + Hash []byte `json:"dah_hash"` + Reason error `json:"reason,omitempty"` + }{ + Available: available, + Hash: []byte(args[0]), + Reason: err, + } + } + return printOutput(err, nil, formatter) + }, +} + +var probabilityOfAvailabilityCmd = &cobra.Command{ + Use: "availability", + Short: "Calculates the probability of the data square being available based on the number of samples collected.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + prob := client.Share.ProbabilityOfAvailability(cmd.Context()) + return printOutput(prob, nil, nil) + }, +} + +var getSharesByNamespaceCmd = &cobra.Command{ + Use: "get-by-namespace [dah, namespace]", + Short: "Gets all shares from an EDS within the given namespace.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + raw, err := parseJSON(args[0]) + if err != nil { + return err + } + + root := da.MinDataAvailabilityHeader() + err = json.Unmarshal(raw, &root) + if err != nil { + return err + } + + ns, err := parseV0Namespace(args[1]) + if err != nil { + return err + } + + shares, err := client.Share.GetSharesByNamespace(cmd.Context(), &root, ns) + return printOutput(shares, err, nil) + }, +} + +var getShare = &cobra.Command{ + Use: "get-share [dah, row, col]", + Short: "Gets a Share by coordinates in EDS.", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + raw, err := parseJSON(args[0]) + if err != nil { + return err + } + + root := da.MinDataAvailabilityHeader() + err = json.Unmarshal(raw, &root) + if err != nil { + return err + } + + row, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + + col, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return err + } + + s, err := client.Share.GetShare(cmd.Context(), &root, int(row), int(col)) + + formatter := func(data interface{}) interface{} { + sh, ok := data.(share.Share) + if !ok { + return data + } + + ns := hex.EncodeToString(share.GetNamespace(sh)) + + return struct { + Namespace string `json:"namespace"` + Data []byte `json:"data"` + }{ + Namespace: ns, + Data: share.GetData(sh), + } + } + return printOutput(s, err, formatter) + }, +} + +var getEDS = &cobra.Command{ + Use: "get-eds [dah]", + Short: "Gets the full EDS identified by the given root", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + raw, err := parseJSON(args[0]) + if err != nil { + return err + } + + root := da.MinDataAvailabilityHeader() + err = json.Unmarshal(raw, &root) + if err != nil { + return err + } + + shares, err := client.Share.GetEDS(cmd.Context(), &root) + return printOutput(shares, err, nil) + }, +} From c38fcb7e8453c79280e6267e29454a03c9fa02de Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Fri, 15 Sep 2023 13:40:54 +0300 Subject: [PATCH 05/11] feat(rpc): add admin cmd (#2701) --- cmd/celestia/admin.go | 108 ++++++++++++++++++++++++++++++++++++++++++ cmd/celestia/logs.go | 48 ------------------- cmd/celestia/rpc.go | 3 +- 3 files changed, 109 insertions(+), 50 deletions(-) create mode 100644 cmd/celestia/admin.go delete mode 100644 cmd/celestia/logs.go diff --git a/cmd/celestia/admin.go b/cmd/celestia/admin.go new file mode 100644 index 0000000000..a3665e0aa1 --- /dev/null +++ b/cmd/celestia/admin.go @@ -0,0 +1,108 @@ +package main + +import ( + "context" + "errors" + "strings" + + "github.com/filecoin-project/go-jsonrpc/auth" + "github.com/spf13/cobra" +) + +func init() { + nodeCmd.AddCommand(nodeInfoCmd, logCmd, verifyCmd, authCmd) + rootCmd.AddCommand(nodeCmd) +} + +var nodeCmd = &cobra.Command{ + Use: "node [command]", + Short: "Allows administrating running node.", + Args: cobra.NoArgs, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + rpcClient, err := newRPCClient(cmd.Context()) + if err != nil { + return err + } + + ctx := context.WithValue(cmd.Context(), rpcClientKey{}, rpcClient) + cmd.SetContext(ctx) + return nil + }, +} + +var nodeInfoCmd = &cobra.Command{ + Use: "info", + Args: cobra.NoArgs, + Short: "Returns administrative information about the node.", + RunE: func(c *cobra.Command, args []string) error { + client, err := rpcClient(c.Context()) + if err != nil { + return err + } + info, err := client.Node.Info(c.Context()) + return printOutput(info, err, nil) + }, +} + +var logCmd = &cobra.Command{ + Use: "log-level", + Args: cobra.MinimumNArgs(1), + Short: "Allows to set log level for module to in format :" + + "`DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL and their lower-case forms`.\n" + + "To set all modules to a particular level `*:` should be passed", + RunE: func(c *cobra.Command, args []string) error { + client, err := rpcClient(c.Context()) + if err != nil { + return err + } + + for _, ll := range args { + params := strings.Split(ll, ":") + if len(params) != 2 { + return errors.New("cmd: log-level arg must be in form :," + + "e.g. pubsub:debug") + } + + if err = client.Node.LogLevelSet(c.Context(), params[0], params[1]); err != nil { + return err + } + } + return nil + }, +} + +var verifyCmd = &cobra.Command{ + Use: "permissions", + Args: cobra.ExactArgs(1), + Short: "Returns the permissions assigned to the given token.", + + RunE: func(c *cobra.Command, args []string) error { + client, err := rpcClient(c.Context()) + if err != nil { + return err + } + + perms, err := client.Node.AuthVerify(c.Context(), args[0]) + return printOutput(perms, err, nil) + }, +} + +var authCmd = &cobra.Command{ + Use: "set-permissions", + Args: cobra.MinimumNArgs(1), + Short: "Signs and returns a new token with the given permissions.", + RunE: func(c *cobra.Command, args []string) error { + client, err := rpcClient(c.Context()) + if err != nil { + return err + } + + perms := make([]auth.Permission, len(args)) + for i, p := range args { + perms[i] = (auth.Permission)(p) + } + + result, err := client.Node.AuthNew(c.Context(), perms) + return printOutput(result, err, nil) + }, +} diff --git a/cmd/celestia/logs.go b/cmd/celestia/logs.go deleted file mode 100644 index ac302ff6dd..0000000000 --- a/cmd/celestia/logs.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - "github.com/celestiaorg/celestia-node/cmd" -) - -var logCmd = &cobra.Command{ - Use: cmd.LogLevelFlag, - Args: cobra.ExactArgs(1), - Short: "Allows to set log level for all modules to " + - "`DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL and their lower-case forms`", - - RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) - if err != nil { - return err - } - return client.Node.LogLevelSet(c.Context(), "*", args[0]) - }, -} - -var logModuleCmd = &cobra.Command{ - Use: cmd.LogLevelModuleFlag, - Args: cobra.MinimumNArgs(1), - Short: "Allows to set log level for a particular module in format :", - RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) - if err != nil { - return err - } - for _, ll := range args { - params := strings.Split(ll, ":") - if len(params) != 2 { - return fmt.Errorf("cmd: %s arg must be in form :,"+ - "e.g. pubsub:debug", cmd.LogLevelModuleFlag) - } - if err = client.Node.LogLevelSet(c.Context(), params[0], params[1]); err != nil { - return err - } - } - return nil - }, -} diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 1516211c3e..a0dea6e0dd 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -23,7 +23,7 @@ import ( "github.com/celestiaorg/celestia-node/state" ) -const authEnvKey = "CELESTIA_NODE_AUTH_TOKEN" //nolint:gosec +const authEnvKey = "CELESTIA_NODE_AUTH_TOKEN" var requestURL string var authTokenFlag string @@ -60,7 +60,6 @@ func init() { false, "Print JSON-RPC request along with the response", ) - rpcCmd.AddCommand(logCmd, logModuleCmd) rpcCmd.AddCommand(blobCmd) rpcCmd.AddCommand(p2pCmd) rpcCmd.AddCommand(dasCmd) From cc02d71d9e10a2b747bdb6ea4796c6a0f87d4c4e Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Fri, 15 Sep 2023 13:46:41 +0300 Subject: [PATCH 06/11] feat(rpc): add state cmd (#2691) --- cmd/celestia/rpc.go | 1 + cmd/celestia/state.go | 424 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 425 insertions(+) create mode 100644 cmd/celestia/state.go diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index a0dea6e0dd..e7e3c0d5be 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -65,6 +65,7 @@ func init() { rpcCmd.AddCommand(dasCmd) rpcCmd.AddCommand(headerCmd) rpcCmd.AddCommand(shareCmd) + rpcCmd.AddCommand(stateCmd) rootCmd.AddCommand(rpcCmd) } diff --git a/cmd/celestia/state.go b/cmd/celestia/state.go new file mode 100644 index 0000000000..2f3d1e138a --- /dev/null +++ b/cmd/celestia/state.go @@ -0,0 +1,424 @@ +package main + +import ( + "fmt" + "strconv" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/blob" + "github.com/celestiaorg/celestia-node/state" +) + +func init() { + stateCmd.AddCommand( + accountAddressCmd, + balanceCmd, + balanceForAddressCmd, + transferCmd, + submitTxCmd, + submitPFBCmd, + cancelUnbondingDelegationCmd, + beginRedelegateCmd, + undelegateCmd, + delegateCmd, + queryDelegationCmd, + queryUnbondingCmd, + queryRedelegationCmd, + ) +} + +var stateCmd = &cobra.Command{ + Use: "state [command]", + Short: "Allows interaction with the State Module via JSON-RPC", + Args: cobra.NoArgs, +} + +var accountAddressCmd = &cobra.Command{ + Use: "account-address", + Short: "Retrieves the address of the node's account/signer.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + address, err := client.State.AccountAddress(cmd.Context()) + return printOutput(address, err, nil) + }, +} + +var balanceCmd = &cobra.Command{ + Use: "balance", + Short: "Retrieves the Celestia coin balance for the node's account/signer and verifies it against " + + "the corresponding block's AppHash.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + balance, err := client.State.Balance(cmd.Context()) + return printOutput(balance, err, nil) + }, +} + +var balanceForAddressCmd = &cobra.Command{ + Use: "balance-for-address [address]", + Short: "Retrieves the Celestia coin balance for the given address and verifies the returned balance against " + + "the corresponding block's AppHash.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + balance, err := client.State.BalanceForAddress(cmd.Context(), addr) + return printOutput(balance, err, nil) + }, +} + +var transferCmd = &cobra.Command{ + Use: "transfer [address] [amount] [fee] [gasLimit]", + Short: "Sends the given amount of coins from default wallet of the node to the given account address.", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + amount, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return fmt.Errorf("error parsing an amount:%v", err) + } + fee, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + gasLimit, err := strconv.ParseUint(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gas limit:%v", err) + } + + txResponse, err := client.State.Transfer( + cmd.Context(), + addr.Address.(state.AccAddress), + math.NewInt(amount), + math.NewInt(fee), gasLimit, + ) + return printOutput(txResponse, err, nil) + }, +} + +var submitTxCmd = &cobra.Command{ + Use: "submit-tx [tx]", + Short: "Submits the given transaction/message to the Celestia network and blocks until the tx is included in a block.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + rawTx, err := decodeToBytes(args[0]) + if err != nil { + return fmt.Errorf("failed to decode tx: %v", err) + } + txResponse, err := client.State.SubmitTx( + cmd.Context(), + rawTx, + ) + return printOutput(txResponse, err, nil) + }, +} + +var submitPFBCmd = &cobra.Command{ + Use: "submit-pfb [namespace] [data] [fee] [gasLim]", + Short: "Allows to submit PFBs", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + namespace, err := parseV0Namespace(args[0]) + if err != nil { + return fmt.Errorf("error parsing a namespace:%v", err) + } + + fee, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + + gasLimit, err := strconv.ParseUint(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gasLim:%v", err) + } + + parsedBlob, err := blob.NewBlobV0(namespace, []byte(args[1])) + if err != nil { + return fmt.Errorf("error creating a blob:%v", err) + } + + txResp, err := client.State.SubmitPayForBlob(cmd.Context(), types.NewInt(fee), gasLimit, []*blob.Blob{parsedBlob}) + return printOutput(txResp, err, nil) + }, +} + +var cancelUnbondingDelegationCmd = &cobra.Command{ + Use: "cancel-unbonding-delegation [address] [amount] [height] [fee] [gasLimit]", + Short: "Cancels a user's pending undelegation from a validator.", + Args: cobra.ExactArgs(5), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + amount, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return fmt.Errorf("error parsing an amount:%v", err) + } + + height, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + + fee, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + + gasLimit, err := strconv.ParseUint(args[4], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gas limit:%v", err) + } + + txResponse, err := client.State.CancelUnbondingDelegation( + cmd.Context(), + addr.Address.(state.ValAddress), + math.NewInt(amount), + math.NewInt(height), + math.NewInt(fee), + gasLimit, + ) + return printOutput(txResponse, err, nil) + }, +} + +var beginRedelegateCmd = &cobra.Command{ + Use: "begin-redelegate [srcAddress] [dstAddress] [amount] [fee] [gasLimit]", + Short: "Sends a user's delegated tokens to a new validator for redelegation", + Args: cobra.ExactArgs(5), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + srcAddr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + dstAddr, err := parseAddressFromString(args[1]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + amount, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing an amount:%v", err) + } + + fee, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + gasLimit, err := strconv.ParseUint(args[4], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gas limit:%v", err) + } + + txResponse, err := client.State.BeginRedelegate( + cmd.Context(), + srcAddr.Address.(state.ValAddress), + dstAddr.Address.(state.ValAddress), + math.NewInt(amount), + math.NewInt(fee), + gasLimit, + ) + return printOutput(txResponse, err, nil) + }, +} + +var undelegateCmd = &cobra.Command{ + Use: "undelegate [valAddress] [amount] [fee] [gasLimit]", + Short: "Undelegates a user's delegated tokens, unbonding them from the current validator.", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + amount, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return fmt.Errorf("error parsing an amount:%v", err) + } + fee, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + gasLimit, err := strconv.ParseUint(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gas limit:%v", err) + } + + txResponse, err := client.State.Undelegate( + cmd.Context(), + addr.Address.(state.ValAddress), + math.NewInt(amount), + math.NewInt(fee), + gasLimit, + ) + return printOutput(txResponse, err, nil) + }, +} + +var delegateCmd = &cobra.Command{ + Use: "delegate [valAddress] [amount] [fee] [gasLimit]", + Short: "Sends a user's liquid tokens to a validator for delegation.", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + amount, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return fmt.Errorf("error parsing an amount:%v", err) + } + + fee, err := strconv.ParseInt(args[2], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a fee:%v", err) + } + + gasLimit, err := strconv.ParseUint(args[3], 10, 64) + if err != nil { + return fmt.Errorf("error parsing a gas limit:%v", err) + } + + txResponse, err := client.State.Delegate( + cmd.Context(), + addr.Address.(state.ValAddress), + math.NewInt(amount), + math.NewInt(fee), + gasLimit, + ) + return printOutput(txResponse, err, nil) + }, +} + +var queryDelegationCmd = &cobra.Command{ + Use: "get-delegation [valAddress]", + Short: "Retrieves the delegation information between a delegator and a validator.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + balance, err := client.State.QueryDelegation(cmd.Context(), addr.Address.(state.ValAddress)) + fmt.Println(balance) + fmt.Println(err) + return printOutput(balance, err, nil) + }, +} + +var queryUnbondingCmd = &cobra.Command{ + Use: "get-unbonding [valAddress]", + Short: "Retrieves the unbonding status between a delegator and a validator.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + addr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing an address:%v", err) + } + + response, err := client.State.QueryUnbonding(cmd.Context(), addr.Address.(state.ValAddress)) + return printOutput(response, err, nil) + }, +} + +var queryRedelegationCmd = &cobra.Command{ + Use: "get-redelegations [srcAddress] [dstAddress]", + Short: "Retrieves the status of the redelegations between a delegator and a validator.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := rpcClient(cmd.Context()) + if err != nil { + return err + } + + srcAddr, err := parseAddressFromString(args[0]) + if err != nil { + return fmt.Errorf("error parsing a src address:%v", err) + } + + dstAddr, err := parseAddressFromString(args[1]) + if err != nil { + return fmt.Errorf("error parsing a dst address:%v", err) + } + + response, err := client.State.QueryRedelegations( + cmd.Context(), + srcAddr.Address.(state.ValAddress), + dstAddr.Address.(state.ValAddress), + ) + return printOutput(response, err, nil) + }, +} From 0d081eb134f4e8cc5ec2dbccc844e78bdced35e2 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 25 Sep 2023 13:43:00 +0300 Subject: [PATCH 07/11] refactor(cmd): extract rpc cmds (#2706) --- cmd/celestia/bridge.go | 2 +- cmd/celestia/cmd_test.go | 20 + cmd/celestia/das.go | 27 -- cmd/celestia/full.go | 2 +- cmd/celestia/light.go | 2 +- cmd/celestia/rpc.go | 452 ++---------------- cmd/celestia/util.go | 68 --- cmd/rpc.go | 58 +++ cmd/util.go | 127 +++++ cmd/{celestia/rpc_test.go => util_test.go} | 4 +- .../celestia => nodebuilder/blob/cmd}/blob.go | 52 +- nodebuilder/das/cmd/das.go | 34 ++ .../header/cmd}/header.go | 40 +- .../admin.go => nodebuilder/node/cmd/node.go | 55 +-- {cmd/celestia => nodebuilder/p2p/cmd}/p2p.go | 110 +++-- .../share/cmd}/share.go | 47 +- .../state/cmd}/state.go | 108 +++-- 17 files changed, 521 insertions(+), 687 deletions(-) delete mode 100644 cmd/celestia/das.go delete mode 100644 cmd/celestia/util.go create mode 100644 cmd/rpc.go create mode 100644 cmd/util.go rename cmd/{celestia/rpc_test.go => util_test.go} (97%) rename {cmd/celestia => nodebuilder/blob/cmd}/blob.go (77%) create mode 100644 nodebuilder/das/cmd/das.go rename {cmd/celestia => nodebuilder/header/cmd}/header.go (68%) rename cmd/celestia/admin.go => nodebuilder/node/cmd/node.go (61%) rename {cmd/celestia => nodebuilder/p2p/cmd}/p2p.go (79%) rename {cmd/celestia => nodebuilder/share/cmd}/share.go (76%) rename {cmd/celestia => nodebuilder/state/cmd}/state.go (80%) diff --git a/cmd/celestia/bridge.go b/cmd/celestia/bridge.go index fb5066e5d4..c0e2ab0d1a 100644 --- a/cmd/celestia/bridge.go +++ b/cmd/celestia/bridge.go @@ -42,6 +42,6 @@ var bridgeCmd = &cobra.Command{ Args: cobra.NoArgs, Short: "Manage your Bridge node", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - return persistentPreRunEnv(cmd, node.Bridge, args) + return cmdnode.PersistentPreRunEnv(cmd, node.Bridge, args) }, } diff --git a/cmd/celestia/cmd_test.go b/cmd/celestia/cmd_test.go index 503548b708..9c26489e14 100644 --- a/cmd/celestia/cmd_test.go +++ b/cmd/celestia/cmd_test.go @@ -128,3 +128,23 @@ func TestBridge(t *testing.T) { }) */ } + +func parseSignatureForHelpstring(methodSig reflect.StructField) string { + simplifiedSignature := "(" + in, out := methodSig.Type.NumIn(), methodSig.Type.NumOut() + for i := 1; i < in; i++ { + simplifiedSignature += methodSig.Type.In(i).String() + if i != in-1 { + simplifiedSignature += ", " + } + } + simplifiedSignature += ") -> (" + for i := 0; i < out-1; i++ { + simplifiedSignature += methodSig.Type.Out(i).String() + if i != out-2 { + simplifiedSignature += ", " + } + } + simplifiedSignature += ")" + return simplifiedSignature +} diff --git a/cmd/celestia/das.go b/cmd/celestia/das.go deleted file mode 100644 index 58c4a8362b..0000000000 --- a/cmd/celestia/das.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import "github.com/spf13/cobra" - -func init() { - dasCmd.AddCommand(samplingStatsCmd) -} - -var dasCmd = &cobra.Command{ - Use: "das [command]", - Short: "Allows to interact with the Daser via JSON-RPC", - Args: cobra.NoArgs, -} - -var samplingStatsCmd = &cobra.Command{ - Use: "sampling-stats", - Short: "Returns the current statistics over the DA sampling process", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) - if err != nil { - return err - } - stats, err := client.DAS.SamplingStats(cmd.Context()) - return printOutput(stats, err, nil) - }, -} diff --git a/cmd/celestia/full.go b/cmd/celestia/full.go index 912de0bca8..8baff1080e 100644 --- a/cmd/celestia/full.go +++ b/cmd/celestia/full.go @@ -46,6 +46,6 @@ var fullCmd = &cobra.Command{ Args: cobra.NoArgs, Short: "Manage your Full node", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - return persistentPreRunEnv(cmd, node.Full, args) + return cmdnode.PersistentPreRunEnv(cmd, node.Full, args) }, } diff --git a/cmd/celestia/light.go b/cmd/celestia/light.go index 9c63945445..553660c5d3 100644 --- a/cmd/celestia/light.go +++ b/cmd/celestia/light.go @@ -46,6 +46,6 @@ var lightCmd = &cobra.Command{ Args: cobra.NoArgs, Short: "Manage your Light node", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - return persistentPreRunEnv(cmd, node.Light, args) + return cmdnode.PersistentPreRunEnv(cmd, node.Light, args) }, } diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index e7e3c0d5be..8cf51fda09 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -1,428 +1,40 @@ package main import ( - "bytes" - "context" - "encoding/base64" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "net/http" - "os" - "reflect" - "strconv" - "strings" - - "github.com/spf13/cobra" - - "github.com/celestiaorg/celestia-node/api/rpc/client" - "github.com/celestiaorg/celestia-node/share" - "github.com/celestiaorg/celestia-node/state" + "github.com/celestiaorg/celestia-node/cmd" + blob "github.com/celestiaorg/celestia-node/nodebuilder/blob/cmd" + das "github.com/celestiaorg/celestia-node/nodebuilder/das/cmd" + header "github.com/celestiaorg/celestia-node/nodebuilder/header/cmd" + node "github.com/celestiaorg/celestia-node/nodebuilder/node/cmd" + p2p "github.com/celestiaorg/celestia-node/nodebuilder/p2p/cmd" + share "github.com/celestiaorg/celestia-node/nodebuilder/share/cmd" + state "github.com/celestiaorg/celestia-node/nodebuilder/state/cmd" ) -const authEnvKey = "CELESTIA_NODE_AUTH_TOKEN" - -var requestURL string -var authTokenFlag string -var printRequest bool - -type jsonRPCRequest struct { - ID int64 `json:"id"` - JSONRPC string `json:"jsonrpc"` - Method string `json:"method"` - Params []interface{} `json:"params"` -} - -type outputWithRequest struct { - Request jsonRPCRequest - Response json.RawMessage -} - func init() { - rpcCmd.PersistentFlags().StringVar( - &requestURL, - "url", - "http://localhost:26658", - "Request URL", - ) - rpcCmd.PersistentFlags().StringVar( - &authTokenFlag, - "auth", - "", - "Authorization token (if not provided, the "+authEnvKey+" environment variable will be used)", + blob.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + das.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + header.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + p2p.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + share.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + state.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + node.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) + + blob.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + das.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + header.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + p2p.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + share.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + state.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + node.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + + rootCmd.AddCommand( + blob.Cmd, + das.Cmd, + header.Cmd, + p2p.Cmd, + share.Cmd, + state.Cmd, + node.Cmd, ) - rpcCmd.PersistentFlags().BoolVar( - &printRequest, - "print-request", - false, - "Print JSON-RPC request along with the response", - ) - rpcCmd.AddCommand(blobCmd) - rpcCmd.AddCommand(p2pCmd) - rpcCmd.AddCommand(dasCmd) - rpcCmd.AddCommand(headerCmd) - rpcCmd.AddCommand(shareCmd) - rpcCmd.AddCommand(stateCmd) - rootCmd.AddCommand(rpcCmd) -} - -var rpcCmd = &cobra.Command{ - Use: "rpc [namespace] [method] [params...]", - Short: "Send JSON-RPC request", - Args: cobra.MinimumNArgs(2), - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - rpcClient, err := newRPCClient(cmd.Context()) - if err != nil { - return err - } - - ctx := context.WithValue(cmd.Context(), rpcClientKey{}, rpcClient) - cmd.SetContext(ctx) - return nil - }, - PersistentPostRunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) - if err != nil { - return err - } - - client.Close() - return nil - }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - modules := client.Modules - if len(args) == 0 { - // get keys from modules (map[string]interface{}) - var keys []string - for k := range modules { - keys = append(keys, k) - } - return keys, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - // get methods from module - module := modules[args[0]] - methods := reflect.VisibleFields(reflect.TypeOf(module).Elem()) - var methodNames []string - for _, m := range methods { - methodNames = append(methodNames, m.Name+"\t"+parseSignatureForHelpstring(m)) - } - return methodNames, cobra.ShellCompDirectiveNoFileComp - } - return nil, cobra.ShellCompDirectiveNoFileComp - }, - Run: func(cmd *cobra.Command, args []string) { - namespace := args[0] - method := args[1] - params := parseParams(method, args[2:]) - - sendJSONRPCRequest(namespace, method, params) - }, -} - -func parseParams(method string, params []string) []interface{} { - parsedParams := make([]interface{}, len(params)) - validateParamsFn := func(has, want int) error { - if has != want { - return fmt.Errorf("rpc: invalid amount of params. has=%d, want=%d", has, want) - } - return nil - } - switch method { - case "GetSharesByNamespace": - if err := validateParamsFn(len(params), 2); err != nil { - panic(err) - } - // 1. Share Root - root, err := parseJSON(params[0]) - if err != nil { - panic(fmt.Errorf("couldn't parse share root as json: %v", err)) - } - parsedParams[0] = root - // 2. Namespace - namespace, err := parseV0Namespace(params[1]) - if err != nil { - panic(fmt.Sprintf("Error parsing namespace: %v", err)) - } - parsedParams[1] = namespace - return parsedParams - case "QueryDelegation", "QueryUnbonding", "BalanceForAddress": - var err error - if err = validateParamsFn(len(params), 2); err != nil { - panic(err) - } - parsedParams[0], err = parseAddressFromString(params[0]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - return parsedParams - case "QueryRedelegations": - var err error - parsedParams[0], err = parseAddressFromString(params[0]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - parsedParams[1], err = parseAddressFromString(params[1]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - return parsedParams - case "Transfer", "Delegate", "Undelegate": - // 1. Address - var err error - if err = validateParamsFn(len(params), 4); err != nil { - panic(err) - } - parsedParams[0], err = parseAddressFromString(params[0]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - // 2. Amount + Fee - parsedParams[1] = params[1] - parsedParams[2] = params[2] - // 3. GasLimit (uint64) - num, err := strconv.ParseUint(params[3], 10, 64) - if err != nil { - panic("Error parsing gas limit: uint64 could not be parsed.") - } - parsedParams[3] = num - return parsedParams - case "CancelUnbondingDelegation": - // 1. Validator Address - var err error - if err = validateParamsFn(len(params), 5); err != nil { - panic(err) - } - parsedParams[0], err = parseAddressFromString(params[0]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - // 2. Amount + Height + Fee - parsedParams[1] = params[1] - parsedParams[2] = params[2] - parsedParams[3] = params[3] - // 4. GasLimit (uint64) - num, err := strconv.ParseUint(params[4], 10, 64) - if err != nil { - panic("Error parsing gas limit: uint64 could not be parsed.") - } - parsedParams[4] = num - return parsedParams - case "BeginRedelegate": - // 1. Source Validator Address - var err error - if err = validateParamsFn(len(params), 5); err != nil { - panic(err) - } - parsedParams[0], err = parseAddressFromString(params[0]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - // 2. Destination Validator Address - parsedParams[1], err = parseAddressFromString(params[1]) - if err != nil { - panic(fmt.Errorf("error parsing address: %w", err)) - } - // 2. Amount + Fee - parsedParams[2] = params[2] - parsedParams[3] = params[3] - // 4. GasLimit (uint64) - num, err := strconv.ParseUint(params[4], 10, 64) - if err != nil { - panic("Error parsing gas limit: uint64 could not be parsed.") - } - parsedParams[4] = num - return parsedParams - default: - } - - for i, param := range params { - if param[0] == '{' || param[0] == '[' { - rawJSON, err := parseJSON(param) - if err != nil { - parsedParams[i] = param - } else { - parsedParams[i] = rawJSON - } - } else { - // try to parse arguments as numbers before adding them as strings - num, err := strconv.ParseInt(param, 10, 64) - if err == nil { - parsedParams[i] = num - continue - } - parsedParams[i] = param - } - } - return parsedParams -} - -func sendJSONRPCRequest(namespace, method string, params []interface{}) { - url := requestURL - request := jsonRPCRequest{ - ID: 1, - JSONRPC: "2.0", - Method: fmt.Sprintf("%s.%s", namespace, method), - Params: params, - } - - requestBody, err := json.Marshal(request) - if err != nil { - log.Fatalf("Error marshaling JSON-RPC request: %v", err) - } - - req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody)) - if err != nil { - log.Fatalf("Error creating JSON-RPC request: %v", err) - } - - req.Header.Set("Content-Type", "application/json") - - authToken := authTokenFlag - if authToken == "" { - authToken = os.Getenv(authEnvKey) - } - if authToken != "" { - req.Header.Set("Authorization", "Bearer "+authToken) - } - - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - log.Fatalf("Error sending JSON-RPC request: %v", err) - } - defer resp.Body.Close() - - responseBody, err := io.ReadAll(resp.Body) - if err != nil { - log.Fatalf("Error reading response body: %v", err) //nolint:gocritic - } - - rawResponseJSON, err := parseJSON(string(responseBody)) - if err != nil { - log.Fatalf("Error parsing JSON-RPC response: %v", err) - } - if printRequest { - output, err := json.MarshalIndent(outputWithRequest{ - Request: request, - Response: rawResponseJSON, - }, "", " ") - if err != nil { - panic(fmt.Sprintf("Error marshaling JSON-RPC response: %v", err)) - } - fmt.Println(string(output)) - return - } - - output, err := json.MarshalIndent(rawResponseJSON, "", " ") - if err != nil { - panic(fmt.Sprintf("Error marshaling JSON-RPC response: %v", err)) - } - fmt.Println(string(output)) -} - -func parseAddressFromString(addrStr string) (state.Address, error) { - var address state.Address - err := address.UnmarshalJSON([]byte(addrStr)) - if err != nil { - return address, err - } - return address, nil -} - -func parseSignatureForHelpstring(methodSig reflect.StructField) string { - simplifiedSignature := "(" - in, out := methodSig.Type.NumIn(), methodSig.Type.NumOut() - for i := 1; i < in; i++ { - simplifiedSignature += methodSig.Type.In(i).String() - if i != in-1 { - simplifiedSignature += ", " - } - } - simplifiedSignature += ") -> (" - for i := 0; i < out-1; i++ { - simplifiedSignature += methodSig.Type.Out(i).String() - if i != out-2 { - simplifiedSignature += ", " - } - } - simplifiedSignature += ")" - return simplifiedSignature -} - -// parseV0Namespace parses a namespace from a base64 or hex string. The param -// is expected to be the user-specified portion of a v0 namespace ID (i.e. the -// last 10 bytes). -func parseV0Namespace(param string) (share.Namespace, error) { - userBytes, err := decodeToBytes(param) - if err != nil { - return nil, err - } - - // if the namespace ID is <= 10 bytes, left pad it with 0s - return share.NewBlobNamespaceV0(userBytes) -} - -// decodeToBytes decodes a Base64 or hex input string into a byte slice. -func decodeToBytes(param string) ([]byte, error) { - if strings.HasPrefix(param, "0x") { - decoded, err := hex.DecodeString(param[2:]) - if err != nil { - return nil, fmt.Errorf("error decoding namespace ID: %w", err) - } - return decoded, nil - } - // otherwise, it's just a base64 string - decoded, err := base64.StdEncoding.DecodeString(param) - if err != nil { - return nil, fmt.Errorf("error decoding namespace ID: %w", err) - } - return decoded, nil -} - -func parseJSON(param string) (json.RawMessage, error) { - var raw json.RawMessage - err := json.Unmarshal([]byte(param), &raw) - return raw, err -} - -func newRPCClient(ctx context.Context) (*client.Client, error) { - if authTokenFlag == "" { - authTokenFlag = os.Getenv(authEnvKey) - } - return client.NewClient(ctx, requestURL, authTokenFlag) -} - -type rpcClientKey struct{} - -func rpcClient(ctx context.Context) (*client.Client, error) { - client, ok := ctx.Value(rpcClientKey{}).(*client.Client) - if !ok { - return nil, errors.New("rpc client was not set") - } - return client, nil -} - -func printOutput(data interface{}, err error, formatData func(interface{}) interface{}) error { - switch { - case err != nil: - data = err - case formatData != nil: - data = formatData(data) - } - - resp := struct { - Result interface{} `json:"result"` - }{ - Result: data, - } - - bytes, err := json.MarshalIndent(resp, "", " ") - if err != nil { - return err - } - fmt.Fprintln(os.Stdout, string(bytes)) - return nil } diff --git a/cmd/celestia/util.go b/cmd/celestia/util.go deleted file mode 100644 index a38860d1f7..0000000000 --- a/cmd/celestia/util.go +++ /dev/null @@ -1,68 +0,0 @@ -package main - -import ( - "github.com/spf13/cobra" - - cmdnode "github.com/celestiaorg/celestia-node/cmd" - "github.com/celestiaorg/celestia-node/nodebuilder/core" - "github.com/celestiaorg/celestia-node/nodebuilder/gateway" - "github.com/celestiaorg/celestia-node/nodebuilder/header" - "github.com/celestiaorg/celestia-node/nodebuilder/node" - "github.com/celestiaorg/celestia-node/nodebuilder/p2p" - "github.com/celestiaorg/celestia-node/nodebuilder/rpc" - "github.com/celestiaorg/celestia-node/nodebuilder/state" -) - -func persistentPreRunEnv(cmd *cobra.Command, nodeType node.Type, _ []string) error { - var ( - ctx = cmd.Context() - err error - ) - - ctx = cmdnode.WithNodeType(ctx, nodeType) - - parsedNetwork, err := p2p.ParseNetwork(cmd) - if err != nil { - return err - } - ctx = cmdnode.WithNetwork(ctx, parsedNetwork) - - // loads existing config into the environment - ctx, err = cmdnode.ParseNodeFlags(ctx, cmd, cmdnode.Network(ctx)) - if err != nil { - return err - } - - cfg := cmdnode.NodeConfig(ctx) - - err = p2p.ParseFlags(cmd, &cfg.P2P) - if err != nil { - return err - } - - err = core.ParseFlags(cmd, &cfg.Core) - if err != nil { - return err - } - - if nodeType != node.Bridge { - err = header.ParseFlags(cmd, &cfg.Header) - if err != nil { - return err - } - } - - ctx, err = cmdnode.ParseMiscFlags(ctx, cmd) - if err != nil { - return err - } - - rpc.ParseFlags(cmd, &cfg.RPC) - gateway.ParseFlags(cmd, &cfg.Gateway) - state.ParseFlags(cmd, &cfg.State) - - // set config - ctx = cmdnode.WithNodeConfig(ctx, &cfg) - cmd.SetContext(ctx) - return nil -} diff --git a/cmd/rpc.go b/cmd/rpc.go new file mode 100644 index 0000000000..513967f0ed --- /dev/null +++ b/cmd/rpc.go @@ -0,0 +1,58 @@ +package cmd + +import ( + "context" + "errors" + "os" + + "github.com/spf13/cobra" + + rpc "github.com/celestiaorg/celestia-node/api/rpc/client" +) + +const ( + // defaultRPCAddress is a default address to dial to + defaultRPCAddress = "http://localhost:26658" + authEnvKey = "CELESTIA_NODE_AUTH_TOKEN" //nolint:gosec +) + +var ( + requestURL string + authTokenFlag string +) + +func InitURLFlag() (*string, string, string, string) { + return &requestURL, "url", defaultRPCAddress, "Request URL" +} + +func InitAuthTokenFlag() (*string, string, string, string) { + return &authTokenFlag, + "token", + "", + "Authorization token (if not provided, the " + authEnvKey + " environment variable will be used)" +} + +func InitClient(cmd *cobra.Command, _ []string) error { + if authTokenFlag == "" { + authTokenFlag = os.Getenv(authEnvKey) + } + + client, err := rpc.NewClient(cmd.Context(), requestURL, authTokenFlag) + if err != nil { + return err + } + + ctx := context.WithValue(cmd.Context(), rpcClientKey{}, client) + cmd.SetContext(ctx) + return nil +} + +type rpcClientKey struct{} + +func ParseClientFromCtx(ctx context.Context) (*rpc.Client, error) { + client, ok := ctx.Value(rpcClientKey{}).(*rpc.Client) + if !ok { + return nil, errors.New("rpc client was not set") + } + return client, nil +} diff --git a/cmd/util.go b/cmd/util.go new file mode 100644 index 0000000000..625685fe0b --- /dev/null +++ b/cmd/util.go @@ -0,0 +1,127 @@ +package cmd + +import ( + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "os" + "strings" + + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/nodebuilder/core" + "github.com/celestiaorg/celestia-node/nodebuilder/gateway" + "github.com/celestiaorg/celestia-node/nodebuilder/header" + "github.com/celestiaorg/celestia-node/nodebuilder/node" + "github.com/celestiaorg/celestia-node/nodebuilder/p2p" + rpc_cfg "github.com/celestiaorg/celestia-node/nodebuilder/rpc" + "github.com/celestiaorg/celestia-node/nodebuilder/state" + "github.com/celestiaorg/celestia-node/share" +) + +func PrintOutput(data interface{}, err error, formatData func(interface{}) interface{}) error { + switch { + case err != nil: + data = err + case formatData != nil: + data = formatData(data) + } + + resp := struct { + Result interface{} `json:"result"` + }{ + Result: data, + } + + bytes, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return err + } + fmt.Fprintln(os.Stdout, string(bytes)) + return nil +} + +// ParseV0Namespace parses a namespace from a base64 or hex string. The param +// is expected to be the user-specified portion of a v0 namespace ID (i.e. the +// last 10 bytes). +func ParseV0Namespace(param string) (share.Namespace, error) { + userBytes, err := DecodeToBytes(param) + if err != nil { + return nil, err + } + + // if the namespace ID is <= 10 bytes, left pad it with 0s + return share.NewBlobNamespaceV0(userBytes) +} + +// DecodeToBytes decodes a Base64 or hex input string into a byte slice. +func DecodeToBytes(param string) ([]byte, error) { + if strings.HasPrefix(param, "0x") { + decoded, err := hex.DecodeString(param[2:]) + if err != nil { + return nil, fmt.Errorf("error decoding namespace ID: %w", err) + } + return decoded, nil + } + // otherwise, it's just a base64 string + decoded, err := base64.StdEncoding.DecodeString(param) + if err != nil { + return nil, fmt.Errorf("error decoding namespace ID: %w", err) + } + return decoded, nil +} + +func PersistentPreRunEnv(cmd *cobra.Command, nodeType node.Type, _ []string) error { + var ( + ctx = cmd.Context() + err error + ) + + ctx = WithNodeType(ctx, nodeType) + + parsedNetwork, err := p2p.ParseNetwork(cmd) + if err != nil { + return err + } + ctx = WithNetwork(ctx, parsedNetwork) + + // loads existing config into the environment + ctx, err = ParseNodeFlags(ctx, cmd, Network(ctx)) + if err != nil { + return err + } + + cfg := NodeConfig(ctx) + + err = p2p.ParseFlags(cmd, &cfg.P2P) + if err != nil { + return err + } + + err = core.ParseFlags(cmd, &cfg.Core) + if err != nil { + return err + } + + if nodeType != node.Bridge { + err = header.ParseFlags(cmd, &cfg.Header) + if err != nil { + return err + } + } + + ctx, err = ParseMiscFlags(ctx, cmd) + if err != nil { + return err + } + + rpc_cfg.ParseFlags(cmd, &cfg.RPC) + gateway.ParseFlags(cmd, &cfg.Gateway) + state.ParseFlags(cmd, &cfg.State) + + // set config + ctx = WithNodeConfig(ctx, &cfg) + cmd.SetContext(ctx) + return nil +} diff --git a/cmd/celestia/rpc_test.go b/cmd/util_test.go similarity index 97% rename from cmd/celestia/rpc_test.go rename to cmd/util_test.go index 53087646a7..b6e245f3e2 100644 --- a/cmd/celestia/rpc_test.go +++ b/cmd/util_test.go @@ -1,4 +1,4 @@ -package main +package cmd import ( "testing" @@ -69,7 +69,7 @@ func Test_parseNamespaceID(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - got, err := parseV0Namespace(tc.param) + got, err := ParseV0Namespace(tc.param) if tc.wantErr { assert.Error(t, err) return diff --git a/cmd/celestia/blob.go b/nodebuilder/blob/cmd/blob.go similarity index 77% rename from cmd/celestia/blob.go rename to nodebuilder/blob/cmd/blob.go index 9550f2c13a..1c5ec1ad50 100644 --- a/cmd/celestia/blob.go +++ b/nodebuilder/blob/cmd/blob.go @@ -1,4 +1,4 @@ -package main +package cmd import ( "encoding/base64" @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/celestiaorg/celestia-node/blob" + cmdnode "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/share" ) @@ -20,7 +21,7 @@ var ( ) func init() { - blobCmd.AddCommand(getCmd, getAllCmd, submitCmd, getProofCmd) + Cmd.AddCommand(getCmd, getAllCmd, submitCmd, getProofCmd) getCmd.PersistentFlags().BoolVar( &base64Flag, @@ -28,6 +29,7 @@ func init() { false, "printed blob's data a base64 string", ) + getAllCmd.PersistentFlags().BoolVar( &base64Flag, "base64", @@ -50,28 +52,30 @@ func init() { ) } -var blobCmd = &cobra.Command{ - Use: "blob [command]", - Short: "Allows to interact with the Blob Service via JSON-RPC", - Args: cobra.NoArgs, +var Cmd = &cobra.Command{ + Use: "blob [command]", + Short: "Allows to interact with the Blob Service via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var getCmd = &cobra.Command{ - Use: "get [height, namespace, commitment]", + Use: "get [height] [namespace] [commitment]", Args: cobra.ExactArgs(3), Short: "Returns the blob for the given namespace by commitment at a particular height.", RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() height, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return fmt.Errorf("error parsing a height:%v", err) } - namespace, err := parseV0Namespace(args[1]) + namespace, err := cmdnode.ParseV0Namespace(args[1]) if err != nil { return fmt.Errorf("error parsing a namespace:%v", err) } @@ -87,51 +91,52 @@ var getCmd = &cobra.Command{ if base64Flag || err != nil { formatter = nil } - return printOutput(blob, err, formatter) + return cmdnode.PrintOutput(blob, err, formatter) }, } var getAllCmd = &cobra.Command{ - Use: "get-all [height, namespace]", + Use: "get-all [height] [namespace]", Args: cobra.ExactArgs(2), Short: "Returns all blobs for the given namespace at a particular height.", RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() height, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return fmt.Errorf("error parsing a height:%v", err) } - namespace, err := parseV0Namespace(args[1]) + namespace, err := cmdnode.ParseV0Namespace(args[1]) if err != nil { return fmt.Errorf("error parsing a namespace:%v", err) } blobs, err := client.Blob.GetAll(cmd.Context(), height, []share.Namespace{namespace}) - formatter := formatData if base64Flag || err != nil { formatter = nil } - return printOutput(blobs, err, formatter) + return cmdnode.PrintOutput(blobs, err, formatter) }, } var submitCmd = &cobra.Command{ - Use: "submit [namespace, blobData]", + Use: "submit [namespace] [blobData]", Args: cobra.ExactArgs(2), Short: "Submit the blob at the given namespace. Note: only one blob is allowed to submit through the RPC.", RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() - namespace, err := parseV0Namespace(args[0]) + namespace, err := cmdnode.ParseV0Namespace(args[0]) if err != nil { return fmt.Errorf("error parsing a namespace:%v", err) } @@ -154,26 +159,27 @@ var submitCmd = &cobra.Command{ Height: height, Commitment: parsedBlob.Commitment, } - return printOutput(response, err, nil) + return cmdnode.PrintOutput(response, err, nil) }, } var getProofCmd = &cobra.Command{ - Use: "get-proof [height, namespace, commitment]", + Use: "get-proof [height] [namespace] [commitment]", Args: cobra.ExactArgs(3), Short: "Retrieves the blob in the given namespaces at the given height by commitment and returns its Proof.", RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() height, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return fmt.Errorf("error parsing a height:%v", err) } - namespace, err := parseV0Namespace(args[1]) + namespace, err := cmdnode.ParseV0Namespace(args[1]) if err != nil { return fmt.Errorf("error parsing a namespace:%v", err) } @@ -184,7 +190,7 @@ var getProofCmd = &cobra.Command{ } proof, err := client.Blob.GetProof(cmd.Context(), height, namespace, commitment) - return printOutput(proof, err, nil) + return cmdnode.PrintOutput(proof, err, nil) }, } diff --git a/nodebuilder/das/cmd/das.go b/nodebuilder/das/cmd/das.go new file mode 100644 index 0000000000..7512861ac3 --- /dev/null +++ b/nodebuilder/das/cmd/das.go @@ -0,0 +1,34 @@ +package cmd + +import ( + "github.com/spf13/cobra" + + cmdnode "github.com/celestiaorg/celestia-node/cmd" +) + +func init() { + Cmd.AddCommand(samplingStatsCmd) +} + +var Cmd = &cobra.Command{ + Use: "das [command]", + Short: "Allows to interact with the Daser via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, +} + +var samplingStatsCmd = &cobra.Command{ + Use: "sampling-stats", + Short: "Returns the current statistics over the DA sampling process", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) + if err != nil { + return err + } + defer client.Close() + + stats, err := client.DAS.SamplingStats(cmd.Context()) + return cmdnode.PrintOutput(stats, err, nil) + }, +} diff --git a/cmd/celestia/header.go b/nodebuilder/header/cmd/header.go similarity index 68% rename from cmd/celestia/header.go rename to nodebuilder/header/cmd/header.go index 1d8dc6d01b..b3bba1eb32 100644 --- a/cmd/celestia/header.go +++ b/nodebuilder/header/cmd/header.go @@ -1,4 +1,4 @@ -package main +package cmd import ( "encoding/hex" @@ -6,10 +6,12 @@ import ( "strconv" "github.com/spf13/cobra" + + cmdnode "github.com/celestiaorg/celestia-node/cmd" ) func init() { - headerCmd.AddCommand( + Cmd.AddCommand( localHeadCmd, networkHeadCmd, getByHashCmd, @@ -18,10 +20,11 @@ func init() { ) } -var headerCmd = &cobra.Command{ - Use: "header [command]", - Short: "Allows interaction with the Header Module via JSON-RPC", - Args: cobra.NoArgs, +var Cmd = &cobra.Command{ + Use: "header [command]", + Short: "Allows interaction with the Header Module via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var localHeadCmd = &cobra.Command{ @@ -29,13 +32,14 @@ var localHeadCmd = &cobra.Command{ Short: "Returns the ExtendedHeader from the chain head.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() header, err := client.Header.LocalHead(cmd.Context()) - return printOutput(header, err, nil) + return cmdnode.PrintOutput(header, err, nil) }, } @@ -44,13 +48,14 @@ var networkHeadCmd = &cobra.Command{ Short: "Provides the Syncer's view of the current network head.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() header, err := client.Header.NetworkHead(cmd.Context()) - return printOutput(header, err, nil) + return cmdnode.PrintOutput(header, err, nil) }, } @@ -59,17 +64,18 @@ var getByHashCmd = &cobra.Command{ Short: "Returns the header of the given hash from the node's header store.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() hash, err := hex.DecodeString(args[0]) if err != nil { return fmt.Errorf("error decoding a hash: expected a hex encoded string:%v", err) } header, err := client.Header.GetByHash(cmd.Context(), hash) - return printOutput(header, err, nil) + return cmdnode.PrintOutput(header, err, nil) }, } @@ -78,10 +84,11 @@ var getByHeightCmd = &cobra.Command{ Short: "Returns the ExtendedHeader at the given height if it is currently available.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() height, err := strconv.ParseUint(args[0], 10, 64) if err != nil { @@ -89,7 +96,7 @@ var getByHeightCmd = &cobra.Command{ } header, err := client.Header.GetByHeight(cmd.Context(), height) - return printOutput(header, err, nil) + return cmdnode.PrintOutput(header, err, nil) }, } @@ -98,12 +105,13 @@ var syncStateCmd = &cobra.Command{ Short: "Returns the current state of the header Syncer.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() header, err := client.Header.SyncState(cmd.Context()) - return printOutput(header, err, nil) + return cmdnode.PrintOutput(header, err, nil) }, } diff --git a/cmd/celestia/admin.go b/nodebuilder/node/cmd/node.go similarity index 61% rename from cmd/celestia/admin.go rename to nodebuilder/node/cmd/node.go index a3665e0aa1..a65727fb03 100644 --- a/cmd/celestia/admin.go +++ b/nodebuilder/node/cmd/node.go @@ -1,33 +1,24 @@ -package main +package cmd import ( - "context" "errors" "strings" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/spf13/cobra" + + cmdnode "github.com/celestiaorg/celestia-node/cmd" ) func init() { - nodeCmd.AddCommand(nodeInfoCmd, logCmd, verifyCmd, authCmd) - rootCmd.AddCommand(nodeCmd) + Cmd.AddCommand(nodeInfoCmd, logCmd, verifyCmd, authCmd) } -var nodeCmd = &cobra.Command{ - Use: "node [command]", - Short: "Allows administrating running node.", - Args: cobra.NoArgs, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - rpcClient, err := newRPCClient(cmd.Context()) - if err != nil { - return err - } - - ctx := context.WithValue(cmd.Context(), rpcClientKey{}, rpcClient) - cmd.SetContext(ctx) - return nil - }, +var Cmd = &cobra.Command{ + Use: "node [command]", + Short: "Allows administrating running node.", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var nodeInfoCmd = &cobra.Command{ @@ -35,26 +26,30 @@ var nodeInfoCmd = &cobra.Command{ Args: cobra.NoArgs, Short: "Returns administrative information about the node.", RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) + client, err := cmdnode.ParseClientFromCtx(c.Context()) if err != nil { return err } + defer client.Close() + info, err := client.Node.Info(c.Context()) - return printOutput(info, err, nil) + return cmdnode.PrintOutput(info, err, nil) }, } var logCmd = &cobra.Command{ - Use: "log-level", - Args: cobra.MinimumNArgs(1), - Short: "Allows to set log level for module to in format :" + + Use: "log-level", + Args: cobra.MinimumNArgs(1), + Short: "Sets log level for module.", + Long: "Allows to set log level for module to in format :" + "`DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL and their lower-case forms`.\n" + "To set all modules to a particular level `*:` should be passed", RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) + client, err := cmdnode.ParseClientFromCtx(c.Context()) if err != nil { return err } + defer client.Close() for _, ll := range args { params := strings.Split(ll, ":") @@ -63,7 +58,7 @@ var logCmd = &cobra.Command{ "e.g. pubsub:debug") } - if err = client.Node.LogLevelSet(c.Context(), params[0], params[1]); err != nil { + if err := client.Node.LogLevelSet(c.Context(), params[0], params[1]); err != nil { return err } } @@ -77,13 +72,14 @@ var verifyCmd = &cobra.Command{ Short: "Returns the permissions assigned to the given token.", RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) + client, err := cmdnode.ParseClientFromCtx(c.Context()) if err != nil { return err } + defer client.Close() perms, err := client.Node.AuthVerify(c.Context(), args[0]) - return printOutput(perms, err, nil) + return cmdnode.PrintOutput(perms, err, nil) }, } @@ -92,10 +88,11 @@ var authCmd = &cobra.Command{ Args: cobra.MinimumNArgs(1), Short: "Signs and returns a new token with the given permissions.", RunE: func(c *cobra.Command, args []string) error { - client, err := rpcClient(c.Context()) + client, err := cmdnode.ParseClientFromCtx(c.Context()) if err != nil { return err } + defer client.Close() perms := make([]auth.Permission, len(args)) for i, p := range args { @@ -103,6 +100,6 @@ var authCmd = &cobra.Command{ } result, err := client.Node.AuthNew(c.Context(), perms) - return printOutput(result, err, nil) + return cmdnode.PrintOutput(result, err, nil) }, } diff --git a/cmd/celestia/p2p.go b/nodebuilder/p2p/cmd/p2p.go similarity index 79% rename from cmd/celestia/p2p.go rename to nodebuilder/p2p/cmd/p2p.go index d0b6549f6c..5951595fa4 100644 --- a/cmd/celestia/p2p.go +++ b/nodebuilder/p2p/cmd/p2p.go @@ -1,4 +1,4 @@ -package main +package cmd import ( "github.com/libp2p/go-libp2p/core/metrics" @@ -7,6 +7,8 @@ import ( "github.com/libp2p/go-libp2p/core/protocol" ma2 "github.com/multiformats/go-multiaddr" "github.com/spf13/cobra" + + cmdnode "github.com/celestiaorg/celestia-node/cmd" ) type peerInfo struct { @@ -15,7 +17,7 @@ type peerInfo struct { } func init() { - p2pCmd.AddCommand(infoCmd, + Cmd.AddCommand(infoCmd, peersCmd, peerInfoCmd, connectCmd, @@ -35,10 +37,11 @@ func init() { ) } -var p2pCmd = &cobra.Command{ - Use: "p2p [command]", - Short: "Allows interaction with the P2P Module via JSON-RPC", - Args: cobra.NoArgs, +var Cmd = &cobra.Command{ + Use: "p2p [command]", + Short: "Allows interaction with the P2P Module via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var infoCmd = &cobra.Command{ @@ -46,10 +49,11 @@ var infoCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() info, err := client.P2P.Info(cmd.Context()) @@ -65,7 +69,7 @@ var infoCmd = &cobra.Command{ PeerAddr: ma, } } - return printOutput(info, err, formatter) + return cmdnode.PrintOutput(info, err, formatter) }, } @@ -74,10 +78,11 @@ var peersCmd = &cobra.Command{ Short: "Lists the peers we are connected to", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() result, err := client.P2P.Peers(cmd.Context()) peers := make([]string, len(result)) @@ -93,7 +98,7 @@ var peersCmd = &cobra.Command{ Peers: conPeers, } } - return printOutput(peers, err, formatter) + return cmdnode.PrintOutput(peers, err, formatter) }, } @@ -102,10 +107,11 @@ var peerInfoCmd = &cobra.Command{ Short: "Gets PeerInfo for a given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -124,7 +130,7 @@ var peerInfoCmd = &cobra.Command{ PeerAddr: ma, } } - return printOutput(info, err, formatter) + return cmdnode.PrintOutput(info, err, formatter) }, } @@ -133,10 +139,11 @@ var connectCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -155,7 +162,7 @@ var connectCmd = &cobra.Command{ err = client.P2P.Connect(cmd.Context(), peerInfo) if err != nil { - return printOutput(nil, err, nil) + return cmdnode.PrintOutput(nil, err, nil) } return connectednessCmd.RunE(cmd, args) }, @@ -166,10 +173,11 @@ var closePeerCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -178,7 +186,7 @@ var closePeerCmd = &cobra.Command{ err = client.P2P.ClosePeer(cmd.Context(), pid) if err != nil { - return printOutput(nil, err, nil) + return cmdnode.PrintOutput(nil, err, nil) } return connectednessCmd.RunE(cmd, args) }, @@ -189,10 +197,11 @@ var connectednessCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -209,7 +218,7 @@ var connectednessCmd = &cobra.Command{ ConnectionState: conn.String(), } } - return printOutput(con, err, formatter) + return cmdnode.PrintOutput(con, err, formatter) }, } @@ -218,10 +227,11 @@ var natStatusCmd = &cobra.Command{ Short: "Gets the currrent NAT status", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() r, err := client.P2P.NATStatus(cmd.Context()) @@ -233,7 +243,7 @@ var natStatusCmd = &cobra.Command{ Reachability: rr.String(), } } - return printOutput(r, err, formatter) + return cmdnode.PrintOutput(r, err, formatter) }, } @@ -242,10 +252,11 @@ var blockPeerCmd = &cobra.Command{ Short: "Blocks the given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -270,7 +281,7 @@ var blockPeerCmd = &cobra.Command{ Reason: err, } } - return printOutput(err, nil, formatter) + return cmdnode.PrintOutput(err, nil, formatter) }, } @@ -279,10 +290,11 @@ var unblockPeerCmd = &cobra.Command{ Short: "Unblocks the given peer", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -308,7 +320,7 @@ var unblockPeerCmd = &cobra.Command{ Reason: err, } } - return printOutput(err, nil, formatter) + return cmdnode.PrintOutput(err, nil, formatter) }, } @@ -317,10 +329,11 @@ var blockedPeersCmd = &cobra.Command{ Short: "Lists the node's blocked peers", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() list, err := client.P2P.ListBlockedPeers(cmd.Context()) @@ -337,7 +350,7 @@ var blockedPeersCmd = &cobra.Command{ Peers: peers, } } - return printOutput(pids, err, formatter) + return cmdnode.PrintOutput(pids, err, formatter) }, } @@ -346,10 +359,11 @@ var protectCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -374,20 +388,22 @@ var protectCmd = &cobra.Command{ Reason: err, } } - return printOutput(err, nil, formatter) + return cmdnode.PrintOutput(err, nil, formatter) }, } 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." + + Use: "unprotect [peer.ID, tag]", + Short: "Removes protection from the given peer.", + Long: "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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -412,7 +428,7 @@ var unprotectCmd = &cobra.Command{ Reason: err, } } - return printOutput(err, nil, formatter) + return cmdnode.PrintOutput(err, nil, formatter) }, } @@ -421,10 +437,11 @@ var protectedCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -432,7 +449,7 @@ var protectedCmd = &cobra.Command{ } result, err := client.P2P.IsProtected(cmd.Context(), pid, args[1]) - return printOutput(result, err, nil) + return cmdnode.PrintOutput(result, err, nil) }, } @@ -444,15 +461,17 @@ type bandwidthStats struct { } var bandwidthStatsCmd = &cobra.Command{ - Use: "bandwidth-stats", - Short: "Get stats struct with bandwidth metrics for all data sent/" + + Use: "bandwidth-stats", + Short: "Provides metrics for current peer.", + Long: "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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() result, err := client.P2P.BandwidthStats(cmd.Context()) @@ -465,7 +484,7 @@ var bandwidthStatsCmd = &cobra.Command{ RateOut: stats.RateOut, } } - return printOutput(result, err, formatter) + return cmdnode.PrintOutput(result, err, formatter) }, } @@ -474,10 +493,11 @@ var peerBandwidthCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() pid, err := peer.Decode(args[0]) if err != nil { @@ -495,7 +515,7 @@ var peerBandwidthCmd = &cobra.Command{ RateOut: stats.RateOut, } } - return printOutput(result, err, formatter) + return cmdnode.PrintOutput(result, err, formatter) }, } @@ -504,10 +524,11 @@ var bandwidthForProtocolCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() result, err := client.P2P.BandwidthForProtocol(cmd.Context(), protocol.ID(args[0])) @@ -520,7 +541,7 @@ var bandwidthForProtocolCmd = &cobra.Command{ RateOut: stats.RateOut, } } - return printOutput(result, err, formatter) + return cmdnode.PrintOutput(result, err, formatter) }, } @@ -529,10 +550,11 @@ var pubsubPeersCmd = &cobra.Command{ 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()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() result, err := client.P2P.PubSubPeers(cmd.Context(), args[0]) peers := make([]string, len(result)) @@ -549,6 +571,6 @@ var pubsubPeersCmd = &cobra.Command{ Peers: conPeers, } } - return printOutput(peers, err, formatter) + return cmdnode.PrintOutput(peers, err, formatter) }, } diff --git a/cmd/celestia/share.go b/nodebuilder/share/cmd/share.go similarity index 76% rename from cmd/celestia/share.go rename to nodebuilder/share/cmd/share.go index 2f84871d80..fbf3e51db4 100644 --- a/cmd/celestia/share.go +++ b/nodebuilder/share/cmd/share.go @@ -1,4 +1,4 @@ -package main +package cmd import ( "encoding/hex" @@ -9,11 +9,12 @@ import ( "github.com/celestiaorg/celestia-app/pkg/da" + cmdnode "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/share" ) func init() { - shareCmd.AddCommand( + Cmd.AddCommand( sharesAvailableCmd, probabilityOfAvailabilityCmd, getSharesByNamespaceCmd, @@ -22,10 +23,11 @@ func init() { ) } -var shareCmd = &cobra.Command{ - Use: "share [command]", - Short: "Allows interaction with the Share Module via JSON-RPC", - Args: cobra.NoArgs, +var Cmd = &cobra.Command{ + Use: "share [command]", + Short: "Allows interaction with the Share Module via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var sharesAvailableCmd = &cobra.Command{ @@ -33,10 +35,11 @@ var sharesAvailableCmd = &cobra.Command{ Short: "Subjectively validates if Shares committed to the given Root are available on the Network.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() raw, err := parseJSON(args[0]) if err != nil { @@ -66,7 +69,7 @@ var sharesAvailableCmd = &cobra.Command{ Reason: err, } } - return printOutput(err, nil, formatter) + return cmdnode.PrintOutput(err, nil, formatter) }, } @@ -75,13 +78,14 @@ var probabilityOfAvailabilityCmd = &cobra.Command{ Short: "Calculates the probability of the data square being available based on the number of samples collected.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() prob := client.Share.ProbabilityOfAvailability(cmd.Context()) - return printOutput(prob, nil, nil) + return cmdnode.PrintOutput(prob, nil, nil) }, } @@ -90,10 +94,11 @@ var getSharesByNamespaceCmd = &cobra.Command{ Short: "Gets all shares from an EDS within the given namespace.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() raw, err := parseJSON(args[0]) if err != nil { @@ -106,13 +111,13 @@ var getSharesByNamespaceCmd = &cobra.Command{ return err } - ns, err := parseV0Namespace(args[1]) + ns, err := cmdnode.ParseV0Namespace(args[1]) if err != nil { return err } shares, err := client.Share.GetSharesByNamespace(cmd.Context(), &root, ns) - return printOutput(shares, err, nil) + return cmdnode.PrintOutput(shares, err, nil) }, } @@ -121,10 +126,11 @@ var getShare = &cobra.Command{ Short: "Gets a Share by coordinates in EDS.", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() raw, err := parseJSON(args[0]) if err != nil { @@ -165,7 +171,7 @@ var getShare = &cobra.Command{ Data: share.GetData(sh), } } - return printOutput(s, err, formatter) + return cmdnode.PrintOutput(s, err, formatter) }, } @@ -174,10 +180,11 @@ var getEDS = &cobra.Command{ Short: "Gets the full EDS identified by the given root", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() raw, err := parseJSON(args[0]) if err != nil { @@ -191,6 +198,12 @@ var getEDS = &cobra.Command{ } shares, err := client.Share.GetEDS(cmd.Context(), &root) - return printOutput(shares, err, nil) + return cmdnode.PrintOutput(shares, err, nil) }, } + +func parseJSON(param string) (json.RawMessage, error) { + var raw json.RawMessage + err := json.Unmarshal([]byte(param), &raw) + return raw, err +} diff --git a/cmd/celestia/state.go b/nodebuilder/state/cmd/state.go similarity index 80% rename from cmd/celestia/state.go rename to nodebuilder/state/cmd/state.go index 2f3d1e138a..be52b6d26a 100644 --- a/cmd/celestia/state.go +++ b/nodebuilder/state/cmd/state.go @@ -1,6 +1,7 @@ -package main +package cmd import ( + "encoding/hex" "fmt" "strconv" @@ -9,11 +10,12 @@ import ( "github.com/spf13/cobra" "github.com/celestiaorg/celestia-node/blob" + cmdnode "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/state" ) func init() { - stateCmd.AddCommand( + Cmd.AddCommand( accountAddressCmd, balanceCmd, balanceForAddressCmd, @@ -30,10 +32,11 @@ func init() { ) } -var stateCmd = &cobra.Command{ - Use: "state [command]", - Short: "Allows interaction with the State Module via JSON-RPC", - Args: cobra.NoArgs, +var Cmd = &cobra.Command{ + Use: "state [command]", + Short: "Allows interaction with the State Module via JSON-RPC", + Args: cobra.NoArgs, + PersistentPreRunE: cmdnode.InitClient, } var accountAddressCmd = &cobra.Command{ @@ -41,13 +44,14 @@ var accountAddressCmd = &cobra.Command{ Short: "Retrieves the address of the node's account/signer.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() address, err := client.State.AccountAddress(cmd.Context()) - return printOutput(address, err, nil) + return cmdnode.PrintOutput(address, err, nil) }, } @@ -57,13 +61,14 @@ var balanceCmd = &cobra.Command{ "the corresponding block's AppHash.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() balance, err := client.State.Balance(cmd.Context()) - return printOutput(balance, err, nil) + return cmdnode.PrintOutput(balance, err, nil) }, } @@ -73,10 +78,11 @@ var balanceForAddressCmd = &cobra.Command{ "the corresponding block's AppHash.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() addr, err := parseAddressFromString(args[0]) if err != nil { @@ -84,7 +90,7 @@ var balanceForAddressCmd = &cobra.Command{ } balance, err := client.State.BalanceForAddress(cmd.Context(), addr) - return printOutput(balance, err, nil) + return cmdnode.PrintOutput(balance, err, nil) }, } @@ -93,10 +99,11 @@ var transferCmd = &cobra.Command{ Short: "Sends the given amount of coins from default wallet of the node to the given account address.", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() addr, err := parseAddressFromString(args[0]) if err != nil { @@ -122,7 +129,7 @@ var transferCmd = &cobra.Command{ math.NewInt(amount), math.NewInt(fee), gasLimit, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -131,20 +138,21 @@ var submitTxCmd = &cobra.Command{ Short: "Submits the given transaction/message to the Celestia network and blocks until the tx is included in a block.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() - rawTx, err := decodeToBytes(args[0]) + decoded, err := hex.DecodeString(args[0]) if err != nil { return fmt.Errorf("failed to decode tx: %v", err) } txResponse, err := client.State.SubmitTx( cmd.Context(), - rawTx, + decoded, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -153,11 +161,13 @@ var submitPFBCmd = &cobra.Command{ Short: "Allows to submit PFBs", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } - namespace, err := parseV0Namespace(args[0]) + defer client.Close() + + namespace, err := cmdnode.ParseV0Namespace(args[0]) if err != nil { return fmt.Errorf("error parsing a namespace:%v", err) } @@ -177,8 +187,13 @@ var submitPFBCmd = &cobra.Command{ return fmt.Errorf("error creating a blob:%v", err) } - txResp, err := client.State.SubmitPayForBlob(cmd.Context(), types.NewInt(fee), gasLimit, []*blob.Blob{parsedBlob}) - return printOutput(txResp, err, nil) + txResp, err := client.State.SubmitPayForBlob( + cmd.Context(), + types.NewInt(fee), + gasLimit, + []*blob.Blob{parsedBlob}, + ) + return cmdnode.PrintOutput(txResp, err, nil) }, } @@ -187,10 +202,12 @@ var cancelUnbondingDelegationCmd = &cobra.Command{ Short: "Cancels a user's pending undelegation from a validator.", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() + addr, err := parseAddressFromString(args[0]) if err != nil { return fmt.Errorf("error parsing an address:%v", err) @@ -224,7 +241,7 @@ var cancelUnbondingDelegationCmd = &cobra.Command{ math.NewInt(fee), gasLimit, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -233,10 +250,12 @@ var beginRedelegateCmd = &cobra.Command{ Short: "Sends a user's delegated tokens to a new validator for redelegation", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() + srcAddr, err := parseAddressFromString(args[0]) if err != nil { return fmt.Errorf("error parsing an address:%v", err) @@ -269,7 +288,7 @@ var beginRedelegateCmd = &cobra.Command{ math.NewInt(fee), gasLimit, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -278,10 +297,12 @@ var undelegateCmd = &cobra.Command{ Short: "Undelegates a user's delegated tokens, unbonding them from the current validator.", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() + addr, err := parseAddressFromString(args[0]) if err != nil { return fmt.Errorf("error parsing an address:%v", err) @@ -307,7 +328,7 @@ var undelegateCmd = &cobra.Command{ math.NewInt(fee), gasLimit, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -316,10 +337,11 @@ var delegateCmd = &cobra.Command{ Short: "Sends a user's liquid tokens to a validator for delegation.", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() addr, err := parseAddressFromString(args[0]) if err != nil { @@ -348,7 +370,7 @@ var delegateCmd = &cobra.Command{ math.NewInt(fee), gasLimit, ) - return printOutput(txResponse, err, nil) + return cmdnode.PrintOutput(txResponse, err, nil) }, } @@ -357,10 +379,11 @@ var queryDelegationCmd = &cobra.Command{ Short: "Retrieves the delegation information between a delegator and a validator.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() addr, err := parseAddressFromString(args[0]) if err != nil { @@ -368,9 +391,7 @@ var queryDelegationCmd = &cobra.Command{ } balance, err := client.State.QueryDelegation(cmd.Context(), addr.Address.(state.ValAddress)) - fmt.Println(balance) - fmt.Println(err) - return printOutput(balance, err, nil) + return cmdnode.PrintOutput(balance, err, nil) }, } @@ -379,10 +400,11 @@ var queryUnbondingCmd = &cobra.Command{ Short: "Retrieves the unbonding status between a delegator and a validator.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() addr, err := parseAddressFromString(args[0]) if err != nil { @@ -390,7 +412,7 @@ var queryUnbondingCmd = &cobra.Command{ } response, err := client.State.QueryUnbonding(cmd.Context(), addr.Address.(state.ValAddress)) - return printOutput(response, err, nil) + return cmdnode.PrintOutput(response, err, nil) }, } @@ -399,10 +421,11 @@ var queryRedelegationCmd = &cobra.Command{ Short: "Retrieves the status of the redelegations between a delegator and a validator.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client, err := rpcClient(cmd.Context()) + client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { return err } + defer client.Close() srcAddr, err := parseAddressFromString(args[0]) if err != nil { @@ -419,6 +442,15 @@ var queryRedelegationCmd = &cobra.Command{ srcAddr.Address.(state.ValAddress), dstAddr.Address.(state.ValAddress), ) - return printOutput(response, err, nil) + return cmdnode.PrintOutput(response, err, nil) }, } + +func parseAddressFromString(addrStr string) (state.Address, error) { + var address state.Address + err := address.UnmarshalJSON([]byte(addrStr)) + if err != nil { + return address, err + } + return address, nil +} From f6a1e9d89f21e24cbba48b76f8061f680ac815b5 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Tue, 26 Sep 2023 13:14:16 +0300 Subject: [PATCH 08/11] refactor(rpc/blob) extend docs in blob (#2755) --- nodebuilder/blob/cmd/blob.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/nodebuilder/blob/cmd/blob.go b/nodebuilder/blob/cmd/blob.go index 1c5ec1ad50..f3510edfe1 100644 --- a/nodebuilder/blob/cmd/blob.go +++ b/nodebuilder/blob/cmd/blob.go @@ -41,15 +41,19 @@ func init() { &fee, "fee", -1, - "specifies fee for blob submission", + "specifies fee (in utia) for blob submission.\n"+ + "Fee will be automatically calculated if negative value is passed [optional]", ) submitCmd.PersistentFlags().Uint64Var( &gasLimit, "gas.limit", 0, - "specifies max gas for the blob submission", + "sets the amount of gas that is consumed during blob submission [optional]", ) + + // unset the default value to avoid users confusion + submitCmd.PersistentFlags().Lookup("fee").DefValue = "0" } var Cmd = &cobra.Command{ @@ -126,9 +130,12 @@ var getAllCmd = &cobra.Command{ } var submitCmd = &cobra.Command{ - Use: "submit [namespace] [blobData]", - Args: cobra.ExactArgs(2), - Short: "Submit the blob at the given namespace. Note: only one blob is allowed to submit through the RPC.", + Use: "submit [namespace] [blobData]", + Args: cobra.ExactArgs(2), + Short: "Submit the blob at the given namespace.\n" + + "Note:\n" + + "* only one blob is allowed to submit through the RPC.\n" + + "* fee and gas.limit params will be calculated automatically if they are not provided as arguments", RunE: func(cmd *cobra.Command, args []string) error { client, err := cmdnode.ParseClientFromCtx(cmd.Context()) if err != nil { From f596e11b6f2239dfe16e891850c911f68bc75b13 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 2 Oct 2023 11:41:04 +0300 Subject: [PATCH 09/11] feat(cmd/rpc): add node store flag (#2762) --- cmd/auth.go | 82 +++++++++++++++++++++++---------------------- cmd/celestia/rpc.go | 22 ++++-------- cmd/flags_node.go | 2 +- cmd/rpc.go | 57 +++++++++++++++++++++++++++---- 4 files changed, 101 insertions(+), 62 deletions(-) diff --git a/cmd/auth.go b/cmd/auth.go index eb2000675e..3006526b15 100644 --- a/cmd/auth.go +++ b/cmd/auth.go @@ -25,59 +25,61 @@ func AuthCmd(fsets ...*flag.FlagSet) *cobra.Command { Short: "Signs and outputs a hex-encoded JWT token with the given permissions.", Long: "Signs and outputs a hex-encoded JWT token with the given permissions. NOTE: only use this command when " + "the node has already been initialized and started.", - RunE: newToken, - } + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("must specify permissions") + } + permissions, err := convertToPerms(args[0]) + if err != nil { + return err + } - for _, set := range fsets { - cmd.Flags().AddFlagSet(set) - } - return cmd -} + ks, err := newKeystore(StorePath(cmd.Context())) + if err != nil { + return err -func newToken(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("must specify permissions") - } + } - permissions, err := convertToPerms(args[0]) - if err != nil { - return err - } + key, err := ks.Get(nodemod.SecretName) + if err != nil { + if !errors.Is(err, keystore.ErrNotFound) { + return err + } + key, err = generateNewKey(ks) + if err != nil { + return err + } + } - expanded, err := homedir.Expand(filepath.Clean(StorePath(cmd.Context()))) - if err != nil { - return err - } - ks, err := keystore.NewFSKeystore(filepath.Join(expanded, "keys"), nil) - if err != nil { - return err + token, err := buildJWTToken(key.Body, permissions) + if err != nil { + return err + } + fmt.Printf("%s", token) + return nil + }, } - var key keystore.PrivKey - key, err = ks.Get(nodemod.SecretName) - if err != nil { - if !errors.Is(err, keystore.ErrNotFound) { - return err - } - // otherwise, generate and save new priv key - key, err = generateNewKey(ks) - if err != nil { - return err - } + for _, set := range fsets { + cmd.Flags().AddFlagSet(set) } + return cmd +} - signer, err := jwt.NewHS256(key.Body) +func newKeystore(path string) (keystore.Keystore, error) { + expanded, err := homedir.Expand(filepath.Clean(path)) if err != nil { - return err + return nil, err } + return keystore.NewFSKeystore(filepath.Join(expanded, "keys"), nil) +} - token, err := authtoken.NewSignedJWT(signer, permissions) +func buildJWTToken(body []byte, permissions []auth.Permission) (string, error) { + signer, err := jwt.NewHS256(body) if err != nil { - return err + return "", err } - - fmt.Printf("%s", token) - return nil + return authtoken.NewSignedJWT(signer, permissions) } func generateNewKey(ks keystore.Keystore) (keystore.PrivKey, error) { diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 8cf51fda09..11e96c2e46 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -12,21 +12,13 @@ import ( ) func init() { - blob.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - das.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - header.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - p2p.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - share.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - state.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - node.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - - blob.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - das.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - header.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - p2p.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - share.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - state.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - node.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + blob.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + das.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + header.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + p2p.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + share.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + state.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + node.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) rootCmd.AddCommand( blob.Cmd, diff --git a/cmd/flags_node.go b/cmd/flags_node.go index 8c73a06169..fe4981b6c6 100644 --- a/cmd/flags_node.go +++ b/cmd/flags_node.go @@ -15,7 +15,7 @@ import ( "github.com/celestiaorg/celestia-node/nodebuilder/p2p" ) -var ( +const ( nodeStoreFlag = "node.store" nodeConfigFlag = "node.config" ) diff --git a/cmd/rpc.go b/cmd/rpc.go index 513967f0ed..7ea0173795 100644 --- a/cmd/rpc.go +++ b/cmd/rpc.go @@ -3,11 +3,15 @@ package cmd import ( "context" "errors" + "fmt" "os" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" rpc "github.com/celestiaorg/celestia-node/api/rpc/client" + "github.com/celestiaorg/celestia-node/api/rpc/perms" + nodemod "github.com/celestiaorg/celestia-node/nodebuilder/node" ) const ( @@ -21,15 +25,26 @@ var ( authTokenFlag string ) -func InitURLFlag() (*string, string, string, string) { - return &requestURL, "url", defaultRPCAddress, "Request URL" -} +func RPCFlags() *flag.FlagSet { + fset := &flag.FlagSet{} + + fset.StringVar( + &requestURL, + "url", + defaultRPCAddress, + "Request URL", + ) -func InitAuthTokenFlag() (*string, string, string, string) { - return &authTokenFlag, + fset.StringVar( + &authTokenFlag, "token", "", - "Authorization token (if not provided, the " + authEnvKey + " environment variable will be used)" + "Authorization token (if not provided, the "+authEnvKey+" environment variable will be used)", + ) + + storeFlag := NodeFlags().Lookup(nodeStoreFlag) + fset.AddFlag(storeFlag) + return fset } func InitClient(cmd *cobra.Command, _ []string) error { @@ -37,6 +52,18 @@ func InitClient(cmd *cobra.Command, _ []string) error { authTokenFlag = os.Getenv(authEnvKey) } + if authTokenFlag == "" { + storePath := "" + if cmd.Flag(nodeStoreFlag).Changed { + storePath = cmd.Flag(nodeStoreFlag).Value.String() + } + token, err := getToken(storePath) + if err != nil { + return fmt.Errorf("cant get the access to the auth token: %v", err) + } + authTokenFlag = token + } + client, err := rpc.NewClient(cmd.Context(), requestURL, authTokenFlag) if err != nil { return err @@ -47,6 +74,24 @@ func InitClient(cmd *cobra.Command, _ []string) error { return nil } +func getToken(path string) (string, error) { + if path == "" { + return "", errors.New("root directory was not specified") + } + + ks, err := newKeystore(path) + if err != nil { + return "", err + } + + key, err := ks.Get(nodemod.SecretName) + if err != nil { + fmt.Printf("error getting the JWT secret: %v", err) + return "", err + } + return buildJWTToken(key.Body, perms.AllPerms) +} + type rpcClientKey struct{} func ParseClientFromCtx(ctx context.Context) (*rpc.Client, error) { From 76ced90ff430cc3bb6d1372de0bb775ab9993421 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 2 Oct 2023 11:47:44 +0300 Subject: [PATCH 10/11] refactor(gateway): remove deprecated endpoints (#2764) --- api/gateway/das.go | 28 ---- api/gateway/endpoints.go | 23 +-- api/gateway/state.go | 209 +++------------------------- api/gateway/state_test.go | 57 -------- nodebuilder/gateway/config.go | 7 +- nodebuilder/gateway/constructors.go | 3 +- nodebuilder/gateway/flags.go | 16 +-- nodebuilder/gateway/module.go | 3 +- nodebuilder/state/cmd/state.go | 44 ------ 9 files changed, 27 insertions(+), 363 deletions(-) delete mode 100644 api/gateway/das.go delete mode 100644 api/gateway/state_test.go diff --git a/api/gateway/das.go b/api/gateway/das.go deleted file mode 100644 index 88dc97927c..0000000000 --- a/api/gateway/das.go +++ /dev/null @@ -1,28 +0,0 @@ -package gateway - -import ( - "encoding/json" - "net/http" -) - -const ( - dasStateEndpoint = "/daser/state" -) - -func (h *Handler) handleDASStateRequest(w http.ResponseWriter, r *http.Request) { - logDeprecation(dasStateEndpoint, "das.SamplingStats") - stats, err := h.das.SamplingStats(r.Context()) - if err != nil { - writeError(w, http.StatusInternalServerError, dasStateEndpoint, err) - return - } - resp, err := json.Marshal(stats) - if err != nil { - writeError(w, http.StatusInternalServerError, dasStateEndpoint, err) - return - } - _, err = w.Write(resp) - if err != nil { - log.Errorw("serving request", "endpoint", dasStateEndpoint, "err", err) - } -} diff --git a/api/gateway/endpoints.go b/api/gateway/endpoints.go index 9600138909..104d01b053 100644 --- a/api/gateway/endpoints.go +++ b/api/gateway/endpoints.go @@ -5,28 +5,7 @@ import ( "net/http" ) -func (h *Handler) RegisterEndpoints(rpc *Server, deprecatedEndpointsEnabled bool) { - if deprecatedEndpointsEnabled { - log.Warn("Deprecated endpoints will be removed from the gateway in the next release. Use the RPC instead.") - // state endpoints - rpc.RegisterHandlerFunc(balanceEndpoint, h.handleBalanceRequest, http.MethodGet) - rpc.RegisterHandlerFunc(submitPFBEndpoint, h.handleSubmitPFB, http.MethodPost) - - // staking queries - rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}", queryDelegationEndpoint, addrKey), h.handleQueryDelegation, - http.MethodGet) - rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}", queryUnbondingEndpoint, addrKey), h.handleQueryUnbonding, - http.MethodGet) - rpc.RegisterHandlerFunc(queryRedelegationsEndpoint, h.handleQueryRedelegations, - http.MethodPost) - - // DASer endpoints - // only register if DASer service is available - if h.das != nil { - rpc.RegisterHandlerFunc(dasStateEndpoint, h.handleDASStateRequest, http.MethodGet) - } - } - +func (h *Handler) RegisterEndpoints(rpc *Server) { // state endpoints rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}", balanceEndpoint, addrKey), h.handleBalanceRequest, http.MethodGet) diff --git a/api/gateway/state.go b/api/gateway/state.go index 69900b0bfc..13cf729cc6 100644 --- a/api/gateway/state.go +++ b/api/gateway/state.go @@ -9,17 +9,12 @@ import ( "github.com/cosmos/cosmos-sdk/types" "github.com/gorilla/mux" - "github.com/celestiaorg/celestia-node/blob" "github.com/celestiaorg/celestia-node/state" ) const ( - balanceEndpoint = "/balance" - submitTxEndpoint = "/submit_tx" - submitPFBEndpoint = "/submit_pfb" - queryDelegationEndpoint = "/query_delegation" - queryUnbondingEndpoint = "/query_unbonding" - queryRedelegationsEndpoint = "/query_redelegations" + balanceEndpoint = "/balance" + submitTxEndpoint = "/submit_tx" ) const addrKey = "address" @@ -34,21 +29,6 @@ type submitTxRequest struct { Tx string `json:"tx"` } -// submitPFBRequest represents a request to submit a PayForBlob -// transaction. -type submitPFBRequest struct { - NamespaceID string `json:"namespace_id"` - Data string `json:"data"` - Fee int64 `json:"fee"` - GasLimit uint64 `json:"gas_limit"` -} - -// queryRedelegationsRequest represents a request to query redelegations -type queryRedelegationsRequest struct { - From string `json:"from"` - To string `json:"to"` -} - func (h *Handler) handleBalanceRequest(w http.ResponseWriter, r *http.Request) { var ( bal *state.Balance @@ -57,24 +37,25 @@ func (h *Handler) handleBalanceRequest(w http.ResponseWriter, r *http.Request) { // read and parse request vars := mux.Vars(r) addrStr, exists := vars[addrKey] - if exists { - // convert address to Address type - var addr state.AccAddress - addr, err = types.AccAddressFromBech32(addrStr) + if !exists { + writeError(w, http.StatusBadRequest, balanceEndpoint, errors.New("balance endpoint requires address")) + return + } + + // convert address to Address type + var addr state.AccAddress + addr, err = types.AccAddressFromBech32(addrStr) + if err != nil { + // first check if it is a validator address and can be converted + valAddr, err := types.ValAddressFromBech32(addrStr) if err != nil { - // first check if it is a validator address and can be converted - valAddr, err := types.ValAddressFromBech32(addrStr) - if err != nil { - writeError(w, http.StatusBadRequest, balanceEndpoint, ErrInvalidAddressFormat) - return - } - addr = valAddr.Bytes() + writeError(w, http.StatusBadRequest, balanceEndpoint, ErrInvalidAddressFormat) + return } - bal, err = h.state.BalanceForAddress(r.Context(), state.Address{Address: addr}) - } else { - logDeprecation(balanceEndpoint, "state.Balance") - bal, err = h.state.Balance(r.Context()) + addr = valAddr.Bytes() } + + bal, err = h.state.BalanceForAddress(r.Context(), state.Address{Address: addr}) if err != nil { writeError(w, http.StatusInternalServerError, balanceEndpoint, err) return @@ -119,157 +100,3 @@ func (h *Handler) handleSubmitTx(w http.ResponseWriter, r *http.Request) { log.Errorw("writing response", "endpoint", submitTxEndpoint, "err", err) } } - -func (h *Handler) handleSubmitPFB(w http.ResponseWriter, r *http.Request) { - logDeprecation(submitPFBEndpoint, "blob.Submit or state.SubmitPayForBlob") - // decode request - var req submitPFBRequest - err := json.NewDecoder(r.Body).Decode(&req) - if err != nil { - writeError(w, http.StatusBadRequest, submitPFBEndpoint, err) - return - } - namespace, err := hex.DecodeString(req.NamespaceID) - if err != nil { - writeError(w, http.StatusBadRequest, submitPFBEndpoint, err) - return - } - data, err := hex.DecodeString(req.Data) - if err != nil { - writeError(w, http.StatusBadRequest, submitPFBEndpoint, err) - return - } - fee := types.NewInt(req.Fee) - - constructedBlob, err := blob.NewBlobV0(namespace, data) - if err != nil { - writeError(w, http.StatusBadRequest, submitPFBEndpoint, err) - return - } - - // perform request - txResp, err := h.state.SubmitPayForBlob(r.Context(), fee, req.GasLimit, []*blob.Blob{constructedBlob}) - if err != nil { - if txResp == nil { - // no tx data to return - writeError(w, http.StatusBadRequest, submitPFBEndpoint, err) - return - } - // if error returned, change status from 200 to 206 - w.WriteHeader(http.StatusPartialContent) - } - - bs, err := json.Marshal(&txResp) - if err != nil { - writeError(w, http.StatusInternalServerError, submitPFBEndpoint, err) - return - } - - _, err = w.Write(bs) - if err != nil { - log.Errorw("writing response", "endpoint", submitPFBEndpoint, "err", err) - } -} - -func (h *Handler) handleQueryDelegation(w http.ResponseWriter, r *http.Request) { - logDeprecation(queryDelegationEndpoint, "state.QueryDelegation") - // read and parse request - vars := mux.Vars(r) - addrStr, exists := vars[addrKey] - if !exists { - writeError(w, http.StatusBadRequest, queryDelegationEndpoint, ErrMissingAddress) - return - } - - // convert address to Address type - addr, err := types.ValAddressFromBech32(addrStr) - if err != nil { - writeError(w, http.StatusBadRequest, queryDelegationEndpoint, err) - return - } - delegation, err := h.state.QueryDelegation(r.Context(), addr) - if err != nil { - writeError(w, http.StatusInternalServerError, queryDelegationEndpoint, err) - return - } - resp, err := json.Marshal(delegation) - if err != nil { - writeError(w, http.StatusInternalServerError, queryDelegationEndpoint, err) - return - } - _, err = w.Write(resp) - if err != nil { - log.Errorw("writing response", "endpoint", queryDelegationEndpoint, "err", err) - } -} - -func (h *Handler) handleQueryUnbonding(w http.ResponseWriter, r *http.Request) { - logDeprecation(queryUnbondingEndpoint, "state.QueryUnbonding") - // read and parse request - vars := mux.Vars(r) - addrStr, exists := vars[addrKey] - if !exists { - writeError(w, http.StatusBadRequest, queryUnbondingEndpoint, ErrMissingAddress) - return - } - - // convert address to Address type - addr, err := types.ValAddressFromBech32(addrStr) - if err != nil { - writeError(w, http.StatusBadRequest, queryUnbondingEndpoint, err) - return - } - unbonding, err := h.state.QueryUnbonding(r.Context(), addr) - if err != nil { - writeError(w, http.StatusInternalServerError, queryUnbondingEndpoint, err) - return - } - resp, err := json.Marshal(unbonding) - if err != nil { - writeError(w, http.StatusInternalServerError, queryUnbondingEndpoint, err) - return - } - _, err = w.Write(resp) - if err != nil { - log.Errorw("writing response", "endpoint", queryUnbondingEndpoint, "err", err) - } -} - -func (h *Handler) handleQueryRedelegations(w http.ResponseWriter, r *http.Request) { - logDeprecation(queryRedelegationsEndpoint, "state.QueryRedelegations") - var req queryRedelegationsRequest - err := json.NewDecoder(r.Body).Decode(&req) - if err != nil { - writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err) - return - } - srcValAddr, err := types.ValAddressFromBech32(req.From) - if err != nil { - writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err) - return - } - dstValAddr, err := types.ValAddressFromBech32(req.To) - if err != nil { - writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err) - return - } - unbonding, err := h.state.QueryRedelegations(r.Context(), srcValAddr, dstValAddr) - if err != nil { - writeError(w, http.StatusInternalServerError, queryRedelegationsEndpoint, err) - return - } - resp, err := json.Marshal(unbonding) - if err != nil { - writeError(w, http.StatusInternalServerError, queryRedelegationsEndpoint, err) - return - } - _, err = w.Write(resp) - if err != nil { - log.Errorw("writing response", "endpoint", queryRedelegationsEndpoint, "err", err) - } -} - -func logDeprecation(endpoint string, alternative string) { - log.Warn("The " + endpoint + " endpoint is deprecated and will be removed in the next release. Please " + - "use " + alternative + " from the RPC instead.") -} diff --git a/api/gateway/state_test.go b/api/gateway/state_test.go deleted file mode 100644 index aa9196cc8d..0000000000 --- a/api/gateway/state_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package gateway - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "errors" - "net/http" - "net/http/httptest" - "testing" - - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" - - stateMock "github.com/celestiaorg/celestia-node/nodebuilder/state/mocks" - "github.com/celestiaorg/celestia-node/share" - "github.com/celestiaorg/celestia-node/state" -) - -func TestHandleSubmitPFB(t *testing.T) { - ctrl := gomock.NewController(t) - mock := stateMock.NewMockModule(ctrl) - handler := NewHandler(mock, nil, nil, nil) - - t.Run("partial response", func(t *testing.T) { - txResponse := state.TxResponse{ - Height: 1, - TxHash: "hash", - Codespace: "codespace", - Code: 1, - } - // simulate core-app err, since it is not exported - timedErr := errors.New("timed out waiting for tx to be included in a block") - mock.EXPECT().SubmitPayForBlob(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&txResponse, timedErr) - - ns, err := share.NewBlobNamespaceV0([]byte("abc")) - require.NoError(t, err) - hexNs := hex.EncodeToString(ns[:]) - - bs, err := json.Marshal(submitPFBRequest{ - NamespaceID: hexNs, - Data: "DEADBEEF", - }) - require.NoError(t, err) - httpreq := httptest.NewRequest("GET", "/", bytes.NewReader(bs)) - respRec := httptest.NewRecorder() - handler.handleSubmitPFB(respRec, httpreq) - - var resp state.TxResponse - err = json.NewDecoder(respRec.Body).Decode(&resp) - require.NoError(t, err) - - require.Equal(t, http.StatusPartialContent, respRec.Code) - require.Equal(t, resp, txResponse) - }) -} diff --git a/nodebuilder/gateway/config.go b/nodebuilder/gateway/config.go index f85f207ceb..903a27489a 100644 --- a/nodebuilder/gateway/config.go +++ b/nodebuilder/gateway/config.go @@ -8,10 +8,9 @@ import ( ) type Config struct { - Address string - Port string - Enabled bool - deprecatedEndpoints bool + Address string + Port string + Enabled bool } func DefaultConfig() Config { diff --git a/nodebuilder/gateway/constructors.go b/nodebuilder/gateway/constructors.go index c771c12023..c28153b0a5 100644 --- a/nodebuilder/gateway/constructors.go +++ b/nodebuilder/gateway/constructors.go @@ -10,7 +10,6 @@ import ( // Handler constructs a new RPC Handler from the given services. func Handler( - cfg *Config, state state.Module, share share.Module, header header.Module, @@ -18,7 +17,7 @@ func Handler( serv *gateway.Server, ) { handler := gateway.NewHandler(state, share, header, daser) - handler.RegisterEndpoints(serv, cfg.deprecatedEndpoints) + handler.RegisterEndpoints(serv) handler.RegisterMiddleware(serv) } diff --git a/nodebuilder/gateway/flags.go b/nodebuilder/gateway/flags.go index 4d72a278e5..cd13e47162 100644 --- a/nodebuilder/gateway/flags.go +++ b/nodebuilder/gateway/flags.go @@ -6,10 +6,9 @@ import ( ) var ( - enabledFlag = "gateway" - addrFlag = "gateway.addr" - portFlag = "gateway.port" - deprecatedEndpoints = "gateway.deprecated-endpoints" + enabledFlag = "gateway" + addrFlag = "gateway.addr" + portFlag = "gateway.port" ) // Flags gives a set of hardcoded node/gateway package flags. @@ -21,11 +20,6 @@ func Flags() *flag.FlagSet { false, "Enables the REST gateway", ) - flags.Bool( - deprecatedEndpoints, - false, - "Enables deprecated endpoints on the gateway. These will be removed in the next release.", - ) flags.String( addrFlag, "", @@ -46,10 +40,6 @@ func ParseFlags(cmd *cobra.Command, cfg *Config) { if cmd.Flags().Changed(enabledFlag) && err == nil { cfg.Enabled = enabled } - deprecatedEndpointsEnabled, err := cmd.Flags().GetBool(deprecatedEndpoints) - if cmd.Flags().Changed(deprecatedEndpoints) && err == nil { - cfg.deprecatedEndpoints = deprecatedEndpointsEnabled - } addr, port := cmd.Flag(addrFlag), cmd.Flag(portFlag) if !cfg.Enabled && (addr.Changed || port.Changed) { log.Warn("custom address or port provided without enabling gateway, setting config values") diff --git a/nodebuilder/gateway/module.go b/nodebuilder/gateway/module.go index b727f4c04d..4cdf325dc0 100644 --- a/nodebuilder/gateway/module.go +++ b/nodebuilder/gateway/module.go @@ -48,13 +48,12 @@ func ConstructModule(tp node.Type, cfg *Config) fx.Option { "gateway", baseComponents, fx.Invoke(func( - cfg *Config, state stateServ.Module, share shareServ.Module, header headerServ.Module, serv *gateway.Server, ) { - Handler(cfg, state, share, header, nil, serv) + Handler(state, share, header, nil, serv) }), ) default: diff --git a/nodebuilder/state/cmd/state.go b/nodebuilder/state/cmd/state.go index be52b6d26a..d35c4a1b4f 100644 --- a/nodebuilder/state/cmd/state.go +++ b/nodebuilder/state/cmd/state.go @@ -6,10 +6,8 @@ import ( "strconv" "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" - "github.com/celestiaorg/celestia-node/blob" cmdnode "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/state" ) @@ -21,7 +19,6 @@ func init() { balanceForAddressCmd, transferCmd, submitTxCmd, - submitPFBCmd, cancelUnbondingDelegationCmd, beginRedelegateCmd, undelegateCmd, @@ -156,47 +153,6 @@ var submitTxCmd = &cobra.Command{ }, } -var submitPFBCmd = &cobra.Command{ - Use: "submit-pfb [namespace] [data] [fee] [gasLim]", - Short: "Allows to submit PFBs", - Args: cobra.ExactArgs(4), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := cmdnode.ParseClientFromCtx(cmd.Context()) - if err != nil { - return err - } - defer client.Close() - - namespace, err := cmdnode.ParseV0Namespace(args[0]) - if err != nil { - return fmt.Errorf("error parsing a namespace:%v", err) - } - - fee, err := strconv.ParseInt(args[2], 10, 64) - if err != nil { - return fmt.Errorf("error parsing a fee:%v", err) - } - - gasLimit, err := strconv.ParseUint(args[3], 10, 64) - if err != nil { - return fmt.Errorf("error parsing a gasLim:%v", err) - } - - parsedBlob, err := blob.NewBlobV0(namespace, []byte(args[1])) - if err != nil { - return fmt.Errorf("error creating a blob:%v", err) - } - - txResp, err := client.State.SubmitPayForBlob( - cmd.Context(), - types.NewInt(fee), - gasLimit, - []*blob.Blob{parsedBlob}, - ) - return cmdnode.PrintOutput(txResp, err, nil) - }, -} - var cancelUnbondingDelegationCmd = &cobra.Command{ Use: "cancel-unbonding-delegation [address] [amount] [height] [fee] [gasLimit]", Short: "Cancels a user's pending undelegation from a validator.", From 9ef7594c7827cfa53ccabb5ff454fc586eed967c Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Thu, 5 Oct 2023 12:27:57 +0300 Subject: [PATCH 11/11] refactoring(rpc): remove authEnvKey (#2810) ## Overview ## Checklist - [ ] New and updated code has appropriate documentation - [ ] New and updated code has new and/or updated testing - [ ] Required CI checks are passing - [ ] Visual proof for any user facing features like CLI or documentation updates - [ ] Linked issues closed with keywords --- cmd/rpc.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cmd/rpc.go b/cmd/rpc.go index 7ea0173795..62e9fe7923 100644 --- a/cmd/rpc.go +++ b/cmd/rpc.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "os" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -17,7 +16,6 @@ import ( const ( // defaultRPCAddress is a default address to dial to defaultRPCAddress = "http://localhost:26658" - authEnvKey = "CELESTIA_NODE_AUTH_TOKEN" //nolint:gosec ) var ( @@ -39,7 +37,7 @@ func RPCFlags() *flag.FlagSet { &authTokenFlag, "token", "", - "Authorization token (if not provided, the "+authEnvKey+" environment variable will be used)", + "Authorization token", ) storeFlag := NodeFlags().Lookup(nodeStoreFlag) @@ -48,15 +46,12 @@ func RPCFlags() *flag.FlagSet { } func InitClient(cmd *cobra.Command, _ []string) error { - if authTokenFlag == "" { - authTokenFlag = os.Getenv(authEnvKey) - } - if authTokenFlag == "" { storePath := "" - if cmd.Flag(nodeStoreFlag).Changed { - storePath = cmd.Flag(nodeStoreFlag).Value.String() + if !cmd.Flag(nodeStoreFlag).Changed { + return fmt.Errorf("cant get the access to the auth token: token/node-store flag was not specified") } + storePath = cmd.Flag(nodeStoreFlag).Value.String() token, err := getToken(storePath) if err != nil { return fmt.Errorf("cant get the access to the auth token: %v", err)