custom queriables

This commit is contained in:
Sunny Aggarwal 2018-07-31 18:48:32 -07:00
parent d8f01be211
commit 1d1a95656a
4 changed files with 165 additions and 14 deletions

View File

@ -41,13 +41,14 @@ const (
// BaseApp reflects the ABCI application implementation.
type BaseApp struct {
// initialized on creation
Logger log.Logger
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
router Router // handle any kind of message
codespacer *sdk.Codespacer // handle module codespacing
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
Logger log.Logger
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
router Router // handle any kind of message
queryrouter QueryRouter // router for redirecting query calls
codespacer *sdk.Codespacer // handle module codespacing
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
anteHandler sdk.AnteHandler // ante handler for fee and auth
@ -84,13 +85,14 @@ var _ abci.Application = (*BaseApp)(nil)
// Accepts variable number of option functions, which act on the BaseApp to set configuration choices
func NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp)) *BaseApp {
app := &BaseApp{
Logger: logger,
name: name,
db: db,
cms: store.NewCommitMultiStore(db),
router: NewRouter(),
codespacer: sdk.NewCodespacer(),
txDecoder: txDecoder,
Logger: logger,
name: name,
db: db,
cms: store.NewCommitMultiStore(db),
router: NewRouter(),
queryrouter: NewQueryRouter(),
codespacer: sdk.NewCodespacer(),
txDecoder: txDecoder,
}
// Register the undefined & root codespaces, which should not be used by
@ -135,6 +137,31 @@ func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
app.cms.MountStoreWithDB(key, typ, nil)
}
<<<<<<< HEAD
=======
// nolint - Set functions
func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) {
app.initChainer = initChainer
}
func (app *BaseApp) SetBeginBlocker(beginBlocker sdk.BeginBlocker) {
app.beginBlocker = beginBlocker
}
func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) {
app.endBlocker = endBlocker
}
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
app.anteHandler = ah
}
func (app *BaseApp) SetAddrPeerFilter(pf sdk.PeerFilter) {
app.addrPeerFilter = pf
}
func (app *BaseApp) SetPubKeyPeerFilter(pf sdk.PeerFilter) {
app.pubkeyPeerFilter = pf
}
func (app *BaseApp) Router() Router { return app.router }
func (app *BaseApp) QueryRouter() QueryRouter { return app.queryrouter }
>>>>>>> custom queriables
// load latest application version
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
err := app.cms.LoadLatestVersion()
@ -291,6 +318,8 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
return handleQueryStore(app, path, req)
case "p2p":
return handleQueryP2P(app, path, req)
case "custom":
return handleQueryCustom(app, path, req)
}
msg := "unknown query path"
@ -362,6 +391,14 @@ func handleQueryP2P(app *BaseApp, path []string, req abci.RequestQuery) (res abc
return sdk.ErrUnknownRequest(msg).QueryResult()
}
func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) {
// "/custom" prefix for keeper queries
queryable := app.queryrouter.Route(path[1])
ctx := app.checkState.ctx
res, err := queryable.Query(ctx, path[2:], req)
return
}
// BeginBlock implements the ABCI application interface.
func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
if app.cms.TracingEnabled() {

51
baseapp/queryrouter.go Normal file
View File

@ -0,0 +1,51 @@
package baseapp
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// QueryRouter provides queryables for each query path.
type QueryRouter interface {
AddRoute(r string, h sdk.CustomQueryable) (rtr QueryRouter)
Route(path string) (h sdk.CustomQueryable)
}
// map a transaction type to a handler and an initgenesis function
type queryroute struct {
r string
h sdk.CustomQueryable
}
type queryrouter struct {
routes []queryroute
}
// nolint
// NewRouter - create new router
// TODO either make Function unexported or make return type (router) Exported
func NewQueryRouter() *queryrouter {
return &queryrouter{
routes: make([]queryroute, 0),
}
}
// AddRoute - TODO add description
func (rtr *queryrouter) AddRoute(r string, h sdk.CustomQueryable) QueryRouter {
if !isAlphaNumeric(r) {
panic("route expressions can only contain alphanumeric characters")
}
rtr.routes = append(rtr.routes, queryroute{r, h})
return rtr
}
// Route - TODO add description
// TODO handle expressive matches.
func (rtr *queryrouter) Route(path string) (h sdk.CustomQueryable) {
for _, route := range rtr.routes {
if route.r == path {
return route.h
}
}
return nil
}

7
types/queryable.go Normal file
View File

@ -0,0 +1,7 @@
package types
import abci "github.com/tendermint/tendermint/abci/types"
type CustomQueryable interface {
Query(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error)
}

56
x/gov/queryable.go Normal file
View File

@ -0,0 +1,56 @@
package gov
import (
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
)
type Querier struct {
keeper Keeper
}
func NewQuerier(keeper Keeper) {
return Querier{
keeper: keeper,
}
}
func (keeper Keeper) Query(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
switch path[0] {
case "tally":
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) {
var proposalID int64
err := keeper.cdc.UnmarshalBinary(req.Data, proposalID)
if err != nil {
return []byte{}, sdk.ErrUnknownRequest()
}
proposal := keeper.GetProposal(ctx, proposalID)
if proposal == nil {
return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID)
}
return keeper.cdc.MustMarshalBinary(proposal), nil
}
func QueryTally(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
var proposalID int64
err := keeper.cdc.UnmarshalBinary(req.Data, proposalID)
if err != nil {
return []byte{}, sdk.ErrUnknownRequest()
}
proposal := keeper.GetProposal(ctx, proposalID)
if proposal == nil {
return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID)
}
passes, _ := tally(ctx, keeper, proposal)
}