Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add cli for listing all module accounts #9812

Merged
merged 10 commits into from
Aug 2, 2021
28 changes: 28 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
- [QueryAccountResponse](#cosmos.auth.v1beta1.QueryAccountResponse)
- [QueryAccountsRequest](#cosmos.auth.v1beta1.QueryAccountsRequest)
- [QueryAccountsResponse](#cosmos.auth.v1beta1.QueryAccountsResponse)
- [QueryModuleAccountsRequest](#cosmos.auth.v1beta1.QueryModuleAccountsRequest)
- [QueryModuleAccountsResponse](#cosmos.auth.v1beta1.QueryModuleAccountsResponse)
- [QueryParamsRequest](#cosmos.auth.v1beta1.QueryParamsRequest)
- [QueryParamsResponse](#cosmos.auth.v1beta1.QueryParamsResponse)

Expand Down Expand Up @@ -898,6 +900,31 @@ QueryAccountsResponse is the response type for the Query/Accounts RPC method.



<a name="cosmos.auth.v1beta1.QueryModuleAccountsRequest"></a>

### QueryModuleAccountsRequest
QueryModuleAccountsRequest is the request type for the Query/ModuleAccounts RPC method.






<a name="cosmos.auth.v1beta1.QueryModuleAccountsResponse"></a>

### QueryModuleAccountsResponse
QueryModuleAccountsResponse is the response type for the Query/ModuleAccounts RPC method.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `accounts` | [google.protobuf.Any](#google.protobuf.Any) | repeated | |






<a name="cosmos.auth.v1beta1.QueryParamsRequest"></a>

### QueryParamsRequest
Expand Down Expand Up @@ -939,6 +966,7 @@ Query defines the gRPC querier service.
| `Accounts` | [QueryAccountsRequest](#cosmos.auth.v1beta1.QueryAccountsRequest) | [QueryAccountsResponse](#cosmos.auth.v1beta1.QueryAccountsResponse) | Accounts returns all the existing accounts | GET|/cosmos/auth/v1beta1/accounts|
| `Account` | [QueryAccountRequest](#cosmos.auth.v1beta1.QueryAccountRequest) | [QueryAccountResponse](#cosmos.auth.v1beta1.QueryAccountResponse) | Account returns account details based on address. | GET|/cosmos/auth/v1beta1/accounts/{address}|
| `Params` | [QueryParamsRequest](#cosmos.auth.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#cosmos.auth.v1beta1.QueryParamsResponse) | Params queries all parameters. | GET|/cosmos/auth/v1beta1/params|
| `ModuleAccounts` | [QueryModuleAccountsRequest](#cosmos.auth.v1beta1.QueryModuleAccountsRequest) | [QueryModuleAccountsResponse](#cosmos.auth.v1beta1.QueryModuleAccountsResponse) | ModuleAccounts returns all the existing Module Accounts. | GET|/cosmos/auth/v1beta1/module_accounts|

<!-- end services -->

Expand Down
13 changes: 13 additions & 0 deletions proto/cosmos/auth/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/auth/v1beta1/params";
}

// ModuleAccounts returns all the existing Module Accounts.
mattverse marked this conversation as resolved.
Show resolved Hide resolved
rpc ModuleAccounts(QueryModuleAccountsRequest) returns (QueryModuleAccountsResponse) {
option (google.api.http).get = "/cosmos/auth/v1beta1/module_accounts";
}
}

// QueryAccountsRequest is the request type for the Query/Accounts RPC method.
Expand Down Expand Up @@ -66,3 +71,11 @@ message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];
}

// QueryModuleAccountsRequest is the request type for the Query/ModuleAccounts RPC method.
message QueryModuleAccountsRequest {}

// QueryModuleAccountsResponse is the response type for the Query/ModuleAccounts RPC method.
message QueryModuleAccountsResponse {
repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "ModuleAccountI"];
}
29 changes: 29 additions & 0 deletions x/auth/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cli

import (
"context"
"fmt"
"strings"

Expand Down Expand Up @@ -42,6 +43,7 @@ func GetQueryCmd() *cobra.Command {
GetAccountCmd(),
GetAccountsCmd(),
QueryParamsCmd(),
QueryModuleAccountsCmd(),
)

return cmd
Expand Down Expand Up @@ -142,6 +144,33 @@ func GetAccountsCmd() *cobra.Command {
return cmd
}

// QueryAllModuleAccountCmd returns list of modules and its account address
mattverse marked this conversation as resolved.
Show resolved Hide resolved
func QueryModuleAccountsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "module-accounts",
Short: "Query all module accounts",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ModuleAccounts(context.Background(), &types.QueryModuleAccountsRequest{})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// QueryTxsByEventsCmd returns a command to search through transactions by events.
func QueryTxsByEventsCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down
25 changes: 25 additions & 0 deletions x/auth/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,28 @@ func (ak AccountKeeper) Params(c context.Context, req *types.QueryParamsRequest)

return &types.QueryParamsResponse{Params: params}, nil
}

// ModuleAccounts returns all the existing Module Accounts
func (ak AccountKeeper) ModuleAccounts(c context.Context, req *types.QueryModuleAccountsRequest) (*types.QueryModuleAccountsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(c)

var a []*codectypes.Any
mattverse marked this conversation as resolved.
Show resolved Hide resolved

for moduleName := range ak.permAddrs {
account := ak.GetModuleAccount(ctx, moduleName)
if account == nil {
return nil, status.Errorf(codes.NotFound, "account %s not found", moduleName)
}
any, err := codectypes.NewAnyWithValue(account)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
a = append(a, any)
mattverse marked this conversation as resolved.
Show resolved Hide resolved
}

return &types.QueryModuleAccountsResponse{Accounts: a}, nil
mattverse marked this conversation as resolved.
Show resolved Hide resolved
}
58 changes: 58 additions & 0 deletions x/auth/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,61 @@ func (suite *KeeperTestSuite) TestGRPCQueryParameters() {
})
}
}

func (suite *KeeperTestSuite) TestGRPCQueryModuleAccounts() {
var (
req *types.QueryModuleAccountsRequest
)

testCases := []struct {
msg string
malleate func()
expPass bool
posttests func(res *types.QueryModuleAccountsResponse)
}{
{
"success",
func() {
req = &types.QueryModuleAccountsRequest{}
},
true,
func(res *types.QueryModuleAccountsResponse) {
var stakeModuleExists = false
for _, acc := range res.Accounts {
var account types.AccountI
err := suite.app.InterfaceRegistry().UnpackAny(acc, &account)
suite.Require().NoError(err)

moduleAccount, ok := account.(types.ModuleAccountI)

suite.Require().True(ok)
if moduleAccount.GetName() == "mint" {
stakeModuleExists = true
mattverse marked this conversation as resolved.
Show resolved Hide resolved
}
}
suite.Require().True(stakeModuleExists)
},
},
}

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.ModuleAccounts(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)
})
}
}
Loading