github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/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/BlockABC/godash/database"
    12  	"github.com/BlockABC/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  }