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

Problem: node can't quit by signal #543

Merged
merged 4 commits into from
Oct 17, 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: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#534](https://github.com/crypto-org-chain/ethermint/pull/534), [#540](https://github.com/crypto-org-chain/ethermint/pull/540) Fix opBlockhash when no block header in abci request.
* (rpc) [#536](https://github.com/crypto-org-chain/ethermint/pull/536) Fix validate basic after transaction conversion with raw field.
* (cli) [#537](https://github.com/crypto-org-chain/ethermint/pull/537) Fix unsuppored sign mode SIGN_MODE_TEXTUAL for bank transfer.
* (cli) [#543](https://github.com/crypto-org-chain/ethermint/pull/543) Fix graceful shutdown.

### Improvements

Expand Down
37 changes: 28 additions & 9 deletions server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package server

import (
"context"
"fmt"
"net/http"
"time"
Expand Down Expand Up @@ -47,18 +48,20 @@
}

// StartJSONRPC starts the JSON-RPC server
func StartJSONRPC(srvCtx *server.Context,
func StartJSONRPC(
ctx context.Context,
srvCtx *server.Context,
clientCtx client.Context,
g *errgroup.Group,
config *config.Config,
indexer ethermint.EVMTxIndexer,
app AppWithPendingTxStream,
) (*http.Server, chan struct{}, error) {
) (*http.Server, error) {

Check warning on line 59 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L59

Added line #L59 was not covered by tests
logger := srvCtx.Logger.With("module", "geth")

evtClient, ok := clientCtx.Client.(rpcclient.EventsClient)
if !ok {
return nil, nil, fmt.Errorf("client %T does not implement EventsClient", clientCtx.Client)
return nil, fmt.Errorf("client %T does not implement EventsClient", clientCtx.Client)

Check warning on line 64 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L64

Added line #L64 was not covered by tests
}

var rpcStream *stream.RPCStream
Expand All @@ -73,7 +76,7 @@
}

if err != nil {
return nil, nil, fmt.Errorf("failed to create rpc streams after %d attempts: %w", MaxRetry, err)
return nil, fmt.Errorf("failed to create rpc streams after %d attempts: %w", MaxRetry, err)

Check warning on line 79 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L79

Added line #L79 was not covered by tests
}

app.RegisterPendingTxListener(rpcStream.ListenPendingTx)
Expand Down Expand Up @@ -104,7 +107,7 @@
"namespace", api.Namespace,
"service", api.Service,
)
return nil, nil, err
return nil, err

Check warning on line 110 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L110

Added line #L110 was not covered by tests
}
}

Expand All @@ -128,25 +131,41 @@

ln, err := Listen(httpSrv.Addr, config)
if err != nil {
return nil, nil, err
return nil, err

Check warning on line 134 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L134

Added line #L134 was not covered by tests
}

g.Go(func() error {
srvCtx.Logger.Info("Starting JSON-RPC server", "address", config.JSONRPC.Address)
if err := httpSrv.Serve(ln); err != nil {
errCh := make(chan error)
go func() {
errCh <- httpSrv.Serve(ln)
}()

Check warning on line 142 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L139-L142

Added lines #L139 - L142 were not covered by tests

// Start a blocking select to wait for an indication to stop the server or that
// the server failed to start properly.
select {
case <-ctx.Done():

Check warning on line 147 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L146-L147

Added lines #L146 - L147 were not covered by tests
mmsqe marked this conversation as resolved.
Show resolved Hide resolved
// The calling process canceled or closed the provided context, so we must
// gracefully stop the JSON-RPC server.
logger.Info("stopping JSON-RPC server...", "address", config.JSONRPC.Address)
if err := httpSrv.Shutdown(context.Background()); err != nil {
logger.Error("failed to shutdown JSON-RPC server", "error", err.Error())

Check warning on line 152 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L150-L152

Added lines #L150 - L152 were not covered by tests
}
return ln.Close()

Check warning on line 154 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L154

Added line #L154 was not covered by tests

case err := <-errCh:

Check warning on line 156 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L156

Added line #L156 was not covered by tests
if err == http.ErrServerClosed {
close(httpSrvDone)
}

srvCtx.Logger.Error("failed to start JSON-RPC server", "error", err.Error())
return err
}
return nil
})

srvCtx.Logger.Info("Starting JSON WebSocket server", "address", config.JSONRPC.WsAddress)

wsSrv := rpc.NewWebsocketsServer(clientCtx, srvCtx.Logger, rpcStream, config)
wsSrv.Start()
return httpSrv, httpSrvDone, nil
return httpSrv, nil

Check warning on line 170 in server/json_rpc.go

View check run for this annotation

Codecov / codecov/patch

server/json_rpc.go#L170

Added line #L170 was not covered by tests
}
54 changes: 16 additions & 38 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@
"fmt"
"io"
"net"
"net/http"
"os"
"path/filepath"
"runtime/pprof"
"time"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -419,10 +417,11 @@
idxer = indexer.NewKVIndexer(idxDB, idxLogger, clientCtx)
indexerService := NewEVMIndexerService(idxer, clientCtx.Client.(rpcclient.Client), config.JSONRPC.AllowIndexerGap)
indexerService.SetLogger(servercmtlog.CometLoggerWrapper{Logger: idxLogger})

g.Go(func() error {
return indexerService.Start()
})
go func() {
if err := indexerService.Start(); err != nil {
logger.Error("failed to start evm indexer service", "error", err.Error())

Check warning on line 422 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L420-L422

Added lines #L420 - L422 were not covered by tests
}
}()
}

if config.API.Enable || config.JSONRPC.Enable {
Expand All @@ -443,30 +442,12 @@
if err != nil {
return err
}
if grpcSrv != nil {
defer grpcSrv.GracefulStop()
}

apiSrv := startAPIServer(ctx, svrCtx, clientCtx, g, config.Config, app, grpcSrv, metrics)
if apiSrv != nil {
defer apiSrv.Close()
}
startAPIServer(ctx, svrCtx, clientCtx, g, config.Config, app, grpcSrv, metrics)

Check warning on line 446 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L446

Added line #L446 was not covered by tests

clientCtx, httpSrv, httpSrvDone, err := startJSONRPCServer(svrCtx, clientCtx, g, config, genDocProvider, idxer, app)
if httpSrv != nil {
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:
}
}
}()
clientCtx, err = startJSONRPCServer(ctx, svrCtx, clientCtx, g, config, genDocProvider, idxer, app)
if err != nil {
return err

Check warning on line 450 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L448-L450

Added lines #L448 - L450 were not covered by tests
}

// At this point it is safe to block the process if we're in query only mode as
Expand Down Expand Up @@ -619,9 +600,9 @@
app types.Application,
grpcSrv *grpc.Server,
metrics *telemetry.Metrics,
) *api.Server {
) {

Check warning on line 603 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L603

Added line #L603 was not covered by tests
if !svrCfg.API.Enable {
return nil
return

Check warning on line 605 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L605

Added line #L605 was not covered by tests
}

apiSrv := api.New(clientCtx, svrCtx.Logger.With("server", "api"), grpcSrv)
Expand All @@ -634,38 +615,35 @@
g.Go(func() error {
return apiSrv.Start(ctx, svrCfg)
})
return apiSrv
}

func startJSONRPCServer(
stdCtx context.Context,
svrCtx *server.Context,
clientCtx client.Context,
g *errgroup.Group,
config config.Config,
genDocProvider node.GenesisDocProvider,
idxer ethermint.EVMTxIndexer,
app types.Application,
) (ctx client.Context, httpSrv *http.Server, httpSrvDone chan struct{}, err error) {
) (ctx client.Context, err error) {

Check warning on line 629 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L629

Added line #L629 was not covered by tests
ctx = clientCtx
if !config.JSONRPC.Enable {
return
}

txApp, ok := app.(AppWithPendingTxStream)
if !ok {
return ctx, httpSrv, httpSrvDone, fmt.Errorf("json-rpc server requires AppWithPendingTxStream")
return ctx, fmt.Errorf("json-rpc server requires AppWithPendingTxStream")

Check warning on line 637 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L637

Added line #L637 was not covered by tests
}

genDoc, err := genDocProvider()
if err != nil {
return ctx, httpSrv, httpSrvDone, err
return ctx, err

Check warning on line 642 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L642

Added line #L642 was not covered by tests
}

ctx = clientCtx.WithChainID(genDoc.ChainID)
g.Go(func() error {
httpSrv, httpSrvDone, err = StartJSONRPC(svrCtx, clientCtx, g, &config, idxer, txApp)
return err
})
_, err = StartJSONRPC(stdCtx, svrCtx, clientCtx, g, &config, idxer, txApp)

Check warning on line 646 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L646

Added line #L646 was not covered by tests
return
}

Expand Down
28 changes: 8 additions & 20 deletions testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,13 @@
RPCClient tmrpcclient.Client
JSONRPCClient *ethclient.Client

tmNode *node.Node
api *api.Server
grpc *grpc.Server
grpcWeb *http.Server
jsonrpc *http.Server
jsonrpcDone chan struct{}
errGroup *errgroup.Group
cancelFn context.CancelFunc
tmNode *node.Node
api *api.Server
grpc *grpc.Server
grpcWeb *http.Server
jsonrpc *http.Server
errGroup *errgroup.Group
cancelFn context.CancelFunc
}
)

Expand Down Expand Up @@ -648,18 +647,7 @@
}

if v.jsonrpc != nil {
shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
defer cancelFn()

if err := v.jsonrpc.Shutdown(shutdownCtx); err != nil {
v.tmNode.Logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
} else {
v.tmNode.Logger.Info("HTTP server shut down, waiting 5 sec")
select {
case <-time.Tick(5 * time.Second):
case <-v.jsonrpcDone:
}
}
_ = v.jsonrpc.Close()

Check warning on line 650 in testutil/network/network.go

View check run for this annotation

Codecov / codecov/patch

testutil/network/network.go#L650

Added line #L650 was not covered by tests
}
}

Expand Down
4 changes: 2 additions & 2 deletions testutil/network/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@
return fmt.Errorf("validator %s context is nil", val.Moniker)
}

val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(
val.Ctx, val.ClientCtx, val.errGroup, val.AppConfig,
val.jsonrpc, err = server.StartJSONRPC(
ctx, val.Ctx, val.ClientCtx, val.errGroup, val.AppConfig,

Check warning on line 147 in testutil/network/util.go

View check run for this annotation

Codecov / codecov/patch

testutil/network/util.go#L146-L147

Added lines #L146 - L147 were not covered by tests
nil, app.(server.AppWithPendingTxStream),
)
if err != nil {
Expand Down
Loading