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 }