github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/types/filecontracts.go (about)

     1  package types
     2  
     3  // filecontracts.go contains the basic structs and helper functions for file
     4  // contracts.
     5  
     6  import (
     7  	"github.com/NebulousLabs/Sia/build"
     8  	"github.com/NebulousLabs/Sia/crypto"
     9  )
    10  
    11  var (
    12  	ProofValid  ProofStatus = true
    13  	ProofMissed ProofStatus = false
    14  )
    15  
    16  type (
    17  	// A FileContract is a public record of a storage agreement between a "host"
    18  	// and a "renter." It mandates that a host must submit a storage proof to the
    19  	// network, proving that they still possess the file they have agreed to
    20  	// store.
    21  	//
    22  	// The party must submit the storage proof in a block that is between
    23  	// 'WindowStart' and 'WindowEnd'. Upon submitting the proof, the outputs
    24  	// for 'ValidProofOutputs' are created. If the party does not submit a
    25  	// storage proof by 'WindowEnd', then the outputs for 'MissedProofOutputs'
    26  	// are created instead. The sum of 'MissedProofOutputs' must equal
    27  	// 'Payout', and the sum of 'ValidProofOutputs' must equal 'Payout' plus
    28  	// the siafund fee.  This fee is sent to the siafund pool, which is a set
    29  	// of siacoins only spendable by siafund owners.
    30  	//
    31  	// Under normal circumstances, the payout will be funded by both the host and
    32  	// the renter, which gives the host incentive not to lose the file. The
    33  	// 'ValidProofUnlockHash' will typically be spendable by host, and the
    34  	// 'MissedProofUnlockHash' will either by spendable by the renter or by
    35  	// nobody (the ZeroUnlockHash).
    36  	//
    37  	// A contract can be terminated early by submitting a FileContractTermination
    38  	// whose UnlockConditions hash to 'TerminationHash'.
    39  	FileContract struct {
    40  		FileSize           uint64          `json:"filesize"`
    41  		FileMerkleRoot     crypto.Hash     `json:"filemerkleroot"`
    42  		WindowStart        BlockHeight     `json:"windowstart"`
    43  		WindowEnd          BlockHeight     `json:"windowend"`
    44  		Payout             Currency        `json:"payout"`
    45  		ValidProofOutputs  []SiacoinOutput `json:"validproofoutputs"`
    46  		MissedProofOutputs []SiacoinOutput `json:"missedproofoutputs"`
    47  		UnlockHash         UnlockHash      `json:"unlockhash"`
    48  		RevisionNumber     uint64          `json:"revisionnumber"`
    49  	}
    50  
    51  	// A FileContractRevision revises an existing file contract. The ParentID
    52  	// points to the file contract that is being revised. The UnlockConditions
    53  	// are the conditions under which the revision is valid, and must match the
    54  	// UnlockHash of the parent file contract. The Payout of the file contract
    55  	// cannot be changed, but all other fields are allowed to be changed. The
    56  	// sum of the outputs must match the original payout (taking into account
    57  	// the fee for the proof payouts.) A revision number is included. When
    58  	// getting accepted, the revision number of the revision must be higher
    59  	// than any previously seen revision number for that file contract.
    60  	//
    61  	// FileContractRevisions enable trust-free modifications to existing file
    62  	// contracts.
    63  	FileContractRevision struct {
    64  		ParentID          FileContractID   `json:"parentid"`
    65  		UnlockConditions  UnlockConditions `json:"unlockconditions"`
    66  		NewRevisionNumber uint64           `json:"newrevisionnumber"`
    67  
    68  		NewFileSize           uint64          `json:"newfilesize"`
    69  		NewFileMerkleRoot     crypto.Hash     `json:"newfilemerkleroot"`
    70  		NewWindowStart        BlockHeight     `json:"newwindowstart"`
    71  		NewWindowEnd          BlockHeight     `json:"newwindowend"`
    72  		NewValidProofOutputs  []SiacoinOutput `json:"newvalidproofoutputs"`
    73  		NewMissedProofOutputs []SiacoinOutput `json:"newmissedproofoutputs"`
    74  		NewUnlockHash         UnlockHash      `json:"newunlockhash"`
    75  	}
    76  
    77  	// A StorageProof fulfills a FileContract. The proof contains a specific
    78  	// segment of the file, along with a set of hashes from the file's Merkle
    79  	// tree. In combination, these can be used to prove that the segment came
    80  	// from the file. To prevent abuse, the segment must be chosen randomly, so
    81  	// the ID of block 'WindowStart' - 1 is used as a seed value; see
    82  	// StorageProofSegment for the exact implementation.
    83  	//
    84  	// A transaction with a StorageProof cannot have any SiacoinOutputs,
    85  	// SiafundOutputs, or FileContracts. This is because a mundane reorg can
    86  	// invalidate the proof, and with it the rest of the transaction.
    87  	StorageProof struct {
    88  		ParentID FileContractID           `json:"parentid"`
    89  		Segment  [crypto.SegmentSize]byte `json:"segment"`
    90  		HashSet  []crypto.Hash            `json:"hashset"`
    91  	}
    92  
    93  	ProofStatus bool
    94  )
    95  
    96  // StorageProofOutputID returns the ID of an output created by a file
    97  // contract, given the status of the storage proof. The ID is calculating by
    98  // hashing the concatenation of the StorageProofOutput Specifier, the ID of
    99  // the file contract that the proof is for, a boolean indicating whether the
   100  // proof was valid (true) or missed (false), and the index of the output
   101  // within the file contract.
   102  func (fcid FileContractID) StorageProofOutputID(proofStatus ProofStatus, i uint64) SiacoinOutputID {
   103  	return SiacoinOutputID(crypto.HashAll(
   104  		SpecifierStorageProofOutput,
   105  		fcid,
   106  		proofStatus,
   107  		i,
   108  	))
   109  }
   110  
   111  // PostTax returns the amount of currency remaining in a file contract payout
   112  // after tax.
   113  func PostTax(height BlockHeight, payout Currency) Currency {
   114  	return payout.Sub(Tax(height, payout))
   115  }
   116  
   117  // Tax returns the amount of Currency that will be taxed from fc.
   118  func Tax(height BlockHeight, payout Currency) Currency {
   119  	// COMPATv0.4.0 - until the first 20,000 blocks have been archived, they
   120  	// will need to be handled in a special way.
   121  	if (height < 21e3 && build.Release == "standard") || (height < 10 && build.Release == "testing") {
   122  		return payout.MulFloat(0.039).RoundDown(SiafundCount)
   123  	}
   124  	return payout.MulTax().RoundDown(SiafundCount)
   125  }