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 }