mirror of https://github.com/status-im/op-geth.git
rpc: clean up IPC handler (#16524)
This avoids logging accept errors on shutdown and removes a bit of duplication. It also fixes some goimports lint warnings.
This commit is contained in:
parent
661f5f3dac
commit
52b046c9b6
|
@ -23,17 +23,18 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"encoding/hex"
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
@ -44,7 +45,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/signer/rules"
|
"github.com/ethereum/go-ethereum/signer/rules"
|
||||||
"github.com/ethereum/go-ethereum/signer/storage"
|
"github.com/ethereum/go-ethereum/signer/storage"
|
||||||
"gopkg.in/urfave/cli.v1"
|
"gopkg.in/urfave/cli.v1"
|
||||||
"os/signal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExternalApiVersion -- see extapi_changelog.md
|
// ExternalApiVersion -- see extapi_changelog.md
|
||||||
|
@ -435,7 +435,7 @@ func signer(c *cli.Context) error {
|
||||||
ipcApiUrl = filepath.Join(configDir, "clef.ipc")
|
ipcApiUrl = filepath.Join(configDir, "clef.ipc")
|
||||||
}
|
}
|
||||||
|
|
||||||
listener, _, err := rpc.StartIPCEndpoint(func() bool { return true }, ipcApiUrl, rpcApi)
|
listener, _, err := rpc.StartIPCEndpoint(ipcApiUrl, rpcApi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not start IPC api: %v", err)
|
utils.Fatalf("Could not start IPC api: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,15 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
14
node/node.go
14
node/node.go
|
@ -303,23 +303,13 @@ func (n *Node) stopInProc() {
|
||||||
|
|
||||||
// startIPC initializes and starts the IPC RPC endpoint.
|
// startIPC initializes and starts the IPC RPC endpoint.
|
||||||
func (n *Node) startIPC(apis []rpc.API) error {
|
func (n *Node) startIPC(apis []rpc.API) error {
|
||||||
// Short circuit if the IPC endpoint isn't being exposed
|
|
||||||
if n.ipcEndpoint == "" {
|
if n.ipcEndpoint == "" {
|
||||||
return nil
|
return nil // IPC disabled.
|
||||||
|
|
||||||
}
|
}
|
||||||
isClosed := func() bool {
|
listener, handler, err := rpc.StartIPCEndpoint(n.ipcEndpoint, apis)
|
||||||
n.lock.RLock()
|
|
||||||
defer n.lock.RUnlock()
|
|
||||||
return n.ipcListener == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
listener, handler, err := rpc.StartIPCEndpoint(isClosed, n.ipcEndpoint, apis)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// All listeners booted successfully
|
|
||||||
n.ipcListener = listener
|
n.ipcListener = listener
|
||||||
n.ipcHandler = handler
|
n.ipcHandler = handler
|
||||||
n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
|
n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -33,7 +34,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules
|
// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules
|
||||||
|
@ -81,9 +82,9 @@ func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartIPCEndpoint starts an IPC endpoint
|
// StartIPCEndpoint starts an IPC endpoint.
|
||||||
func StartIPCEndpoint(isClosedFn func() bool, ipcEndpoint string, apis []API) (net.Listener, *Server, error) {
|
func StartIPCEndpoint(ipcEndpoint string, apis []API) (net.Listener, *Server, error) {
|
||||||
// Register all the APIs exposed by the services
|
// Register all the APIs exposed by the services.
|
||||||
handler := NewServer()
|
handler := NewServer()
|
||||||
for _, api := range apis {
|
for _, api := range apis {
|
||||||
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
|
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
|
||||||
|
@ -91,30 +92,11 @@ func StartIPCEndpoint(isClosedFn func() bool, ipcEndpoint string, apis []API) (n
|
||||||
}
|
}
|
||||||
log.Debug("IPC registered", "namespace", api.Namespace)
|
log.Debug("IPC registered", "namespace", api.Namespace)
|
||||||
}
|
}
|
||||||
// All APIs registered, start the IPC listener
|
// All APIs registered, start the IPC listener.
|
||||||
var (
|
listener, err := ipcListen(ipcEndpoint)
|
||||||
listener net.Listener
|
if err != nil {
|
||||||
err error
|
|
||||||
)
|
|
||||||
if listener, err = CreateIPCListener(ipcEndpoint); err != nil {
|
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
go func() {
|
go handler.ServeListener(listener)
|
||||||
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
|
return listener, handler, nil
|
||||||
}
|
}
|
||||||
|
|
15
rpc/ipc.go
15
rpc/ipc.go
|
@ -18,26 +18,23 @@ package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateIPCListener creates an listener, on Unix platforms this is a unix socket, on
|
|
||||||
// Windows this is a named pipe
|
|
||||||
func CreateIPCListener(endpoint string) (net.Listener, error) {
|
|
||||||
return ipcListen(endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServeListener accepts connections on l, serving JSON-RPC on them.
|
// ServeListener accepts connections on l, serving JSON-RPC on them.
|
||||||
func (srv *Server) ServeListener(l net.Listener) error {
|
func (srv *Server) ServeListener(l net.Listener) error {
|
||||||
for {
|
for {
|
||||||
conn, err := l.Accept()
|
conn, err := l.Accept()
|
||||||
if err != nil {
|
if netutil.IsTemporaryError(err) {
|
||||||
|
log.Warn("RPC accept error", "err", err)
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Trace(fmt.Sprint("accepted conn", conn.RemoteAddr()))
|
log.Trace("Accepted connection", "addr", conn.RemoteAddr())
|
||||||
go srv.ServeCodec(NewJSONCodec(conn), OptionMethodInvocation|OptionSubscriptions)
|
go srv.ServeCodec(NewJSONCodec(conn), OptionMethodInvocation|OptionSubscriptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue