diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94efc4d653d1..11184090ae53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md
index 6b68c21ae232..b9d5372e35ab 100644
--- a/docs/core/proto-docs.md
+++ b/docs/core/proto-docs.md
@@ -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)
@@ -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|
@@ -6957,6 +6960,50 @@ QueryParamsResponse is response type for the Query/Params RPC method.
+
+
+
+### QuerySubspacesRequest
+QuerySubspacesRequest defines a request type for querying for all registered
+subspaces and all keys for a subspace.
+
+
+
+
+
+
+
+
+### 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 | |
+
+
+
+
+
+
+
+
+### 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 | |
+
+
+
+
+
@@ -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|
diff --git a/proto/cosmos/params/v1beta1/query.proto b/proto/cosmos/params/v1beta1/query.proto
index 1078e02ae3e6..3b1c9a760092 100644
--- a/proto/cosmos/params/v1beta1/query.proto
+++ b/proto/cosmos/params/v1beta1/query.proto
@@ -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.
@@ -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;
+}
diff --git a/x/auth/types/query.pb.go b/x/auth/types/query.pb.go
index 61c7041a6a9d..c3712a26cf79 100644
--- a/x/auth/types/query.pb.go
+++ b/x/auth/types/query.pb.go
@@ -456,7 +456,7 @@ type QueryClient interface {
Account(ctx context.Context, in *QueryAccountRequest, opts ...grpc.CallOption) (*QueryAccountResponse, error)
// Params queries all parameters.
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
- // ModuleAccounts returns all the existing Module Accounts.
+ // ModuleAccounts returns all the existing module accounts.
ModuleAccounts(ctx context.Context, in *QueryModuleAccountsRequest, opts ...grpc.CallOption) (*QueryModuleAccountsResponse, error)
}
@@ -512,7 +512,7 @@ type QueryServer interface {
Account(context.Context, *QueryAccountRequest) (*QueryAccountResponse, error)
// Params queries all parameters.
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
- // ModuleAccounts returns all the existing Module Accounts.
+ // ModuleAccounts returns all the existing module accounts.
ModuleAccounts(context.Context, *QueryModuleAccountsRequest) (*QueryModuleAccountsResponse, error)
}
diff --git a/x/group/types.pb.go b/x/group/types.pb.go
index 56fbe2286f4f..c0e5cf2d5e75 100644
--- a/x/group/types.pb.go
+++ b/x/group/types.pb.go
@@ -567,9 +567,9 @@ type Proposal struct {
Result Proposal_Result `protobuf:"varint,9,opt,name=result,proto3,enum=cosmos.group.v1beta1.Proposal_Result" json:"result,omitempty"`
// vote_state contains the sums of all weighted votes for this proposal.
VoteState Tally `protobuf:"bytes,10,opt,name=vote_state,json=voteState,proto3" json:"vote_state"`
- // timeout is the timestamp of the block where the proposal execution times out. Header times of the votes and execution messages
- // must be before this end time to be included in the election. After the timeout timestamp the proposal can not be
- // executed anymore and should be considered pending delete.
+ // timeout is the timestamp of the block where the proposal execution times out. Header times of the votes and
+ // execution messages must be before this end time to be included in the election. After the timeout timestamp the
+ // proposal can not be executed anymore and should be considered pending delete.
Timeout time.Time `protobuf:"bytes,11,opt,name=timeout,proto3,stdtime" json:"timeout"`
// executor_result is the final result based on the votes and election rule. Initial value is NotRun.
ExecutorResult Proposal_ExecutorResult `protobuf:"varint,12,opt,name=executor_result,json=executorResult,proto3,enum=cosmos.group.v1beta1.Proposal_ExecutorResult" json:"executor_result,omitempty"`
diff --git a/x/params/keeper/grpc_query.go b/x/params/keeper/grpc_query.go
index 2cfa1c8042d7..d918dc002a38 100644
--- a/x/params/keeper/grpc_query.go
+++ b/x/params/keeper/grpc_query.go
@@ -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
+}
diff --git a/x/params/keeper/grpc_query_test.go b/x/params/keeper/grpc_query_test.go
index 19794beb0808..f6985fe7e6dd 100644
--- a/x/params/keeper/grpc_query_test.go
+++ b/x/params/keeper/grpc_query_test.go
@@ -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")
+}
diff --git a/x/params/keeper/keeper.go b/x/params/keeper/keeper.go
index 388d99c51c99..8a0e708aeb3d 100644
--- a/x/params/keeper/keeper.go
+++ b/x/params/keeper/keeper.go
@@ -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
+}
diff --git a/x/params/keeper/keeper_test.go b/x/params/keeper/keeper_test.go
index 44c8223f2c25..795a9aac6ffc 100644
--- a/x/params/keeper/keeper_test.go
+++ b/x/params/keeper/keeper_test.go
@@ -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()
diff --git a/x/params/types/proposal/query.pb.go b/x/params/types/proposal/query.pb.go
index e0c770d70e24..229f4f8e9bb0 100644
--- a/x/params/types/proposal/query.pb.go
+++ b/x/params/types/proposal/query.pb.go
@@ -130,36 +130,182 @@ func (m *QueryParamsResponse) GetParam() ParamChange {
return ParamChange{}
}
+// QuerySubspacesRequest defines a request type for querying for all registered
+// subspaces and all keys for a subspace.
+type QuerySubspacesRequest struct {
+}
+
+func (m *QuerySubspacesRequest) Reset() { *m = QuerySubspacesRequest{} }
+func (m *QuerySubspacesRequest) String() string { return proto.CompactTextString(m) }
+func (*QuerySubspacesRequest) ProtoMessage() {}
+func (*QuerySubspacesRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2b32979c1792ccc4, []int{2}
+}
+func (m *QuerySubspacesRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QuerySubspacesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QuerySubspacesRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QuerySubspacesRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QuerySubspacesRequest.Merge(m, src)
+}
+func (m *QuerySubspacesRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *QuerySubspacesRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_QuerySubspacesRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QuerySubspacesRequest proto.InternalMessageInfo
+
+// QuerySubspacesResponse defines the response types for querying for all
+// registered subspaces and all keys for a subspace.
+type QuerySubspacesResponse struct {
+ Subspaces []*Subspace `protobuf:"bytes,1,rep,name=subspaces,proto3" json:"subspaces,omitempty"`
+}
+
+func (m *QuerySubspacesResponse) Reset() { *m = QuerySubspacesResponse{} }
+func (m *QuerySubspacesResponse) String() string { return proto.CompactTextString(m) }
+func (*QuerySubspacesResponse) ProtoMessage() {}
+func (*QuerySubspacesResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2b32979c1792ccc4, []int{3}
+}
+func (m *QuerySubspacesResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QuerySubspacesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QuerySubspacesResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QuerySubspacesResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QuerySubspacesResponse.Merge(m, src)
+}
+func (m *QuerySubspacesResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *QuerySubspacesResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_QuerySubspacesResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QuerySubspacesResponse proto.InternalMessageInfo
+
+func (m *QuerySubspacesResponse) GetSubspaces() []*Subspace {
+ if m != nil {
+ return m.Subspaces
+ }
+ return nil
+}
+
+// Subspace defines a parameter subspace name and all the keys that exist for
+// the subspace.
+type Subspace struct {
+ Subspace string `protobuf:"bytes,1,opt,name=subspace,proto3" json:"subspace,omitempty"`
+ Keys []string `protobuf:"bytes,2,rep,name=keys,proto3" json:"keys,omitempty"`
+}
+
+func (m *Subspace) Reset() { *m = Subspace{} }
+func (m *Subspace) String() string { return proto.CompactTextString(m) }
+func (*Subspace) ProtoMessage() {}
+func (*Subspace) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2b32979c1792ccc4, []int{4}
+}
+func (m *Subspace) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *Subspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_Subspace.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *Subspace) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Subspace.Merge(m, src)
+}
+func (m *Subspace) XXX_Size() int {
+ return m.Size()
+}
+func (m *Subspace) XXX_DiscardUnknown() {
+ xxx_messageInfo_Subspace.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Subspace proto.InternalMessageInfo
+
+func (m *Subspace) GetSubspace() string {
+ if m != nil {
+ return m.Subspace
+ }
+ return ""
+}
+
+func (m *Subspace) GetKeys() []string {
+ if m != nil {
+ return m.Keys
+ }
+ return nil
+}
+
func init() {
proto.RegisterType((*QueryParamsRequest)(nil), "cosmos.params.v1beta1.QueryParamsRequest")
proto.RegisterType((*QueryParamsResponse)(nil), "cosmos.params.v1beta1.QueryParamsResponse")
+ proto.RegisterType((*QuerySubspacesRequest)(nil), "cosmos.params.v1beta1.QuerySubspacesRequest")
+ proto.RegisterType((*QuerySubspacesResponse)(nil), "cosmos.params.v1beta1.QuerySubspacesResponse")
+ proto.RegisterType((*Subspace)(nil), "cosmos.params.v1beta1.Subspace")
}
func init() { proto.RegisterFile("cosmos/params/v1beta1/query.proto", fileDescriptor_2b32979c1792ccc4) }
var fileDescriptor_2b32979c1792ccc4 = []byte{
- // 321 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x31, 0x4b, 0x3b, 0x31,
- 0x14, 0xc0, 0x2f, 0xfd, 0xff, 0x5b, 0x34, 0x2e, 0x12, 0x15, 0xca, 0xa1, 0x57, 0x3d, 0x10, 0x54,
- 0x30, 0xa1, 0xd5, 0xd9, 0xa1, 0xee, 0xa2, 0x05, 0x17, 0xb7, 0x5c, 0x0d, 0x69, 0x69, 0x7b, 0x2f,
- 0xbd, 0x97, 0x13, 0xbb, 0x3a, 0x38, 0x17, 0xfc, 0x52, 0x1d, 0x0b, 0x2e, 0x4e, 0x22, 0xad, 0x1f,
- 0x44, 0x9a, 0xb4, 0x82, 0x58, 0xc5, 0x29, 0x2f, 0x2f, 0xbf, 0xf7, 0x7b, 0x79, 0x09, 0xdd, 0x6b,
- 0x02, 0xf6, 0x00, 0x85, 0x91, 0x99, 0xec, 0xa1, 0xb8, 0xab, 0x26, 0xca, 0xca, 0xaa, 0xe8, 0xe7,
- 0x2a, 0x1b, 0x70, 0x93, 0x81, 0x05, 0xb6, 0xe5, 0x11, 0xee, 0x11, 0x3e, 0x47, 0xc2, 0x4d, 0x0d,
- 0x1a, 0x1c, 0x21, 0x66, 0x91, 0x87, 0xc3, 0x6d, 0x0d, 0xa0, 0xbb, 0x4a, 0x48, 0xd3, 0x16, 0x32,
- 0x4d, 0xc1, 0x4a, 0xdb, 0x86, 0x14, 0xe7, 0xa7, 0xf1, 0xf2, 0x6e, 0x73, 0xb3, 0x63, 0xe2, 0x3a,
- 0x65, 0x57, 0xb3, 0xee, 0x97, 0x2e, 0xd9, 0x50, 0xfd, 0x5c, 0xa1, 0x65, 0x21, 0x5d, 0xc1, 0x3c,
- 0x41, 0x23, 0x9b, 0xaa, 0x4c, 0x76, 0xc9, 0xc1, 0x6a, 0xe3, 0x73, 0xcf, 0xd6, 0xe9, 0xbf, 0x8e,
- 0x1a, 0x94, 0x0b, 0x2e, 0x3d, 0x0b, 0xe3, 0x6b, 0xba, 0xf1, 0xc5, 0x81, 0x06, 0x52, 0x54, 0xec,
- 0x8c, 0x16, 0x5d, 0x2b, 0x67, 0x58, 0xab, 0xc5, 0x7c, 0xe9, 0x64, 0xdc, 0x55, 0x9d, 0xb7, 0x64,
- 0xaa, 0x55, 0xfd, 0xff, 0xe8, 0xb5, 0x12, 0x34, 0x7c, 0x59, 0x6d, 0x48, 0x68, 0xd1, 0x79, 0xd9,
- 0x23, 0xa1, 0x25, 0x2f, 0x67, 0x87, 0x3f, 0x58, 0xbe, 0x0f, 0x11, 0x1e, 0xfd, 0x05, 0xf5, 0x77,
- 0x8d, 0xf7, 0x1f, 0x9e, 0xdf, 0x9f, 0x0a, 0x15, 0xb6, 0x23, 0x7e, 0x7b, 0xb3, 0xfa, 0xc5, 0x68,
- 0x12, 0x91, 0xf1, 0x24, 0x22, 0x6f, 0x93, 0x88, 0x0c, 0xa7, 0x51, 0x30, 0x9e, 0x46, 0xc1, 0xcb,
- 0x34, 0x0a, 0x6e, 0x4e, 0x75, 0xdb, 0xb6, 0xf2, 0x84, 0x37, 0xa1, 0xb7, 0x50, 0xf8, 0xe5, 0x18,
- 0x6f, 0x3b, 0xe2, 0x7e, 0xe1, 0xb3, 0x03, 0xa3, 0x50, 0x98, 0x0c, 0x0c, 0xa0, 0xec, 0x26, 0x25,
- 0xf7, 0x09, 0x27, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xd5, 0x67, 0xc7, 0x18, 0x02, 0x00,
- 0x00,
+ // 415 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4d, 0x8b, 0xd3, 0x40,
+ 0x18, 0xce, 0xa4, 0x1f, 0x34, 0xd3, 0x8b, 0x8c, 0x56, 0x43, 0xd0, 0x34, 0x0e, 0x08, 0x51, 0x6c,
+ 0x86, 0x56, 0x4f, 0x82, 0x1e, 0xea, 0x5d, 0x34, 0x22, 0x82, 0xb7, 0x49, 0x1d, 0xd2, 0xd2, 0x36,
+ 0x33, 0xcd, 0x24, 0x62, 0xae, 0x1e, 0x3c, 0x2f, 0xbb, 0xbf, 0x61, 0xff, 0x4b, 0x8f, 0x85, 0xbd,
+ 0xec, 0x69, 0x59, 0xda, 0xfd, 0x21, 0x4b, 0x27, 0x49, 0x97, 0xed, 0xb6, 0xa5, 0xa7, 0xbc, 0x79,
+ 0xe7, 0xf9, 0x9a, 0x27, 0x81, 0x2f, 0x07, 0x5c, 0x4e, 0xb9, 0x24, 0x82, 0xc6, 0x74, 0x2a, 0xc9,
+ 0x9f, 0x6e, 0xc0, 0x12, 0xda, 0x25, 0xb3, 0x94, 0xc5, 0x99, 0x27, 0x62, 0x9e, 0x70, 0xd4, 0xca,
+ 0x21, 0x5e, 0x0e, 0xf1, 0x0a, 0x88, 0xf5, 0x24, 0xe4, 0x21, 0x57, 0x08, 0xb2, 0x9e, 0x72, 0xb0,
+ 0xf5, 0x3c, 0xe4, 0x3c, 0x9c, 0x30, 0x42, 0xc5, 0x88, 0xd0, 0x28, 0xe2, 0x09, 0x4d, 0x46, 0x3c,
+ 0x92, 0xc5, 0x29, 0xde, 0xed, 0x56, 0x28, 0x2b, 0x0c, 0xee, 0x43, 0xf4, 0x6d, 0xed, 0xfe, 0x55,
+ 0x2d, 0x7d, 0x36, 0x4b, 0x99, 0x4c, 0x90, 0x05, 0x1b, 0x32, 0x0d, 0xa4, 0xa0, 0x03, 0x66, 0x02,
+ 0x07, 0xb8, 0x86, 0xbf, 0x79, 0x47, 0x8f, 0x60, 0x65, 0xcc, 0x32, 0x53, 0x57, 0xeb, 0xf5, 0x88,
+ 0x7f, 0xc0, 0xc7, 0xf7, 0x34, 0xa4, 0xe0, 0x91, 0x64, 0xe8, 0x13, 0xac, 0x29, 0x2b, 0xa5, 0xd0,
+ 0xec, 0x61, 0x6f, 0xe7, 0xcd, 0x3c, 0xc5, 0xfa, 0x3c, 0xa4, 0x51, 0xc8, 0xfa, 0xd5, 0xf9, 0x55,
+ 0x5b, 0xf3, 0x73, 0x1a, 0x7e, 0x06, 0x5b, 0x4a, 0xf6, 0x7b, 0xe1, 0x5c, 0xa6, 0xc3, 0x3f, 0xe1,
+ 0xd3, 0xed, 0x83, 0xc2, 0xf2, 0x23, 0x34, 0xca, 0x9c, 0xd2, 0x04, 0x4e, 0xc5, 0x6d, 0xf6, 0xda,
+ 0x7b, 0x6c, 0x4b, 0xb2, 0x7f, 0xc7, 0xc0, 0x1f, 0x60, 0xa3, 0x5c, 0x1f, 0xac, 0x00, 0xc1, 0xea,
+ 0x98, 0x65, 0xd2, 0xd4, 0x9d, 0x8a, 0x6b, 0xf8, 0x6a, 0xee, 0x9d, 0xeb, 0xb0, 0xa6, 0x52, 0xa1,
+ 0xff, 0x00, 0xd6, 0xf3, 0x2a, 0xd0, 0xeb, 0x3d, 0xe6, 0x0f, 0x2b, 0xb7, 0xde, 0x1c, 0x03, 0xcd,
+ 0xaf, 0x89, 0x5f, 0xfd, 0xbb, 0xb8, 0x39, 0xd3, 0xdb, 0xe8, 0x05, 0x39, 0xf4, 0x85, 0xd1, 0x29,
+ 0x80, 0xc6, 0xa6, 0x23, 0xf4, 0xf6, 0x90, 0xc1, 0x76, 0xc7, 0x56, 0xe7, 0x48, 0x74, 0x91, 0xc8,
+ 0x55, 0x89, 0x30, 0x72, 0xf6, 0x24, 0xda, 0x74, 0xdc, 0xff, 0x32, 0x5f, 0xda, 0x60, 0xb1, 0xb4,
+ 0xc1, 0xf5, 0xd2, 0x06, 0x27, 0x2b, 0x5b, 0x5b, 0xac, 0x6c, 0xed, 0x72, 0x65, 0x6b, 0xbf, 0xde,
+ 0x87, 0xa3, 0x64, 0x98, 0x06, 0xde, 0x80, 0x4f, 0x4b, 0x95, 0xfc, 0xd1, 0x91, 0xbf, 0xc7, 0xe4,
+ 0x6f, 0x29, 0x99, 0x64, 0x82, 0x49, 0x22, 0x62, 0x2e, 0xb8, 0xa4, 0x93, 0xa0, 0xae, 0xfe, 0xe3,
+ 0x77, 0xb7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x69, 0xa9, 0xbc, 0x11, 0x5b, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -177,6 +323,8 @@ type QueryClient interface {
// Params queries a specific parameter of a module, given its subspace and
// key.
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
+ // Subspaces queries for all registered subspaces and all keys for a subspace.
+ Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error)
}
type queryClient struct {
@@ -196,11 +344,22 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts .
return out, nil
}
+func (c *queryClient) Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) {
+ out := new(QuerySubspacesResponse)
+ err := c.cc.Invoke(ctx, "/cosmos.params.v1beta1.Query/Subspaces", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// QueryServer is the server API for Query service.
type QueryServer interface {
// Params queries a specific parameter of a module, given its subspace and
// key.
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
+ // Subspaces queries for all registered subspaces and all keys for a subspace.
+ Subspaces(context.Context, *QuerySubspacesRequest) (*QuerySubspacesResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
@@ -210,6 +369,9 @@ type UnimplementedQueryServer struct {
func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
}
+func (*UnimplementedQueryServer) Subspaces(ctx context.Context, req *QuerySubspacesRequest) (*QuerySubspacesResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Subspaces not implemented")
+}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
@@ -233,6 +395,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf
return interceptor(ctx, in, info, handler)
}
+func _Query_Subspaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(QuerySubspacesRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).Subspaces(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/cosmos.params.v1beta1.Query/Subspaces",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).Subspaces(ctx, req.(*QuerySubspacesRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.params.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
@@ -241,6 +421,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{
MethodName: "Params",
Handler: _Query_Params_Handler,
},
+ {
+ MethodName: "Subspaces",
+ Handler: _Query_Subspaces_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/params/v1beta1/query.proto",
@@ -316,6 +500,105 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *QuerySubspacesRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QuerySubspacesRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QuerySubspacesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *QuerySubspacesResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QuerySubspacesResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Subspaces) > 0 {
+ for iNdEx := len(m.Subspaces) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Subspaces[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *Subspace) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Subspace) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Subspace) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Keys) > 0 {
+ for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Keys[iNdEx])
+ copy(dAtA[i:], m.Keys[iNdEx])
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Keys[iNdEx])))
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ if len(m.Subspace) > 0 {
+ i -= len(m.Subspace)
+ copy(dAtA[i:], m.Subspace)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Subspace)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
@@ -355,6 +638,49 @@ func (m *QueryParamsResponse) Size() (n int) {
return n
}
+func (m *QuerySubspacesRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *QuerySubspacesResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Subspaces) > 0 {
+ for _, e := range m.Subspaces {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *Subspace) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Subspace)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if len(m.Keys) > 0 {
+ for _, s := range m.Keys {
+ l = len(s)
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -558,6 +884,254 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QuerySubspacesRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QuerySubspacesRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QuerySubspacesResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QuerySubspacesResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Subspaces = append(m.Subspaces, &Subspace{})
+ if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *Subspace) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Subspace: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Subspace = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
diff --git a/x/params/types/proposal/query.pb.gw.go b/x/params/types/proposal/query.pb.gw.go
index f5b9f9d5b686..dcb9c9443c0c 100644
--- a/x/params/types/proposal/query.pb.gw.go
+++ b/x/params/types/proposal/query.pb.gw.go
@@ -67,6 +67,24 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal
}
+func request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QuerySubspacesRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := client.Subspaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ return msg, metadata, err
+
+}
+
+func local_request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QuerySubspacesRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := server.Subspaces(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -93,6 +111,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
})
+ mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_Query_Subspaces_0(rctx, inboundMarshaler, server, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -154,13 +192,37 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
})
+ mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_Query_Subspaces_0(rctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
var (
pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"cosmos", "params", "v1beta1"}, "", runtime.AssumeColonVerbOpt(false)))
+
+ pattern_Query_Subspaces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "params", "v1beta1", "subspaces"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_Params_0 = runtime.ForwardResponseMessage
+
+ forward_Query_Subspaces_0 = runtime.ForwardResponseMessage
)
diff --git a/x/params/types/subspace.go b/x/params/types/subspace.go
index 42afe6cc9b21..541277dcf612 100644
--- a/x/params/types/subspace.go
+++ b/x/params/types/subspace.go
@@ -127,6 +127,22 @@ func (s Subspace) GetIfExists(ctx sdk.Context, key []byte, ptr interface{}) {
}
}
+// IterateKeys iterates over all the keys in the subspace and executes the
+// provided callback. If the callback returns true for a given key, iteration
+// will halt.
+func (s Subspace) IterateKeys(ctx sdk.Context, cb func(key []byte) bool) {
+ store := s.kvStore(ctx)
+
+ iter := sdk.KVStorePrefixIterator(store, nil)
+ defer iter.Close()
+
+ for ; iter.Valid(); iter.Next() {
+ if cb(iter.Key()) {
+ break
+ }
+ }
+}
+
// GetRaw queries for the raw values bytes for a parameter by key.
func (s Subspace) GetRaw(ctx sdk.Context, key []byte) []byte {
store := s.kvStore(ctx)
diff --git a/x/params/types/subspace_test.go b/x/params/types/subspace_test.go
index 664c70df1801..d09e9c26b532 100644
--- a/x/params/types/subspace_test.go
+++ b/x/params/types/subspace_test.go
@@ -1,6 +1,7 @@
package types_test
import (
+ "bytes"
"fmt"
"testing"
"time"
@@ -92,6 +93,41 @@ func (suite *SubspaceTestSuite) TestGetRaw() {
})
}
+func (suite *SubspaceTestSuite) TestIterateKeys() {
+ suite.Require().NotPanics(func() {
+ suite.ss.Set(suite.ctx, keyUnbondingTime, time.Second)
+ })
+ suite.Require().NotPanics(func() {
+ suite.ss.Set(suite.ctx, keyMaxValidators, uint16(50))
+ })
+ suite.Require().NotPanics(func() {
+ suite.ss.Set(suite.ctx, keyBondDenom, "stake")
+ })
+
+ var keys [][]byte
+ suite.ss.IterateKeys(suite.ctx, func(key []byte) bool {
+ keys = append(keys, key)
+ return false
+ })
+ suite.Require().Len(keys, 3)
+ suite.Require().Contains(keys, keyUnbondingTime)
+ suite.Require().Contains(keys, keyMaxValidators)
+ suite.Require().Contains(keys, keyBondDenom)
+
+ var keys2 [][]byte
+ suite.ss.IterateKeys(suite.ctx, func(key []byte) bool {
+ if bytes.Equal(key, keyUnbondingTime) {
+ return true
+ }
+
+ keys2 = append(keys2, key)
+ return false
+ })
+ suite.Require().Len(keys2, 2)
+ suite.Require().Contains(keys2, keyMaxValidators)
+ suite.Require().Contains(keys2, keyBondDenom)
+}
+
func (suite *SubspaceTestSuite) TestHas() {
t := time.Hour * 48