Merge PR #1773: Query the votes on a proposal
* added lcd endpoint to query all votes on a proposal * added cli support * Gopkg.lock from new dep * Update PENDING.md
This commit is contained in:
parent
a054532a89
commit
f3a12909ef
|
@ -646,6 +646,7 @@
|
|||
"github.com/tendermint/tendermint/rpc/lib/client",
|
||||
"github.com/tendermint/tendermint/rpc/lib/server",
|
||||
"github.com/tendermint/tendermint/types",
|
||||
"github.com/tendermint/tendermint/version",
|
||||
"github.com/zondax/ledger-goclient",
|
||||
"golang.org/x/crypto/blowfish",
|
||||
"golang.org/x/crypto/ripemd160",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ func main() {
|
|||
client.GetCommands(
|
||||
govcmd.GetCmdQueryProposal("gov", cdc),
|
||||
govcmd.GetCmdQueryVote("gov", cdc),
|
||||
govcmd.GetCmdQueryVotes("gov", cdc),
|
||||
)...)
|
||||
govCmd.AddCommand(
|
||||
client.PostCommands(
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue