github.com/vipernet-xyz/tm@v0.34.24/p2p/pex/file.go (about)

     1  package pex
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/vipernet-xyz/tm/libs/tempfile"
     9  )
    10  
    11  /* Loading & Saving */
    12  
    13  type addrBookJSON struct {
    14  	Key   string          `json:"key"`
    15  	Addrs []*knownAddress `json:"addrs"`
    16  }
    17  
    18  func (a *addrBook) saveToFile(filePath string) {
    19  	a.mtx.Lock()
    20  	defer a.mtx.Unlock()
    21  
    22  	a.Logger.Info("Saving AddrBook to file", "size", a.size())
    23  
    24  	addrs := make([]*knownAddress, 0, len(a.addrLookup))
    25  	for _, ka := range a.addrLookup {
    26  		addrs = append(addrs, ka)
    27  	}
    28  	aJSON := &addrBookJSON{
    29  		Key:   a.key,
    30  		Addrs: addrs,
    31  	}
    32  
    33  	jsonBytes, err := json.MarshalIndent(aJSON, "", "\t")
    34  	if err != nil {
    35  		a.Logger.Error("Failed to save AddrBook to file", "err", err)
    36  		return
    37  	}
    38  	err = tempfile.WriteFileAtomic(filePath, jsonBytes, 0644)
    39  	if err != nil {
    40  		a.Logger.Error("Failed to save AddrBook to file", "file", filePath, "err", err)
    41  	}
    42  }
    43  
    44  // Returns false if file does not exist.
    45  // cmn.Panics if file is corrupt.
    46  func (a *addrBook) loadFromFile(filePath string) bool {
    47  	// If doesn't exist, do nothing.
    48  	_, err := os.Stat(filePath)
    49  	if os.IsNotExist(err) {
    50  		return false
    51  	}
    52  
    53  	// Load addrBookJSON{}
    54  	r, err := os.Open(filePath)
    55  	if err != nil {
    56  		panic(fmt.Sprintf("Error opening file %s: %v", filePath, err))
    57  	}
    58  	defer r.Close()
    59  	aJSON := &addrBookJSON{}
    60  	dec := json.NewDecoder(r)
    61  	err = dec.Decode(aJSON)
    62  	if err != nil {
    63  		panic(fmt.Sprintf("Error reading file %s: %v", filePath, err))
    64  	}
    65  
    66  	// Restore all the fields...
    67  	// Restore the key
    68  	a.key = aJSON.Key
    69  	// Restore .bucketsNew & .bucketsOld
    70  	for _, ka := range aJSON.Addrs {
    71  		for _, bucketIndex := range ka.Buckets {
    72  			bucket := a.getBucket(ka.BucketType, bucketIndex)
    73  			bucket[ka.Addr.String()] = ka
    74  		}
    75  		a.addrLookup[ka.ID()] = ka
    76  		if ka.BucketType == bucketTypeNew {
    77  			a.nNew++
    78  		} else {
    79  			a.nOld++
    80  		}
    81  	}
    82  	return true
    83  }