From 55b300b6c2256fae3752ce97ff225ac2680ec36e Mon Sep 17 00:00:00 2001 From: David Hill <dhill@mindcry.org> Date: Thu, 10 Oct 2013 14:05:54 -0400 Subject: [PATCH] improve addblock --- util/addblock/addblock.go | 128 +++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/util/addblock/addblock.go b/util/addblock/addblock.go index ca12626a..68713674 100644 --- a/util/addblock/addblock.go +++ b/util/addblock/addblock.go @@ -6,13 +6,13 @@ package main import ( "encoding/binary" - "flag" "fmt" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/sqlite3" "github.com/conformal/btcutil" "github.com/conformal/btcwire" + "github.com/conformal/go-flags" "github.com/conformal/seelog" "io" "os" @@ -23,6 +23,14 @@ import ( type ShaHash btcwire.ShaHash +type config struct { + DataDir string `short:"b" long:"datadir" description:"Directory to store data"` + DbType string `long:"dbtype" description:"Database backend"` + TestNet3 bool `long:"testnet" description:"Use the test network"` + Progress bool `short:"p" description:"show progress"` + InFile string `short:"i" long:"infile" description:"File containing the block(s)" required:"true"` +} + var log seelog.LoggerInterface const ( @@ -42,25 +50,21 @@ type blkQueue struct { } func main() { - var err error - var dbType string - var datadir string - var infile string - var progress int - flag.StringVar(&dbType, "dbtype", "", "Database backend to use for the Block Chain") - flag.StringVar(&datadir, "datadir", "", "Directory to store data") - flag.StringVar(&infile, "i", "", "infile") - flag.IntVar(&progress, "p", 0, "show progress") - - flag.Parse() - - runtime.GOMAXPROCS(runtime.NumCPU()) - - if len (infile) == 0 { - fmt.Printf("Must specify inputfile") + cfg := config{ + DbType: "leveldb", + DataDir: filepath.Join(btcdHomeDir(), "data"), + } + parser := flags.NewParser(&cfg, flags.Default) + _, err := parser.Parse() + if err != nil { + if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { + parser.WriteHelp(os.Stderr) + } return } + runtime.GOMAXPROCS(runtime.NumCPU()) + log, err = seelog.LoggerFromWriterWithMinLevel(os.Stdout, seelog.InfoLvl) if err != nil { @@ -70,30 +74,29 @@ func main() { defer log.Flush() btcdb.UseLogger(log) - if len(dbType) == 0 { - dbType = "sqlite" + var testnet string + if cfg.TestNet3 { + testnet = "testnet" + } else { + testnet = "mainnet" } - if len(datadir) == 0 { - datadir = filepath.Join(btcdHomeDir(), "data") - } - datadir = filepath.Join(datadir, "mainnet") + cfg.DataDir = filepath.Join(cfg.DataDir, testnet) - err = os.MkdirAll(datadir, 0700) + err = os.MkdirAll(cfg.DataDir, 0700) if err != nil { - fmt.Printf("unable to create db repo area %v, %v", datadir, err) + fmt.Printf("unable to create db repo area %v, %v", cfg.DataDir, err) } - blockDbNamePrefix := "blocks" - dbName := blockDbNamePrefix + "_" + dbType - if dbType == "sqlite" { + dbName := blockDbNamePrefix + "_" + cfg.DbType + if cfg.DbType == "sqlite" { dbName = dbName + ".db" } - dbPath := filepath.Join(datadir, dbName) + dbPath := filepath.Join(cfg.DataDir, dbName) log.Infof("loading db") - db, err := btcdb.CreateDB(dbType, dbPath) + db, err := btcdb.CreateDB(cfg.DbType, dbPath) if err != nil { log.Warnf("db open failed: %v", err) return @@ -101,16 +104,15 @@ func main() { defer db.Close() log.Infof("db created") - var fi io.ReadCloser - fi, err = os.Open(infile) + fi, err = os.Open(cfg.InFile) if err != nil { - log.Warnf("failed to open file %v, err %v", infile, err) + log.Warnf("failed to open file %v, err %v", cfg.InFile, err) } defer func() { if err := fi.Close(); err != nil { - log.Warn("failed to close file %v %v", infile, err) + log.Warn("failed to close file %v %v", cfg.InFile, err) } }() @@ -125,11 +127,11 @@ func main() { go readBlocks(fi, bufqueue) var eheight int64 - doneMap := map [int64] *blkQueue {} + doneMap := map[int64]*blkQueue{} for { select { - case blkM := <- blkqueue: + case blkM := <-blkqueue: doneMap[blkM.height] = blkM for { @@ -138,12 +140,12 @@ func main() { blkP.complete <- true db.InsertBlock(blkP.blk) - if progress != 0 && eheight%int64(progress) == 0 { + if cfg.Progress && eheight%int64(1) == 0 { log.Infof("Processing block %v", eheight) } eheight++ - if eheight % 2000 == 0 { + if eheight%2000 == 0 { f, err := os.Create(fmt.Sprintf("profile.%d", eheight)) if err == nil { pprof.WriteHeapProfile(f) @@ -161,10 +163,10 @@ func main() { } func processBuf(idx int, bufqueue chan *bufQueue, blkqueue chan *blkQueue) { - complete := make (chan bool) + complete := make(chan bool) for { select { - case bq := <- bufqueue: + case bq := <-bufqueue: var blkmsg blkQueue blkmsg.height = bq.height @@ -174,7 +176,7 @@ func processBuf(idx int, bufqueue chan *bufQueue, blkqueue chan *blkQueue) { blkqueue <- &blkmsg } - blk, err := btcutil.NewBlockFromBytes(bq.blkbuf) + blk, err := btcutil.NewBlockFromBytes(bq.blkbuf) if err != nil { fmt.Printf("failed to parse block %v", bq.height) return @@ -183,7 +185,7 @@ func processBuf(idx int, bufqueue chan *bufQueue, blkqueue chan *blkQueue) { blkmsg.complete = complete blkqueue <- &blkmsg select { - case <- complete: + case <-complete: } } } @@ -204,7 +206,7 @@ func readBlocks(fi io.Reader, bufqueue chan *bufQueue) { bufqueue <- &bufM } if net != uint32(btcwire.MainNet) { - fmt.Printf("network mismatch %v %v", + fmt.Printf("network mismatch %v %v", net, uint32(btcwire.MainNet)) bufqueue <- &bufM @@ -224,7 +226,7 @@ func readBlocks(fi io.Reader, bufqueue chan *bufQueue) { // newLogger creates a new seelog logger using the provided logging level and // log message prefix. func newLogger(level string, prefix string) seelog.LoggerInterface { - fmtstring := ` + fmtstring := ` <seelog type="adaptive" mininterval="2000000" maxinterval="100000000" critmsgcount="500" minlevel="%s"> <outputs formatid="all"> @@ -234,31 +236,31 @@ func newLogger(level string, prefix string) seelog.LoggerInterface { <format id="all" format="[%%Time %%Date] [%%LEV] [%s] %%Msg%%n" /> </formats> </seelog>` - config := fmt.Sprintf(fmtstring, level, prefix) + config := fmt.Sprintf(fmtstring, level, prefix) - logger, err := seelog.LoggerFromConfigAsString(config) - if err != nil { - fmt.Fprintf(os.Stderr, "failed to create logger: %v", err) - os.Exit(1) - } + logger, err := seelog.LoggerFromConfigAsString(config) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to create logger: %v", err) + os.Exit(1) + } - return logger + return logger } // btcdHomeDir returns an OS appropriate home directory for btcd. func btcdHomeDir() string { - // Search for Windows APPDATA first. This won't exist on POSIX OSes. - appData := os.Getenv("APPDATA") - if appData != "" { - return filepath.Join(appData, "btcd") - } + // Search for Windows APPDATA first. This won't exist on POSIX OSes. + appData := os.Getenv("APPDATA") + if appData != "" { + return filepath.Join(appData, "btcd") + } - // Fall back to standard HOME directory that works for most POSIX OSes. - home := os.Getenv("HOME") - if home != "" { - return filepath.Join(home, ".btcd") - } + // Fall back to standard HOME directory that works for most POSIX OSes. + home := os.Getenv("HOME") + if home != "" { + return filepath.Join(home, ".btcd") + } - // In the worst case, use the current directory. - return "." + // In the worst case, use the current directory. + return "." }