Add Query routing to rootMultiStore
This commit is contained in:
parent
57b28d95de
commit
bc325c4d1c
|
@ -2,10 +2,13 @@ package store
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
@ -28,6 +31,7 @@ type rootMultiStore struct {
|
|||
}
|
||||
|
||||
var _ CommitMultiStore = (*rootMultiStore)(nil)
|
||||
var _ Queryable = (*rootMultiStore)(nil)
|
||||
|
||||
func NewCommitMultiStore(db dbm.DB) *rootMultiStore {
|
||||
return &rootMultiStore{
|
||||
|
@ -185,6 +189,52 @@ func (rs *rootMultiStore) GetStoreByName(name string) Store {
|
|||
return rs.stores[key]
|
||||
}
|
||||
|
||||
//---------------------- Query ------------------
|
||||
|
||||
func (rs *rootMultiStore) Query(req abci.RequestQuery) abci.ResponseQuery {
|
||||
// Query just routes this to a substore.
|
||||
path := req.Path
|
||||
storeName, subpath, err := parsePath(path)
|
||||
if err != nil {
|
||||
return err.Result().ToQuery()
|
||||
}
|
||||
|
||||
store := rs.GetStoreByName(storeName)
|
||||
if store == nil {
|
||||
msg := fmt.Sprintf("no such store: %s", storeName)
|
||||
return sdk.ErrUnknownRequest(msg).Result().ToQuery()
|
||||
}
|
||||
query, ok := store.(Queryable)
|
||||
if !ok {
|
||||
msg := fmt.Sprintf("store %s doesn't support queries", storeName)
|
||||
return sdk.ErrUnknownRequest(msg).Result().ToQuery()
|
||||
}
|
||||
|
||||
// trim the path and make the query
|
||||
req.Path = subpath
|
||||
res := query.Query(req)
|
||||
|
||||
// Note: later we have to think about adding information about
|
||||
// the multistore -> store path to the proof
|
||||
return res
|
||||
}
|
||||
|
||||
// parsePath expects a format like /<storeName>[/<subpath>]
|
||||
// Must start with /, subpath may be empty
|
||||
// Returns error if it doesn't start with /
|
||||
func parsePath(path string) (storeName string, subpath string, err sdk.Error) {
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
err = sdk.ErrUnknownRequest(fmt.Sprintf("invalid path: %s", path))
|
||||
return
|
||||
}
|
||||
paths := strings.SplitN(path[1:], "/", 2)
|
||||
storeName = paths[0]
|
||||
if len(paths) == 2 {
|
||||
subpath = paths[1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storeParams) (store CommitStore, err error) {
|
||||
|
|
|
@ -19,3 +19,4 @@ type CacheWrap = types.CacheWrap
|
|||
type CommitID = types.CommitID
|
||||
type StoreKey = types.StoreKey
|
||||
type StoreType = types.StoreType
|
||||
type Queryable = types.Queryable
|
||||
|
|
|
@ -2,8 +2,9 @@ package types
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"runtime"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
type CodeType uint32
|
||||
|
|
|
@ -38,3 +38,11 @@ type Result struct {
|
|||
func (res Result) IsOK() bool {
|
||||
return res.Code.IsOK()
|
||||
}
|
||||
|
||||
// ToQuery allows us to return sdk.Error.Result() in query responses
|
||||
func (res Result) ToQuery() abci.ResponseQuery {
|
||||
return abci.ResponseQuery{
|
||||
Code: uint32(res.Code),
|
||||
Log: res.Log,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package types
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
|
@ -25,6 +26,14 @@ type CommitStore interface {
|
|||
Store
|
||||
}
|
||||
|
||||
// Queryable allows a Store to expose internal state to the abci.Query
|
||||
// interface. Multistore can route requests to the proper Store.
|
||||
//
|
||||
// This is an optional, but useful extension to any CommitStore
|
||||
type Queryable interface {
|
||||
Query(abci.RequestQuery) abci.ResponseQuery
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// MultiStore
|
||||
|
||||
|
|
Loading…
Reference in New Issue