diff --git a/p2p/enode/node.go b/p2p/enode/node.go index beb75f72ef..ae6b4ca4b7 100644 --- a/p2p/enode/node.go +++ b/p2p/enode/node.go @@ -37,11 +37,14 @@ var errMissingPrefix = errors.New("missing 'enr:' prefix for base64-encoded reco type Node struct { r enr.Record id ID - // endpoint information - ip netip.Addr - udp uint16 - tcp uint16 + + // hostname tracks the DNS name of the node. hostname string + + // endpoint information + ip netip.Addr + udp uint16 + tcp uint16 } // New wraps a node record. The record must be valid according to the given @@ -185,20 +188,16 @@ func (n *Node) TCP() int { return int(n.tcp) } -// Endpoint returns the hostname of the node if set, otherwise the IP address. -func (n *Node) Endpoint() string { - if n.hostname != "" { - return n.hostname - } - if n.ip.IsValid() { - return n.ip.String() - } - return "" +// WithHostname adds a DNS hostname to the node. +func (n *Node) WithHostname(hostname string) *Node { + cpy := *n + cpy.hostname = hostname + return &cpy } -// NeedResolve checks if the node requires DNS resolution. -func (n *Node) NeedResolve() bool { - return n.hostname != "" //TODO: Add check for n.ip.IsValid(), but we need to implement invalidation for the previous resolved IP +// Hostname returns the DNS name assigned by WithHostname. +func (n *Node) Hostname() string { + return n.hostname } // UDPEndpoint returns the announced UDP endpoint. @@ -246,9 +245,6 @@ func (n *Node) Record() *enr.Record { cpy := n.r return &cpy } -func (n *Node) Hostname() string { - return n.hostname -} // ValidateComplete checks whether n has a valid IP and UDP port. // Deprecated: don't use this method. diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index 5221cc0fd8..b455cd4533 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -100,28 +100,6 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp int) *Node { return n } -func NewV4WithDNS(pubkey *ecdsa.PublicKey, ip net.IP, hostname string, tcp, udp int) *Node { - var r enr.Record - if tcp != 0 { - r.Set(enr.TCP(tcp)) - } - if udp != 0 { - r.Set(enr.UDP(udp)) - } - if len(ip) > 0 { - r.Set(enr.IP(ip)) - } - signV4Compat(&r, pubkey) - n, err := New(v4CompatID{}, &r) - if err != nil { - panic(err) - } - n.tcp = uint16(tcp) - n.udp = uint16(udp) - n.hostname = hostname - return n -} - // isNewV4 returns true for nodes created by NewV4. func isNewV4(n *Node) bool { var k s256raw @@ -132,7 +110,6 @@ func parseComplete(rawurl string) (*Node, error) { var ( id *ecdsa.PublicKey tcpPort, udpPort uint64 - node *Node ) u, err := url.Parse(rawurl) if err != nil { @@ -149,15 +126,8 @@ func parseComplete(rawurl string) (*Node, error) { return nil, fmt.Errorf("invalid public key (%v)", err) } - // Parse the IP address if its one. + // Parse the IP and ports. ip := net.ParseIP(u.Hostname()) - if ip != nil { - // Ensure the IP is 4 bytes long for IPv4 addresses. - if ipv4 := ip.To4(); ipv4 != nil { - ip = ipv4 - } - } - // Parse the port numbers. if tcpPort, err = strconv.ParseUint(u.Port(), 10, 16); err != nil { return nil, errors.New("invalid port") } @@ -170,12 +140,11 @@ func parseComplete(rawurl string) (*Node, error) { } } - if ip != nil { - node = NewV4(id, ip, int(tcpPort), int(udpPort)) - } else { - node = NewV4WithDNS(id, nil, u.Hostname(), int(tcpPort), int(udpPort)) + // Create the node. + node := NewV4(id, ip, int(tcpPort), int(udpPort)) + if ip == nil && u.Hostname() != "" { + node = node.WithHostname(u.Hostname()) } - return node, nil } @@ -207,7 +176,7 @@ func (n *Node) URLv4() string { } u := url.URL{Scheme: "enode"} if n.Hostname() != "" { - // For DNS nodes: include DNS name, TCP port, and optional UDP port + // For nodes with a DNS name: include DNS name, TCP port, and optional UDP port u.User = url.User(nodeid) u.Host = fmt.Sprintf("%s:%d", n.Hostname(), n.TCP()) if n.UDP() != n.TCP() { diff --git a/p2p/enode/urlv4_test.go b/p2p/enode/urlv4_test.go index 9b7b4c7612..f39d5a2deb 100644 --- a/p2p/enode/urlv4_test.go +++ b/p2p/enode/urlv4_test.go @@ -79,13 +79,12 @@ var parseNodeTests = []struct { }, { input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@valid.:3", - wantResult: NewV4WithDNS( + wantResult: NewV4( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), nil, - "valid.", 3, 3, - ), + ).WithHostname("valid."), }, { input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150",