tidy up and test client

This commit is contained in:
rhuairahrighairigh 2020-03-23 20:57:15 +00:00
parent b31cfbe39b
commit eefda597f0
7 changed files with 139 additions and 370 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/version"
"github.com/kava-labs/kava/x/committee/client/common" "github.com/kava-labs/kava/x/committee/client/common"
"github.com/kava-labs/kava/x/committee/types" "github.com/kava-labs/kava/x/committee/types"
@ -26,13 +27,14 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
govQueryCmd.AddCommand(client.GetCommands( govQueryCmd.AddCommand(client.GetCommands(
//GetCmdQueryCommittee(queryRoute, cdc), // GetCmdQueryCommittee(queryRoute, cdc), // TODO is this needed?
GetCmdQueryCommittees(queryRoute, cdc), GetCmdQueryCommittees(queryRoute, cdc),
GetCmdQueryProposal(queryRoute, cdc), GetCmdQueryProposal(queryRoute, cdc),
GetCmdQueryProposals(queryRoute, cdc), GetCmdQueryProposals(queryRoute, cdc),
//GetCmdQueryVote(queryRoute, cdc),
GetCmdQueryVotes(queryRoute, cdc), GetCmdQueryVotes(queryRoute, cdc),
//GetCmdQueryParams(queryRoute, cdc), //TODO GetCmdQueryParams(queryRoute, cdc),
GetCmdQueryProposer(queryRoute, cdc), GetCmdQueryProposer(queryRoute, cdc),
GetCmdQueryTally(queryRoute, cdc))...) GetCmdQueryTally(queryRoute, cdc))...)
@ -43,8 +45,9 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryCommittees(queryRoute string, cdc *codec.Codec) *cobra.Command { func GetCmdQueryCommittees(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "committees", Use: "committees",
Args: cobra.NoArgs,
Short: "Query all committees", Short: "Query all committees",
Long: "", // TODO Example: fmt.Sprintf("%s query %s committees", version.ClientName, types.ModuleName),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -55,7 +58,7 @@ func GetCmdQueryCommittees(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
// Decode and print result // Decode and print result
committees := []types.Committee{} committees := []types.Committee{} // using empty (not nil) slice so json output returns "[]"" instead of "null" when there's no data
if err = cdc.UnmarshalJSON(res, &committees); err != nil { if err = cdc.UnmarshalJSON(res, &committees); err != nil {
return err return err
} }
@ -71,16 +74,7 @@ func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
Use: "proposal [proposal-id]", Use: "proposal [proposal-id]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Short: "Query details of a single proposal", Short: "Query details of a single proposal",
// Long: strings.TrimSpace( Example: fmt.Sprintf("%s query %s proposal 2", version.ClientName, types.ModuleName),
// fmt.Sprintf(`Query details for a proposal. You can find the
// proposal-id by running "%s query gov proposals".
// Example:
// $ %s query gov proposal 1
// `,
// version.ClientName, version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -95,7 +89,6 @@ func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
// Query // Query
//res, err := gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryProposal), bz) res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryProposal), bz)
if err != nil { if err != nil {
return err return err
@ -113,19 +106,9 @@ func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command { func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "proposals [committee-id]", Use: "proposals [committee-id]",
Short: "Query proposals by committee.", Short: "Query all proposals for a committee",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
// Long: strings.TrimSpace( Example: fmt.Sprintf("%s query %s proposals 1", version.ClientName, types.ModuleName),
// fmt.Sprintf(`Query for a all proposals. You can filter the returns with the following flags.
// Example:
// $ %s query gov proposals --depositor cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
// $ %s query gov proposals --voter cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
// $ %s query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Rejected)
// `,
// version.ClientName, version.ClientName, version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -146,7 +129,7 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
// Decode and print results // Decode and print results
proposals := []types.Proposal{} // using empty (not nil) slice so json returns [] instead of null when there's no data // TODO check proposals := []types.Proposal{}
err = cdc.UnmarshalJSON(res, &proposals) err = cdc.UnmarshalJSON(res, &proposals)
if err != nil { if err != nil {
return err return err
@ -157,91 +140,13 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command {
return cmd return cmd
} }
// // Command to Get a Proposal Information
// // GetCmdQueryVote implements the query proposal vote command.
// func GetCmdQueryVote(queryRoute string, cdc *codec.Codec) *cobra.Command {
// return &cobra.Command{
// Use: "vote [proposal-id] [voter-addr]",
// Args: cobra.ExactArgs(2),
// Short: "Query details of a single vote",
// Long: strings.TrimSpace(
// fmt.Sprintf(`Query details for a single vote on a proposal given its identifier.
// Example:
// $ %s query gov vote 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
// `,
// version.ClientName,
// ),
// ),
// RunE: func(cmd *cobra.Command, args []string) error {
// cliCtx := context.NewCLIContext().WithCodec(cdc)
// // validate that the proposal id is a uint
// proposalID, err := strconv.ParseUint(args[0], 10, 64)
// if err != nil {
// return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
// }
// // check to see if the proposal is in the store
// _, err = gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
// if err != nil {
// return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
// }
// voterAddr, err := sdk.AccAddressFromBech32(args[1])
// if err != nil {
// return err
// }
// params := types.NewQueryVoteParams(proposalID, voterAddr)
// bz, err := cdc.MarshalJSON(params)
// if err != nil {
// return err
// }
// res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/vote", queryRoute), bz)
// if err != nil {
// return err
// }
// var vote types.Vote
// // XXX: Allow the decoding to potentially fail as the vote may have been
// // pruned from state. If so, decoding will fail and so we need to check the
// // Empty() case. Consider updating Vote JSON decoding to not fail when empty.
// _ = cdc.UnmarshalJSON(res, &vote)
// if vote.Empty() {
// res, err = gcutils.QueryVoteByTxQuery(cliCtx, params)
// if err != nil {
// return err
// }
// if err := cdc.UnmarshalJSON(res, &vote); err != nil {
// return err
// }
// }
// return cliCtx.PrintOutput(vote)
// },
// }
// }
// GetCmdQueryVotes implements the command to query for proposal votes. // GetCmdQueryVotes implements the command to query for proposal votes.
func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command { func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "votes [proposal-id]", Use: "votes [proposal-id]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Short: "Query votes on a proposal", Short: "Query votes on a proposal",
// Long: strings.TrimSpace( Example: fmt.Sprintf("%s query %s votes 2", version.ClientName, types.ModuleName),
// fmt.Sprintf(`Query vote details for a single proposal by its identifier.
// Example:
// $ %s query gov votes 1
// `,
// version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -272,22 +177,13 @@ func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
} }
// GetCmdQueryTally implements the command to query for proposal tally result.
func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command { func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "tally [proposal-id]", Use: "tally [proposal-id]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Short: "Get the tally of a proposal vote", Short: "Get the current tally of votes on a proposal",
// Long: strings.TrimSpace( Long: "Query the current tally of votes on a proposal to see the progress of the voting.",
// fmt.Sprintf(`Query tally of votes on a proposal. You can find Example: fmt.Sprintf("%s query %s tally 2", version.ClientName, types.ModuleName),
// the proposal-id by running "%s query gov proposals".
// Example:
// $ %s query gov tally 1
// `,
// version.ClientName, version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -309,69 +205,21 @@ func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command {
// Decode and print results // Decode and print results
var tally bool var tally bool
cdc.MustUnmarshalJSON(res, &tally) // TODO must or normal, what's the difference on the cli? if err = cdc.UnmarshalJSON(res, &tally); err != nil {
return err
}
return cliCtx.PrintOutput(tally) return cliCtx.PrintOutput(tally)
}, },
} }
} }
// // GetCmdQueryProposal implements the query proposal command.
// func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
// return &cobra.Command{
// Use: "params",
// Short: "Query the parameters of the governance process",
// Long: strings.TrimSpace(
// fmt.Sprintf(`Query the all the parameters for the governance process.
// Example:
// $ %s query gov params
// `,
// version.ClientName,
// ),
// ),
// Args: cobra.NoArgs,
// RunE: func(cmd *cobra.Command, args []string) error {
// cliCtx := context.NewCLIContext().WithCodec(cdc)
// tp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/tallying", queryRoute), nil)
// if err != nil {
// return err
// }
// dp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/deposit", queryRoute), nil)
// if err != nil {
// return err
// }
// vp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/voting", queryRoute), nil)
// if err != nil {
// return err
// }
// var tallyParams types.TallyParams
// cdc.MustUnmarshalJSON(tp, &tallyParams)
// var depositParams types.DepositParams
// cdc.MustUnmarshalJSON(dp, &depositParams)
// var votingParams types.VotingParams
// cdc.MustUnmarshalJSON(vp, &votingParams)
// return cliCtx.PrintOutput(types.NewParams(votingParams, tallyParams, depositParams))
// },
// }
// }
// GetCmdQueryProposer implements the query proposer command.
func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command { func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "proposer [proposal-id]", Use: "proposer [proposal-id]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Short: "Query the proposer of a governance proposal", Short: "Query the proposer of a governance proposal",
// Long: strings.TrimSpace( Long: "Query which address proposed a proposal with a given ID.",
// fmt.Sprintf(`Query which address proposed a proposal with a given ID. Example: fmt.Sprintf("%s query %s proposer 2", version.ClientName, types.ModuleName),
// Example:
// $ %s query gov proposer 1
// `,
// version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)

View File

@ -11,49 +11,17 @@ import (
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/auth/client/utils"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/tendermint/tendermint/crypto"
"github.com/kava-labs/kava/x/committee/types" "github.com/kava-labs/kava/x/committee/types"
) )
// // Proposal flags func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
// const (
// FlagTitle = "title"
// FlagDescription = "description"
// flagProposalType = "type"
// FlagDeposit = "deposit"
// flagVoter = "voter"
// flagDepositor = "depositor"
// flagStatus = "status"
// flagNumLimit = "limit"
// FlagProposal = "proposal"
// )
// type proposal struct {
// Title string
// Description string
// Type string
// Deposit string
// }
// // ProposalFlags defines the core required fields of a proposal. It is used to
// // verify that these values are not provided in conjunction with a JSON proposal
// // file.
// var ProposalFlags = []string{
// FlagTitle,
// FlagDescription,
// flagProposalType,
// FlagDeposit,
// }
// GetTxCmd returns the transaction commands for this module
// governance ModuleClient is slightly different from other ModuleClients in that
// it contains a slice of "proposal" child commands. These commands are respective
// to proposal type handlers that are implemented in other modules but are mounted
// under the governance CLI (eg. parameter change proposals).
func GetTxCmd(storeKey string, cdc *codec.Codec /*, pcmds []*cobra.Command*/) *cobra.Command { // TODO why is storeKey here?
txCmd := &cobra.Command{ txCmd := &cobra.Command{
Use: types.ModuleName, Use: types.ModuleName,
Short: "committee governance transactions subcommands", Short: "committee governance transactions subcommands",
@ -62,39 +30,27 @@ func GetTxCmd(storeKey string, cdc *codec.Codec /*, pcmds []*cobra.Command*/) *c
RunE: client.ValidateCmd, RunE: client.ValidateCmd,
} }
cmdSubmitProp := GetCmdSubmitProposal(cdc)
// for _, pcmd := range pcmds {
// cmdSubmitProp.AddCommand(client.PostCommands(pcmd)[0])
// }
txCmd.AddCommand(client.PostCommands( txCmd.AddCommand(client.PostCommands(
GetCmdVote(cdc), GetCmdVote(cdc),
cmdSubmitProp, GetCmdSubmitProposal(cdc),
)...) )...)
return txCmd return txCmd
} }
// // GetCmdSubmitProposal is the root command on which commands for submitting proposals are registered. // GetCmdSubmitProposal returns the command to submit a proposal to a committee
// func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
// cmd := &cobra.Command{
// Use: "submit-proposal [committee-id]",
// Short: "Submit a governance proposal to a particular committee.", // TODO
// DisableFlagParsing: true,
// SuggestionsMinimumDistance: 2,
// RunE: client.ValidateCmd,
// }
// return cmd
// }
// GetCmdSubmitProposal
func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command { func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "submit-proposal [committee-id] [proposal-file]", Use: "submit-proposal [committee-id] [proposal-file]",
Short: "Submit a governance proposal to a particular committee.", Short: "Submit a governance proposal to a particular committee",
Long: "", // TODO Long: fmt.Sprintf(`Submit a proposal to a committee so they can vote on it.
The proposal file must be the json encoded forms of the proposal type you want to submit.
For example:
%s
`, mustGetExampleParameterChangeProposal(cdc)),
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
Example: fmt.Sprintf("%s tx %s submit-proposal 1 your-proposal.json", version.ClientName, types.ModuleName),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -136,22 +92,14 @@ func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
return cmd return cmd
} }
// GetCmdVote implements creating a new vote command. // GetCmdVote returns the command to vote on a proposal.
func GetCmdVote(cdc *codec.Codec) *cobra.Command { func GetCmdVote(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "vote [proposal-id]", Use: "vote [proposal-id]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Short: "Vote for an active proposal", // TODO Short: "Vote for an active proposal",
// Long: strings.TrimSpace( Long: "Submit a yes vote for the proposal with id [proposal-id].",
// fmt.Sprintf(`Submit a vote for an active proposal. You can Example: fmt.Sprintf("%s tx %s vote 2", version.ClientName, types.ModuleName),
// find the proposal-id by running "%s query gov proposals".
// Example:
// $ %s tx gov vote 1 yes --from mykey
// `,
// version.ClientName, version.ClientName,
// ),
// ),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -177,13 +125,22 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command {
} }
} }
// TODO this could replace the whole gov submit-proposal cmd, remove and replace the gov cmd in kvcli main.go // TODO This could replace the whole gov submit-proposal cmd. It would align how it works with how submiting proposal to committees works.
// would want the documentation/examples though // Requires removing and replacing the gov cmd in kvcli main.go
// GetGovCmdSubmitProposal returns a command to submit a proposal to the gov module. It is passed to the gov module for use on its command subtree.
func GetGovCmdSubmitProposal(cdc *codec.Codec) *cobra.Command { func GetGovCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "committee [proposal-file] [deposit]", Use: "committee [proposal-file] [deposit]",
Short: "Submit a governance proposal to change a committee.", Short: "Submit a governance proposal to change a committee.",
Long: "This command will work with either CommitteeChange proposals or CommitteeDelete proposals.", // TODO Long: fmt.Sprintf(`Submit a governance proposal to create, alter, or delete a committee.
The proposal file must be the json encoded form of the proposal type you want to submit.
For example, to create or update a committee:
%s
and to delete a committee:
%s
`, mustGetExampleCommitteeChangeProposal(cdc), mustGetExampleCommitteeDeleteProposal(cdc)),
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
@ -193,7 +150,7 @@ func GetGovCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
proposer := cliCtx.GetFromAddress() proposer := cliCtx.GetFromAddress()
// Get the deposit // Get the deposit
deposit, err := sdk.ParseCoins(args[0]) deposit, err := sdk.ParseCoins(args[1])
if err != nil { if err != nil {
return err return err
} }
@ -224,3 +181,49 @@ func GetGovCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
} }
return cmd return cmd
} }
// mustGetExampleCommitteeChangeProposal is a helper function to return an example json proposal
func mustGetExampleCommitteeChangeProposal(cdc *codec.Codec) string {
exampleChangeProposal := types.NewCommitteeChangeProposal(
"A Title",
"A description of this proposal.",
types.NewCommittee(
1,
[]sdk.AccAddress{sdk.AccAddress(crypto.AddressHash([]byte("exampleAddres")))},
[]types.Permission{}, // TODO permissions
),
)
exampleChangeProposalBz, err := cdc.MarshalJSONIndent(exampleChangeProposal, "", " ")
if err != nil {
panic(err)
}
return string(exampleChangeProposalBz)
}
// mustGetExampleCommitteeDeleteProposal is a helper function to return an example json proposal
func mustGetExampleCommitteeDeleteProposal(cdc *codec.Codec) string {
exampleDeleteProposal := types.NewCommitteeDeleteProposal(
"A Title",
"A description of this proposal.",
1,
)
exampleDeleteProposalBz, err := cdc.MarshalJSONIndent(exampleDeleteProposal, "", " ")
if err != nil {
panic(err)
}
return string(exampleDeleteProposalBz)
}
// mustGetExampleParameterChangeProposal is a helper function to return an example json proposal
func mustGetExampleParameterChangeProposal(cdc *codec.Codec) string {
exampleParameterChangeProposal := params.NewParameterChangeProposal(
"A Title",
"A description of this proposal.",
[]params.ParamChange{params.NewParamChange("cdp", "SurplusAuctionThreshold", "1000000000")},
)
exampleParameterChangeProposalBz, err := cdc.MarshalJSONIndent(exampleParameterChangeProposal, "", " ")
if err != nil {
panic(err)
}
return string(exampleParameterChangeProposalBz)
}

View File

@ -22,8 +22,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/proposer", types.ModuleName, RestProposalID), queryProposerHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/proposer", types.ModuleName, RestProposalID), queryProposerHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/tally", types.ModuleName, RestProposalID), queryTallyOnProposalHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/tally", types.ModuleName, RestProposalID), queryTallyOnProposalHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/votes", types.ModuleName, RestProposalID), queryVotesOnProposalHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/votes", types.ModuleName, RestProposalID), queryVotesOnProposalHandlerFn(cliCtx)).Methods("GET")
//r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/votes/{%s}", types.ModuleName, RestProposalID, RestVoter), queryVoteHandlerFn(cliCtx)).Methods("GET") // TODO r.HandleFunc(fmt.Sprintf("/%s/parameters/{%s}", types.ModuleName, RestParamsType), queryParamsHandlerFn(cliCtx)).Methods("GET")
//r.HandleFunc(fmt.Sprintf("/%s/parameters/{%s}", types.ModuleName, RestParamsType), queryParamsHandlerFn(cliCtx)).Methods("GET")
} }
// ---------- Committees ---------- // ---------- Committees ----------
@ -68,7 +67,7 @@ func queryCommitteeHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
if !ok { if !ok {
return return
} }
bz, err := cliCtx.Codec.MarshalJSON(types.NewQueryProposalParams(committeeID)) bz, err := cliCtx.Codec.MarshalJSON(types.NewQueryCommitteeParams(committeeID))
if err != nil { if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return return
@ -108,7 +107,7 @@ func queryProposalsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
if !ok { if !ok {
return return
} }
bz, err := cliCtx.Codec.MarshalJSON(types.NewQueryProposalParams(committeeID)) bz, err := cliCtx.Codec.MarshalJSON(types.NewQueryCommitteeParams(committeeID))
if err != nil { if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return return
@ -153,7 +152,7 @@ func queryProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
// Query // Query
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryProposals), bz) res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryProposal), bz)
if err != nil { if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return return
@ -253,88 +252,6 @@ func queryVotesOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
// func queryVoteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
// return func(w http.ResponseWriter, r *http.Request) {
// vars := mux.Vars(r)
// strProposalID := vars[RestProposalID]
// bechVoterAddr := vars[RestVoter]
// if len(strProposalID) == 0 {
// err := errors.New("proposalId required but not specified")
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// proposalID, ok := rest.ParseUint64OrReturnBadRequest(w, strProposalID)
// if !ok {
// return
// }
// if len(bechVoterAddr) == 0 {
// err := errors.New("voter address required but not specified")
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
// if err != nil {
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
// if !ok {
// return
// }
// params := types.NewQueryVoteParams(proposalID, voterAddr)
// bz, err := cliCtx.Codec.MarshalJSON(params)
// if err != nil {
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// res, _, err := cliCtx.QueryWithData("custom/gov/vote", bz)
// if err != nil {
// rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
// return
// }
// var vote types.Vote
// if err := cliCtx.Codec.UnmarshalJSON(res, &vote); err != nil {
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// // For an empty vote, either the proposal does not exist or is inactive in
// // which case the vote would be removed from state and should be queried for
// // directly via a txs query.
// if vote.Empty() {
// bz, err := cliCtx.Codec.MarshalJSON(types.NewQueryProposalParams(proposalID))
// if err != nil {
// rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
// return
// }
// res, _, err = cliCtx.QueryWithData("custom/gov/proposal", bz)
// if err != nil || len(res) == 0 {
// err := fmt.Errorf("proposalID %d does not exist", proposalID)
// rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
// return
// }
// res, err = gcutils.QueryVoteByTxQuery(cliCtx, params)
// if err != nil {
// rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
// return
// }
// }
// rest.PostProcessResponse(w, cliCtx, res)
// }
// }
func queryTallyOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryTallyOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// Parse the query height // Parse the query height
@ -375,6 +292,7 @@ func queryTallyOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
// ---------- Params ---------- // ---------- Params ----------
// TODO
// func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
// return func(w http.ResponseWriter, r *http.Request) { // return func(w http.ResponseWriter, r *http.Request) {
// vars := mux.Vars(r) // vars := mux.Vars(r)

View File

@ -11,19 +11,10 @@ const (
RestProposalID = "proposal-id" RestProposalID = "proposal-id"
RestCommitteeID = "committee-id" RestCommitteeID = "committee-id"
RestVoter = "voter" RestVoter = "voter"
//RestProposalStatus = "status"
//RestNumLimit = "limit"
) )
// // ProposalRESTHandler defines a REST handler implemented in another module. The
// // sub-route is mounted on the governance REST handler.
// type ProposalRESTHandler struct {
// SubRoute string
// Handler func(http.ResponseWriter, *http.Request)
// }
// RegisterRoutes - Central function to define routes that get registered by the main application // RegisterRoutes - Central function to define routes that get registered by the main application
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router /*, phs []ProposalRESTHandler*/) { func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
registerQueryRoutes(cliCtx, r) registerQueryRoutes(cliCtx, r)
registerTxRoutes(cliCtx, r /* , phs*/) registerTxRoutes(cliCtx, r)
} }

View File

@ -16,12 +16,7 @@ import (
"github.com/kava-labs/kava/x/committee/types" "github.com/kava-labs/kava/x/committee/types"
) )
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router /*, phs []ProposalRESTHandler*/) { func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
// propSubRtr := r.PathPrefix("/gov/proposals").Subrouter()
// for _, ph := range phs {
// propSubRtr.HandleFunc(fmt.Sprintf("/%s", ph.SubRoute), ph.Handler).Methods("POST")
// }
r.HandleFunc(fmt.Sprintf("/%s/committees/{%s}/proposals", types.ModuleName, RestCommitteeID), postProposalHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/%s/committees/{%s}/proposals", types.ModuleName, RestCommitteeID), postProposalHandlerFn(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/votes", types.ModuleName, RestProposalID), postVoteHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/%s/proposals/{%s}/votes", types.ModuleName, RestProposalID), postVoteHandlerFn(cliCtx)).Methods("POST")
} }

View File

@ -22,8 +22,14 @@ type CommitteeChangeProposal struct {
var _ govtypes.Content = CommitteeChangeProposal{} var _ govtypes.Content = CommitteeChangeProposal{}
func init() { func init() {
// Gov proposals need to be registered on gov's ModuleCdc so MsgSubmitProposal can be encoded.
govtypes.RegisterProposalType(ProposalTypeCommitteeChange) govtypes.RegisterProposalType(ProposalTypeCommitteeChange)
govtypes.RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal") govtypes.RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal")
// Since these proposals include Permissions that needs to be registered as well (including the interface and concrete types)
govtypes.ModuleCdc.RegisterInterface((*Permission)(nil), nil)
govtypes.RegisterProposalTypeCodec(GodPermission{}, "kava/GodPermission")
// TODO register other permissions here
// TODO write these // TODO write these
//RegisterProposalType(ProposalTypeCommitteeChange) //RegisterProposalType(ProposalTypeCommitteeChange)
//RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal") //RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal")

View File

@ -24,6 +24,14 @@ type Committee struct {
Permissions []Permission `json:"permissions" yaml:"permissions"` Permissions []Permission `json:"permissions" yaml:"permissions"`
} }
func NewCommittee(id uint64, members []sdk.AccAddress, permissions []Permission) Committee {
return Committee{
ID: id,
Members: members,
Permissions: permissions,
}
}
func (c Committee) HasMember(addr sdk.AccAddress) bool { func (c Committee) HasMember(addr sdk.AccAddress) bool {
for _, m := range c.Members { for _, m := range c.Members {
if m.Equals(addr) { if m.Equals(addr) {