github.com/palcoin-project/palcd@v1.0.0/database/cmd/dbtool/loadheaders.go (about) 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/palcoin-project/palcd/chaincfg/chainhash" 11 "github.com/palcoin-project/palcd/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 }