github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/integration/db.go (about)

     1  package integration
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"os"
     7  	"path"
     8  	"strings"
     9  
    10  	"github.com/unicornultrafoundation/go-helios/hash"
    11  	"github.com/unicornultrafoundation/go-helios/native/dag"
    12  	"github.com/unicornultrafoundation/go-helios/u2udb"
    13  	"github.com/unicornultrafoundation/go-helios/u2udb/flaggedproducer"
    14  	"github.com/unicornultrafoundation/go-helios/u2udb/flushable"
    15  	"github.com/unicornultrafoundation/go-helios/u2udb/leveldb"
    16  	"github.com/unicornultrafoundation/go-helios/u2udb/multidb"
    17  	"github.com/unicornultrafoundation/go-helios/u2udb/pebble"
    18  	"github.com/unicornultrafoundation/go-helios/utils/fmtfilter"
    19  	"github.com/unicornultrafoundation/go-u2u/cmd/utils"
    20  	"github.com/unicornultrafoundation/go-u2u/log"
    21  	"github.com/unicornultrafoundation/go-u2u/metrics"
    22  
    23  	"github.com/unicornultrafoundation/go-u2u/gossip"
    24  	"github.com/unicornultrafoundation/go-u2u/utils/dbutil/asyncflushproducer"
    25  	"github.com/unicornultrafoundation/go-u2u/utils/dbutil/dbcounter"
    26  )
    27  
    28  type DBsConfig struct {
    29  	Routing       RoutingConfig
    30  	RuntimeCache  DBsCacheConfig
    31  	GenesisCache  DBsCacheConfig
    32  	MigrationMode string
    33  }
    34  
    35  type DBCacheConfig struct {
    36  	Cache   uint64
    37  	Fdlimit uint64
    38  }
    39  
    40  type DBsCacheConfig struct {
    41  	Table map[string]DBCacheConfig
    42  }
    43  
    44  func SupportedDBs(chaindataDir string, cfg DBsCacheConfig) (map[multidb.TypeName]u2udb.IterableDBProducer, map[multidb.TypeName]u2udb.FullDBProducer) {
    45  	if chaindataDir == "inmemory" || chaindataDir == "" {
    46  		chaindataDir, _ = ioutil.TempDir("", "u2u-tmp")
    47  	}
    48  	cacher, err := DbCacheFdlimit(cfg)
    49  	if err != nil {
    50  		utils.Fatalf("Failed to create DB cacher: %v", err)
    51  	}
    52  
    53  	leveldbFsh := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-fsh"), cacher), true)
    54  	leveldbFlg := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-flg"), cacher), true)
    55  	leveldbDrc := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-drc"), cacher), true)
    56  	pebbleFsh := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-fsh"), cacher), true)
    57  	pebbleFlg := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-flg"), cacher), true)
    58  	pebbleDrc := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-drc"), cacher), true)
    59  
    60  	if metrics.Enabled {
    61  		leveldbFsh = WrapDatabaseWithMetrics(leveldbFsh)
    62  		leveldbFlg = WrapDatabaseWithMetrics(leveldbFlg)
    63  		leveldbDrc = WrapDatabaseWithMetrics(leveldbDrc)
    64  		pebbleFsh = WrapDatabaseWithMetrics(pebbleFsh)
    65  		pebbleFlg = WrapDatabaseWithMetrics(pebbleFlg)
    66  		pebbleDrc = WrapDatabaseWithMetrics(pebbleDrc)
    67  	}
    68  
    69  	return map[multidb.TypeName]u2udb.IterableDBProducer{
    70  			"leveldb-fsh": leveldbFsh,
    71  			"leveldb-flg": leveldbFlg,
    72  			"leveldb-drc": leveldbDrc,
    73  			"pebble-fsh":  pebbleFsh,
    74  			"pebble-flg":  pebbleFlg,
    75  			"pebble-drc":  pebbleDrc,
    76  		}, map[multidb.TypeName]u2udb.FullDBProducer{
    77  			"leveldb-fsh": flushable.NewSyncedPool(leveldbFsh, FlushIDKey),
    78  			"leveldb-flg": flaggedproducer.Wrap(leveldbFlg, FlushIDKey),
    79  			"leveldb-drc": &DummyScopedProducer{leveldbDrc},
    80  			"pebble-fsh":  asyncflushproducer.Wrap(flushable.NewSyncedPool(pebbleFsh, FlushIDKey), 200000),
    81  			"pebble-flg":  flaggedproducer.Wrap(pebbleFlg, FlushIDKey),
    82  			"pebble-drc":  &DummyScopedProducer{pebbleDrc},
    83  		}
    84  }
    85  
    86  func DbCacheFdlimit(cfg DBsCacheConfig) (func(string) (int, int), error) {
    87  	fmts := make([]func(req string) (string, error), 0, len(cfg.Table))
    88  	fmtsCaches := make([]DBCacheConfig, 0, len(cfg.Table))
    89  	exactTable := make(map[string]DBCacheConfig, len(cfg.Table))
    90  	// build scanf filters
    91  	for name, cache := range cfg.Table {
    92  		if !strings.ContainsRune(name, '%') {
    93  			exactTable[name] = cache
    94  		} else {
    95  			fn, err := fmtfilter.CompileFilter(name, name)
    96  			if err != nil {
    97  				return nil, err
    98  			}
    99  			fmts = append(fmts, fn)
   100  			fmtsCaches = append(fmtsCaches, cache)
   101  		}
   102  	}
   103  	return func(name string) (int, int) {
   104  		// try exact match
   105  		if cache, ok := cfg.Table[name]; ok {
   106  			return int(cache.Cache), int(cache.Fdlimit)
   107  		}
   108  		// try regexp
   109  		for i, fn := range fmts {
   110  			if _, err := fn(name); err == nil {
   111  				return int(fmtsCaches[i].Cache), int(fmtsCaches[i].Fdlimit)
   112  			}
   113  		}
   114  		// default
   115  		return int(cfg.Table[""].Cache), int(cfg.Table[""].Fdlimit)
   116  	}, nil
   117  }
   118  
   119  func isEmpty(dir string) bool {
   120  	f, err := os.Open(dir)
   121  	if err != nil {
   122  		return true
   123  	}
   124  	defer f.Close()
   125  	_, err = f.Readdirnames(1)
   126  	return err == io.EOF
   127  }
   128  
   129  func dropAllDBs(chaindataDir string) {
   130  	_ = os.RemoveAll(chaindataDir)
   131  }
   132  
   133  func dropAllDBsIfInterrupted(chaindataDir string) {
   134  	if isInterrupted(chaindataDir) {
   135  		log.Info("Restarting genesis processing")
   136  		dropAllDBs(chaindataDir)
   137  	}
   138  }
   139  
   140  type GossipStoreAdapter struct {
   141  	*gossip.Store
   142  }
   143  
   144  func (g *GossipStoreAdapter) GetEvent(id hash.Event) dag.Event {
   145  	e := g.Store.GetEvent(id)
   146  	if e == nil {
   147  		return nil
   148  	}
   149  	return e
   150  }
   151  
   152  func MakeDBDirs(chaindataDir string) {
   153  	dbs, _ := SupportedDBs(chaindataDir, DBsCacheConfig{})
   154  	for typ := range dbs {
   155  		if err := os.MkdirAll(path.Join(chaindataDir, string(typ)), 0700); err != nil {
   156  			utils.Fatalf("Failed to create chaindata/leveldb directory: %v", err)
   157  		}
   158  	}
   159  }
   160  
   161  type DummyScopedProducer struct {
   162  	u2udb.IterableDBProducer
   163  }
   164  
   165  func (d DummyScopedProducer) NotFlushedSizeEst() int {
   166  	return 0
   167  }
   168  
   169  func (d DummyScopedProducer) Flush(_ []byte) error {
   170  	return nil
   171  }
   172  
   173  func (d DummyScopedProducer) Initialize(_ []string, flushID []byte) ([]byte, error) {
   174  	return flushID, nil
   175  }
   176  
   177  func (d DummyScopedProducer) Close() error {
   178  	return nil
   179  }