github.com/fozzysec/SiaPrime@v0.0.0-20190612043147-66c8e8d11fe3/modules/renter/contractor/persist.go (about) 1 package contractor 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "SiaPrime/modules" 8 "SiaPrime/modules/renter/proto" 9 "SiaPrime/persist" 10 "SiaPrime/types" 11 12 "gitlab.com/NebulousLabs/errors" 13 ) 14 15 // contractorPersist defines what Contractor data persists across sessions. 16 type contractorPersist struct { 17 Allowance modules.Allowance `json:"allowance"` 18 BlockHeight types.BlockHeight `json:"blockheight"` 19 CurrentPeriod types.BlockHeight `json:"currentperiod"` 20 LastChange modules.ConsensusChangeID `json:"lastchange"` 21 OldContracts []modules.RenterContract `json:"oldcontracts"` 22 RenewedFrom map[string]types.FileContractID `json:"renewedfrom"` 23 RenewedTo map[string]types.FileContractID `json:"renewedto"` 24 } 25 26 // persistData returns the data in the Contractor that will be saved to disk. 27 func (c *Contractor) persistData() contractorPersist { 28 data := contractorPersist{ 29 Allowance: c.allowance, 30 BlockHeight: c.blockHeight, 31 CurrentPeriod: c.currentPeriod, 32 LastChange: c.lastChange, 33 RenewedFrom: make(map[string]types.FileContractID), 34 RenewedTo: make(map[string]types.FileContractID), 35 } 36 for k, v := range c.renewedFrom { 37 data.RenewedFrom[k.String()] = v 38 } 39 for k, v := range c.renewedTo { 40 data.RenewedTo[k.String()] = v 41 } 42 for _, contract := range c.oldContracts { 43 data.OldContracts = append(data.OldContracts, contract) 44 } 45 return data 46 } 47 48 // load loads the Contractor persistence data from disk. 49 func (c *Contractor) load() error { 50 var data contractorPersist 51 err := c.persist.load(&data) 52 if err != nil { 53 return err 54 } 55 c.allowance = data.Allowance 56 c.blockHeight = data.BlockHeight 57 c.currentPeriod = data.CurrentPeriod 58 c.lastChange = data.LastChange 59 var fcid types.FileContractID 60 for k, v := range data.RenewedFrom { 61 if err := fcid.LoadString(k); err != nil { 62 return err 63 } 64 c.renewedFrom[fcid] = v 65 } 66 for k, v := range data.RenewedTo { 67 if err := fcid.LoadString(k); err != nil { 68 return err 69 } 70 c.renewedTo[fcid] = v 71 } 72 for _, contract := range data.OldContracts { 73 c.oldContracts[contract.ID] = contract 74 } 75 76 return nil 77 } 78 79 // save saves the Contractor persistence data to disk. 80 func (c *Contractor) save() error { 81 return c.persist.save(c.persistData()) 82 } 83 84 // saveSync saves the Contractor persistence data to disk and then syncs to disk. 85 func (c *Contractor) saveSync() error { 86 return c.persist.save(c.persistData()) 87 } 88 89 // convertPersist converts the pre-v1.3.1 contractor persist formats to the new 90 // formats. 91 func convertPersist(dir string) error { 92 // Try loading v1.3.1 persist. If it has the correct version number, no 93 // further action is necessary. 94 persistPath := filepath.Join(dir, "contractor.json") 95 err := persist.LoadJSON(persistMeta, nil, persistPath) 96 if err == nil { 97 return nil 98 } 99 100 // Try loading v1.3.0 persist (journal). 101 journalPath := filepath.Join(dir, "contractor.journal") 102 if _, err := os.Stat(journalPath); os.IsNotExist(err) { 103 // no journal file found; assume this is a fresh install 104 return nil 105 } 106 var p journalPersist 107 j, err := openJournal(journalPath, &p) 108 if err != nil { 109 return err 110 } 111 j.Close() 112 // convert to v1.3.1 format and save 113 data := contractorPersist{ 114 Allowance: p.Allowance, 115 BlockHeight: p.BlockHeight, 116 CurrentPeriod: p.CurrentPeriod, 117 LastChange: p.LastChange, 118 } 119 for _, c := range p.OldContracts { 120 data.OldContracts = append(data.OldContracts, modules.RenterContract{ 121 ID: c.ID, 122 HostPublicKey: c.HostPublicKey, 123 StartHeight: c.StartHeight, 124 EndHeight: c.EndHeight(), 125 RenterFunds: c.RenterFunds(), 126 DownloadSpending: c.DownloadSpending, 127 StorageSpending: c.StorageSpending, 128 UploadSpending: c.UploadSpending, 129 TotalCost: c.TotalCost, 130 ContractFee: c.ContractFee, 131 TxnFee: c.TxnFee, 132 SiafundFee: c.SiafundFee, 133 }) 134 } 135 err = persist.SaveJSON(persistMeta, data, persistPath) 136 if err != nil { 137 return err 138 } 139 140 // create the contracts directory if it does not yet exist 141 cs, err := proto.NewContractSet(filepath.Join(dir, "contracts"), modules.ProdDependencies) 142 if err != nil { 143 return err 144 } 145 defer cs.Close() 146 147 // convert contracts to contract files 148 for _, c := range p.Contracts { 149 cachedRev := p.CachedRevisions[c.ID.String()] 150 if err := cs.ConvertV130Contract(c, cachedRev); err != nil { 151 return err 152 } 153 } 154 155 // delete the journal file 156 return errors.AddContext(os.Remove(journalPath), "failed to remove journal file") 157 }