Skip to content

Commit

Permalink
Merge PR #1773: Query the votes on a proposal
Browse files Browse the repository at this point in the history
* added lcd endpoint to query all votes on a proposal
* added cli support
* Gopkg.lock from new dep
* Update PENDING.md
  • Loading branch information
sunnya97 authored and cwgoes committed Jul 20, 2018
1 parent a054532 commit f3a1290
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ IMPROVEMENTS
* [cli] Improve error messages for all txs when the account doesn't exist
* [tools] Remove `rm -rf vendor/` from `make get_vendor_deps`
* [x/stake] Add revoked to human-readable validator
* [x/gov] Votes on a proposal can now be queried

BUG FIXES
* \#1666 Add intra-tx counter to the genesis validators
20 changes: 20 additions & 0 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,17 @@ func TestProposalsQuery(t *testing.T) {
// Test query voted and deposited by addr1
proposals = getProposalsFilterVoterDepositer(t, port, addr, addr)
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())

// Test query votes on Proposal 2
votes := getVotes(t, port, proposalID2)
require.Len(t, votes, 1)
require.Equal(t, addr, votes[0].Voter)

// Test query votes on Proposal 3
votes = getVotes(t, port, proposalID3)
require.Len(t, votes, 2)
require.True(t, addr.String() == votes[0].Voter.String() || addr.String() == votes[1].Voter.String())
require.True(t, addr2.String() == votes[0].Voter.String() || addr2.String() == votes[1].Voter.String())
}

//_____________________________________________________________________________
Expand Down Expand Up @@ -875,6 +886,15 @@ func getVote(t *testing.T, port string, proposalID int64, voterAddr sdk.AccAddre
return vote
}

func getVotes(t *testing.T, port string, proposalID int64) []gov.Vote {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var votes []gov.Vote
err := cdc.UnmarshalJSON([]byte(body), &votes)
require.Nil(t, err)
return votes
}

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)
Expand Down
14 changes: 14 additions & 0 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
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.OptionYes, vote.Option)

votes := executeGetVotes(t, fmt.Sprintf("gaiacli gov query-votes --proposalID=1 --output=json %v", flags))
require.Len(t, votes, 1)
require.Equal(t, int64(1), votes[0].ProposalID)
require.Equal(t, gov.OptionYes, votes[0].Option)
}

//___________________________________________________________________________________
Expand Down Expand Up @@ -321,3 +326,12 @@ func executeGetVote(t *testing.T, cmdStr string) gov.Vote {
require.NoError(t, err, "out %v\n, err %v", out, err)
return vote
}

func executeGetVotes(t *testing.T, cmdStr string) []gov.Vote {
out := tests.ExecuteT(t, cmdStr)
var votes []gov.Vote
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &votes)
require.NoError(t, err, "out %v\n, err %v", out, err)
return votes
}
1 change: 1 addition & 0 deletions cmd/gaia/cmd/gaiacli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func main() {
client.GetCommands(
govcmd.GetCmdQueryProposal("gov", cdc),
govcmd.GetCmdQueryVote("gov", cdc),
govcmd.GetCmdQueryVotes("gov", cdc),
)...)
govCmd.AddCommand(
client.PostCommands(
Expand Down
51 changes: 51 additions & 0 deletions x/gov/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,54 @@ func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {

return cmd
}

// Command to Get a Proposal Information
func GetCmdQueryVotes(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "query-votes",
Short: "query votes on a proposal",
RunE: func(cmd *cobra.Command, args []string) error {
proposalID := viper.GetInt64(flagProposalID)

ctx := context.NewCoreContextFromViper()

res, err := ctx.QueryStore(gov.KeyProposal(proposalID), storeName)
if len(res) == 0 || err != nil {
return errors.Errorf("proposalID [%d] does not exist", proposalID)
}

var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)

if proposal.GetStatus() != gov.StatusVotingPeriod {
fmt.Println("Proposal not in voting period.")
return nil
}

res2, err := ctx.QuerySubspace(cdc, gov.KeyVotesSubspace(proposalID), storeName)
if err != nil {
return err
}

var votes []gov.Vote
for i := 0; i < len(res2); i++ {
var vote gov.Vote
cdc.MustUnmarshalBinary(res2[i].Value, &vote)
votes = append(votes, vote)
}

output, err := wire.MarshalJSONIndent(cdc, votes)
if err != nil {
return err
}

fmt.Println(string(output))

return nil
},
}

cmd.Flags().String(flagProposalID, "", "proposalID of which proposal's votes are being queried")

return cmd
}
67 changes: 67 additions & 0 deletions x/gov/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) {
r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits/{%s}", RestProposalID, RestDepositer), queryDepositHandlerFn(cdc)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes/{%s}", RestProposalID, RestVoter), queryVoteHandlerFn(cdc)).Methods("GET")

r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes", RestProposalID), queryVotesOnProposalHandlerFn(cdc)).Methods("GET")

r.HandleFunc("/gov/proposals", queryProposalsWithParameterFn(cdc)).Methods("GET")
}

Expand Down Expand Up @@ -335,6 +337,71 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
}
}

// nolint: gocyclo
// todo: Split this functionality into helper functions to remove the above
func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
strProposalID := vars[RestProposalID]

if len(strProposalID) == 0 {
w.WriteHeader(http.StatusBadRequest)
err := errors.New("proposalId required but not specified")
w.Write([]byte(err.Error()))
return
}

proposalID, err := strconv.ParseInt(strProposalID, 10, 64)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
err := errors.Errorf("proposalID [%s] is not positive", proposalID)
w.Write([]byte(err.Error()))
return
}

ctx := context.NewCoreContextFromViper()

res, err := ctx.QueryStore(gov.KeyProposal(proposalID), storeName)
if err != nil || len(res) == 0 {
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
w.Write([]byte(err.Error()))
return
}

var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)

if proposal.GetStatus() != gov.StatusVotingPeriod {
err := errors.Errorf("proposal is not in Voting Period", proposalID)
w.Write([]byte(err.Error()))
return
}

res2, err := ctx.QuerySubspace(cdc, gov.KeyVotesSubspace(proposalID), storeName)
if err != nil {
err = errors.New("ProposalID doesn't exist")
w.Write([]byte(err.Error()))
return
}

var votes []gov.Vote

for i := 0; i < len(res2); i++ {
var vote gov.Vote
cdc.MustUnmarshalBinary(res2[i].Value, &vote)
votes = append(votes, vote)
}

output, err := wire.MarshalJSONIndent(cdc, votes)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}

// nolint: gocyclo
// todo: Split this functionality into helper functions to remove the above
func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
Expand Down

0 comments on commit f3a1290

Please sign in to comment.