// threadedProbeHost tries to fetch the settings of a host. If successful, the // host is put in the set of active hosts. If unsuccessful, the host id deleted // from the set of active hosts. func (hdb *HostDB) threadedProbeHosts() { for hostEntry := range hdb.scanPool { // Request settings from the queued host entry. var settings modules.HostSettings err := func() error { conn, err := hdb.dialer.DialTimeout(hostEntry.NetAddress, hostRequestTimeout) if err != nil { return err } defer conn.Close() err = encoding.WriteObject(conn, modules.RPCSettings) if err != nil { return err } // COMPATv0.4.8 - If first decoding attempt fails, try decoding // into the old HostSettings type. Because we decode twice, we // must read the data into memory first. settingsBytes, err := encoding.ReadPrefix(conn, maxSettingsLen) if err != nil { return err } err = encoding.Unmarshal(settingsBytes, &settings) if err != nil { var oldSettings oldHostSettings err = encoding.Unmarshal(settingsBytes, &oldSettings) if err != nil { return err } // Convert the old type. settings = modules.HostSettings{ NetAddress: oldSettings.NetAddress, TotalStorage: oldSettings.TotalStorage, MinDuration: oldSettings.MinDuration, MaxDuration: oldSettings.MaxDuration, WindowSize: oldSettings.WindowSize, Price: oldSettings.Price, Collateral: oldSettings.Collateral, UnlockHash: oldSettings.UnlockHash, } } return nil }() // Now that network communication is done, lock the hostdb to modify the // host entry. func() { hdb.mu.Lock() defer hdb.mu.Unlock() // Regardless of whether the host responded, add it to allHosts. if _, exists := hdb.allHosts[hostEntry.NetAddress]; !exists { hdb.allHosts[hostEntry.NetAddress] = hostEntry } // If the scan was unsuccessful, decrement the host's reliability. if err != nil { hdb.decrementReliability(hostEntry.NetAddress, UnreachablePenalty) return } // Update the host settings, reliability, and weight. The old NetAddress // must be preserved. settings.NetAddress = hostEntry.HostSettings.NetAddress hostEntry.HostSettings = settings hostEntry.reliability = MaxReliability hostEntry.weight = calculateHostWeight(*hostEntry) hostEntry.online = true // If 'MaxActiveHosts' has not been reached, add the host to the // activeHosts tree. if _, exists := hdb.activeHosts[hostEntry.NetAddress]; !exists && len(hdb.activeHosts) < MaxActiveHosts { hdb.insertNode(hostEntry) } }() } }