@@ -490,6 +490,66 @@ func quickcfg() *quick.Config {
490490 }
491491}
492492
493+ func TestSetFallbackNodes_DNSHostname (t * testing.T ) {
494+ // Create a node with a DNS hostname but no IP, simulating an enode URL
495+ // like enode://<key>@localhost:30303.
496+ key := newkey ()
497+ node := enode .NewV4 (& key .PublicKey , nil , 30303 , 30303 ).WithHostname ("localhost" )
498+
499+ // Verify the node has a hostname but no valid IP.
500+ if node .Hostname () != "localhost" {
501+ t .Fatal ("expected hostname to be set" )
502+ }
503+ if node .IPAddr ().IsValid () {
504+ t .Fatal ("expected no IP address" )
505+ }
506+
507+ // Create a table and set the hostname node as a bootnode.
508+ // This should resolve the hostname to an IP address.
509+ db , _ := enode .OpenDB (t .TempDir () + "/node.db" )
510+ defer db .Close ()
511+
512+ cfg := Config {Log : testlog .Logger (t , log .LvlTrace )}
513+ cfg = cfg .withDefaults ()
514+ tab := & Table {
515+ cfg : cfg ,
516+ log : cfg .Log ,
517+ refreshReq : make (chan chan struct {}),
518+ revalResponseCh : make (chan revalidationResponse ),
519+ addNodeCh : make (chan addNodeOp ),
520+ addNodeHandled : make (chan bool ),
521+ trackRequestCh : make (chan trackRequestOp ),
522+ initDone : make (chan struct {}),
523+ closeReq : make (chan struct {}),
524+ closed : make (chan struct {}),
525+ ips : netutil.DistinctNetSet {Subnet : tableSubnet , Limit : tableIPLimit },
526+ }
527+ for i := range tab .buckets {
528+ tab .buckets [i ] = & bucket {
529+ index : i ,
530+ ips : netutil.DistinctNetSet {Subnet : bucketSubnet , Limit : bucketIPLimit },
531+ }
532+ }
533+
534+ err := tab .setFallbackNodes ([]* enode.Node {node })
535+ if err != nil {
536+ t .Fatalf ("setFallbackNodes failed: %v" , err )
537+ }
538+ if len (tab .nursery ) != 1 {
539+ t .Fatalf ("expected 1 nursery node, got %d" , len (tab .nursery ))
540+ }
541+
542+ // The resolved node should have a valid IP and retain the hostname.
543+ resolved := tab .nursery [0 ]
544+ if ! resolved .IPAddr ().IsValid () {
545+ t .Fatal ("expected resolved node to have a valid IP" )
546+ }
547+ if resolved .Hostname () != "localhost" {
548+ t .Errorf ("expected hostname to be preserved, got %q" , resolved .Hostname ())
549+ }
550+ t .Logf ("resolved localhost to %v" , resolved .IPAddr ())
551+ }
552+
493553func newkey () * ecdsa.PrivateKey {
494554 key , err := crypto .GenerateKey ()
495555 if err != nil {
0 commit comments