github.com/nebulouslabs/sia@v1.3.7/modules/renter/hostdb/update.go (about) 1 package hostdb 2 3 import ( 4 "github.com/NebulousLabs/Sia/build" 5 "github.com/NebulousLabs/Sia/modules" 6 "github.com/NebulousLabs/Sia/types" 7 ) 8 9 // findHostAnnouncements returns a list of the host announcements found within 10 // a given block. No check is made to see that the ip address found in the 11 // announcement is actually a valid ip address. 12 func findHostAnnouncements(b types.Block) (announcements []modules.HostDBEntry) { 13 for _, t := range b.Transactions { 14 // the HostAnnouncement must be prefaced by the standard host 15 // announcement string 16 for _, arb := range t.ArbitraryData { 17 addr, pubKey, err := modules.DecodeAnnouncement(arb) 18 if err != nil { 19 continue 20 } 21 22 // Add the announcement to the slice being returned. 23 var host modules.HostDBEntry 24 host.NetAddress = addr 25 host.PublicKey = pubKey 26 announcements = append(announcements, host) 27 } 28 } 29 return 30 } 31 32 // insertBlockchainHost adds a host entry to the state. The host will be inserted 33 // into the set of all hosts, and if it is online and responding to requests it 34 // will be put into the list of active hosts. 35 func (hdb *HostDB) insertBlockchainHost(host modules.HostDBEntry) { 36 // Remove garbage hosts and local hosts (but allow local hosts in testing). 37 if err := host.NetAddress.IsValid(); err != nil { 38 hdb.log.Debugf("WARN: host '%v' has an invalid NetAddress: %v", host.NetAddress, err) 39 return 40 } 41 // Ignore all local hosts announced through the blockchain. 42 if build.Release == "standard" && host.NetAddress.IsLocal() { 43 return 44 } 45 46 // Make sure the host gets into the host tree so it does not get dropped if 47 // shutdown occurs before a scan can be performed. 48 oldEntry, exists := hdb.hostTree.Select(host.PublicKey) 49 if exists { 50 // Replace the netaddress with the most recently announced netaddress. 51 // Also replace the FirstSeen value with the current block height if 52 // the first seen value has been set to zero (no hosts actually have a 53 // first seen height of zero, but due to rescans hosts can end up with 54 // a zero-value FirstSeen field. 55 oldEntry.NetAddress = host.NetAddress 56 if oldEntry.FirstSeen == 0 { 57 oldEntry.FirstSeen = hdb.blockHeight 58 } 59 err := hdb.hostTree.Modify(oldEntry) 60 if err != nil { 61 hdb.log.Println("ERROR: unable to modify host entry of host tree after a blockchain scan:", err) 62 } 63 } else { 64 host.FirstSeen = hdb.blockHeight 65 err := hdb.hostTree.Insert(host) 66 if err != nil { 67 hdb.log.Println("ERROR: unable to insert host entry into host tree after a blockchain scan:", err) 68 } 69 } 70 71 // Add the host to the scan queue. 72 hdb.queueScan(host) 73 } 74 75 // ProcessConsensusChange will be called by the consensus set every time there 76 // is a change in the blockchain. Updates will always be called in order. 77 func (hdb *HostDB) ProcessConsensusChange(cc modules.ConsensusChange) { 78 hdb.mu.Lock() 79 defer hdb.mu.Unlock() 80 81 // Update the hostdb's understanding of the block height. 82 for _, block := range cc.RevertedBlocks { 83 // Only doing the block check if the height is above zero saves hashing 84 // and saves a nontrivial amount of time during IBD. 85 if hdb.blockHeight > 0 || block.ID() != types.GenesisID { 86 hdb.blockHeight-- 87 } else if hdb.blockHeight != 0 { 88 // Sanity check - if the current block is the genesis block, the 89 // hostdb height should be set to zero. 90 hdb.log.Critical("Hostdb has detected a genesis block, but the height of the hostdb is set to ", hdb.blockHeight) 91 hdb.blockHeight = 0 92 } 93 } 94 for _, block := range cc.AppliedBlocks { 95 // Only doing the block check if the height is above zero saves hashing 96 // and saves a nontrivial amount of time during IBD. 97 if hdb.blockHeight > 0 || block.ID() != types.GenesisID { 98 hdb.blockHeight++ 99 } else if hdb.blockHeight != 0 { 100 // Sanity check - if the current block is the genesis block, the 101 // hostdb height should be set to zero. 102 hdb.log.Critical("Hostdb has detected a genesis block, but the height of the hostdb is set to ", hdb.blockHeight) 103 hdb.blockHeight = 0 104 } 105 } 106 107 // Add hosts announced in blocks that were applied. 108 for _, block := range cc.AppliedBlocks { 109 for _, host := range findHostAnnouncements(block) { 110 hdb.log.Debugln("Found a host in a host announcement:", host.NetAddress, host.PublicKey) 111 hdb.insertBlockchainHost(host) 112 } 113 } 114 115 hdb.lastChange = cc.ID 116 }