Skip to content

Commit

Permalink
Merge PR #3504: Fix validator address encoding in tm validator set co…
Browse files Browse the repository at this point in the history
…mmand
  • Loading branch information
alexanderbez authored and cwgoes committed Feb 6, 2019
1 parent 52350c5 commit 7173164
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 45 deletions.
2 changes: 2 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ BREAKING CHANGES
- `--insecure` flag is removed.
- `--tls` is now used to enable secure layer.
- [\#3451](https://github.com/cosmos/cosmos-sdk/pull/3451) `gaiacli` now returns transactions in plain text including tags.
* [\#3501](https://github.com/cosmos/cosmos-sdk/issues/3501) Change validator
address Bech32 encoding to consensus address in `tendermint-validator-set`.

* Gaia
* [\#3457](https://github.com/cosmos/cosmos-sdk/issues/3457) Changed governance tally validatorGovInfo to use sdk.Int power instead of sdk.Dec
Expand Down
2 changes: 1 addition & 1 deletion client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func TestValidators(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
resultVals := getValidatorSets(t, port, -1, false)
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvaloper")
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvalcons")
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalconspub")
getValidatorSets(t, port, 2, false)
getValidatorSets(t, port, 10000000, true)
Expand Down
108 changes: 65 additions & 43 deletions client/rpc/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/codec"

"github.com/cosmos/cosmos-sdk/client/rest"

Expand All @@ -22,26 +25,53 @@ import (
// TODO these next two functions feel kinda hacky based on their placement

//ValidatorCommand returns the validator set for a given height
func ValidatorCommand() *cobra.Command {
func ValidatorCommand(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "tendermint-validator-set [height]",
Short: "Get the full tendermint validator set at given height",
Args: cobra.MaximumNArgs(1),
RunE: printValidators,
RunE: func(cmd *cobra.Command, args []string) error {
var height *int64

// optional height
if len(args) > 0 {
h, err := strconv.Atoi(args[0])
if err != nil {
return err
}
if h > 0 {
tmp := int64(h)
height = &tmp
}
}

cliCtx := context.NewCLIContext().WithCodec(cdc)

result, err := getValidators(cliCtx, height)
if err != nil {
return err
}

return cliCtx.PrintOutput(result)
},
}

cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to")
viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode))
cmd.Flags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
viper.BindPFlag(client.FlagTrustNode, cmd.Flags().Lookup(client.FlagTrustNode))
cmd.Flags().Bool(client.FlagIndentResponse, false, "indent JSON response")
viper.BindPFlag(client.FlagIndentResponse, cmd.Flags().Lookup(client.FlagIndentResponse))

return cmd
}

// Validator output in bech32 format
type ValidatorOutput struct {
Address sdk.ValAddress `json:"address"` // in bech32
PubKey string `json:"pub_key"` // in bech32
ProposerPriority int64 `json:"proposer_priority"`
VotingPower int64 `json:"voting_power"`
Address sdk.ConsAddress `json:"address"`
PubKey string `json:"pub_key"`
ProposerPriority int64 `json:"proposer_priority"`
VotingPower int64 `json:"voting_power"`
}

// Validators at a certain height output in bech32 format
Expand All @@ -50,40 +80,61 @@ type ResultValidatorsOutput struct {
Validators []ValidatorOutput `json:"validators"`
}

func (rvo ResultValidatorsOutput) String() string {
var b strings.Builder

b.WriteString(fmt.Sprintf("block height: %d\n", rvo.BlockHeight))

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 bech32ValidatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) {
bechValPubkey, err := sdk.Bech32ifyConsPub(validator.PubKey)
if err != nil {
return ValidatorOutput{}, err
}

return ValidatorOutput{
Address: sdk.ValAddress(validator.Address),
Address: sdk.ConsAddress(validator.Address),
PubKey: bechValPubkey,
ProposerPriority: validator.ProposerPriority,
VotingPower: validator.VotingPower,
}, nil
}

func getValidators(cliCtx context.CLIContext, height *int64) ([]byte, error) {
func getValidators(cliCtx context.CLIContext, height *int64) (ResultValidatorsOutput, error) {
// get the node
node, err := cliCtx.GetNode()
if err != nil {
return nil, err
return ResultValidatorsOutput{}, err
}

validatorsRes, err := node.Validators(height)
if err != nil {
return nil, err
return ResultValidatorsOutput{}, err
}

if !cliCtx.TrustNode {
check, err := cliCtx.Verify(validatorsRes.BlockHeight)
if err != nil {
return nil, err
return ResultValidatorsOutput{}, err
}

if !bytes.Equal(check.ValidatorsHash, tmtypes.NewValidatorSet(validatorsRes.Validators).Hash()) {
return nil, fmt.Errorf("got invalid validatorset")
return ResultValidatorsOutput{}, fmt.Errorf("received invalid validatorset")
}
}

Expand All @@ -95,40 +146,11 @@ func getValidators(cliCtx context.CLIContext, height *int64) ([]byte, error) {
for i := 0; i < len(validatorsRes.Validators); i++ {
outputValidatorsRes.Validators[i], err = bech32ValidatorOutput(validatorsRes.Validators[i])
if err != nil {
return nil, err
}
}

if cliCtx.Indent {
return cdc.MarshalJSONIndent(outputValidatorsRes, "", " ")
}
return cdc.MarshalJSON(outputValidatorsRes)

}

// CMD

func printValidators(cmd *cobra.Command, args []string) error {
var height *int64
// optional height
if len(args) > 0 {
h, err := strconv.Atoi(args[0])
if err != nil {
return err
}
if h > 0 {
tmp := int64(h)
height = &tmp
return ResultValidatorsOutput{}, err
}
}

output, err := getValidators(context.NewCLIContext(), height)
if err != nil {
return err
}

fmt.Println(string(output))
return nil
return outputValidatorsRes, nil
}

// REST
Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/cmd/gaiacli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command {
}

queryCmd.AddCommand(
rpc.ValidatorCommand(),
rpc.ValidatorCommand(cdc),
rpc.BlockCommand(),
tx.SearchTxCmd(cdc),
tx.QueryTxCmd(cdc),
Expand Down

0 comments on commit 7173164

Please sign in to comment.