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  }