// Copyright 2021 Evmos Foundation // This file is part of Evmos' Ethermint library. // // The Ethermint library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The Ethermint library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE package server import ( "net" "net/http" "time" "github.com/evmos/ethermint/server/config" "github.com/gorilla/mux" "github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/spf13/cobra" "golang.org/x/net/netutil" sdkserver "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/version" tmcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" tmlog "github.com/tendermint/tendermint/libs/log" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" ) // AddCommands adds server commands func AddCommands( rootCmd *cobra.Command, defaultNodeHome string, appCreator types.AppCreator, appExport types.AppExporter, addStartFlags types.ModuleInitFlags, ) { tendermintCmd := &cobra.Command{ Use: "tendermint", Short: "Tendermint subcommands", } tendermintCmd.AddCommand( sdkserver.ShowNodeIDCmd(), sdkserver.ShowValidatorCmd(), sdkserver.ShowAddressCmd(), sdkserver.VersionCmd(), tmcmd.ResetAllCmd, tmcmd.ResetStateCmd, ) startCmd := StartCmd(appCreator, defaultNodeHome) addStartFlags(startCmd) rootCmd.AddCommand( startCmd, tendermintCmd, sdkserver.ExportCmd(appExport, defaultNodeHome), version.NewVersionCommand(), sdkserver.NewRollbackCmd(appCreator, defaultNodeHome), // custom tx indexer command NewIndexTxCmd(), ) } func ConnectTmWS(tmRPCAddr, tmEndpoint string, logger tmlog.Logger) *rpcclient.WSClient { tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint, rpcclient.MaxReconnectAttempts(256), rpcclient.ReadWait(120*time.Second), rpcclient.WriteWait(120*time.Second), rpcclient.PingPeriod(50*time.Second), rpcclient.OnReconnect(func() { logger.Debug("EVM RPC reconnects to Tendermint WS", "address", tmRPCAddr+tmEndpoint) }), ) if err != nil { logger.Error( "Tendermint WS client could not be created", "address", tmRPCAddr+tmEndpoint, "error", err, ) } else if err := tmWsClient.OnStart(); err != nil { logger.Error( "Tendermint WS client could not start", "address", tmRPCAddr+tmEndpoint, "error", err, ) } return tmWsClient } func MountGRPCWebServices( router *mux.Router, grpcWeb *grpcweb.WrappedGrpcServer, grpcResources []string, logger tmlog.Logger, ) { for _, res := range grpcResources { logger.Info("[GRPC Web] HTTP POST mounted", "resource", res) s := router.Methods("POST").Subrouter() s.HandleFunc(res, func(resp http.ResponseWriter, req *http.Request) { if grpcWeb.IsGrpcWebSocketRequest(req) { grpcWeb.HandleGrpcWebsocketRequest(resp, req) return } if grpcWeb.IsGrpcWebRequest(req) { grpcWeb.HandleGrpcWebRequest(resp, req) return } }) } } // Listen starts a net.Listener on the tcp network on the given address. // If there is a specified MaxOpenConnections in the config, it will also set the limitListener. func Listen(addr string, config *config.Config) (net.Listener, error) { if addr == "" { addr = ":http" } ln, err := net.Listen("tcp", addr) if err != nil { return nil, err } if config.JSONRPC.MaxOpenConnections > 0 { ln = netutil.LimitListener(ln, config.JSONRPC.MaxOpenConnections) } return ln, err }