This bumps the major version of the database module to v3. This is needed because the current code already has backwards incompatible changes.
118 lines
3.2 KiB
Go
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)
|
|
}
|
|
}
|