Skip to content

Commit

Permalink
feat: add feegrant query to see allowances from a given granter (#10947)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmwaters authored Jan 21, 2022
1 parent 628547c commit eb01537
Show file tree
Hide file tree
Showing 13 changed files with 2,272 additions and 93 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10507](https://github.com/cosmos/cosmos-sdk/pull/10507) Add middleware for tx priority.
* [\#10311](https://github.com/cosmos/cosmos-sdk/pull/10311) Adds cli to use tips transactions. It adds an `--aux` flag to all CLI tx commands to generate the aux signer data (with optional tip), and a new `tx aux-to-fee` subcommand to let the fee payer gather aux signer data and broadcast the tx
* [\#10430](https://github.com/cosmos/cosmos-sdk/pull/10430) ADR-040: Add store/v2 `MultiStore` implementation
* [\#10947](https://github.com/cosmos/cosmos-sdk/pull/10947) Add `AllowancesByGranter` query to the feegrant module

### API Breaking Changes

Expand Down
1,341 changes: 1,284 additions & 57 deletions api/cosmos/feegrant/v1beta1/query.pulsar.go

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions api/cosmos/feegrant/v1beta1/query_grpc.pb.go

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

23 changes: 23 additions & 0 deletions proto/cosmos/feegrant/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ service Query {
rpc Allowances(QueryAllowancesRequest) returns (QueryAllowancesResponse) {
option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowances/{grantee}";
}

// AllowancesByGranter returns all the grants given by an address
// Since v0.46
rpc AllowancesByGranter(QueryAllowancesByGranterRequest) returns (QueryAllowancesByGranterResponse) {
option (google.api.http).get = "/cosmos/feegrant/v1beta1/issued/{granter}";
}
}

// QueryAllowanceRequest is the request type for the Query/Allowance RPC method.
Expand Down Expand Up @@ -54,3 +60,20 @@ message QueryAllowancesResponse {
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryAllowancesByGranterRequest is the request type for the Query/AllowancesByGranter RPC method.
message QueryAllowancesByGranterRequest {
string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryAllowancesByGranterResponse is the response type for the Query/AllowancesByGranter RPC method.
message QueryAllowancesByGranterResponse {
// allowances that have been issued by the granter.
repeated cosmos.feegrant.v1beta1.Grant allowances = 1;

// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
56 changes: 53 additions & 3 deletions x/feegrant/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ func GetQueryCmd() *cobra.Command {

feegrantQueryCmd.AddCommand(
GetCmdQueryFeeGrant(),
GetCmdQueryFeeGrants(),
GetCmdQueryFeeGrantsByGrantee(),
GetCmdQueryFeeGrantsByGranter(),
)

return feegrantQueryCmd
Expand Down Expand Up @@ -80,8 +81,8 @@ $ %s query feegrant grant [granter] [grantee]
return cmd
}

// GetCmdQueryFeeGrants returns cmd to query for all grants for a grantee.
func GetCmdQueryFeeGrants() *cobra.Command {
// GetCmdQueryFeeGrantsByGrantee returns cmd to query for all grants for a grantee.
func GetCmdQueryFeeGrantsByGrantee() *cobra.Command {
cmd := &cobra.Command{
Use: "grants [grantee]",
Args: cobra.ExactArgs(1),
Expand Down Expand Up @@ -128,3 +129,52 @@ $ %s query feegrant grants [grantee]

return cmd
}

// GetCmdQueryFeeGrantsByGranter returns cmd to query for all grants by a granter.
func GetCmdQueryFeeGrantsByGranter() *cobra.Command {
cmd := &cobra.Command{
Use: "grants [granter]",
Args: cobra.ExactArgs(1),
Short: "Query all grants by a granter",
Long: strings.TrimSpace(
fmt.Sprintf(`Queries all the grants issued for a granter address.
Example:
$ %s query feegrant grants [granter]
`, version.AppName),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
queryClient := feegrant.NewQueryClient(clientCtx)

granterAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}

pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}

res, err := queryClient.AllowancesByGranter(
cmd.Context(),
&feegrant.QueryAllowancesByGranterRequest{
Granter: granterAddr.String(),
Pagination: pageReq,
},
)

if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)
flags.AddPaginationFlagsToCmd(cmd, "grants")

return cmd
}
1 change: 1 addition & 0 deletions x/feegrant/client/testutil/cli_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build norace
// +build norace

package testutil
Expand Down
62 changes: 59 additions & 3 deletions x/feegrant/client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (s *IntegrationTestSuite) TestCmdGetFeeGrant() {
}
}

func (s *IntegrationTestSuite) TestCmdGetFeeGrants() {
func (s *IntegrationTestSuite) TestCmdGetFeeGrantsByGrantee() {
val := s.network.Validators[0]
grantee := s.addedGrantee
clientCtx := val.ClientCtx
Expand All @@ -219,7 +219,7 @@ func (s *IntegrationTestSuite) TestCmdGetFeeGrants() {
true, nil, 0,
},
{
"non existed grantee",
"non existent grantee",
[]string{
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
Expand All @@ -240,7 +240,63 @@ func (s *IntegrationTestSuite) TestCmdGetFeeGrants() {
tc := tc

s.Run(tc.name, func() {
cmd := cli.GetCmdQueryFeeGrants()
cmd := cli.GetCmdQueryFeeGrantsByGrantee()
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)

if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.resp), out.String())
s.Require().Len(tc.resp.Allowances, tc.expectLength)
}
})
}
}

func (s *IntegrationTestSuite) TestCmdGetFeeGrantsByGranter() {
val := s.network.Validators[0]
granter := s.addedGranter
clientCtx := val.ClientCtx

testCases := []struct {
name string
args []string
expectErr bool
resp *feegrant.QueryAllowancesByGranterResponse
expectLength int
}{
{
"wrong grantee",
[]string{
"wrong_grantee",
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
},
true, nil, 0,
},
{
"non existent grantee",
[]string{
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
},
false, &feegrant.QueryAllowancesByGranterResponse{}, 0,
},
{
"valid req",
[]string{
granter.String(),
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
},
false, &feegrant.QueryAllowancesByGranterResponse{}, 1,
},
}

for _, tc := range testCases {
tc := tc

s.Run(tc.name, func() {
cmd := cli.GetCmdQueryFeeGrantsByGranter()
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)

if tc.expectErr {
Expand Down
39 changes: 39 additions & 0 deletions x/feegrant/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,42 @@ func (q Keeper) Allowances(c context.Context, req *feegrant.QueryAllowancesReque

return &feegrant.QueryAllowancesResponse{Allowances: grants, Pagination: pageRes}, nil
}

// AllowancesByGranter queries all the allowances granted by the given granter
func (q Keeper) AllowancesByGranter(c context.Context, req *feegrant.QueryAllowancesByGranterRequest) (*feegrant.QueryAllowancesByGranterResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

granterAddr, err := sdk.AccAddressFromBech32(req.Granter)
if err != nil {
return nil, err
}

ctx := sdk.UnwrapSDKContext(c)

var grants []*feegrant.Grant

store := ctx.KVStore(q.storeKey)
pageRes, err := query.Paginate(store, req.Pagination, func(key []byte, value []byte) error {
var grant feegrant.Grant

granter, _ := feegrant.ParseAddressesFromFeeAllowanceKey(key)
if !granter.Equals(granterAddr) {
return nil
}

if err := q.cdc.Unmarshal(value, &grant); err != nil {
return err
}

grants = append(grants, &grant)
return nil
})

if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

return &feegrant.QueryAllowancesByGranterResponse{Allowances: grants, Pagination: pageRes}, nil
}
Loading

0 comments on commit eb01537

Please sign in to comment.