github.com/Finschia/finschia-sdk@v0.48.1/client/rpc/validators.go (about) 1 package rpc 2 3 import ( 4 "context" 5 "fmt" 6 "strconv" 7 "strings" 8 9 octypes "github.com/Finschia/ostracon/types" 10 "github.com/spf13/cobra" 11 12 "github.com/Finschia/finschia-sdk/client" 13 "github.com/Finschia/finschia-sdk/client/flags" 14 cryptocodec "github.com/Finschia/finschia-sdk/crypto/codec" 15 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 16 sdk "github.com/Finschia/finschia-sdk/types" 17 "github.com/Finschia/finschia-sdk/types/query" 18 ) 19 20 // TODO these next two functions feel kinda hacky based on their placement 21 22 // ValidatorCommand returns the validator set for a given height 23 func ValidatorCommand() *cobra.Command { 24 cmd := &cobra.Command{ 25 Use: "ostracon-validator-set [height]", 26 Short: "Get the full ostracon validator set at given height", 27 Args: cobra.MaximumNArgs(1), 28 RunE: func(cmd *cobra.Command, args []string) error { 29 clientCtx, err := client.GetClientQueryContext(cmd) 30 if err != nil { 31 return err 32 } 33 var height *int64 34 35 // optional height 36 if len(args) > 0 { 37 h, err := strconv.Atoi(args[0]) 38 if err != nil { 39 return err 40 } 41 if h > 0 { 42 tmp := int64(h) 43 height = &tmp 44 } 45 } 46 47 page, _ := cmd.Flags().GetInt(flags.FlagPage) 48 limit, _ := cmd.Flags().GetInt(flags.FlagLimit) 49 50 result, err := GetValidators(cmd.Context(), clientCtx, height, &page, &limit) 51 if err != nil { 52 return err 53 } 54 55 return clientCtx.PrintObjectLegacy(result) 56 }, 57 } 58 59 cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") 60 cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") 61 cmd.Flags().Int(flags.FlagPage, query.DefaultPage, "Query a specific page of paginated results") 62 cmd.Flags().Int(flags.FlagLimit, 100, "Query number of results returned per page") 63 64 return cmd 65 } 66 67 // Validator output 68 type ValidatorOutput struct { 69 Address sdk.ConsAddress `json:"address"` 70 PubKey cryptotypes.PubKey `json:"pub_key"` 71 ProposerPriority int64 `json:"proposer_priority"` 72 VotingPower int64 `json:"voting_power"` 73 } 74 75 // Validators at a certain height output in bech32 format 76 type ResultValidatorsOutput struct { 77 BlockHeight int64 `json:"block_height"` 78 Validators []ValidatorOutput `json:"validators"` 79 Total uint64 `json:"total"` 80 } 81 82 func (rvo ResultValidatorsOutput) String() string { 83 var b strings.Builder 84 85 b.WriteString(fmt.Sprintf("block height: %d\n", rvo.BlockHeight)) 86 b.WriteString(fmt.Sprintf("total count: %d\n", rvo.Total)) 87 88 for _, val := range rvo.Validators { 89 b.WriteString( 90 fmt.Sprintf(` 91 Address: %s 92 Pubkey: %s 93 ProposerPriority: %d 94 VotingPower: %d 95 `, 96 val.Address, val.PubKey, val.ProposerPriority, val.VotingPower, 97 ), 98 ) 99 } 100 101 return b.String() 102 } 103 104 func validatorOutput(validator *octypes.Validator) (ValidatorOutput, error) { 105 pk, err := cryptocodec.FromOcPubKeyInterface(validator.PubKey) 106 if err != nil { 107 return ValidatorOutput{}, err 108 } 109 110 return ValidatorOutput{ 111 Address: sdk.ConsAddress(validator.Address), 112 PubKey: pk, 113 ProposerPriority: validator.ProposerPriority, 114 VotingPower: validator.VotingPower, 115 }, nil 116 } 117 118 // GetValidators from client 119 func GetValidators(ctx context.Context, clientCtx client.Context, height *int64, page, limit *int) (ResultValidatorsOutput, error) { 120 // get the node 121 node, err := clientCtx.GetNode() 122 if err != nil { 123 return ResultValidatorsOutput{}, err 124 } 125 126 validatorsRes, err := node.Validators(ctx, height, page, limit) 127 if err != nil { 128 return ResultValidatorsOutput{}, err 129 } 130 131 total := validatorsRes.Total 132 if validatorsRes.Total < 0 { 133 total = 0 134 } 135 out := ResultValidatorsOutput{ 136 BlockHeight: validatorsRes.BlockHeight, 137 Validators: make([]ValidatorOutput, len(validatorsRes.Validators)), 138 Total: uint64(total), 139 } 140 for i := 0; i < len(validatorsRes.Validators); i++ { 141 out.Validators[i], err = validatorOutput(validatorsRes.Validators[i]) 142 if err != nil { 143 return out, err 144 } 145 } 146 147 return out, nil 148 }