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