gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/hostdb/randomhosts.go (about)

     1  package hostdb
     2  
     3  import (
     4  	"gitlab.com/NebulousLabs/errors"
     5  
     6  	"gitlab.com/SkynetLabs/skyd/skymodules"
     7  	"gitlab.com/SkynetLabs/skyd/skymodules/renter/hostdb/hosttree"
     8  	"go.sia.tech/siad/types"
     9  )
    10  
    11  // RandomHosts implements the HostDB interface's RandomHosts() method. It takes
    12  // a number of hosts to return, and a slice of netaddresses to ignore, and
    13  // returns a slice of entries. If the IP violation check was disabled, the
    14  // addressBlacklist is ignored.
    15  func (hdb *HostDB) RandomHosts(n int, blacklist, addressBlacklist []types.SiaPublicKey) ([]skymodules.HostDBEntry, error) {
    16  	return hdb.RandomHostsWithWhitelist(n, blacklist, addressBlacklist, nil)
    17  }
    18  
    19  // RandomHostsWithWhitelist is the same as RandomHosts with an additional
    20  // whitelist parameter that guarantees that only whitelisted hosts are returned.
    21  func (hdb *HostDB) RandomHostsWithWhitelist(n int, blacklist, addressBlacklist []types.SiaPublicKey, whitelist map[string]struct{}) ([]skymodules.HostDBEntry, error) {
    22  	hdb.mu.RLock()
    23  	initialScanComplete := hdb.initialScanComplete
    24  	ipCheckDisabled := hdb.disableIPViolationCheck
    25  	hdb.mu.RUnlock()
    26  	if !initialScanComplete {
    27  		return []skymodules.HostDBEntry{}, ErrInitialScanIncomplete
    28  	}
    29  	if ipCheckDisabled {
    30  		return hdb.staticFilteredTree.SelectRandomWithWhitelist(n, blacklist, nil, whitelist), nil
    31  	}
    32  	return hdb.staticFilteredTree.SelectRandomWithWhitelist(n, blacklist, addressBlacklist, whitelist), nil
    33  }
    34  
    35  // RandomHostsWithAllowance works as RandomHosts but uses a temporary hosttree
    36  // created from the specified allowance. This is a very expensive call and
    37  // should be used with caution.
    38  func (hdb *HostDB) RandomHostsWithAllowance(n int, blacklist, addressBlacklist []types.SiaPublicKey, allowance skymodules.Allowance) ([]skymodules.HostDBEntry, error) {
    39  	hdb.mu.RLock()
    40  	initialScanComplete := hdb.initialScanComplete
    41  	filteredHosts := hdb.filteredHosts
    42  	filterType := hdb.filterMode
    43  	hdb.mu.RUnlock()
    44  	if !initialScanComplete && !hdb.staticDeps.Disrupt("InitialScanComplete") {
    45  		return []skymodules.HostDBEntry{}, ErrInitialScanIncomplete
    46  	}
    47  	// Create a temporary hosttree from the given allowance.
    48  	ht := hosttree.New(hdb.managedCalculateHostWeightFn(allowance), hdb.staticDeps.Resolver())
    49  
    50  	// Insert all known hosts.
    51  	hdb.mu.RLock()
    52  	defer hdb.mu.RUnlock()
    53  	var insertErrs error
    54  	allHosts := hdb.staticHostTree.All()
    55  	isWhitelist := filterType == skymodules.HostDBActiveWhitelist
    56  	for _, host := range allHosts {
    57  		// Filter out listed hosts
    58  		_, ok := filteredHosts[host.PublicKey.String()]
    59  		if isWhitelist != ok {
    60  			continue
    61  		}
    62  		if err := ht.Insert(host); err != nil {
    63  			insertErrs = errors.Compose(insertErrs, err)
    64  		}
    65  	}
    66  
    67  	// Select hosts from the temporary hosttree.
    68  	return ht.SelectRandom(n, blacklist, addressBlacklist), insertErrs
    69  }