From ebc5db27103115f03cec36c48573de1aa41726d9 Mon Sep 17 00:00:00 2001 From: David Hill Date: Fri, 4 Jul 2014 14:04:01 -0400 Subject: [PATCH] Lookup each DNS seed in its own go routine. By putting each DNS seed in its own go routine, btcd can start connecting to nodes as they are found instead of waiting for all seeds to respond. This significantly speeds up startup time. Additionally, logging was added to show how many addresses were fetched from each seed. --- discovery.go | 13 ++++------- server.go | 63 +++++++++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/discovery.go b/discovery.go index edff9535..c46138a5 100644 --- a/discovery.go +++ b/discovery.go @@ -125,17 +125,12 @@ func torLookupIP(host, proxy string) ([]net.IP, error) { // dnsDiscover looks up the list of peers resolved by DNS for all hosts in // seeders. If proxy is not "" then it is used as a tor proxy for the -// resolution. If any errors occur then the seeder that errored will not have -// any hosts in the list. Therefore if all hosts failed an empty slice of -// strings will be returned. -func dnsDiscover(seeder string) []net.IP { - discLog.Debugf("Fetching list of seeds from %v", seeder) +// resolution. +func dnsDiscover(seeder string) ([]net.IP, error) { peers, err := btcdLookup(seeder) if err != nil { - discLog.Debugf("Unable to fetch dns seeds from %s: %v", - seeder, err) - return []net.IP{} + return nil, err } - return peers + return peers, nil } diff --git a/server.go b/server.go index 60fd7f06..9abf1610 100644 --- a/server.go +++ b/server.go @@ -474,33 +474,41 @@ func (s *server) seedFromDNS() { } for _, seeder := range activeNetParams.dnsSeeds { - seedpeers := dnsDiscover(seeder) - if len(seedpeers) == 0 { - continue - } - addresses := make([]*btcwire.NetAddress, len(seedpeers)) - // if this errors then we have *real* problems - intPort, _ := strconv.Atoi(activeNetParams.DefaultPort) - for i, peer := range seedpeers { - addresses[i] = new(btcwire.NetAddress) - addresses[i].SetAddress(peer, uint16(intPort)) - // bitcoind seeds with addresses from - // a time randomly selected between 3 - // and 7 days ago. - addresses[i].Timestamp = time.Now().Add(-1 * - time.Second * time.Duration(secondsIn3Days+ - s.addrManager.rand.Int31n(secondsIn4Days))) - } + go func(seeder string) { + seedpeers, err := dnsDiscover(seeder) + if err != nil { + discLog.Infof("DNS discovery failed on seed %s: %v", seeder, err) + return + } + numPeers := len(seedpeers) - // Bitcoind uses a lookup of the dns seeder here. This - // is rather strange since the values looked up by the - // DNS seed lookups will vary quite a lot. - // to replicate this behaviour we put all addresses as - // having come from the first one. - s.addrManager.AddAddresses(addresses, addresses[0]) + discLog.Infof("%d addresses found from DNS seed %s", numPeers, seeder) + + if numPeers == 0 { + return + } + addresses := make([]*btcwire.NetAddress, len(seedpeers)) + // if this errors then we have *real* problems + intPort, _ := strconv.Atoi(activeNetParams.DefaultPort) + for i, peer := range seedpeers { + addresses[i] = new(btcwire.NetAddress) + addresses[i].SetAddress(peer, uint16(intPort)) + // bitcoind seeds with addresses from + // a time randomly selected between 3 + // and 7 days ago. + addresses[i].Timestamp = time.Now().Add(-1 * + time.Second * time.Duration(secondsIn3Days+ + s.addrManager.rand.Int31n(secondsIn4Days))) + } + + // Bitcoind uses a lookup of the dns seeder here. This + // is rather strange since the values looked up by the + // DNS seed lookups will vary quite a lot. + // to replicate this behaviour we put all addresses as + // having come from the first one. + s.addrManager.AddAddresses(addresses, addresses[0]) + }(seeder) } - // XXX if this is empty do we want to use hardcoded - // XXX peers like bitcoind does? } // peerHandler is used to handle peer operations such as adding and removing @@ -617,10 +625,9 @@ out: // Just check that we don't already have an address // in the same group so that we are not connecting // to the same network segment at the expense of - // others. bitcoind breaks out of the loop here, but - // we continue to try other addresses. + // others. if state.outboundGroups[key] != 0 { - continue + break } tries++