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, ¶m) 236 out = param 237 case "tallying": 238 var param types.TallyParams 239 cdc.MustUnmarshalJSON(res, ¶m) 240 out = param 241 case "deposit": 242 var param types.DepositParams 243 cdc.MustUnmarshalJSON(res, ¶m) 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