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