p2p/enode: clean up DNS name support in Node

Remove methods Endpoint and NeedResolve, since they are kind of redundant.
Instead of adding a new constructor with a hostname parameter, provide method
WithHostname to attach a name to any node.
This commit is contained in:
Felix Lange 2024-12-12 18:08:26 +01:00
parent e67f38aa29
commit 42cb347ed7
3 changed files with 23 additions and 59 deletions

View file

@ -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.

View file

@ -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() {

View file

@ -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",