added querier to gov module
This commit is contained in:
parent
1d1a95656a
commit
804baa70f4
|
@ -393,10 +393,18 @@ func handleQueryP2P(app *BaseApp, path []string, req abci.RequestQuery) (res abc
|
||||||
|
|
||||||
func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) {
|
func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||||
// "/custom" prefix for keeper queries
|
// "/custom" prefix for keeper queries
|
||||||
queryable := app.queryrouter.Route(path[1])
|
querier := app.queryrouter.Route(path[1])
|
||||||
ctx := app.checkState.ctx
|
ctx := app.checkState.ctx
|
||||||
res, err := queryable.Query(ctx, path[2:], req)
|
resBytes, err := querier(ctx, path[2:], req)
|
||||||
return
|
if err != nil {
|
||||||
|
return abci.ResponseQuery{
|
||||||
|
Code: uint32(err.ABCICode()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return abci.ResponseQuery{
|
||||||
|
Code: uint32(sdk.ABCICodeOK),
|
||||||
|
Value: resBytes,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginBlock implements the ABCI application interface.
|
// BeginBlock implements the ABCI application interface.
|
||||||
|
|
|
@ -6,14 +6,14 @@ import (
|
||||||
|
|
||||||
// QueryRouter provides queryables for each query path.
|
// QueryRouter provides queryables for each query path.
|
||||||
type QueryRouter interface {
|
type QueryRouter interface {
|
||||||
AddRoute(r string, h sdk.CustomQueryable) (rtr QueryRouter)
|
AddRoute(r string, h sdk.Querier) (rtr QueryRouter)
|
||||||
Route(path string) (h sdk.CustomQueryable)
|
Route(path string) (h sdk.Querier)
|
||||||
}
|
}
|
||||||
|
|
||||||
// map a transaction type to a handler and an initgenesis function
|
// map a transaction type to a handler and an initgenesis function
|
||||||
type queryroute struct {
|
type queryroute struct {
|
||||||
r string
|
r string
|
||||||
h sdk.CustomQueryable
|
h sdk.Querier
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryrouter struct {
|
type queryrouter struct {
|
||||||
|
@ -30,7 +30,7 @@ func NewQueryRouter() *queryrouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRoute - TODO add description
|
// AddRoute - TODO add description
|
||||||
func (rtr *queryrouter) AddRoute(r string, h sdk.CustomQueryable) QueryRouter {
|
func (rtr *queryrouter) AddRoute(r string, h sdk.Querier) QueryRouter {
|
||||||
if !isAlphaNumeric(r) {
|
if !isAlphaNumeric(r) {
|
||||||
panic("route expressions can only contain alphanumeric characters")
|
panic("route expressions can only contain alphanumeric characters")
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func (rtr *queryrouter) AddRoute(r string, h sdk.CustomQueryable) QueryRouter {
|
||||||
|
|
||||||
// Route - TODO add description
|
// Route - TODO add description
|
||||||
// TODO handle expressive matches.
|
// TODO handle expressive matches.
|
||||||
func (rtr *queryrouter) Route(path string) (h sdk.CustomQueryable) {
|
func (rtr *queryrouter) Route(path string) (h sdk.Querier) {
|
||||||
for _, route := range rtr.routes {
|
for _, route := range rtr.routes {
|
||||||
if route.r == path {
|
if route.r == path {
|
||||||
return route.h
|
return route.h
|
||||||
|
|
|
@ -2,6 +2,5 @@ package types
|
||||||
|
|
||||||
import abci "github.com/tendermint/tendermint/abci/types"
|
import abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
type CustomQueryable interface {
|
// Type for querier functions on keepers to implement to handle custom queries
|
||||||
Query(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error)
|
type Querier = func(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error)
|
||||||
}
|
|
||||||
|
|
|
@ -108,6 +108,52 @@ func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposal Proposal) {
|
||||||
store.Delete(KeyProposal(proposal.GetProposalID()))
|
store.Delete(KeyProposal(proposal.GetProposalID()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint: gocyclo
|
||||||
|
// Get Proposal from store by ProposalID
|
||||||
|
func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddress, depositerAddr sdk.AccAddress, status ProposalStatus, numLatest int64) []Proposal {
|
||||||
|
|
||||||
|
maxProposalID, err := keeper.peekCurrentProposalID(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
matchingProposals := []Proposal{}
|
||||||
|
|
||||||
|
if numLatest <= 0 {
|
||||||
|
numLatest = maxProposalID
|
||||||
|
}
|
||||||
|
|
||||||
|
for proposalID := maxProposalID - numLatest; proposalID < maxProposalID; proposalID++ {
|
||||||
|
if voterAddr != nil && len(voterAddr) != 0 {
|
||||||
|
_, found := keeper.GetVote(ctx, proposalID, voterAddr)
|
||||||
|
if !found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if depositerAddr != nil && len(depositerAddr) != 0 {
|
||||||
|
_, found := keeper.GetDeposit(ctx, proposalID, depositerAddr)
|
||||||
|
if !found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proposal := keeper.GetProposal(ctx, proposalID)
|
||||||
|
if proposal == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if validProposalStatus(status) {
|
||||||
|
if proposal.GetStatus() != status {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matchingProposals = append(matchingProposals, proposal)
|
||||||
|
}
|
||||||
|
return matchingProposals
|
||||||
|
}
|
||||||
|
|
||||||
func (keeper Keeper) setInitialProposalID(ctx sdk.Context, proposalID int64) sdk.Error {
|
func (keeper Keeper) setInitialProposalID(ctx sdk.Context, proposalID int64) sdk.Error {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
bz := store.Get(KeyNextProposalID)
|
bz := store.Get(KeyNextProposalID)
|
||||||
|
@ -131,6 +177,7 @@ func (keeper Keeper) GetLastProposalID(ctx sdk.Context) (proposalID int64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the next available ProposalID and increments it
|
||||||
func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sdk.Error) {
|
func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sdk.Error) {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
bz := store.Get(KeyNextProposalID)
|
bz := store.Get(KeyNextProposalID)
|
||||||
|
@ -143,6 +190,19 @@ func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sd
|
||||||
return proposalID, nil
|
return proposalID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Peeks the next available ProposalID without incrementing it
|
||||||
|
func (keeper Keeper) peekCurrentProposalID(ctx sdk.Context) (proposalID int64, err sdk.Error) {
|
||||||
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
|
bz := store.Get(KeyNextProposalID)
|
||||||
|
if bz == nil {
|
||||||
|
return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set")
|
||||||
|
}
|
||||||
|
keeper.cdc.MustUnmarshalBinary(bz, &proposalID)
|
||||||
|
bz = keeper.cdc.MustMarshalBinary(proposalID + 1)
|
||||||
|
store.Set(KeyNextProposalID, bz)
|
||||||
|
return proposalID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
||||||
proposal.SetVotingStartBlock(ctx.BlockHeight())
|
proposal.SetVotingStartBlock(ctx.BlockHeight())
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
proposal.SetStatus(StatusVotingPeriod)
|
||||||
|
|
|
@ -5,52 +5,167 @@ import (
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Querier struct {
|
func NewQuerier(keeper Keeper) sdk.Querier {
|
||||||
keeper Keeper
|
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
||||||
}
|
switch path[0] {
|
||||||
|
case "proposal":
|
||||||
func NewQuerier(keeper Keeper) {
|
return queryProposal(ctx, path[1:], req, keeper)
|
||||||
return Querier{
|
case "deposit":
|
||||||
keeper: keeper,
|
return queryDeposit(ctx, path[1:], req, keeper)
|
||||||
|
case "vote":
|
||||||
|
return queryVote(ctx, path[1:], req, keeper)
|
||||||
|
case "deposits":
|
||||||
|
return queryDeposits(ctx, path[1:], req, keeper)
|
||||||
|
case "votes":
|
||||||
|
return queryVotes(ctx, path[1:], req, keeper)
|
||||||
|
case "proposals":
|
||||||
|
return queryProposals(ctx, path[1:], req, keeper)
|
||||||
|
case "tally":
|
||||||
|
return queryTally(ctx, path[1:], req, keeper)
|
||||||
|
default:
|
||||||
|
return nil, sdk.ErrUnknownRequest("unknown gov query endpoint")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (keeper Keeper) Query(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
// Params for query 'custom/gov/proposal'
|
||||||
switch path[0] {
|
type QueryProposalParams struct {
|
||||||
case "tally":
|
ProposalID int64
|
||||||
return QueryTally(ctx, path[1:], req)
|
|
||||||
case "proposal":
|
|
||||||
return handleMsgSubmitProposal(ctx, keeper, msg)
|
|
||||||
case MsgVote:
|
|
||||||
return handleMsgVote(ctx, keeper, msg)
|
|
||||||
default:
|
|
||||||
errMsg := "Unrecognized gov msg type"
|
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func QueryProposal(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
var proposalID int64
|
var params QueryProposalParams
|
||||||
err := keeper.cdc.UnmarshalBinary(req.Data, proposalID)
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, ¶ms)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
return []byte{}, sdk.ErrUnknownRequest()
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
}
|
}
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
|
||||||
|
proposal := keeper.GetProposal(ctx, params.ProposalID)
|
||||||
if proposal == nil {
|
if proposal == nil {
|
||||||
return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID)
|
return []byte{}, ErrUnknownProposal(DefaultCodespace, params.ProposalID)
|
||||||
}
|
}
|
||||||
return keeper.cdc.MustMarshalBinary(proposal), nil
|
return keeper.cdc.MustMarshalBinary(proposal), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func QueryTally(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
// Params for query 'custom/gov/deposit'
|
||||||
var proposalID int64
|
type QueryDepositParams struct {
|
||||||
err := keeper.cdc.UnmarshalBinary(req.Data, proposalID)
|
ProposalID int64
|
||||||
if err != nil {
|
Depositer sdk.AccAddress
|
||||||
return []byte{}, sdk.ErrUnknownRequest()
|
}
|
||||||
}
|
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
if proposal == nil {
|
var params QueryDepositParams
|
||||||
return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID)
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, params)
|
||||||
}
|
if err2 != nil {
|
||||||
passes, _ := tally(ctx, keeper, proposal)
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
|
}
|
||||||
|
|
||||||
|
deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer)
|
||||||
|
return keeper.cdc.MustMarshalBinary(deposit), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params for query 'custom/gov/vote'
|
||||||
|
type QueryVoteParams struct {
|
||||||
|
ProposalID int64
|
||||||
|
Voter sdk.AccAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
|
var params QueryVoteParams
|
||||||
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, ¶ms)
|
||||||
|
if err2 != nil {
|
||||||
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
|
}
|
||||||
|
|
||||||
|
vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter)
|
||||||
|
return keeper.cdc.MustMarshalBinary(vote), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params for query 'custom/gov/deposits'
|
||||||
|
type QueryDepositsParams struct {
|
||||||
|
ProposalID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
|
var params QueryDepositParams
|
||||||
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, ¶ms)
|
||||||
|
if err2 != nil {
|
||||||
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
|
}
|
||||||
|
|
||||||
|
var deposits []Deposit
|
||||||
|
depositsIterator := keeper.GetDeposits(ctx, params.ProposalID)
|
||||||
|
for ; depositsIterator.Valid(); depositsIterator.Next() {
|
||||||
|
deposit := Deposit{}
|
||||||
|
keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), &deposit)
|
||||||
|
deposits = append(deposits, deposit)
|
||||||
|
}
|
||||||
|
|
||||||
|
return keeper.cdc.MustMarshalBinary(deposits), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params for query 'custom/gov/votes'
|
||||||
|
type QueryVotesParams struct {
|
||||||
|
ProposalID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
|
var params QueryVotesParams
|
||||||
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, ¶ms)
|
||||||
|
if err2 != nil {
|
||||||
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
|
}
|
||||||
|
|
||||||
|
var votes []Vote
|
||||||
|
votesIterator := keeper.GetVotes(ctx, params.ProposalID)
|
||||||
|
for ; votesIterator.Valid(); votesIterator.Next() {
|
||||||
|
vote := Vote{}
|
||||||
|
keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), &vote)
|
||||||
|
votes = append(votes, vote)
|
||||||
|
}
|
||||||
|
|
||||||
|
return keeper.cdc.MustMarshalBinary(votes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params for query 'custom/gov/proposals'
|
||||||
|
type QueryProposalsParams struct {
|
||||||
|
Voter sdk.AccAddress
|
||||||
|
Depositer sdk.AccAddress
|
||||||
|
ProposalStatus ProposalStatus
|
||||||
|
NumLatestProposals int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
|
var params QueryProposalsParams
|
||||||
|
err2 := keeper.cdc.UnmarshalBinary(req.Data, ¶ms)
|
||||||
|
if err2 != nil {
|
||||||
|
return []byte{}, sdk.ErrUnknownRequest("incorrectly formatted request data")
|
||||||
|
}
|
||||||
|
|
||||||
|
proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals)
|
||||||
|
|
||||||
|
bz := keeper.cdc.MustMarshalBinary(proposals)
|
||||||
|
return bz, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params for query 'custom/gov/tally'
|
||||||
|
type QueryTallyParams struct {
|
||||||
|
ProposalID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||||
|
// TODO: Dependant on #1914
|
||||||
|
|
||||||
|
// var proposalID int64
|
||||||
|
// err2 := keeper.cdc.UnmarshalBinary(req.Data, proposalID)
|
||||||
|
// if err2 != nil {
|
||||||
|
// return []byte{}, sdk.ErrUnknownRequest()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// proposal := keeper.GetProposal(ctx, proposalID)
|
||||||
|
// if proposal == nil {
|
||||||
|
// return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID)
|
||||||
|
// }
|
||||||
|
// _, tallyResult, _ := tally(ctx, keeper, proposal)
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue