gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/contractor/README.md (about) 1 # Contractor 2 3 The Contractor is responsible for forming and renewing file contracts with 4 hosts. Its goal is to manage the low-level details of the negotiation, revision, 5 and renewal protocols, such that the renter can operate at a higher level of 6 abstraction. Ideally, the renter should be mostly ignorant of the Sia protocol, 7 instead focusing on file management, redundancy, and upload/download algorithms. 8 9 The Contractor is also responsible for various forms of contract maintenance 10 including contract recovery, utility checking, archiving, and monitoring its own 11 contracts using the watchdog subsystem. 12 13 ## Design Challenges 14 15 The primary challenge of the Contractor is that it must be smart enough for the 16 user to feel comfortable allowing it to spend their money. Because contract 17 renewal is a background task, it is difficult to report errors to the user and 18 defer to their decision. For example, what should the Contractor do in the 19 following scenarios? 20 21 - The contract set is up for renewal, but the average host price has increased, 22 and now the allowance is not sufficient to cover all of the user's uploaded 23 data. 24 25 - The user sets an allowance of 10 hosts. The Contractor forms 5 contracts, but 26 the rest fail, and the remaining hosts in the HostDB are too expensive. 27 28 - After contract formation succeeds, 2 of 10 hosts become unresponsive. Later, 29 another 4 become unresponsive. 30 31 Waiting for user input is dangerous because if the contract period elapses, data 32 is permanently lost. The Contractor should treat this as the worst-case 33 scenario, and take steps to prevent it, so long as the allowance is not 34 exceeded. However, since the Contractor has no concept of redundancy, it is not 35 well-positioned to determine which sectors to sacrifice and which to preserve. 36 The Contractor also lacks the ability to reupload data; it can download sectors, 37 but it does not know the decryption keys or erasure coding metadata required to 38 reconstruct the original data. It follows that these responsibilities must be 39 delegated to the renter. 40 41 ## Alerts 42 43 `WalletLockedDuringMaintenance` is registered if the wallet is locked while the 44 contractor is attempting to create contracts. 45 46 `AllowanceLowFunds` is registered if the contractor lacks the necessary fund to 47 renew or form contracts. 48 49 ## TODOs 50 * [ ] (watchdog) Perform action when storage proof is found and when missing at the end of the window. 51 * [ ] (watchdog) Add renter dependencies in `sweepContractInputs` if necessary. 52 53 54 ## Subsystems 55 The Contractor is split up into the following subsystems: 56 - [Allowance](#allowance-subsystem) 57 - [Contract Maintenance Subsystem](#contract-maintenance-subsystem) 58 - [Churn Limiter Subsystem](#churn-limiter-subsystem) 59 - [Recovery Subsystem](#recovery-subsystem) 60 - [Session Subsystem](#session-subsystem) 61 - [Persistence Subsystem](#persistence-subsystem) 62 - [Watchdog Subsystem](#watchdog-subsystem) 63 64 65 ## Allowance Subsystem 66 **Key Files** 67 - [Allowance](./allowance.go) 68 69 The allowance subsystem is used for setting and cancelling allowances. A change 70 in allowance does not necessarily cause changes in contract formation. 71 72 ### Exports 73 - `SetAllowance` is exported by the `Contractor` and allows the caller to 74 dictate the contract spendings of the `Renter`. 75 76 ### Outbound Complexities 77 - `callInterruptContractMaintenance` is used when setting the allowance to 78 stop and restart contract maintenance with the new allowance settings in 79 place. 80 81 82 ## Contract Maintenance Subsystem 83 **Key Files** 84 - [contractmaintenance.go](./contractmaintenance.go) 85 86 The contract maintenance subsystem is responsible for forming and renewing 87 contracts, and for other general maintenance tasks. 88 89 ### Contract Formation 90 91 Contract formation does not begin until the user first calls `SetAllowance`. An 92 allowance dictates how much money the Contractor is allowed to spend on file 93 contracts during a given period. When the user calls `SetAllowance` the 94 [Allowance subsystem](#allowance-subsytem) updates the allowance and restarts the 95 Maintenance subsystem so that it will form new contracts with the changed 96 settings. New contracts will only be formed if needed and if the allowance is 97 sufficiently greater than the previous allowance, where "sufficiently greater" 98 currently means "enough money to pay for at least one additional sector on every 99 host." This allows the user to increase the amount of available storage 100 immediately, at the cost of some complexity. 101 102 The Contractor forms many contracts in parallel with different host, and tries 103 to keep all the contracts "consistent" -- that is, they should all have the same 104 storage capacity, and they should all end at the same height. Hosts are selected 105 from the HostDB. There is no support for manually specifying hosts, but the 106 Contractor will not form contracts with multiple hosts within the same subnet. 107 108 **Contract Renewal** 109 110 Contracts are automatically renewed by the Contractor at a safe threshold before 111 they are set to expire. This value is set in the allowance. When contracts are 112 renewed, they are renewed with the current allowance, which may differ from the 113 allowance that was used to form the initial contracts. In general, this means 114 that allowance modifications only take effect upon the next "contract cycle". 115 116 ### Other Maintenance Checks 117 118 - Check the contract set for **duplicate contracts** and remove them. 119 - **Prune hosts** that are no longer used for any contracts and hosts that violate rules about address ranges 120 - **Check the utility of opened contracts** by figuring out which contracts are still useful for uploading or for renewing 121 - **Archive contracts** which have expired by placing them in a historic contract set. 122 123 ### Inbound Complexities 124 - `threadedContractMaintenance` is called by the 125 [Allowance subsystem](#allowance-subsystem) when setting allowances, when `CancelContract` 126 is called from the `Contractor`, and also with every `ConsensusChange` by the 127 `Contractor` in the `ProcessConsensusChange` when the `Contractor` is synced. 128 - `callInterruptContractMaintenance` is used by [Allowance 129 subsystem](#allowance-subsystem) when setting the allowance to 130 stop and restart contract maintenance with the new allowance settings in 131 place. 132 - `callNotifyDoubleSpend` is a Contract Maintenance call used by the watchdog to 133 indicate that a contract is double-spent and triggers actions from the 134 Contractor. 135 136 ### Outbound Complexities 137 - `callInitRecoveryScan` in the [Recovery subsystem](#recovery-subsystem) is 138 called to scan blocks for recoverable contracts. 139 - `save` is called to persist the contractor whenever the `Contractor's` state 140 is updated during maintenance. 141 - Funds established by the [Allowance subsystem](#allowance-subsystem) are used 142 and deducted appropriately during maintenance to form and renew contracts. 143 - `callNotifyChurnedContract` is used when a contract utility changes from GFR 144 to !GFR. 145 - `threadedSendMostRecentRevision` in the [Watchdog subsystem](#watchdog-subsystem) 146 is called when a contract is renewed and no new revisions are expected. 147 148 149 ## Churn Limiter Subsystem 150 **Key Files** 151 - [churnlimiter.go](./churnlimiter.go) 152 153 The Churn Limiter is responsible for decreasing contract churn. It keeps track 154 of the aggregate size of all contracts churned in the current period. Churn is 155 limited by keeping contracts with low-scoring hosts around if the maximum 156 aggregate for the period has been reached. 157 158 ### Exports 159 - `SetMaxPeriodChurn` is exported by the `Contractor` and allows the caller 160 to set the maximum allowed churn in bytes per period. 161 162 ### Inbound Complexities 163 - `callNotifyChurnedContract` is used when contracts are marked GFR after 164 previously being !GFR. 165 - `callBumpChurnBudget` is used to increase the churn budget when new blocks 166 are processed. 167 - `callResetAggregateChurn` resets the aggregate churn and is called every 168 time the contractor enters a new period. 169 - `callPersistData` is called whenever the contractor's `persistData` is 170 called. 171 172 173 ## Recovery Subsystem 174 **Key Files** 175 - [recovery.go](./recovery.go) 176 177 The Contractor is also responsible for scanning the Sia blockchain and 178 recovering all unexpired contracts which belong to the current wallet seed. The 179 relevant contracts are found by examining the contract identifier attached to 180 every file contract. Recovery scans are initiated whenever the wallet is 181 unlocked or when a new seed is imported. 182 183 A recoverable contract is recovered by reinitiating a session with the relevant 184 host and by getting the most recent revision from the host using this session. 185 186 ### Inbound Complexities 187 - `callInitRecoveryScan` is called in the [Maintenance 188 subsystem](#contract-maintenance-subsystem) to initiate recovery scans. 189 - `callRecoverContracts` is called in the [Maintenance 190 subsystem](#contract-maintenance-subsystem) to recover contracts found in a 191 recovery scan. 192 193 194 ## Session Subsystem 195 **Key Files** 196 - [session.go](./session.go) 197 - [downloader.go](./downloader.go) 198 - [editor.go](./editor.go) 199 200 The Session subsystem provides an interface for communication with hosts. It 201 allows the contractor to modify its contracts through the renter-host protocol. 202 Sessions are used to initiate uploads, downloads, and file modifications. This 203 subsystem exports several methods used outside of the `Contractor` for this 204 purpose. 205 206 The session subsystem will watch out for certain host behaviors that indicate 207 the host is permanently unusable. If this happens, the session subsystem will 208 call 'MarkBadContract', which will prevent the contract from being considered a 209 part of the usable contracts, and allow the repair process to happen. 210 211 Pre-v1.4.0 contracts using an older version of the renter-host protocol use the 212 Editor and Downloader interfaces to interact with hosts. 213 214 ### Pre-v1.4.0 Contract Modification 215 216 Modifications to file contracts are mediated through the Editor interface. An 217 Editor maintains a network connection to a host, over which is sends 218 modification requests, such as "delete sector 12." After each modification, the 219 Editor revises the underlying file contract and saves it to disk. 220 221 ### Exports 222 The following `Session` methods are all exported by the Contractor: 223 - `Address` 224 - `Close` 225 - `ContractID` 226 - `Download` 227 - `DownloadIndex` 228 - `EndHeight` 229 - `Upload` 230 - `Replace` 231 232 233 ## Persistence Subsystem 234 **Key Files** 235 - [persist.go](./persist.go) 236 - [persist\_journal.go](./persist_journal.go) 237 238 239 The Persistence subsystem is used to persist Contractor data across sessions. 240 Currently it uses the Sia persist package. Prior to v1.3.0 the persistence 241 subsystem used a journal system which is no longer used. If, on startup, this 242 old journal system is found, the Contractor will convert it into the new 243 Persistence subsystem. 244 245 ### Inbound Complexities 246 - `save` is called from the [Allowance](#allowance-subsystem), and 247 [Maintenance](#contract-maintenance-subsystem) subsystems to persist the 248 `Contractor` when its internal state is updated. 249 250 ### Outbound Complexities 251 The persist system is also responsible for persisting the [Watchdog 252 subsystem](#watchdog-subsystem). 253 254 255 ## Watchdog Subsystem 256 **Key Files** 257 - [watchdog.go](./watchdog.go) 258 - [watchdog\_persist.go](./watchdog\_persist.go) 259 260 The watchdog is responsible for monitoring the blockchain for file contracts, 261 revisions, and storage proofs that are relevant to the contractor. 262 263 To scan for revisions, the watchdog is used during the Contractor's 264 `ProcessConsensusChange` method and during the recovery subsystem's 265 `ProcessConsensusChange` method. 266 267 When processing a newly added block the watchdog checks if any contracts, 268 revision, or storage proofs for a monitored contract have appeared on-chain. For 269 file contracts being monitored that haven't yet appeared on-chain, the watchdog 270 also monitors all the parent Siacoin outputs used in the creation of the 271 contract. It will update the dependency set of that contract as blocks are added 272 and reverted. If a contract's inputs are ever double-spent, the watchdog 273 notifies the Contractor. The Contractor returns the contract's funds to the 274 allowance, and marks the contract as `!GoodForUpload` and `!GoodForRenew`, 275 276 The watchdog will also check if any monitored contracts revisions or storage 277 proofs were removed in a reverted blocks and marks them as such. Note that once 278 a the storage proof window for a file contract elapses for the first time, the 279 watchdog will no longer monitor that contract. This is acceptable because even 280 if the storage proof is reorged out, the host has at least proven they fulfilled 281 their storage obligation once. It is up to the host to re-post storage proofs 282 if they are reorged out, if they want to claim valid proof outputs afterwards. 283 284 When the watchdog is synced to the `consensusset` it will do all of its checks 285 on monitored contracts in `managedCheckContracts`. It waits until being synced, 286 rather than taking action in the middle of a `ProcessConsensusChange` call to 287 avoid taking actions that would be prevented if e.g. the next block in a 288 `ConsensusChange` was checked. For example, a formation transaction may be 289 reverted and re-applied in the same consensus change. In this case, the watchdog 290 should not take any actions. 291 292 The watchdog does the following checks on monitored contracts. 293 - check that monitored file contract formation transaction sets appeared 294 on-chain in the expected number of blocks. 295 - re-send the transaction set if not, and double-spend the inputs used with the 296 set if much more time has elapsed. 297 - check if any monitored contracts should have a more recent revision on-chain 298 already. If not, the watchdog will send the latest revision transaction out. 299 - Check if storage proofs for a contract were found at the end of the expiration 300 window 301 302 ## Inbound Complexities 303 - `threadedSendMostRecentRevision` is called in a go-routine from the Contract 304 Maintenance subsystem when a contract is renewed and no new revisions are 305 expected. 306 - `callMonitorContract` is called from the Contract Maintenance and Recovery 307 subsystems whenever contracts are formed, renewed, or recovered. 308 - `callScanConsensusChange`is used in the `ProcessConsensusChange` method of the 309 contractor to let the watchdog scan blocks. 310 - `callPersistData` is called whenever the contractor's `persistData` is 311 called. 312 313 ## Outbound Complexities 314 - `callNotifyDoubleSpend` is a Contract Maintenance call used by the watchdog to 315 indicate that a contract is double-spent and triggers actions from the 316 Contractor. 317 318 ## State Complexities 319 All state updates from the watchdog are driven by changes observed in 320 `ProcessConsensusChange` and from contract formation and renewal which cause a 321 file contract to be monitored. Therefore, the watchdog persist needs to be 322 synced with the most recent consensus change. 323 324 ## Why The Watchdog Should Sweep Renter Inputs 325 326 If the watchdog fails to find a monitored file contract on-chain before its 327 `formationSweepHeight` the watchdog will sweep the inputs used by the renter to 328 create the file contract. This action must take place to prevent the renter from 329 overspending its allowance. 330 331 If the contractor were to simply create new contracts while other contracts were 332 still unconfirmed, it would be possible to overspend the set allowance. When the 333 watchdog sweeps its inputs successfully, the contract will be marked as 334 double-spent in which case the allowance funds are returned for further use.