github.com/lbryio/lbcd@v0.22.119/database/cmd/dbtool/main.go (about) 1 // Copyright (c) 2015-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "os" 9 "path/filepath" 10 "strings" 11 12 "github.com/btcsuite/btclog" 13 flags "github.com/jessevdk/go-flags" 14 "github.com/lbryio/lbcd/database" 15 ) 16 17 const ( 18 // blockDbNamePrefix is the prefix for the btcd block database. 19 blockDbNamePrefix = "blocks" 20 ) 21 22 var ( 23 log btclog.Logger 24 shutdownChannel = make(chan error) 25 ) 26 27 // loadBlockDB opens the block database and returns a handle to it. 28 func loadBlockDB() (database.DB, error) { 29 // The database name is based on the database type. 30 dbName := blockDbNamePrefix + "_" + cfg.DbType 31 dbPath := filepath.Join(cfg.DataDir, dbName) 32 33 log.Infof("Loading block database from '%s'", dbPath) 34 db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net) 35 if err != nil { 36 // Return the error if it's not because the database doesn't 37 // exist. 38 if dbErr, ok := err.(database.Error); !ok || dbErr.ErrorCode != 39 database.ErrDbDoesNotExist { 40 41 return nil, err 42 } 43 44 // Create the db if it does not exist. 45 err = os.MkdirAll(cfg.DataDir, 0700) 46 if err != nil { 47 return nil, err 48 } 49 db, err = database.Create(cfg.DbType, dbPath, activeNetParams.Net) 50 if err != nil { 51 return nil, err 52 } 53 } 54 55 log.Info("Block database loaded") 56 return db, nil 57 } 58 59 // realMain is the real main function for the utility. It is necessary to work 60 // around the fact that deferred functions do not run when os.Exit() is called. 61 func realMain() error { 62 // Setup logging. 63 backendLogger := btclog.NewBackend(os.Stdout) 64 defer os.Stdout.Sync() 65 log = backendLogger.Logger("MAIN") 66 dbLog := backendLogger.Logger("BCDB") 67 dbLog.SetLevel(btclog.LevelDebug) 68 database.UseLogger(dbLog) 69 70 // Setup the parser options and commands. 71 appName := filepath.Base(os.Args[0]) 72 appName = strings.TrimSuffix(appName, filepath.Ext(appName)) 73 parserFlags := flags.Options(flags.HelpFlag | flags.PassDoubleDash) 74 parser := flags.NewNamedParser(appName, parserFlags) 75 parser.AddGroup("Global Options", "", cfg) 76 parser.AddCommand("insecureimport", 77 "Insecurely import bulk block data from bootstrap.dat", 78 "Insecurely import bulk block data from bootstrap.dat. "+ 79 "WARNING: This is NOT secure because it does NOT "+ 80 "verify chain rules. It is only provided for testing "+ 81 "purposes.", &importCfg) 82 parser.AddCommand("loadheaders", 83 "Time how long to load headers for all blocks in the database", 84 "", &headersCfg) 85 parser.AddCommand("fetchblock", 86 "Fetch the specific block hash from the database", "", 87 &fetchBlockCfg) 88 parser.AddCommand("fetchblockregion", 89 "Fetch the specified block region from the database", "", 90 &blockRegionCfg) 91 92 // Parse command line and invoke the Execute function for the specified 93 // command. 94 if _, err := parser.Parse(); err != nil { 95 if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp { 96 parser.WriteHelp(os.Stderr) 97 } else { 98 log.Error(err) 99 } 100 101 return err 102 } 103 104 return nil 105 } 106 107 func main() { 108 // Work around defer not working after os.Exit() 109 if err := realMain(); err != nil { 110 os.Exit(1) 111 } 112 }