diff --git a/cmd/clef/main.go b/cmd/clef/main.go index 2135eb0f80..e55daf0c8e 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -416,7 +416,7 @@ func signer(c *cli.Context) error { // start http server httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.RPCListenAddrFlag.Name), c.Int(rpcPortFlag.Name)) - listener, _, err := node.StartHTTPEndpoint(httpEndpoint, rpcApi, []string{"account"}, cors, vhosts) + listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcApi, []string{"account"}, cors, vhosts) if err != nil { utils.Fatalf("Could not start RPC api: %v", err) } @@ -436,7 +436,7 @@ func signer(c *cli.Context) error { ipcApiUrl = fmt.Sprintf("%s", filepath.Join(configDir, "clef.ipc")) } - listener, _, err := node.StartIPCEndpoint(func() bool { return true }, ipcApiUrl, rpcApi) + listener, _, err := rpc.StartIPCEndpoint(func() bool { return true }, ipcApiUrl, rpcApi) if err != nil { utils.Fatalf("Could not start IPC api: %v", err) } diff --git a/node/node.go b/node/node.go index aaa73a25e0..bf6e9a7c17 100644 --- a/node/node.go +++ b/node/node.go @@ -301,43 +301,6 @@ func (n *Node) stopInProc() { } } -func StartIPCEndpoint(isClosedFn func() bool, ipcEndpoint string, apis []rpc.API) (net.Listener, *rpc.Server, error) { - // Register all the APIs exposed by the services - handler := rpc.NewServer() - for _, api := range apis { - if err := handler.RegisterName(api.Namespace, api.Service); err != nil { - return nil, nil, err - } - log.Debug("IPC registered", "namespace", api.Namespace) - } - // All APIs registered, start the IPC listener - var ( - listener net.Listener - err error - ) - if listener, err = rpc.CreateIPCListener(ipcEndpoint); err != nil { - return nil, nil, err - } - go func() { - for { - conn, err := listener.Accept() - if err != nil { - // Terminate if the listener was closed - if isClosedFn() { - log.Info("IPC closed", "err", err) - } else { - // Not closed, just some error; report and continue - log.Error("IPC accept failed", "err", err) - } - continue - } - go handler.ServeCodec(rpc.NewJSONCodec(conn), rpc.OptionMethodInvocation|rpc.OptionSubscriptions) - } - }() - - return listener, handler, nil -} - // startIPC initializes and starts the IPC RPC endpoint. func (n *Node) startIPC(apis []rpc.API) error { // Short circuit if the IPC endpoint isn't being exposed @@ -351,7 +314,7 @@ func (n *Node) startIPC(apis []rpc.API) error { return n.ipcListener == nil } - listener, handler, err := StartIPCEndpoint(isClosed, n.ipcEndpoint, apis) + listener, handler, err := rpc.StartIPCEndpoint(isClosed, n.ipcEndpoint, apis) if err != nil { return err } @@ -376,33 +339,6 @@ func (n *Node) stopIPC() { n.ipcHandler = nil } } -func StartHttpEndpoint(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string) (net.Listener, *rpc.Server, error) { - // Generate the whitelist based on the allowed modules - whitelist := make(map[string]bool) - for _, module := range modules { - whitelist[module] = true - } - // Register all the APIs exposed by the services - handler := rpc.NewServer() - for _, api := range apis { - if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) { - if err := handler.RegisterName(api.Namespace, api.Service); err != nil { - return nil, nil, err - } - log.Debug("HTTP registered", "namespace", api.Namespace) - } - } - // All APIs registered, start the HTTP listener - var ( - listener net.Listener - err error - ) - if listener, err = net.Listen("tcp", endpoint); err != nil { - return nil, nil, err - } - go rpc.NewHTTPServer(cors, vhosts, handler).Serve(listener) - return listener, handler, err -} // startHTTP initializes and starts the HTTP RPC endpoint. func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string) error { @@ -410,7 +346,7 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors if endpoint == "" { return nil } - listener, handler, err := StartHttpEndpoint(endpoint, apis, modules, cors, vhosts) + listener, handler, err := rpc.StartHTTPEndpoint(endpoint, apis, modules, cors, vhosts) if err != nil { return err } @@ -443,32 +379,11 @@ func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrig if endpoint == "" { return nil } - // Generate the whitelist based on the allowed modules - whitelist := make(map[string]bool) - for _, module := range modules { - whitelist[module] = true - } - // Register all the APIs exposed by the services - handler := rpc.NewServer() - for _, api := range apis { - if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) { - if err := handler.RegisterName(api.Namespace, api.Service); err != nil { - return err - } - n.log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace) - } - } - // All APIs registered, start the HTTP listener - var ( - listener net.Listener - err error - ) - if listener, err = net.Listen("tcp", endpoint); err != nil { + listener, handler, err := rpc.StartWSEndpoint(endpoint, apis, modules, wsOrigins, exposeAll) + if err != nil { return err } - go rpc.NewWSServer(wsOrigins, handler).Serve(listener) n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%s", listener.Addr())) - // All listeners booted successfully n.wsEndpoint = endpoint n.wsListener = listener diff --git a/rpc/endpoints.go b/rpc/endpoints.go new file mode 100644 index 0000000000..9ba2ed9707 --- /dev/null +++ b/rpc/endpoints.go @@ -0,0 +1,120 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see . + +package rpc + +import ( + "github.com/ethereum/go-ethereum/log" + "net" +) + +// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules +func StartHTTPEndpoint(endpoint string, apis []API, modules []string, cors []string, vhosts []string) (net.Listener, *Server, error) { + // Generate the whitelist based on the allowed modules + whitelist := make(map[string]bool) + for _, module := range modules { + whitelist[module] = true + } + // Register all the APIs exposed by the services + handler := NewServer() + for _, api := range apis { + if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) { + if err := handler.RegisterName(api.Namespace, api.Service); err != nil { + return nil, nil, err + } + log.Debug("HTTP registered", "namespace", api.Namespace) + } + } + // All APIs registered, start the HTTP listener + var ( + listener net.Listener + err error + ) + if listener, err = net.Listen("tcp", endpoint); err != nil { + return nil, nil, err + } + go NewHTTPServer(cors, vhosts, handler).Serve(listener) + return listener, handler, err +} + +// StartWSEndpoint starts a websocket endpoint +func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []string, exposeAll bool) (net.Listener, *Server, error) { + + // Generate the whitelist based on the allowed modules + whitelist := make(map[string]bool) + for _, module := range modules { + whitelist[module] = true + } + // Register all the APIs exposed by the services + handler := NewServer() + for _, api := range apis { + if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) { + if err := handler.RegisterName(api.Namespace, api.Service); err != nil { + return nil, nil, err + } + log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace) + } + } + // All APIs registered, start the HTTP listener + var ( + listener net.Listener + err error + ) + if listener, err = net.Listen("tcp", endpoint); err != nil { + return nil, nil, err + } + go NewWSServer(wsOrigins, handler).Serve(listener) + return listener, handler, err + +} + +// StartIPCEndpoint starts an IPC endpoint +func StartIPCEndpoint(isClosedFn func() bool, ipcEndpoint string, apis []API) (net.Listener, *Server, error) { + // Register all the APIs exposed by the services + handler := NewServer() + for _, api := range apis { + if err := handler.RegisterName(api.Namespace, api.Service); err != nil { + return nil, nil, err + } + log.Debug("IPC registered", "namespace", api.Namespace) + } + // All APIs registered, start the IPC listener + var ( + listener net.Listener + err error + ) + if listener, err = CreateIPCListener(ipcEndpoint); err != nil { + return nil, nil, err + } + go func() { + for { + conn, err := listener.Accept() + if err != nil { + // Terminate if the listener was closed + if isClosedFn() { + log.Info("IPC closed", "err", err) + } else { + // Not closed, just some error; report and continue + log.Error("IPC accept failed", "err", err) + } + continue + } + go handler.ServeCodec(NewJSONCodec(conn), OptionMethodInvocation|OptionSubscriptions) + } + }() + + return listener, handler, nil +} diff --git a/signer/core/abihelper.go b/signer/core/abihelper.go index 6f01ac69d3..d3f9daa6e0 100644 --- a/signer/core/abihelper.go +++ b/signer/core/abihelper.go @@ -175,7 +175,10 @@ func NewAbiDBFromFile(path string) (*AbiDb, error) { if err != nil { return nil, err } - db := new(AbiDb) + db, err := NewEmptyAbiDB() + if err != nil { + return nil, err + } json.Unmarshal(raw, &db.db) return db, nil } diff --git a/signer/core/abihelper_test.go b/signer/core/abihelper_test.go index b3ebf009a4..8bb5776691 100644 --- a/signer/core/abihelper_test.go +++ b/signer/core/abihelper_test.go @@ -182,7 +182,7 @@ func TestSelectorUnmarshalling(t *testing.T) { abistruct abi.ABI ) - db, err = NewAbiDBFromFile("../4byte.json") + db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json") if err != nil { t.Fatal(err) } @@ -217,7 +217,7 @@ func TestCustomABI(t *testing.T) { t.Fatal(err) } filename := fmt.Sprintf("%s/4byte_custom.json", d) - abidb, err := NewAbiDBFromFiles("../4byte.json", filename) + abidb, err := NewAbiDBFromFiles("../../cmd/clef/4byte.json", filename) if err != nil { t.Fatal(err) } @@ -237,6 +237,9 @@ func TestCustomABI(t *testing.T) { } //Check that it wrote to file abidb2, err := NewAbiDBFromFile(filename) + if err != nil { + t.Fatalf("Failed to create new abidb: %v", err) + } _, err = abidb2.LookupMethodSelector(calldata) if err != nil { t.Fatalf("Save failed: should find a match for abi signature after loading from disk") diff --git a/signer/rules/rules_test.go b/signer/rules/rules_test.go index c8810785ae..d9ced505c1 100644 --- a/signer/rules/rules_test.go +++ b/signer/rules/rules_test.go @@ -23,12 +23,12 @@ import ( "testing" "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/cmd/clef/core" - "github.com/ethereum/go-ethereum/cmd/clef/storage" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/signer/core" + "github.com/ethereum/go-ethereum/signer/storage" ) const JS = `