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 }