// 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 { // Load configuration and parse command line. tcfg, _, err := loadConfig() if err != nil { return err } cfg = tcfg // Setup logging. backendLogger := btclog.NewDefaultBackendLogger() defer backendLogger.Flush() log = btclog.NewSubsystemLogger(backendLogger, "") database.UseLogger(btclog.NewSubsystemLogger(backendLogger, "BCDB: ")) blockchain.UseLogger(btclog.NewSubsystemLogger(backendLogger, "CHAN: ")) // Load the block database. db, err := loadBlockDB() if err != nil { log.Errorf("Failed to load database: %v", err) return err } defer db.Close() fi, err := os.Open(cfg.InFile) if err != nil { log.Errorf("Failed to open file %v: %v", cfg.InFile, err) return err } defer fi.Close() // Create a block importer for the database and input file and start it. // The done channel returned from start will contain an error if // anything went wrong. importer := newBlockImporter(db, fi) // Perform the import asynchronously. This allows blocks to be // processed and read in parallel. The results channel returned from // Import contains the statistics about the import including an error // if something went wrong. log.Info("Starting import") resultsChan := importer.Import() results := <-resultsChan if results.err != nil { log.Errorf("%v", results.err) return results.err } log.Infof("Processed a total of %d blocks (%d imported, %d already "+ "known)", results.blocksProcessed, results.blocksImported, results.blocksProcessed-results.blocksImported) return nil }
func main() { cfg := config{ DbType: "leveldb", DataDir: defaultDataDir, } parser := flags.NewParser(&cfg, flags.Default) _, err := parser.Parse() if err != nil { if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { parser.WriteHelp(os.Stderr) } return } backendLogger := btclog.NewDefaultBackendLogger() defer backendLogger.Flush() log = btclog.NewSubsystemLogger(backendLogger, "") database.UseLogger(log) // Multiple networks can't be selected simultaneously. funcName := "main" numNets := 0 // Count number of network flags passed; assign active network params // while we're at it if cfg.TestNet3 { numNets++ activeNetParams = &chaincfg.TestNet3Params } if cfg.RegressionTest { numNets++ activeNetParams = &chaincfg.RegressionNetParams } if cfg.SimNet { numNets++ activeNetParams = &chaincfg.SimNetParams } if numNets > 1 { str := "%s: The testnet, regtest, and simnet params can't be " + "used together -- choose one of the three" err := fmt.Errorf(str, funcName) fmt.Fprintln(os.Stderr, err) parser.WriteHelp(os.Stderr) return } cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams)) blockDbNamePrefix := "blocks" dbName := blockDbNamePrefix + "_" + cfg.DbType if cfg.DbType == "sqlite" { dbName = dbName + ".db" } dbPath := filepath.Join(cfg.DataDir, dbName) log.Infof("loading db") db, err := database.OpenDB(cfg.DbType, dbPath) if err != nil { log.Warnf("db open failed: %v", err) return } defer db.Close() log.Infof("db load complete") _, height, err := db.NewestSha() log.Infof("loaded block height %v", height) sha, err := getSha(db, cfg.ShaString) if err != nil { log.Infof("Invalid block hash %v", cfg.ShaString) return } err = db.DropAfterBlockBySha(&sha) if err != nil { log.Warnf("failed %v", err) } }