gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter.go (about)

     1  package modules
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"time"
     8  
     9  	"gitlab.com/SiaPrime/SiaPrime/build"
    10  	"gitlab.com/SiaPrime/SiaPrime/crypto"
    11  	"gitlab.com/SiaPrime/SiaPrime/types"
    12  
    13  	"gitlab.com/NebulousLabs/errors"
    14  )
    15  
    16  var (
    17  	// DefaultAllowance is the set of default allowance settings that will be
    18  	// used when allowances are not set or not fully set
    19  	DefaultAllowance = Allowance{
    20  		Funds:       types.SiacoinPrecision.Mul64(1e5),          // 100 KS
    21  		Hosts:       uint64(PriceEstimationScope),               // 50
    22  		Period:      types.BlockHeight(types.BlocksPerMonth),    // 1 Month
    23  		RenewWindow: types.BlockHeight(2 * types.BlocksPerWeek), // 2 Weeks
    24  
    25  		ExpectedStorage:    1e12,                                 // 1 TB
    26  		ExpectedUpload:     uint64(200e9) / types.BlocksPerMonth, // 200 GB per month
    27  		ExpectedDownload:   uint64(100e9) / types.BlocksPerMonth, // 100 GB per month
    28  		ExpectedRedundancy: 3.0,                                  // default is 10/30 erasure coding
    29  	}
    30  	// ErrHostFault indicates if an error is the host's fault.
    31  	ErrHostFault = errors.New("host has returned an error")
    32  
    33  	// ErrDownloadCancelled is the error set when a download was cancelled
    34  	// manually by the user.
    35  	ErrDownloadCancelled = errors.New("download was cancelled")
    36  
    37  	// PriceEstimationScope is the number of hosts that get queried by the
    38  	// renter when providing price estimates. Especially for the 'Standard'
    39  	// variable, there should be congruence with the number of contracts being
    40  	// used in the renter allowance.
    41  	PriceEstimationScope = build.Select(build.Var{
    42  		Standard: int(50),
    43  		Dev:      int(12),
    44  		Testing:  int(4),
    45  	}).(int)
    46  	// BackupKeySpecifier is a specifier that is hashed with the wallet seed to
    47  	// create a key for encrypting backups.
    48  	BackupKeySpecifier = types.Specifier{'b', 'a', 'c', 'k', 'u', 'p', 'k', 'e', 'y'}
    49  )
    50  
    51  // FilterMode is the helper type for the enum constants for the HostDB filter
    52  // mode
    53  type FilterMode int
    54  
    55  // HostDBFilterError HostDBDisableFilter HostDBActivateBlacklist and
    56  // HostDBActiveWhitelist are the constants used to enable and disable the filter
    57  // mode of the renter's hostdb
    58  const (
    59  	HostDBFilterError FilterMode = iota
    60  	HostDBDisableFilter
    61  	HostDBActivateBlacklist
    62  	HostDBActiveWhitelist
    63  )
    64  
    65  // String returns the string value for the FilterMode
    66  func (fm FilterMode) String() string {
    67  	switch fm {
    68  	case HostDBFilterError:
    69  		return "error"
    70  	case HostDBDisableFilter:
    71  		return "disable"
    72  	case HostDBActivateBlacklist:
    73  		return "blacklist"
    74  	case HostDBActiveWhitelist:
    75  		return "whitelist"
    76  	default:
    77  		return ""
    78  	}
    79  }
    80  
    81  // FromString assigned the FilterMode from the provide string
    82  func (fm *FilterMode) FromString(s string) error {
    83  	switch s {
    84  	case "disable":
    85  		*fm = HostDBDisableFilter
    86  	case "blacklist":
    87  		*fm = HostDBActivateBlacklist
    88  	case "whitelist":
    89  		*fm = HostDBActiveWhitelist
    90  	default:
    91  		*fm = HostDBFilterError
    92  		return fmt.Errorf("Could not assigned FilterMode from string %v", s)
    93  	}
    94  	return nil
    95  }
    96  
    97  // IsHostsFault indicates if a returned error is the host's fault.
    98  func IsHostsFault(err error) bool {
    99  	return errors.Contains(err, ErrHostFault)
   100  }
   101  
   102  const (
   103  	// RenterDir is the name of the directory that is used to store the
   104  	// renter's persistent data.
   105  	RenterDir = "renter"
   106  
   107  	// SiapathRoot is the name of the directory that is used to store the
   108  	// renter's siafiles.
   109  	SiapathRoot = "siafiles"
   110  
   111  	// BackupRoot is the name of the directory that is used to store the renter's
   112  	// snapshot siafiles.
   113  	BackupRoot = "snapshots"
   114  
   115  	// CombinedChunksRoot is the name of the directory that contains combined
   116  	// chunks consisting of multiple partial chunks.
   117  	CombinedChunksRoot = "combinedchunks"
   118  
   119  	// EstimatedFileContractTransactionSetSize is the estimated blockchain size
   120  	// of a transaction set between a renter and a host that contains a file
   121  	// contract. This transaction set will contain a setup transaction from each
   122  	// the host and the renter, and will also contain a file contract and file
   123  	// contract revision that have each been signed by all parties.
   124  	EstimatedFileContractTransactionSetSize = 2048
   125  
   126  	// EstimatedFileContractRevisionAndProofTransactionSetSize is the
   127  	// estimated blockchain size of a transaction set used by the host to
   128  	// provide the storage proof at the end of the contract duration.
   129  	EstimatedFileContractRevisionAndProofTransactionSetSize = 5000
   130  )
   131  
   132  type (
   133  	// CombinedChunkID is a unique identifier for a combined chunk which makes up
   134  	// part of its filename on disk.
   135  	CombinedChunkID string
   136  
   137  	// PartialChunk holds some information about a combined chunk
   138  	PartialChunk struct {
   139  		ChunkID        CombinedChunkID // The ChunkID of the combined chunk the partial is in.
   140  		InPartialsFile bool            // 'true' if the combined chunk is already in the partials siafile.
   141  		Length         uint64          // length of the partial chunk within the combined chunk.
   142  		Offset         uint64          // offset of the partial chunk within the combined chunk.
   143  	}
   144  )
   145  
   146  type (
   147  	// ErasureCoderType is an identifier for the individual types of erasure
   148  	// coders.
   149  	ErasureCoderType [4]byte
   150  
   151  	// ErasureCoderIdentifier is an identifier that only matches another
   152  	// ErasureCoder's identifier if they both are of the same type and settings.
   153  	ErasureCoderIdentifier string
   154  
   155  	// An ErasureCoder is an error-correcting encoder and decoder.
   156  	ErasureCoder interface {
   157  		// NumPieces is the number of pieces returned by Encode.
   158  		NumPieces() int
   159  
   160  		// MinPieces is the minimum number of pieces that must be present to
   161  		// recover the original data.
   162  		MinPieces() int
   163  
   164  		// Encode splits data into equal-length pieces, with some pieces
   165  		// containing parity data.
   166  		Encode(data []byte) ([][]byte, error)
   167  
   168  		// Identifier returns the ErasureCoderIdentifier of the ErasureCoder.
   169  		Identifier() ErasureCoderIdentifier
   170  
   171  		// EncodeShards encodes the input data like Encode but accepts an already
   172  		// sharded input.
   173  		EncodeShards(data [][]byte) ([][]byte, error)
   174  
   175  		// Reconstruct recovers the full set of encoded shards from the provided
   176  		// pieces, of which at least MinPieces must be non-nil.
   177  		Reconstruct(pieces [][]byte) error
   178  
   179  		// Recover recovers the original data from pieces and writes it to w.
   180  		// pieces should be identical to the slice returned by Encode (length and
   181  		// order must be preserved), but with missing elements set to nil. n is
   182  		// the number of bytes to be written to w; this is necessary because
   183  		// pieces may have been padded with zeros during encoding.
   184  		Recover(pieces [][]byte, n uint64, w io.Writer) error
   185  
   186  		// SupportsPartialEncoding returns true if the ErasureCoder can be used
   187  		// to encode/decode any crypto.SegmentSize bytes of an encoded piece or
   188  		// false otherwise.
   189  		SupportsPartialEncoding() bool
   190  
   191  		// Type returns the type identifier of the ErasureCoder.
   192  		Type() ErasureCoderType
   193  	}
   194  )
   195  
   196  // An Allowance dictates how much the Renter is allowed to spend in a given
   197  // period. Note that funds are spent on both storage and bandwidth.
   198  type Allowance struct {
   199  	Funds       types.Currency    `json:"funds"`
   200  	Hosts       uint64            `json:"hosts"`
   201  	Period      types.BlockHeight `json:"period"`
   202  	RenewWindow types.BlockHeight `json:"renewwindow"`
   203  	//	FilterHostsSubnet bool              `json:"filterhostssubnet"`
   204  
   205  	// ExpectedStorage is the amount of data that we expect to have in a contract.
   206  	ExpectedStorage uint64 `json:"expectedstorage"`
   207  
   208  	// ExpectedUpload is the expected amount of data uploaded through the API,
   209  	// before redundancy, per block.
   210  	ExpectedUpload uint64 `json:"expectedupload"`
   211  
   212  	// ExpectedDownload is the expected amount of data downloaded through the
   213  	// API per block.
   214  	ExpectedDownload uint64 `json:"expecteddownload"`
   215  
   216  	// ExpectedRedundancy is the average redundancy of files being uploaded.
   217  	ExpectedRedundancy float64 `json:"expectedredundancy"`
   218  }
   219  
   220  // ContractUtility contains metrics internal to the contractor that reflect the
   221  // utility of a given contract.
   222  type ContractUtility struct {
   223  	GoodForUpload bool
   224  	GoodForRenew  bool
   225  	LastOOSErr    types.BlockHeight // OOS means Out Of Storage
   226  	Locked        bool              // Locked utilities can only be set to false.
   227  }
   228  
   229  // DirectoryInfo provides information about a siadir
   230  type DirectoryInfo struct {
   231  	// The following fields are aggregate values of the siadir. These values are
   232  	// the totals of the siadir and any sub siadirs, or are calculated based on
   233  	// all the values in the subtree
   234  	AggregateHealth              float64   `json:"aggregatehealth"`
   235  	AggregateLastHealthCheckTime time.Time `json:"aggregatelasthealthchecktime"`
   236  	AggregateMaxHealth           float64   `json:"aggregatemaxhealth"`
   237  	AggregateMaxHealthPercentage float64   `json:"aggregatemaxhealthpercentage"`
   238  	AggregateMinRedundancy       float64   `json:"aggregateminredundancy"`
   239  	AggregateMostRecentModTime   time.Time `json:"aggregatemostrecentmodtime"`
   240  	AggregateNumFiles            uint64    `json:"aggregatenumfiles"`
   241  	AggregateNumStuckChunks      uint64    `json:"aggregatenumstuckchunks"`
   242  	AggregateNumSubDirs          uint64    `json:"aggregatenumsubdirs"`
   243  	AggregateSize                uint64    `json:"aggregatesize"`
   244  	AggregateStuckHealth         float64   `json:"aggregatestuckhealth"`
   245  
   246  	// The following fields are information specific to the siadir that is not
   247  	// an aggregate of the entire sub directory tree
   248  	Health              float64   `json:"health"`
   249  	LastHealthCheckTime time.Time `json:"lasthealthchecktime"`
   250  	MaxHealthPercentage float64   `json:"maxhealthpercentage"`
   251  	MaxHealth           float64   `json:"maxhealth"`
   252  	MinRedundancy       float64   `json:"minredundancy"`
   253  	MostRecentModTime   time.Time `json:"mostrecentmodtime"`
   254  	NumFiles            uint64    `json:"numfiles"`
   255  	NumStuckChunks      uint64    `json:"numstuckchunks"`
   256  	NumSubDirs          uint64    `json:"numsubdirs"`
   257  	SiaPath             SiaPath   `json:"siapath"`
   258  	Size                uint64    `json:"size"`
   259  	StuckHealth         float64   `json:"stuckhealth"`
   260  }
   261  
   262  // DownloadInfo provides information about a file that has been requested for
   263  // download.
   264  type DownloadInfo struct {
   265  	Destination     string  `json:"destination"`     // The destination of the download.
   266  	DestinationType string  `json:"destinationtype"` // Can be "file", "memory buffer", or "http stream".
   267  	Length          uint64  `json:"length"`          // The length requested for the download.
   268  	Offset          uint64  `json:"offset"`          // The offset within the siafile requested for the download.
   269  	SiaPath         SiaPath `json:"siapath"`         // The siapath of the file used for the download.
   270  
   271  	Completed            bool      `json:"completed"`            // Whether or not the download has completed.
   272  	EndTime              time.Time `json:"endtime"`              // The time when the download fully completed.
   273  	Error                string    `json:"error"`                // Will be the empty string unless there was an error.
   274  	Received             uint64    `json:"received"`             // Amount of data confirmed and decoded.
   275  	StartTime            time.Time `json:"starttime"`            // The time when the download was started.
   276  	StartTimeUnix        int64     `json:"starttimeunix"`        // The time when the download was started in unix format.
   277  	TotalDataTransferred uint64    `json:"totaldatatransferred"` // Total amount of data transferred, including negotiation, etc.
   278  }
   279  
   280  // FileUploadParams contains the information used by the Renter to upload a
   281  // file.
   282  type FileUploadParams struct {
   283  	Source              string
   284  	SiaPath             SiaPath
   285  	ErasureCode         ErasureCoder
   286  	Force               bool
   287  	DisablePartialChunk bool
   288  	Repair              bool
   289  }
   290  
   291  // FileInfo provides information about a file.
   292  type FileInfo struct {
   293  	AccessTime       time.Time         `json:"accesstime"`
   294  	Available        bool              `json:"available"`
   295  	ChangeTime       time.Time         `json:"changetime"`
   296  	CipherType       string            `json:"ciphertype"`
   297  	CreateTime       time.Time         `json:"createtime"`
   298  	Expiration       types.BlockHeight `json:"expiration"`
   299  	Filesize         uint64            `json:"filesize"`
   300  	Health           float64           `json:"health"`
   301  	LocalPath        string            `json:"localpath"`
   302  	MaxHealth        float64           `json:"maxhealth"`
   303  	MaxHealthPercent float64           `json:"maxhealthpercent"`
   304  	ModTime          time.Time         `json:"modtime"`
   305  	NumStuckChunks   uint64            `json:"numstuckchunks"`
   306  	OnDisk           bool              `json:"ondisk"`
   307  	Recoverable      bool              `json:"recoverable"`
   308  	Redundancy       float64           `json:"redundancy"`
   309  	Renewing         bool              `json:"renewing"`
   310  	SiaPath          SiaPath           `json:"siapath"`
   311  	Stuck            bool              `json:"stuck"`
   312  	StuckHealth      float64           `json:"stuckhealth"`
   313  	UploadedBytes    uint64            `json:"uploadedbytes"`
   314  	UploadProgress   float64           `json:"uploadprogress"`
   315  }
   316  
   317  // A HostDBEntry represents one host entry in the Renter's host DB. It
   318  // aggregates the host's external settings and metrics with its public key.
   319  type HostDBEntry struct {
   320  	HostExternalSettings
   321  
   322  	// FirstSeen is the last block height at which this host was announced.
   323  	FirstSeen types.BlockHeight `json:"firstseen"`
   324  
   325  	// Measurements that have been taken on the host. The most recent
   326  	// measurements are kept in full detail, historic ones are compressed into
   327  	// the historic values.
   328  	HistoricDowntime time.Duration `json:"historicdowntime"`
   329  	HistoricUptime   time.Duration `json:"historicuptime"`
   330  	ScanHistory      HostDBScans   `json:"scanhistory"`
   331  
   332  	// Measurements that are taken whenever we interact with a host.
   333  	HistoricFailedInteractions     float64 `json:"historicfailedinteractions"`
   334  	HistoricSuccessfulInteractions float64 `json:"historicsuccessfulinteractions"`
   335  	RecentFailedInteractions       float64 `json:"recentfailedinteractions"`
   336  	RecentSuccessfulInteractions   float64 `json:"recentsuccessfulinteractions"`
   337  
   338  	LastHistoricUpdate types.BlockHeight `json:"lasthistoricupdate"`
   339  
   340  	// Measurements related to the IP subnet mask.
   341  	IPNets          []string  `json:"ipnets"`
   342  	LastIPNetChange time.Time `json:"lastipnetchange"`
   343  
   344  	// The public key of the host, stored separately to minimize risk of certain
   345  	// MitM based vulnerabilities.
   346  	PublicKey types.SiaPublicKey `json:"publickey"`
   347  
   348  	// Filtered says whether or not a HostDBEntry is being filtered out of the
   349  	// filtered hosttree due to the filter mode of the hosttree
   350  	Filtered bool `json:"filtered"`
   351  }
   352  
   353  // HostDBScan represents a single scan event.
   354  type HostDBScan struct {
   355  	Timestamp time.Time `json:"timestamp"`
   356  	Success   bool      `json:"success"`
   357  }
   358  
   359  // HostScoreBreakdown provides a piece-by-piece explanation of why a host has
   360  // the score that they do.
   361  //
   362  // NOTE: Renters are free to use whatever scoring they feel appropriate for
   363  // hosts. Some renters will outright blacklist or whitelist sets of hosts. The
   364  // results provided by this struct can only be used as a guide, and may vary
   365  // significantly from machine to machine.
   366  type HostScoreBreakdown struct {
   367  	Score          types.Currency `json:"score"`
   368  	ConversionRate float64        `json:"conversionrate"`
   369  
   370  	AgeAdjustment              float64 `json:"ageadjustment"`
   371  	BurnAdjustment             float64 `json:"burnadjustment"`
   372  	CollateralAdjustment       float64 `json:"collateraladjustment"`
   373  	DurationAdjustment         float64 `json:"durationadjustment"`
   374  	InteractionAdjustment      float64 `json:"interactionadjustment"`
   375  	PriceAdjustment            float64 `json:"pricesmultiplier"`
   376  	StorageRemainingAdjustment float64 `json:"storageremainingadjustment"`
   377  	UptimeAdjustment           float64 `json:"uptimeadjustment"`
   378  	VersionAdjustment          float64 `json:"versionadjustment"`
   379  }
   380  
   381  // RenterPriceEstimation contains a bunch of files estimating the costs of
   382  // various operations on the network.
   383  type RenterPriceEstimation struct {
   384  	// The cost of downloading 1 TB of data.
   385  	DownloadTerabyte types.Currency `json:"downloadterabyte"`
   386  
   387  	// The cost of forming a set of contracts using the defaults.
   388  	FormContracts types.Currency `json:"formcontracts"`
   389  
   390  	// The cost of storing 1 TB for a month, including redundancy.
   391  	StorageTerabyteMonth types.Currency `json:"storageterabytemonth"`
   392  
   393  	// The cost of consuming 1 TB of upload bandwidth from the host, including
   394  	// redundancy.
   395  	UploadTerabyte types.Currency `json:"uploadterabyte"`
   396  }
   397  
   398  // RenterSettings control the behavior of the Renter.
   399  type RenterSettings struct {
   400  	Allowance         Allowance `json:"allowance"`
   401  	IPViolationsCheck bool      `json:"ipviolationcheck"`
   402  	MaxUploadSpeed    int64     `json:"maxuploadspeed"`
   403  	MaxDownloadSpeed  int64     `json:"maxdownloadspeed"`
   404  	//	StreamCacheSize   uint64    `json:"streamcachesize"`
   405  }
   406  
   407  // HostDBScans represents a sortable slice of scans.
   408  type HostDBScans []HostDBScan
   409  
   410  func (s HostDBScans) Len() int           { return len(s) }
   411  func (s HostDBScans) Less(i, j int) bool { return s[i].Timestamp.Before(s[j].Timestamp) }
   412  func (s HostDBScans) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   413  
   414  // MerkleRootSet is a set of Merkle roots, and gets encoded more efficiently.
   415  type MerkleRootSet []crypto.Hash
   416  
   417  // MarshalJSON defines a JSON encoding for a MerkleRootSet.
   418  func (mrs MerkleRootSet) MarshalJSON() ([]byte, error) {
   419  	// Copy the whole array into a giant byte slice and then encode that.
   420  	fullBytes := make([]byte, crypto.HashSize*len(mrs))
   421  	for i := range mrs {
   422  		copy(fullBytes[i*crypto.HashSize:(i+1)*crypto.HashSize], mrs[i][:])
   423  	}
   424  	return json.Marshal(fullBytes)
   425  }
   426  
   427  // UnmarshalJSON attempts to decode a MerkleRootSet, falling back on the legacy
   428  // decoding of a []crypto.Hash if that fails.
   429  func (mrs *MerkleRootSet) UnmarshalJSON(b []byte) error {
   430  	// Decode the giant byte slice, and then split it into separate arrays.
   431  	var fullBytes []byte
   432  	err := json.Unmarshal(b, &fullBytes)
   433  	if err != nil {
   434  		// Encoding the byte slice has failed, try decoding it as a []crypto.Hash.
   435  		var hashes []crypto.Hash
   436  		err := json.Unmarshal(b, &hashes)
   437  		if err != nil {
   438  			return err
   439  		}
   440  		*mrs = MerkleRootSet(hashes)
   441  		return nil
   442  	}
   443  
   444  	umrs := make(MerkleRootSet, len(fullBytes)/32)
   445  	for i := range umrs {
   446  		copy(umrs[i][:], fullBytes[i*crypto.HashSize:(i+1)*crypto.HashSize])
   447  	}
   448  	*mrs = umrs
   449  	return nil
   450  }
   451  
   452  // RecoverableContract is a types.FileContract as it appears on the blockchain
   453  // with additional fields which contain the information required to recover its
   454  // latest revision from a host.
   455  type RecoverableContract struct {
   456  	types.FileContract
   457  	// ID is the FileContract's ID.
   458  	ID types.FileContractID `json:"id"`
   459  	// HostPublicKey is the public key of the host we formed this contract
   460  	// with.
   461  	HostPublicKey types.SiaPublicKey `json:"hostpublickey"`
   462  	// InputParentID is the ParentID of the first SiacoinInput of the
   463  	// transaction that contains this contract.
   464  	InputParentID types.SiacoinOutputID `json:"inputparentid"`
   465  	// StartHeight is the estimated startheight of a recoverable contract.
   466  	StartHeight types.BlockHeight `json:"startheight"`
   467  	// TxnFee of the transaction which contains the contract.
   468  	TxnFee types.Currency `json:"txnfee"`
   469  }
   470  
   471  // A RenterContract contains metadata about a file contract. It is read-only;
   472  // modifying a RenterContract does not modify the actual file contract.
   473  type RenterContract struct {
   474  	ID            types.FileContractID
   475  	HostPublicKey types.SiaPublicKey
   476  	Transaction   types.Transaction
   477  
   478  	StartHeight types.BlockHeight
   479  	EndHeight   types.BlockHeight
   480  
   481  	// RenterFunds is the amount remaining in the contract that the renter can
   482  	// spend.
   483  	RenterFunds types.Currency
   484  
   485  	// The FileContract does not indicate what funds were spent on, so we have
   486  	// to track the various costs manually.
   487  	DownloadSpending types.Currency
   488  	StorageSpending  types.Currency
   489  	UploadSpending   types.Currency
   490  
   491  	// Utility contains utility information about the renter.
   492  	Utility ContractUtility
   493  
   494  	// TotalCost indicates the amount of money that the renter spent and/or
   495  	// locked up while forming a contract. This includes fees, and includes
   496  	// funds which were allocated (but not necessarily committed) to spend on
   497  	// uploads/downloads/storage.
   498  	TotalCost types.Currency
   499  
   500  	// ContractFee is the amount of money paid to the host to cover potential
   501  	// future transaction fees that the host may incur, and to cover any other
   502  	// overheads the host may have.
   503  	//
   504  	// TxnFee is the amount of money spent on the transaction fee when putting
   505  	// the renter contract on the blockchain.
   506  	//
   507  	// SiafundFee is the amount of money spent on siafund fees when creating the
   508  	// contract. The siafund fee that the renter pays covers both the renter and
   509  	// the host portions of the contract, and therefore can be unexpectedly high
   510  	// if the the host collateral is high.
   511  	ContractFee types.Currency
   512  	TxnFee      types.Currency
   513  	SiafundFee  types.Currency
   514  }
   515  
   516  // ContractorSpending contains the metrics about how much the Contractor has
   517  // spent during the current billing period.
   518  type ContractorSpending struct {
   519  	// ContractFees are the sum of all fees in the contract. This means it
   520  	// includes the ContractFee, TxnFee and SiafundFee
   521  	ContractFees types.Currency `json:"contractfees"`
   522  	// DownloadSpending is the money currently spent on downloads.
   523  	DownloadSpending types.Currency `json:"downloadspending"`
   524  	// StorageSpending is the money currently spent on storage.
   525  	StorageSpending types.Currency `json:"storagespending"`
   526  	// ContractSpending is the total amount of money that the renter has put
   527  	// into contracts, whether it's locked and the renter gets that money
   528  	// back or whether it's spent and the renter won't get the money back.
   529  	TotalAllocated types.Currency `json:"totalallocated"`
   530  	// UploadSpending is the money currently spent on uploads.
   531  	UploadSpending types.Currency `json:"uploadspending"`
   532  	// Unspent is locked-away, unspent money.
   533  	Unspent types.Currency `json:"unspent"`
   534  	// ContractSpendingDeprecated was renamed to TotalAllocated and always has the
   535  	// same value as TotalAllocated.
   536  	ContractSpendingDeprecated types.Currency `json:"contractspending"`
   537  	// WithheldFunds are the funds from the previous period that are tied up
   538  	// in contracts and have not been released yet
   539  	WithheldFunds types.Currency `json:"withheldfunds"`
   540  	// ReleaseBlock is the block at which the WithheldFunds should be
   541  	// released to the renter, based on worst case.
   542  	// Contract End Height + Host Window Size + Maturity Delay
   543  	ReleaseBlock types.BlockHeight `json:"releaseblock"`
   544  	// PreviousSpending is the total spend funds from old contracts
   545  	// that are not included in the current period spending
   546  	PreviousSpending types.Currency `json:"previousspending"`
   547  }
   548  
   549  // UploadedBackup contains metadata about an uploaded backup.
   550  type UploadedBackup struct {
   551  	Name           string
   552  	UID            [16]byte
   553  	CreationDate   types.Timestamp
   554  	Size           uint64 // size of snapshot .sia file
   555  	UploadProgress float64
   556  }
   557  
   558  // A Renter uploads, tracks, repairs, and downloads a set of files for the
   559  // user.
   560  type Renter interface {
   561  	// ActiveHosts provides the list of hosts that the renter is selecting,
   562  	// sorted by preference.
   563  	ActiveHosts() []HostDBEntry
   564  
   565  	// AllHosts returns the full list of hosts known to the renter.
   566  	AllHosts() []HostDBEntry
   567  
   568  	// Close closes the Renter.
   569  	Close() error
   570  
   571  	// CancelContract cancels a specific contract of the renter.
   572  	CancelContract(id types.FileContractID) error
   573  
   574  	// Contracts returns the staticContracts of the renter's hostContractor.
   575  	Contracts() []RenterContract
   576  
   577  	// CreateBackup creates a backup of the renter's siafiles. If a secret is not
   578  	// nil, the backup will be encrypted using the provided secret.
   579  	CreateBackup(dst string, secret []byte) error
   580  
   581  	// LoadBackup loads the siafiles of a previously created backup into the
   582  	// renter. If the backup is encrypted, secret will be used to decrypt it.
   583  	// Otherwise the argument is ignored.
   584  	// If a file from the backup would have the same path as an already
   585  	// existing file, a suffix of the form _[num] is appended to the siapath.
   586  	// [num] is incremented until a siapath is found that is not already in
   587  	// use.
   588  	LoadBackup(src string, secret []byte) error
   589  
   590  	// InitRecoveryScan starts scanning the whole blockchain for recoverable
   591  	// contracts within a separate thread.
   592  	InitRecoveryScan() error
   593  
   594  	// OldContracts returns the oldContracts of the renter's hostContractor.
   595  	OldContracts() []RenterContract
   596  
   597  	// ContractUtility provides the contract utility for a given host key.
   598  	ContractUtility(pk types.SiaPublicKey) (ContractUtility, bool)
   599  
   600  	// CurrentPeriod returns the height at which the current allowance period
   601  	// began.
   602  	CurrentPeriod() types.BlockHeight
   603  
   604  	// PeriodSpending returns the amount spent on contracts in the current
   605  	// billing period.
   606  	PeriodSpending() ContractorSpending
   607  
   608  	// RecoverableContracts returns the contracts that the contractor deems
   609  	// recoverable. That means they are not expired yet and also not part of the
   610  	// active contracts. Usually this should return an empty slice unless the host
   611  	// isn't available for recovery or something went wrong.
   612  	RecoverableContracts() []RecoverableContract
   613  
   614  	// RecoveryScanStatus returns a bool indicating if a scan for recoverable
   615  	// contracts is in progress and if it is, the current progress of the scan.
   616  	RecoveryScanStatus() (bool, types.BlockHeight)
   617  
   618  	// RefreshedContract checks if the contract was previously refreshed
   619  	RefreshedContract(fcid types.FileContractID) bool
   620  
   621  	// SetFileStuck sets the 'stuck' status of a file.
   622  	SetFileStuck(siaPath SiaPath, stuck bool) error
   623  
   624  	// UploadBackup uploads a backup to hosts, such that it can be retrieved
   625  	// using only the seed.
   626  	UploadBackup(src string, name string) error
   627  
   628  	// DownloadBackup downloads a backup previously uploaded to hosts.
   629  	DownloadBackup(dst string, name string) error
   630  
   631  	// UploadedBackups returns a list of backups previously uploaded to hosts,
   632  	// along with a list of which hosts are storing all known backups.
   633  	UploadedBackups() ([]UploadedBackup, []types.SiaPublicKey, error)
   634  
   635  	// BackupsOnHost returns the backups stored on the specified host.
   636  	BackupsOnHost(hostKey types.SiaPublicKey) ([]UploadedBackup, error)
   637  
   638  	// DeleteFile deletes a file entry from the renter.
   639  	DeleteFile(siaPath SiaPath) error
   640  
   641  	// Download performs a download according to the parameters passed, including
   642  	// downloads of `offset` and `length` type.
   643  	Download(params RenterDownloadParameters) error
   644  
   645  	// Download performs a download according to the parameters passed without
   646  	// blocking, including downloads of `offset` and `length` type.
   647  	DownloadAsync(params RenterDownloadParameters, onComplete func(error) error) (cancel func(), err error)
   648  
   649  	// ClearDownloadHistory clears the download history of the renter
   650  	// inclusive for before and after times.
   651  	ClearDownloadHistory(after, before time.Time) error
   652  
   653  	// DownloadHistory lists all the files that have been scheduled for download.
   654  	DownloadHistory() []DownloadInfo
   655  
   656  	// File returns information on specific file queried by user
   657  	File(siaPath SiaPath) (FileInfo, error)
   658  
   659  	// FileList returns information on all of the files stored by the renter at the
   660  	// specified folder. The 'cached' argument specifies whether cached values
   661  	// should be returned or not.
   662  	FileList(siaPath SiaPath, recursive, cached bool) ([]FileInfo, error)
   663  
   664  	// Filter returns the renter's hostdb's filterMode and filteredHosts
   665  	Filter() (FilterMode, map[string]types.SiaPublicKey, error)
   666  
   667  	// SetFilterMode sets the renter's hostdb filter mode
   668  	SetFilterMode(fm FilterMode, hosts []types.SiaPublicKey) error
   669  
   670  	// Host provides the DB entry and score breakdown for the requested host.
   671  	Host(pk types.SiaPublicKey) (HostDBEntry, bool)
   672  
   673  	// InitialScanComplete returns a boolean indicating if the initial scan of the
   674  	// hostdb is completed.
   675  	InitialScanComplete() (bool, error)
   676  
   677  	// PriceEstimation estimates the cost in siacoins of performing various
   678  	// storage and data operations.
   679  	PriceEstimation(allowance Allowance) (RenterPriceEstimation, Allowance, error)
   680  
   681  	// RenameFile changes the path of a file.
   682  	RenameFile(siaPath, newSiaPath SiaPath) error
   683  
   684  	// RenameDir changes the path of a dir.
   685  	RenameDir(oldPath, newPath SiaPath) error
   686  
   687  	// EstimateHostScore will return the score for a host with the provided
   688  	// settings, assuming perfect age and uptime adjustments
   689  	EstimateHostScore(entry HostDBEntry, allowance Allowance) (HostScoreBreakdown, error)
   690  
   691  	// ScoreBreakdown will return the score for a host db entry using the
   692  	// hostdb's weighting algorithm.
   693  	ScoreBreakdown(entry HostDBEntry) (HostScoreBreakdown, error)
   694  
   695  	// Settings returns the Renter's current settings.
   696  	Settings() RenterSettings
   697  
   698  	// SetSettings sets the Renter's settings.
   699  	SetSettings(RenterSettings) error
   700  
   701  	// SetFileTrackingPath sets the on-disk location of an uploaded file to a
   702  	// new value. Useful if files need to be moved on disk.
   703  	SetFileTrackingPath(siaPath SiaPath, newPath string) error
   704  
   705  	// Streamer creates a io.ReadSeeker that can be used to stream downloads
   706  	// from the Sia network and also returns the fileName of the streamed
   707  	// resource.
   708  	Streamer(siapath SiaPath) (string, Streamer, error)
   709  
   710  	// Upload uploads a file using the input parameters.
   711  	Upload(FileUploadParams) error
   712  
   713  	// UploadStreamFromReader reads from the provided reader until io.EOF is reached and
   714  	// upload the data to the Sia network.
   715  	UploadStreamFromReader(up FileUploadParams, reader io.Reader) error
   716  
   717  	// CreateDir creates a directory for the renter
   718  	CreateDir(siaPath SiaPath) error
   719  
   720  	// DeleteDir deletes a directory from the renter
   721  	DeleteDir(siaPath SiaPath) error
   722  
   723  	// DirList lists the directories in a siadir
   724  	DirList(siaPath SiaPath) ([]DirectoryInfo, error)
   725  }
   726  
   727  // Streamer is the interface implemented by the Renter's streamer type which
   728  // allows for streaming files uploaded to the Sia network.
   729  type Streamer interface {
   730  	io.ReadSeeker
   731  	io.Closer
   732  }
   733  
   734  // RenterDownloadParameters defines the parameters passed to the Renter's
   735  // Download method.
   736  type RenterDownloadParameters struct {
   737  	Async       bool
   738  	Httpwriter  io.Writer
   739  	Length      uint64
   740  	Offset      uint64
   741  	SiaPath     SiaPath
   742  	Destination string
   743  }