diff --git a/CHANGELOG.md b/CHANGELOG.md index d0f0aacf6fb6..97bf73f19f6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +* (server) [#18110](https://github.com/cosmos/cosmos-sdk/pull/18110) Start gRPC & API server in standalone mode * (client) [#18101](https://github.com/cosmos/cosmos-sdk/pull/18101) Add a `keyring-default-keyname` in `client.toml` for specifying a default key name, and skip the need to use the `--from` flag when signing transactions. * (tests) [#17868](https://github.com/cosmos/cosmos-sdk/pull/17868) Added helper method `SubmitTestTx` in testutil to broadcast test txns to test e2e tests. * (x/protocolpool) [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) Create a new `x/protocolpool` module that is responsible for handling community pool funds. This module is split out into a new module from x/distribution. diff --git a/docs/user/run-node/01-run-node.md b/docs/user/run-node/01-run-node.md index a9ef422b6889..f16eb42f52de 100644 --- a/docs/user/run-node/01-run-node.md +++ b/docs/user/run-node/01-run-node.md @@ -157,6 +157,13 @@ The previous command allow you to run a single node. This is enough for the next The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the Cosmos SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the Cosmos SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/docker-compose.yml). +### Standalone App/CometBFT + +By default, the Cosmos SDK runs CometBFT in-process with the application +If you want to run the application and CometBFT in separate processes, +start the application with the `--with-comet=false` flag +and set `rpc.laddr` in `config.toml` to the CometBFT node's RPC address. + ## Logging Logging provides a way to see what is going on with a node. By default the info level is set. This is a global level and all info logs will be outputted to the terminal. If you would like to filter specific logs to the terminal instead of all, then setting `module:log_level` is how this can work. diff --git a/server/start.go b/server/start.go index 5e4383b1422e..008fb2e1864e 100644 --- a/server/start.go +++ b/server/start.go @@ -16,6 +16,7 @@ import ( "github.com/cometbft/cometbft/p2p" pvm "github.com/cometbft/cometbft/privval" "github.com/cometbft/cometbft/proxy" + rpchttp "github.com/cometbft/cometbft/rpc/client/http" "github.com/cometbft/cometbft/rpc/client/local" cmttypes "github.com/cometbft/cometbft/types" dbm "github.com/cosmos/cosmos-db" @@ -258,12 +259,12 @@ func start(svrCtx *Context, clientCtx client.Context, appCreator types.AppCreato emitServerInfoMetrics() if !withCmt { - return startStandAlone(svrCtx, app, opts) + return startStandAlone(svrCtx, svrCfg, clientCtx, app, metrics, opts) } return startInProcess(svrCtx, svrCfg, clientCtx, app, metrics, opts) } -func startStandAlone(svrCtx *Context, app types.Application, opts StartCmdOptions) error { +func startStandAlone(svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app types.Application, metrics *telemetry.Metrics, opts StartCmdOptions) error { addr := svrCtx.Viper.GetString(flagAddress) transport := svrCtx.Viper.GetString(flagTransport) @@ -277,6 +278,39 @@ func startStandAlone(svrCtx *Context, app types.Application, opts StartCmdOption g, ctx := getCtx(svrCtx, false) + // Add the tx service to the gRPC router. We only need to register this + // service if API or gRPC is enabled, and avoid doing so in the general + // case, because it spawns a new local CometBFT RPC client. + if svrCfg.API.Enable || svrCfg.GRPC.Enable { + // create tendermint client + // assumes the rpc listen address is where tendermint has its rpc server + rpcclient, err := rpchttp.New(svrCtx.Config.RPC.ListenAddress, "/websocket") + if err != nil { + return err + } + // re-assign for making the client available below + // do not use := to avoid shadowing clientCtx + clientCtx = clientCtx.WithClient(rpcclient) + + // use the provided clientCtx to register the services + app.RegisterTxService(clientCtx) + app.RegisterTendermintService(clientCtx) + app.RegisterNodeService(clientCtx, svrCfg) + } + + grpcSrv, clientCtx, err := startGrpcServer(ctx, g, svrCfg.GRPC, clientCtx, svrCtx, app) + if err != nil { + return err + } + + cmtCfg := svrCtx.Config + home := cmtCfg.RootDir + + err = startAPIServer(ctx, g, cmtCfg, svrCfg, clientCtx, svrCtx, app, home, grpcSrv, metrics) + if err != nil { + return err + } + g.Go(func() error { if err := svr.Start(); err != nil { svrCtx.Logger.Error("failed to start out-of-process ABCI server", "err", err)