// checkWalletBalance looks at an upload and determines if there is enough // money in the wallet to support such an upload. An error is returned if it is // determined that there is not enough money. func (r *Renter) checkWalletBalance(up modules.FileUploadParams) error { // Get the size of the file. fileInfo, err := os.Stat(up.Filename) if err != nil { return err } curSize := types.NewCurrency64(uint64(fileInfo.Size())) var averagePrice types.Currency sampleSize := up.ErasureCode.NumPieces() * 3 / 2 hosts := r.hostDB.RandomHosts(sampleSize) for _, host := range hosts { averagePrice = averagePrice.Add(host.Price) } if len(hosts) == 0 { return errors.New("no hosts!") } averagePrice = averagePrice.Div(types.NewCurrency64(uint64(len(hosts)))) estimatedCost := averagePrice.Mul(types.NewCurrency64(uint64(up.Duration))).Mul(curSize) bufferedCost := estimatedCost.Mul(types.NewCurrency64(2)) siacoinBalance, _, _ := r.wallet.ConfirmedBalance() if bufferedCost.Cmp(siacoinBalance) > 0 { return errors.New("insufficient balance for upload") } return nil }
// Info returns generic information about the renter and the files that are // being rented. func (r *Renter) Info() (ri modules.RentInfo) { lockID := r.mu.RLock() // Include the list of files the renter knows about. for filename := range r.files { ri.Files = append(ri.Files, filename) } r.mu.RUnlock(lockID) // Calculate the average cost of a file. var totalPrice types.Currency sampleSize := defaultParityPieces + defaultDataPieces hosts := r.hostDB.RandomHosts(sampleSize) for _, host := range hosts { totalPrice = totalPrice.Add(host.Price) } if len(hosts) == 0 { return } averagePrice := totalPrice.Div(types.NewCurrency64(uint64(len(hosts)))) estimatedCost := averagePrice.Mul(types.NewCurrency64(defaultDuration)).Mul(types.NewCurrency64(1e9)).Mul(types.NewCurrency64(defaultParityPieces + defaultDataPieces)) // this also accounts for the buffering in the contract negotiation bufferedCost := estimatedCost.Mul(types.NewCurrency64(5)).Div(types.NewCurrency64(2)) ri.Price = bufferedCost // Report the number of known hosts. ri.KnownHosts = len(r.hostDB.ActiveHosts()) return }
// Info returns generic information about the renter and the files that are // being rented. func (r *Renter) Info() (ri modules.RentInfo) { lockID := r.mu.RLock() defer r.mu.RUnlock(lockID) // Include the list of files the renter knows about. for filename := range r.files { ri.Files = append(ri.Files, filename) } // Calculate the average cost of a file. var totalPrice types.Currency redundancy := 6 // reasonable estimate until we come up with an alternative sampleSize := redundancy * 3 hosts := r.hostDB.RandomHosts(sampleSize) for _, host := range hosts { totalPrice = totalPrice.Add(host.Price) } if len(hosts) == 0 { return } averagePrice := totalPrice.Div(types.NewCurrency64(uint64(len(hosts)))).Mul(types.NewCurrency64(uint64(redundancy))) // HACK: 6000 is the duration (set by the API), and 1024^3 is a GB. Price // is reported as per GB, no timeframe is given. estimatedCost := averagePrice.Mul(types.NewCurrency64(6000)).Mul(types.NewCurrency64(1024 * 1024 * 1024)) bufferedCost := estimatedCost.Mul(types.NewCurrency64(3)) // For some reason, this estimate can still be off by a large factor. ri.Price = bufferedCost // Report the number of known hosts. ri.KnownHosts = len(r.hostDB.ActiveHosts()) return }
// AveragePrice returns the average price of a host. func (hdb *HostDB) AveragePrice() types.Currency { // maybe a more sophisticated way of doing this var totalPrice types.Currency sampleSize := 18 hosts := hdb.randomHosts(sampleSize, nil) if len(hosts) == 0 { return totalPrice } for _, host := range hosts { totalPrice = totalPrice.Add(host.Price) } return totalPrice.Div(types.NewCurrency64(uint64(len(hosts)))) }
func (h *Host) Info() modules.HostInfo { lockID := h.mu.RLock() defer h.mu.RUnlock(lockID) info := modules.HostInfo{ HostSettings: h.HostSettings, StorageRemaining: h.spaceRemaining, NumContracts: len(h.obligationsByID), Profit: h.profit, } // sum up the current obligations to calculate PotentialProfit for _, obligation := range h.obligationsByID { fc := obligation.FileContract info.PotentialProfit = info.PotentialProfit.Add(types.PostTax(h.blockHeight, fc.Payout)) } // Calculate estimated competition (reported in per GB per month). Price // calculated by taking the average of hosts 8-15. var averagePrice types.Currency hosts := h.hostdb.RandomHosts(15) for i, host := range hosts { if i < 8 { continue } averagePrice = averagePrice.Add(host.Price) } if len(hosts) == 0 { return info } averagePrice = averagePrice.Div(types.NewCurrency64(uint64(len(hosts)))) // HACK: 4320 is one month, and 1024^3 is a GB. Price is reported as per GB // per month. estimatedCost := averagePrice.Mul(types.NewCurrency64(4320)).Mul(types.NewCurrency64(1024 * 1024 * 1024)) info.Competition = estimatedCost return info }