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: implement x/params get all subspaces/keys #9884

Merged
merged 11 commits into from Aug 10, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* [\#9884](https://github.com/cosmos/cosmos-sdk/pull/9884) Provide a new gRPC query handler, `/cosmos/params/v1beta1/subspaces`, that allows the ability to query for all registered subspaces and their respective keys.
* [\#9860](https://github.com/cosmos/cosmos-sdk/pull/9860) Emit transaction fee in ante handler fee decorator. The event type is `tx` and the attribute is `fee`.
* [\#9776](https://github.com/cosmos/cosmos-sdk/pull/9776) Add flag `staking-bond-denom` to specify the staking bond denomination value when initializing a new chain.
* [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination.
Expand Down
50 changes: 49 additions & 1 deletion docs/core/proto-docs.md
Expand Up @@ -483,6 +483,9 @@
- [cosmos/params/v1beta1/query.proto](#cosmos/params/v1beta1/query.proto)
- [QueryParamsRequest](#cosmos.params.v1beta1.QueryParamsRequest)
- [QueryParamsResponse](#cosmos.params.v1beta1.QueryParamsResponse)
- [QuerySubspacesRequest](#cosmos.params.v1beta1.QuerySubspacesRequest)
- [QuerySubspacesResponse](#cosmos.params.v1beta1.QuerySubspacesResponse)
- [Subspace](#cosmos.params.v1beta1.Subspace)

- [Query](#cosmos.params.v1beta1.Query)

Expand Down Expand Up @@ -966,7 +969,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|
| `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 Expand Up @@ -6957,6 +6960,50 @@ QueryParamsResponse is response type for the Query/Params RPC method.




<a name="cosmos.params.v1beta1.QuerySubspacesRequest"></a>

### QuerySubspacesRequest
QuerySubspacesRequest defines a request type for querying for all registered
subspaces and all keys for a subspace.






<a name="cosmos.params.v1beta1.QuerySubspacesResponse"></a>

### QuerySubspacesResponse
QuerySubspacesResponse defines the response types for querying for all
registered subspaces and all keys for a subspace.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `subspaces` | [Subspace](#cosmos.params.v1beta1.Subspace) | repeated | |






<a name="cosmos.params.v1beta1.Subspace"></a>

### Subspace
Subspace defines a parameter subspace name and all the keys that exist for
the subspace.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `subspace` | [string](#string) | | |
| `keys` | [string](#string) | repeated | |





<!-- end messages -->

<!-- end enums -->
Expand All @@ -6972,6 +7019,7 @@ Query defines the gRPC querier service.
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `Params` | [QueryParamsRequest](#cosmos.params.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#cosmos.params.v1beta1.QueryParamsResponse) | Params queries a specific parameter of a module, given its subspace and key. | GET|/cosmos/params/v1beta1/params|
| `Subspaces` | [QuerySubspacesRequest](#cosmos.params.v1beta1.QuerySubspacesRequest) | [QuerySubspacesResponse](#cosmos.params.v1beta1.QuerySubspacesResponse) | Subspaces queries for all registered subspaces and all keys for a subspace. | GET|/cosmos/params/v1beta1/subspaces|

<!-- end services -->

Expand Down
22 changes: 22 additions & 0 deletions proto/cosmos/params/v1beta1/query.proto
Expand Up @@ -14,6 +14,11 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/params/v1beta1/params";
}

// Subspaces queries for all registered subspaces and all keys for a subspace.
rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) {
option (google.api.http).get = "/cosmos/params/v1beta1/subspaces";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand All @@ -30,3 +35,20 @@ message QueryParamsResponse {
// param defines the queried parameter.
ParamChange param = 1 [(gogoproto.nullable) = false];
}

// QuerySubspacesRequest defines a request type for querying for all registered
// subspaces and all keys for a subspace.
message QuerySubspacesRequest {}

// QuerySubspacesResponse defines the response types for querying for all
// registered subspaces and all keys for a subspace.
message QuerySubspacesResponse {
repeated Subspace subspaces = 1;
}

// Subspace defines a parameter subspace name and all the keys that exist for
// the subspace.
message Subspace {
string subspace = 1;
repeated string keys = 2;
}
4 changes: 2 additions & 2 deletions x/auth/types/query.pb.go

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

6 changes: 3 additions & 3 deletions x/group/types.pb.go

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

33 changes: 33 additions & 0 deletions x/params/keeper/grpc_query.go
Expand Up @@ -34,3 +34,36 @@ func (k Keeper) Params(c context.Context, req *proposal.QueryParamsRequest) (*pr

return &proposal.QueryParamsResponse{Param: param}, nil
}

// Subspaces implements the gRPC query handler for fetching all registered
// subspaces and all the keys for each subspace.
func (k Keeper) Subspaces(
goCtx context.Context,
req *proposal.QuerySubspacesRequest,
) (*proposal.QuerySubspacesResponse, error) {

if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

spaces := k.GetSubspaces()
resp := &proposal.QuerySubspacesResponse{
Subspaces: make([]*proposal.Subspace, len(spaces)),
}

ctx := sdk.UnwrapSDKContext(goCtx)
for i, ss := range spaces {
var keys []string
ss.IterateKeys(ctx, func(key []byte) bool {
keys = append(keys, string(key))
return false
})

resp.Subspaces[i] = &proposal.Subspace{
Subspace: ss.Name(),
Keys: keys,
}
}

return resp, nil
}
21 changes: 21 additions & 0 deletions x/params/keeper/grpc_query_test.go
Expand Up @@ -84,3 +84,24 @@ func (suite *KeeperTestSuite) TestGRPCQueryParams() {
})
}
}

func (suite *KeeperTestSuite) TestGRPCQuerySubspaces() {
ctx := sdk.WrapSDKContext(suite.ctx)

// NOTE: Each subspace will not have any keys that we can check against
// because InitGenesis has not been called during app construction.
resp, err := suite.queryClient.Subspaces(ctx, &proposal.QuerySubspacesRequest{})
suite.Require().NoError(err)
suite.Require().NotNil(resp)

spaces := make([]string, len(resp.Subspaces))
i := 0
for _, ss := range resp.Subspaces {
spaces[i] = ss.Subspace
i++
}

// require the response contains a few subspaces we know exist
suite.Require().Contains(spaces, "bank")
suite.Require().Contains(spaces, "staking")
}
12 changes: 12 additions & 0 deletions x/params/keeper/keeper.go
Expand Up @@ -59,3 +59,15 @@ func (k Keeper) GetSubspace(s string) (types.Subspace, bool) {
}
return *space, ok
}

// GetSubspaces returns all the registered subspaces.
func (k Keeper) GetSubspaces() []types.Subspace {
spaces := make([]types.Subspace, len(k.spaces))
i := 0
for _, ss := range k.spaces {
spaces[i] = *ss
i++
}

return spaces
}
23 changes: 23 additions & 0 deletions x/params/keeper/keeper_test.go
Expand Up @@ -148,6 +148,29 @@ func indirect(ptr interface{}) interface{} {
return reflect.ValueOf(ptr).Elem().Interface()
}

func TestGetSubspaces(t *testing.T) {
_, _, _, _, keeper := testComponents()

table := types.NewKeyTable(
types.NewParamSetPair([]byte("string"), "", validateNoOp),
types.NewParamSetPair([]byte("bool"), false, validateNoOp),
)

_ = keeper.Subspace("key1").WithKeyTable(table)
_ = keeper.Subspace("key2").WithKeyTable(table)

spaces := keeper.GetSubspaces()
require.Len(t, spaces, 2)

var names []string
for _, ss := range spaces {
names = append(names, ss.Name())
}

require.Contains(t, names, "key1")
require.Contains(t, names, "key2")
}

func TestSubspace(t *testing.T) {
cdc, ctx, key, _, keeper := testComponents()

Expand Down