added to gov rest

This commit is contained in:
Sunny Aggarwal 2018-08-05 01:56:48 -04:00
parent cc1d1fbcf7
commit 1311117658
6 changed files with 139 additions and 93 deletions

View File

@ -31,6 +31,11 @@ func (ctx CLIContext) Query(path string) (res []byte, err error) {
return ctx.query(path, nil)
}
// Query information about the connected node with a data payload
func (ctx CLIContext) QueryWithData(path string, data []byte) (res []byte, err error) {
return ctx.query(path, data)
}
// QueryStore performs a query from a Tendermint node with the provided key and
// store name.
func (ctx CLIContext) QueryStore(key cmn.HexBytes, storeName string) (res []byte, err error) {

View File

@ -105,6 +105,9 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
AddRoute("gov", gov.NewHandler(app.govKeeper))
app.QueryRouter().
AddRoute("gov", gov.NewQuerier(app.govKeeper))
// initialize BaseApp
app.SetInitChainer(app.initChainer)
app.SetBeginBlocker(app.BeginBlocker)

View File

@ -1,6 +1,7 @@
package types
import (
"bytes"
"encoding/hex"
"encoding/json"
"errors"
@ -108,6 +109,17 @@ func (bz AccAddress) Format(s fmt.State, verb rune) {
}
}
// Returns boolean for whether two AccAddresses are Equal
func (bz AccAddress) Equals(bz2 AccAddress) bool {
return (bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0)
}
// Returns boolean for whether an AccAddress is empty
func (bz AccAddress) Empty() bool {
bz2 := AccAddress{}
return bz.Equals(bz2)
}
//__________________________________________________________
// AccAddress a wrapper around bytes meant to represent a validator address
@ -192,6 +204,17 @@ func (bz ValAddress) Format(s fmt.State, verb rune) {
}
}
// Returns boolean for whether two ValAddresses are Equal
func (bz ValAddress) Equals(bz2 ValAddress) bool {
return (bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0)
}
// Returns boolean for whether an AccAddress is empty
func (bz ValAddress) Empty() bool {
bz2 := ValAddress{}
return bz.Equals(bz2)
}
// Bech32ifyAccPub takes AccountPubKey and returns the bech32 encoded string
func Bech32ifyAccPub(pub crypto.PubKey) (string, error) {
return bech32.ConvertAndEncode(Bech32PrefixAccPub, pub.Bytes())

View File

@ -21,6 +21,7 @@ const (
RestDepositer = "depositer"
RestVoter = "voter"
RestProposalStatus = "status"
RestNumLatest = "latest"
storeName = "gov"
)
@ -190,9 +191,13 @@ func queryProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
if err != nil || len(res) == 0 {
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
params := gov.QueryProposalParams{
ProposalID: proposalID,
}
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(params))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
@ -255,19 +260,14 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(gov.KeyDeposit(proposalID, depositerAddr), storeName)
if err != nil || len(res) == 0 {
res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
if err != nil || len(res) == 0 {
w.WriteHeader(http.StatusNotFound)
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
w.Write([]byte(err.Error()))
params := gov.QueryDepositParams{
ProposalID: proposalID,
Depositer: depositerAddr,
}
return
}
w.WriteHeader(http.StatusNotFound)
err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID)
res, err := cliCtx.QueryWithData("custom/gov/deposit", cdc.MustMarshalBinary(params))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
@ -283,7 +283,19 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
return
}
if deposit.Empty() {
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(gov.QueryProposalParams{params.ProposalID}))
if err != nil || len(res) == 0 {
w.WriteHeader(http.StatusNotFound)
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusNotFound)
err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}
@ -328,19 +340,14 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName)
if err != nil || len(res) == 0 {
res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
if err != nil || len(res) == 0 {
w.WriteHeader(http.StatusNotFound)
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
w.Write([]byte(err.Error()))
params := gov.QueryVoteParams{
Voter: voterAddr,
ProposalID: proposalID,
}
return
}
w.WriteHeader(http.StatusNotFound)
err = errors.Errorf("voter [%s] did not vote on proposalID [%d]", bechVoterAddr, proposalID)
res, err := cliCtx.QueryWithData("custom/gov/vote", cdc.MustMarshalBinary(params))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
@ -356,7 +363,19 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
return
}
if vote.Empty() {
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(gov.QueryProposalParams{params.ProposalID}))
if err != nil || len(res) == 0 {
w.WriteHeader(http.StatusNotFound)
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusNotFound)
err = errors.Errorf("voter [%s] did not deposit on proposalID [%d]", bechVoterAddr, proposalID)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}
@ -387,38 +406,19 @@ func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.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
params := gov.QueryVotesParams{
ProposalID: proposalID,
}
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 := cliCtx.QuerySubspace(gov.KeyVotesSubspace(proposalID), storeName)
res, err := cliCtx.QueryWithData("custom/gov/votes", cdc.MustMarshalBinary(params))
if err != nil {
err = errors.New("ProposalID doesn't exist")
w.WriteHeader(http.StatusInternalServerError)
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)
}
cdc.MustUnmarshalBinary(res, &votes)
output, err := wire.MarshalJSONIndent(cdc, votes)
if err != nil {
@ -439,11 +439,13 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
bechVoterAddr := r.URL.Query().Get(RestVoter)
bechDepositerAddr := r.URL.Query().Get(RestDepositer)
strProposalStatus := r.URL.Query().Get(RestProposalStatus)
strNumLatest := r.URL.Query().Get(RestNumLatest)
var err error
var voterAddr sdk.AccAddress
var depositerAddr sdk.AccAddress
var proposalStatus gov.ProposalStatus
var numLatest int64
if len(bechVoterAddr) != 0 {
voterAddr, err = sdk.AccAddressFromBech32(bechVoterAddr)
@ -476,54 +478,35 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
return
}
}
if len(strNumLatest) != 0 {
numLatest, err = strconv.ParseInt(strNumLatest, 10, 64)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
err := errors.Errorf("'%s' is not a valid int64", strNumLatest)
w.Write([]byte(err.Error()))
return
}
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(gov.KeyNextProposalID, storeName)
params := gov.QueryProposalsParams{
Depositer: depositerAddr,
Voter: voterAddr,
ProposalStatus: proposalStatus,
NumLatestProposals: numLatest,
}
res, err := cliCtx.QueryWithData("custom/gov/proposals", cdc.MustMarshalBinary(params))
if err != nil {
err = errors.New("no proposals exist yet and proposalID has not been set")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
var maxProposalID int64
cdc.MustUnmarshalBinary(res, &maxProposalID)
matchingProposals := []gov.Proposal{}
for proposalID := int64(0); proposalID < maxProposalID; proposalID++ {
if voterAddr != nil {
res, err = cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName)
if err != nil || len(res) == 0 {
continue
}
}
if depositerAddr != nil {
res, err = cliCtx.QueryStore(gov.KeyDeposit(proposalID, depositerAddr), storeName)
if err != nil || len(res) == 0 {
continue
}
}
res, err = cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
if err != nil || len(res) == 0 {
continue
}
var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)
if len(strProposalStatus) != 0 {
if proposal.GetStatus() != proposalStatus {
continue
}
}
matchingProposals = append(matchingProposals, proposal)
}
var matchingProposals []gov.Proposal
cdc.MustUnmarshalBinary(res, &matchingProposals)
output, err := wire.MarshalJSONIndent(cdc, matchingProposals)
if err != nil {
w.WriteHeader(http.StatusBadRequest)

View File

@ -15,6 +15,22 @@ type Vote struct {
Option VoteOption `json:"option"` // option from OptionSet chosen by the voter
}
// Returns whether 2 votes are equal
func (voteA Vote) Equals(voteB Vote) bool {
if voteA.Voter.Equals(voteB.Voter) &&
voteA.ProposalID == voteB.ProposalID &&
voteA.Option == voteB.Option {
return true
}
return false
}
// Returns whether a vote is empty
func (voteA Vote) Empty() bool {
voteB := Vote{}
return voteA.Equals(voteB)
}
// Deposit
type Deposit struct {
Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer
@ -22,6 +38,22 @@ type Deposit struct {
Amount sdk.Coins `json:"amount"` // Deposit amount
}
// Returns whether 2 deposits are equal
func (depositA Deposit) Equals(depositB Deposit) bool {
if depositA.Depositer.Equals(depositB.Depositer) &&
depositA.ProposalID == depositB.ProposalID &&
depositA.Amount.IsEqual(depositB.Amount) {
return true
}
return false
}
// Returns whether a deposit is empty
func (depositA Deposit) Empty() bool {
depositB := Deposit{}
return depositA.Equals(depositB)
}
// Type that represents VoteOption as a byte
type VoteOption byte

View File

@ -55,7 +55,7 @@ type QueryDepositParams struct {
func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
var params QueryDepositParams
err2 := keeper.cdc.UnmarshalBinary(req.Data, params)
err2 := keeper.cdc.UnmarshalBinary(req.Data, &params)
if err2 != nil {
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
}