package server import ( "net" "net/http" "time" "github.com/gorilla/mux" "github.com/rs/cors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/types" ethrpc "github.com/ethereum/go-ethereum/rpc" "github.com/tharsis/ethermint/ethereum/rpc" "github.com/tharsis/ethermint/server/config" ) // StartJSONRPC starts the JSON-RPC server func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEndpoint string, config config.Config) (*http.Server, chan struct{}, error) { tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger) rpcServer := ethrpc.NewServer() rpcAPIArr := config.JSONRPC.API apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient, rpcAPIArr) for _, api := range apis { if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil { ctx.Logger.Error( "failed to register service in JSON RPC namespace", "namespace", api.Namespace, "service", api.Service, ) return nil, nil, err } } r := mux.NewRouter() r.HandleFunc("/", rpcServer.ServeHTTP).Methods("POST") handlerWithCors := cors.Default() if config.API.EnableUnsafeCORS { handlerWithCors = cors.AllowAll() } httpSrv := &http.Server{ Addr: config.JSONRPC.Address, Handler: handlerWithCors.Handler(r), } httpSrvDone := make(chan struct{}, 1) errCh := make(chan error) go func() { ctx.Logger.Info("Starting JSON-RPC server", "address", config.JSONRPC.Address) if err := httpSrv.ListenAndServe(); err != nil { if err == http.ErrServerClosed { close(httpSrvDone) return } ctx.Logger.Error("failed to start JSON-RPC server", "error", err.Error()) errCh <- err } }() select { case err := <-errCh: ctx.Logger.Error("failed to boot JSON-RPC server", "error", err.Error()) return nil, nil, err case <-time.After(types.ServerStartTime): // assume JSON RPC server started successfully } ctx.Logger.Info("Starting JSON WebSocket server", "address", config.JSONRPC.WsAddress) _, port, _ := net.SplitHostPort(config.JSONRPC.Address) // allocate separate WS connection to Tendermint tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger) wsSrv := rpc.NewWebsocketsServer(ctx.Logger, tmWsClient, "localhost:"+port, config.JSONRPC.WsAddress) wsSrv.Start() return httpSrv, httpSrvDone, nil }