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  }