github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/cmd/addblock/addblock.go (about)

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package main
     7  
     8  import (
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  
    13  	"github.com/btcsuite/btclog"
    14  	"github.com/BlockABC/godash/blockchain"
    15  	"github.com/BlockABC/godash/blockchain/indexers"
    16  	"github.com/BlockABC/godash/database"
    17  	"github.com/BlockABC/godash/limits"
    18  )
    19  
    20  const (
    21  	// blockDbNamePrefix is the prefix for the btcd block database.
    22  	blockDbNamePrefix = "blocks"
    23  )
    24  
    25  var (
    26  	cfg *config
    27  	log btclog.Logger
    28  )
    29  
    30  // loadBlockDB opens the block database and returns a handle to it.
    31  func loadBlockDB() (database.DB, error) {
    32  	// The database name is based on the database type.
    33  	dbName := blockDbNamePrefix + "_" + cfg.DbType
    34  	dbPath := filepath.Join(cfg.DataDir, dbName)
    35  
    36  	log.Infof("Loading block database from '%s'", dbPath)
    37  	db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net)
    38  	if err != nil {
    39  		// Return the error if it's not because the database doesn't
    40  		// exist.
    41  		if dbErr, ok := err.(database.Error); !ok || dbErr.ErrorCode !=
    42  			database.ErrDbDoesNotExist {
    43  
    44  			return nil, err
    45  		}
    46  
    47  		// Create the db if it does not exist.
    48  		err = os.MkdirAll(cfg.DataDir, 0700)
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  		db, err = database.Create(cfg.DbType, dbPath, activeNetParams.Net)
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  	}
    57  
    58  	log.Info("Block database loaded")
    59  	return db, nil
    60  }
    61  
    62  // realMain is the real main function for the utility.  It is necessary to work
    63  // around the fact that deferred functions do not run when os.Exit() is called.
    64  func realMain() error {
    65  	// Load configuration and parse command line.
    66  	tcfg, _, err := loadConfig()
    67  	if err != nil {
    68  		return err
    69  	}
    70  	cfg = tcfg
    71  
    72  	// Setup logging.
    73  	backendLogger := btclog.NewDefaultBackendLogger()
    74  	defer backendLogger.Flush()
    75  	log = btclog.NewSubsystemLogger(backendLogger, "")
    76  	database.UseLogger(btclog.NewSubsystemLogger(backendLogger, "BCDB: "))
    77  	blockchain.UseLogger(btclog.NewSubsystemLogger(backendLogger, "CHAN: "))
    78  	indexers.UseLogger(btclog.NewSubsystemLogger(backendLogger, "INDX: "))
    79  
    80  	// Load the block database.
    81  	db, err := loadBlockDB()
    82  	if err != nil {
    83  		log.Errorf("Failed to load database: %v", err)
    84  		return err
    85  	}
    86  	defer db.Close()
    87  
    88  	fi, err := os.Open(cfg.InFile)
    89  	if err != nil {
    90  		log.Errorf("Failed to open file %v: %v", cfg.InFile, err)
    91  		return err
    92  	}
    93  	defer fi.Close()
    94  
    95  	// Create a block importer for the database and input file and start it.
    96  	// The done channel returned from start will contain an error if
    97  	// anything went wrong.
    98  	importer, err := newBlockImporter(db, fi)
    99  	if err != nil {
   100  		log.Errorf("Failed create block importer: %v", err)
   101  		return err
   102  	}
   103  
   104  	// Perform the import asynchronously.  This allows blocks to be
   105  	// processed and read in parallel.  The results channel returned from
   106  	// Import contains the statistics about the import including an error
   107  	// if something went wrong.
   108  	log.Info("Starting import")
   109  	resultsChan := importer.Import()
   110  	results := <-resultsChan
   111  	if results.err != nil {
   112  		log.Errorf("%v", results.err)
   113  		return results.err
   114  	}
   115  
   116  	log.Infof("Processed a total of %d blocks (%d imported, %d already "+
   117  		"known)", results.blocksProcessed, results.blocksImported,
   118  		results.blocksProcessed-results.blocksImported)
   119  	return nil
   120  }
   121  
   122  func main() {
   123  	// Use all processor cores and up some limits.
   124  	runtime.GOMAXPROCS(runtime.NumCPU())
   125  	if err := limits.SetLimits(); err != nil {
   126  		os.Exit(1)
   127  	}
   128  
   129  	// Work around defer not working after os.Exit()
   130  	if err := realMain(); err != nil {
   131  		os.Exit(1)
   132  	}
   133  }