pull/29330/head
a 8 months ago
parent 15e5e6176b
commit 63a060d8ed
No known key found for this signature in database
GPG Key ID: 374BC539FE795AF0
  1. 4
      cmd/clef/main.go
  2. 1
      cmd/geth/main.go
  3. 24
      cmd/utils/flags.go
  4. 12
      node/api.go
  5. 20
      node/api_test.go
  6. 4
      node/config.go
  7. 17
      node/defaults.go
  8. 4
      node/endpoints.go
  9. 8
      node/node.go
  10. 9
      node/rpcstack.go
  11. 2
      node/rpcstack_test.go

@ -590,7 +590,7 @@ func accountImport(c *cli.Context) error {
Address %v Address %v
Keystore file: %v Keystore file: %v
The key is now encrypted; losing the password will result in permanently losing The key is now encrypted; losing the password will result in permanently losing
access to the key and all associated funds! access to the key and all associated funds!
Make sure to backup keystore and passwords in a safe location.`, Make sure to backup keystore and passwords in a safe location.`,
@ -743,7 +743,7 @@ func signer(c *cli.Context) error {
// start http server // start http server
httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.HTTPListenAddrFlag.Name), port) httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.HTTPListenAddrFlag.Name), port)
httpServer, addr, err := node.StartHTTPEndpoint(httpEndpoint, rpc.DefaultHTTPTimeouts, handler) httpServer, addr, err := node.StartHTTPEndpoint(httpEndpoint, c.String(utils.HTTPListenProtocolFlag.Name), rpc.DefaultHTTPTimeouts, handler)
if err != nil { if err != nil {
utils.Fatalf("Could not start RPC api: %v", err) utils.Fatalf("Could not start RPC api: %v", err)
} }

@ -155,6 +155,7 @@ var (
rpcFlags = []cli.Flag{ rpcFlags = []cli.Flag{
utils.HTTPEnabledFlag, utils.HTTPEnabledFlag,
utils.HTTPListenAddrFlag, utils.HTTPListenAddrFlag,
utils.HTTPListenProtocolFlag,
utils.HTTPPortFlag, utils.HTTPPortFlag,
utils.HTTPCORSDomainFlag, utils.HTTPCORSDomainFlag,
utils.AuthListenFlag, utils.AuthListenFlag,

@ -28,6 +28,7 @@ import (
"math/big" "math/big"
"net/http" "net/http"
"os" "os"
"path"
"path/filepath" "path/filepath"
godebug "runtime/debug" godebug "runtime/debug"
"strconv" "strconv"
@ -689,6 +690,12 @@ var (
Value: node.DefaultHTTPHost, Value: node.DefaultHTTPHost,
Category: flags.APICategory, Category: flags.APICategory,
} }
HTTPListenProtocolFlag = &cli.StringFlag{
Name: "http.proto",
Usage: "HTTP-RPC server listening protocol (tcp,unix)",
Value: node.DefaultHTTPProtocol,
Category: flags.APICategory,
}
HTTPPortFlag = &cli.IntFlag{ HTTPPortFlag = &cli.IntFlag{
Name: "http.port", Name: "http.port",
Usage: "HTTP-RPC server listening port", Usage: "HTTP-RPC server listening port",
@ -1169,12 +1176,23 @@ func SplitAndTrim(input string) (ret []string) {
// command line flags, returning empty if the HTTP endpoint is disabled. // command line flags, returning empty if the HTTP endpoint is disabled.
func setHTTP(ctx *cli.Context, cfg *node.Config) { func setHTTP(ctx *cli.Context, cfg *node.Config) {
if ctx.Bool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" { if ctx.Bool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" {
cfg.HTTPHost = "127.0.0.1"
if ctx.IsSet(HTTPListenAddrFlag.Name) { if HTTPListenProtocolFlag.Name == "unix" {
cfg.HTTPHost = ctx.String(HTTPListenAddrFlag.Name) cfg.HTTPHost = path.Join(os.TempDir(), "geth.http.sock")
} else {
cfg.HTTPHost = "127.0.0.1"
if ctx.IsSet(HTTPListenAddrFlag.Name) {
cfg.HTTPHost = ctx.String(HTTPListenAddrFlag.Name)
}
} }
} }
if ctx.IsSet(HTTPListenProtocolFlag.Name) {
cfg.HTTPProto = ctx.String(HTTPListenProtocolFlag.Name)
} else {
cfg.HTTPProto = "tcp"
}
if ctx.IsSet(HTTPPortFlag.Name) { if ctx.IsSet(HTTPPortFlag.Name) {
cfg.HTTPPort = ctx.Int(HTTPPortFlag.Name) cfg.HTTPPort = ctx.Int(HTTPPortFlag.Name)
} }

@ -155,7 +155,7 @@ func (api *adminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error)
} }
// StartHTTP starts the HTTP RPC API server. // StartHTTP starts the HTTP RPC API server.
func (api *adminAPI) StartHTTP(host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) { func (api *adminAPI) StartHTTP(proto *string, host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) {
api.node.lock.Lock() api.node.lock.Lock()
defer api.node.lock.Unlock() defer api.node.lock.Unlock()
@ -196,7 +196,7 @@ func (api *adminAPI) StartHTTP(host *string, port *int, cors *string, apis *stri
} }
} }
if err := api.node.http.setListenAddr(*host, *port); err != nil { if err := api.node.http.setListenAddr(*proto, *host, *port); err != nil {
return false, err return false, err
} }
if err := api.node.http.enableRPC(api.node.rpcAPIs, config); err != nil { if err := api.node.http.enableRPC(api.node.rpcAPIs, config); err != nil {
@ -210,9 +210,9 @@ func (api *adminAPI) StartHTTP(host *string, port *int, cors *string, apis *stri
// StartRPC starts the HTTP RPC API server. // StartRPC starts the HTTP RPC API server.
// Deprecated: use StartHTTP instead. // Deprecated: use StartHTTP instead.
func (api *adminAPI) StartRPC(host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) { func (api *adminAPI) StartRPC(proto *string, host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) {
log.Warn("Deprecation warning", "method", "admin.StartRPC", "use-instead", "admin.StartHTTP") log.Warn("Deprecation warning", "method", "admin.StartRPC", "use-instead", "admin.StartHTTP")
return api.StartHTTP(host, port, cors, apis, vhosts) return api.StartHTTP(proto, host, port, cors, apis, vhosts)
} }
// StopHTTP shuts down the HTTP server. // StopHTTP shuts down the HTTP server.
@ -229,7 +229,7 @@ func (api *adminAPI) StopRPC() (bool, error) {
} }
// StartWS starts the websocket RPC API server. // StartWS starts the websocket RPC API server.
func (api *adminAPI) StartWS(host *string, port *int, allowedOrigins *string, apis *string) (bool, error) { func (api *adminAPI) StartWS(proto *string, host *string, port *int, allowedOrigins *string, apis *string) (bool, error) {
api.node.lock.Lock() api.node.lock.Lock()
defer api.node.lock.Unlock() defer api.node.lock.Unlock()
@ -266,7 +266,7 @@ func (api *adminAPI) StartWS(host *string, port *int, allowedOrigins *string, ap
// Enable WebSocket on the server. // Enable WebSocket on the server.
server := api.node.wsServerForPort(*port, false) server := api.node.wsServerForPort(*port, false)
if err := server.setListenAddr(*host, *port); err != nil { if err := server.setListenAddr(*proto, *host, *port); err != nil {
return false, err return false, err
} }
openApis, _ := api.node.getAPIs() openApis, _ := api.node.getAPIs()

@ -69,7 +69,7 @@ func TestStartRPC(t *testing.T) {
name: "rpc enabled through API", name: "rpc enabled through API",
cfg: Config{}, cfg: Config{},
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
_, err := api.StartHTTP(sp("127.0.0.1"), ip(0), nil, nil, nil) _, err := api.StartHTTP(sp("tcp"), sp("127.0.0.1"), ip(0), nil, nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
}, },
wantReachable: true, wantReachable: true,
@ -90,14 +90,14 @@ func TestStartRPC(t *testing.T) {
port := listener.Addr().(*net.TCPAddr).Port port := listener.Addr().(*net.TCPAddr).Port
// Now try to start RPC on that port. This should fail. // Now try to start RPC on that port. This should fail.
_, err = api.StartHTTP(sp("127.0.0.1"), ip(port), nil, nil, nil) _, err = api.StartHTTP(sp("tcp"), sp("127.0.0.1"), ip(port), nil, nil, nil)
if err == nil { if err == nil {
t.Fatal("StartHTTP should have failed on port", port) t.Fatal("StartHTTP should have failed on port", port)
} }
// Try again after unblocking the port. It should work this time. // Try again after unblocking the port. It should work this time.
listener.Close() listener.Close()
_, err = api.StartHTTP(sp("127.0.0.1"), ip(port), nil, nil, nil) _, err = api.StartHTTP(sp("tcp"), sp("127.0.0.1"), ip(port), nil, nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
}, },
wantReachable: true, wantReachable: true,
@ -144,7 +144,7 @@ func TestStartRPC(t *testing.T) {
name: "ws enabled through API", name: "ws enabled through API",
cfg: Config{}, cfg: Config{},
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
_, err := api.StartWS(sp("127.0.0.1"), ip(0), nil, nil) _, err := api.StartWS(sp("tcp"), sp("127.0.0.1"), ip(0), nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
}, },
wantReachable: true, wantReachable: true,
@ -184,7 +184,7 @@ func TestStartRPC(t *testing.T) {
cfg: Config{HTTPHost: "127.0.0.1"}, cfg: Config{HTTPHost: "127.0.0.1"},
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
wsport := n.http.port wsport := n.http.port
_, err := api.StartWS(sp("127.0.0.1"), ip(wsport), nil, nil) _, err := api.StartWS(sp("tcp"), sp("127.0.0.1"), ip(wsport), nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
}, },
wantReachable: true, wantReachable: true,
@ -197,7 +197,7 @@ func TestStartRPC(t *testing.T) {
cfg: Config{HTTPHost: "127.0.0.1"}, cfg: Config{HTTPHost: "127.0.0.1"},
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
wsport := n.http.port wsport := n.http.port
_, err := api.StartWS(sp("127.0.0.1"), ip(wsport), nil, nil) _, err := api.StartWS(sp("tcp"), sp("127.0.0.1"), ip(wsport), nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
_, err = api.StopWS() _, err = api.StopWS()
@ -211,11 +211,11 @@ func TestStartRPC(t *testing.T) {
{ {
name: "rpc stopped with ws enabled", name: "rpc stopped with ws enabled",
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
_, err := api.StartHTTP(sp("127.0.0.1"), ip(0), nil, nil, nil) _, err := api.StartHTTP(sp("tcp"), sp("127.0.0.1"), ip(0), nil, nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
wsport := n.http.port wsport := n.http.port
_, err = api.StartWS(sp("127.0.0.1"), ip(wsport), nil, nil) _, err = api.StartWS(sp("tcp"), sp("127.0.0.1"), ip(wsport), nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
_, err = api.StopHTTP() _, err = api.StopHTTP()
@ -229,11 +229,11 @@ func TestStartRPC(t *testing.T) {
{ {
name: "rpc enabled after ws", name: "rpc enabled after ws",
fn: func(t *testing.T, n *Node, api *adminAPI) { fn: func(t *testing.T, n *Node, api *adminAPI) {
_, err := api.StartWS(sp("127.0.0.1"), ip(0), nil, nil) _, err := api.StartWS(sp("tcp"), sp("127.0.0.1"), ip(0), nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
wsport := n.http.port wsport := n.http.port
_, err = api.StartHTTP(sp("127.0.0.1"), ip(wsport), nil, nil, nil) _, err = api.StartHTTP(sp("tcp"), sp("127.0.0.1"), ip(wsport), nil, nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
}, },
wantReachable: true, wantReachable: true,

@ -105,6 +105,10 @@ type Config struct {
// field is empty, no HTTP API endpoint will be started. // field is empty, no HTTP API endpoint will be started.
HTTPHost string HTTPHost string
// HTTPProto is the protocol on which the HTTP RPC server will bind.
// Supported values are tcp, unix. HTTPPort is ignored if HTTPProto == unix
HTTPProto string
// HTTPPort is the TCP port number on which to start the HTTP RPC server. The // HTTPPort is the TCP port number on which to start the HTTP RPC server. The
// default zero value is/ valid and will pick a port number randomly (useful // default zero value is/ valid and will pick a port number randomly (useful
// for ephemeral nodes). // for ephemeral nodes).

@ -28,14 +28,15 @@ import (
) )
const ( const (
DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server DefaultHTTPProtocol = "tcp" // Default protocol for the HTTP RPC SERVER
DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server
DefaultWSHost = "localhost" // Default host interface for the websocket RPC server DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server
DefaultWSPort = 8546 // Default TCP port for the websocket RPC server DefaultWSHost = "localhost" // Default host interface for the websocket RPC server
DefaultGraphQLHost = "localhost" // Default host interface for the GraphQL server DefaultWSPort = 8546 // Default TCP port for the websocket RPC server
DefaultGraphQLPort = 8547 // Default TCP port for the GraphQL server DefaultGraphQLHost = "localhost" // Default host interface for the GraphQL server
DefaultAuthHost = "localhost" // Default host interface for the authenticated apis DefaultGraphQLPort = 8547 // Default TCP port for the GraphQL server
DefaultAuthPort = 8551 // Default port for the authenticated apis DefaultAuthHost = "localhost" // Default host interface for the authenticated apis
DefaultAuthPort = 8551 // Default port for the authenticated apis
) )
var ( var (

@ -26,13 +26,13 @@ import (
) )
// StartHTTPEndpoint starts the HTTP RPC endpoint. // StartHTTPEndpoint starts the HTTP RPC endpoint.
func StartHTTPEndpoint(endpoint string, timeouts rpc.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) { func StartHTTPEndpoint(endpoint string, protocol string, timeouts rpc.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) {
// start the HTTP listener // start the HTTP listener
var ( var (
listener net.Listener listener net.Listener
err error err error
) )
if listener, err = net.Listen("tcp", endpoint); err != nil { if listener, err = net.Listen(protocol, endpoint); err != nil {
return nil, nil, err return nil, nil, err
} }
// make sure timeout values are meaningful // make sure timeout values are meaningful

@ -404,7 +404,7 @@ func (n *Node) startRPC() error {
) )
initHttp := func(server *httpServer, port int) error { initHttp := func(server *httpServer, port int) error {
if err := server.setListenAddr(n.config.HTTPHost, port); err != nil { if err := server.setListenAddr(n.config.HTTPProto, n.config.HTTPHost, port); err != nil {
return err return err
} }
if err := server.enableRPC(openAPIs, httpConfig{ if err := server.enableRPC(openAPIs, httpConfig{
@ -421,7 +421,7 @@ func (n *Node) startRPC() error {
initWS := func(port int) error { initWS := func(port int) error {
server := n.wsServerForPort(port, false) server := n.wsServerForPort(port, false)
if err := server.setListenAddr(n.config.WSHost, port); err != nil { if err := server.setListenAddr(n.config.HTTPProto, n.config.WSHost, port); err != nil {
return err return err
} }
if err := server.enableWS(openAPIs, wsConfig{ if err := server.enableWS(openAPIs, wsConfig{
@ -438,7 +438,7 @@ func (n *Node) startRPC() error {
initAuth := func(port int, secret []byte) error { initAuth := func(port int, secret []byte) error {
// Enable auth via HTTP // Enable auth via HTTP
server := n.httpAuth server := n.httpAuth
if err := server.setListenAddr(n.config.AuthAddr, port); err != nil { if err := server.setListenAddr(n.config.HTTPProto, n.config.AuthAddr, port); err != nil {
return err return err
} }
if err := server.enableRPC(allAPIs, httpConfig{ if err := server.enableRPC(allAPIs, httpConfig{
@ -453,7 +453,7 @@ func (n *Node) startRPC() error {
servers = append(servers, server) servers = append(servers, server)
// Enable auth via WS // Enable auth via WS
server = n.wsServerForPort(port, true) server = n.wsServerForPort(port, true)
if err := server.setListenAddr(n.config.AuthAddr, port); err != nil { if err := server.setListenAddr(n.config.HTTPProto, n.config.AuthAddr, port); err != nil {
return err return err
} }
if err := server.enableWS(allAPIs, wsConfig{ if err := server.enableWS(allAPIs, wsConfig{

@ -77,6 +77,7 @@ type httpServer struct {
// These are set by setListenAddr. // These are set by setListenAddr.
endpoint string endpoint string
proto string
host string host string
port int port int
@ -97,15 +98,15 @@ func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts) *httpServer {
// setListenAddr configures the listening address of the server. // setListenAddr configures the listening address of the server.
// The address can only be set while the server isn't running. // The address can only be set while the server isn't running.
func (h *httpServer) setListenAddr(host string, port int) error { func (h *httpServer) setListenAddr(proto string, host string, port int) error {
h.mu.Lock() h.mu.Lock()
defer h.mu.Unlock() defer h.mu.Unlock()
if h.listener != nil && (host != h.host || port != h.port) { if h.listener != nil && (host != h.host || port != h.port || proto != h.proto) {
return fmt.Errorf("HTTP server already running on %s", h.endpoint) return fmt.Errorf("HTTP server already running on %s", h.endpoint)
} }
h.host, h.port = host, port h.proto, h.host, h.port = proto, host, port
h.endpoint = fmt.Sprintf("%s:%d", host, port) h.endpoint = fmt.Sprintf("%s:%d", host, port)
return nil return nil
} }
@ -141,7 +142,7 @@ func (h *httpServer) start() error {
} }
// Start the server. // Start the server.
listener, err := net.Listen("tcp", h.endpoint) listener, err := net.Listen(h.proto, h.endpoint)
if err != nil { if err != nil {
// If the server fails to start, we need to clear out the RPC and WS // If the server fails to start, we need to clear out the RPC and WS
// configuration so they can be configured another time. // configuration so they can be configured another time.

@ -246,7 +246,7 @@ func createAndStartServer(t *testing.T, conf *httpConfig, ws bool, wsConf *wsCon
if ws { if ws {
assert.NoError(t, srv.enableWS(nil, *wsConf)) assert.NoError(t, srv.enableWS(nil, *wsConf))
} }
assert.NoError(t, srv.setListenAddr("localhost", 0)) assert.NoError(t, srv.setListenAddr("tcp", "localhost", 0))
assert.NoError(t, srv.start()) assert.NoError(t, srv.start())
return srv return srv
} }

Loading…
Cancel
Save