github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/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/dashpay/godash/blockchain" 15 "github.com/dashpay/godash/blockchain/indexers" 16 "github.com/dashpay/godash/database" 17 "github.com/dashpay/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 }