gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/hostdb/persist.go (about)

     1  package hostdb
     2  
     3  import (
     4  	"path/filepath"
     5  	"time"
     6  
     7  	"gitlab.com/NebulousLabs/errors"
     8  	"gitlab.com/SkynetLabs/skyd/skymodules"
     9  	"gitlab.com/SkynetLabs/skyd/skymodules/renter/hostdb/hosttree"
    10  	"go.sia.tech/siad/modules"
    11  	"go.sia.tech/siad/persist"
    12  	"go.sia.tech/siad/types"
    13  )
    14  
    15  var (
    16  	// persistFilename defines the name of the file that holds the hostdb's
    17  	// persistence.
    18  	persistFilename = "hostdb.json"
    19  
    20  	// persistMetadata defines the metadata that tags along with the most recent
    21  	// version of the hostdb persistence file.
    22  	persistMetadata = persist.Metadata{
    23  		Header:  "HostDB Persistence",
    24  		Version: "0.5",
    25  	}
    26  )
    27  
    28  // hdbPersist defines what HostDB data persists across sessions.
    29  type hdbPersist struct {
    30  	AllHosts                 []skymodules.HostDBEntry
    31  	BlockedDomains           []string
    32  	BlockHeight              types.BlockHeight
    33  	DisableIPViolationsCheck bool
    34  	KnownContracts           map[string]contractInfo
    35  	LastChange               modules.ConsensusChangeID
    36  	FilteredHosts            map[string]types.SiaPublicKey
    37  	FilterMode               skymodules.FilterMode
    38  }
    39  
    40  // persistData returns the data in the hostdb that will be saved to disk.
    41  func (hdb *HostDB) persistData() (data hdbPersist) {
    42  	data.AllHosts = hdb.staticHostTree.All()
    43  	data.BlockedDomains = hdb.staticBlockedDomains.managedBlockedDomains()
    44  	data.BlockHeight = hdb.blockHeight
    45  	data.DisableIPViolationsCheck = hdb.disableIPViolationCheck
    46  	data.KnownContracts = hdb.knownContracts
    47  	data.LastChange = hdb.lastChange
    48  	data.FilteredHosts = hdb.filteredHosts
    49  	data.FilterMode = hdb.filterMode
    50  	return data
    51  }
    52  
    53  // saveSync saves the hostdb persistence data to disk and then syncs to disk.
    54  func (hdb *HostDB) saveSync() error {
    55  	return hdb.staticDeps.SaveFileSync(persistMetadata, hdb.persistData(), filepath.Join(hdb.persistDir, persistFilename))
    56  }
    57  
    58  // load loads the hostdb persistence data from disk.
    59  func (hdb *HostDB) load() error {
    60  	// Fetch the data from the file.
    61  	var data hdbPersist
    62  	data.FilteredHosts = make(map[string]types.SiaPublicKey)
    63  	err := hdb.staticDeps.LoadFile(persistMetadata, &data, filepath.Join(hdb.persistDir, persistFilename))
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	// Set the hostdb internal values.
    69  	hdb.blockHeight = data.BlockHeight
    70  	hdb.disableIPViolationCheck = data.DisableIPViolationsCheck
    71  	hdb.lastChange = data.LastChange
    72  	hdb.knownContracts = data.KnownContracts
    73  	hdb.filteredHosts = data.FilteredHosts
    74  	hdb.filterMode = data.FilterMode
    75  
    76  	// Overwrite the initialized staticBlockedDomains with the data loaded
    77  	// from disk
    78  	hdb.staticBlockedDomains = newBlockedDomains(data.BlockedDomains)
    79  
    80  	if len(hdb.filteredHosts) > 0 {
    81  		hdb.staticFilteredTree = hosttree.New(hdb.weightFunc, modules.ProdDependencies.Resolver())
    82  	}
    83  
    84  	// Load each of the hosts into the host trees.
    85  	for _, host := range data.AllHosts {
    86  		err := hdb.insert(host)
    87  		if errors.Contains(err, errHostDomainBlocked) {
    88  			hdb.staticLog.Debugf("Could not insert host %v to the hostdb. Host domain blocked %v\n", host.PublicKey.String(), host.NetAddress)
    89  		} else if err != nil {
    90  			hdb.staticLog.Debugln("ERROR: could not insert host into hosttree while loading:", host.NetAddress)
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  // threadedSaveLoop saves the hostdb to disk every 2 minutes, also saving when
    97  // given the shutdown signal.
    98  func (hdb *HostDB) threadedSaveLoop() {
    99  	err := hdb.tg.Add()
   100  	if err != nil {
   101  		return
   102  	}
   103  	defer hdb.tg.Done()
   104  
   105  	for {
   106  		select {
   107  		case <-hdb.tg.StopChan():
   108  			return
   109  		case <-time.After(saveFrequency):
   110  			hdb.mu.Lock()
   111  			err = hdb.saveSync()
   112  			hdb.mu.Unlock()
   113  			if err != nil {
   114  				hdb.staticLog.Println("Difficulties saving the hostdb:", err)
   115  			}
   116  		}
   117  	}
   118  }