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

Add CodeInfo rpc query #1943

Merged
merged 5 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion benchmarks/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
)

func setup(db dbm.DB, withGenesis bool) (*app.WasmApp, app.GenesisState) {

logLevel := log.LevelOption(zerolog.InfoLevel)

wasmApp := app.NewWasmApp(log.NewLogger(os.Stdout, logLevel), db, nil, true, simtestutil.EmptyAppOptions{}, nil)
Expand Down
42 changes: 39 additions & 3 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
- [QueryAllContractStateResponse](#cosmwasm.wasm.v1.QueryAllContractStateResponse)
- [QueryBuildAddressRequest](#cosmwasm.wasm.v1.QueryBuildAddressRequest)
- [QueryBuildAddressResponse](#cosmwasm.wasm.v1.QueryBuildAddressResponse)
- [QueryCodeInfoRequest](#cosmwasm.wasm.v1.QueryCodeInfoRequest)
- [QueryCodeInfoResponse](#cosmwasm.wasm.v1.QueryCodeInfoResponse)
- [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest)
- [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse)
- [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest)
Expand Down Expand Up @@ -1066,6 +1068,39 @@ method.



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

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


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






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

### QueryCodeInfoResponse
QueryCodeInfoResponse is the response type for the Query/CodeInfo RPC method


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `code_id` | [uint64](#uint64) | | |
| `creator` | [string](#string) | | |
| `checksum` | [bytes](#bytes) | | |
| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | |






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

### QueryCodeRequest
Expand All @@ -1074,7 +1109,7 @@ QueryCodeRequest 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 |
| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodeID |



Expand Down Expand Up @@ -1204,7 +1239,7 @@ RPC method

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID |
| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodeID |
| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. |


Expand Down Expand Up @@ -1406,8 +1441,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) | [QueryCodeInfoResponse](#cosmwasm.wasm.v1.QueryCodeInfoResponse) | 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
29 changes: 26 additions & 3 deletions proto/cosmwasm/wasm/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,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 @@ -64,6 +64,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 (QueryCodeInfoResponse) {
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 @@ -134,7 +140,7 @@ message QueryContractHistoryResponse {
// QueryContractsByCodeRequest is the request type for the Query/ContractsByCode
// RPC method
message QueryContractsByCodeRequest {
uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID
uint64 code_id = 1; // grpc-gateway_out does not support Go style CodeID
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
Expand Down Expand Up @@ -207,7 +213,24 @@ message QuerySmartContractStateResponse {

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

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

// QueryCodeInfoResponse is the response type for the Query/CodeInfo RPC method
message QueryCodeInfoResponse {
option (gogoproto.equal) = true;

uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ];
string creator = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
bytes checksum = 3 [ (gogoproto.casttype) =
"github.com/cometbft/cometbft/libs/bytes.HexBytes" ];
AccessConfig instantiate_permission = 4
[ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
}

// CodeInfoResponse contains code meta data from CodeInfo
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 @@
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.Code(
res, err := queryClient.CodeInfo(

Check warning on line 255 in x/wasm/client/cli/query.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/client/cli/query.go#L255

Added line #L255 was not covered by tests
webmaster128 marked this conversation as resolved.
Show resolved Hide resolved
context.Background(),
&types.QueryCodeRequest{
&types.QueryCodeInfoRequest{

Check warning on line 257 in x/wasm/client/cli/query.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/client/cli/query.go#L257

Added line #L257 was not covered by tests
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)

Check warning on line 265 in x/wasm/client/cli/query.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/client/cli/query.go#L265

Added line #L265 was not covered by tests
},
SilenceUsage: true,
}
Expand Down
47 changes: 37 additions & 10 deletions x/wasm/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,25 @@
return &types.QueryCodesResponse{CodeInfos: r, Pagination: pageRes}, nil
}

func (q GrpcQuerier) CodeInfo(c context.Context, req *types.QueryCodeInfoRequest) (*types.QueryCodeInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")

Check warning on line 290 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L290

Added line #L290 was not covered by tests
}
if req.CodeId == 0 {
return nil, errorsmod.Wrap(types.ErrInvalid, "code id")

Check warning on line 293 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L293

Added line #L293 was not covered by tests
}
info := queryCodeInfo(sdk.UnwrapSDKContext(c), req.CodeId, q.keeper)
if info == nil {
return nil, types.ErrNoSuchCodeFn(req.CodeId).Wrapf("code id %d", req.CodeId)

Check warning on line 297 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L297

Added line #L297 was not covered by tests
}
return &types.QueryCodeInfoResponse{
CodeID: info.CodeID,
Creator: info.Creator,
Checksum: info.DataHash,
InstantiatePermission: info.InstantiatePermission,
}, 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,27 +317,35 @@
}

func queryCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) (*types.QueryCodeResponse, error) {
if codeID == 0 {
info := queryCodeInfo(ctx, codeID, keeper)
if info == nil {
// nil, nil leads to 404 in rest handler
return nil, nil
}

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

Check warning on line 328 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L328

Added line #L328 was not covered by tests
}

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

func queryCodeInfo(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) *types.CodeInfoResponse {
if codeID == 0 {
return nil

Check warning on line 336 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L336

Added line #L336 was not covered by tests
}
res := keeper.GetCodeInfo(ctx, codeID)
if res == nil {
// nil, nil leads to 404 in rest handler
return nil, nil
return nil

Check warning on line 340 in x/wasm/keeper/querier.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/querier.go#L340

Added line #L340 was not covered by tests
}
info := types.CodeInfoResponse{
CodeID: codeID,
Creator: res.Creator,
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
}

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.QueryCodeInfoResponse{
CodeID: spec.codeID,
Creator: codeInfo.Creator,
Checksum: 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