diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index bda8cf9e6f..35ece9fdc3 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -207,9 +207,8 @@ func NewCmdVote() *cobra.Command { fmt.Sprintf(`Submit a vote for an active proposal. You can find the proposal-id by running "%s query gov proposals". - Example: -$ %s tx gov vote 1 yes --from mykey +$ %s tx gov vote 1 yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05 --from mykey `, version.AppName, version.AppName, ), @@ -230,14 +229,14 @@ $ %s tx gov vote 1 yes --from mykey return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0]) } - // Find out which vote option user chose - byteVoteOption, err := types.VoteOptionFromString(govutils.NormalizeVoteOption(args[1])) + // Figure out which subvotes user chose + subvotes, err := types.SubVotesFromString(govutils.NormalizeSubVotes(args[1])) if err != nil { return err } // Build vote message and run basic validation - msg := types.NewMsgVote(from, proposalID, types.SubVotes{types.NewSubVote(byteVoteOption, 1)}) + msg := types.NewMsgVote(from, proposalID, subvotes) err = msg.ValidateBasic() if err != nil { return err diff --git a/x/gov/client/utils/utils.go b/x/gov/client/utils/utils.go index 84c2884d1a..7a4658ddbb 100644 --- a/x/gov/client/utils/utils.go +++ b/x/gov/client/utils/utils.go @@ -1,6 +1,10 @@ package utils -import "github.com/cosmos/cosmos-sdk/x/gov/types" +import ( + "strings" + + "github.com/cosmos/cosmos-sdk/x/gov/types" +) // NormalizeVoteOption - normalize user specified vote option func NormalizeVoteOption(option string) string { @@ -22,6 +26,20 @@ func NormalizeVoteOption(option string) string { } } +// NormalizeSubVotes - normalize subvotes +func NormalizeSubVotes(subvotes string) string { + var newSubVotes []string + for _, subvote := range strings.Split(subvotes, ",") { + fields := strings.Split(subvote, "=") + fields[0] = NormalizeVoteOption(fields[0]) + if len(fields) < 2 { + fields = append(fields, "1") + } + newSubVotes = append(newSubVotes, strings.Join(fields, "=")) + } + return strings.Join(newSubVotes, ",") +} + //NormalizeProposalType - normalize user specified proposal type func NormalizeProposalType(proposalType string) string { switch proposalType { diff --git a/x/gov/types/vote.go b/x/gov/types/vote.go index eb721f1d6f..ce8e94d50a 100644 --- a/x/gov/types/vote.go +++ b/x/gov/types/vote.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "fmt" + "strings" yaml "gopkg.in/yaml.v2" @@ -91,6 +92,31 @@ func VoteOptionFromString(str string) (VoteOption, error) { return VoteOption(option), nil } +// SubVotesFromString returns a SubVotes from a string. It returns an error +// if the string is invalid. +func SubVotesFromString(str string) (SubVotes, error) { + var subvotes SubVotes + for _, subvote := range strings.Split(str, ",") { + fields := strings.Split(subvote, "=") + option, err := VoteOptionFromString(fields[0]) + if err != nil { + return subvotes, err + } + if len(fields) < 2 { + return subvotes, fmt.Errorf("rate field does not exist for %s opion", fields[0]) + } + rate, err := sdk.NewDecFromStr(fields[1]) + if err != nil { + return subvotes, err + } + subvotes = append(subvotes, SubVote{ + option, + rate, + }) + } + return subvotes, nil +} + // ValidVoteOption returns true if the vote option is valid and false otherwise. func ValidVoteOption(option VoteOption) bool { if option == OptionYes ||