gitlab.com/jokerrs1/Sia@v1.3.2/modules/renter.go (about)

     1  package modules
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"time"
     7  
     8  	"github.com/NebulousLabs/Sia/crypto"
     9  	"github.com/NebulousLabs/Sia/types"
    10  )
    11  
    12  const (
    13  	// RenterDir is the name of the directory that is used to store the
    14  	// renter's persistent data.
    15  	RenterDir = "renter"
    16  )
    17  
    18  // An ErasureCoder is an error-correcting encoder and decoder.
    19  type ErasureCoder interface {
    20  	// NumPieces is the number of pieces returned by Encode.
    21  	NumPieces() int
    22  
    23  	// MinPieces is the minimum number of pieces that must be present to
    24  	// recover the original data.
    25  	MinPieces() int
    26  
    27  	// Encode splits data into equal-length pieces, with some pieces
    28  	// containing parity data.
    29  	Encode(data []byte) ([][]byte, error)
    30  
    31  	// Recover recovers the original data from pieces and writes it to w.
    32  	// pieces should be identical to the slice returned by Encode (length and
    33  	// order must be preserved), but with missing elements set to nil. n is
    34  	// the number of bytes to be written to w; this is necessary because
    35  	// pieces may have been padded with zeros during encoding.
    36  	Recover(pieces [][]byte, n uint64, w io.Writer) error
    37  }
    38  
    39  // An Allowance dictates how much the Renter is allowed to spend in a given
    40  // period. Note that funds are spent on both storage and bandwidth.
    41  type Allowance struct {
    42  	Funds       types.Currency    `json:"funds"`
    43  	Hosts       uint64            `json:"hosts"`
    44  	Period      types.BlockHeight `json:"period"`
    45  	RenewWindow types.BlockHeight `json:"renewwindow"`
    46  }
    47  
    48  // ContractUtility contains metrics internal to the contractor that reflect the
    49  // utility of a given contract.
    50  type ContractUtility struct {
    51  	GoodForUpload bool
    52  	GoodForRenew  bool
    53  }
    54  
    55  // DownloadInfo provides information about a file that has been requested for
    56  // download.
    57  type DownloadInfo struct {
    58  	Destination     string `json:"destination"`     // The destination of the download.
    59  	DestinationType string `json:"destinationtype"` // Can be "file", "memory buffer", or "http stream".
    60  	Length          uint64 `json:"length"`          // The length requested for the download.
    61  	Offset          uint64 `json:"offset"`          // The offset within the siafile requested for the download.
    62  	SiaPath         string `json:"siapath"`         // The siapath of the file used for the download.
    63  
    64  	Completed            bool      `json:"completed"`            // Whether or not the download has completed.
    65  	EndTime              time.Time `json:"endtime"`              // The time when the download fully completed.
    66  	Error                string    `json:"error"`                // Will be the empty string unless there was an error.
    67  	Received             uint64    `json:"received"`             // Amount of data confirmed and decoded.
    68  	StartTime            time.Time `json:"starttime"`            // The time when the download was started.
    69  	TotalDataTransferred uint64    `json:"totaldatatransferred"` // Total amount of data transferred, including negotiation, etc.
    70  }
    71  
    72  // FileUploadParams contains the information used by the Renter to upload a
    73  // file.
    74  type FileUploadParams struct {
    75  	Source      string
    76  	SiaPath     string
    77  	ErasureCode ErasureCoder
    78  }
    79  
    80  // FileInfo provides information about a file.
    81  type FileInfo struct {
    82  	SiaPath        string            `json:"siapath"`
    83  	LocalPath      string            `json:"localpath"`
    84  	Filesize       uint64            `json:"filesize"`
    85  	Available      bool              `json:"available"`
    86  	Renewing       bool              `json:"renewing"`
    87  	Redundancy     float64           `json:"redundancy"`
    88  	UploadedBytes  uint64            `json:"uploadedbytes"`
    89  	UploadProgress float64           `json:"uploadprogress"`
    90  	Expiration     types.BlockHeight `json:"expiration"`
    91  }
    92  
    93  // A HostDBEntry represents one host entry in the Renter's host DB. It
    94  // aggregates the host's external settings and metrics with its public key.
    95  type HostDBEntry struct {
    96  	HostExternalSettings
    97  
    98  	// FirstSeen is the last block height at which this host was announced.
    99  	FirstSeen types.BlockHeight `json:"firstseen"`
   100  
   101  	// Measurements that have been taken on the host. The most recent
   102  	// measurements are kept in full detail, historic ones are compressed into
   103  	// the historic values.
   104  	HistoricDowntime time.Duration `json:"historicdowntime"`
   105  	HistoricUptime   time.Duration `json:"historicuptime"`
   106  	ScanHistory      HostDBScans   `json:"scanhistory"`
   107  
   108  	HistoricFailedInteractions     float64 `json:"historicfailedinteractions"`
   109  	HistoricSuccessfulInteractions float64 `json:"historicsuccessfulinteractions"`
   110  	RecentFailedInteractions       float64 `json:"recentfailedinteractions"`
   111  	RecentSuccessfulInteractions   float64 `json:"recentsuccessfulinteractions"`
   112  
   113  	LastHistoricUpdate types.BlockHeight
   114  
   115  	// The public key of the host, stored separately to minimize risk of certain
   116  	// MitM based vulnerabilities.
   117  	PublicKey types.SiaPublicKey `json:"publickey"`
   118  }
   119  
   120  // HostDBScan represents a single scan event.
   121  type HostDBScan struct {
   122  	Timestamp time.Time `json:"timestamp"`
   123  	Success   bool      `json:"success"`
   124  }
   125  
   126  // HostScoreBreakdown provides a piece-by-piece explanation of why a host has
   127  // the score that they do.
   128  //
   129  // NOTE: Renters are free to use whatever scoring they feel appropriate for
   130  // hosts. Some renters will outright blacklist or whitelist sets of hosts. The
   131  // results provided by this struct can only be used as a guide, and may vary
   132  // significantly from machine to machine.
   133  type HostScoreBreakdown struct {
   134  	Score          types.Currency `json:"score"`
   135  	ConversionRate float64        `json:"conversionrate"`
   136  
   137  	AgeAdjustment              float64 `json:"ageadjustment"`
   138  	BurnAdjustment             float64 `json:"burnadjustment"`
   139  	CollateralAdjustment       float64 `json:"collateraladjustment"`
   140  	InteractionAdjustment      float64 `json:"interactionadjustment"`
   141  	PriceAdjustment            float64 `json:"pricesmultiplier"`
   142  	StorageRemainingAdjustment float64 `json:"storageremainingadjustment"`
   143  	UptimeAdjustment           float64 `json:"uptimeadjustment"`
   144  	VersionAdjustment          float64 `json:"versionadjustment"`
   145  }
   146  
   147  // RenterPriceEstimation contains a bunch of files estimating the costs of
   148  // various operations on the network.
   149  type RenterPriceEstimation struct {
   150  	// The cost of downloading 1 TB of data.
   151  	DownloadTerabyte types.Currency `json:"downloadterabyte"`
   152  
   153  	// The cost of forming a set of contracts using the defaults.
   154  	FormContracts types.Currency `json:"formcontracts"`
   155  
   156  	// The cost of storing 1 TB for a month, including redundancy.
   157  	StorageTerabyteMonth types.Currency `json:"storageterabytemonth"`
   158  
   159  	// The cost of consuming 1 TB of upload bandwidth from the host, including
   160  	// redundancy.
   161  	UploadTerabyte types.Currency `json:"uploadterabyte"`
   162  }
   163  
   164  // RenterSettings control the behavior of the Renter.
   165  type RenterSettings struct {
   166  	Allowance        Allowance `json:"allowance"`
   167  	MaxUploadSpeed   int64     `json:"maxuploadspeed"`
   168  	MaxDownloadSpeed int64     `json:"maxdownloadspeed"`
   169  }
   170  
   171  // HostDBScans represents a sortable slice of scans.
   172  type HostDBScans []HostDBScan
   173  
   174  func (s HostDBScans) Len() int           { return len(s) }
   175  func (s HostDBScans) Less(i, j int) bool { return s[i].Timestamp.Before(s[j].Timestamp) }
   176  func (s HostDBScans) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   177  
   178  // MerkleRootSet is a set of Merkle roots, and gets encoded more efficiently.
   179  type MerkleRootSet []crypto.Hash
   180  
   181  // MarshalJSON defines a JSON encoding for a MerkleRootSet.
   182  func (mrs MerkleRootSet) MarshalJSON() ([]byte, error) {
   183  	// Copy the whole array into a giant byte slice and then encode that.
   184  	fullBytes := make([]byte, crypto.HashSize*len(mrs))
   185  	for i := range mrs {
   186  		copy(fullBytes[i*crypto.HashSize:(i+1)*crypto.HashSize], mrs[i][:])
   187  	}
   188  	return json.Marshal(fullBytes)
   189  }
   190  
   191  // UnmarshalJSON attempts to decode a MerkleRootSet, falling back on the legacy
   192  // decoding of a []crypto.Hash if that fails.
   193  func (mrs *MerkleRootSet) UnmarshalJSON(b []byte) error {
   194  	// Decode the giant byte slice, and then split it into separate arrays.
   195  	var fullBytes []byte
   196  	err := json.Unmarshal(b, &fullBytes)
   197  	if err != nil {
   198  		// Encoding the byte slice has failed, try decoding it as a []crypto.Hash.
   199  		var hashes []crypto.Hash
   200  		err := json.Unmarshal(b, &hashes)
   201  		if err != nil {
   202  			return err
   203  		}
   204  		*mrs = MerkleRootSet(hashes)
   205  		return nil
   206  	}
   207  
   208  	umrs := make(MerkleRootSet, len(fullBytes)/32)
   209  	for i := range umrs {
   210  		copy(umrs[i][:], fullBytes[i*crypto.HashSize:(i+1)*crypto.HashSize])
   211  	}
   212  	*mrs = umrs
   213  	return nil
   214  }
   215  
   216  // A RenterContract contains metadata about a file contract. It is read-only;
   217  // modifying a RenterContract does not modify the actual file contract.
   218  type RenterContract struct {
   219  	ID            types.FileContractID
   220  	HostPublicKey types.SiaPublicKey
   221  	Transaction   types.Transaction
   222  
   223  	StartHeight types.BlockHeight
   224  	EndHeight   types.BlockHeight
   225  
   226  	// RenterFunds is the amount remaining in the contract that the renter can
   227  	// spend.
   228  	RenterFunds types.Currency
   229  
   230  	// The FileContract does not indicate what funds were spent on, so we have
   231  	// to track the various costs manually.
   232  	DownloadSpending types.Currency
   233  	StorageSpending  types.Currency
   234  	UploadSpending   types.Currency
   235  
   236  	// TotalCost indicates the amount of money that the renter spent and/or
   237  	// locked up while forming a contract. This includes fees, and includes
   238  	// funds which were allocated (but not necessarily committed) to spend on
   239  	// uploads/downloads/storage.
   240  	//
   241  	// ContractFee is the amount of money paid to the host to cover potential
   242  	// future transaction fees that the host may incur, and to cover any other
   243  	// overheads the host may have.
   244  	//
   245  	// TxnFee is the amount of money spent on the transaction fee when putting
   246  	// the renter contract on the blockchain.
   247  	//
   248  	// SiafundFee is the amount of money spent on siafund fees when creating the
   249  	// contract. The siafund fee that the renter pays covers both the renter and
   250  	// the host portions of the contract, and therefore can be unexpectedly high
   251  	// if the the host collateral is high.
   252  	TotalCost   types.Currency
   253  	ContractFee types.Currency
   254  	TxnFee      types.Currency
   255  	SiafundFee  types.Currency
   256  }
   257  
   258  // ContractorSpending contains the metrics about how much the Contractor has
   259  // spent during the current billing period.
   260  type ContractorSpending struct {
   261  	ContractSpending types.Currency `json:"contractspending"`
   262  	DownloadSpending types.Currency `json:"downloadspending"`
   263  	StorageSpending  types.Currency `json:"storagespending"`
   264  	UploadSpending   types.Currency `json:"uploadspending"`
   265  	Unspent          types.Currency `json:"unspent"`
   266  }
   267  
   268  // A Renter uploads, tracks, repairs, and downloads a set of files for the
   269  // user.
   270  type Renter interface {
   271  	// ActiveHosts provides the list of hosts that the renter is selecting,
   272  	// sorted by preference.
   273  	ActiveHosts() []HostDBEntry
   274  
   275  	// AllHosts returns the full list of hosts known to the renter.
   276  	AllHosts() []HostDBEntry
   277  
   278  	// Close closes the Renter.
   279  	Close() error
   280  
   281  	// Contracts returns the contracts formed by the renter.
   282  	Contracts() []RenterContract
   283  
   284  	// ContractUtility provides the contract utility for a given id
   285  	ContractUtility(id types.FileContractID) (ContractUtility, bool)
   286  
   287  	// CurrentPeriod returns the height at which the current allowance period
   288  	// began.
   289  	CurrentPeriod() types.BlockHeight
   290  
   291  	// PeriodSpending returns the amount spent on contracts in the current
   292  	// billing period.
   293  	PeriodSpending() ContractorSpending
   294  
   295  	// DeleteFile deletes a file entry from the renter.
   296  	DeleteFile(path string) error
   297  
   298  	// Download performs a download according to the parameters passed, including
   299  	// downloads of `offset` and `length` type.
   300  	Download(params RenterDownloadParameters) error
   301  
   302  	// DownloadHistory lists all the files that have been scheduled for download.
   303  	DownloadHistory() []DownloadInfo
   304  
   305  	// FileList returns information on all of the files stored by the renter.
   306  	FileList() []FileInfo
   307  
   308  	// Host provides the DB entry and score breakdown for the requested host.
   309  	Host(pk types.SiaPublicKey) (HostDBEntry, bool)
   310  
   311  	// LoadSharedFiles loads a '.sia' file into the renter. A .sia file may
   312  	// contain multiple files. The paths of the added files are returned.
   313  	LoadSharedFiles(source string) ([]string, error)
   314  
   315  	// LoadSharedFilesASCII loads an ASCII-encoded '.sia' file into the
   316  	// renter.
   317  	LoadSharedFilesASCII(asciiSia string) ([]string, error)
   318  
   319  	// PriceEstimation estimates the cost in siacoins of performing various
   320  	// storage and data operations.
   321  	PriceEstimation() RenterPriceEstimation
   322  
   323  	// RenameFile changes the path of a file.
   324  	RenameFile(path, newPath string) error
   325  
   326  	// EstimateHostScore will return the score for a host with the provided
   327  	// settings, assuming perfect age and uptime adjustments
   328  	EstimateHostScore(entry HostDBEntry) HostScoreBreakdown
   329  
   330  	// ScoreBreakdown will return the score for a host db entry using the
   331  	// hostdb's weighting algorithm.
   332  	ScoreBreakdown(entry HostDBEntry) HostScoreBreakdown
   333  
   334  	// Settings returns the Renter's current settings.
   335  	Settings() RenterSettings
   336  
   337  	// SetSettings sets the Renter's settings.
   338  	SetSettings(RenterSettings) error
   339  
   340  	// ShareFiles creates a '.sia' file that can be shared with others.
   341  	ShareFiles(paths []string, shareDest string) error
   342  
   343  	// ShareFilesAscii creates an ASCII-encoded '.sia' file.
   344  	ShareFilesASCII(paths []string) (asciiSia string, err error)
   345  
   346  	// Upload uploads a file using the input parameters.
   347  	Upload(FileUploadParams) error
   348  }
   349  
   350  // RenterDownloadParameters defines the parameters passed to the Renter's
   351  // Download method.
   352  type RenterDownloadParameters struct {
   353  	Async       bool
   354  	Httpwriter  io.Writer
   355  	Length      uint64
   356  	Offset      uint64
   357  	SiaPath     string
   358  	Destination string
   359  }