From 57f93d25bd9a09f4a68307342ad44a5af1d5dc26 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 16 Apr 2015 12:56:51 +0200 Subject: [PATCH 1/7] admin.stopRPC support added which stops the RPC HTTP listener --- cmd/geth/admin.go | 8 ++++++ rpc/http.go | 21 +++++++++++++-- rpc/types.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go index f8c717187..3b37cba75 100644 --- a/cmd/geth/admin.go +++ b/cmd/geth/admin.go @@ -26,6 +26,7 @@ func (js *jsre) adminBindings() { admin := t.Object() admin.Set("suggestPeer", js.suggestPeer) admin.Set("startRPC", js.startRPC) + admin.Set("stopRPC", js.stopRPC) admin.Set("nodeInfo", js.nodeInfo) admin.Set("peers", js.peers) admin.Set("newAccount", js.newAccount) @@ -141,6 +142,13 @@ func (js *jsre) startRPC(call otto.FunctionCall) otto.Value { return otto.TrueValue() } +func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value { + if rpc.Stop() == nil { + return otto.TrueValue() + } + return otto.FalseValue() +} + func (js *jsre) suggestPeer(call otto.FunctionCall) otto.Value { nodeURL, err := call.Argument(0).ToString() if err != nil { diff --git a/rpc/http.go b/rpc/http.go index 790442a28..61f8da549 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "io/ioutil" - "net" "net/http" "github.com/ethereum/go-ethereum/logger" @@ -15,6 +14,7 @@ import ( ) var rpclogger = logger.NewLogger("RPC") +var rpclistener *ControllableTCPListener const ( jsonrpcver = "2.0" @@ -22,11 +22,17 @@ const ( ) func Start(pipe *xeth.XEth, config RpcConfig) error { - l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) + if rpclistener != nil { // listener already running + glog.Infoln("RPC listener already running") + return fmt.Errorf("RPC already running on %s", rpclistener.Addr().String()) + } + + l, err := NewControllableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) if err != nil { rpclogger.Errorf("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err) return err } + rpclistener = l var handler http.Handler if len(config.CorsDomain) > 0 { @@ -45,6 +51,17 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { return nil } +func Stop() error { + if rpclistener == nil { // listener not running + glog.Infoln("RPC listener not running") + return nil + } + + rpclistener.Stop() + rpclistener = nil + return nil +} + // JSONRPC returns a handler that implements the Ethereum JSON-RPC API. func JSONRPC(pipe *xeth.XEth) http.Handler { api := NewEthereumApi(pipe) diff --git a/rpc/types.go b/rpc/types.go index bc9a46ed5..c7dc2cc9a 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -23,6 +23,10 @@ import ( "math/big" "strings" + "errors" + "net" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -257,3 +261,66 @@ type RpcErrorObject struct { Message string `json:"message"` // Data interface{} `json:"data"` } + +type ListenerStoppedError struct { + msg string +} + +func (self ListenerStoppedError) Timout() bool { + return false +} + +func (self ListenerStoppedError) Temporary() bool { + return false +} + +func (self ListenerStoppedError) Error() string { + return self.msg +} + +type ControllableTCPListener struct { + *net.TCPListener + stop chan struct{} +} + +var listenerStoppedError ListenerStoppedError + +func (self *ControllableTCPListener) Stop() { + close(self.stop) +} + +func (self *ControllableTCPListener) Accept() (net.Conn, error) { + for { + self.SetDeadline(time.Now().Add(time.Duration(500 * time.Millisecond))) + c, err := self.TCPListener.AcceptTCP() + + select { + case <-self.stop: + self.TCPListener.Close() + return nil, listenerStoppedError + default: // keep on going + } + + if err != nil { + if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() { + continue // regular timeout + } + } + + return c, err + } +} + +func NewControllableTCPListener(addr string) (*ControllableTCPListener, error) { + wl, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + if tcpl, ok := wl.(*net.TCPListener); ok { + l := &ControllableTCPListener{tcpl, make(chan struct{})} + return l, nil + } + + return nil, errors.New("Unable to create TCP listener for RPC") +} From ead3dd9759c9cc8076ad716fe10cf641751b65b0 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 16 Apr 2015 19:23:57 +0200 Subject: [PATCH 2/7] Stop accepted and alive connections (http keep-alive) when the rpc service is stopped --- rpc/http.go | 22 ++++++------- rpc/types.go | 91 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index 61f8da549..882aff7ea 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -14,7 +14,7 @@ import ( ) var rpclogger = logger.NewLogger("RPC") -var rpclistener *ControllableTCPListener +var rpclistener *StoppableTCPListener const ( jsonrpcver = "2.0" @@ -22,12 +22,14 @@ const ( ) func Start(pipe *xeth.XEth, config RpcConfig) error { - if rpclistener != nil { // listener already running - glog.Infoln("RPC listener already running") - return fmt.Errorf("RPC already running on %s", rpclistener.Addr().String()) + if rpclistener != nil { + if fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort) != rpclistener.Addr().String() { + return fmt.Errorf("RPC service already running on %s ", rpclistener.Addr().String()) + } + return nil // RPC service already running on given host/port } - l, err := NewControllableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) + l, err := NewStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) if err != nil { rpclogger.Errorf("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err) return err @@ -41,7 +43,7 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { opts.AllowedOrigins = []string{config.CorsDomain} c := cors.New(opts) - handler = c.Handler(JSONRPC(pipe)) + handler = NewStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) } else { handler = JSONRPC(pipe) } @@ -52,13 +54,11 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { } func Stop() error { - if rpclistener == nil { // listener not running - glog.Infoln("RPC listener not running") - return nil + if rpclistener != nil { + rpclistener.Stop() + rpclistener = nil } - rpclistener.Stop() - rpclistener = nil return nil } diff --git a/rpc/types.go b/rpc/types.go index c7dc2cc9a..b33621fef 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -25,8 +25,11 @@ import ( "errors" "net" + "net/http" "time" + "io" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -266,39 +269,64 @@ type ListenerStoppedError struct { msg string } -func (self ListenerStoppedError) Timout() bool { - return false -} - -func (self ListenerStoppedError) Temporary() bool { - return false -} - func (self ListenerStoppedError) Error() string { return self.msg } -type ControllableTCPListener struct { +var listenerStoppedError = ListenerStoppedError{"Listener stopped"} + +type StoppableTCPListener struct { *net.TCPListener - stop chan struct{} + stop *chan struct{} // closed when the listener must stop } -var listenerStoppedError ListenerStoppedError - -func (self *ControllableTCPListener) Stop() { - close(self.stop) +// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an +// error indicating that the service was stopped. This will only happen for connections which are +// kept open (HTTP keep-alive) when the RPC service was shutdown. +func NewStoppableHandler(h http.Handler, stop *chan struct{}) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + select { + case <-*stop: + w.Header().Set("Content-Type", "application/json") + jsonerr := &RpcErrorObject{-32603, "RPC service stopt"} + send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) + default: + h.ServeHTTP(w, r) + } + }) } -func (self *ControllableTCPListener) Accept() (net.Conn, error) { +// Stop the listener and all accepted and still active connections. +func (self *StoppableTCPListener) Stop() { + close(*self.stop) +} + +func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { + wl, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + if tcpl, ok := wl.(*net.TCPListener); ok { + stop := make(chan struct{}) + l := &StoppableTCPListener{tcpl, &stop} + return l, nil + } + + return nil, errors.New("Unable to create TCP listener for RPC service") +} + +func (self *StoppableTCPListener) Accept() (net.Conn, error) { for { - self.SetDeadline(time.Now().Add(time.Duration(500 * time.Millisecond))) + self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second))) c, err := self.TCPListener.AcceptTCP() select { - case <-self.stop: + case <-*self.stop: + c.Close() self.TCPListener.Close() return nil, listenerStoppedError - default: // keep on going + default: } if err != nil { @@ -307,20 +335,21 @@ func (self *ControllableTCPListener) Accept() (net.Conn, error) { } } - return c, err + return &ClosableConnection{c, self.stop}, err } } -func NewControllableTCPListener(addr string) (*ControllableTCPListener, error) { - wl, err := net.Listen("tcp", addr) - if err != nil { - return nil, err - } - - if tcpl, ok := wl.(*net.TCPListener); ok { - l := &ControllableTCPListener{tcpl, make(chan struct{})} - return l, nil - } - - return nil, errors.New("Unable to create TCP listener for RPC") +type ClosableConnection struct { + *net.TCPConn + closed *chan struct{} +} + +func (self *ClosableConnection) Read(b []byte) (n int, err error) { + select { + case <-*self.closed: + self.TCPConn.Close() + return 0, io.EOF + default: + return self.TCPConn.Read(b) + } } From 2c229bac003b30908fd0dc0d69d35044c6cb2425 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Sun, 19 Apr 2015 09:55:41 +0200 Subject: [PATCH 3/7] Replaced channel pointer field with non pointer channel --- rpc/http.go | 2 +- rpc/types.go | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index 882aff7ea..5ff4f613b 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -45,7 +45,7 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { c := cors.New(opts) handler = NewStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) } else { - handler = JSONRPC(pipe) + handler = NewStoppableHandler(JSONRPC(pipe), l.stop) } go http.Serve(l, handler) diff --git a/rpc/types.go b/rpc/types.go index b33621fef..71ed5df49 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -275,20 +275,21 @@ func (self ListenerStoppedError) Error() string { var listenerStoppedError = ListenerStoppedError{"Listener stopped"} +// When https://github.com/golang/go/issues/4674 is fixed this could be replaced type StoppableTCPListener struct { *net.TCPListener - stop *chan struct{} // closed when the listener must stop + stop chan struct{} // closed when the listener must stop } // Wraps the default handler and checks if the RPC service was stopped. In that case it returns an // error indicating that the service was stopped. This will only happen for connections which are // kept open (HTTP keep-alive) when the RPC service was shutdown. -func NewStoppableHandler(h http.Handler, stop *chan struct{}) http.Handler { +func NewStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { select { - case <-*stop: + case <-stop: w.Header().Set("Content-Type", "application/json") - jsonerr := &RpcErrorObject{-32603, "RPC service stopt"} + jsonerr := &RpcErrorObject{-32603, "RPC service stopped"} send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) default: h.ServeHTTP(w, r) @@ -298,7 +299,7 @@ func NewStoppableHandler(h http.Handler, stop *chan struct{}) http.Handler { // Stop the listener and all accepted and still active connections. func (self *StoppableTCPListener) Stop() { - close(*self.stop) + close(self.stop) } func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { @@ -309,7 +310,7 @@ func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { if tcpl, ok := wl.(*net.TCPListener); ok { stop := make(chan struct{}) - l := &StoppableTCPListener{tcpl, &stop} + l := &StoppableTCPListener{tcpl, stop} return l, nil } @@ -322,8 +323,10 @@ func (self *StoppableTCPListener) Accept() (net.Conn, error) { c, err := self.TCPListener.AcceptTCP() select { - case <-*self.stop: - c.Close() + case <-self.stop: + if c != nil { // accept timeout + c.Close() + } self.TCPListener.Close() return nil, listenerStoppedError default: @@ -341,12 +344,12 @@ func (self *StoppableTCPListener) Accept() (net.Conn, error) { type ClosableConnection struct { *net.TCPConn - closed *chan struct{} + closed chan struct{} } func (self *ClosableConnection) Read(b []byte) (n int, err error) { select { - case <-*self.closed: + case <-self.closed: self.TCPConn.Close() return 0, io.EOF default: From 61885aa965282d5879b9c4fbb740e96e9b680558 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Sun, 19 Apr 2015 10:01:50 +0200 Subject: [PATCH 4/7] Don't export types/functions --- rpc/http.go | 8 ++++---- rpc/types.go | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index 5ff4f613b..f9c646908 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -14,7 +14,7 @@ import ( ) var rpclogger = logger.NewLogger("RPC") -var rpclistener *StoppableTCPListener +var rpclistener *stoppableTCPListener const ( jsonrpcver = "2.0" @@ -29,7 +29,7 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { return nil // RPC service already running on given host/port } - l, err := NewStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) + l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort)) if err != nil { rpclogger.Errorf("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err) return err @@ -43,9 +43,9 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { opts.AllowedOrigins = []string{config.CorsDomain} c := cors.New(opts) - handler = NewStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) + handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) } else { - handler = NewStoppableHandler(JSONRPC(pipe), l.stop) + handler = newStoppableHandler(JSONRPC(pipe), l.stop) } go http.Serve(l, handler) diff --git a/rpc/types.go b/rpc/types.go index 71ed5df49..1784759a4 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -265,18 +265,18 @@ type RpcErrorObject struct { // Data interface{} `json:"data"` } -type ListenerStoppedError struct { +type listenerHasStoppedError struct { msg string } -func (self ListenerStoppedError) Error() string { +func (self listenerHasStoppedError) Error() string { return self.msg } -var listenerStoppedError = ListenerStoppedError{"Listener stopped"} +var listenerStoppedError = listenerHasStoppedError{"Listener stopped"} // When https://github.com/golang/go/issues/4674 is fixed this could be replaced -type StoppableTCPListener struct { +type stoppableTCPListener struct { *net.TCPListener stop chan struct{} // closed when the listener must stop } @@ -284,7 +284,7 @@ type StoppableTCPListener struct { // Wraps the default handler and checks if the RPC service was stopped. In that case it returns an // error indicating that the service was stopped. This will only happen for connections which are // kept open (HTTP keep-alive) when the RPC service was shutdown. -func NewStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { +func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { select { case <-stop: @@ -298,11 +298,11 @@ func NewStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { } // Stop the listener and all accepted and still active connections. -func (self *StoppableTCPListener) Stop() { +func (self *stoppableTCPListener) Stop() { close(self.stop) } -func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { +func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) { wl, err := net.Listen("tcp", addr) if err != nil { return nil, err @@ -310,14 +310,14 @@ func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { if tcpl, ok := wl.(*net.TCPListener); ok { stop := make(chan struct{}) - l := &StoppableTCPListener{tcpl, stop} + l := &stoppableTCPListener{tcpl, stop} return l, nil } return nil, errors.New("Unable to create TCP listener for RPC service") } -func (self *StoppableTCPListener) Accept() (net.Conn, error) { +func (self *stoppableTCPListener) Accept() (net.Conn, error) { for { self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second))) c, err := self.TCPListener.AcceptTCP() @@ -338,16 +338,16 @@ func (self *StoppableTCPListener) Accept() (net.Conn, error) { } } - return &ClosableConnection{c, self.stop}, err + return &closableConnection{c, self.stop}, err } } -type ClosableConnection struct { +type closableConnection struct { *net.TCPConn closed chan struct{} } -func (self *ClosableConnection) Read(b []byte) (n int, err error) { +func (self *closableConnection) Read(b []byte) (n int, err error) { select { case <-self.closed: self.TCPConn.Close() From 8830403acfea745bd5e256d1498727e9128f02ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 20 Apr 2015 18:45:37 +0300 Subject: [PATCH 5/7] cmd/geth, cmd/utils: add cli flags for pprof and whisper. --- cmd/geth/main.go | 15 +++++++------ cmd/utils/flags.go | 53 +++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index fa6a93b78..de1a59772 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -24,8 +24,6 @@ import ( "bufio" "fmt" "io/ioutil" - "log" - "net/http" "os" "runtime" "strconv" @@ -236,6 +234,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.WhisperEnabledFlag, utils.VMDebugFlag, utils.ProtocolVersionFlag, utils.NetworkIdFlag, @@ -246,6 +245,8 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.LogVModuleFlag, utils.LogFileFlag, utils.LogJSONFlag, + utils.PProfEnabledFlag, + utils.PProfPortFlag, } // missing: @@ -260,11 +261,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso } func main() { - // Start up the default http server for pprof - go func() { - log.Println(http.ListenAndServe("localhost:6060", nil)) - }() - fmt.Printf("Welcome to the FRONTIER\n") runtime.GOMAXPROCS(runtime.NumCPU()) defer logger.Flush() @@ -336,6 +332,11 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass } func startEth(ctx *cli.Context, eth *eth.Ethereum) { + // Start profiling, if requested + if ctx.GlobalBool(utils.PProfEnabledFlag.Name) { + utils.StartPProf(ctx) + } + // Start Ethereum itself utils.StartEthereum(eth) am := eth.AccountManager() diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a1d9eedda..3b1fda32e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2,6 +2,9 @@ package utils import ( "crypto/ecdsa" + "fmt" + "log" + "net/http" "os" "path" "runtime" @@ -136,10 +139,33 @@ var ( Usage: "Send json structured log output to a file or '-' for standard output (default: no json output)", Value: "", } + LogToStdErrFlag = cli.BoolFlag{ + Name: "logtostderr", + Usage: "Logs are written to standard error instead of to files.", + } + LogVModuleFlag = cli.GenericFlag{ + Name: "vmodule", + Usage: "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a V level.", + Value: glog.GetVModule(), + } VMDebugFlag = cli.BoolFlag{ Name: "vmdebug", Usage: "Virtual Machine debug output", } + BacktraceAtFlag = cli.GenericFlag{ + Name: "backtrace_at", + Usage: "When set to a file and line number holding a logging statement a stack trace will be written to the Info log", + Value: glog.GetTraceLocation(), + } + PProfEnabledFlag = cli.BoolFlag{ + Name: "pprof", + Usage: "Whether the profiling server is enabled", + } + PProfPortFlag = cli.IntFlag{ + Name: "pprofport", + Usage: "Port on which the profiler should listen", + Value: 6060, + } // RPC settings RPCEnabledFlag = cli.BoolFlag{ @@ -190,25 +216,15 @@ var ( Usage: "Port mapping mechanism (any|none|upnp|pmp|extip:)", Value: "any", } + WhisperEnabledFlag = cli.BoolFlag{ + Name: "shh", + Usage: "Whether the whisper sub-protocol is enabled", + } JSpathFlag = cli.StringFlag{ Name: "jspath", Usage: "JS library path to be used with console and js subcommands", Value: ".", } - BacktraceAtFlag = cli.GenericFlag{ - Name: "backtrace_at", - Usage: "When set to a file and line number holding a logging statement a stack trace will be written to the Info log", - Value: glog.GetTraceLocation(), - } - LogToStdErrFlag = cli.BoolFlag{ - Name: "logtostderr", - Usage: "Logs are written to standard error instead of to files.", - } - LogVModuleFlag = cli.GenericFlag{ - Name: "vmodule", - Usage: "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a V level.", - Value: glog.GetVModule(), - } ) func GetNAT(ctx *cli.Context) nat.Interface { @@ -269,7 +285,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { Port: ctx.GlobalString(ListenPortFlag.Name), NAT: GetNAT(ctx), NodeKey: GetNodeKey(ctx), - Shh: true, + Shh: ctx.GlobalBool(WhisperEnabledFlag.Name), Dial: true, BootNodes: ctx.GlobalString(BootnodesFlag.Name), } @@ -319,3 +335,10 @@ func StartRPC(eth *eth.Ethereum, ctx *cli.Context) { xeth := xeth.New(eth, nil) _ = rpc.Start(xeth, config) } + +func StartPProf(ctx *cli.Context) { + address := fmt.Sprintf("localhost:%d", ctx.GlobalInt(PProfPortFlag.Name)) + go func() { + log.Println(http.ListenAndServe(address, nil)) + }() +} From c8e2b3710cec47f023fd01c42ea829579a2753be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 20 Apr 2015 18:59:41 +0300 Subject: [PATCH 6/7] cmd/geth, cmd/utils: use pprof disable flag, start globally --- cmd/geth/main.go | 12 +++++++----- cmd/utils/flags.go | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index de1a59772..5695c4117 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -245,9 +245,15 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.LogVModuleFlag, utils.LogFileFlag, utils.LogJSONFlag, - utils.PProfEnabledFlag, + utils.PProfDisabledFlag, utils.PProfPortFlag, } + app.Before = func(ctx *cli.Context) error { + if !ctx.GlobalBool(utils.PProfDisabledFlag.Name) { + utils.StartPProf(ctx) + } + return nil + } // missing: // flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") @@ -332,10 +338,6 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass } func startEth(ctx *cli.Context, eth *eth.Ethereum) { - // Start profiling, if requested - if ctx.GlobalBool(utils.PProfEnabledFlag.Name) { - utils.StartPProf(ctx) - } // Start Ethereum itself utils.StartEthereum(eth) am := eth.AccountManager() diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 3b1fda32e..429007642 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -157,9 +157,9 @@ var ( Usage: "When set to a file and line number holding a logging statement a stack trace will be written to the Info log", Value: glog.GetTraceLocation(), } - PProfEnabledFlag = cli.BoolFlag{ - Name: "pprof", - Usage: "Whether the profiling server is enabled", + PProfDisabledFlag = cli.BoolFlag{ + Name: "nopprof", + Usage: "Whether the profiling server should be disabled", } PProfPortFlag = cli.IntFlag{ Name: "pprofport", From 3b008723db3f89696dab53b311cbd2efc987a01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 20 Apr 2015 19:14:49 +0300 Subject: [PATCH 7/7] cmd/geth, cmd/utils: invert --pprof once more --- cmd/geth/main.go | 4 ++-- cmd/utils/flags.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 5695c4117..e213423ce 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -245,11 +245,11 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.LogVModuleFlag, utils.LogFileFlag, utils.LogJSONFlag, - utils.PProfDisabledFlag, + utils.PProfEanbledFlag, utils.PProfPortFlag, } app.Before = func(ctx *cli.Context) error { - if !ctx.GlobalBool(utils.PProfDisabledFlag.Name) { + if ctx.GlobalBool(utils.PProfEanbledFlag.Name) { utils.StartPProf(ctx) } return nil diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 429007642..f81645e4e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -157,9 +157,9 @@ var ( Usage: "When set to a file and line number holding a logging statement a stack trace will be written to the Info log", Value: glog.GetTraceLocation(), } - PProfDisabledFlag = cli.BoolFlag{ - Name: "nopprof", - Usage: "Whether the profiling server should be disabled", + PProfEanbledFlag = cli.BoolFlag{ + Name: "pprof", + Usage: "Whether the profiling server should be enabled", } PProfPortFlag = cli.IntFlag{ Name: "pprofport",