dcrd/database/cmd/dbtool/main.go
Matheus Degiovani 9ede6ae83e multi: Introduce database/v3 module.
This bumps the major version of the database module to v3. This is
needed because the current code already has backwards incompatible
changes.
2021-08-02 08:29:46 -05:00

118 lines
3.2 KiB
Go

// Copyright (c) 2015-2016 The btcsuite developers
// Copyright (c) 2016-2020 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package main
import (
"errors"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/decred/dcrd/database/v3"
"github.com/decred/slog"
flags "github.com/jessevdk/go-flags"
)
const (
// blockDbNamePrefix is the prefix for the block database.
blockDbNamePrefix = "blocks"
)
var (
log slog.Logger
shutdownChannel = make(chan error)
)
// loadBlockDB opens the block database and returns a handle to it.
func loadBlockDB() (database.DB, error) {
// The database name is based on the database type.
dbName := blockDbNamePrefix + "_" + cfg.DbType
dbPath := filepath.Join(cfg.DataDir, dbName)
log.Infof("Loading block database from '%s'", dbPath)
db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net)
if err != nil {
// Return the error if it's not because the database doesn't
// exist.
if !errors.Is(err, database.ErrDbDoesNotExist) {
return nil, err
}
// Create the db if it does not exist.
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
return nil, err
}
db, err = database.Create(cfg.DbType, dbPath, activeNetParams.Net)
if err != nil {
return nil, err
}
}
log.Info("Block database loaded")
return db, nil
}
// realMain is the real main function for the utility. It is necessary to work
// around the fact that deferred functions do not run when os.Exit() is called.
func realMain() error {
// Setup logging.
backendLogger := slog.NewBackend(os.Stdout)
defer os.Stdout.Sync()
log = backendLogger.Logger("MAIN")
dbLog := backendLogger.Logger("BCDB")
dbLog.SetLevel(slog.LevelDebug)
database.UseLogger(dbLog)
// Setup the parser options and commands.
appName := filepath.Base(os.Args[0])
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
parserFlags := flags.Options(flags.HelpFlag | flags.PassDoubleDash)
parser := flags.NewNamedParser(appName, parserFlags)
parser.AddGroup("Global Options", "", cfg)
parser.AddCommand("insecureimport",
"Insecurely import bulk block data from bootstrap.dat",
"Insecurely import bulk block data from bootstrap.dat. "+
"WARNING: This is NOT secure because it does NOT "+
"verify chain rules. It is only provided for testing "+
"purposes.", &importCfg)
parser.AddCommand("loadheaders",
"Time how long to load headers for all blocks in the database",
"", &headersCfg)
parser.AddCommand("fetchblock",
"Fetch the specific block hash from the database", "",
&fetchBlockCfg)
parser.AddCommand("fetchblockregion",
"Fetch the specified block region from the database", "",
&blockRegionCfg)
// Parse command line and invoke the Execute function for the specified
// command.
if _, err := parser.Parse(); err != nil {
var e *flags.Error
if errors.As(err, &e) && e.Type == flags.ErrHelp {
parser.WriteHelp(os.Stderr)
} else {
log.Error(err)
}
return err
}
return nil
}
func main() {
// Use all processor cores.
runtime.GOMAXPROCS(runtime.NumCPU())
// Work around defer not working after os.Exit()
if err := realMain(); err != nil {
os.Exit(1)
}
}