diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index b455cd4533..4fe4c2908d 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -33,6 +33,7 @@ import ( var ( incompleteNodeURL = regexp.MustCompile("(?i)^(?:enode://)?([0-9a-f]+)$") + lookupIPFunc = net.LookupIP ) // MustParseV4 parses a node URL. It panics if the URL is not valid. @@ -128,6 +129,25 @@ func parseComplete(rawurl string) (*Node, error) { // Parse the IP and ports. ip := net.ParseIP(u.Hostname()) + + // OP-Stack diff: add back DNS hostname resolution at parsing time + // - removed in https://github.com/ethereum/go-ethereum/pull/30822 in favor of on-demand runtime dialling + // - reported to have removed bootnodes DNS resolution at https://github.com/ethereum/go-ethereum/issues/31208 + // - possibly broke DNS resolution for other methods of adding peers + var resolved bool + if ip == nil { + ips, err := lookupIPFunc(u.Hostname()) + if err != nil { + return nil, err + } + resolved = true + ip = ips[0] + } + // Ensure the IP is 4 bytes long for IPv4 addresses. + if ipv4 := ip.To4(); ipv4 != nil { + ip = ipv4 + } + if tcpPort, err = strconv.ParseUint(u.Port(), 10, 16); err != nil { return nil, errors.New("invalid port") } @@ -142,7 +162,7 @@ func parseComplete(rawurl string) (*Node, error) { // Create the node. node := NewV4(id, ip, int(tcpPort), int(udpPort)) - if ip == nil && u.Hostname() != "" { + if resolved { node = node.WithHostname(u.Hostname()) } return node, nil diff --git a/p2p/enode/urlv4_test.go b/p2p/enode/urlv4_test.go index f39d5a2deb..5bf14afb0a 100644 --- a/p2p/enode/urlv4_test.go +++ b/p2p/enode/urlv4_test.go @@ -18,6 +18,7 @@ package enode import ( "crypto/ecdsa" + "errors" "net" "reflect" "strings" @@ -27,6 +28,15 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" ) +func init() { + lookupIPFunc = func(name string) ([]net.IP, error) { + if name == "valid." { + return []net.IP{{33, 44, 55, 66}}, nil + } + return nil, errors.New("no such host") + } +} + var parseNodeTests = []struct { input string wantError string @@ -81,7 +91,7 @@ var parseNodeTests = []struct { input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@valid.:3", wantResult: NewV4( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), - nil, + net.IP{33, 44, 55, 66}, // OP-Stack adds back DNS resolutino at parsing time 3, 3, ).WithHostname("valid."),