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

refactor(server/v2/cometbft): Handle non-module service queries #22803

Merged
merged 17 commits into from
Dec 11, 2024
100 changes: 97 additions & 3 deletions server/v2/cometbft/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"cosmossdk.io/core/event"
"cosmossdk.io/core/server"
"cosmossdk.io/core/store"
"cosmossdk.io/core/transaction"
errorsmod "cosmossdk.io/errors/v2"
"cosmossdk.io/log"
"cosmossdk.io/schema/appdata"
Expand All @@ -35,6 +34,11 @@ import (
"cosmossdk.io/store/v2/snapshots"
consensustypes "cosmossdk.io/x/consensus/types"

addresscodec "cosmossdk.io/core/address"
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
coreserver "cosmossdk.io/core/server"
"cosmossdk.io/core/transaction"
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
hieuvubk marked this conversation as resolved.
Show resolved Hide resolved
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -86,8 +90,10 @@ type consensus[T transaction.Tx] struct {
addrPeerFilter types.PeerFilter // filter peers by address and port
idPeerFilter types.PeerFilter // filter peers by node ID

queryHandlersMap map[string]appmodulev2.Handler
getProtoRegistry func() (*protoregistry.Files, error)
queryHandlersMap map[string]appmodulev2.Handler
getProtoRegistry func() (*protoregistry.Files, error)
consensusAddressCodec addresscodec.Codec
cfgMap coreserver.ConfigMap
}

// CheckTx implements types.Application.
Expand Down Expand Up @@ -184,6 +190,15 @@ func (c *consensus[T]) Query(ctx context.Context, req *abciproto.QueryRequest) (
return resp, err
}

// when a client did not provide a query height, manually inject the latest
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
if req.Height == 0 {
lastestVersion, err := c.store.GetLatestVersion()
if err != nil {
return nil, err
}
req.Height = int64(lastestVersion)
hieuvubk marked this conversation as resolved.
Show resolved Hide resolved
}

// this error most probably means that we can't handle it with a proto message, so
// it must be an app/p2p/store query
path := splitABCIQueryPath(req.Path)
Expand Down Expand Up @@ -238,6 +253,61 @@ func (c *consensus[T]) maybeRunGRPCQuery(ctx context.Context, req *abci.QueryReq
handlerFullName = string(md.Input().FullName())
}

// Handle comet service
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
if strings.Contains(req.Path, "/cosmos.base.tendermint.v1beta1.Service") {
rpcClient, _ := rpchttp.New(c.cfg.AppTomlConfig.Address)
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
cometQServer := cmtservice.NewQueryServer(rpcClient, c.Query, c.consensusAddressCodec)
paths := strings.Split(req.Path, "/")

var resp transaction.Msg
var err error
switch paths[2] {
hieuvubk marked this conversation as resolved.
Show resolved Hide resolved
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
case "GetNodeInfo":
resp, err = handleCometService(ctx, req, cometQServer.GetNodeInfo)
case "GetSyncing":
resp, err = handleCometService(ctx, req, cometQServer.GetSyncing)
case "GetLatestBlock":
resp, err = handleCometService(ctx, req, cometQServer.GetLatestBlock)
case "GetBlockByHeight":
resp, err = handleCometService(ctx, req, cometQServer.GetBlockByHeight)
case "GetLatestValidatorSet":
resp, err = handleCometService(ctx, req, cometQServer.GetLatestValidatorSet)
case "GetValidatorSetByHeight":
resp, err = handleCometService(ctx, req, cometQServer.GetValidatorSetByHeight)
case "ABCIQuery":
resp, err = handleCometService(ctx, req, cometQServer.ABCIQuery)
}

if err != nil {
return nil, true, err
}

res, err := queryResponse(resp, req.Height)
return res, true, err
}

// Handle node service
if strings.Contains(req.Path, "/cosmos.base.node.v1beta1.Service") {
nodeQService := nodeServer[transaction.Tx]{c.cfgMap, c.cfg.AppTomlConfig, c}
paths := strings.Split(req.Path, "/")
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved

var resp transaction.Msg
var err error
switch paths[2] {
case "Config":
resp, err = handleCometService(ctx, req, nodeQService.Config)
case "Status":
resp, err = handleCometService(ctx, req, nodeQService.Status)
}

if err != nil {
return nil, true, err
}

res, err := queryResponse(resp, req.Height)
return res, true, err
}

// special case for simulation as it is an external gRPC registered on the grpc server component
// and not on the app itself, so it won't pass the router afterwards.
if req.Path == "/cosmos.tx.v1beta1.Service/Simulate" {
Expand Down Expand Up @@ -303,6 +373,30 @@ func (c *consensus[T]) maybeRunGRPCQuery(ctx context.Context, req *abci.QueryReq
return resp, true, err
}

func handleCometService[T any, PT interface {
*T
gogoproto.Message
},
U any, UT interface {
*U
gogoproto.Message
}](
ctx context.Context,
rawReq *abciproto.QueryRequest,
handler func(ctx context.Context, msg PT) (UT, error),
) (transaction.Msg, error) {
req := PT(new(T))
err := gogoproto.Unmarshal(rawReq.Data, req)
if err != nil {
return nil, err
}
typedResp, err := handler(ctx, req)
if err != nil {
return nil, err
}
return typedResp, nil
}

// InitChain implements types.Application.
func (c *consensus[T]) InitChain(ctx context.Context, req *abciproto.InitChainRequest) (*abciproto.InitChainResponse, error) {
c.logger.Info("InitChain", "initialHeight", req.InitialHeight, "chainID", req.ChainId)
Expand Down
3 changes: 3 additions & 0 deletions server/v2/cometbft/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"cosmossdk.io/server/v2/cometbft/types"
"cosmossdk.io/store/v2/snapshots"

addresscodec "cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
Expand Down Expand Up @@ -66,6 +67,7 @@ type CometBFTServer[T transaction.Tx] struct {
}

func New[T transaction.Tx](
consensusAddressCodec addresscodec.Codec,
hieuvubk marked this conversation as resolved.
Show resolved Hide resolved
logger log.Logger,
appName string,
store types.Store,
Expand Down Expand Up @@ -189,6 +191,7 @@ func New[T transaction.Tx](
getProtoRegistry: sync.OnceValues(gogoproto.MergedRegistry),
addrPeerFilter: srv.serverOptions.AddrPeerFilter,
idPeerFilter: srv.serverOptions.IdPeerFilter,
cfgMap: cfg,
}

c.optimisticExec = oe.NewOptimisticExecution(
Expand Down
1 change: 1 addition & 0 deletions simapp/v2/simdv2/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func InitRootCmd[T transaction.Tx](
// consensus component
if deps.ConsensusServer == nil {
deps.ConsensusServer, err = cometbft.New(
deps.ClientContext.ConsensusAddressCodec,
logger,
simApp.Name(),
simApp.Store(),
Expand Down
Loading