github.com/lbryio/lbcd@v0.22.119/cmd/addblock/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 defaultDbType = "ffldb" 22 defaultDataFile = "bootstrap.dat" 23 defaultProgress = 10 24 ) 25 26 var ( 27 btcdHomeDir = btcutil.AppDataDir("lbcd", false) 28 defaultDataDir = filepath.Join(btcdHomeDir, "data") 29 knownDbTypes = database.SupportedDrivers() 30 activeNetParams = &chaincfg.MainNetParams 31 ) 32 33 // config defines the configuration options for findcheckpoint. 34 // 35 // See loadConfig for details on the configuration load process. 36 type config struct { 37 AddrIndex bool `long:"addrindex" description:"Build a full address-based transaction index which makes the searchrawtransactions RPC available"` 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 InFile string `short:"i" long:"infile" description:"File containing the block(s)"` 41 Progress int `short:"p" long:"progress" description:"Show a progress message each time this number of seconds have passed -- Use 0 to disable progress announcements"` 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 TxIndex bool `long:"txindex" description:"Build a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"` 46 } 47 48 // filesExists reports whether the named file or directory exists. 49 func fileExists(name string) bool { 50 if _, err := os.Stat(name); err != nil { 51 if os.IsNotExist(err) { 52 return false 53 } 54 } 55 return true 56 } 57 58 // validDbType returns whether or not dbType is a supported database type. 59 func validDbType(dbType string) bool { 60 for _, knownType := range knownDbTypes { 61 if dbType == knownType { 62 return true 63 } 64 } 65 66 return false 67 } 68 69 // netName returns the name used when referring to a bitcoin network. At the 70 // time of writing, lbcd currently places blocks for testnet version 3 in the 71 // data and log directory "testnet", which does not match the Name field of the 72 // chaincfg parameters. This function can be used to override this directory name 73 // as "testnet" when the passed active network matches wire.TestNet3. 74 // 75 // A proper upgrade to move the data and log directories for this network to 76 // "testnet3" is planned for the future, at which point this function can be 77 // removed and the network parameter's name used instead. 78 func netName(chainParams *chaincfg.Params) string { 79 switch chainParams.Net { 80 case wire.TestNet3: 81 return "testnet" 82 default: 83 return chainParams.Name 84 } 85 } 86 87 // loadConfig initializes and parses the config using command line options. 88 func loadConfig() (*config, []string, error) { 89 // Default config. 90 cfg := config{ 91 DataDir: defaultDataDir, 92 DbType: defaultDbType, 93 InFile: defaultDataFile, 94 Progress: defaultProgress, 95 } 96 97 // Parse command line options. 98 parser := flags.NewParser(&cfg, flags.Default) 99 remainingArgs, err := parser.Parse() 100 if err != nil { 101 if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { 102 parser.WriteHelp(os.Stderr) 103 } 104 return nil, nil, err 105 } 106 107 // Multiple networks can't be selected simultaneously. 108 funcName := "loadConfig" 109 numNets := 0 110 // Count number of network flags passed; assign active network params 111 // while we're at it 112 if cfg.TestNet3 { 113 numNets++ 114 activeNetParams = &chaincfg.TestNet3Params 115 } 116 if cfg.RegressionTest { 117 numNets++ 118 activeNetParams = &chaincfg.RegressionNetParams 119 } 120 if cfg.SimNet { 121 numNets++ 122 activeNetParams = &chaincfg.SimNetParams 123 } 124 if numNets > 1 { 125 str := "%s: The testnet, regtest, and simnet params can't be " + 126 "used together -- choose one of the three" 127 err := fmt.Errorf(str, funcName) 128 fmt.Fprintln(os.Stderr, err) 129 parser.WriteHelp(os.Stderr) 130 return nil, nil, err 131 } 132 133 // Validate database type. 134 if !validDbType(cfg.DbType) { 135 str := "%s: The specified database type [%v] is invalid -- " + 136 "supported types %v" 137 err := fmt.Errorf(str, "loadConfig", cfg.DbType, knownDbTypes) 138 fmt.Fprintln(os.Stderr, err) 139 parser.WriteHelp(os.Stderr) 140 return nil, nil, err 141 } 142 143 // Append the network type to the data directory so it is "namespaced" 144 // per network. In addition to the block database, there are other 145 // pieces of data that are saved to disk such as address manager state. 146 // All data is specific to a network, so namespacing the data directory 147 // means each individual piece of serialized data does not have to 148 // worry about changing names per network and such. 149 cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams)) 150 151 // Ensure the specified block file exists. 152 if !fileExists(cfg.InFile) { 153 str := "%s: The specified block file [%v] does not exist" 154 err := fmt.Errorf(str, "loadConfig", cfg.InFile) 155 fmt.Fprintln(os.Stderr, err) 156 parser.WriteHelp(os.Stderr) 157 return nil, nil, err 158 } 159 160 return &cfg, remainingArgs, nil 161 }