From 403a39e139a8cf3feccb666d777a368eb32ff25a Mon Sep 17 00:00:00 2001 From: Evan Forbes <42654277+evan-forbes@users.noreply.github.com> Date: Thu, 5 Oct 2023 07:21:24 -0500 Subject: [PATCH 01/13] chore: bump celestia-app, celestia-core, and the cosmos-sdk (#2801) bumps app, core, and the sdk. leaving as a draft for now since we still have to cut the official app version after we get enough approves. The review process can start for this tho --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index bcd7f2aab4..702d964619 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/BurntSushi/toml v1.3.2 github.com/alecthomas/jsonschema v0.0.0-20220216202328-9eeeec9d044b github.com/benbjohnson/clock v1.3.5 - github.com/celestiaorg/celestia-app v1.0.0-rc17 + github.com/celestiaorg/celestia-app v1.0.0-rc18 github.com/celestiaorg/go-ds-badger4 v0.0.0-20230712104058-7ede1c814ac5 github.com/celestiaorg/go-fraud v0.2.0 github.com/celestiaorg/go-header v0.3.1 @@ -77,7 +77,7 @@ require ( require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/bits-and-blooms/bitset v1.5.0 // indirect - github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.1 // indirect + github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.2 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.10.0 // indirect github.com/crate-crypto/go-kzg-4844 v0.3.0 // indirect @@ -116,7 +116,7 @@ require ( github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect - github.com/confio/ics23/go v0.9.0 // indirect + github.com/confio/ics23/go v0.9.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect @@ -145,7 +145,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/etclabscore/go-jsonschema-walk v0.0.6 // indirect - github.com/ethereum/go-ethereum v1.13.1 // indirect + github.com/ethereum/go-ethereum v1.13.2 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -343,10 +343,10 @@ require ( ) replace ( - github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14 + github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.18.1-sdk-v0.46.14 github.com/filecoin-project/dagstore => github.com/celestiaorg/dagstore v0.0.0-20230824094345-537c012aa403 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // broken goleveldb needs to be replaced for the cosmos-sdk and celestia-app github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28 + github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.29.0-tm-v0.34.29 ) diff --git a/go.sum b/go.sum index 236dd50f4f..0ee3078273 100644 --- a/go.sum +++ b/go.sum @@ -358,12 +358,12 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7 github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/celestiaorg/celestia-app v1.0.0-rc17 h1:ak9OIViNJCfDFklopPgxnjRqUx5oKPcctpGpmwmqJy4= -github.com/celestiaorg/celestia-app v1.0.0-rc17/go.mod h1:gDKOpD8xCWHw/PUdcTc0WFYf52Mq0etOFZ1oTkBlFkQ= -github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28 h1:BE7JFZ1SYpwM9OfL9cPcjlO5xjIbDPgdFkJNouyl6jA= -github.com/celestiaorg/celestia-core v1.27.0-tm-v0.34.28/go.mod h1:1GT0RfdNqOXvyR3Hq4ROcNBknQNz9E6K5l3Cla9eFFk= -github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14 h1:dDfoQJOlVNj4HufJ1lBLTo2k3/L/255MIiKmEQziDmw= -github.com/celestiaorg/cosmos-sdk v1.18.0-sdk-v0.46.14/go.mod h1:kkdiHo/zG6ar80730+bG1owdMAQXrGp4utFu7mbfADo= +github.com/celestiaorg/celestia-app v1.0.0-rc18 h1:d2+KYPr4ri10aOtnXih3hOUd6ap94c/Hv46JFzpWzy0= +github.com/celestiaorg/celestia-app v1.0.0-rc18/go.mod h1:Q375ijriqMv8PjKmMujNs2WzMAsgxjpbeUoQt+AZre0= +github.com/celestiaorg/celestia-core v1.29.0-tm-v0.34.29 h1:Fd7ymPUzExPGNl2gZw4i5S74arMw+iDHLE78M/cCxl4= +github.com/celestiaorg/celestia-core v1.29.0-tm-v0.34.29/go.mod h1:xrICN0PBhp3AdTaZ8q4wS5Jvi32V02HNjaC2EsWiEKk= +github.com/celestiaorg/cosmos-sdk v1.18.1-sdk-v0.46.14 h1:c4cMVLU2bGTesZW1ZVgeoCB++gOOJTF3OvBsqBvo6n0= +github.com/celestiaorg/cosmos-sdk v1.18.1-sdk-v0.46.14/go.mod h1:D5y5Exw0bJkcDv9fvYDiZfZrDV1b6+xsFyiungxrCsU= github.com/celestiaorg/dagstore v0.0.0-20230824094345-537c012aa403 h1:Lj73O3S+KJx5/hgZ+IeOLEIoLsAveJN/7/ZtQQtPSVw= github.com/celestiaorg/dagstore v0.0.0-20230824094345-537c012aa403/go.mod h1:cCGM1UoMvyTk8k62mkc+ReVu8iHBCtSBAAL4wYU7KEI= github.com/celestiaorg/go-ds-badger4 v0.0.0-20230712104058-7ede1c814ac5 h1:MJgXvhJP1Au8rXTvMMlBXodu9jplEK1DxiLtMnEphOs= @@ -378,8 +378,8 @@ github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 h1:CJdIpo8n github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4/go.mod h1:fzuHnhzj1pUygGz+1ZkB3uQbEUL4htqCGJ4Qs2LwMZA= github.com/celestiaorg/nmt v0.20.0 h1:9i7ultZ8Wv5ytt8ZRaxKQ5KOOMo4A2K2T/aPGjIlSas= github.com/celestiaorg/nmt v0.20.0/go.mod h1:Oz15Ub6YPez9uJV0heoU4WpFctxazuIhKyUtaYNio7E= -github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.1 h1:xOBMoRYSh/hnsEW7OLI3bjSJXKlqILfZehjPEK/+3oI= -github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.1/go.mod h1:NziNBP12grIi+DH3TqIKUUPM2T6Hl9BTyxiK3+p8yeA= +github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.2 h1:Q8nr5SAtDW5gocrBwqwDJcSS/JedqU58WwQA2SP+nXw= +github.com/celestiaorg/quantum-gravity-bridge/v2 v2.1.2/go.mod h1:s/LzLUw0WeYPJ6qdk4q46jKLOq7rc9Z5Mdrxtfpcigw= github.com/celestiaorg/rsmt2d v0.11.0 h1:lcto/637WyTEZR3dLRoNvyuExfnUbxvdvKi3qz/2V4k= github.com/celestiaorg/rsmt2d v0.11.0/go.mod h1:6Y580I3gVr0+OVFfW6m2JTwnCCmvW3WfbwSLfuT+HCA= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -446,8 +446,8 @@ github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZ github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= -github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= -github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/confio/ics23/go v0.9.1 h1:3MV46eeWwO3xCauKyAtuAdJYMyPnnchW4iLr2bTw6/U= +github.com/confio/ics23/go v0.9.1/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -606,8 +606,8 @@ github.com/etclabscore/go-openrpc-reflect v0.0.37/go.mod h1:0404Ky3igAasAOpyj1eE github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/ethereum/go-ethereum v1.13.1 h1:UF2FaUKPIy5jeZk3X06ait3y2Q4wI+vJ1l7+UARp+60= -github.com/ethereum/go-ethereum v1.13.1/go.mod h1:xHQKzwkHSl0gnSjZK1mWa06XEdm9685AHqhRknOzqGQ= +github.com/ethereum/go-ethereum v1.13.2 h1:g9mCpfPWqCA1OL4e6C98PeVttb0HadfBRuKTGvMnOvw= +github.com/ethereum/go-ethereum v1.13.2/go.mod h1:gkQ5Ygi64ZBh9M/4iXY1R8WqoNCx1Ey0CkYn2BD4/fw= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= From e6e840225c1b71d8dacf1150938364671bdb7858 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 4 Sep 2023 16:21:00 +0300 Subject: [PATCH 02/13] 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 03/13] 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 04/13] 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 05/13] 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 06/13] 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 07/13] 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 08/13] 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 09/13] 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 10/13] 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 11/13] 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 12/13] 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) From e6a69829c1883c32eab96ca8e1dd9e0aa99a4bd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:27:04 +0300 Subject: [PATCH 13/13] chore(deps): Bump the otel group with 2 updates (#2800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the otel group with 2 updates: [go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp](https://github.com/open-telemetry/opentelemetry-go) and [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp](https://github.com/open-telemetry/opentelemetry-go). Updates `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` from 0.41.0 to 0.42.0
Release notes

Sourced from go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp's releases.

Release v1.19.0/v0.42.0/v0.0.7

This release contains the first stable release of the OpenTelemetry Go metric SDK. Our project stability guarantees now apply to the go.opentelemetry.io/otel/sdk/metric package. See our versioning policy for more information about these stability guarantees.

Added

  • Add the "Roll the dice" getting started application example in go.opentelemetry.io/otel/example/dice. (#4539)
  • The WithWriter and WithPrettyPrint options to go.opentelemetry.io/otel/exporters/stdout/stdoutmetric to set a custom io.Writer, and allow displaying the output in human-readable JSON. (#4507)

Changed

  • Allow '/' characters in metric instrument names. (#4501)
  • The exporter in go.opentelemetry.io/otel/exporters/stdout/stdoutmetric does not prettify its output by default anymore. (#4507)
  • Upgrade gopkg.io/yaml from v2 to v3 in go.opentelemetry.io/otel/schema. (#4535)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the Prometheus metric on every Collect if we know the scope is invalid. (#4499)

Removed

  • Remove "go.opentelemetry.io/otel/bridge/opencensus".NewMetricExporter, which is replaced by NewMetricProducer. (#4566)

Full Changelog: https://github.com/open-telemetry/opentelemetry-go/compare/v1.18.0...v1.19.0

Release v1.19.0-rc.1/v0.42.0-rc.1

This is a release candidate for the v1.19.0/v0.42.0 release. That release is expected to include the v1 release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK. See our versioning policy for more information about these stability guarantees.

Changed

  • Allow '/' characters in metric instrument names. (#4501)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the Prometheus metric on every Collect if we know the scope is invalid. (#4499)

New Contributors

Full Changelog: https://github.com/open-telemetry/opentelemetry-go/compare/v1.18.0...v1.19.0-rc.1

Release v1.18.0/v0.41.0/v0.0.6

This release drops the compatibility guarantee of [Go 1.19].

Added

  • Add WithProducer option in go.opentelemetry.op/otel/exporters/prometheus to restore the ability to register producers on the prometheus exporter's manual reader. (#4473)
  • Add IgnoreValue option in go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest to allow ignoring values when comparing metrics. (#4447)

... (truncated)

Changelog

Sourced from go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp's changelog.

[1.19.0/0.42.0/0.0.7] 2023-09-28

This release contains the first stable release of the OpenTelemetry Go [metric SDK]. Our project stability guarantees now apply to the go.opentelemetry.io/otel/sdk/metric package. See our versioning policy for more information about these stability guarantees.

Added

  • Add the "Roll the dice" getting started application example in go.opentelemetry.io/otel/example/dice. (#4539)
  • The WithWriter and WithPrettyPrint options to go.opentelemetry.io/otel/exporters/stdout/stdoutmetric to set a custom io.Writer, and allow displaying the output in human-readable JSON. (#4507)

Changed

  • Allow '/' characters in metric instrument names. (#4501)
  • The exporter in go.opentelemetry.io/otel/exporters/stdout/stdoutmetric does not prettify its output by default anymore. (#4507)
  • Upgrade gopkg.io/yaml from v2 to v3 in go.opentelemetry.io/otel/schema. (#4535)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the Prometheus metric on every Collect if we know the scope is invalid. (#4499)

Removed

  • Remove "go.opentelemetry.io/otel/bridge/opencensus".NewMetricExporter, which is replaced by NewMetricProducer. (#4566)

[1.19.0-rc.1/0.42.0-rc.1] 2023-09-14

This is a release candidate for the v1.19.0/v0.42.0 release. That release is expected to include the v1 release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK. See our versioning policy for more information about these stability guarantees.

Changed

  • Allow '/' characters in metric instrument names. (#4501)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the prometheus metric on every Collect if we know the scope is invalid. (#4499)
Commits

Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` from 1.18.0 to 1.19.0
Changelog

Sourced from go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp's changelog.

[1.19.0/0.42.0/0.0.7] 2023-09-28

This release contains the first stable release of the OpenTelemetry Go [metric SDK]. Our project stability guarantees now apply to the go.opentelemetry.io/otel/sdk/metric package. See our versioning policy for more information about these stability guarantees.

Added

  • Add the "Roll the dice" getting started application example in go.opentelemetry.io/otel/example/dice. (#4539)
  • The WithWriter and WithPrettyPrint options to go.opentelemetry.io/otel/exporters/stdout/stdoutmetric to set a custom io.Writer, and allow displaying the output in human-readable JSON. (#4507)

Changed

  • Allow '/' characters in metric instrument names. (#4501)
  • The exporter in go.opentelemetry.io/otel/exporters/stdout/stdoutmetric does not prettify its output by default anymore. (#4507)
  • Upgrade gopkg.io/yaml from v2 to v3 in go.opentelemetry.io/otel/schema. (#4535)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the Prometheus metric on every Collect if we know the scope is invalid. (#4499)

Removed

  • Remove "go.opentelemetry.io/otel/bridge/opencensus".NewMetricExporter, which is replaced by NewMetricProducer. (#4566)

[1.19.0-rc.1/0.42.0-rc.1] 2023-09-14

This is a release candidate for the v1.19.0/v0.42.0 release. That release is expected to include the v1 release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK. See our versioning policy for more information about these stability guarantees.

Changed

  • Allow '/' characters in metric instrument names. (#4501)

Fixed

  • In go.opentelemetry.op/otel/exporters/prometheus, don't try to create the prometheus metric on every Collect if we know the scope is invalid. (#4499)
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 702d964619..13f218440c 100644 --- a/go.mod +++ b/go.mod @@ -56,12 +56,12 @@ require ( github.com/tendermint/tendermint v0.34.28 go.opentelemetry.io/contrib/instrumentation/runtime v0.44.0 go.opentelemetry.io/otel v1.19.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.41.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.18.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 go.opentelemetry.io/otel/metric v1.19.0 go.opentelemetry.io/otel/sdk v1.19.0 - go.opentelemetry.io/otel/sdk/metric v0.41.0 + go.opentelemetry.io/otel/sdk/metric v1.19.0 go.opentelemetry.io/otel/trace v1.19.0 go.opentelemetry.io/proto/otlp v1.0.0 go.uber.org/fx v1.20.0 @@ -316,7 +316,7 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect diff --git a/go.sum b/go.sum index 0ee3078273..7c1334a343 100644 --- a/go.sum +++ b/go.sum @@ -2384,14 +2384,14 @@ go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+n go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.41.0 h1:k0k7hFNDd8K4iOMJXj7s8sHaC4mhTlAeppRmZXLgZ6k= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.41.0/go.mod h1:hG4Fj/y8TR/tlEDREo8tWstl9fO9gcFkn4xrx0Io8xU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.41.0 h1:iV3BOgW4fry1Riw9dwypigqlIYWXvSRVT2RJmblzo40= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.41.0/go.mod h1:7PGzqlKrxIRmbj5tlNW0nTkYZ5fHXDgk6Fy8/KjR0CI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 h1:ZtfnDL+tUrs1F0Pzfwbg2d59Gru9NCH3bgSHBM6LDwU= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0/go.mod h1:hG4Fj/y8TR/tlEDREo8tWstl9fO9gcFkn4xrx0Io8xU= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 h1:wNMDy/LVGLj2h3p6zg4d0gypKfWKSWI14E1C4smOgl8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0/go.mod h1:YfbDdXAAkemWJK3H/DshvlrxqFB2rtW4rY6ky/3x/H0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.18.0 h1:6pu8ttx76BxHf+xz/H77AUZkPF3cwWzXqAUsXhVKI18= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.18.0/go.mod h1:IOmXxPrxoxFMXdNy7lfDmE8MzE61YPcurbUm0SMjerI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.1 h1:2PunuO5SbkN5MhCbuHCd3tC6qrcaj+uDAkX/qBU5BAs= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.15.1/go.mod h1:q8+Tha+5LThjeSU8BW93uUC5w5/+DnYHMKBMpRCsui0= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= @@ -2401,8 +2401,8 @@ go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/sdk/metric v0.41.0 h1:c3sAt9/pQ5fSIUfl0gPtClV3HhE18DCVzByD33R/zsk= -go.opentelemetry.io/otel/sdk/metric v0.41.0/go.mod h1:PmOmSt+iOklKtIg5O4Vz9H/ttcRFSNTgii+E1KGyn1w= +go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8Ni+hx+8i1k= +go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=