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