github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/cmd/findcheckpoint/config.go (about) 1 // Copyright (c) 2013-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 "fmt" 10 "os" 11 "path/filepath" 12 13 flags "github.com/btcsuite/go-flags" 14 "github.com/BlockABC/godash/chaincfg" 15 "github.com/BlockABC/godash/database" 16 _ "github.com/BlockABC/godash/database/ffldb" 17 "github.com/BlockABC/godash/wire" 18 "github.com/BlockABC/godashutil" 19 ) 20 21 const ( 22 minCandidates = 1 23 maxCandidates = 20 24 defaultNumCandidates = 5 25 defaultDbType = "ffldb" 26 ) 27 28 var ( 29 btcdHomeDir = godashutil.AppDataDir("btcd", false) 30 defaultDataDir = filepath.Join(btcdHomeDir, "data") 31 knownDbTypes = database.SupportedDrivers() 32 activeNetParams = &chaincfg.MainNetParams 33 ) 34 35 // config defines the configuration options for findcheckpoint. 36 // 37 // See loadConfig for details on the configuration load process. 38 type config struct { 39 DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` 40 DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` 41 TestNet3 bool `long:"testnet" description:"Use the test network"` 42 RegressionTest bool `long:"regtest" description:"Use the regression test network"` 43 SimNet bool `long:"simnet" description:"Use the simulation test network"` 44 NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"` 45 UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"` 46 } 47 48 // validDbType returns whether or not dbType is a supported database type. 49 func validDbType(dbType string) bool { 50 for _, knownType := range knownDbTypes { 51 if dbType == knownType { 52 return true 53 } 54 } 55 56 return false 57 } 58 59 // netName returns the name used when referring to a bitcoin network. At the 60 // time of writing, btcd currently places blocks for testnet version 3 in the 61 // data and log directory "testnet", which does not match the Name field of the 62 // chaincfg parameters. This function can be used to override this directory name 63 // as "testnet" when the passed active network matches wire.TestNet3. 64 // 65 // A proper upgrade to move the data and log directories for this network to 66 // "testnet3" is planned for the future, at which point this function can be 67 // removed and the network parameter's name used instead. 68 func netName(chainParams *chaincfg.Params) string { 69 switch chainParams.Net { 70 case wire.TestNet3: 71 return "testnet" 72 default: 73 return chainParams.Name 74 } 75 } 76 77 // loadConfig initializes and parses the config using command line options. 78 func loadConfig() (*config, []string, error) { 79 // Default config. 80 cfg := config{ 81 DataDir: defaultDataDir, 82 DbType: defaultDbType, 83 NumCandidates: defaultNumCandidates, 84 } 85 86 // Parse command line options. 87 parser := flags.NewParser(&cfg, flags.Default) 88 remainingArgs, err := parser.Parse() 89 if err != nil { 90 if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { 91 parser.WriteHelp(os.Stderr) 92 } 93 return nil, nil, err 94 } 95 96 // Multiple networks can't be selected simultaneously. 97 funcName := "loadConfig" 98 numNets := 0 99 // Count number of network flags passed; assign active network params 100 // while we're at it 101 if cfg.TestNet3 { 102 numNets++ 103 activeNetParams = &chaincfg.TestNet3Params 104 } 105 if cfg.RegressionTest { 106 numNets++ 107 activeNetParams = &chaincfg.RegressionNetParams 108 } 109 if cfg.SimNet { 110 numNets++ 111 activeNetParams = &chaincfg.SimNetParams 112 } 113 if numNets > 1 { 114 str := "%s: The testnet, regtest, and simnet params can't be " + 115 "used together -- choose one of the three" 116 err := fmt.Errorf(str, funcName) 117 fmt.Fprintln(os.Stderr, err) 118 parser.WriteHelp(os.Stderr) 119 return nil, nil, err 120 } 121 122 // Validate database type. 123 if !validDbType(cfg.DbType) { 124 str := "%s: The specified database type [%v] is invalid -- " + 125 "supported types %v" 126 err := fmt.Errorf(str, "loadConfig", cfg.DbType, knownDbTypes) 127 fmt.Fprintln(os.Stderr, err) 128 parser.WriteHelp(os.Stderr) 129 return nil, nil, err 130 } 131 132 // Append the network type to the data directory so it is "namespaced" 133 // per network. In addition to the block database, there are other 134 // pieces of data that are saved to disk such as address manager state. 135 // All data is specific to a network, so namespacing the data directory 136 // means each individual piece of serialized data does not have to 137 // worry about changing names per network and such. 138 cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams)) 139 140 // Validate the number of candidates. 141 if cfg.NumCandidates < minCandidates || cfg.NumCandidates > maxCandidates { 142 str := "%s: The specified number of candidates is out of " + 143 "range -- parsed [%v]" 144 err = fmt.Errorf(str, "loadConfig", cfg.NumCandidates) 145 fmt.Fprintln(os.Stderr, err) 146 parser.WriteHelp(os.Stderr) 147 return nil, nil, err 148 } 149 150 return &cfg, remainingArgs, nil 151 }