gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/contractor/watchdog_persist.go (about)

     1  package contractor
     2  
     3  import (
     4  	"errors"
     5  
     6  	"gitlab.com/SkynetLabs/skyd/skymodules"
     7  	"go.sia.tech/siad/types"
     8  )
     9  
    10  // watchdogPersist defines what watchdog data persists across sessions.
    11  type watchdogPersist struct {
    12  	Contracts         map[string]fileContractStatusPersist      `json:"contracts"`
    13  	ArchivedContracts map[string]skymodules.ContractWatchStatus `json:"archivedcontracts"`
    14  }
    15  
    16  // fileContractStatusPersist defines what information from fileContractStatus is persisted.
    17  type fileContractStatusPersist struct {
    18  	FormationSweepHeight types.BlockHeight `json:"formationsweepheight,omitempty"`
    19  	ContractFound        bool              `json:"contractfound,omitempty"`
    20  	RevisionFound        uint64            `json:"revisionfound,omitempty"`
    21  	StorageProofFound    types.BlockHeight `json:"storageprooffound,omitempty"`
    22  
    23  	FormationTxnSet []types.Transaction     `json:"formationtxnset,omitempty"`
    24  	ParentOutputs   []types.SiacoinOutputID `json:"parentoutputs,omitempty"`
    25  
    26  	SweepTxn     types.Transaction   `json:"sweeptxn,omitempty"`
    27  	SweepParents []types.Transaction `json:"sweepparents,omitempty"`
    28  
    29  	WindowStart types.BlockHeight `json:"windowstart"`
    30  	WindowEnd   types.BlockHeight `json:"windowend"`
    31  }
    32  
    33  // persistData returns the data that will be saved to disk for
    34  // fileContractStatus.
    35  func (d *fileContractStatus) persistData() fileContractStatusPersist {
    36  	persistedParentOutputs := make([]types.SiacoinOutputID, 0, len(d.parentOutputs))
    37  	for oid := range d.parentOutputs {
    38  		persistedParentOutputs = append(persistedParentOutputs, oid)
    39  	}
    40  
    41  	return fileContractStatusPersist{
    42  		FormationSweepHeight: d.formationSweepHeight,
    43  		ContractFound:        d.contractFound,
    44  		RevisionFound:        d.revisionFound,
    45  		StorageProofFound:    d.storageProofFound,
    46  		FormationTxnSet:      d.formationTxnSet,
    47  		ParentOutputs:        persistedParentOutputs,
    48  		SweepTxn:             d.sweepTxn,
    49  		SweepParents:         d.sweepParents,
    50  		WindowStart:          d.windowStart,
    51  		WindowEnd:            d.windowEnd,
    52  	}
    53  }
    54  
    55  // callPersistData returns the data in the watchdog that will be saved to disk.
    56  func (w *watchdog) callPersistData() watchdogPersist {
    57  	w.mu.Lock()
    58  	defer w.mu.Unlock()
    59  
    60  	data := watchdogPersist{
    61  		Contracts:         make(map[string]fileContractStatusPersist),
    62  		ArchivedContracts: make(map[string]skymodules.ContractWatchStatus),
    63  	}
    64  	for fcID, contractData := range w.contracts {
    65  		data.Contracts[fcID.String()] = contractData.persistData()
    66  	}
    67  	for fcID, archivedData := range w.archivedContracts {
    68  		data.ArchivedContracts[fcID.String()] = archivedData
    69  	}
    70  
    71  	return data
    72  }
    73  
    74  // newWatchdogFromPersist creates a new watchdog and loads it with the
    75  // information stored in persistData.
    76  func newWatchdogFromPersist(contractor *Contractor, persistData watchdogPersist) (*watchdog, error) {
    77  	w := newWatchdog(contractor)
    78  
    79  	var fcID types.FileContractID
    80  	for fcIDString, data := range persistData.Contracts {
    81  		if err := fcID.LoadString(fcIDString); err != nil {
    82  			return nil, err
    83  		}
    84  
    85  		// Add persisted contract data to the watchdog.
    86  		contractData := &fileContractStatus{
    87  			formationSweepHeight: data.FormationSweepHeight,
    88  			contractFound:        data.ContractFound,
    89  			revisionFound:        data.RevisionFound,
    90  			storageProofFound:    data.StorageProofFound,
    91  
    92  			formationTxnSet: data.FormationTxnSet,
    93  			parentOutputs:   make(map[types.SiacoinOutputID]struct{}),
    94  
    95  			sweepTxn:     data.SweepTxn,
    96  			sweepParents: data.SweepParents,
    97  			windowStart:  data.WindowStart,
    98  			windowEnd:    data.WindowEnd,
    99  		}
   100  		for _, oid := range data.ParentOutputs {
   101  			contractData.parentOutputs[oid] = struct{}{}
   102  		}
   103  		w.contracts[fcID] = contractData
   104  
   105  		// Add all parent outputs the formation txn.
   106  		parentOutputs := getParentOutputIDs(data.FormationTxnSet)
   107  		for _, oid := range parentOutputs {
   108  			w.addOutputDependency(oid, fcID)
   109  		}
   110  	}
   111  
   112  	for fcIDString, data := range persistData.ArchivedContracts {
   113  		if err := fcID.LoadString(fcIDString); err != nil {
   114  			return nil, err
   115  		}
   116  		if _, ok := w.contracts[fcID]; ok {
   117  			return nil, errors.New("(watchdog) archived contract still in regular contracts map")
   118  		}
   119  
   120  		// Add persisted contract data to the watchdog.
   121  		w.archivedContracts[fcID] = data
   122  	}
   123  
   124  	return w, nil
   125  }