gov enums marshal to String

This commit is contained in:
Sunny Aggarwal 2018-07-10 17:59:07 -07:00
parent 338c7b5e4c
commit cba7fd7ee8
11 changed files with 335 additions and 301 deletions

View File

@ -48,6 +48,8 @@ BREAKING CHANGES
* [lcd] Switch key creation output to return bech32
* [lcd] Removed shorthand CLI flags (`a`, `c`, `n`, `o`)
* [gaiad] genesis transactions now use bech32 addresses / pubkeys
* [gov] VoteStatus renamed to ProposalStatus
* [gov] VoteOption, ProposalType, and ProposalStatus all marshal to string form in JSON
DEPRECATED
* [cli] Deprecated `--name` flag in commands that send txs, in favor of `--from`

View File

@ -443,7 +443,7 @@ func TestSubmitProposal(t *testing.T) {
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.Title)
require.Equal(t, "Test", proposal.GetTitle())
}
func TestDeposit(t *testing.T) {
@ -465,7 +465,7 @@ func TestDeposit(t *testing.T) {
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.Title)
require.Equal(t, "Test", proposal.GetTitle())
// create SubmitProposal TX
resultTx = doDeposit(t, port, seed, name, password, addr, proposalID)
@ -473,7 +473,7 @@ func TestDeposit(t *testing.T) {
// query proposal
proposal = getProposal(t, port, proposalID)
require.True(t, proposal.TotalDeposit.IsEqual(sdk.Coins{sdk.NewCoin("steak", 10)}))
require.True(t, proposal.GetTotalDeposit().IsEqual(sdk.Coins{sdk.NewCoin("steak", 10)}))
// query deposit
deposit := getDeposit(t, port, proposalID, addr)
@ -499,7 +499,7 @@ func TestVote(t *testing.T) {
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.Title)
require.Equal(t, "Test", proposal.GetTitle())
// create SubmitProposal TX
resultTx = doDeposit(t, port, seed, name, password, addr, proposalID)
@ -507,7 +507,7 @@ func TestVote(t *testing.T) {
// query proposal
proposal = getProposal(t, port, proposalID)
require.Equal(t, gov.StatusToString(gov.StatusVotingPeriod), proposal.Status)
require.Equal(t, gov.StatusVotingPeriod, proposal.GetStatus())
// create SubmitProposal TX
resultTx = doVote(t, port, seed, name, password, addr, proposalID)
@ -515,7 +515,7 @@ func TestVote(t *testing.T) {
vote := getVote(t, port, proposalID, addr)
require.Equal(t, proposalID, vote.ProposalID)
require.Equal(t, gov.VoteOptionToString(gov.OptionYes), vote.Option)
require.Equal(t, gov.OptionYes, vote.Option)
}
func TestUnrevoke(t *testing.T) {
@ -576,31 +576,31 @@ func TestProposalsQuery(t *testing.T) {
// Test query all proposals
proposals := getProposalsAll(t, port)
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
require.Equal(t, proposalID2, (proposals[1]).ProposalID)
require.Equal(t, proposalID3, (proposals[2]).ProposalID)
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
require.Equal(t, proposalID2, (proposals[1]).GetProposalID())
require.Equal(t, proposalID3, (proposals[2]).GetProposalID())
// Test query deposited by addr1
proposals = getProposalsFilterDepositer(t, port, addr)
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
// Test query deposited by addr2
proposals = getProposalsFilterDepositer(t, port, addr2)
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
// Test query voted by addr1
proposals = getProposalsFilterVoter(t, port, addr)
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
// Test query voted by addr2
proposals = getProposalsFilterVoter(t, port, addr2)
require.Equal(t, proposalID3, (proposals[0]).ProposalID)
require.Equal(t, proposalID3, (proposals[0]).GetProposalID())
// Test query voted and deposited by addr1
proposals = getProposalsFilterVoterDepositer(t, port, addr, addr)
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
}
//_____________________________________________________________________________
@ -838,68 +838,68 @@ func getValidators(t *testing.T, port string) []stakerest.StakeValidatorOutput {
return validators
}
func getProposal(t *testing.T, port string, proposalID int64) gov.ProposalRest {
func getProposal(t *testing.T, port string, proposalID int64) gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d", proposalID), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var proposal gov.ProposalRest
var proposal gov.Proposal
err := cdc.UnmarshalJSON([]byte(body), &proposal)
require.Nil(t, err)
return proposal
}
func getDeposit(t *testing.T, port string, proposalID int64, depositerAddr sdk.AccAddress) gov.DepositRest {
func getDeposit(t *testing.T, port string, proposalID int64, depositerAddr sdk.AccAddress) gov.Deposit {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits/%s", proposalID, depositerAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var deposit gov.DepositRest
var deposit gov.Deposit
err := cdc.UnmarshalJSON([]byte(body), &deposit)
require.Nil(t, err)
return deposit
}
func getVote(t *testing.T, port string, proposalID int64, voterAddr sdk.AccAddress) gov.VoteRest {
func getVote(t *testing.T, port string, proposalID int64, voterAddr sdk.AccAddress) gov.Vote {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes/%s", proposalID, voterAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var vote gov.VoteRest
var vote gov.Vote
err := cdc.UnmarshalJSON([]byte(body), &vote)
require.Nil(t, err)
return vote
}
func getProposalsAll(t *testing.T, port string) []gov.ProposalRest {
func getProposalsAll(t *testing.T, port string) []gov.Proposal {
res, body := Request(t, port, "GET", "/gov/proposals", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var proposals []gov.ProposalRest
var proposals []gov.Proposal
err := cdc.UnmarshalJSON([]byte(body), &proposals)
require.Nil(t, err)
return proposals
}
func getProposalsFilterDepositer(t *testing.T, port string, depositerAddr sdk.AccAddress) []gov.ProposalRest {
func getProposalsFilterDepositer(t *testing.T, port string, depositerAddr sdk.AccAddress) []gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositer=%s", depositerAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var proposals []gov.ProposalRest
var proposals []gov.Proposal
err := cdc.UnmarshalJSON([]byte(body), &proposals)
require.Nil(t, err)
return proposals
}
func getProposalsFilterVoter(t *testing.T, port string, voterAddr sdk.AccAddress) []gov.ProposalRest {
func getProposalsFilterVoter(t *testing.T, port string, voterAddr sdk.AccAddress) []gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?voter=%s", voterAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var proposals []gov.ProposalRest
var proposals []gov.Proposal
err := cdc.UnmarshalJSON([]byte(body), &proposals)
require.Nil(t, err)
return proposals
}
func getProposalsFilterVoterDepositer(t *testing.T, port string, voterAddr, depositerAddr sdk.AccAddress) []gov.ProposalRest {
func getProposalsFilterVoterDepositer(t *testing.T, port string, voterAddr, depositerAddr sdk.AccAddress) []gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositer=%s&voter=%s", depositerAddr, voterAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var proposals []gov.ProposalRest
var proposals []gov.Proposal
err := cdc.UnmarshalJSON([]byte(body), &proposals)
require.Nil(t, err)
return proposals

View File

@ -183,8 +183,8 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
require.Equal(t, int64(45), fooAcc.GetCoins().AmountOf("steak").Int64())
proposal1 := executeGetProposal(t, fmt.Sprintf("gaiacli gov query-proposal --proposalID=1 --output=json %v", flags))
require.Equal(t, int64(1), proposal1.ProposalID)
require.Equal(t, gov.StatusToString(gov.StatusDepositPeriod), proposal1.Status)
require.Equal(t, int64(1), proposal1.GetProposalID())
require.Equal(t, gov.StatusDepositPeriod, proposal1.GetStatus())
executeWrite(t, fmt.Sprintf("gaiacli gov deposit %v --depositer=%s --deposit=10steak --proposalID=1 --from=foo", flags, fooAddr), pass)
tests.WaitForNextHeightTM(port)
@ -192,15 +192,15 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
require.Equal(t, int64(35), fooAcc.GetCoins().AmountOf("steak").Int64())
proposal1 = executeGetProposal(t, fmt.Sprintf("gaiacli gov query-proposal --proposalID=1 --output=json %v", flags))
require.Equal(t, int64(1), proposal1.ProposalID)
require.Equal(t, gov.StatusToString(gov.StatusVotingPeriod), proposal1.Status)
require.Equal(t, int64(1), proposal1.GetProposalID())
require.Equal(t, gov.StatusVotingPeriod, proposal1.GetStatus())
executeWrite(t, fmt.Sprintf("gaiacli gov vote %v --proposalID=1 --voter=%s --option=Yes --from=foo", flags, fooAddr), pass)
tests.WaitForNextHeightTM(port)
vote := executeGetVote(t, fmt.Sprintf("gaiacli gov query-vote --proposalID=1 --voter=%s --output=json %v", fooAddr, flags))
require.Equal(t, int64(1), vote.ProposalID)
require.Equal(t, gov.VoteOptionToString(gov.OptionYes), vote.Option)
require.Equal(t, gov.OptionYes, vote.Option)
}
//___________________________________________________________________________________
@ -288,18 +288,18 @@ func executeGetValidator(t *testing.T, cmdStr string) stake.Validator {
return validator
}
func executeGetProposal(t *testing.T, cmdStr string) gov.ProposalRest {
func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal {
out := tests.ExecuteT(t, cmdStr)
var proposal gov.ProposalRest
var proposal gov.Proposal
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &proposal)
require.NoError(t, err, "out %v\n, err %v", out, err)
return proposal
}
func executeGetVote(t *testing.T, cmdStr string) gov.VoteRest {
func executeGetVote(t *testing.T, cmdStr string) gov.Vote {
out := tests.ExecuteT(t, cmdStr)
var vote gov.VoteRest
var vote gov.Vote
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &vote)
require.NoError(t, err, "out %v\n, err %v", out, err)

View File

@ -48,7 +48,7 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command {
return err
}
proposalType, err := gov.StringToProposalType(strProposalType)
proposalType, err := gov.ProposalTypeFromString(strProposalType)
if err != nil {
return err
}
@ -145,7 +145,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
option := viper.GetString(flagOption)
byteVoteOption, err := gov.StringToVoteOption(option)
byteVoteOption, err := gov.VoteOptionFromString(option)
if err != nil {
return err
}
@ -158,7 +158,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
return err
}
fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", bechVoter, msg.ProposalID, gov.VoteOptionToString(msg.Option))
fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", bechVoter, msg.ProposalID, msg.Option)
// build and sign the transaction, then broadcast to Tendermint
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
@ -195,8 +195,7 @@ func GetCmdQueryProposal(storeName string, cdc *wire.Codec) *cobra.Command {
var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)
proposalRest := gov.ProposalToRest(proposal)
output, err := wire.MarshalJSONIndent(cdc, proposalRest)
output, err := wire.MarshalJSONIndent(cdc, proposal)
if err != nil {
return err
}
@ -232,8 +231,7 @@ func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {
var vote gov.Vote
cdc.MustUnmarshalBinary(res, &vote)
voteRest := gov.VoteToRest(vote)
output, err := wire.MarshalJSONIndent(cdc, voteRest)
output, err := wire.MarshalJSONIndent(cdc, vote)
if err != nil {
return err
}

View File

@ -36,24 +36,24 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) {
}
type postProposalReq struct {
BaseReq baseReq `json:"base_req"`
Title string `json:"title"` // Title of the proposal
Description string `json:"description"` // Description of the proposal
ProposalType string `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
Proposer string `json:"proposer"` // Address of the proposer
InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit
BaseReq baseReq `json:"base_req"`
Title string `json:"title"` // Title of the proposal
Description string `json:"description"` // Description of the proposal
ProposalType gov.ProposalKind `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
Proposer sdk.AccAddress `json:"proposer"` // Address of the proposer
InitialDeposit sdk.Coins `json:"initial_deposit"` // Coins to add to the proposal's deposit
}
type depositReq struct {
BaseReq baseReq `json:"base_req"`
Depositer string `json:"depositer"` // Address of the depositer
Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit
BaseReq baseReq `json:"base_req"`
Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer
Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit
}
type voteReq struct {
BaseReq baseReq `json:"base_req"`
Voter string `json:"voter"` // address of the voter
Option string `json:"option"` // option from OptionSet chosen by the voter
BaseReq baseReq `json:"base_req"`
Voter sdk.AccAddress `json:"voter"` // address of the voter
Option gov.VoteOption `json:"option"` // option from OptionSet chosen by the voter
}
func postProposalHandlerFn(cdc *wire.Codec, ctx context.CoreContext) http.HandlerFunc {
@ -68,20 +68,8 @@ func postProposalHandlerFn(cdc *wire.Codec, ctx context.CoreContext) http.Handle
return
}
proposer, err := sdk.AccAddressFromBech32(req.Proposer)
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
return
}
proposalTypeByte, err := gov.StringToProposalType(req.ProposalType)
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := gov.NewMsgSubmitProposal(req.Title, req.Description, proposalTypeByte, proposer, req.InitialDeposit)
msg := gov.NewMsgSubmitProposal(req.Title, req.Description, req.ProposalType, req.Proposer, req.InitialDeposit)
err = msg.ValidateBasic()
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
@ -117,19 +105,12 @@ func depositHandlerFn(cdc *wire.Codec, ctx context.CoreContext) http.HandlerFunc
if err != nil {
return
}
if !req.BaseReq.baseReqValidate(w) {
return
}
depositer, err := sdk.AccAddressFromBech32(req.Depositer)
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := gov.NewMsgDeposit(depositer, proposalID, req.Amount)
msg := gov.NewMsgDeposit(req.Depositer, proposalID, req.Amount)
err = msg.ValidateBasic()
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
@ -165,25 +146,12 @@ func voteHandlerFn(cdc *wire.Codec, ctx context.CoreContext) http.HandlerFunc {
if err != nil {
return
}
if !req.BaseReq.baseReqValidate(w) {
return
}
voter, err := sdk.AccAddressFromBech32(req.Voter)
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
return
}
voteOptionByte, err := gov.StringToVoteOption(req.Option)
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := gov.NewMsgVote(voter, proposalID, voteOptionByte)
msg := gov.NewMsgVote(req.Voter, proposalID, req.Option)
err = msg.ValidateBasic()
if err != nil {
writeErr(&w, http.StatusBadRequest, err.Error())
@ -225,8 +193,7 @@ func queryProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)
proposalRest := gov.ProposalToRest(proposal)
output, err := wire.MarshalJSONIndent(cdc, proposalRest)
output, err := wire.MarshalJSONIndent(cdc, proposal)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
@ -291,8 +258,7 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
var deposit gov.Deposit
cdc.MustUnmarshalBinary(res, &deposit)
depositRest := gov.DepositToRest(deposit)
output, err := wire.MarshalJSONIndent(cdc, depositRest)
output, err := wire.MarshalJSONIndent(cdc, deposit)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
@ -358,8 +324,7 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
var vote gov.Vote
cdc.MustUnmarshalBinary(res, &vote)
voteRest := gov.VoteToRest(vote)
output, err := wire.MarshalJSONIndent(cdc, voteRest)
output, err := wire.MarshalJSONIndent(cdc, vote)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
@ -411,7 +376,7 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
var maxProposalID int64
cdc.MustUnmarshalBinary(res, &maxProposalID)
matchingProposals := []gov.ProposalRest{}
matchingProposals := []gov.Proposal{}
for proposalID := int64(0); proposalID < maxProposalID; proposalID++ {
if voterAddr != nil {
@ -435,7 +400,7 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)
matchingProposals = append(matchingProposals, gov.ProposalToRest(proposal))
matchingProposals = append(matchingProposals, proposal)
}
output, err := wire.MarshalJSONIndent(cdc, matchingProposals)

View File

@ -1,19 +1,11 @@
package gov
import (
"encoding/json"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Type that represents VoteOption as a byte
type VoteOption = byte
//nolint
const (
OptionEmpty VoteOption = 0x00
OptionYes VoteOption = 0x01
OptionAbstain VoteOption = 0x02
OptionNo VoteOption = 0x03
OptionNoWithVeto VoteOption = 0x04
"github.com/pkg/errors"
)
// Vote
@ -30,9 +22,80 @@ type Deposit struct {
Amount sdk.Coins `json:"amount"` // Deposit amount
}
// ProposalTypeToString for pretty prints of ProposalType
func VoteOptionToString(option VoteOption) string {
switch option {
// Type that represents VoteOption as a byte
type VoteOption byte
//nolint
const (
OptionEmpty VoteOption = 0x00
OptionYes VoteOption = 0x01
OptionAbstain VoteOption = 0x02
OptionNo VoteOption = 0x03
OptionNoWithVeto VoteOption = 0x04
)
// String to proposalType byte. Returns ff if invalid.
func VoteOptionFromString(str string) (VoteOption, error) {
switch str {
case "Yes":
return OptionYes, nil
case "Abstain":
return OptionAbstain, nil
case "No":
return OptionNo, nil
case "NoWithVeto":
return OptionNoWithVeto, nil
default:
return VoteOption(0xff), errors.Errorf("'%s' is not a valid vote option", str)
}
}
// Is defined VoteOption
func validVoteOption(option VoteOption) bool {
if option == OptionYes ||
option == OptionAbstain ||
option == OptionNo ||
option == OptionNoWithVeto {
return true
}
return false
}
// Marshal needed for protobuf compatibility
func (vo VoteOption) Marshal() ([]byte, error) {
return []byte{byte(vo)}, nil
}
// Unmarshal needed for protobuf compatibility
func (vo *VoteOption) Unmarshal(data []byte) error {
*vo = VoteOption(data[0])
return nil
}
// Marshals to JSON using string
func (vo VoteOption) MarshalJSON() ([]byte, error) {
return json.Marshal(vo.String())
}
// Unmarshals from JSON assuming Bech32 encoding
func (vo *VoteOption) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return nil
}
bz2, err := VoteOptionFromString(s)
if err != nil {
return err
}
*vo = bz2
return nil
}
// Turns VoteOption byte to String
func (vo VoteOption) String() string {
switch vo {
case OptionYes:
return "Yes"
case OptionAbstain:
@ -46,63 +109,12 @@ func VoteOptionToString(option VoteOption) string {
}
}
func validVoteOption(option VoteOption) bool {
if option == OptionYes ||
option == OptionAbstain ||
option == OptionNo ||
option == OptionNoWithVeto {
return true
}
return false
}
// String to proposalType byte. Returns ff if invalid.
func StringToVoteOption(str string) (VoteOption, sdk.Error) {
switch str {
case "Yes":
return OptionYes, nil
case "Abstain":
return OptionAbstain, nil
case "No":
return OptionNo, nil
case "NoWithVeto":
return OptionNoWithVeto, nil
// For Printf / Sprintf, returns bech32 when using %s
func (vo VoteOption) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", vo.String())))
default:
return VoteOption(0xff), ErrInvalidVote(DefaultCodespace, str)
}
}
//-----------------------------------------------------------
// REST
// Rest Deposits
type DepositRest struct {
Depositer sdk.AccAddress `json:"depositer"` // address of the depositer
ProposalID int64 `json:"proposal_id"` // proposalID of the proposal
Amount sdk.Coins `json:"option"`
}
// Turn any Deposit to a DepositRest
func DepositToRest(deposit Deposit) DepositRest {
return DepositRest{
Depositer: deposit.Depositer,
ProposalID: deposit.ProposalID,
Amount: deposit.Amount,
}
}
// Rest Votes
type VoteRest struct {
Voter sdk.AccAddress `json:"voter"` // address of the voter
ProposalID int64 `json:"proposal_id"` // proposalID of the proposal
Option string `json:"option"`
}
// Turn any Vote to a VoteRest
func VoteToRest(vote Vote) VoteRest {
return VoteRest{
Voter: vote.Voter,
ProposalID: vote.ProposalID,
Option: VoteOptionToString(vote.Option),
s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
}
}

View File

@ -20,6 +20,7 @@ const (
CodeInvalidProposalType sdk.CodeType = 8
CodeInvalidVote sdk.CodeType = 9
CodeInvalidGenesis sdk.CodeType = 10
CodeInvalidProposalStatus sdk.CodeType = 11
)
//----------------------------------------
@ -53,12 +54,12 @@ func ErrInvalidDescription(codespace sdk.CodespaceType, description string) sdk.
return sdk.NewError(codespace, CodeInvalidDescription, fmt.Sprintf("Proposal Desciption '%s' is not valid", description))
}
func ErrInvalidProposalType(codespace sdk.CodespaceType, strProposalType string) sdk.Error {
return sdk.NewError(codespace, CodeInvalidProposalType, fmt.Sprintf("Proposal Type '%s' is not valid", strProposalType))
func ErrInvalidProposalType(codespace sdk.CodespaceType, proposalType ProposalKind) sdk.Error {
return sdk.NewError(codespace, CodeInvalidProposalType, fmt.Sprintf("Proposal Type '%s' is not valid", proposalType))
}
func ErrInvalidVote(codespace sdk.CodespaceType, strOption string) sdk.Error {
return sdk.NewError(codespace, CodeInvalidVote, fmt.Sprintf("'%s' is not a valid voting option", strOption))
func ErrInvalidVote(codespace sdk.CodespaceType, voteOption VoteOption) sdk.Error {
return sdk.NewError(codespace, CodeInvalidVote, fmt.Sprintf("'%v' is not a valid voting option", voteOption))
}
func ErrInvalidGenesis(codespace sdk.CodespaceType, msg string) sdk.Error {

View File

@ -48,7 +48,7 @@ func (keeper Keeper) WireCodec() *wire.Codec {
// Proposals
// Creates a NewProposal
func (keeper Keeper) NewTextProposal(ctx sdk.Context, title string, description string, proposalType byte) Proposal {
func (keeper Keeper) NewTextProposal(ctx sdk.Context, title string, description string, proposalType ProposalKind) Proposal {
proposalID, err := keeper.getNewProposalID(ctx)
if err != nil {
return nil
@ -165,8 +165,8 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID int64, voterAddr sdk.Ac
return ErrInactiveProposal(keeper.codespace, proposalID)
}
if option != OptionYes && option != OptionAbstain && option != OptionNo && option != OptionNoWithVeto {
return ErrInvalidVote(keeper.codespace, VoteOptionToString(option))
if !validVoteOption(option) {
return ErrInvalidVote(keeper.codespace, option)
}
vote := Vote{

View File

@ -41,7 +41,7 @@ func (msg MsgSubmitProposal) ValidateBasic() sdk.Error {
return ErrInvalidDescription(DefaultCodespace, msg.Description) // TODO: Proper Error
}
if !validProposalType(msg.ProposalType) {
return ErrInvalidProposalType(DefaultCodespace, ProposalTypeToString(msg.ProposalType))
return ErrInvalidProposalType(DefaultCodespace, msg.ProposalType)
}
if len(msg.Proposer) == 0 {
return sdk.ErrInvalidAddress(msg.Proposer.String())
@ -56,7 +56,7 @@ func (msg MsgSubmitProposal) ValidateBasic() sdk.Error {
}
func (msg MsgSubmitProposal) String() string {
return fmt.Sprintf("MsgSubmitProposal{%v, %v, %v, %v}", msg.Title, msg.Description, ProposalTypeToString(msg.ProposalType), msg.InitialDeposit)
return fmt.Sprintf("MsgSubmitProposal{%s, %s, %s, %v}", msg.Title, msg.Description, msg.ProposalType, msg.InitialDeposit)
}
// Implements Msg.
@ -66,19 +66,7 @@ func (msg MsgSubmitProposal) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgSubmitProposal) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(struct {
Title string `json:"title"`
Description string `json:"description"`
ProposalType string `json:"proposal_type"`
Proposer sdk.AccAddress `json:"proposer"`
InitialDeposit sdk.Coins `json:"deposit"`
}{
Title: msg.Title,
Description: msg.Description,
ProposalType: ProposalTypeToString(msg.ProposalType),
Proposer: msg.Proposer,
InitialDeposit: msg.InitialDeposit,
})
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
@ -127,7 +115,7 @@ func (msg MsgDeposit) ValidateBasic() sdk.Error {
}
func (msg MsgDeposit) String() string {
return fmt.Sprintf("MsgDeposit{%v=>%v: %v}", msg.Depositer, msg.ProposalID, msg.Amount)
return fmt.Sprintf("MsgDeposit{%s=>%v: %v}", msg.Depositer, msg.ProposalID, msg.Amount)
}
// Implements Msg.
@ -137,15 +125,7 @@ func (msg MsgDeposit) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgDeposit) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(struct {
ProposalID int64 `json:"proposalID"`
Depositer sdk.AccAddress `json:"proposer"`
Amount sdk.Coins `json:"deposit"`
}{
ProposalID: msg.ProposalID,
Depositer: msg.Depositer,
Amount: msg.Amount,
})
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
@ -185,13 +165,13 @@ func (msg MsgVote) ValidateBasic() sdk.Error {
return ErrUnknownProposal(DefaultCodespace, msg.ProposalID)
}
if !validVoteOption(msg.Option) {
return ErrInvalidVote(DefaultCodespace, VoteOptionToString(msg.Option))
return ErrInvalidVote(DefaultCodespace, msg.Option)
}
return nil
}
func (msg MsgVote) String() string {
return fmt.Sprintf("MsgVote{%v - %v}", msg.ProposalID, msg.Option)
return fmt.Sprintf("MsgVote{%v - %s}", msg.ProposalID, msg.Option)
}
// Implements Msg.
@ -201,15 +181,7 @@ func (msg MsgVote) Get(key interface{}) (value interface{}) {
// Implements Msg.
func (msg MsgVote) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(struct {
ProposalID int64 `json:"proposalID"`
Voter sdk.AccAddress `json:"voter"`
Option string `json:"option"`
}{
ProposalID: msg.ProposalID,
Voter: msg.Voter,
Option: VoteOptionToString(msg.Option),
})
b, err := msgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}

View File

@ -22,7 +22,7 @@ func TestMsgSubmitProposal(t *testing.T) {
_, addrs, _, _ := mock.CreateGenAccounts(1, sdk.Coins{})
tests := []struct {
title, description string
proposalType byte
proposalType ProposalKind
proposerAddr sdk.AccAddress
initialDeposit sdk.Coins
expectPass bool

View File

@ -1,27 +1,14 @@
package gov
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Type that represents Status as a byte
type VoteStatus = byte
// Type that represents Proposal Type as a byte
type ProposalKind = byte
//nolint
const (
StatusDepositPeriod VoteStatus = 0x01
StatusVotingPeriod VoteStatus = 0x02
StatusPassed VoteStatus = 0x03
StatusRejected VoteStatus = 0x04
ProposalTypeText ProposalKind = 0x01
ProposalTypeParameterChange ProposalKind = 0x02
ProposalTypeSoftwareUpgrade ProposalKind = 0x03
)
//-----------------------------------------------------------
// Proposal interface
type Proposal interface {
@ -37,8 +24,8 @@ type Proposal interface {
GetProposalType() ProposalKind
SetProposalType(ProposalKind)
GetStatus() VoteStatus
SetStatus(VoteStatus)
GetStatus() ProposalStatus
SetStatus(ProposalStatus)
GetSubmitBlock() int64
SetSubmitBlock(int64)
@ -73,7 +60,7 @@ type TextProposal struct {
Description string `json:"description"` // Description of the proposal
ProposalType ProposalKind `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
Status VoteStatus `json:"string"` // Status of the Proposal {Pending, Active, Passed, Rejected}
Status ProposalStatus `json:"string"` // Status of the Proposal {Pending, Active, Passed, Rejected}
SubmitBlock int64 `json:"submit_block"` // Height of the block where TxGovSubmitProposal was included
TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit
@ -93,8 +80,8 @@ func (tp TextProposal) GetDescription() string { return tp.D
func (tp *TextProposal) SetDescription(description string) { tp.Description = description }
func (tp TextProposal) GetProposalType() ProposalKind { return tp.ProposalType }
func (tp *TextProposal) SetProposalType(proposalType ProposalKind) { tp.ProposalType = proposalType }
func (tp TextProposal) GetStatus() VoteStatus { return tp.Status }
func (tp *TextProposal) SetStatus(status VoteStatus) { tp.Status = status }
func (tp TextProposal) GetStatus() ProposalStatus { return tp.Status }
func (tp *TextProposal) SetStatus(status ProposalStatus) { tp.Status = status }
func (tp TextProposal) GetSubmitBlock() int64 { return tp.SubmitBlock }
func (tp *TextProposal) SetSubmitBlock(submitBlock int64) { tp.SubmitBlock = submitBlock }
func (tp TextProposal) GetTotalDeposit() sdk.Coins { return tp.TotalDeposit }
@ -104,12 +91,82 @@ func (tp *TextProposal) SetVotingStartBlock(votingStartBlock int64) {
tp.VotingStartBlock = votingStartBlock
}
// Current Active Proposals
//-----------------------------------------------------------
// ProposalQueue
type ProposalQueue []int64
// ProposalTypeToString for pretty prints of ProposalType
func ProposalTypeToString(proposalType ProposalKind) string {
switch proposalType {
//-----------------------------------------------------------
// ProposalKind
// Type that represents Proposal Type as a byte
type ProposalKind byte
//nolint
const (
ProposalTypeText ProposalKind = 0x01
ProposalTypeParameterChange ProposalKind = 0x02
ProposalTypeSoftwareUpgrade ProposalKind = 0x03
)
// String to proposalType byte. Returns ff if invalid.
func ProposalTypeFromString(str string) (ProposalKind, error) {
switch str {
case "Text":
return ProposalTypeText, nil
case "ParameterChange":
return ProposalTypeParameterChange, nil
case "SoftwareUpgrade":
return ProposalTypeSoftwareUpgrade, nil
default:
return ProposalKind(0xff), errors.Errorf("'%s' is not a valid proposal type", str)
}
}
// is defined ProposalType?
func validProposalType(pt ProposalKind) bool {
if pt == ProposalTypeText ||
pt == ProposalTypeParameterChange ||
pt == ProposalTypeSoftwareUpgrade {
return true
}
return false
}
// Marshal needed for protobuf compatibility
func (pt ProposalKind) Marshal() ([]byte, error) {
return []byte{byte(pt)}, nil
}
// Unmarshal needed for protobuf compatibility
func (pt *ProposalKind) Unmarshal(data []byte) error {
*pt = ProposalKind(data[0])
return nil
}
// Marshals to JSON using string
func (pt ProposalKind) MarshalJSON() ([]byte, error) {
return json.Marshal(pt.String())
}
// Unmarshals from JSON assuming Bech32 encoding
func (pt *ProposalKind) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return nil
}
bz2, err := ProposalTypeFromString(s)
if err != nil {
return err
}
*pt = bz2
return nil
}
// Turns VoteOption byte to String
func (pt ProposalKind) String() string {
switch pt {
case 0x00:
return "Text"
case 0x01:
@ -121,31 +178,91 @@ func ProposalTypeToString(proposalType ProposalKind) string {
}
}
func validProposalType(proposalType ProposalKind) bool {
if proposalType == ProposalTypeText ||
proposalType == ProposalTypeParameterChange ||
proposalType == ProposalTypeSoftwareUpgrade {
// For Printf / Sprintf, returns bech32 when using %s
func (pt ProposalKind) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", pt.String())))
default:
s.Write([]byte(fmt.Sprintf("%v", pt)))
}
}
//-----------------------------------------------------------
// ProposalStatus
// Type that represents Proposal Status as a byte
type ProposalStatus byte
//nolint
const (
StatusDepositPeriod ProposalStatus = 0x01
StatusVotingPeriod ProposalStatus = 0x02
StatusPassed ProposalStatus = 0x03
StatusRejected ProposalStatus = 0x04
)
// ProposalStatusToString turns a string into a ProposalStatus
func ProposalStatusFromString(str string) (ProposalStatus, error) {
switch str {
case "DepositPeriod":
return StatusDepositPeriod, nil
case "VotingPeriod":
return StatusVotingPeriod, nil
case "Passed":
return StatusPassed, nil
case "Rejected":
return StatusRejected, nil
default:
return ProposalStatus(0xff), errors.Errorf("'%s' is not a valid proposal status", str)
}
}
// is defined ProposalType?
func validProposalStatus(status ProposalStatus) bool {
if status == StatusDepositPeriod ||
status == StatusVotingPeriod ||
status == StatusPassed ||
status == StatusRejected {
return true
}
return false
}
// String to proposalType byte. Returns ff if invalid.
func StringToProposalType(str string) (ProposalKind, sdk.Error) {
switch str {
case "Text":
return ProposalTypeText, nil
case "ParameterChange":
return ProposalTypeParameterChange, nil
case "SoftwareUpgrade":
return ProposalTypeSoftwareUpgrade, nil
default:
return ProposalKind(0xff), ErrInvalidProposalType(DefaultCodespace, str)
}
// Marshal needed for protobuf compatibility
func (status ProposalStatus) Marshal() ([]byte, error) {
return []byte{byte(status)}, nil
}
// StatusToString for pretty prints of Status
func StatusToString(status VoteStatus) string {
// Unmarshal needed for protobuf compatibility
func (status *ProposalStatus) Unmarshal(data []byte) error {
*status = ProposalStatus(data[0])
return nil
}
// Marshals to JSON using string
func (status ProposalStatus) MarshalJSON() ([]byte, error) {
return json.Marshal(status.String())
}
// Unmarshals from JSON assuming Bech32 encoding
func (status *ProposalStatus) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return nil
}
bz2, err := ProposalStatusFromString(s)
if err != nil {
return err
}
*status = bz2
return nil
}
// Turns VoteStatus byte to String
func (status ProposalStatus) String() string {
switch status {
case StatusDepositPeriod:
return "DepositPeriod"
@ -160,45 +277,12 @@ func StatusToString(status VoteStatus) string {
}
}
// StatusToString for pretty prints of Status
func StringToStatus(status string) VoteStatus {
switch status {
case "DepositPeriod":
return StatusDepositPeriod
case "VotingPeriod":
return StatusVotingPeriod
case "Passed":
return StatusPassed
case "Rejected":
return StatusRejected
// For Printf / Sprintf, returns bech32 when using %s
func (status ProposalStatus) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", status.String())))
default:
return VoteStatus(0xff)
}
}
//-----------------------------------------------------------
// Rest Proposals
type ProposalRest struct {
ProposalID int64 `json:"proposal_id"` // ID of the proposal
Title string `json:"title"` // Title of the proposal
Description string `json:"description"` // Description of the proposal
ProposalType string `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
Status string `json:"string"` // Status of the Proposal {Pending, Active, Passed, Rejected}
SubmitBlock int64 `json:"submit_block"` // Height of the block where TxGovSubmitProposal was included
TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit
VotingStartBlock int64 `json:"voting_start_block"` // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
}
// Turn any Proposal to a ProposalRest
func ProposalToRest(proposal Proposal) ProposalRest {
return ProposalRest{
ProposalID: proposal.GetProposalID(),
Title: proposal.GetTitle(),
Description: proposal.GetDescription(),
ProposalType: ProposalTypeToString(proposal.GetProposalType()),
Status: StatusToString(proposal.GetStatus()),
SubmitBlock: proposal.GetSubmitBlock(),
TotalDeposit: proposal.GetTotalDeposit(),
VotingStartBlock: proposal.GetVotingStartBlock(),
s.Write([]byte(fmt.Sprintf("%v", status)))
}
}