Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: x/gov Get Vote(s)/Deposit(s) Updates #3091

Merged
merged 26 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions client/tx/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ $ gaiacli query txs --tags '<tag1>:<value1>&<tag2>:<value2>'
}

cliCtx := context.NewCLIContext().WithCodec(cdc)
txs, err := searchTxs(cliCtx, cdc, tmTags)
txs, err := SearchTxs(cliCtx, cdc, tmTags)
if err != nil {
return err
}
Expand Down Expand Up @@ -89,7 +89,10 @@ $ gaiacli query txs --tags '<tag1>:<value1>&<tag2>:<value2>'
return cmd
}

func searchTxs(cliCtx context.CLIContext, cdc *codec.Codec, tags []string) ([]Info, error) {
// SearchTxs performs a search for transactions for a given set of tags via
// Tendermint RPC. It returns a slice of Info object containing txs and metadata.
// An error is returned if the query fails.
func SearchTxs(cliCtx context.CLIContext, cdc *codec.Codec, tags []string) ([]Info, error) {
if len(tags) == 0 {
return nil, errors.New("must declare at least one tag to search")
}
Expand Down Expand Up @@ -172,7 +175,7 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.
tags = append(tags, tag)
}

txs, err = searchTxs(cliCtx, cdc, tags)
txs, err = SearchTxs(cliCtx, cdc, tags)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
Expand Down
46 changes: 41 additions & 5 deletions x/gov/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,7 @@ func queryProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha
return
}

params := gov.QueryProposalParams{
ProposalID: proposalID,
}
params := gov.NewQueryProposalParams(proposalID)

bz, err := cdc.MarshalJSON(params)
if err != nil {
Expand Down Expand Up @@ -263,7 +261,26 @@ func queryDepositsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha
return
}

res, err := cliCtx.QueryWithData("custom/gov/deposits", bz)
res, err := cliCtx.QueryWithData("custom/gov/proposal", bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

var proposal gov.Proposal
if err := cdc.UnmarshalJSON(res, &proposal); err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

// For inactive proposals we must query the txs directly to get the deposits
// as they're no longer in state.
if proposal.GetStatus() != gov.StatusVotingPeriod {
queryDepositsByTxQuery(cdc, cliCtx, w, proposalID)
return
}

res, err = cliCtx.QueryWithData("custom/gov/deposits", bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
Expand Down Expand Up @@ -429,7 +446,26 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext)
return
}

res, err := cliCtx.QueryWithData("custom/gov/votes", bz)
res, err := cliCtx.QueryWithData("custom/gov/proposal", bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

var proposal gov.Proposal
if err := cdc.UnmarshalJSON(res, &proposal); err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

// For inactive proposals we must query the txs directly to get the votes
// as they're no longer in state.
if proposal.GetStatus() != gov.StatusVotingPeriod {
queryVotesByTxQuery(cdc, cliCtx, w, proposalID)
return
}

res, err = cliCtx.QueryWithData("custom/gov/votes", bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
Expand Down
87 changes: 87 additions & 0 deletions x/gov/client/rest/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package rest

import (
"fmt"
"net/http"

"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/gov/tags"
)

// queryDepositsByTxQuery will query for deposits via a direct txs tags query. It
// will fetch and build deposits directly from the returned txs and write the
// JSON response to the provided ResponseWriter.
//
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
// support configurable pagination.
func queryDepositsByTxQuery(cdc *codec.Codec, cliCtx context.CLIContext, w http.ResponseWriter, proposalID uint64) {
tags := []string{
fmt.Sprintf("%s='%s'", tags.Action, tags.ActionProposalDeposit),
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", proposalID))),
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
}

infos, err := tx.SearchTxs(cliCtx, cdc, tags)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

var deposits []gov.Deposit

for _, info := range infos {
for _, msg := range info.Tx.GetMsgs() {
if msg.Type() == gov.TypeMsgDeposit {
depMsg := msg.(gov.MsgDeposit)

deposits = append(deposits, gov.Deposit{
Depositor: depMsg.Depositor,
ProposalID: proposalID,
Amount: depMsg.Amount,
})
}
}
}

utils.PostProcessResponse(w, cdc, deposits, cliCtx.Indent)
}

// queryVotesByTxQuery will query for votes via a direct txs tags query. It
// will fetch and build votes directly from the returned txs and write the
// JSON response to the provided ResponseWriter.
//
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
// support configurable pagination.
func queryVotesByTxQuery(cdc *codec.Codec, cliCtx context.CLIContext, w http.ResponseWriter, proposalID uint64) {
tags := []string{
fmt.Sprintf("%s='%s'", tags.Action, tags.ActionProposalVote),
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", proposalID))),
}

infos, err := tx.SearchTxs(cliCtx, cdc, tags)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

var votes []gov.Vote

for _, info := range infos {
for _, msg := range info.Tx.GetMsgs() {
if msg.Type() == gov.TypeMsgVote {
voteMsg := msg.(gov.MsgVote)

votes = append(votes, gov.Vote{
Voter: voteMsg.Voter,
ProposalID: proposalID,
Option: voteMsg.Option,
})
}
}
}

utils.PostProcessResponse(w, cdc, votes, cliCtx.Indent)
}
36 changes: 16 additions & 20 deletions x/gov/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,22 @@ func NewHandler(keeper Keeper) sdk.Handler {
case MsgVote:
return handleMsgVote(ctx, keeper, msg)
default:
errMsg := "Unrecognized gov msg type"
errMsg := fmt.Sprintf("Unrecognized gov msg type: %T", msg)
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
return sdk.ErrUnknownRequest(errMsg).Result()
}
}
}

func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitProposal) sdk.Result {

proposal := keeper.NewTextProposal(ctx, msg.Title, msg.Description, msg.ProposalType)
proposalID := proposal.GetProposalID()
proposalIDBytes := []byte(fmt.Sprintf("%d", proposalID))

err, votingStarted := keeper.AddDeposit(ctx, proposal.GetProposalID(), msg.Proposer, msg.InitialDeposit)
err, votingStarted := keeper.AddDeposit(ctx, proposalID, msg.Proposer, msg.InitialDeposit)
if err != nil {
return err.Result()
}

proposalIDBytes := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal.GetProposalID())

resTags := sdk.NewTags(
tags.Proposer, []byte(msg.Proposer.String()),
tags.ProposalID, proposalIDBytes,
Expand All @@ -51,16 +50,14 @@ func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitPropos
}

func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result {

err, votingStarted := keeper.AddDeposit(ctx, msg.ProposalID, msg.Depositor, msg.Amount)
if err != nil {
return err.Result()
}

proposalIDBytes := keeper.cdc.MustMarshalBinaryBare(msg.ProposalID)

// TODO: Add tag for if voting period started
proposalIDBytes := []byte(fmt.Sprintf("%d", msg.ProposalID))
resTags := sdk.NewTags(
tags.Action, tags.ActionProposalDeposit,
tags.Depositor, []byte(msg.Depositor.String()),
tags.ProposalID, proposalIDBytes,
)
Expand All @@ -75,33 +72,29 @@ func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result
}

func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {

err := keeper.AddVote(ctx, msg.ProposalID, msg.Voter, msg.Option)
if err != nil {
return err.Result()
}

proposalIDBytes := keeper.cdc.MustMarshalBinaryBare(msg.ProposalID)

resTags := sdk.NewTags(
tags.Voter, []byte(msg.Voter.String()),
tags.ProposalID, proposalIDBytes,
)
return sdk.Result{
Tags: resTags,
Tags: sdk.NewTags(
tags.Action, tags.ActionProposalVote,
tags.Voter, []byte(msg.Voter.String()),
tags.ProposalID, []byte(fmt.Sprintf("%d", msg.ProposalID)),
),
}
}

// Called every block, process inflation, update validator set
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {

logger := ctx.Logger().With("module", "x/gov")

resTags = sdk.NewTags()

inactiveIterator := keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
for ; inactiveIterator.Valid(); inactiveIterator.Next() {
var proposalID uint64

keeper.cdc.MustUnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
inactiveProposal := keeper.GetProposal(ctx, proposalID)
keeper.DeleteProposal(ctx, proposalID)
Expand All @@ -119,11 +112,13 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
),
)
}

inactiveIterator.Close()

activeIterator := keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
for ; activeIterator.Valid(); activeIterator.Next() {
var proposalID uint64

keeper.cdc.MustUnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
activeProposal := keeper.GetProposal(ctx, proposalID)
passes, tallyResults := tally(ctx, keeper, activeProposal)
Expand All @@ -138,9 +133,9 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
activeProposal.SetStatus(StatusRejected)
action = tags.ActionProposalRejected
}

activeProposal.SetTallyResult(tallyResults)
keeper.SetProposal(ctx, activeProposal)

keeper.RemoveFromActiveProposalQueue(ctx, activeProposal.GetVotingEndTime(), activeProposal.GetProposalID())

logger.Info(fmt.Sprintf("proposal %d (%s) tallied; passed: %v",
Expand All @@ -149,6 +144,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
resTags = resTags.AppendTag(tags.Action, action)
resTags = resTags.AppendTag(tags.ProposalID, []byte(string(proposalID)))
}

activeIterator.Close()

return resTags
Expand Down
12 changes: 8 additions & 4 deletions x/gov/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// name to idetify transaction types
const MsgRoute = "gov"
// Governance message types and routes
const (
MsgRoute = "gov"
TypeMsgDeposit = "deposit"
TypeMsgVote = "vote"
)
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

var _, _, _ sdk.Msg = MsgSubmitProposal{}, MsgDeposit{}, MsgVote{}

Expand Down Expand Up @@ -100,7 +104,7 @@ func NewMsgDeposit(depositor sdk.AccAddress, proposalID uint64, amount sdk.Coins
// Implements Msg.
// nolint
func (msg MsgDeposit) Route() string { return MsgRoute }
func (msg MsgDeposit) Type() string { return "deposit" }
func (msg MsgDeposit) Type() string { return TypeMsgDeposit }

// Implements Msg.
func (msg MsgDeposit) ValidateBasic() sdk.Error {
Expand Down Expand Up @@ -161,7 +165,7 @@ func NewMsgVote(voter sdk.AccAddress, proposalID uint64, option VoteOption) MsgV
// Implements Msg.
// nolint
func (msg MsgVote) Route() string { return MsgRoute }
func (msg MsgVote) Type() string { return "vote" }
func (msg MsgVote) Type() string { return TypeMsgVote }

// Implements Msg.
func (msg MsgVote) ValidateBasic() sdk.Error {
Expand Down
4 changes: 3 additions & 1 deletion x/gov/tags/tags.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// nolint
package tags

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// Governance tags
var (
ActionProposalDropped = []byte("proposal-dropped")
ActionProposalPassed = []byte("proposal-passed")
ActionProposalRejected = []byte("proposal-rejected")
ActionProposalVote = []byte("proposal-vote")
ActionProposalDeposit = []byte("proposal-deposit")

Action = sdk.TagAction
Proposer = "proposer"
Expand Down