OSDN Git Service

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