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.
13 "github.com/btcsuite/btcd/database"
14 "github.com/btcsuite/btclog"
15 flags "github.com/jessevdk/go-flags"
19 // blockDbNamePrefix is the prefix for the btcd block database.
20 blockDbNamePrefix = "blocks"
25 shutdownChannel = make(chan error)
28 // loadBlockDB opens the block database and returns a handle to it.
29 func loadBlockDB() (database.DB, error) {
30 // The database name is based on the database type.
31 dbName := blockDbNamePrefix + "_" + cfg.DbType
32 dbPath := filepath.Join(cfg.DataDir, dbName)
34 log.Infof("Loading block database from '%s'", dbPath)
35 db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net)
37 // Return the error if it's not because the database doesn't
39 if dbErr, ok := err.(database.Error); !ok || dbErr.ErrorCode !=
40 database.ErrDbDoesNotExist {
45 // Create the db if it does not exist.
46 err = os.MkdirAll(cfg.DataDir, 0700)
50 db, err = database.Create(cfg.DbType, dbPath, activeNetParams.Net)
56 log.Info("Block database loaded")
60 // realMain is the real main function for the utility. It is necessary to work
61 // around the fact that deferred functions do not run when os.Exit() is called.
62 func realMain() error {
64 backendLogger := btclog.NewBackend(os.Stdout)
65 defer os.Stdout.Sync()
66 log = backendLogger.Logger("MAIN")
67 dbLog := backendLogger.Logger("BCDB")
68 dbLog.SetLevel(btclog.LevelDebug)
69 database.UseLogger(dbLog)
71 // Setup the parser options and commands.
72 appName := filepath.Base(os.Args[0])
73 appName = strings.TrimSuffix(appName, filepath.Ext(appName))
74 parserFlags := flags.Options(flags.HelpFlag | flags.PassDoubleDash)
75 parser := flags.NewNamedParser(appName, parserFlags)
76 parser.AddGroup("Global Options", "", cfg)
77 parser.AddCommand("insecureimport",
78 "Insecurely import bulk block data from bootstrap.dat",
79 "Insecurely import bulk block data from bootstrap.dat. "+
80 "WARNING: This is NOT secure because it does NOT "+
81 "verify chain rules. It is only provided for testing "+
82 "purposes.", &importCfg)
83 parser.AddCommand("loadheaders",
84 "Time how long to load headers for all blocks in the database",
86 parser.AddCommand("fetchblock",
87 "Fetch the specific block hash from the database", "",
89 parser.AddCommand("fetchblockregion",
90 "Fetch the specified block region from the database", "",
93 // Parse command line and invoke the Execute function for the specified
95 if _, err := parser.Parse(); err != nil {
96 if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
97 parser.WriteHelp(os.Stderr)
109 // Use all processor cores.
110 runtime.GOMAXPROCS(runtime.NumCPU())
112 // Work around defer not working after os.Exit()
113 if err := realMain(); err != nil {