Skip to content

Commit

Permalink
feat(cli): add acc-address by id cli and grpc gateway api (backport #…
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Jun 16, 2022
1 parent 17bb4fa commit 53d0cc9
Show file tree
Hide file tree
Showing 17 changed files with 1,957 additions and 173 deletions.
1,181 changes: 1,063 additions & 118 deletions api/cosmos/auth/v1beta1/query.pulsar.go

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions api/cosmos/auth/v1beta1/query_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion baseapp/block_gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func TestBaseApp_BlockGas(t *testing.T) {
require.Equal(t, []byte("ok"), okValue)
}
// check block gas is always consumed
baseGas := uint64(63724) // baseGas is the gas consumed before tx msg
baseGas := uint64(70184) // baseGas is the gas consumed before tx msg
expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas)
if expGasConsumed > txtypes.MaxGasWanted {
// capped by gasLimit
Expand Down
15 changes: 15 additions & 0 deletions proto/cosmos/auth/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ service Query {
option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}";
}

// AccountAddressByID returns account address based on account id
rpc AccountAddressByID(QueryAccountAddressByIDRequest) returns (QueryAccountAddressByIDResponse) {
option (google.api.http).get = "/cosmos/auth/v1beta1/address_by_id/{id}";
}

// Params queries all parameters.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/auth/v1beta1/params";
Expand Down Expand Up @@ -152,3 +157,13 @@ message AddressStringToBytesRequest {
message AddressStringToBytesResponse {
bytes address_bytes = 1;
}

// QueryAccountAddressByIDRequest is the request type for AccountAddressByID rpc method
message QueryAccountAddressByIDRequest{
int64 id = 1;
}

// QueryAccountAddressByIDResponse is the response type for AccountAddressByID rpc method
message QueryAccountAddressByIDResponse {
string account_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
2 changes: 1 addition & 1 deletion x/auth/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ func (suite *AnteTestSuite) TestAnteHandlerMemoGas() {
"tx with memo has enough gas",
func() {
feeAmount = sdk.NewCoins(sdk.NewInt64Coin("atom", 0))
gasLimit = 50000
gasLimit = 60000
suite.txBuilder.SetMemo(strings.Repeat("0123456789", 10))
},
false,
Expand Down
35 changes: 35 additions & 0 deletions x/auth/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"context"
"fmt"
"strconv"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -41,6 +42,7 @@ func GetQueryCmd() *cobra.Command {

cmd.AddCommand(
GetAccountCmd(),
GetAccountAddressByIDCmd(),
GetAccountsCmd(),
QueryParamsCmd(),
QueryModuleAccountsCmd(),
Expand Down Expand Up @@ -124,6 +126,39 @@ func GetAccountCmd() *cobra.Command {
return cmd
}

// GetAccountAddressByIDCmd returns a query account that will display the account address of a given account id.
func GetAccountAddressByIDCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "address-by-id [id]",
Short: "Query for account address by account id",
Args: cobra.ExactArgs(1),
Example: fmt.Sprintf("%s q auth address-by-id 1", version.AppName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

id, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.AccountAddressByID(cmd.Context(), &types.QueryAccountAddressByIDRequest{Id: id})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetAccountsCmd returns a query command that will display a list of accounts
func GetAccountsCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down
45 changes: 45 additions & 0 deletions x/auth/client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/auth/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
Expand Down Expand Up @@ -280,6 +281,50 @@ func (s *IntegrationTestSuite) TestCLISignBatch() {
s.Require().Error(err)
}

func (s *IntegrationTestSuite) TestCliGetAccountAddressByID() {
require := s.Require()
val1 := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
}{
{
"not enough args",
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
true,
},
{
"invalid account id",
[]string{fmt.Sprint(-1), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
true,
},
{
"valid account id",
[]string{fmt.Sprint(0), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
false,
},
}

for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := authcli.GetAccountAddressByIDCmd()
clientCtx := val1.ClientCtx

queryResJSON, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
var res types.QueryAccountAddressByIDResponse
require.NoError(val1.ClientCtx.Codec.UnmarshalJSON(queryResJSON.Bytes(), &res))
require.NotNil(res.GetAccountAddress())
}
})
}
}

func (s *IntegrationTestSuite) TestCLISignAminoJSON() {
require := s.Require()
val1 := s.network.Validators[0]
Expand Down
18 changes: 18 additions & 0 deletions x/auth/keeper/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ func (ak AccountKeeper) HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool {
return store.Has(types.AddressStoreKey(addr))
}

// HasAccountAddressByID checks account address exists by id.
func (ak AccountKeeper) HasAccountAddressByID(ctx sdk.Context, id uint64) bool {
store := ctx.KVStore(ak.key)
return store.Has(types.AccountNumberStoreKey(id))
}

// GetAccount implements AccountKeeperI.
func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI {
store := ctx.KVStore(ak.key)
Expand All @@ -42,6 +48,16 @@ func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.A
return ak.decodeAccount(bz)
}

// GetAccountAddressById returns account address by id.
func (ak AccountKeeper) GetAccountAddressByID(ctx sdk.Context, id uint64) string {
store := ctx.KVStore(ak.key)
bz := store.Get(types.AccountNumberStoreKey(id))
if bz == nil {
return ""
}
return sdk.AccAddress(bz).String()
}

// GetAllAccounts returns all accounts in the accountKeeper.
func (ak AccountKeeper) GetAllAccounts(ctx sdk.Context) (accounts []types.AccountI) {
ak.IterateAccounts(ctx, func(acc types.AccountI) (stop bool) {
Expand All @@ -63,6 +79,7 @@ func (ak AccountKeeper) SetAccount(ctx sdk.Context, acc types.AccountI) {
}

store.Set(types.AddressStoreKey(addr), bz)
store.Set(types.AccountNumberStoreKey(acc.GetAccountNumber()), addr.Bytes())
}

// RemoveAccount removes an account for the account mapper store.
Expand All @@ -71,6 +88,7 @@ func (ak AccountKeeper) RemoveAccount(ctx sdk.Context, acc types.AccountI) {
addr := acc.GetAddress()
store := ctx.KVStore(ak.key)
store.Delete(types.AddressStoreKey(addr))
store.Delete(types.AccountNumberStoreKey(acc.GetAccountNumber()))
}

// IterateAccounts iterates over all the stored accounts and performs a callback function.
Expand Down
18 changes: 18 additions & 0 deletions x/auth/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ import (

var _ types.QueryServer = AccountKeeper{}

func (ak AccountKeeper) AccountAddressByID(c context.Context, req *types.QueryAccountAddressByIDRequest) (*types.QueryAccountAddressByIDResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

if req.Id < 0 {
return nil, status.Error(codes.InvalidArgument, "Invalid account id")
}

ctx := sdk.UnwrapSDKContext(c)
address := ak.GetAccountAddressByID(ctx, uint64(req.GetId()))
if len(address) == 0 {
return nil, status.Errorf(codes.NotFound, "account address not found with id %d", req.Id)
}

return &types.QueryAccountAddressByIDResponse{AccountAddress: address}, nil
}

func (ak AccountKeeper) Accounts(c context.Context, req *types.QueryAccountsRequest) (*types.QueryAccountsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
Expand Down
63 changes: 63 additions & 0 deletions x/auth/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"math"
"sort"

"github.com/cosmos/cosmos-sdk/testutil/testdata"
Expand Down Expand Up @@ -153,6 +154,68 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccount() {
}
}

func (suite *KeeperTestSuite) TestGRPCQueryAccountAddressByID() {
var req *types.QueryAccountAddressByIDRequest
_, _, addr := testdata.KeyTestPubAddr()

testCases := []struct {
msg string
malleate func()
expPass bool
posttests func(res *types.QueryAccountAddressByIDResponse)
}{
{
"invalid request",
func() {
req = &types.QueryAccountAddressByIDRequest{Id: -1}
},
false,
func(res *types.QueryAccountAddressByIDResponse) {},
},
{
"account address not found",
func() {
req = &types.QueryAccountAddressByIDRequest{Id: math.MaxInt64}
},
false,
func(res *types.QueryAccountAddressByIDResponse) {},
},
{
"valid request",
func() {
account := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)
suite.app.AccountKeeper.SetAccount(suite.ctx, account)
req = &types.QueryAccountAddressByIDRequest{Id: int64(account.GetAccountNumber())}
},
true,
func(res *types.QueryAccountAddressByIDResponse) {
suite.Require().NotNil(res.AccountAddress)
},
},
}

for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)

res, err := suite.queryClient.AccountAddressByID(ctx, req)

if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
} else {
suite.Require().Error(err)
suite.Require().Nil(res)
}

tc.posttests(res)
})
}
}

func (suite *KeeperTestSuite) TestGRPCQueryParameters() {
var (
req *types.QueryParamsRequest
Expand Down
Loading

0 comments on commit 53d0cc9

Please sign in to comment.