config.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. // Copyright (c) 2013-2017 The btcsuite developers
  2. // Copyright (c) 2019 Caleb James DeLisle
  3. // Use of this source code is governed by an ISC
  4. // license that can be found in the LICENSE file.
  5. package main
  6. import (
  7. crand "crypto/rand"
  8. "encoding/binary"
  9. "encoding/hex"
  10. "fmt"
  11. "io/ioutil"
  12. "math/rand"
  13. "net"
  14. "os"
  15. "path/filepath"
  16. "runtime"
  17. "strconv"
  18. "strings"
  19. "time"
  20. flags "github.com/jessevdk/go-flags"
  21. "github.com/pkt-cash/pktd/blockchain"
  22. "github.com/pkt-cash/pktd/btcutil"
  23. "github.com/pkt-cash/pktd/btcutil/er"
  24. "github.com/pkt-cash/pktd/chaincfg"
  25. "github.com/pkt-cash/pktd/chaincfg/chainhash"
  26. "github.com/pkt-cash/pktd/chaincfg/globalcfg"
  27. "github.com/pkt-cash/pktd/database"
  28. _ "github.com/pkt-cash/pktd/database/ffldb"
  29. "github.com/pkt-cash/pktd/mempool"
  30. "github.com/pkt-cash/pktd/peer"
  31. "github.com/pkt-cash/pktd/pktlog/log"
  32. )
  33. const (
  34. defaultConfigFilename = "pktd.conf"
  35. defaultDataDirname = "data"
  36. defaultLogLevel = "info"
  37. defaultLogDirname = "logs"
  38. defaultMaxPeers = 125
  39. defaultBanDuration = time.Hour * 24
  40. defaultBanThreshold = 120
  41. defaultConnectTimeout = time.Second * 10
  42. defaultMaxRPCClients = 10
  43. defaultMaxRPCWebsockets = 25
  44. defaultMaxRPCConcurrentReqs = 20
  45. defaultDbType = "ffldb"
  46. defaultFreeTxRelayLimit = 15.0
  47. defaultTrickleInterval = peer.DefaultTrickleInterval
  48. defaultBlockMinSize = 0
  49. defaultBlockMaxSize = 750000
  50. defaultBlockMinWeight = 0
  51. defaultBlockMaxWeight = 3000000
  52. blockMaxSizeMin = 1000
  53. blockMaxSizeMax = blockchain.MaxBlockBaseSize - 1000
  54. blockMaxWeightMin = 4000
  55. blockMaxWeightMax = blockchain.MaxBlockWeight - 4000
  56. defaultGenerate = false
  57. defaultMaxOrphanTransactions = 100
  58. defaultMaxOrphanTxSize = 100000
  59. defaultSigCacheMaxSize = 100000
  60. defaultTxIndex = false
  61. defaultAddrIndex = false
  62. )
  63. var (
  64. defaultHomeDir = btcutil.AppDataDir("pktd", false)
  65. defaultConfigFile = filepath.Join(defaultHomeDir, defaultConfigFilename)
  66. defaultDataDir = filepath.Join(defaultHomeDir, defaultDataDirname)
  67. knownDbTypes = database.SupportedDrivers()
  68. defaultRPCKeyFile = filepath.Join(defaultHomeDir, "rpc.key")
  69. defaultRPCCertFile = filepath.Join(defaultHomeDir, "rpc.cert")
  70. defaultLogDir = filepath.Join(defaultHomeDir, defaultLogDirname)
  71. )
  72. // runServiceCommand is only set to a real function on Windows. It is used
  73. // to parse and execute service commands specified via the -s flag.
  74. var runServiceCommand func(string) er.R
  75. // minUint32 is a helper function to return the minimum of two uint32s.
  76. // This avoids a math import and the need to cast to floats.
  77. func minUint32(a, b uint32) uint32 {
  78. if a < b {
  79. return a
  80. }
  81. return b
  82. }
  83. // config defines the configuration options for pktd.
  84. //
  85. // See loadConfig for details on the configuration load process.
  86. type config struct {
  87. ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
  88. ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
  89. DataDir string `short:"b" long:"datadir" description:"Directory to store data"`
  90. LogDir string `long:"logdir" description:"Directory to log output."`
  91. AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"`
  92. ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"`
  93. DisableListen bool `long:"nolisten" description:"Disable listening for incoming connections -- NOTE: Listening is automatically disabled if the --connect option is used without also specifying listening interfaces via --listen"`
  94. Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"`
  95. MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"`
  96. DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"`
  97. BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"`
  98. BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."`
  99. Whitelists []string `long:"whitelist" description:"Add an IP network or IP that will not be banned. (eg. 192.168.1.0/24 or ::1)"`
  100. AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause pktd to reject any peers whose user-agent contains any of the blacklisted substrings."`
  101. AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause pktd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."`
  102. HomeDir string `long:"homedir" description:"Creates this directory at startup"`
  103. RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"`
  104. RPCPass string `short:"P" long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
  105. RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"`
  106. RPCLimitPass string `long:"rpclimitpass" default-mask:"-" description:"Password for limited RPC connections"`
  107. RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"`
  108. RPCCert string `long:"rpccert" description:"File containing the certificate file"`
  109. RPCKey string `long:"rpckey" description:"File containing the certificate key"`
  110. RPCMaxClients int `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"`
  111. RPCMaxWebsockets int `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"`
  112. RPCMaxConcurrentReqs int `long:"rpcmaxconcurrentreqs" description:"Max number of concurrent RPC requests that may be processed concurrently"`
  113. RPCQuirks bool `long:"rpcquirks" description:"Mirror some JSON-RPC quirks of Bitcoin Core -- NOTE: Discouraged unless interoperability issues need to be worked around"`
  114. DisableRPC bool `long:"norpc" description:"Disable built-in RPC server -- NOTE: The RPC server is disabled by default if no rpcuser/rpcpass or rpclimituser/rpclimitpass is specified"`
  115. DisableTLS bool `long:"notls" description:"Nolonger used, see --tls" hidden:"true"`
  116. EnableTLS bool `long:"tls" description:"Enable TLS for the RPC server -- default is disabled unless bound to non-localhost"`
  117. DisableDNSSeed bool `long:"nodnsseed" description:"Disable DNS seeding for peers"`
  118. ExternalIPs []string `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"`
  119. TestNet3 bool `long:"testnet" description:"Use the test network"`
  120. PktTest bool `long:"pkttest" description:"Use the pkt.cash test network"`
  121. BtcMainNet bool `long:"btc" description:"Use the bitcoin main network"`
  122. PktMainNet bool `long:"pkt" description:"Use the pkt.cash main network"`
  123. RegressionTest bool `long:"regtest" description:"Use the regression test network"`
  124. SimNet bool `long:"simnet" description:"Use the simulation test network"`
  125. AddCheckpoints []string `long:"addcheckpoint" description:"Add a custom checkpoint. Format: '<height>:<hash>'"`
  126. DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."`
  127. DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"`
  128. StatsViz string `long:"statsviz" description:"Enable StatsViz runtime visualization on given port -- NOTE port must be between 1024 and 65535"`
  129. Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65535"`
  130. CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
  131. DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
  132. Upnp bool `long:"upnp" description:"Use UPnP to map our listening port outside of NAT"`
  133. MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in BTC/kB to be considered a non-zero fee."`
  134. FreeTxRelayLimit float64 `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"`
  135. NoRelayPriority bool `long:"norelaypriority" description:"Do not require free or low-fee transactions to have high priority for relaying"`
  136. TrickleInterval time.Duration `long:"trickleinterval" description:"Minimum time between attempts to send new inventory to a connected peer"`
  137. MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"`
  138. Generate bool `long:"generate" description:"Generate (mine) bitcoins using the CPU"`
  139. MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"`
  140. BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"`
  141. BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"`
  142. BlockMinWeight uint32 `long:"blockminweight" description:"Mininum block weight to be used when creating a block"`
  143. BlockMaxWeight uint32 `long:"blockmaxweight" description:"Maximum block weight to be used when creating a block"`
  144. BlockPrioritySize uint32 `long:"blockprioritysize" description:"Size in bytes for high-priority/low-fee transactions when creating a block"`
  145. UserAgentComments []string `long:"uacomment" description:"Comment to add to the user agent -- See BIP 14 for more information."`
  146. NoPeerBloomFilters bool `long:"nopeerbloomfilters" description:"Disable bloom filtering support"`
  147. NoCFilters bool `long:"nocfilters" description:"Disable committed filtering (CF) support"`
  148. DropCfIndex bool `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."`
  149. SigCacheMaxSize uint `long:"sigcachemaxsize" description:"The maximum number of entries in the signature verification cache"`
  150. BlocksOnly bool `long:"blocksonly" description:"Do not accept transactions from remote peers."`
  151. TxIndex bool `long:"txindex" description:"Maintain a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"`
  152. DropTxIndex bool `long:"droptxindex" description:"Deletes the hash-based transaction index from the database on start up and then exits."`
  153. AddrIndex bool `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"`
  154. DropAddrIndex bool `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."`
  155. RelayNonStd bool `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."`
  156. RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."`
  157. RejectReplacement bool `long:"rejectreplacement" description:"Reject transactions that attempt to replace existing transactions within the mempool through the Replace-By-Fee (RBF) signaling policy."`
  158. MiningSkipChecks string `long:"miningskipchecks" description:"Either 'txns', 'template' or 'both', skips certain time-consuming checks during mining process, be careful as you might create invalid block templates!"`
  159. lookup func(string) ([]net.IP, er.R)
  160. dial func(string, string, time.Duration) (net.Conn, er.R)
  161. addCheckpoints []chaincfg.Checkpoint
  162. miningAddrs map[btcutil.Address]float64
  163. minRelayTxFee btcutil.Amount
  164. whitelists []*net.IPNet
  165. }
  166. // serviceOptions defines the configuration options for the daemon as a service on
  167. // Windows.
  168. type serviceOptions struct {
  169. ServiceCommand string `short:"s" long:"service" description:"Service command {install, remove, start, stop}"`
  170. }
  171. // cleanAndExpandPath expands environment variables and leading ~ in the
  172. // passed path, cleans the result, and returns it.
  173. func cleanAndExpandPath(path string) string {
  174. // Expand initial ~ to OS specific home directory.
  175. if strings.HasPrefix(path, "~") {
  176. homeDir := filepath.Dir(defaultHomeDir)
  177. path = strings.Replace(path, "~", homeDir, 1)
  178. }
  179. // NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
  180. // but they variables can still be expanded via POSIX-style $VARIABLE.
  181. return filepath.Clean(os.ExpandEnv(path))
  182. }
  183. // validLogLevel returns whether or not logLevel is a valid debug log level.
  184. func validLogLevel(logLevel string) bool {
  185. switch logLevel {
  186. case "trace":
  187. fallthrough
  188. case "debug":
  189. fallthrough
  190. case "info":
  191. fallthrough
  192. case "warn":
  193. fallthrough
  194. case "error":
  195. fallthrough
  196. case "critical":
  197. return true
  198. }
  199. return false
  200. }
  201. // validDbType returns whether or not dbType is a supported database type.
  202. func validDbType(dbType string) bool {
  203. for _, knownType := range knownDbTypes {
  204. if dbType == knownType {
  205. return true
  206. }
  207. }
  208. return false
  209. }
  210. // removeDuplicateAddresses returns a new slice with all duplicate entries in
  211. // addrs removed.
  212. func removeDuplicateAddresses(addrs []string) []string {
  213. result := make([]string, 0, len(addrs))
  214. seen := map[string]struct{}{}
  215. for _, val := range addrs {
  216. if _, ok := seen[val]; !ok {
  217. result = append(result, val)
  218. seen[val] = struct{}{}
  219. }
  220. }
  221. return result
  222. }
  223. // normalizeAddress returns addr with the passed default port appended if
  224. // there is not already a port specified.
  225. func normalizeAddress(addr, defaultPort string) string {
  226. _, _, err := net.SplitHostPort(addr)
  227. if err != nil {
  228. return net.JoinHostPort(addr, defaultPort)
  229. }
  230. return addr
  231. }
  232. // normalizeAddresses returns a new slice with all the passed peer addresses
  233. // normalized with the given default port, and all duplicates removed.
  234. func normalizeAddresses(addrs []string, defaultPort string) []string {
  235. for i, addr := range addrs {
  236. addrs[i] = normalizeAddress(addr, defaultPort)
  237. }
  238. return removeDuplicateAddresses(addrs)
  239. }
  240. // newCheckpointFromStr parses checkpoints in the '<height>:<hash>' format.
  241. func newCheckpointFromStr(checkpoint string) (chaincfg.Checkpoint, er.R) {
  242. parts := strings.Split(checkpoint, ":")
  243. if len(parts) != 2 {
  244. return chaincfg.Checkpoint{}, er.Errorf("unable to parse "+
  245. "checkpoint %q -- use the syntax <height>:<hash>",
  246. checkpoint)
  247. }
  248. height, errr := strconv.ParseInt(parts[0], 10, 32)
  249. if errr != nil {
  250. return chaincfg.Checkpoint{}, er.Errorf("unable to parse "+
  251. "checkpoint %q due to malformed height", checkpoint)
  252. }
  253. if parts[1] == "" {
  254. return chaincfg.Checkpoint{}, er.Errorf("unable to parse "+
  255. "checkpoint %q due to missing hash", checkpoint)
  256. }
  257. hash, err := chainhash.NewHashFromStr(parts[1])
  258. if err != nil {
  259. return chaincfg.Checkpoint{}, er.Errorf("unable to parse "+
  260. "checkpoint %q due to malformed hash", checkpoint)
  261. }
  262. return chaincfg.Checkpoint{
  263. Height: int32(height),
  264. Hash: hash,
  265. }, nil
  266. }
  267. // parseCheckpoints checks the checkpoint strings for valid syntax
  268. // ('<height>:<hash>') and parses them to chaincfg.Checkpoint instances.
  269. func parseCheckpoints(checkpointStrings []string) ([]chaincfg.Checkpoint, er.R) {
  270. if len(checkpointStrings) == 0 {
  271. return nil, nil
  272. }
  273. checkpoints := make([]chaincfg.Checkpoint, len(checkpointStrings))
  274. for i, cpString := range checkpointStrings {
  275. checkpoint, err := newCheckpointFromStr(cpString)
  276. if err != nil {
  277. return nil, err
  278. }
  279. checkpoints[i] = checkpoint
  280. }
  281. return checkpoints, nil
  282. }
  283. // filesExists reports whether the named file or directory exists.
  284. func fileExists(name string) bool {
  285. if _, err := os.Stat(name); err != nil {
  286. if os.IsNotExist(err) {
  287. return false
  288. }
  289. }
  290. return true
  291. }
  292. // newConfigParser returns a new command line flags parser.
  293. func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *flags.Parser {
  294. parser := flags.NewParser(cfg, options)
  295. if runtime.GOOS == "windows" {
  296. parser.AddGroup("Service Options", "Service Options", so)
  297. }
  298. return parser
  299. }
  300. // loadConfig initializes and parses the config using a config file and command
  301. // line options.
  302. //
  303. // The configuration proceeds as follows:
  304. // 1) Start with a default config with sane settings
  305. // 2) Pre-parse the command line to check for an alternative config file
  306. // 3) Load configuration file overwriting defaults with any specified options
  307. // 4) Parse CLI options and overwrite/add any specified options
  308. //
  309. // The above results in pktd functioning properly without any config settings
  310. // while still allowing the user to override settings with config files and
  311. // command line options. Command line options always take precedence.
  312. func loadConfig() (*config, []string, er.R) {
  313. // Default config.
  314. cfg := config{
  315. ConfigFile: defaultConfigFile,
  316. DebugLevel: defaultLogLevel,
  317. MaxPeers: defaultMaxPeers,
  318. BanDuration: defaultBanDuration,
  319. BanThreshold: defaultBanThreshold,
  320. RPCMaxClients: defaultMaxRPCClients,
  321. RPCMaxWebsockets: defaultMaxRPCWebsockets,
  322. RPCMaxConcurrentReqs: defaultMaxRPCConcurrentReqs,
  323. HomeDir: defaultHomeDir,
  324. DataDir: defaultDataDir,
  325. LogDir: defaultLogDir,
  326. DbType: defaultDbType,
  327. RPCKey: defaultRPCKeyFile,
  328. RPCCert: defaultRPCCertFile,
  329. MinRelayTxFee: -1, // this gets configured later
  330. FreeTxRelayLimit: defaultFreeTxRelayLimit,
  331. TrickleInterval: defaultTrickleInterval,
  332. BlockMinSize: defaultBlockMinSize,
  333. BlockMaxSize: defaultBlockMaxSize,
  334. BlockMinWeight: defaultBlockMinWeight,
  335. BlockMaxWeight: defaultBlockMaxWeight,
  336. BlockPrioritySize: mempool.DefaultBlockPrioritySize,
  337. MaxOrphanTxs: defaultMaxOrphanTransactions,
  338. SigCacheMaxSize: defaultSigCacheMaxSize,
  339. Generate: defaultGenerate,
  340. TxIndex: defaultTxIndex,
  341. AddrIndex: defaultAddrIndex,
  342. }
  343. // Service options which are only added on Windows.
  344. serviceOpts := serviceOptions{}
  345. // Pre-parse the command line options to see if an alternative config
  346. // file or the version flag was specified. Any errors aside from the
  347. // help message error can be ignored here since they will be caught by
  348. // the final parse below.
  349. preCfg := cfg
  350. preParser := newConfigParser(&preCfg, &serviceOpts, flags.HelpFlag)
  351. _, errr := preParser.Parse()
  352. if errr != nil {
  353. if e, ok := errr.(*flags.Error); ok && e.Type == flags.ErrHelp {
  354. fmt.Fprintln(os.Stderr, errr)
  355. return nil, nil, er.E(errr)
  356. }
  357. }
  358. // Just need to exit if the version flag was specified
  359. appName := filepath.Base(os.Args[0])
  360. appName = strings.TrimSuffix(appName, filepath.Ext(appName))
  361. usageMessage := fmt.Sprintf("Use %s -h to show usage", appName)
  362. if preCfg.ShowVersion {
  363. os.Exit(0)
  364. }
  365. // Perform service command and exit if specified. Invalid service
  366. // commands show an appropriate error. Only runs on Windows since
  367. // the runServiceCommand function will be nil when not on Windows.
  368. if serviceOpts.ServiceCommand != "" && runServiceCommand != nil {
  369. err := runServiceCommand(serviceOpts.ServiceCommand)
  370. if err != nil {
  371. fmt.Fprintln(os.Stderr, err)
  372. }
  373. os.Exit(0)
  374. }
  375. // Load additional config from file.
  376. configNotFound := false
  377. parser := newConfigParser(&cfg, &serviceOpts, flags.Default)
  378. if !(preCfg.RegressionTest || preCfg.SimNet) || preCfg.ConfigFile !=
  379. defaultConfigFile {
  380. errr := flags.NewIniParser(parser).ParseFile(preCfg.ConfigFile)
  381. if errr != nil {
  382. if _, ok := errr.(*os.PathError); !ok {
  383. fmt.Fprintf(os.Stderr, "Error parsing config "+
  384. "file: %v\n", errr)
  385. fmt.Fprintln(os.Stderr, usageMessage)
  386. return nil, nil, er.E(errr)
  387. }
  388. configNotFound = true
  389. }
  390. }
  391. // Don't add peers from the config file when in regression test mode.
  392. if preCfg.RegressionTest && len(cfg.AddPeers) > 0 {
  393. cfg.AddPeers = nil
  394. }
  395. // Parse command line options again to ensure they take precedence.
  396. remainingArgs, errr := parser.Parse()
  397. if errr != nil {
  398. if e, ok := errr.(*flags.Error); !ok || e.Type != flags.ErrHelp {
  399. fmt.Fprintln(os.Stderr, usageMessage)
  400. }
  401. return nil, nil, er.E(errr)
  402. }
  403. // Create the home directory if it doesn't already exist.
  404. funcName := "loadConfig"
  405. errr = os.MkdirAll(cfg.HomeDir, 0o700)
  406. if errr != nil {
  407. // Show a nicer error message if it's because a symlink is
  408. // linked to a directory that does not exist (probably because
  409. // it's not mounted).
  410. if e, ok := errr.(*os.PathError); ok && os.IsExist(errr) {
  411. if link, lerr := os.Readlink(e.Path); lerr == nil {
  412. str := "is symlink %s -> %s mounted?"
  413. errr = fmt.Errorf(str, e.Path, link)
  414. }
  415. }
  416. str := "%s: Failed to create home directory: %v"
  417. err := er.Errorf(str, funcName, errr)
  418. fmt.Fprintln(os.Stderr, err)
  419. return nil, nil, err
  420. }
  421. // Multiple networks can't be selected simultaneously.
  422. numNets := 0
  423. // Count number of network flags passed; assign active network params
  424. // while we're at it
  425. if cfg.TestNet3 {
  426. numNets++
  427. activeNetParams = &testNet3Params
  428. }
  429. if cfg.PktTest {
  430. numNets++
  431. activeNetParams = &pktTestNetParams
  432. }
  433. if cfg.BtcMainNet {
  434. numNets++
  435. activeNetParams = &mainNetParams
  436. }
  437. if cfg.PktMainNet {
  438. numNets++
  439. activeNetParams = &pktMainNetParams
  440. }
  441. if cfg.RegressionTest {
  442. numNets++
  443. activeNetParams = &regressionNetParams
  444. }
  445. if cfg.SimNet {
  446. numNets++
  447. // Also disable dns seeding on the simulation test network.
  448. activeNetParams = &simNetParams
  449. cfg.DisableDNSSeed = true
  450. }
  451. if numNets > 1 {
  452. str := "%s: The testnet, regtest, segnet, and simnet params " +
  453. "can't be used together -- choose one of the four"
  454. err := er.Errorf(str, funcName)
  455. fmt.Fprintln(os.Stderr, err)
  456. fmt.Fprintln(os.Stderr, usageMessage)
  457. return nil, nil, err
  458. }
  459. // TODO(cjd): this is trash, but CompactToBig is a util function and it shouldn't
  460. // be in blockchain, but it is, and trying to call it from cfg is a dependency
  461. // loop. And duplicating the powlimit twice in the config is also trash...
  462. activeNetParams.PowLimit = blockchain.CompactToBig(activeNetParams.PowLimitBits)
  463. globalcfg.SelectConfig(activeNetParams.GlobalConf)
  464. // Set the default policy for relaying non-standard transactions
  465. // according to the default of the active network. The set
  466. // configuration value takes precedence over the default value for the
  467. // selected network.
  468. relayNonStd := activeNetParams.RelayNonStdTxs
  469. switch {
  470. case cfg.RelayNonStd && cfg.RejectNonStd:
  471. str := "%s: rejectnonstd and relaynonstd cannot be used " +
  472. "together -- choose only one"
  473. err := er.Errorf(str, funcName)
  474. fmt.Fprintln(os.Stderr, err)
  475. fmt.Fprintln(os.Stderr, usageMessage)
  476. return nil, nil, err
  477. case cfg.RejectNonStd:
  478. relayNonStd = false
  479. case cfg.RelayNonStd:
  480. relayNonStd = true
  481. }
  482. cfg.RelayNonStd = relayNonStd
  483. // Append the network type to the data directory so it is "namespaced"
  484. // per network. In addition to the block database, there are other
  485. // pieces of data that are saved to disk such as address manager state.
  486. // All data is specific to a network, so namespacing the data directory
  487. // means each individual piece of serialized data does not have to
  488. // worry about changing names per network and such.
  489. cfg.DataDir = cleanAndExpandPath(cfg.DataDir)
  490. cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams))
  491. // Append the network type to the log directory so it is "namespaced"
  492. // per network in the same fashion as the data directory.
  493. cfg.LogDir = cleanAndExpandPath(cfg.LogDir)
  494. cfg.LogDir = filepath.Join(cfg.LogDir, netName(activeNetParams))
  495. // Parse, validate, and set debug log level(s).
  496. if err := log.SetLogLevels(cfg.DebugLevel); err != nil {
  497. err := er.Errorf("%s: %v", funcName, err)
  498. fmt.Fprintln(os.Stderr, err)
  499. fmt.Fprintln(os.Stderr, usageMessage)
  500. return nil, nil, err
  501. }
  502. // Validate database type.
  503. if !validDbType(cfg.DbType) {
  504. str := "%s: The specified database type [%v] is invalid -- " +
  505. "supported types %v"
  506. err := er.Errorf(str, funcName, cfg.DbType, knownDbTypes)
  507. fmt.Fprintln(os.Stderr, err)
  508. fmt.Fprintln(os.Stderr, usageMessage)
  509. return nil, nil, err
  510. }
  511. // Validate profile port number
  512. if cfg.Profile != "" {
  513. profilePort, err := strconv.Atoi(cfg.Profile)
  514. if err != nil || profilePort < 1024 || profilePort > 65535 {
  515. str := "%s: The profile port must be between 1024 and 65535"
  516. err := er.Errorf(str, funcName)
  517. fmt.Fprintln(os.Stderr, err)
  518. fmt.Fprintln(os.Stderr, usageMessage)
  519. return nil, nil, err
  520. }
  521. }
  522. // Validate StatsViz port number
  523. if cfg.StatsViz != "" {
  524. statsvizPort, err := strconv.Atoi(cfg.StatsViz)
  525. if err != nil || statsvizPort < 1024 || statsvizPort > 65535 {
  526. str := "%s: The StatsViz port must be between 1024 and 65535"
  527. err := er.Errorf(str, funcName)
  528. fmt.Fprintln(os.Stderr, err)
  529. fmt.Fprintln(os.Stderr, usageMessage)
  530. return nil, nil, err
  531. }
  532. }
  533. // Don't allow ban durations that are too short.
  534. if cfg.BanDuration < time.Second {
  535. str := "%s: The banduration option may not be less than 1s -- parsed [%v]"
  536. err := er.Errorf(str, funcName, cfg.BanDuration)
  537. fmt.Fprintln(os.Stderr, err)
  538. fmt.Fprintln(os.Stderr, usageMessage)
  539. return nil, nil, err
  540. }
  541. // Validate any given whitelisted IP addresses and networks.
  542. if len(cfg.Whitelists) > 0 {
  543. var ip net.IP
  544. cfg.whitelists = make([]*net.IPNet, 0, len(cfg.Whitelists))
  545. for _, addr := range cfg.Whitelists {
  546. _, ipnet, err := net.ParseCIDR(addr)
  547. if err != nil {
  548. ip = net.ParseIP(addr)
  549. if ip == nil {
  550. str := "%s: The whitelist value of '%s' is invalid"
  551. err := er.Errorf(str, funcName, addr)
  552. fmt.Fprintln(os.Stderr, err)
  553. fmt.Fprintln(os.Stderr, usageMessage)
  554. return nil, nil, err
  555. }
  556. var bits int
  557. if ip.To4() == nil {
  558. // IPv6
  559. bits = 128
  560. } else {
  561. bits = 32
  562. }
  563. ipnet = &net.IPNet{
  564. IP: ip,
  565. Mask: net.CIDRMask(bits, bits),
  566. }
  567. }
  568. cfg.whitelists = append(cfg.whitelists, ipnet)
  569. }
  570. }
  571. // --addPeer and --connect do not mix.
  572. if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 {
  573. str := "%s: the --addpeer and --connect options can not be " +
  574. "mixed"
  575. err := er.Errorf(str, funcName)
  576. fmt.Fprintln(os.Stderr, err)
  577. fmt.Fprintln(os.Stderr, usageMessage)
  578. return nil, nil, err
  579. }
  580. // --connect without --listen disables listening.
  581. if len(cfg.ConnectPeers) > 0 &&
  582. len(cfg.Listeners) == 0 {
  583. cfg.DisableListen = true
  584. }
  585. // Connect means no DNS seeding.
  586. if len(cfg.ConnectPeers) > 0 {
  587. cfg.DisableDNSSeed = true
  588. }
  589. // Add the default listener if none were specified. The default
  590. // listener is all addresses on the listen port for the network
  591. // we are to connect to.
  592. if len(cfg.Listeners) == 0 {
  593. cfg.Listeners = []string{
  594. net.JoinHostPort("", activeNetParams.DefaultPort),
  595. }
  596. }
  597. // Check to make sure limited and admin users don't have the same username
  598. if cfg.RPCUser == cfg.RPCLimitUser && cfg.RPCUser != "" {
  599. str := "%s: --rpcuser and --rpclimituser must not specify the " +
  600. "same username"
  601. err := er.Errorf(str, funcName)
  602. fmt.Fprintln(os.Stderr, err)
  603. fmt.Fprintln(os.Stderr, usageMessage)
  604. return nil, nil, err
  605. }
  606. // Check to make sure limited and admin users don't have the same password
  607. if cfg.RPCPass == cfg.RPCLimitPass && cfg.RPCPass != "" {
  608. str := "%s: --rpcpass and --rpclimitpass must not specify the " +
  609. "same password"
  610. err := er.Errorf(str, funcName)
  611. fmt.Fprintln(os.Stderr, err)
  612. fmt.Fprintln(os.Stderr, usageMessage)
  613. return nil, nil, err
  614. }
  615. if cfg.RPCUser == "" || cfg.RPCPass == "" {
  616. log.Infof("Creating a new .pktcookie authorization file")
  617. cookiePath := filepath.Join(defaultHomeDir, ".pktcookie")
  618. var buf [32]byte
  619. var src cryptoSource
  620. rnd := rand.New(src)
  621. if _, errr := rnd.Read(buf[:]); errr != nil {
  622. err := er.E(errr)
  623. err.AddMessage("Unable to get random numbers")
  624. return nil, nil, err
  625. }
  626. cfg.RPCUser = "__PKT_COOKIE__"
  627. cfg.RPCPass = hex.EncodeToString(buf[:])
  628. cookie := cfg.RPCUser + ":" + cfg.RPCPass
  629. if errr := ioutil.WriteFile(cookiePath, []byte(cookie), 0o600); errr != nil {
  630. err := er.E(errr)
  631. err.AddMessage("Could not write .pktcookie file")
  632. return nil, nil, err
  633. }
  634. }
  635. // The RPC server is disabled if no username or password is provided.
  636. if (cfg.RPCUser == "" || cfg.RPCPass == "") &&
  637. (cfg.RPCLimitUser == "" || cfg.RPCLimitPass == "") {
  638. cfg.DisableRPC = true
  639. }
  640. if cfg.DisableRPC {
  641. log.Infof("RPC service is disabled")
  642. }
  643. // Default RPC to listen on localhost only.
  644. if !cfg.DisableRPC && len(cfg.RPCListeners) == 0 {
  645. addrs, errr := net.LookupHost("localhost")
  646. if errr != nil {
  647. return nil, nil, er.E(errr)
  648. }
  649. cfg.RPCListeners = make([]string, 0, len(addrs))
  650. for _, addr := range addrs {
  651. addr = net.JoinHostPort(addr, activeNetParams.rpcPort)
  652. cfg.RPCListeners = append(cfg.RPCListeners, addr)
  653. }
  654. }
  655. if cfg.RPCMaxConcurrentReqs < 0 {
  656. str := "%s: The rpcmaxwebsocketconcurrentrequests option may " +
  657. "not be less than 0 -- parsed [%d]"
  658. err := er.Errorf(str, funcName, cfg.RPCMaxConcurrentReqs)
  659. fmt.Fprintln(os.Stderr, err)
  660. fmt.Fprintln(os.Stderr, usageMessage)
  661. return nil, nil, err
  662. }
  663. // Validate the the minrelaytxfee.
  664. if cfg.MinRelayTxFee >= 0 {
  665. mrf, err := globalcfg.NewAmount(cfg.MinRelayTxFee)
  666. if err != nil {
  667. str := "%s: invalid minrelaytxfee: %v"
  668. err := er.Errorf(str, funcName, err)
  669. fmt.Fprintln(os.Stderr, err)
  670. fmt.Fprintln(os.Stderr, usageMessage)
  671. return nil, nil, err
  672. }
  673. cfg.minRelayTxFee = btcutil.Amount(mrf)
  674. } else {
  675. cfg.minRelayTxFee = mempool.DefaultMinRelayTxFee
  676. cfg.MinRelayTxFee = btcutil.Amount(cfg.minRelayTxFee).ToBTC()
  677. }
  678. // Limit the max block size to a sane value.
  679. if cfg.BlockMaxSize < blockMaxSizeMin || cfg.BlockMaxSize >
  680. blockMaxSizeMax {
  681. str := "%s: The blockmaxsize option must be in between %d " +
  682. "and %d -- parsed [%d]"
  683. err := er.Errorf(str, funcName, blockMaxSizeMin,
  684. blockMaxSizeMax, cfg.BlockMaxSize)
  685. fmt.Fprintln(os.Stderr, err)
  686. fmt.Fprintln(os.Stderr, usageMessage)
  687. return nil, nil, err
  688. }
  689. // Limit the max block weight to a sane value.
  690. if cfg.BlockMaxWeight < blockMaxWeightMin ||
  691. cfg.BlockMaxWeight > blockMaxWeightMax {
  692. str := "%s: The blockmaxweight option must be in between %d " +
  693. "and %d -- parsed [%d]"
  694. err := er.Errorf(str, funcName, blockMaxWeightMin,
  695. blockMaxWeightMax, cfg.BlockMaxWeight)
  696. fmt.Fprintln(os.Stderr, err)
  697. fmt.Fprintln(os.Stderr, usageMessage)
  698. return nil, nil, err
  699. }
  700. // Limit the max orphan count to a sane vlue.
  701. if cfg.MaxOrphanTxs < 0 {
  702. str := "%s: The maxorphantx option may not be less than 0 " +
  703. "-- parsed [%d]"
  704. err := er.Errorf(str, funcName, cfg.MaxOrphanTxs)
  705. fmt.Fprintln(os.Stderr, err)
  706. fmt.Fprintln(os.Stderr, usageMessage)
  707. return nil, nil, err
  708. }
  709. // Limit the block priority and minimum block sizes to max block size.
  710. cfg.BlockPrioritySize = minUint32(cfg.BlockPrioritySize, cfg.BlockMaxSize)
  711. cfg.BlockMinSize = minUint32(cfg.BlockMinSize, cfg.BlockMaxSize)
  712. cfg.BlockMinWeight = minUint32(cfg.BlockMinWeight, cfg.BlockMaxWeight)
  713. switch {
  714. // If the max block size isn't set, but the max weight is, then we'll
  715. // set the limit for the max block size to a safe limit so weight takes
  716. // precedence.
  717. case cfg.BlockMaxSize == defaultBlockMaxSize &&
  718. cfg.BlockMaxWeight != defaultBlockMaxWeight:
  719. cfg.BlockMaxSize = blockchain.MaxBlockBaseSize - 1000
  720. // If the max block weight isn't set, but the block size is, then we'll
  721. // scale the set weight accordingly based on the max block size value.
  722. case cfg.BlockMaxSize != defaultBlockMaxSize &&
  723. cfg.BlockMaxWeight == defaultBlockMaxWeight:
  724. cfg.BlockMaxWeight = cfg.BlockMaxSize * blockchain.WitnessScaleFactor
  725. }
  726. // Look for illegal characters in the user agent comments.
  727. for _, uaComment := range cfg.UserAgentComments {
  728. if strings.ContainsAny(uaComment, "/:()") {
  729. err := er.Errorf("%s: The following characters must not "+
  730. "appear in user agent comments: '/', ':', '(', ')'",
  731. funcName)
  732. fmt.Fprintln(os.Stderr, err)
  733. fmt.Fprintln(os.Stderr, usageMessage)
  734. return nil, nil, err
  735. }
  736. }
  737. // --txindex and --droptxindex do not mix.
  738. if cfg.TxIndex && cfg.DropTxIndex {
  739. err := er.Errorf("%s: the --txindex and --droptxindex "+
  740. "options may not be activated at the same time",
  741. funcName)
  742. fmt.Fprintln(os.Stderr, err)
  743. fmt.Fprintln(os.Stderr, usageMessage)
  744. return nil, nil, err
  745. }
  746. // --addrindex and --dropaddrindex do not mix.
  747. if cfg.AddrIndex && cfg.DropAddrIndex {
  748. err := er.Errorf("%s: the --addrindex and --dropaddrindex "+
  749. "options may not be activated at the same time",
  750. funcName)
  751. fmt.Fprintln(os.Stderr, err)
  752. fmt.Fprintln(os.Stderr, usageMessage)
  753. return nil, nil, err
  754. }
  755. // --addrindex and --droptxindex do not mix.
  756. if cfg.AddrIndex && cfg.DropTxIndex {
  757. err := er.Errorf("%s: the --addrindex and --droptxindex "+
  758. "options may not be activated at the same time "+
  759. "because the address index relies on the transaction "+
  760. "index",
  761. funcName)
  762. fmt.Fprintln(os.Stderr, err)
  763. fmt.Fprintln(os.Stderr, usageMessage)
  764. return nil, nil, err
  765. }
  766. // Check mining addresses are valid and saved parsed versions.
  767. cfg.miningAddrs = make(map[btcutil.Address]float64)
  768. for _, strAddr := range cfg.MiningAddrs {
  769. addr, err := btcutil.DecodeAddress(strAddr, activeNetParams.Params)
  770. if err != nil {
  771. str := "%s: mining address '%s' failed to decode: %v"
  772. err := er.Errorf(str, funcName, strAddr, err)
  773. fmt.Fprintln(os.Stderr, err)
  774. fmt.Fprintln(os.Stderr, usageMessage)
  775. return nil, nil, err
  776. }
  777. if !addr.IsForNet(activeNetParams.Params) {
  778. str := "%s: mining address '%s' is on the wrong network"
  779. err := er.Errorf(str, funcName, strAddr)
  780. fmt.Fprintln(os.Stderr, err)
  781. fmt.Fprintln(os.Stderr, usageMessage)
  782. return nil, nil, err
  783. }
  784. cfg.miningAddrs[addr] = float64(1)
  785. }
  786. // Ensure there is at least one mining address when the generate flag is
  787. // set.
  788. if cfg.Generate && len(cfg.MiningAddrs) == 0 {
  789. str := "%s: the generate flag is set, but there are no mining " +
  790. "addresses specified "
  791. err := er.Errorf(str, funcName)
  792. fmt.Fprintln(os.Stderr, err)
  793. fmt.Fprintln(os.Stderr, usageMessage)
  794. return nil, nil, err
  795. }
  796. // Add default port to all listener addresses if needed and remove
  797. // duplicate addresses.
  798. cfg.Listeners = normalizeAddresses(cfg.Listeners,
  799. activeNetParams.DefaultPort)
  800. // Add default port to all rpc listener addresses if needed and remove
  801. // duplicate addresses.
  802. cfg.RPCListeners = normalizeAddresses(cfg.RPCListeners,
  803. activeNetParams.rpcPort)
  804. // Add default port to all added peer addresses if needed and remove
  805. // duplicate addresses.
  806. cfg.AddPeers = normalizeAddresses(cfg.AddPeers,
  807. activeNetParams.DefaultPort)
  808. cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers,
  809. activeNetParams.DefaultPort)
  810. // Check the checkpoints for syntax errors.
  811. var err er.R
  812. cfg.addCheckpoints, err = parseCheckpoints(cfg.AddCheckpoints)
  813. if err != nil {
  814. str := "%s: Error parsing checkpoints: %v"
  815. err := er.Errorf(str, funcName, err)
  816. fmt.Fprintln(os.Stderr, err)
  817. fmt.Fprintln(os.Stderr, usageMessage)
  818. return nil, nil, err
  819. }
  820. // Setup dial and DNS resolution (lookup) functions depending on the
  821. // specified options. The default is to use the standard
  822. // net.DialTimeout function as well as the system DNS resolver.
  823. cfg.dial = func(n, addr string, to time.Duration) (net.Conn, er.R) {
  824. ret, errr := net.DialTimeout(n, addr, to)
  825. return ret, er.E(errr)
  826. }
  827. cfg.lookup = func(host string) ([]net.IP, er.R) {
  828. out, errr := net.LookupIP(host)
  829. return out, er.E(errr)
  830. }
  831. // Warn about missing config file only after all other configuration is
  832. // done. This prevents the warning on help messages and invalid
  833. // options. Note this should go directly before the return.
  834. if configNotFound && preCfg.ConfigFile != defaultConfigFile {
  835. log.Warnf("Could not find config file [%s]", preCfg.ConfigFile)
  836. }
  837. return &cfg, remainingArgs, nil
  838. }
  839. // pktdDial connects to the address on the named network using the appropriate
  840. // dial function depending on the address and configuration options.
  841. func pktdDial(addr net.Addr) (net.Conn, er.R) {
  842. return cfg.dial(addr.Network(), addr.String(), defaultConnectTimeout)
  843. }
  844. // pktdLookup resolves the IP of the given host using the correct DNS lookup
  845. // function depending on the configuration options.
  846. func pktdLookup(host string) ([]net.IP, er.R) {
  847. return cfg.lookup(host)
  848. }
  849. type cryptoSource struct{}
  850. func (s cryptoSource) Seed(seed int64) {}
  851. func (s cryptoSource) Int63() int64 {
  852. return int64(s.Uint64() & ^uint64(1<<63))
  853. }
  854. func (s cryptoSource) Uint64() (v uint64) {
  855. err := binary.Read(crand.Reader, binary.BigEndian, &v)
  856. if err != nil {
  857. panic("CSPRNG failure: Could not read random numbers")
  858. }
  859. return v
  860. }