github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/staking/client/cli/query.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
     9  
    10  	"github.com/spf13/cobra"
    11  
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    15  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    17  	"github.com/fibonacci-chain/fbc/x/staking/types"
    18  )
    19  
    20  // GetQueryCmd returns the cli query commands for staking module
    21  func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
    22  	stakingQueryCmd := &cobra.Command{
    23  		Use:                        types.ModuleName,
    24  		Short:                      "Querying commands for the staking module",
    25  		DisableFlagParsing:         true,
    26  		SuggestionsMinimumDistance: 2,
    27  		RunE:                       client.ValidateCmd,
    28  	}
    29  	stakingQueryCmd.AddCommand(flags.GetCommands(
    30  		GetCmdQueryDelegator(queryRoute, cdc),
    31  		GetCmdQueryValidatorShares(queryRoute, cdc),
    32  		GetCmdQueryValidator(queryRoute, cdc),
    33  		GetCmdQueryValidators(queryRoute, cdc),
    34  		GetCmdQueryProxy(queryRoute, cdc),
    35  		GetCmdQueryParams(queryRoute, cdc),
    36  		GetCmdQueryPool(queryRoute, cdc))...)
    37  
    38  	return stakingQueryCmd
    39  
    40  }
    41  
    42  // GetCmdQueryValidator gets the validator query command.
    43  func GetCmdQueryValidator(storeName string, cdc *codec.Codec) *cobra.Command {
    44  	return &cobra.Command{
    45  		Use:   "validator [validator-addr]",
    46  		Short: "query a validator",
    47  		Long: strings.TrimSpace(
    48  			fmt.Sprintf(`Query details about an individual validator.
    49  
    50  Example:
    51  $ %s query staking validator fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg
    52  `,
    53  				version.ClientName,
    54  			),
    55  		),
    56  		Args: cobra.ExactArgs(1),
    57  		RunE: func(cmd *cobra.Command, args []string) error {
    58  			cliCtx := context.NewCLIContext().WithCodec(cdc)
    59  
    60  			addr, err := sdk.ValAddressFromBech32(args[0])
    61  			if err != nil {
    62  				return err
    63  			}
    64  
    65  			res, _, err := cliCtx.QueryStore(types.GetValidatorKey(addr), storeName)
    66  			if err != nil {
    67  				return err
    68  			}
    69  
    70  			if len(res) == 0 {
    71  				return fmt.Errorf("no validator found with address %s", addr)
    72  			}
    73  
    74  			//return cliCtx.PrintOutput(types.MustUnmarshalValidator(cdc, res))
    75  			return cliCtx.PrintOutput(types.MustUnmarshalValidator(cdc, res).Standardize())
    76  		},
    77  	}
    78  }
    79  
    80  // GetCmdQueryValidators gets the query all validators command.
    81  func GetCmdQueryValidators(storeName string, cdc *codec.Codec) *cobra.Command {
    82  	return &cobra.Command{
    83  		Use:   "validators",
    84  		Short: "query for all validators",
    85  		Args:  cobra.NoArgs,
    86  		Long: strings.TrimSpace(
    87  			fmt.Sprintf(`Query details about all validators on a network.
    88  
    89  Example:
    90  $ %s query staking validators
    91  `,
    92  				version.ClientName,
    93  			),
    94  		),
    95  		RunE: func(cmd *cobra.Command, args []string) error {
    96  			cliCtx := context.NewCLIContext().WithCodec(cdc)
    97  
    98  			resKVs, _, err := cliCtx.QuerySubspace(types.ValidatorsKey, storeName)
    99  			if err != nil {
   100  				return err
   101  			}
   102  
   103  			var validators types.Validators
   104  			for _, kv := range resKVs {
   105  				validators = append(validators, types.MustUnmarshalValidator(cdc, kv.Value))
   106  			}
   107  
   108  			//return cliCtx.PrintOutput(validators)
   109  			return cliCtx.PrintOutput(validators.Standardize())
   110  		},
   111  	}
   112  }
   113  
   114  // GetCmdQueryPool gets the pool query command.
   115  func GetCmdQueryPool(storeName string, cdc *codec.Codec) *cobra.Command {
   116  	return &cobra.Command{
   117  		Use:   "pool",
   118  		Args:  cobra.NoArgs,
   119  		Short: "query the current staking pool values",
   120  		Long: strings.TrimSpace(
   121  			fmt.Sprintf(`Query values for amounts stored in the staking pool.
   122  
   123  Example:
   124  $ %s query staking pool
   125  `,
   126  				version.ClientName,
   127  			),
   128  		),
   129  		RunE: func(cmd *cobra.Command, args []string) error {
   130  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   131  
   132  			bz, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/pool", storeName), nil)
   133  			if err != nil {
   134  				return err
   135  			}
   136  
   137  			var pool types.Pool
   138  			if err := cdc.UnmarshalJSON(bz, &pool); err != nil {
   139  				return err
   140  			}
   141  
   142  			return cliCtx.PrintOutput(pool)
   143  		},
   144  	}
   145  }
   146  
   147  // GetCmdQueryParams gets the params query command.
   148  func GetCmdQueryParams(storeName string, cdc *codec.Codec) *cobra.Command {
   149  	return &cobra.Command{
   150  		Use:   "params",
   151  		Args:  cobra.NoArgs,
   152  		Short: "query the current staking parameters information",
   153  		Long: strings.TrimSpace(
   154  			fmt.Sprintf(`Query values set as staking parameters.
   155  
   156  Example:
   157  $ %s query staking params
   158  `,
   159  				version.ClientName,
   160  			),
   161  		),
   162  		RunE: func(cmd *cobra.Command, args []string) error {
   163  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   164  
   165  			route := fmt.Sprintf("custom/%s/%s", storeName, types.QueryParameters)
   166  			bz, _, err := cliCtx.QueryWithData(route, nil)
   167  			if err != nil {
   168  				return err
   169  			}
   170  
   171  			var params types.Params
   172  			cdc.MustUnmarshalJSON(bz, &params)
   173  			return cliCtx.PrintOutput(params)
   174  		},
   175  	}
   176  }
   177  
   178  // GetCmdQueryProxy gets command for querying the delegators by a specific proxy
   179  func GetCmdQueryProxy(storeName string, cdc *codec.Codec) *cobra.Command {
   180  	return &cobra.Command{
   181  		Use:   "proxy [address]",
   182  		Short: "query the delegator addresses by a proxy",
   183  		Args:  cobra.ExactArgs(1),
   184  		Long: strings.TrimSpace(
   185  			fmt.Sprintf(`Query the addresses of delegators by a specific proxy
   186  
   187  Example:
   188  $ %s query staking proxy fb1cftp8q8g4aa65nw9s5trwexe77d9t6cr8ndu02
   189  `,
   190  				version.ClientName,
   191  			),
   192  		),
   193  		RunE: func(cmd *cobra.Command, args []string) error {
   194  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   195  			proxyAddr, err := sdk.AccAddressFromBech32(args[0])
   196  			if err != nil {
   197  				return fmt.Errorf("invalid address:%s", args[0])
   198  			}
   199  
   200  			bytes, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(proxyAddr))
   201  			if err != nil {
   202  				return err
   203  			}
   204  
   205  			route := fmt.Sprintf("custom/%s/%s", storeName, types.QueryProxy)
   206  			resp, _, err := cliCtx.QueryWithData(route, bytes)
   207  			if err != nil {
   208  				return err
   209  			}
   210  
   211  			var delAddrs Delegators
   212  			if err := cdc.UnmarshalJSON(resp, &delAddrs); err != nil {
   213  				return err
   214  			}
   215  
   216  			return cliCtx.PrintOutput(delAddrs)
   217  		},
   218  	}
   219  }
   220  
   221  // Delegators is a type alias of sdk.AccAddress slice
   222  type Delegators []sdk.AccAddress
   223  
   224  // String returns a human readable string representation of Delegators
   225  func (as Delegators) String() (strFormat string) {
   226  	for _, a := range as {
   227  		strFormat = fmt.Sprintf("%s%s\n", strFormat, a.String())
   228  	}
   229  
   230  	return strings.TrimSpace(strFormat)
   231  }
   232  
   233  // GetCmdQueryDelegator gets command for querying the info of delegator about delegation and shares
   234  func GetCmdQueryDelegator(storeName string, cdc *codec.Codec) *cobra.Command {
   235  	return &cobra.Command{
   236  		Use:   "delegator [address]",
   237  		Short: "query the information about a delegator",
   238  		Args:  cobra.ExactArgs(1),
   239  		Long: strings.TrimSpace(
   240  			fmt.Sprintf(`Query the information of delegations and all shares recently added by a delegator
   241  
   242  Example:
   243  $ %s query staking delegator fb1cftp8q8g4aa65nw9s5trwexe77d9t6cr8ndu02
   244  `,
   245  				version.ClientName,
   246  			),
   247  		),
   248  		RunE: func(cmd *cobra.Command, args []string) error {
   249  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   250  			delAddr, err := sdk.AccAddressFromBech32(args[0])
   251  			if err != nil {
   252  				return fmt.Errorf("invalid address:%s", args[0])
   253  			}
   254  
   255  			delegator, undelegation := types.NewDelegator(delAddr), types.DefaultUndelegation()
   256  			resp, _, err := cliCtx.QueryStore(types.GetDelegatorKey(delAddr), storeName)
   257  			if err != nil {
   258  				return err
   259  			}
   260  			if len(resp) != 0 {
   261  				cdc.MustUnmarshalBinaryLengthPrefixed(resp, &delegator)
   262  			}
   263  
   264  			// query for the undelegation info
   265  			bytes, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr))
   266  			if err != nil {
   267  				return err
   268  			}
   269  
   270  			route := fmt.Sprintf("custom/%s/%s", storeName, types.QueryUnbondingDelegation)
   271  			res, _, err := cliCtx.QueryWithData(route, bytes)
   272  			// if err!= nil , we treat it as there's no undelegation of the delegator
   273  			if err == nil {
   274  				if err := cdc.UnmarshalJSON(res, &undelegation); err != nil {
   275  					return err
   276  				}
   277  			}
   278  
   279  			return cliCtx.PrintOutput(convertToDelegatorResp(delegator, undelegation))
   280  		},
   281  	}
   282  }
   283  
   284  // DelegatorResponse is designed for delegator info query
   285  type DelegatorResponse struct {
   286  	DelegatorAddress     sdk.AccAddress   `json:"delegator_address" yaml:"delegator_address"`
   287  	ValidatorAddresses   []sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
   288  	Shares               sdk.Dec          `json:"shares" yaml:"shares"`
   289  	Tokens               sdk.Dec          `json:"tokens" yaml:"tokens"`
   290  	UnbondedTokens       sdk.Dec          `json:"unbonded_tokens" yaml:"unbonded_tokens"`
   291  	CompletionTime       time.Time        `json:"completion_time" yaml:"completion_time"`
   292  	IsProxy              bool             `json:"is_proxy" yaml:"is_proxy"`
   293  	TotalDelegatedTokens sdk.Dec          `json:"total_delegated_tokens" yaml:"total_delegated_tokens"`
   294  	ProxyAddress         sdk.AccAddress   `json:"proxy_address" yaml:"proxy_address"`
   295  }
   296  
   297  // String returns a human readable string representation of DelegatorResponse
   298  func (dr DelegatorResponse) String() (output string) {
   299  	n := len(dr.ValidatorAddresses)
   300  	if n > 0 {
   301  		output = fmt.Sprintf("%s\n", dr.ValidatorAddresses[0].String())
   302  		for i := 1; i < n; i++ {
   303  			output = fmt.Sprintf("%s						%s\n", output, dr.ValidatorAddresses[i].String())
   304  		}
   305  	}
   306  
   307  	proxy := "No"
   308  	if dr.IsProxy {
   309  		proxy = "Yes"
   310  	}
   311  
   312  	proxied := "No"
   313  	if dr.ProxyAddress != nil {
   314  		proxied = "Yes\n	Proxied by " + dr.ProxyAddress.String() + "\n"
   315  	}
   316  
   317  	output = fmt.Sprintf(`Delegator:
   318  	DelegatorAddress: 		%s
   319  	ValidatorAddresses:		%s	
   320  	Shares:					%s
   321  	Tokens:					%s
   322  	UnbondedTokens: 		%s
   323  	CompletionTime:			%s
   324  	IsProxied:				%s
   325  	IsProxy:				%s`,
   326  		dr.DelegatorAddress, output, dr.Shares, dr.Tokens, dr.UnbondedTokens, dr.CompletionTime, proxied, proxy)
   327  
   328  	return
   329  }
   330  
   331  func convertToDelegatorResp(delegator types.Delegator, undelegation types.UndelegationInfo,
   332  ) DelegatorResponse {
   333  	return DelegatorResponse{
   334  		delegator.DelegatorAddress,
   335  		delegator.ValidatorAddresses,
   336  		delegator.Shares,
   337  		delegator.Tokens,
   338  		undelegation.Quantity,
   339  		undelegation.CompletionTime,
   340  		delegator.IsProxy,
   341  		delegator.TotalDelegatedTokens,
   342  		delegator.ProxyAddress,
   343  	}
   344  }
   345  
   346  // GetCmdQueryValidatorShares gets command for querying all shares added to a validator
   347  func GetCmdQueryValidatorShares(queryRoute string, cdc *codec.Codec) *cobra.Command {
   348  	return &cobra.Command{
   349  		Use:   "shares-added-to [validator-addr]",
   350  		Short: "query all shares added to a validator",
   351  		Args:  cobra.ExactArgs(1),
   352  		Long: strings.TrimSpace(
   353  			fmt.Sprintf(`Query all shares added to a validator.
   354  
   355  Example:
   356  $ %s query staking shares-added-to fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg
   357  `,
   358  				version.ClientName,
   359  			),
   360  		),
   361  		RunE: func(cmd *cobra.Command, args []string) error {
   362  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   363  
   364  			valAddr, err := sdk.ValAddressFromBech32(args[0])
   365  			if err != nil {
   366  				return err
   367  			}
   368  
   369  			bytes, err := cdc.MarshalJSON(types.NewQueryValidatorParams(valAddr))
   370  			if err != nil {
   371  				return err
   372  			}
   373  
   374  			route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryValidatorAllShares)
   375  			resp, _, err := cliCtx.QueryWithData(route, bytes)
   376  			if err != nil {
   377  				return err
   378  			}
   379  
   380  			var sharesResponses types.SharesResponses
   381  			if err := cdc.UnmarshalJSON(resp, &sharesResponses); err != nil {
   382  				return err
   383  			}
   384  
   385  			return cliCtx.PrintOutput(sharesResponses)
   386  		},
   387  	}
   388  }