Skip to content

Commit

Permalink
Add CodeInfo rpc query
Browse files Browse the repository at this point in the history
  • Loading branch information
pinosu committed Aug 1, 2024
1 parent 4762f4b commit 3e269cf
Show file tree
Hide file tree
Showing 7 changed files with 539 additions and 125 deletions.
19 changes: 18 additions & 1 deletion docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- [QueryAllContractStateResponse](#cosmwasm.wasm.v1.QueryAllContractStateResponse)
- [QueryBuildAddressRequest](#cosmwasm.wasm.v1.QueryBuildAddressRequest)
- [QueryBuildAddressResponse](#cosmwasm.wasm.v1.QueryBuildAddressResponse)
- [QueryCodeInfoRequest](#cosmwasm.wasm.v1.QueryCodeInfoRequest)
- [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest)
- [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse)
- [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest)
Expand Down Expand Up @@ -1066,6 +1067,21 @@ method.



<a name="cosmwasm.wasm.v1.QueryCodeInfoRequest"></a>

### QueryCodeInfoRequest
QueryCodeInfoRequest is the request type for the Query/Code RPC method


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID |






<a name="cosmwasm.wasm.v1.QueryCodeRequest"></a>

### QueryCodeRequest
Expand Down Expand Up @@ -1406,8 +1422,9 @@ Query provides defines the gRPC querier service
| `AllContractState` | [QueryAllContractStateRequest](#cosmwasm.wasm.v1.QueryAllContractStateRequest) | [QueryAllContractStateResponse](#cosmwasm.wasm.v1.QueryAllContractStateResponse) | AllContractState gets all raw store data for a single contract | GET|/cosmwasm/wasm/v1/contract/{address}/state|
| `RawContractState` | [QueryRawContractStateRequest](#cosmwasm.wasm.v1.QueryRawContractStateRequest) | [QueryRawContractStateResponse](#cosmwasm.wasm.v1.QueryRawContractStateResponse) | RawContractState gets single key from the raw store data of a contract | GET|/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}|
| `SmartContractState` | [QuerySmartContractStateRequest](#cosmwasm.wasm.v1.QuerySmartContractStateRequest) | [QuerySmartContractStateResponse](#cosmwasm.wasm.v1.QuerySmartContractStateResponse) | SmartContractState get smart query result from the contract | GET|/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}|
| `Code` | [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest) | [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse) | Code gets the binary code and metadata for a singe wasm code | GET|/cosmwasm/wasm/v1/code/{code_id}|
| `Code` | [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest) | [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse) | Code gets the binary code and metadata for a single wasm code | GET|/cosmwasm/wasm/v1/code/{code_id}|
| `Codes` | [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest) | [QueryCodesResponse](#cosmwasm.wasm.v1.QueryCodesResponse) | Codes gets the metadata for all stored wasm codes | GET|/cosmwasm/wasm/v1/code|
| `CodeInfo` | [QueryCodeInfoRequest](#cosmwasm.wasm.v1.QueryCodeInfoRequest) | [CodeInfoResponse](#cosmwasm.wasm.v1.CodeInfoResponse) | CodeInfo gets the metadata for a single wasm code | GET|/cosmwasm/wasm/v1/code-info/{code_id}|
| `PinnedCodes` | [QueryPinnedCodesRequest](#cosmwasm.wasm.v1.QueryPinnedCodesRequest) | [QueryPinnedCodesResponse](#cosmwasm.wasm.v1.QueryPinnedCodesResponse) | PinnedCodes gets the pinned code ids | GET|/cosmwasm/wasm/v1/codes/pinned|
| `Params` | [QueryParamsRequest](#cosmwasm.wasm.v1.QueryParamsRequest) | [QueryParamsResponse](#cosmwasm.wasm.v1.QueryParamsResponse) | Params gets the module params | GET|/cosmwasm/wasm/v1/codes/params|
| `ContractsByCreator` | [QueryContractsByCreatorRequest](#cosmwasm.wasm.v1.QueryContractsByCreatorRequest) | [QueryContractsByCreatorResponse](#cosmwasm.wasm.v1.QueryContractsByCreatorResponse) | ContractsByCreator gets the contracts by creator | GET|/cosmwasm/wasm/v1/contracts/creator/{creator_address}|
Expand Down
13 changes: 12 additions & 1 deletion proto/cosmwasm/wasm/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ service Query {
option (google.api.http).get =
"/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}";
}
// Code gets the binary code and metadata for a singe wasm code
// Code gets the binary code and metadata for a single wasm code
rpc Code(QueryCodeRequest) returns (QueryCodeResponse) {
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}";
Expand All @@ -65,6 +65,12 @@ service Query {
option (google.api.http).get = "/cosmwasm/wasm/v1/code";
}

// CodeInfo gets the metadata for a single wasm code
rpc CodeInfo(QueryCodeInfoRequest) returns (CodeInfoResponse) {
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/cosmwasm/wasm/v1/code-info/{code_id}";
}

// PinnedCodes gets the pinned code ids
rpc PinnedCodes(QueryPinnedCodesRequest) returns (QueryPinnedCodesResponse) {
option (cosmos.query.v1.module_query_safe) = true;
Expand Down Expand Up @@ -211,6 +217,11 @@ message QueryCodeRequest {
uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID
}

// QueryCodeInfoRequest is the request type for the Query/Code RPC method
message QueryCodeInfoRequest {
uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID
}

// CodeInfoResponse contains code meta data from CodeInfo
message CodeInfoResponse {
option (gogoproto.equal) = true;
Expand Down
9 changes: 3 additions & 6 deletions x/wasm/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,20 +252,17 @@ func GetCmdQueryCodeInfo() *cobra.Command {
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.Code(
res, err := queryClient.CodeInfo(
context.Background(),
&types.QueryCodeRequest{
&types.QueryCodeInfoRequest{
CodeId: codeID,
},
)
if err != nil {
return err
}
if res.CodeInfoResponse == nil {
return fmt.Errorf("contract not found")
}

return clientCtx.PrintProto(res.CodeInfoResponse)
return clientCtx.PrintProto(res)
},
SilenceUsage: true,
}
Expand Down
39 changes: 32 additions & 7 deletions x/wasm/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,23 @@ func (q GrpcQuerier) Codes(c context.Context, req *types.QueryCodesRequest) (*ty
return &types.QueryCodesResponse{CodeInfos: r, Pagination: pageRes}, nil
}

func (q GrpcQuerier) CodeInfo(c context.Context, req *types.QueryCodeInfoRequest) (*types.CodeInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.CodeId == 0 {
return nil, errorsmod.Wrap(types.ErrInvalid, "code id")
}
rsp, err := queryCodeInfo(sdk.UnwrapSDKContext(c), req.CodeId, q.keeper)
switch {
case err != nil:
return nil, err
case rsp == nil:
return nil, types.ErrNoSuchCodeFn(req.CodeId).Wrapf("code id %d", req.CodeId)
}
return rsp, nil
}

func queryContractInfo(ctx sdk.Context, addr sdk.AccAddress, keeper types.ViewKeeper) (*types.QueryContractInfoResponse, error) {
info := keeper.GetContractInfo(ctx, addr)
if info == nil {
Expand All @@ -298,6 +315,20 @@ func queryContractInfo(ctx sdk.Context, addr sdk.AccAddress, keeper types.ViewKe
}

func queryCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) (*types.QueryCodeResponse, error) {
info, err := queryCodeInfo(ctx, codeID, keeper)
if err != nil {
return nil, err
}

code, err := keeper.GetByteCode(ctx, codeID)
if err != nil {
return nil, errorsmod.Wrap(err, "loading wasm code")
}

return &types.QueryCodeResponse{CodeInfoResponse: info, Data: code}, nil
}

func queryCodeInfo(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) (*types.CodeInfoResponse, error) {
if codeID == 0 {
return nil, nil
}
Expand All @@ -312,13 +343,7 @@ func queryCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) (*types.
DataHash: res.CodeHash,
InstantiatePermission: res.InstantiateConfig,
}

code, err := keeper.GetByteCode(ctx, codeID)
if err != nil {
return nil, errorsmod.Wrap(err, "loading wasm code")
}

return &types.QueryCodeResponse{CodeInfoResponse: &info, Data: code}, nil
return &info, nil
}

func (q GrpcQuerier) PinnedCodes(c context.Context, req *types.QueryPinnedCodesRequest) (*types.QueryPinnedCodesResponse, error) {
Expand Down
52 changes: 52 additions & 0 deletions x/wasm/keeper/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,58 @@ func TestQueryCodeInfo(t *testing.T) {
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
keeper := keepers.WasmKeeper

anyAddress, err := sdk.AccAddressFromBech32("cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz")
require.NoError(t, err)
specs := map[string]struct {
codeID uint64
accessConfig types.AccessConfig
}{
"everybody": {
codeID: 1,
accessConfig: types.AllowEverybody,
},
"nobody": {
codeID: 10,
accessConfig: types.AllowNobody,
},
"with_address": {
codeID: 20,
accessConfig: types.AccessTypeAnyOfAddresses.With(anyAddress),
},
}
for msg, spec := range specs {
t.Run(msg, func(t *testing.T) {
codeInfo := types.CodeInfoFixture(types.WithSHA256CodeHash(wasmCode))
codeInfo.InstantiateConfig = spec.accessConfig
require.NoError(t, keeper.importCode(ctx, spec.codeID,
codeInfo,
wasmCode),
)

q := Querier(keeper)
got, err := q.CodeInfo(ctx, &types.QueryCodeInfoRequest{
CodeId: spec.codeID,
})
require.NoError(t, err)
expectedResponse := &types.CodeInfoResponse{
CodeID: spec.codeID,
Creator: codeInfo.Creator,
DataHash: codeInfo.CodeHash,
InstantiatePermission: spec.accessConfig,
}
require.NotNil(t, got)
require.EqualValues(t, expectedResponse, got)
})
}
}

func TestQueryCode(t *testing.T) {
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
keeper := keepers.WasmKeeper

anyAddress, err := sdk.AccAddressFromBech32("cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz")
require.NoError(t, err)
specs := map[string]struct {
Expand Down
Loading

0 comments on commit 3e269cf

Please sign in to comment.