gitlab.com/jokerrs1/Sia@v1.3.2/modules/host/announce.go (about) 1 package host 2 3 import ( 4 "errors" 5 6 "github.com/NebulousLabs/Sia/build" 7 "github.com/NebulousLabs/Sia/modules" 8 ) 9 10 var ( 11 // errAnnWalletLocked is returned during a host announcement if the wallet 12 // is locked. 13 errAnnWalletLocked = errors.New("cannot announce the host while the wallet is locked") 14 15 // errUnknownAddress is returned if the host is unable to determine a 16 // public address for itself to use in the announcement. 17 errUnknownAddress = errors.New("host cannot announce, does not seem to have a valid address.") 18 ) 19 20 // managedAnnounce creates an announcement transaction and submits it to the network. 21 func (h *Host) managedAnnounce(addr modules.NetAddress) error { 22 // The wallet needs to be unlocked to add fees to the transaction, and the 23 // host needs to have an active unlock hash that renters can make payment 24 // to. 25 if !h.wallet.Unlocked() { 26 return errAnnWalletLocked 27 } 28 29 h.mu.Lock() 30 pubKey := h.publicKey 31 secKey := h.secretKey 32 err := h.checkUnlockHash() 33 h.mu.Unlock() 34 if err != nil { 35 return err 36 } 37 38 // Create the announcement that's going to be added to the arbitrary data 39 // field of the transaction. 40 signedAnnouncement, err := modules.CreateAnnouncement(addr, pubKey, secKey) 41 if err != nil { 42 return err 43 } 44 45 // Create a transaction, with a fee, that contains the full announcement. 46 txnBuilder := h.wallet.StartTransaction() 47 _, fee := h.tpool.FeeEstimation() 48 fee = fee.Mul64(600) // Estimated txn size (in bytes) of a host announcement. 49 err = txnBuilder.FundSiacoins(fee) 50 if err != nil { 51 txnBuilder.Drop() 52 return err 53 } 54 _ = txnBuilder.AddMinerFee(fee) 55 _ = txnBuilder.AddArbitraryData(signedAnnouncement) 56 txnSet, err := txnBuilder.Sign(true) 57 if err != nil { 58 txnBuilder.Drop() 59 return err 60 } 61 62 // Add the transactions to the transaction pool. 63 err = h.tpool.AcceptTransactionSet(txnSet) 64 if err != nil { 65 txnBuilder.Drop() 66 return err 67 } 68 69 h.mu.Lock() 70 h.announced = true 71 h.mu.Unlock() 72 h.log.Printf("INFO: Successfully announced as %v", addr) 73 return nil 74 } 75 76 // Announce creates a host announcement transaction. 77 func (h *Host) Announce() error { 78 err := h.tg.Add() 79 if err != nil { 80 return err 81 } 82 defer h.tg.Done() 83 84 // Grab the internal net address and internal auto address, and compare 85 // them. 86 h.mu.RLock() 87 userSet := h.settings.NetAddress 88 autoSet := h.autoAddress 89 h.mu.RUnlock() 90 91 // Check that we have at least one address to work with. 92 if userSet == "" && autoSet == "" { 93 return build.ExtendErr("cannot announce because address could not be determined", err) 94 } 95 96 // Prefer using the userSet address, otherwise use the automatic address. 97 var annAddr modules.NetAddress 98 if userSet != "" { 99 annAddr = userSet 100 } else { 101 annAddr = autoSet 102 } 103 104 // Check that the address is sane, and that the address is also not local. 105 err = annAddr.IsStdValid() 106 if err != nil { 107 return build.ExtendErr("announcement requested with bad net address", err) 108 } 109 if annAddr.IsLocal() && build.Release != "testing" { 110 return errors.New("announcement requested with local net address") 111 } 112 113 // Address has cleared inspection, perform the announcement. 114 return h.managedAnnounce(annAddr) 115 } 116 117 // AnnounceAddress submits a host announcement to the blockchain to announce a 118 // specific address. If there is no error, the host's address will be updated 119 // to the supplied address. 120 func (h *Host) AnnounceAddress(addr modules.NetAddress) error { 121 err := h.tg.Add() 122 if err != nil { 123 return err 124 } 125 defer h.tg.Done() 126 127 // Check that the address is sane, and that the address is also not local. 128 err = addr.IsStdValid() 129 if err != nil { 130 return build.ExtendErr("announcement requested with bad net address", err) 131 } 132 if addr.IsLocal() { 133 return errors.New("announcement requested with local net address") 134 } 135 136 // Attempt the actual announcement. 137 err = h.managedAnnounce(addr) 138 if err != nil { 139 return build.ExtendErr("unable to perform manual host announcement", err) 140 } 141 142 // Address is valid, update the host's internal net address to match the 143 // specified addr. 144 h.mu.Lock() 145 h.settings.NetAddress = addr 146 h.mu.Unlock() 147 return nil 148 }