Skip to content

Commit

Permalink
fix(server/v2/cometbft): proper query error (cosmos#22746)
Browse files Browse the repository at this point in the history
Co-authored-by: mmsqe <[email protected]>
  • Loading branch information
julienrbrt and mmsqe authored Dec 4, 2024
1 parent 92ddbf7 commit 556102c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
11 changes: 6 additions & 5 deletions server/v2/cometbft/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (c *consensus[T]) Query(ctx context.Context, req *abciproto.QueryRequest) (
// it must be an app/p2p/store query
path := splitABCIQueryPath(req.Path)
if len(path) == 0 {
return QueryResult(errorsmod.Wrap(cometerrors.ErrUnknownRequest, "no query path provided"), c.cfg.AppTomlConfig.Trace), nil
return queryResult(errorsmod.Wrap(cometerrors.ErrUnknownRequest, "no query path provided"), c.cfg.AppTomlConfig.Trace), nil
}

switch path[0] {
Expand All @@ -202,11 +202,11 @@ func (c *consensus[T]) Query(ctx context.Context, req *abciproto.QueryRequest) (
resp, err = c.handleQueryP2P(path)

default:
resp = QueryResult(errorsmod.Wrapf(cometerrors.ErrUnknownRequest, "unknown query path %s", req.Path), c.cfg.AppTomlConfig.Trace)
resp = queryResult(errorsmod.Wrapf(cometerrors.ErrUnknownRequest, "unknown query path %s", req.Path), c.cfg.AppTomlConfig.Trace)
}

if err != nil {
return QueryResult(err, c.cfg.AppTomlConfig.Trace), nil
return queryResult(err, c.cfg.AppTomlConfig.Trace), nil
}

return resp, nil
Expand Down Expand Up @@ -291,11 +291,12 @@ func (c *consensus[T]) maybeRunGRPCQuery(ctx context.Context, req *abci.QueryReq
if err != nil {
return nil, true, fmt.Errorf("unable to decode gRPC request with path %s from ABCI.Query: %w", req.Path, err)
}

res, err := c.app.Query(ctx, uint64(req.Height), protoRequest)
if err != nil {
resp := QueryResult(err, c.cfg.AppTomlConfig.Trace)
resp := gRPCErrorToSDKError(err)
resp.Height = req.Height
return resp, true, err
return resp, true, nil
}

resp, err = queryResponse(res, req.Height)
Expand Down
2 changes: 1 addition & 1 deletion server/v2/cometbft/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
cosmossdk.io/api v0.7.6
cosmossdk.io/collections v0.4.1-0.20241128094659-bd76b47e1d8b
cosmossdk.io/core v1.0.0-alpha.6
cosmossdk.io/errors v1.0.1
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5
cosmossdk.io/log v1.5.0
cosmossdk.io/schema v0.3.1-0.20241128094659-bd76b47e1d8b
Expand All @@ -46,7 +47,6 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/core/testing v0.0.0 // indirect
cosmossdk.io/depinject v1.1.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/math v1.4.0 // indirect
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
Expand Down
45 changes: 41 additions & 4 deletions server/v2/cometbft/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ import (
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
gogoproto "github.com/cosmos/gogoproto/proto"
gogoany "github.com/cosmos/gogoproto/types/any"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"

appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/comet"
"cosmossdk.io/core/event"
"cosmossdk.io/core/server"
"cosmossdk.io/core/transaction"
errorsmod "cosmossdk.io/errors/v2"
errorsmod "cosmossdk.io/errors" // we aren't using errors/v2 as it doesn't support grpc status codes
"cosmossdk.io/x/consensus/types"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

func queryResponse(res transaction.Msg, height int64) (*abci.QueryResponse, error) {
Expand Down Expand Up @@ -258,9 +261,8 @@ func ToSDKExtendedCommitInfo(commit abci.ExtendedCommitInfo) comet.CommitInfo {
return ci
}

// QueryResult returns a ResponseQuery from an error. It will try to parse ABCI
// info from the error.
func QueryResult(err error, debug bool) *abci.QueryResponse {
// queryResult returns a ResponseQuery from an error. It will try to parse ABCI info from the error.
func queryResult(err error, debug bool) *abci.QueryResponse {
space, code, log := errorsmod.ABCIInfo(err, debug)
return &abci.QueryResponse{
Codespace: space,
Expand All @@ -269,6 +271,41 @@ func QueryResult(err error, debug bool) *abci.QueryResponse {
}
}

func gRPCErrorToSDKError(err error) *abci.QueryResponse {
toQueryResp := func(sdkErr *errorsmod.Error, err error) *abci.QueryResponse {
res := &abci.QueryResponse{
Code: sdkErr.ABCICode(),
Codespace: sdkErr.Codespace(),
}
type grpcStatus interface{ GRPCStatus() *grpcstatus.Status }
if grpcErr, ok := err.(grpcStatus); ok {
res.Log = grpcErr.GRPCStatus().Message()
} else {
res.Log = err.Error()
}
return res

}

status, ok := grpcstatus.FromError(err)
if !ok {
return toQueryResp(sdkerrors.ErrInvalidRequest, err)
}

switch status.Code() {
case codes.NotFound:
return toQueryResp(sdkerrors.ErrKeyNotFound, err)
case codes.InvalidArgument:
return toQueryResp(sdkerrors.ErrInvalidRequest, err)
case codes.FailedPrecondition:
return toQueryResp(sdkerrors.ErrInvalidRequest, err)
case codes.Unauthenticated:
return toQueryResp(sdkerrors.ErrUnauthorized, err)
default:
return toQueryResp(sdkerrors.ErrUnknownRequest, err)
}
}

func (c *consensus[T]) validateFinalizeBlockHeight(req *abci.FinalizeBlockRequest) error {
if req.Height < 1 {
return fmt.Errorf("invalid height: %d", req.Height)
Expand Down

0 comments on commit 556102c

Please sign in to comment.