gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/proto/contractpersist_compat.go (about) 1 package proto 2 3 import ( 4 "io" 5 6 "gitlab.com/NebulousLabs/errors" 7 8 "gitlab.com/NebulousLabs/encoding" 9 "gitlab.com/SkynetLabs/skyd/skymodules" 10 "go.sia.tech/siad/crypto" 11 "go.sia.tech/siad/types" 12 ) 13 14 // v132UpdateHeader was introduced due to backwards compatibility reasons after 15 // changing the format of the contractHeader. It contains the legacy 16 // v132ContractHeader. 17 type v132UpdateSetHeader struct { 18 ID types.FileContractID 19 Header v132ContractHeader 20 } 21 22 // v160UpdateHeader was introduced due to backwards compatibility reasons after 23 // changing the format of the contractHeader. It contains the legacy 24 // v1420ContractHeader. 25 type v160UpdateSetHeader struct { 26 ID types.FileContractID 27 Header v1420ContractHeader 28 } 29 30 // v132ContractHeader is a contractHeader without the Utility field. This field 31 // was added after v132 to be able to persist contract utilities. 32 type v132ContractHeader struct { 33 // transaction is the signed transaction containing the most recent 34 // revision of the file contract. 35 Transaction types.Transaction 36 37 // secretKey is the key used by the renter to sign the file contract 38 // transaction. 39 SecretKey crypto.SecretKey 40 41 // Same as skymodules.RenterContract. 42 StartHeight types.BlockHeight 43 DownloadSpending types.Currency 44 StorageSpending types.Currency 45 UploadSpending types.Currency 46 TotalCost types.Currency 47 ContractFee types.Currency 48 TxnFee types.Currency 49 SiafundFee types.Currency 50 } 51 52 // v1412ContractHeader is the contract header that was used up to and including 53 // v1.4.1.2 54 type v1412ContractHeader struct { 55 // transaction is the signed transaction containing the most recent 56 // revision of the file contract. 57 Transaction types.Transaction 58 59 // secretKey is the key used by the renter to sign the file contract 60 // transaction. 61 SecretKey crypto.SecretKey 62 63 // Same as skymodules.RenterContract. 64 StartHeight types.BlockHeight 65 DownloadSpending types.Currency 66 StorageSpending types.Currency 67 UploadSpending types.Currency 68 TotalCost types.Currency 69 ContractFee types.Currency 70 TxnFee types.Currency 71 SiafundFee types.Currency 72 73 GoodForUpload bool 74 GoodForRenew bool 75 LastOOSErr types.BlockHeight 76 Locked bool 77 } 78 79 // v1420ContractUtility is the contract utility that was used up to and including 80 // v1.6.0. 81 type v1420ContractUtility struct { 82 GoodForUpload bool `json:"goodforupload"` 83 GoodForRenew bool `json:"goodforrenew"` 84 85 // BadContract will be set to true if there's good reason to believe that 86 // the contract is unusable and will continue to be unusable. For example, 87 // if the host is claiming that the contract does not exist, the contract 88 // should be marked as bad. 89 BadContract bool `json:"badcontract"` 90 LastOOSErr types.BlockHeight `json:"lastooserr"` // OOS means Out Of Storage 91 92 // If a contract is locked, the utility should not be updated. 'Locked' is a 93 // value that gets persisted. 94 Locked bool `json:"locked"` 95 } 96 97 // v1420ContractHeader is the contract header that was used up to and including 98 // v1.4.2. 99 type v1420ContractHeader struct { 100 // transaction is the signed transaction containing the most recent 101 // revision of the file contract. 102 Transaction types.Transaction 103 104 // secretKey is the key used by the renter to sign the file contract 105 // transaction. 106 SecretKey crypto.SecretKey 107 108 // Same as skymodules.RenterContract. 109 StartHeight types.BlockHeight 110 DownloadSpending types.Currency 111 FundAccountSpending types.Currency 112 MaintenanceSpending skymodules.MaintenanceSpending 113 StorageSpending types.Currency 114 UploadSpending types.Currency 115 TotalCost types.Currency 116 ContractFee types.Currency 117 TxnFee types.Currency 118 SiafundFee types.Currency 119 Utility v1420ContractUtility 120 } 121 122 // contractHeaderDecodeV1412ToV160 attempts to decode a contract header using 123 // the persist struct as of v1.4.1.2, returning a header that has been converted 124 // to the v1.6.0 version of the header. 125 func contractHeaderDecodeV1412ToV160(f io.ReadSeeker, decodeMaxSize int) (contractHeader, error) { 126 _, err := f.Seek(0, 0) 127 if err != nil { 128 return contractHeader{}, errors.AddContext(err, "unable to reset file when attempting legacy decode") 129 } 130 var v1412Header v1412ContractHeader 131 err = encoding.NewDecoder(f, decodeMaxSize).Decode(&v1412Header) 132 if err != nil { 133 return contractHeader{}, errors.AddContext(err, "unable to decode header as a v1412 header") 134 } 135 136 return contractHeader{ 137 Transaction: v1412Header.Transaction, 138 139 SecretKey: v1412Header.SecretKey, 140 141 StartHeight: v1412Header.StartHeight, 142 DownloadSpending: v1412Header.DownloadSpending, 143 StorageSpending: v1412Header.StorageSpending, 144 UploadSpending: v1412Header.UploadSpending, 145 TotalCost: v1412Header.TotalCost, 146 ContractFee: v1412Header.ContractFee, 147 TxnFee: v1412Header.TxnFee, 148 SiafundFee: v1412Header.SiafundFee, 149 150 Utility: skymodules.ContractUtility{ 151 GoodForUpload: v1412Header.GoodForUpload, 152 GoodForRenew: v1412Header.GoodForRenew, 153 BadContract: false, 154 LastOOSErr: v1412Header.LastOOSErr, 155 Locked: v1412Header.Locked, 156 }, 157 }, nil 158 } 159 160 // contractHeaderDecodeV1412ToV1420 attempts to decode a contract header using 161 // the persist struct as of v1.4.1.2, returning a header that has been converted 162 // to the v1.4.2 version of the header. 163 func contractHeaderDecodeV1420ToV160(f io.ReadSeeker, decodeMaxSize int) (contractHeader, error) { 164 _, err := f.Seek(0, 0) 165 if err != nil { 166 return contractHeader{}, errors.AddContext(err, "unable to reset file when attempting legacy decode") 167 } 168 var v160Header v1420ContractHeader 169 err = encoding.NewDecoder(f, decodeMaxSize).Decode(&v160Header) 170 if err != nil { 171 return contractHeader{}, errors.AddContext(err, "unable to decode header as a v1412 header") 172 } 173 174 return contractHeader{ 175 Transaction: v160Header.Transaction, 176 177 SecretKey: v160Header.SecretKey, 178 179 StartHeight: v160Header.StartHeight, 180 DownloadSpending: v160Header.DownloadSpending, 181 StorageSpending: v160Header.StorageSpending, 182 UploadSpending: v160Header.UploadSpending, 183 TotalCost: v160Header.TotalCost, 184 ContractFee: v160Header.ContractFee, 185 TxnFee: v160Header.TxnFee, 186 SiafundFee: v160Header.SiafundFee, 187 188 Utility: skymodules.ContractUtility{ 189 GoodForUpload: v160Header.Utility.GoodForUpload, 190 GoodForRefresh: v160Header.Utility.GoodForRenew, // set it to the same as GoodForRenew 191 GoodForRenew: v160Header.Utility.GoodForRenew, 192 BadContract: v160Header.Utility.BadContract, 193 LastOOSErr: v160Header.Utility.LastOOSErr, 194 Locked: v160Header.Utility.Locked, 195 }, 196 }, nil 197 } 198 199 // updateSetHeaderUnmarshalV132ToV160 attempts to unmarshal an update set header 200 // using the v1.3.2 encoding scheme, returning a v1.6.0 version of the update 201 // set header. 202 func updateSetHeaderUnmarshalV132ToV160(b []byte, u *updateSetHeader) error { 203 var oldHeader v132UpdateSetHeader 204 if err := encoding.Unmarshal(b, &oldHeader); err != nil { 205 // If unmarshaling the header the old way also doesn't work we 206 // return the original error. 207 return errors.AddContext(err, "could not unmarshal update into v1.3.2 format") 208 } 209 // If unmarshaling it the old way was successful we convert it to a new 210 // header. 211 u.Header = contractHeader{ 212 Transaction: oldHeader.Header.Transaction, 213 SecretKey: oldHeader.Header.SecretKey, 214 StartHeight: oldHeader.Header.StartHeight, 215 DownloadSpending: oldHeader.Header.DownloadSpending, 216 StorageSpending: oldHeader.Header.StorageSpending, 217 UploadSpending: oldHeader.Header.UploadSpending, 218 TotalCost: oldHeader.Header.TotalCost, 219 ContractFee: oldHeader.Header.ContractFee, 220 TxnFee: oldHeader.Header.TxnFee, 221 SiafundFee: oldHeader.Header.SiafundFee, 222 } 223 return nil 224 } 225 226 // updateSetHeaderUnmarshalV1420ToV160 attempts to unmarshal an update set 227 // header using the v1.3.2 encoding scheme, returning a v1.4.2 version of the 228 // update set header. 229 func updateSetHeaderUnmarshalV1420ToV160(b []byte, u *updateSetHeader) error { 230 var oldHeader v160UpdateSetHeader 231 if err := encoding.Unmarshal(b, &oldHeader); err != nil { 232 // If unmarshaling the header the old way also doesn't work we 233 // return the original error. 234 return errors.AddContext(err, "could not unmarshal update into v1.6.0 format") 235 } 236 // If unmarshaling it the old way was successful we convert it to a new 237 // header. 238 u.Header = contractHeader{ 239 Transaction: oldHeader.Header.Transaction, 240 SecretKey: oldHeader.Header.SecretKey, 241 StartHeight: oldHeader.Header.StartHeight, 242 DownloadSpending: oldHeader.Header.DownloadSpending, 243 FundAccountSpending: oldHeader.Header.FundAccountSpending, 244 MaintenanceSpending: oldHeader.Header.MaintenanceSpending, 245 StorageSpending: oldHeader.Header.StorageSpending, 246 UploadSpending: oldHeader.Header.UploadSpending, 247 TotalCost: oldHeader.Header.TotalCost, 248 ContractFee: oldHeader.Header.ContractFee, 249 TxnFee: oldHeader.Header.TxnFee, 250 SiafundFee: oldHeader.Header.SiafundFee, 251 Utility: skymodules.ContractUtility{ 252 GoodForUpload: oldHeader.Header.Utility.GoodForUpload, 253 GoodForRefresh: oldHeader.Header.Utility.GoodForRenew, // set it to the same as GoodForRenew 254 GoodForRenew: oldHeader.Header.Utility.GoodForRenew, 255 BadContract: oldHeader.Header.Utility.BadContract, 256 LastOOSErr: oldHeader.Header.Utility.LastOOSErr, 257 Locked: oldHeader.Header.Utility.Locked, 258 }, 259 } 260 return nil 261 }