Skip to content

Commit

Permalink
Merge PR cosmos#3767: Added querier for auth module
Browse files Browse the repository at this point in the history
  • Loading branch information
jackzampolin authored Mar 1, 2019
2 parents b47032d + f7df00f commit 7ac01bd
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 31 deletions.
4 changes: 2 additions & 2 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ decoded automatically.

* [\#3653] Prompt user confirmation prior to signing and broadcasting a transaction.
* [\#3670] CLI support for showing bech32 addresses in Ledger devices
* [\#3711] Update `tx sign` to use `--from` instead of the deprecated `--name`
CLI flag.
* [\#3711] Update `tx sign` to use `--from` instead of the deprecated `--name` CLI flag.
* [\#3730](https://github.com/cosmos/cosmos-sdk/issues/3730) Improve workflow for `gaiad gentx` with offline public keys, by outputting stdtx file that needs to be signed.
* [\#3761](https://github.com/cosmos/cosmos-sdk/issues/3761) Querying account related information using custom querier in auth module

### Gaia

Expand Down
39 changes: 19 additions & 20 deletions client/context/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,13 @@ func (ctx CLIContext) GetAccount(address []byte) (auth.Account, error) {
return nil, errors.New("account decoder required but not provided")
}

res, err := ctx.QueryStore(auth.AddressStoreKey(address), ctx.AccountStore)
res, err := ctx.queryAccount(address)
if err != nil {
return nil, err
} else if len(res) == 0 {
return nil, ErrInvalidAccount(address)
}

account, err := ctx.AccDecoder(res)
if err != nil {
var account auth.Account
if err := ctx.Codec.UnmarshalJSON(res, &account); err != nil {
return nil, err
}

Expand Down Expand Up @@ -117,32 +115,33 @@ func (ctx CLIContext) GetAccountSequence(address []byte) (uint64, error) {
// error is returned if it does not.
func (ctx CLIContext) EnsureAccountExists() error {
addr := ctx.GetFromAddress()
accountBytes, err := ctx.QueryStore(auth.AddressStoreKey(addr), ctx.AccountStore)
if err != nil {
return err
}

if len(accountBytes) == 0 {
return ErrInvalidAccount(addr)
}

return nil
return ctx.EnsureAccountExistsFromAddr(addr)
}

// EnsureAccountExistsFromAddr ensures that an account exists for a given
// address. Instead of using the context's from name, a direct address is
// given. An error is returned if it does not.
func (ctx CLIContext) EnsureAccountExistsFromAddr(addr sdk.AccAddress) error {
accountBytes, err := ctx.QueryStore(auth.AddressStoreKey(addr), ctx.AccountStore)
_, err := ctx.queryAccount(addr)
return err
}

// queryAccount queries an account using custom query endpoint of auth module
// returns an error if result is `null` otherwise account data
func (ctx CLIContext) queryAccount(addr sdk.AccAddress) ([]byte, error) {
bz, err := ctx.Codec.MarshalJSON(auth.NewQueryAccountParams(addr))
if err != nil {
return err
return nil, err
}

if len(accountBytes) == 0 {
return ErrInvalidAccount(addr)
route := fmt.Sprintf("custom/%s/%s", ctx.AccountStore, auth.QueryAccount)

res, err := ctx.QueryWithData(route, bz)
if err != nil {
return nil, err
}

return nil
return res, nil
}

// query performs a query from a Tendermint node with the provided store name
Expand Down
3 changes: 2 additions & 1 deletion cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper))

app.QueryRouter().
AddRoute(auth.QuerierRoute, auth.NewQuerier(app.accountKeeper)).
AddRoute(distr.QuerierRoute, distr.NewQuerier(app.distrKeeper)).
AddRoute(gov.QuerierRoute, gov.NewQuerier(app.govKeeper)).
AddRoute(slashing.QuerierRoute, slashing.NewQuerier(app.slashingKeeper, app.cdc)).
Expand Down Expand Up @@ -324,7 +325,7 @@ func (app *GaiaApp) LoadHeight(height int64) error {
return app.LoadVersion(height, app.keyMain)
}

//______________________________________________________________________________________________
// ______________________________________________________________________________________________

var _ sdk.StakingHooks = StakingHooks{}

Expand Down
21 changes: 13 additions & 8 deletions x/auth/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ import (
"github.com/cosmos/cosmos-sdk/x/params"
)

var (
// AddressStoreKeyPrefix prefix for account-by-address store
AddressStoreKeyPrefix = []byte{0x01}

globalAccountNumberKey = []byte("globalAccountNumber")

const (
// StoreKey is string representation of the store key for auth
StoreKey = "acc"

// FeeStoreKey is a string representation of the store key for fees
FeeStoreKey = "fee"

// QuerierRoute is the querier route for acc
QuerierRoute = StoreKey
)

var (
// AddressStoreKeyPrefix prefix for account-by-address store
AddressStoreKeyPrefix = []byte{0x01}

globalAccountNumberKey = []byte("globalAccountNumber")
)

// AccountKeeper encodes/decodes accounts using the go-amino (binary)
Expand Down Expand Up @@ -193,7 +198,7 @@ func (ak AccountKeeper) GetNextAccountNumber(ctx sdk.Context) uint64 {
return accNumber
}

//-----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Params

// SetParams sets the auth module's parameters.
Expand All @@ -207,7 +212,7 @@ func (ak AccountKeeper) GetParams(ctx sdk.Context) (params Params) {
return
}

//-----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Misc.

func (ak AccountKeeper) decodeAccount(bz []byte) (acc Account) {
Expand Down
57 changes: 57 additions & 0 deletions x/auth/querier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package auth

import (
"fmt"

abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// query endpoints supported by the auth Querier
const (
QueryAccount = "account"
)

// creates a querier for auth REST endpoints
func NewQuerier(keeper AccountKeeper) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) {
switch path[0] {
case QueryAccount:
return queryAccount(ctx, req, keeper)
default:
return nil, sdk.ErrUnknownRequest("unknown auth query endpoint")
}
}
}

// defines the params for query: "custom/acc/account"
type QueryAccountParams struct {
Address sdk.AccAddress
}

func NewQueryAccountParams(addr sdk.AccAddress) QueryAccountParams {
return QueryAccountParams{
Address: addr,
}
}

func queryAccount(ctx sdk.Context, req abci.RequestQuery, keeper AccountKeeper) ([]byte, sdk.Error) {
var params QueryAccountParams
if err := keeper.cdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
}

account := keeper.GetAccount(ctx, params.Address)
if account == nil {
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", params.Address))
}

bz, err := codec.MarshalJSONIndent(keeper.cdc, account)
if err != nil {
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
}

return bz, nil
}
41 changes: 41 additions & 0 deletions x/auth/querier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package auth

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
)

func Test_queryAccount(t *testing.T) {
input := setupTestInput()
req := abci.RequestQuery{
Path: fmt.Sprintf("custom/%s/%s", QuerierRoute, QueryAccount),
Data: []byte{},
}

res, err := queryAccount(input.ctx, req, input.ak)
require.NotNil(t, err)
require.Nil(t, res)

req.Data = input.cdc.MustMarshalJSON(NewQueryAccountParams([]byte("")))
res, err = queryAccount(input.ctx, req, input.ak)
require.NotNil(t, err)
require.Nil(t, res)

_, _, addr := keyPubAddr()
req.Data = input.cdc.MustMarshalJSON(NewQueryAccountParams(addr))
res, err = queryAccount(input.ctx, req, input.ak)
require.NotNil(t, err)
require.Nil(t, res)

input.ak.SetAccount(input.ctx, input.ak.NewAccountWithAddress(input.ctx, addr))
res, err = queryAccount(input.ctx, req, input.ak)
require.Nil(t, err)
require.NotNil(t, res)

var account Account
err2 := input.cdc.UnmarshalJSON(res, &account)
require.Nil(t, err2)
}

0 comments on commit 7ac01bd

Please sign in to comment.