diff --git a/p2p/metrics.go b/p2p/metrics.go index e1bfe37ec3..b70c40e07a 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -68,6 +68,7 @@ func markDialError(err error) { return } + var e *protoHandshakeError switch { case errors.Is(err, DiscTooManyPeers): dialTooManyPeers.Mark(1) @@ -81,7 +82,7 @@ func markDialError(err error) { dialUnexpectedIdentity.Mark(1) case errors.Is(err, errEncHandshakeError): dialEncHandshakeError.Mark(1) - case errors.Is(err, errProtoHandshakeError): + case errors.As(err, &e): dialProtoHandshakeError.Mark(1) } } diff --git a/p2p/server.go b/p2p/server.go index 21a14bb5f4..222b711f03 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -66,11 +66,15 @@ const ( ) var ( - errServerStopped = errors.New("server stopped") - errEncHandshakeError = errors.New("rlpx enc error") - errProtoHandshakeError = errors.New("rlpx proto error") + errServerStopped = errors.New("server stopped") + errEncHandshakeError = errors.New("rlpx enc error") ) +type protoHandshakeError struct{ err error } + +func (e *protoHandshakeError) Error() string { return fmt.Sprintf("rlpx proto error: %s", e.err) } +func (e *protoHandshakeError) Unwrap() error { return e.err } + // Server manages all peer connections. type Server struct { // Config fields may not be modified while the server is running. @@ -908,7 +912,7 @@ func (srv *Server) setupConn(c *conn, dialDest *enode.Node) error { if err != nil { clog.Trace("Failed p2p handshake", "err", err) //Wrapping both errors for later inspection - return fmt.Errorf("%w: %w", errProtoHandshakeError, err) + return &protoHandshakeError{err: err} } if id := c.node.ID(); !bytes.Equal(crypto.Keccak256(phs.ID), id[:]) { clog.Trace("Wrong devp2p handshake identity", "phsid", hex.EncodeToString(phs.ID))