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  }