Sync from fork #74
@ -60,6 +60,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
* (ledger) [#1277](https://github.com/evmos/ethermint/pull/1277) Add Ledger preprocessing transaction hook for EIP-712-signed Cosmos payloads.
|
* (ledger) [#1277](https://github.com/evmos/ethermint/pull/1277) Add Ledger preprocessing transaction hook for EIP-712-signed Cosmos payloads.
|
||||||
* (rpc) [#1296](https://github.com/evmos/ethermint/pull/1296) Add RPC Backend unit tests.
|
* (rpc) [#1296](https://github.com/evmos/ethermint/pull/1296) Add RPC Backend unit tests.
|
||||||
* (rpc) [#1352](https://github.com/evmos/ethermint/pull/1352) Make the grpc queries run concurrently, don't block the consensus state machine.
|
* (rpc) [#1352](https://github.com/evmos/ethermint/pull/1352) Make the grpc queries run concurrently, don't block the consensus state machine.
|
||||||
|
* (cli) [#1360](https://github.com/evmos/ethermint/pull/1360) Introduce a new `grpc-only` flag, such that when enabled, will start the node in a query-only mode. Note, gRPC MUST be enabled with this flag.
|
||||||
* (rpc) [#1378](https://github.com/evmos/ethermint/pull/1378) Add support for EVM RPC metrics
|
* (rpc) [#1378](https://github.com/evmos/ethermint/pull/1378) Add support for EVM RPC metrics
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -20,6 +20,7 @@ const (
|
|||||||
|
|
||||||
// GRPC-related flags.
|
// GRPC-related flags.
|
||||||
const (
|
const (
|
||||||
|
GRPCOnly = "grpc-only"
|
||||||
GRPCEnable = "grpc.enable"
|
GRPCEnable = "grpc.enable"
|
||||||
GRPCAddress = "grpc.address"
|
GRPCAddress = "grpc.address"
|
||||||
GRPCWebEnable = "grpc-web.enable"
|
GRPCWebEnable = "grpc-web.enable"
|
||||||
|
143
server/start.go
143
server/start.go
@ -150,6 +150,7 @@ which accepts a path for the resulting pprof file.
|
|||||||
cmd.Flags().Uint64(server.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks")
|
cmd.Flags().Uint64(server.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks")
|
||||||
cmd.Flags().String(srvflags.AppDBBackend, "", "The type of database for application and snapshots databases")
|
cmd.Flags().String(srvflags.AppDBBackend, "", "The type of database for application and snapshots databases")
|
||||||
|
|
||||||
|
cmd.Flags().Bool(srvflags.GRPCOnly, false, "Start the node in gRPC query only mode without Tendermint process")
|
||||||
cmd.Flags().Bool(srvflags.GRPCEnable, true, "Define if the gRPC server should be enabled")
|
cmd.Flags().Bool(srvflags.GRPCEnable, true, "Define if the gRPC server should be enabled")
|
||||||
cmd.Flags().String(srvflags.GRPCAddress, serverconfig.DefaultGRPCAddress, "the gRPC server address to listen on")
|
cmd.Flags().String(srvflags.GRPCAddress, serverconfig.DefaultGRPCAddress, "the gRPC server address to listen on")
|
||||||
cmd.Flags().Bool(srvflags.GRPCWebEnable, true, "Define if the gRPC-Web server should be enabled. (Note: gRPC must also be enabled.)")
|
cmd.Flags().Bool(srvflags.GRPCWebEnable, true, "Define if the gRPC-Web server should be enabled. (Note: gRPC must also be enabled.)")
|
||||||
@ -158,7 +159,7 @@ which accepts a path for the resulting pprof file.
|
|||||||
cmd.Flags().Bool(srvflags.RPCEnable, false, "Defines if Cosmos-sdk REST server should be enabled")
|
cmd.Flags().Bool(srvflags.RPCEnable, false, "Defines if Cosmos-sdk REST server should be enabled")
|
||||||
cmd.Flags().Bool(srvflags.EnabledUnsafeCors, false, "Defines if CORS should be enabled (unsafe - use it at your own risk)")
|
cmd.Flags().Bool(srvflags.EnabledUnsafeCors, false, "Defines if CORS should be enabled (unsafe - use it at your own risk)")
|
||||||
|
|
||||||
cmd.Flags().Bool(srvflags.JSONRPCEnable, true, "Define if the gRPC server should be enabled")
|
cmd.Flags().Bool(srvflags.JSONRPCEnable, true, "Define if the JSON-RPC server should be enabled")
|
||||||
cmd.Flags().StringSlice(srvflags.JSONRPCAPI, config.GetDefaultAPINamespaces(), "Defines a list of JSON-RPC namespaces that should be enabled")
|
cmd.Flags().StringSlice(srvflags.JSONRPCAPI, config.GetDefaultAPINamespaces(), "Defines a list of JSON-RPC namespaces that should be enabled")
|
||||||
cmd.Flags().String(srvflags.JSONRPCAddress, config.DefaultJSONRPCAddress, "the JSON-RPC server address to listen on")
|
cmd.Flags().String(srvflags.JSONRPCAddress, config.DefaultJSONRPCAddress, "the JSON-RPC server address to listen on")
|
||||||
cmd.Flags().String(srvflags.JSONWsAddress, config.DefaultJSONRPCWsAddress, "the JSON-RPC WS server address to listen on")
|
cmd.Flags().String(srvflags.JSONWsAddress, config.DefaultJSONRPCWsAddress, "the JSON-RPC WS server address to listen on")
|
||||||
@ -239,8 +240,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
cfg := ctx.Config
|
cfg := ctx.Config
|
||||||
home := cfg.RootDir
|
home := cfg.RootDir
|
||||||
logger := ctx.Logger
|
logger := ctx.Logger
|
||||||
var cpuProfileCleanup func() error
|
|
||||||
|
|
||||||
if cpuProfile := ctx.Viper.GetString(srvflags.CPUProfile); cpuProfile != "" {
|
if cpuProfile := ctx.Viper.GetString(srvflags.CPUProfile); cpuProfile != "" {
|
||||||
fp, err := ethdebug.ExpandHome(cpuProfile)
|
fp, err := ethdebug.ExpandHome(cpuProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -257,15 +256,13 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuProfileCleanup = func() error {
|
defer func() {
|
||||||
ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile)
|
ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile)
|
||||||
pprof.StopCPUProfile()
|
pprof.StopCPUProfile()
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
logger.Error("failed to close CPU profiler file", "error", err.Error())
|
logger.Error("failed to close CPU profiler file", "error", err.Error())
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
traceWriterFile := ctx.Viper.GetString(srvflags.TraceStore)
|
traceWriterFile := ctx.Viper.GetString(srvflags.TraceStore)
|
||||||
@ -313,7 +310,16 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)
|
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)
|
||||||
tmNode, err := node.NewNode(
|
var (
|
||||||
|
tmNode *node.Node
|
||||||
|
gRPCOnly = ctx.Viper.GetBool(srvflags.GRPCOnly)
|
||||||
|
)
|
||||||
|
if gRPCOnly {
|
||||||
|
ctx.Logger.Info("starting node in query only mode; Tendermint is disabled")
|
||||||
|
config.GRPC.Enable = true
|
||||||
|
config.JSONRPC.EnableIndexer = false
|
||||||
|
} else {
|
||||||
|
tmNode, err = node.NewNode(
|
||||||
cfg,
|
cfg,
|
||||||
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
|
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
|
||||||
nodeKey,
|
nodeKey,
|
||||||
@ -333,10 +339,18 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if tmNode.IsRunning() {
|
||||||
|
_ = tmNode.Stop()
|
||||||
|
}
|
||||||
|
logger.Info("Bye!")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// Add the tx service to the gRPC router. We only need to register this
|
// Add the tx service to the gRPC router. We only need to register this
|
||||||
// service if API or gRPC or JSONRPC is enabled, and avoid doing so in the general
|
// service if API or gRPC or JSONRPC is enabled, and avoid doing so in the general
|
||||||
// case, because it spawns a new local tendermint RPC client.
|
// case, because it spawns a new local tendermint RPC client.
|
||||||
if config.API.Enable || config.GRPC.Enable || config.JSONRPC.Enable || config.JSONRPC.EnableIndexer {
|
if (config.API.Enable || config.GRPC.Enable || config.JSONRPC.Enable || config.JSONRPC.EnableIndexer) && tmNode != nil {
|
||||||
clientCtx = clientCtx.WithClient(local.New(tmNode))
|
clientCtx = clientCtx.WithClient(local.New(tmNode))
|
||||||
|
|
||||||
app.RegisterTxService(clientCtx)
|
app.RegisterTxService(clientCtx)
|
||||||
@ -429,7 +443,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
apiSrv = api.New(clientCtx, ctx.Logger.With("server", "api"))
|
apiSrv = api.New(clientCtx, ctx.Logger.With("server", "api"))
|
||||||
app.RegisterAPIRoutes(apiSrv, config.API)
|
app.RegisterAPIRoutes(apiSrv, config.API)
|
||||||
errCh := make(chan error)
|
errCh := make(chan error)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := apiSrv.Start(config.Config); err != nil {
|
if err := apiSrv.Start(config.Config); err != nil {
|
||||||
errCh <- err
|
errCh <- err
|
||||||
@ -441,6 +454,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
return err
|
return err
|
||||||
case <-time.After(types.ServerStartTime): // assume server started successfully
|
case <-time.After(types.ServerStartTime): // assume server started successfully
|
||||||
}
|
}
|
||||||
|
defer apiSrv.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -452,13 +466,60 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer grpcSrv.Stop()
|
||||||
if config.GRPCWeb.Enable {
|
if config.GRPCWeb.Enable {
|
||||||
grpcWebSrv, err = servergrpc.StartGRPCWeb(grpcSrv, config.Config)
|
grpcWebSrv, err = servergrpc.StartGRPCWeb(grpcSrv, config.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Logger.Error("failed to start grpc-web http server", "error", err)
|
ctx.Logger.Error("failed to start grpc-web http server", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := grpcWebSrv.Close(); err != nil {
|
||||||
|
logger.Error("failed to close the grpcWebSrc", "error", err.Error())
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
httpSrv *http.Server
|
||||||
|
httpSrvDone chan struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if config.JSONRPC.Enable {
|
||||||
|
genDoc, err := genDocProvider()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCtx := clientCtx.WithChainID(genDoc.ChainID)
|
||||||
|
|
||||||
|
tmEndpoint := "/websocket"
|
||||||
|
tmRPCAddr := cfg.RPC.ListenAddress
|
||||||
|
httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, tmRPCAddr, tmEndpoint, &config, idxer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancelFn()
|
||||||
|
if err := httpSrv.Shutdown(shutdownCtx); err != nil {
|
||||||
|
logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
|
||||||
|
} else {
|
||||||
|
logger.Info("HTTP server shut down, waiting 5 sec")
|
||||||
|
select {
|
||||||
|
case <-time.Tick(5 * time.Second):
|
||||||
|
case <-httpSrvDone:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point it is safe to block the process if we're in query only mode as
|
||||||
|
// we do not need to start Rosetta or handle any Tendermint related processes.
|
||||||
|
if gRPCOnly {
|
||||||
|
// wait for signal capture and gracefully return
|
||||||
|
return server.WaitForQuitSignals()
|
||||||
}
|
}
|
||||||
|
|
||||||
var rosettaSrv crgserver.Server
|
var rosettaSrv crgserver.Server
|
||||||
@ -496,68 +557,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
|||||||
case <-time.After(types.ServerStartTime): // assume server started successfully
|
case <-time.After(types.ServerStartTime): // assume server started successfully
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
httpSrv *http.Server
|
|
||||||
httpSrvDone chan struct{}
|
|
||||||
)
|
|
||||||
|
|
||||||
if config.JSONRPC.Enable {
|
|
||||||
genDoc, err := genDocProvider()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
clientCtx := clientCtx.WithChainID(genDoc.ChainID)
|
|
||||||
|
|
||||||
tmEndpoint := "/websocket"
|
|
||||||
tmRPCAddr := cfg.RPC.ListenAddress
|
|
||||||
httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, tmRPCAddr, tmEndpoint, &config, idxer)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if tmNode.IsRunning() {
|
|
||||||
_ = tmNode.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
if cpuProfileCleanup != nil {
|
|
||||||
_ = cpuProfileCleanup()
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiSrv != nil {
|
|
||||||
_ = apiSrv.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if grpcSrv != nil {
|
|
||||||
grpcSrv.Stop()
|
|
||||||
if grpcWebSrv != nil {
|
|
||||||
if err := grpcWebSrv.Close(); err != nil {
|
|
||||||
logger.Error("failed to close the grpcWebSrc", "error", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if httpSrv != nil {
|
|
||||||
shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancelFn()
|
|
||||||
|
|
||||||
if err := httpSrv.Shutdown(shutdownCtx); err != nil {
|
|
||||||
logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
|
|
||||||
} else {
|
|
||||||
logger.Info("HTTP server shut down, waiting 5 sec")
|
|
||||||
select {
|
|
||||||
case <-time.Tick(5 * time.Second):
|
|
||||||
case <-httpSrvDone:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info("Bye!")
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait for SIGINT or SIGTERM signal
|
// Wait for SIGINT or SIGTERM signal
|
||||||
return server.WaitForQuitSignals()
|
return server.WaitForQuitSignals()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user