github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/renter/hostdb/hostentry.go (about)

     1  package hostdb
     2  
     3  import (
     4  	"bytes"
     5  
     6  	"github.com/NebulousLabs/Sia/modules"
     7  	"github.com/NebulousLabs/Sia/types"
     8  )
     9  
    10  // A hostEntry represents a host on the network.
    11  type hostEntry struct {
    12  	modules.HostDBEntry
    13  
    14  	Weight      types.Currency
    15  	Reliability types.Currency
    16  	Online      bool
    17  }
    18  
    19  // insertHost adds a host entry to the state. The host will be inserted into
    20  // the set of all hosts, and if it is online and responding to requests it will
    21  // be put into the list of active hosts.
    22  //
    23  // TODO: Function should return an error.
    24  func (hdb *HostDB) insertHost(host modules.HostDBEntry) {
    25  	// Remove garbage hosts and local hosts (but allow local hosts in testing).
    26  	if err := host.NetAddress.IsValid(); err != nil {
    27  		hdb.log.Printf("WARN: host '%v' has an invalid NetAddress: %v", host.NetAddress, err)
    28  		return
    29  	}
    30  	// Don't do anything if we've already seen this host and the public key is
    31  	// the same.
    32  	if knownHost, exists := hdb.allHosts[host.NetAddress]; exists && bytes.Equal(host.PublicKey.Key, knownHost.PublicKey.Key) {
    33  		return
    34  	}
    35  
    36  	// Create hostEntry and add to allHosts.
    37  	h := &hostEntry{
    38  		HostDBEntry: host,
    39  		Reliability: DefaultReliability,
    40  	}
    41  	hdb.allHosts[host.NetAddress] = h
    42  
    43  	// Add the host to the scan queue. If the scan is successful, the host
    44  	// will be placed in activeHosts.
    45  	hdb.scanHostEntry(h)
    46  }
    47  
    48  // Remove deletes an entry from the hostdb.
    49  func (hdb *HostDB) removeHost(addr modules.NetAddress) error {
    50  	// See if the node is in the set of active hosts.
    51  	node, exists := hdb.activeHosts[addr]
    52  	if exists {
    53  		delete(hdb.activeHosts, addr)
    54  		node.removeNode()
    55  	}
    56  
    57  	// Remove the node from all hosts.
    58  	delete(hdb.allHosts, addr)
    59  
    60  	return nil
    61  }
    62  
    63  // Host returns the HostSettings associated with the specified NetAddress. If
    64  // no matching host is found, Host returns false.
    65  func (hdb *HostDB) Host(addr modules.NetAddress) (modules.HostDBEntry, bool) {
    66  	hdb.mu.RLock()
    67  	defer hdb.mu.RUnlock()
    68  	entry, ok := hdb.allHosts[addr]
    69  	if !ok || entry == nil {
    70  		return modules.HostDBEntry{}, false
    71  	}
    72  	return entry.HostDBEntry, true
    73  }
    74  
    75  // ActiveHosts returns the hosts that can be randomly selected out of the
    76  // hostdb.
    77  func (hdb *HostDB) ActiveHosts() (activeHosts []modules.HostDBEntry) {
    78  	hdb.mu.RLock()
    79  	defer hdb.mu.RUnlock()
    80  
    81  	for _, node := range hdb.activeHosts {
    82  		activeHosts = append(activeHosts, node.hostEntry.HostDBEntry)
    83  	}
    84  	return
    85  }
    86  
    87  // AllHosts returns all of the hosts known to the hostdb, including the
    88  // inactive ones.
    89  func (hdb *HostDB) AllHosts() (allHosts []modules.HostDBEntry) {
    90  	hdb.mu.RLock()
    91  	defer hdb.mu.RUnlock()
    92  
    93  	for _, entry := range hdb.allHosts {
    94  		allHosts = append(allHosts, entry.HostDBEntry)
    95  	}
    96  	return
    97  }
    98  
    99  // AveragePrice returns the average price of a host.
   100  func (hdb *HostDB) AveragePrice() types.Currency {
   101  	// maybe a more sophisticated way of doing this
   102  	var totalPrice types.Currency
   103  	sampleSize := 18
   104  	hosts := hdb.RandomHosts(sampleSize, nil)
   105  	if len(hosts) == 0 {
   106  		return totalPrice
   107  	}
   108  	for _, host := range hosts {
   109  		totalPrice = totalPrice.Add(host.ContractPrice)
   110  	}
   111  	return totalPrice.Div64(uint64(len(hosts)))
   112  }
   113  
   114  // IsOffline reports whether a host is offline. If the HostDB has no record of
   115  // the host, IsOffline will return false.
   116  //
   117  // TODO: Is this behavior that makes sense?
   118  func (hdb *HostDB) IsOffline(addr modules.NetAddress) bool {
   119  	hdb.mu.RLock()
   120  	defer hdb.mu.RUnlock()
   121  
   122  	if _, ok := hdb.activeHosts[addr]; ok {
   123  		return false
   124  	}
   125  	if h, ok := hdb.allHosts[addr]; ok {
   126  		return !h.Online
   127  	}
   128  	return false
   129  }