diff --git a/CHANGELOG.md b/CHANGELOG.md index ad6579950ecd..2f43011619df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +* [#578](https://github.com/provenance-io/cosmos-sdk/pull/578) Add `binary_version` to the `NodeInfo` object returned by status command. * [#577](https://github.com/provenance-io/cosmos-sdk/pull/577) Add an injectable `GetLockedCoinsFn` to the bank module. --- diff --git a/client/grpc/tmservice/service.go b/client/grpc/tmservice/service.go index 9c698c7733bd..e60acbe63fb3 100644 --- a/client/grpc/tmservice/service.go +++ b/client/grpc/tmservice/service.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/rpc" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" qtypes "github.com/cosmos/cosmos-sdk/types/query" @@ -80,7 +79,7 @@ func (s queryServer) GetLatestBlock(ctx context.Context, _ *GetLatestBlockReques // GetBlockByHeight implements ServiceServer.GetBlockByHeight func (s queryServer) GetBlockByHeight(ctx context.Context, req *GetBlockByHeightRequest) (*GetBlockByHeightResponse, error) { - chainHeight, err := rpc.GetChainHeight(s.clientCtx) + chainHeight, err := client.GetChainHeight(s.clientCtx) if err != nil { return nil, err } @@ -130,7 +129,7 @@ func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *GetValida return nil, err } - chainHeight, err := rpc.GetChainHeight(s.clientCtx) + chainHeight, err := client.GetChainHeight(s.clientCtx) if err != nil { return nil, status.Error(codes.Internal, "failed to parse chain height") } @@ -152,7 +151,7 @@ func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *GetValida } func validatorsOutput(ctx context.Context, cctx client.Context, height *int64, page, limit int) (*GetLatestValidatorSetResponse, error) { - vs, err := rpc.GetValidators(ctx, cctx, height, &page, &limit) + vs, err := client.GetValidators(ctx, cctx, height, &page, &limit) if err != nil { return nil, err } diff --git a/client/rpc.go b/client/rpc.go new file mode 100644 index 000000000000..7a54cc3efce2 --- /dev/null +++ b/client/rpc.go @@ -0,0 +1,111 @@ +package client + +import ( + "context" + "fmt" + "strings" + + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + tmtypes "github.com/tendermint/tendermint/types" +) + +// get the current blockchain height +func GetChainHeight(clientCtx Context) (int64, error) { + node, err := clientCtx.GetNode() + if err != nil { + return -1, err + } + + status, err := node.Status(context.Background()) + if err != nil { + return -1, err + } + + height := status.SyncInfo.LatestBlockHeight + return height, nil +} + +// Validator output +type ValidatorOutput struct { + Address sdk.ConsAddress `json:"address"` + PubKey cryptotypes.PubKey `json:"pub_key"` + ProposerPriority int64 `json:"proposer_priority"` + VotingPower int64 `json:"voting_power"` +} + +// Validators at a certain height output in bech32 format +type ResultValidatorsOutput struct { + BlockHeight int64 `json:"block_height"` + Validators []ValidatorOutput `json:"validators"` + Total uint64 `json:"total"` +} + +func (rvo ResultValidatorsOutput) String() string { + var b strings.Builder + + b.WriteString(fmt.Sprintf("block height: %d\n", rvo.BlockHeight)) + b.WriteString(fmt.Sprintf("total count: %d\n", rvo.Total)) + + for _, val := range rvo.Validators { + b.WriteString( + fmt.Sprintf(` + Address: %s + Pubkey: %s + ProposerPriority: %d + VotingPower: %d + `, + val.Address, val.PubKey, val.ProposerPriority, val.VotingPower, + ), + ) + } + + return b.String() +} + +func validatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) { + pk, err := cryptocodec.FromTmPubKeyInterface(validator.PubKey) + if err != nil { + return ValidatorOutput{}, err + } + + return ValidatorOutput{ + Address: sdk.ConsAddress(validator.Address), + PubKey: pk, + ProposerPriority: validator.ProposerPriority, + VotingPower: validator.VotingPower, + }, nil +} + +// GetValidators from client +func GetValidators(ctx context.Context, clientCtx Context, height *int64, page, limit *int) (ResultValidatorsOutput, error) { + // get the node + node, err := clientCtx.GetNode() + if err != nil { + return ResultValidatorsOutput{}, err + } + + validatorsRes, err := node.Validators(ctx, height, page, limit) + if err != nil { + return ResultValidatorsOutput{}, err + } + + total := validatorsRes.Total + if validatorsRes.Total < 0 { + total = 0 + } + out := ResultValidatorsOutput{ + BlockHeight: validatorsRes.BlockHeight, + Validators: make([]ValidatorOutput, len(validatorsRes.Validators)), + Total: uint64(total), + } + for i := 0; i < len(validatorsRes.Validators); i++ { + out.Validators[i], err = validatorOutput(validatorsRes.Validators[i]) + if err != nil { + return out, err + } + } + + return out, nil +} diff --git a/client/rpc/block.go b/client/rpc/block.go index 1594fe9e669e..35aec32f3300 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -69,19 +69,3 @@ func getBlock(clientCtx client.Context, height *int64) ([]byte, error) { return legacy.Cdc.MarshalJSON(res) } - -// get the current blockchain height -func GetChainHeight(clientCtx client.Context) (int64, error) { - node, err := clientCtx.GetNode() - if err != nil { - return -1, err - } - - status, err := node.Status(context.Background()) - if err != nil { - return -1, err - } - - height := status.SyncInfo.LatestBlockHeight - return height, nil -} diff --git a/client/rpc/rpc_test.go b/client/rpc/rpc_test.go index 0b649b34d4fb..c52adb9211c6 100644 --- a/client/rpc/rpc_test.go +++ b/client/rpc/rpc_test.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" + "github.com/cosmos/cosmos-sdk/version" ) type IntegrationTestSuite struct { @@ -41,6 +42,9 @@ func (s *IntegrationTestSuite) TestStatusCommand() { // Make sure the output has the validator moniker. s.Require().Contains(out.String(), fmt.Sprintf("\"moniker\":\"%s\"", val0.Moniker)) + + // Make sure the output has the binary name. + s.Require().Contains(out.String(), fmt.Sprintf("\"binary_version\":\"%s\"", version.NewInfo().Version)) } func TestIntegrationTestSuite(t *testing.T) { diff --git a/client/rpc/status.go b/client/rpc/status.go index 312989554dca..be6702262f0f 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -5,6 +5,7 @@ import ( "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/p2p" coretypes "github.com/tendermint/tendermint/rpc/core/types" @@ -26,11 +27,23 @@ type validatorInfo struct { // ResultStatus is node's info, same as Tendermint, except that we use our own // PubKey. type resultStatus struct { - NodeInfo p2p.DefaultNodeInfo + NodeInfo nodeInfo SyncInfo coretypes.SyncInfo ValidatorInfo validatorInfo } +type nodeInfo struct { + ProtocolVersion p2p.ProtocolVersion `json:"protocol_version"` + DefaultNodeID p2p.ID `json:"default_node_id,omitempty"` + ListenAddr string `json:"listen_addr,omitempty"` + Network string `json:"network,omitempty"` + Version string `json:"version,omitempty"` + Channels bytes.HexBytes `json:"channels,omitempty"` + Moniker string `json:"moniker,omitempty"` + Other p2p.DefaultNodeInfoOther `json:"other"` + BinaryVersion string `json:"binary_version"` +} + // StatusCommand returns the command to return the status of the network. func StatusCommand() *cobra.Command { cmd := &cobra.Command{ @@ -42,6 +55,12 @@ func StatusCommand() *cobra.Command { return err } + queryClient := tmservice.NewServiceClient(clientCtx) + res, err := queryClient.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{}) + if err != nil { + return err + } + status, err := getNodeStatus(clientCtx) if err != nil { return err @@ -52,8 +71,21 @@ func StatusCommand() *cobra.Command { if err != nil { return err } + + infoWithBinary := nodeInfo{ + ProtocolVersion: status.NodeInfo.ProtocolVersion, + DefaultNodeID: status.NodeInfo.DefaultNodeID, + ListenAddr: status.NodeInfo.ListenAddr, + Network: status.NodeInfo.Network, + Version: status.NodeInfo.Version, + Channels: status.NodeInfo.Channels, + Moniker: status.NodeInfo.Moniker, + Other: status.NodeInfo.Other, + BinaryVersion: res.ApplicationVersion.GetVersion(), + } + statusWithPk := resultStatus{ - NodeInfo: status.NodeInfo, + NodeInfo: infoWithBinary, SyncInfo: status.SyncInfo, ValidatorInfo: validatorInfo{ Address: status.ValidatorInfo.Address, diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 1fb7e796d2e6..4a8912036541 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -1,20 +1,13 @@ package rpc import ( - "context" - "fmt" "strconv" - "strings" "github.com/spf13/cobra" tmcli "github.com/tendermint/tendermint/libs/cli" - tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" ) @@ -49,7 +42,7 @@ func ValidatorCommand() *cobra.Command { page, _ := cmd.Flags().GetInt(flags.FlagPage) limit, _ := cmd.Flags().GetInt(flags.FlagLimit) - result, err := GetValidators(cmd.Context(), clientCtx, height, &page, &limit) + result, err := client.GetValidators(cmd.Context(), clientCtx, height, &page, &limit) if err != nil { return err } @@ -65,86 +58,3 @@ func ValidatorCommand() *cobra.Command { return cmd } - -// Validator output -type ValidatorOutput struct { - Address sdk.ConsAddress `json:"address"` - PubKey cryptotypes.PubKey `json:"pub_key"` - ProposerPriority int64 `json:"proposer_priority"` - VotingPower int64 `json:"voting_power"` -} - -// Validators at a certain height output in bech32 format -type ResultValidatorsOutput struct { - BlockHeight int64 `json:"block_height"` - Validators []ValidatorOutput `json:"validators"` - Total uint64 `json:"total"` -} - -func (rvo ResultValidatorsOutput) String() string { - var b strings.Builder - - b.WriteString(fmt.Sprintf("block height: %d\n", rvo.BlockHeight)) - b.WriteString(fmt.Sprintf("total count: %d\n", rvo.Total)) - - for _, val := range rvo.Validators { - b.WriteString( - fmt.Sprintf(` - Address: %s - Pubkey: %s - ProposerPriority: %d - VotingPower: %d - `, - val.Address, val.PubKey, val.ProposerPriority, val.VotingPower, - ), - ) - } - - return b.String() -} - -func validatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) { - pk, err := cryptocodec.FromTmPubKeyInterface(validator.PubKey) - if err != nil { - return ValidatorOutput{}, err - } - - return ValidatorOutput{ - Address: sdk.ConsAddress(validator.Address), - PubKey: pk, - ProposerPriority: validator.ProposerPriority, - VotingPower: validator.VotingPower, - }, nil -} - -// GetValidators from client -func GetValidators(ctx context.Context, clientCtx client.Context, height *int64, page, limit *int) (ResultValidatorsOutput, error) { - // get the node - node, err := clientCtx.GetNode() - if err != nil { - return ResultValidatorsOutput{}, err - } - - validatorsRes, err := node.Validators(ctx, height, page, limit) - if err != nil { - return ResultValidatorsOutput{}, err - } - - total := validatorsRes.Total - if validatorsRes.Total < 0 { - total = 0 - } - out := ResultValidatorsOutput{ - BlockHeight: validatorsRes.BlockHeight, - Validators: make([]ValidatorOutput, len(validatorsRes.Validators)), - Total: uint64(total), - } - for i := 0; i < len(validatorsRes.Validators); i++ { - out.Validators[i], err = validatorOutput(validatorsRes.Validators[i]) - if err != nil { - return out, err - } - } - - return out, nil -}