github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/modules/renter/contractor/update.go (about) 1 package contractor 2 3 import ( 4 "github.com/Synthesix/Sia/modules" 5 "github.com/Synthesix/Sia/types" 6 ) 7 8 // managedArchiveContracts will figure out which contracts are no longer needed 9 // and move them to the historic set of contracts. 10 // 11 // TODO: This function should be performed by threadedContractMaintenance. 12 // threadedContractMaintenance will currently quit if there are no hosts, but it 13 // should at least run this code before quitting. 14 func (c *Contractor) managedArchiveContracts() { 15 err := c.tg.Add() 16 if err != nil { 17 return 18 } 19 defer c.tg.Done() 20 21 // Determine the current block height. 22 c.mu.RLock() 23 currentHeight := c.blockHeight 24 c.mu.RUnlock() 25 26 // Loop through the current set of contracts and migrate any expired ones to 27 // the set of old contracts. 28 var expired []types.FileContractID 29 for _, contract := range c.contracts.ViewAll() { 30 if currentHeight > contract.EndHeight { 31 id := contract.ID 32 c.mu.Lock() 33 c.oldContracts[id] = contract 34 c.mu.Unlock() 35 expired = append(expired, id) 36 c.log.Println("INFO: archived expired contract", id) 37 } 38 } 39 40 // Save. 41 c.mu.Lock() 42 c.save() 43 c.mu.Unlock() 44 45 // Delete all the expired contracts from the contract set. 46 for _, id := range expired { 47 if sc, ok := c.contracts.Acquire(id); ok { 48 c.contracts.Delete(sc) 49 } 50 } 51 } 52 53 // ProcessConsensusChange will be called by the consensus set every time there 54 // is a change in the blockchain. Updates will always be called in order. 55 func (c *Contractor) ProcessConsensusChange(cc modules.ConsensusChange) { 56 c.mu.Lock() 57 for _, block := range cc.RevertedBlocks { 58 if block.ID() != types.GenesisID { 59 c.blockHeight-- 60 } 61 } 62 for _, block := range cc.AppliedBlocks { 63 if block.ID() != types.GenesisID { 64 c.blockHeight++ 65 } 66 } 67 68 // If we have entered the next period, update currentPeriod 69 // NOTE: "period" refers to the duration of contracts, whereas "cycle" 70 // refers to how frequently the period metrics are reset. 71 // TODO: How to make this more explicit. 72 cycleLen := c.allowance.Period - c.allowance.RenewWindow 73 if c.blockHeight >= c.currentPeriod+cycleLen { 74 c.currentPeriod += cycleLen 75 // COMPATv1.0.4-lts 76 // if we were storing a special metrics contract, it will be invalid 77 // after we enter the next period. 78 delete(c.oldContracts, metricsContractID) 79 } 80 81 c.lastChange = cc.ID 82 err := c.save() 83 if err != nil { 84 c.log.Println("Unable to save while processing a consensus change:", err) 85 } 86 c.mu.Unlock() 87 88 // Perform contract maintenance if our blockchain is synced. Use a separate 89 // goroutine so that the rest of the contractor is not blocked during 90 // maintenance. 91 if cc.Synced { 92 go c.threadedContractMaintenance() 93 go c.managedArchiveContracts() 94 } 95 }