OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / database / cmd / dbtool / loadheaders.go
1 // Copyright (c) 2015-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         "time"
9
10         "github.com/btcsuite/btcd/chaincfg/chainhash"
11         "github.com/btcsuite/btcd/database"
12 )
13
14 // headersCmd defines the configuration options for the loadheaders command.
15 type headersCmd struct {
16         Bulk bool `long:"bulk" description:"Use bulk loading of headers instead of one at a time"`
17 }
18
19 var (
20         // headersCfg defines the configuration options for the command.
21         headersCfg = headersCmd{
22                 Bulk: false,
23         }
24 )
25
26 // Execute is the main entry point for the command.  It's invoked by the parser.
27 func (cmd *headersCmd) Execute(args []string) error {
28         // Setup the global config options and ensure they are valid.
29         if err := setupGlobalConfig(); err != nil {
30                 return err
31         }
32
33         // Load the block database.
34         db, err := loadBlockDB()
35         if err != nil {
36                 return err
37         }
38         defer db.Close()
39
40         // NOTE: This code will only work for ffldb.  Ideally the package using
41         // the database would keep a metadata index of its own.
42         blockIdxName := []byte("ffldb-blockidx")
43         if !headersCfg.Bulk {
44                 err = db.View(func(tx database.Tx) error {
45                         totalHdrs := 0
46                         blockIdxBucket := tx.Metadata().Bucket(blockIdxName)
47                         blockIdxBucket.ForEach(func(k, v []byte) error {
48                                 totalHdrs++
49                                 return nil
50                         })
51                         log.Infof("Loading headers for %d blocks...", totalHdrs)
52                         numLoaded := 0
53                         startTime := time.Now()
54                         blockIdxBucket.ForEach(func(k, v []byte) error {
55                                 var hash chainhash.Hash
56                                 copy(hash[:], k)
57                                 _, err := tx.FetchBlockHeader(&hash)
58                                 if err != nil {
59                                         return err
60                                 }
61                                 numLoaded++
62                                 return nil
63                         })
64                         log.Infof("Loaded %d headers in %v", numLoaded,
65                                 time.Since(startTime))
66                         return nil
67                 })
68                 return err
69         }
70
71         // Bulk load headers.
72         err = db.View(func(tx database.Tx) error {
73                 blockIdxBucket := tx.Metadata().Bucket(blockIdxName)
74                 hashes := make([]chainhash.Hash, 0, 500000)
75                 blockIdxBucket.ForEach(func(k, v []byte) error {
76                         var hash chainhash.Hash
77                         copy(hash[:], k)
78                         hashes = append(hashes, hash)
79                         return nil
80                 })
81
82                 log.Infof("Loading headers for %d blocks...", len(hashes))
83                 startTime := time.Now()
84                 hdrs, err := tx.FetchBlockHeaders(hashes)
85                 if err != nil {
86                         return err
87                 }
88                 log.Infof("Loaded %d headers in %v", len(hdrs),
89                         time.Since(startTime))
90                 return nil
91         })
92         return err
93 }