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

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/spf13/cobra"
     9  	"github.com/spf13/viper"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    14  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    16  	"github.com/fibonacci-chain/fbc/x/gov/client/utils"
    17  
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    19  	"github.com/fibonacci-chain/fbc/x/gov/types"
    20  )
    21  
    22  // GetQueryCmd returns the cli query commands for this module
    23  func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
    24  	// Group gov queries under a subcommand
    25  	govQueryCmd := &cobra.Command{
    26  		Use:                        types.ModuleName,
    27  		Short:                      "Querying commands for the governance module",
    28  		DisableFlagParsing:         true,
    29  		SuggestionsMinimumDistance: 2,
    30  		RunE:                       client.ValidateCmd,
    31  	}
    32  
    33  	govQueryCmd.AddCommand(flags.GetCommands(
    34  		GetCmdQueryProposal(queryRoute, cdc),
    35  		GetCmdQueryProposals(queryRoute, cdc),
    36  		getCmdQueryVote(queryRoute, cdc),
    37  		getCmdQueryVotes(queryRoute, cdc),
    38  		GetCmdQueryParam(queryRoute, cdc),
    39  		GetCmdQueryParams(queryRoute, cdc),
    40  		GetCmdQueryProposer(queryRoute, cdc),
    41  		getCmdQueryDeposit(queryRoute, cdc),
    42  		getCmdQueryDeposits(queryRoute, cdc),
    43  		GetCmdQueryTally(queryRoute, cdc))...)
    44  
    45  	return govQueryCmd
    46  }
    47  
    48  // GetCmdQueryProposal implements the query proposal command.
    49  func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
    50  	return &cobra.Command{
    51  		Use:   "proposal [proposal-id]",
    52  		Args:  cobra.ExactArgs(1),
    53  		Short: "Query details of a single proposal",
    54  		Long: strings.TrimSpace(
    55  			fmt.Sprintf(`Query details for a proposal. You can find the
    56  proposal-id by running "%s query gov proposals".
    57  
    58  Example:
    59  $ %s query gov proposal 1
    60  `,
    61  				version.ClientName, version.ClientName,
    62  			),
    63  		),
    64  		RunE: func(cmd *cobra.Command, args []string) error {
    65  			cliCtx := context.NewCLIContext().WithCodec(cdc)
    66  
    67  			// validate that the proposal id is a uint
    68  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
    69  			if err != nil {
    70  				return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
    71  			}
    72  
    73  			// Query the proposal
    74  			res, err := utils.QueryProposalByID(proposalID, cliCtx, queryRoute)
    75  			if err != nil {
    76  				return err
    77  			}
    78  
    79  			var proposal types.Proposal
    80  			cdc.MustUnmarshalJSON(res, &proposal)
    81  			return cliCtx.PrintOutput(proposal) // nolint:errcheck
    82  		},
    83  	}
    84  }
    85  
    86  // GetCmdQueryProposals implements a query proposals command.
    87  func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command {
    88  	cmd := &cobra.Command{
    89  		Use:   "proposals",
    90  		Short: "Query proposals with optional filters",
    91  		Long: strings.TrimSpace(
    92  			fmt.Sprintf(`Query for a all proposals. You can filter the returns with the following flags.
    93  
    94  Example:
    95  $ %s query gov proposals --depositor ex1rf9wr069pt64e58f2w3mjs9w72g8vemzw26658
    96  $ %s query gov proposals --voter ex1rf9wr069pt64e58f2w3mjs9w72g8vemzw26658
    97  $ %s query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Rejected)
    98  `,
    99  				version.ClientName, version.ClientName, version.ClientName,
   100  			),
   101  		),
   102  		RunE: func(cmd *cobra.Command, args []string) error {
   103  			bechDepositorAddr := viper.GetString(flagDepositor)
   104  			bechVoterAddr := viper.GetString(flagVoter)
   105  			strProposalStatus := viper.GetString(flagStatus)
   106  			numLimit := uint64(viper.GetInt64(flagNumLimit))
   107  
   108  			var depositorAddr sdk.AccAddress
   109  			var voterAddr sdk.AccAddress
   110  			var proposalStatus types.ProposalStatus
   111  
   112  			params := types.NewQueryProposalsParams(proposalStatus, numLimit, voterAddr, depositorAddr)
   113  
   114  			if len(bechDepositorAddr) != 0 {
   115  				depositorAddr, err := sdk.AccAddressFromBech32(bechDepositorAddr)
   116  				if err != nil {
   117  					return err
   118  				}
   119  				params.Depositor = depositorAddr
   120  			}
   121  
   122  			if len(bechVoterAddr) != 0 {
   123  				voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
   124  				if err != nil {
   125  					return err
   126  				}
   127  				params.Voter = voterAddr
   128  			}
   129  
   130  			if len(strProposalStatus) != 0 {
   131  				proposalStatus, err := types.ProposalStatusFromString(utils.NormalizeProposalStatus(strProposalStatus))
   132  				if err != nil {
   133  					return err
   134  				}
   135  				params.ProposalStatus = proposalStatus
   136  			}
   137  
   138  			bz, err := cdc.MarshalJSON(params)
   139  			if err != nil {
   140  				return err
   141  			}
   142  
   143  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   144  
   145  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposals", queryRoute), bz)
   146  			if err != nil {
   147  				return err
   148  			}
   149  
   150  			var matchingProposals types.Proposals
   151  			err = cdc.UnmarshalJSON(res, &matchingProposals)
   152  			if err != nil {
   153  				return err
   154  			}
   155  
   156  			if len(matchingProposals) == 0 {
   157  				return fmt.Errorf("No matching proposals found")
   158  			}
   159  
   160  			return cliCtx.PrintOutput(matchingProposals) // nolint:errcheck
   161  		},
   162  	}
   163  
   164  	cmd.Flags().String(flagNumLimit, "", "(optional) limit to latest [number] proposals. Defaults to all proposals")
   165  	cmd.Flags().String(flagDepositor, "", "(optional) filter by proposals deposited on by depositor")
   166  	cmd.Flags().String(flagVoter, "", "(optional) filter by proposals voted on by voted")
   167  	cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status, status: deposit_period/voting_period/passed/rejected")
   168  
   169  	return cmd
   170  }
   171  
   172  // GetCmdQueryProposer implements the query proposer command.
   173  func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
   174  	return &cobra.Command{
   175  		Use:   "proposer [proposal-id]",
   176  		Args:  cobra.ExactArgs(1),
   177  		Short: "Query the proposer of a governance proposal",
   178  		Long: strings.TrimSpace(
   179  			fmt.Sprintf(`Query which address proposed a proposal with a given ID.
   180  
   181  Example:
   182  $ %s query gov proposer 1
   183  `,
   184  				version.ClientName,
   185  			),
   186  		),
   187  		RunE: func(cmd *cobra.Command, args []string) error {
   188  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   189  
   190  			// validate that the proposalID is a uint
   191  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   192  			if err != nil {
   193  				return fmt.Errorf("proposal-id %s is not a valid uint", args[0])
   194  			}
   195  
   196  			prop, err := utils.QueryProposerByTxQuery(cliCtx, proposalID)
   197  			if err != nil {
   198  				return err
   199  			}
   200  
   201  			return cliCtx.PrintOutput(prop)
   202  		},
   203  	}
   204  }
   205  
   206  // GetCmdQueryProposal implements the query proposal command.
   207  func GetCmdQueryParam(queryRoute string, cdc *codec.Codec) *cobra.Command {
   208  	return &cobra.Command{
   209  		Use:   "param [param-type]",
   210  		Args:  cobra.ExactArgs(1),
   211  		Short: "Query the parameters (voting|tallying|deposit) of the governance process",
   212  		Long: strings.TrimSpace(
   213  			fmt.Sprintf(`Query the all the parameters for the governance process.
   214  
   215  Example:
   216  $ %s query gov param voting
   217  $ %s query gov param tallying
   218  $ %s query gov param deposit
   219  `,
   220  				version.ClientName, version.ClientName, version.ClientName,
   221  			),
   222  		),
   223  		RunE: func(cmd *cobra.Command, args []string) error {
   224  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   225  
   226  			// Query store
   227  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/%s", queryRoute, args[0]), nil)
   228  			if err != nil {
   229  				return err
   230  			}
   231  			var out fmt.Stringer
   232  			switch args[0] {
   233  			case "voting":
   234  				var param types.VotingParams
   235  				cdc.MustUnmarshalJSON(res, &param)
   236  				out = param
   237  			case "tallying":
   238  				var param types.TallyParams
   239  				cdc.MustUnmarshalJSON(res, &param)
   240  				out = param
   241  			case "deposit":
   242  				var param types.DepositParams
   243  				cdc.MustUnmarshalJSON(res, &param)
   244  				out = param
   245  			default:
   246  				return fmt.Errorf("Argument must be one of (voting|tallying|deposit), was %s", args[0])
   247  			}
   248  
   249  			return cliCtx.PrintOutput(out)
   250  		},
   251  	}
   252  }
   253  
   254  // GetCmdQueryProposal implements the query proposal command.
   255  func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
   256  	return &cobra.Command{
   257  		Use:   "params",
   258  		Short: "Query the parameters of the governance process",
   259  		Long: strings.TrimSpace(
   260  			fmt.Sprintf(`Query the all the parameters for the governance process.
   261  
   262  Example:
   263  $ %s query gov params
   264  `,
   265  				version.ClientName,
   266  			),
   267  		),
   268  		Args: cobra.NoArgs,
   269  		RunE: func(cmd *cobra.Command, args []string) error {
   270  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   271  			tp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/tallying", queryRoute), nil)
   272  			if err != nil {
   273  				return err
   274  			}
   275  			dp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/deposit", queryRoute), nil)
   276  			if err != nil {
   277  				return err
   278  			}
   279  			vp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/voting", queryRoute), nil)
   280  			if err != nil {
   281  				return err
   282  			}
   283  
   284  			var tallyParams types.TallyParams
   285  			cdc.MustUnmarshalJSON(tp, &tallyParams)
   286  			var depositParams types.DepositParams
   287  			cdc.MustUnmarshalJSON(dp, &depositParams)
   288  			var votingParams types.VotingParams
   289  			cdc.MustUnmarshalJSON(vp, &votingParams)
   290  
   291  			return cliCtx.PrintOutput(types.NewParams(votingParams, tallyParams, depositParams))
   292  		},
   293  	}
   294  }
   295  
   296  // Command to Get a Proposal Information
   297  // getCmdQueryVote implements the query proposal vote command.
   298  func getCmdQueryVote(queryRoute string, cdc *codec.Codec) *cobra.Command {
   299  	return &cobra.Command{
   300  		Use:   "vote [proposal-id] [voter-addr]",
   301  		Args:  cobra.ExactArgs(2),
   302  		Short: "Query details of a single vote",
   303  		Long: strings.TrimSpace(
   304  			fmt.Sprintf(`Query details for a single vote on a proposal given its identifier.
   305  
   306  Example:
   307  $ %s query gov vote 1 fb1cftp8q8g4aa65nw9s5trwexe77d9t6cr8ndu02
   308  `,
   309  				version.ClientName,
   310  			),
   311  		),
   312  		RunE: func(cmd *cobra.Command, args []string) error {
   313  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   314  			voterAddr, proposalID, _, err := parse(cliCtx, queryRoute, args)
   315  			if err != nil {
   316  				return err
   317  			}
   318  
   319  			params := types.NewQueryVoteParams(proposalID, voterAddr)
   320  			bz, err := cdc.MarshalJSON(params)
   321  			if err != nil {
   322  				return err
   323  			}
   324  
   325  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/vote", queryRoute), bz)
   326  			if err != nil {
   327  				return err
   328  			}
   329  
   330  			var vote types.Vote
   331  			if err := cdc.UnmarshalJSON(res, &vote); err != nil {
   332  				return err
   333  			}
   334  
   335  			if vote.Empty() {
   336  				res, err = utils.QueryVoteByTxQuery(cliCtx, params)
   337  				if err != nil {
   338  					return err
   339  				}
   340  				if err := cdc.UnmarshalJSON(res, &vote); err != nil {
   341  					return err
   342  				}
   343  			}
   344  			return cliCtx.PrintOutput(vote) //nolint:errcheck
   345  		},
   346  	}
   347  }
   348  
   349  func getDepositsOrVotes(cdc *codec.Codec, queryRoute string, args []string, isDeposits bool) error {
   350  	cliCtx := context.NewCLIContext().WithCodec(cdc)
   351  
   352  	_, proposalID, res, err := parse(cliCtx, queryRoute, args)
   353  	if err != nil {
   354  		return err
   355  	}
   356  	params := types.NewQueryProposalParams(proposalID)
   357  	bz, err := cdc.MarshalJSON(params)
   358  	if err != nil {
   359  		return err
   360  	}
   361  
   362  	var proposal types.Proposal
   363  	cdc.MustUnmarshalJSON(res, &proposal)
   364  
   365  	propStatus := proposal.Status
   366  	if isDeposits {
   367  		if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) {
   368  			res, err = utils.QueryDepositsByTxQuery(cliCtx, params)
   369  		} else {
   370  			res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposits", queryRoute), bz)
   371  		}
   372  	} else {
   373  		if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) {
   374  			res, err = utils.QueryVotesByTxQuery(cliCtx, params)
   375  		} else {
   376  			res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/votes", queryRoute), bz)
   377  		}
   378  	}
   379  
   380  	if err != nil {
   381  		return err
   382  	}
   383  
   384  	type DepositVotes = types.Votes
   385  	if isDeposits {
   386  		type DepositVotes = types.Deposits
   387  	}
   388  	var dep DepositVotes
   389  	cdc.MustUnmarshalJSON(res, &dep)
   390  	return cliCtx.PrintOutput(dep)
   391  }
   392  
   393  // getCmdQueryVotes implements the command to query for proposal votes.
   394  func getCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command {
   395  	return &cobra.Command{
   396  		Use:   "votes [proposal-id]",
   397  		Args:  cobra.ExactArgs(1),
   398  		Short: "Query votes on a proposal",
   399  		Long: strings.TrimSpace(
   400  			fmt.Sprintf(`Query vote details for a single proposal by its identifier.
   401  
   402  Example:
   403  $ %s query gov votes 1
   404  `,
   405  				version.ClientName,
   406  			),
   407  		),
   408  		RunE: func(cmd *cobra.Command, args []string) error {
   409  			return getDepositsOrVotes(cdc, queryRoute, args, false)
   410  		},
   411  	}
   412  }
   413  
   414  // Command to Get a specific deposit Information
   415  // getCmdQueryDeposit implements the query proposal deposit command.
   416  func getCmdQueryDeposit(queryRoute string, cdc *codec.Codec) *cobra.Command {
   417  	return &cobra.Command{
   418  		Use:   "deposit [proposal-id] [depositer-addr]",
   419  		Args:  cobra.ExactArgs(2),
   420  		Short: "Query details of a deposit",
   421  		Long: strings.TrimSpace(
   422  			fmt.Sprintf(`Query details for a single proposal deposit on a proposal by its identifier.
   423  
   424  Example:
   425  $ %s query gov deposit 1 ex1rf9wr069pt64e58f2w3mjs9w72g8vemzw26658
   426  `,
   427  				version.ClientName,
   428  			),
   429  		),
   430  		RunE: func(cmd *cobra.Command, args []string) error {
   431  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   432  
   433  			depositorAddr, proposalID, _, err := parse(cliCtx, queryRoute, args)
   434  			if err != nil {
   435  				return err
   436  			}
   437  
   438  			params := types.NewQueryDepositParams(proposalID, depositorAddr)
   439  			bz, err := cdc.MarshalJSON(params)
   440  			if err != nil {
   441  				return err
   442  			}
   443  
   444  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposit", queryRoute), bz)
   445  			if err != nil {
   446  				return err
   447  			}
   448  
   449  			var deposit types.Deposit
   450  			cdc.MustUnmarshalJSON(res, &deposit)
   451  
   452  			if deposit.Empty() {
   453  				res, err = utils.QueryDepositByTxQuery(cliCtx, params)
   454  				if err != nil {
   455  					return err
   456  				}
   457  				cdc.MustUnmarshalJSON(res, &deposit)
   458  			}
   459  
   460  			return cliCtx.PrintOutput(deposit)
   461  		},
   462  	}
   463  }
   464  
   465  // getCmdQueryDeposits implements the command to query for proposal deposits.
   466  func getCmdQueryDeposits(queryRoute string, cdc *codec.Codec) *cobra.Command {
   467  	return &cobra.Command{
   468  		Use:   "deposits [proposal-id]",
   469  		Args:  cobra.ExactArgs(1),
   470  		Short: "Query deposits on a proposal",
   471  		Long: strings.TrimSpace(
   472  			fmt.Sprintf(`Query details for all deposits on a proposal.
   473  You can find the proposal-id by running "%s query gov proposals".
   474  
   475  Example:
   476  $ %s query gov deposits 1
   477  `,
   478  				version.ClientName, version.ClientName,
   479  			),
   480  		),
   481  		RunE: func(cmd *cobra.Command, args []string) error {
   482  			return getDepositsOrVotes(cdc, queryRoute, args, true)
   483  		},
   484  	}
   485  }
   486  
   487  func parse(cliCtx context.CLIContext, queryRoute string, args []string) (sdk.AccAddress, uint64, []byte, error) {
   488  	// validate that the proposal id is a uint
   489  	proposalID, err := strconv.ParseUint(args[0], 10, 64)
   490  	if err != nil {
   491  		return nil, 0, []byte{},
   492  			fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
   493  	}
   494  
   495  	// check to see if the proposal is in the store
   496  	res, err := utils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   497  	if err != nil {
   498  		return nil, proposalID, []byte{}, fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   499  	}
   500  
   501  	var addr sdk.AccAddress
   502  	if len(args) > 1 {
   503  		addr, err = sdk.AccAddressFromBech32(args[1])
   504  		if err != nil {
   505  			return addr, proposalID, res, fmt.Errorf("invalid address:%s", args[1])
   506  		}
   507  	}
   508  	return addr, proposalID, res, nil
   509  }
   510  
   511  // GetCmdQueryTally implements the command to query for proposal tally result.
   512  func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command {
   513  	return &cobra.Command{
   514  		Use:   "tally [proposal-id]",
   515  		Args:  cobra.ExactArgs(1),
   516  		Short: "Get the tally of a proposal vote",
   517  		Long: strings.TrimSpace(
   518  			fmt.Sprintf(`Query tally of votes on a proposal. You can find
   519  the proposal-id by running "%s query gov proposals".
   520  
   521  Example:
   522  $ %s query gov tally 1
   523  `,
   524  				version.ClientName, version.ClientName,
   525  			),
   526  		),
   527  		RunE: func(cmd *cobra.Command, args []string) error {
   528  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   529  
   530  			// validate that the proposal id is a uint
   531  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   532  			if err != nil {
   533  				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
   534  			}
   535  
   536  			// check to see if the proposal is in the store
   537  			_, err = utils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   538  			if err != nil {
   539  				return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   540  			}
   541  
   542  			// Construct query
   543  			params := types.NewQueryProposalParams(proposalID)
   544  			bz, err := cdc.MarshalJSON(params)
   545  			if err != nil {
   546  				return err
   547  			}
   548  
   549  			// Query store
   550  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/tally", queryRoute), bz)
   551  			if err != nil {
   552  				return err
   553  			}
   554  
   555  			var tally types.TallyResult
   556  			cdc.MustUnmarshalJSON(res, &tally)
   557  			return cliCtx.PrintOutput(tally)
   558  		},
   559  	}
   560  }
   561  
   562  // DONTCOVER