1// Copyright (c) 2013-2017 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
5package main
6
7import (
8	"bufio"
9	"crypto/rand"
10	"encoding/base64"
11	"errors"
12	"fmt"
13	"io"
14	"net"
15	"os"
16	"path/filepath"
17	"runtime"
18	"sort"
19	"strconv"
20	"strings"
21	"time"
22
23	"github.com/btcsuite/btcd/blockchain"
24	"github.com/btcsuite/btcd/chaincfg"
25	"github.com/btcsuite/btcd/chaincfg/chainhash"
26	"github.com/btcsuite/btcd/connmgr"
27	"github.com/btcsuite/btcd/database"
28	_ "github.com/btcsuite/btcd/database/ffldb"
29	"github.com/btcsuite/btcd/mempool"
30	"github.com/btcsuite/btcd/peer"
31	"github.com/btcsuite/btcutil"
32	"github.com/btcsuite/go-socks/socks"
33	flags "github.com/jessevdk/go-flags"
34)
35
36const (
37	defaultConfigFilename        = "btcd.conf"
38	defaultDataDirname           = "data"
39	defaultLogLevel              = "info"
40	defaultLogDirname            = "logs"
41	defaultLogFilename           = "btcd.log"
42	defaultMaxPeers              = 125
43	defaultBanDuration           = time.Hour * 24
44	defaultBanThreshold          = 100
45	defaultConnectTimeout        = time.Second * 30
46	defaultMaxRPCClients         = 10
47	defaultMaxRPCWebsockets      = 25
48	defaultMaxRPCConcurrentReqs  = 20
49	defaultDbType                = "ffldb"
50	defaultFreeTxRelayLimit      = 15.0
51	defaultTrickleInterval       = peer.DefaultTrickleInterval
52	defaultBlockMinSize          = 0
53	defaultBlockMaxSize          = 750000
54	defaultBlockMinWeight        = 0
55	defaultBlockMaxWeight        = 3000000
56	blockMaxSizeMin              = 1000
57	blockMaxSizeMax              = blockchain.MaxBlockBaseSize - 1000
58	blockMaxWeightMin            = 4000
59	blockMaxWeightMax            = blockchain.MaxBlockWeight - 4000
60	defaultGenerate              = false
61	defaultMaxOrphanTransactions = 100
62	defaultMaxOrphanTxSize       = 100000
63	defaultSigCacheMaxSize       = 100000
64	sampleConfigFilename         = "sample-btcd.conf"
65	defaultTxIndex               = false
66	defaultAddrIndex             = false
67)
68
69var (
70	defaultHomeDir     = btcutil.AppDataDir("btcd", false)
71	defaultConfigFile  = filepath.Join(defaultHomeDir, defaultConfigFilename)
72	defaultDataDir     = filepath.Join(defaultHomeDir, defaultDataDirname)
73	knownDbTypes       = database.SupportedDrivers()
74	defaultRPCKeyFile  = filepath.Join(defaultHomeDir, "rpc.key")
75	defaultRPCCertFile = filepath.Join(defaultHomeDir, "rpc.cert")
76	defaultLogDir      = filepath.Join(defaultHomeDir, defaultLogDirname)
77)
78
79// runServiceCommand is only set to a real function on Windows.  It is used
80// to parse and execute service commands specified via the -s flag.
81var runServiceCommand func(string) error
82
83// minUint32 is a helper function to return the minimum of two uint32s.
84// This avoids a math import and the need to cast to floats.
85func minUint32(a, b uint32) uint32 {
86	if a < b {
87		return a
88	}
89	return b
90}
91
92// config defines the configuration options for btcd.
93//
94// See loadConfig for details on the configuration load process.
95type config struct {
96	AddCheckpoints       []string      `long:"addcheckpoint" description:"Add a custom checkpoint.  Format: '<height>:<hash>'"`
97	AddPeers             []string      `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"`
98	AddrIndex            bool          `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"`
99	AgentBlacklist       []string      `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause btcd to reject any peers whose user-agent contains any of the blacklisted substrings."`
100	AgentWhitelist       []string      `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause btcd 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."`
101	BanDuration          time.Duration `long:"banduration" description:"How long to ban misbehaving peers.  Valid time units are {s, m, h}.  Minimum 1 second"`
102	BanThreshold         uint32        `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."`
103	BlockMaxSize         uint32        `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"`
104	BlockMinSize         uint32        `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"`
105	BlockMaxWeight       uint32        `long:"blockmaxweight" description:"Maximum block weight to be used when creating a block"`
106	BlockMinWeight       uint32        `long:"blockminweight" description:"Mininum block weight to be used when creating a block"`
107	BlockPrioritySize    uint32        `long:"blockprioritysize" description:"Size in bytes for high-priority/low-fee transactions when creating a block"`
108	BlocksOnly           bool          `long:"blocksonly" description:"Do not accept transactions from remote peers."`
109	ConfigFile           string        `short:"C" long:"configfile" description:"Path to configuration file"`
110	ConnectPeers         []string      `long:"connect" description:"Connect only to the specified peers at startup"`
111	CPUProfile           string        `long:"cpuprofile" description:"Write CPU profile to the specified file"`
112	DataDir              string        `short:"b" long:"datadir" description:"Directory to store data"`
113	DbType               string        `long:"dbtype" description:"Database backend to use for the Block Chain"`
114	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"`
115	DropAddrIndex        bool          `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."`
116	DropCfIndex          bool          `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."`
117	DropTxIndex          bool          `long:"droptxindex" description:"Deletes the hash-based transaction index from the database on start up and then exits."`
118	ExternalIPs          []string      `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"`
119	Generate             bool          `long:"generate" description:"Generate (mine) bitcoins using the CPU"`
120	FreeTxRelayLimit     float64       `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"`
121	Listeners            []string      `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"`
122	LogDir               string        `long:"logdir" description:"Directory to log output."`
123	MaxOrphanTxs         int           `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"`
124	MaxPeers             int           `long:"maxpeers" description:"Max number of inbound and outbound peers"`
125	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"`
126	MinRelayTxFee        float64       `long:"minrelaytxfee" description:"The minimum transaction fee in BTC/kB to be considered a non-zero fee."`
127	DisableBanning       bool          `long:"nobanning" description:"Disable banning of misbehaving peers"`
128	NoCFilters           bool          `long:"nocfilters" description:"Disable committed filtering (CF) support"`
129	DisableCheckpoints   bool          `long:"nocheckpoints" description:"Disable built-in checkpoints.  Don't do this unless you know what you're doing."`
130	DisableDNSSeed       bool          `long:"nodnsseed" description:"Disable DNS seeding for peers"`
131	DisableListen        bool          `long:"nolisten" description:"Disable listening for incoming connections -- NOTE: Listening is automatically disabled if the --connect or --proxy options are used without also specifying listen interfaces via --listen"`
132	NoOnion              bool          `long:"noonion" description:"Disable connecting to tor hidden services"`
133	NoPeerBloomFilters   bool          `long:"nopeerbloomfilters" description:"Disable bloom filtering support"`
134	NoRelayPriority      bool          `long:"norelaypriority" description:"Do not require free or low-fee transactions to have high priority for relaying"`
135	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"`
136	DisableTLS           bool          `long:"notls" description:"Disable TLS for the RPC server -- NOTE: This is only allowed if the RPC server is bound to localhost"`
137	OnionProxy           string        `long:"onion" description:"Connect to tor hidden services via SOCKS5 proxy (eg. 127.0.0.1:9050)"`
138	OnionProxyPass       string        `long:"onionpass" default-mask:"-" description:"Password for onion proxy server"`
139	OnionProxyUser       string        `long:"onionuser" description:"Username for onion proxy server"`
140	Profile              string        `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
141	Proxy                string        `long:"proxy" description:"Connect via SOCKS5 proxy (eg. 127.0.0.1:9050)"`
142	ProxyPass            string        `long:"proxypass" default-mask:"-" description:"Password for proxy server"`
143	ProxyUser            string        `long:"proxyuser" description:"Username for proxy server"`
144	RegressionTest       bool          `long:"regtest" description:"Use the regression test network"`
145	RejectNonStd         bool          `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."`
146	RejectReplacement    bool          `long:"rejectreplacement" description:"Reject transactions that attempt to replace existing transactions within the mempool through the Replace-By-Fee (RBF) signaling policy."`
147	RelayNonStd          bool          `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."`
148	RPCCert              string        `long:"rpccert" description:"File containing the certificate file"`
149	RPCKey               string        `long:"rpckey" description:"File containing the certificate key"`
150	RPCLimitPass         string        `long:"rpclimitpass" default-mask:"-" description:"Password for limited RPC connections"`
151	RPCLimitUser         string        `long:"rpclimituser" description:"Username for limited RPC connections"`
152	RPCListeners         []string      `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"`
153	RPCMaxClients        int           `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"`
154	RPCMaxConcurrentReqs int           `long:"rpcmaxconcurrentreqs" description:"Max number of concurrent RPC requests that may be processed concurrently"`
155	RPCMaxWebsockets     int           `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"`
156	RPCQuirks            bool          `long:"rpcquirks" description:"Mirror some JSON-RPC quirks of Bitcoin Core -- NOTE: Discouraged unless interoperability issues need to be worked around"`
157	RPCPass              string        `short:"P" long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
158	RPCUser              string        `short:"u" long:"rpcuser" description:"Username for RPC connections"`
159	SigCacheMaxSize      uint          `long:"sigcachemaxsize" description:"The maximum number of entries in the signature verification cache"`
160	SimNet               bool          `long:"simnet" description:"Use the simulation test network"`
161	TestNet3             bool          `long:"testnet" description:"Use the test network"`
162	TorIsolation         bool          `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
163	TrickleInterval      time.Duration `long:"trickleinterval" description:"Minimum time between attempts to send new inventory to a connected peer"`
164	TxIndex              bool          `long:"txindex" description:"Maintain a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"`
165	UserAgentComments    []string      `long:"uacomment" description:"Comment to add to the user agent -- See BIP 14 for more information."`
166	Upnp                 bool          `long:"upnp" description:"Use UPnP to map our listening port outside of NAT"`
167	ShowVersion          bool          `short:"V" long:"version" description:"Display version information and exit"`
168	Whitelists           []string      `long:"whitelist" description:"Add an IP network or IP that will not be banned. (eg. 192.168.1.0/24 or ::1)"`
169	lookup               func(string) ([]net.IP, error)
170	oniondial            func(string, string, time.Duration) (net.Conn, error)
171	dial                 func(string, string, time.Duration) (net.Conn, error)
172	addCheckpoints       []chaincfg.Checkpoint
173	miningAddrs          []btcutil.Address
174	minRelayTxFee        btcutil.Amount
175	whitelists           []*net.IPNet
176}
177
178// serviceOptions defines the configuration options for the daemon as a service on
179// Windows.
180type serviceOptions struct {
181	ServiceCommand string `short:"s" long:"service" description:"Service command {install, remove, start, stop}"`
182}
183
184// cleanAndExpandPath expands environment variables and leading ~ in the
185// passed path, cleans the result, and returns it.
186func cleanAndExpandPath(path string) string {
187	// Expand initial ~ to OS specific home directory.
188	if strings.HasPrefix(path, "~") {
189		homeDir := filepath.Dir(defaultHomeDir)
190		path = strings.Replace(path, "~", homeDir, 1)
191	}
192
193	// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
194	// but they variables can still be expanded via POSIX-style $VARIABLE.
195	return filepath.Clean(os.ExpandEnv(path))
196}
197
198// validLogLevel returns whether or not logLevel is a valid debug log level.
199func validLogLevel(logLevel string) bool {
200	switch logLevel {
201	case "trace":
202		fallthrough
203	case "debug":
204		fallthrough
205	case "info":
206		fallthrough
207	case "warn":
208		fallthrough
209	case "error":
210		fallthrough
211	case "critical":
212		return true
213	}
214	return false
215}
216
217// supportedSubsystems returns a sorted slice of the supported subsystems for
218// logging purposes.
219func supportedSubsystems() []string {
220	// Convert the subsystemLoggers map keys to a slice.
221	subsystems := make([]string, 0, len(subsystemLoggers))
222	for subsysID := range subsystemLoggers {
223		subsystems = append(subsystems, subsysID)
224	}
225
226	// Sort the subsystems for stable display.
227	sort.Strings(subsystems)
228	return subsystems
229}
230
231// parseAndSetDebugLevels attempts to parse the specified debug level and set
232// the levels accordingly.  An appropriate error is returned if anything is
233// invalid.
234func parseAndSetDebugLevels(debugLevel string) error {
235	// When the specified string doesn't have any delimters, treat it as
236	// the log level for all subsystems.
237	if !strings.Contains(debugLevel, ",") && !strings.Contains(debugLevel, "=") {
238		// Validate debug log level.
239		if !validLogLevel(debugLevel) {
240			str := "The specified debug level [%v] is invalid"
241			return fmt.Errorf(str, debugLevel)
242		}
243
244		// Change the logging level for all subsystems.
245		setLogLevels(debugLevel)
246
247		return nil
248	}
249
250	// Split the specified string into subsystem/level pairs while detecting
251	// issues and update the log levels accordingly.
252	for _, logLevelPair := range strings.Split(debugLevel, ",") {
253		if !strings.Contains(logLevelPair, "=") {
254			str := "The specified debug level contains an invalid " +
255				"subsystem/level pair [%v]"
256			return fmt.Errorf(str, logLevelPair)
257		}
258
259		// Extract the specified subsystem and log level.
260		fields := strings.Split(logLevelPair, "=")
261		subsysID, logLevel := fields[0], fields[1]
262
263		// Validate subsystem.
264		if _, exists := subsystemLoggers[subsysID]; !exists {
265			str := "The specified subsystem [%v] is invalid -- " +
266				"supported subsytems %v"
267			return fmt.Errorf(str, subsysID, supportedSubsystems())
268		}
269
270		// Validate log level.
271		if !validLogLevel(logLevel) {
272			str := "The specified debug level [%v] is invalid"
273			return fmt.Errorf(str, logLevel)
274		}
275
276		setLogLevel(subsysID, logLevel)
277	}
278
279	return nil
280}
281
282// validDbType returns whether or not dbType is a supported database type.
283func validDbType(dbType string) bool {
284	for _, knownType := range knownDbTypes {
285		if dbType == knownType {
286			return true
287		}
288	}
289
290	return false
291}
292
293// removeDuplicateAddresses returns a new slice with all duplicate entries in
294// addrs removed.
295func removeDuplicateAddresses(addrs []string) []string {
296	result := make([]string, 0, len(addrs))
297	seen := map[string]struct{}{}
298	for _, val := range addrs {
299		if _, ok := seen[val]; !ok {
300			result = append(result, val)
301			seen[val] = struct{}{}
302		}
303	}
304	return result
305}
306
307// normalizeAddress returns addr with the passed default port appended if
308// there is not already a port specified.
309func normalizeAddress(addr, defaultPort string) string {
310	_, _, err := net.SplitHostPort(addr)
311	if err != nil {
312		return net.JoinHostPort(addr, defaultPort)
313	}
314	return addr
315}
316
317// normalizeAddresses returns a new slice with all the passed peer addresses
318// normalized with the given default port, and all duplicates removed.
319func normalizeAddresses(addrs []string, defaultPort string) []string {
320	for i, addr := range addrs {
321		addrs[i] = normalizeAddress(addr, defaultPort)
322	}
323
324	return removeDuplicateAddresses(addrs)
325}
326
327// newCheckpointFromStr parses checkpoints in the '<height>:<hash>' format.
328func newCheckpointFromStr(checkpoint string) (chaincfg.Checkpoint, error) {
329	parts := strings.Split(checkpoint, ":")
330	if len(parts) != 2 {
331		return chaincfg.Checkpoint{}, fmt.Errorf("unable to parse "+
332			"checkpoint %q -- use the syntax <height>:<hash>",
333			checkpoint)
334	}
335
336	height, err := strconv.ParseInt(parts[0], 10, 32)
337	if err != nil {
338		return chaincfg.Checkpoint{}, fmt.Errorf("unable to parse "+
339			"checkpoint %q due to malformed height", checkpoint)
340	}
341
342	if len(parts[1]) == 0 {
343		return chaincfg.Checkpoint{}, fmt.Errorf("unable to parse "+
344			"checkpoint %q due to missing hash", checkpoint)
345	}
346	hash, err := chainhash.NewHashFromStr(parts[1])
347	if err != nil {
348		return chaincfg.Checkpoint{}, fmt.Errorf("unable to parse "+
349			"checkpoint %q due to malformed hash", checkpoint)
350	}
351
352	return chaincfg.Checkpoint{
353		Height: int32(height),
354		Hash:   hash,
355	}, nil
356}
357
358// parseCheckpoints checks the checkpoint strings for valid syntax
359// ('<height>:<hash>') and parses them to chaincfg.Checkpoint instances.
360func parseCheckpoints(checkpointStrings []string) ([]chaincfg.Checkpoint, error) {
361	if len(checkpointStrings) == 0 {
362		return nil, nil
363	}
364	checkpoints := make([]chaincfg.Checkpoint, len(checkpointStrings))
365	for i, cpString := range checkpointStrings {
366		checkpoint, err := newCheckpointFromStr(cpString)
367		if err != nil {
368			return nil, err
369		}
370		checkpoints[i] = checkpoint
371	}
372	return checkpoints, nil
373}
374
375// filesExists reports whether the named file or directory exists.
376func fileExists(name string) bool {
377	if _, err := os.Stat(name); err != nil {
378		if os.IsNotExist(err) {
379			return false
380		}
381	}
382	return true
383}
384
385// newConfigParser returns a new command line flags parser.
386func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *flags.Parser {
387	parser := flags.NewParser(cfg, options)
388	if runtime.GOOS == "windows" {
389		parser.AddGroup("Service Options", "Service Options", so)
390	}
391	return parser
392}
393
394// loadConfig initializes and parses the config using a config file and command
395// line options.
396//
397// The configuration proceeds as follows:
398// 	1) Start with a default config with sane settings
399// 	2) Pre-parse the command line to check for an alternative config file
400// 	3) Load configuration file overwriting defaults with any specified options
401// 	4) Parse CLI options and overwrite/add any specified options
402//
403// The above results in btcd functioning properly without any config settings
404// while still allowing the user to override settings with config files and
405// command line options.  Command line options always take precedence.
406func loadConfig() (*config, []string, error) {
407	// Default config.
408	cfg := config{
409		ConfigFile:           defaultConfigFile,
410		DebugLevel:           defaultLogLevel,
411		MaxPeers:             defaultMaxPeers,
412		BanDuration:          defaultBanDuration,
413		BanThreshold:         defaultBanThreshold,
414		RPCMaxClients:        defaultMaxRPCClients,
415		RPCMaxWebsockets:     defaultMaxRPCWebsockets,
416		RPCMaxConcurrentReqs: defaultMaxRPCConcurrentReqs,
417		DataDir:              defaultDataDir,
418		LogDir:               defaultLogDir,
419		DbType:               defaultDbType,
420		RPCKey:               defaultRPCKeyFile,
421		RPCCert:              defaultRPCCertFile,
422		MinRelayTxFee:        mempool.DefaultMinRelayTxFee.ToBTC(),
423		FreeTxRelayLimit:     defaultFreeTxRelayLimit,
424		TrickleInterval:      defaultTrickleInterval,
425		BlockMinSize:         defaultBlockMinSize,
426		BlockMaxSize:         defaultBlockMaxSize,
427		BlockMinWeight:       defaultBlockMinWeight,
428		BlockMaxWeight:       defaultBlockMaxWeight,
429		BlockPrioritySize:    mempool.DefaultBlockPrioritySize,
430		MaxOrphanTxs:         defaultMaxOrphanTransactions,
431		SigCacheMaxSize:      defaultSigCacheMaxSize,
432		Generate:             defaultGenerate,
433		TxIndex:              defaultTxIndex,
434		AddrIndex:            defaultAddrIndex,
435	}
436
437	// Service options which are only added on Windows.
438	serviceOpts := serviceOptions{}
439
440	// Pre-parse the command line options to see if an alternative config
441	// file or the version flag was specified.  Any errors aside from the
442	// help message error can be ignored here since they will be caught by
443	// the final parse below.
444	preCfg := cfg
445	preParser := newConfigParser(&preCfg, &serviceOpts, flags.HelpFlag)
446	_, err := preParser.Parse()
447	if err != nil {
448		if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
449			fmt.Fprintln(os.Stderr, err)
450			return nil, nil, err
451		}
452	}
453
454	// Show the version and exit if the version flag was specified.
455	appName := filepath.Base(os.Args[0])
456	appName = strings.TrimSuffix(appName, filepath.Ext(appName))
457	usageMessage := fmt.Sprintf("Use %s -h to show usage", appName)
458	if preCfg.ShowVersion {
459		fmt.Println(appName, "version", version())
460		os.Exit(0)
461	}
462
463	// Perform service command and exit if specified.  Invalid service
464	// commands show an appropriate error.  Only runs on Windows since
465	// the runServiceCommand function will be nil when not on Windows.
466	if serviceOpts.ServiceCommand != "" && runServiceCommand != nil {
467		err := runServiceCommand(serviceOpts.ServiceCommand)
468		if err != nil {
469			fmt.Fprintln(os.Stderr, err)
470		}
471		os.Exit(0)
472	}
473
474	// Load additional config from file.
475	var configFileError error
476	parser := newConfigParser(&cfg, &serviceOpts, flags.Default)
477	if !(preCfg.RegressionTest || preCfg.SimNet) || preCfg.ConfigFile !=
478		defaultConfigFile {
479
480		if _, err := os.Stat(preCfg.ConfigFile); os.IsNotExist(err) {
481			err := createDefaultConfigFile(preCfg.ConfigFile)
482			if err != nil {
483				fmt.Fprintf(os.Stderr, "Error creating a "+
484					"default config file: %v\n", err)
485			}
486		}
487
488		err := flags.NewIniParser(parser).ParseFile(preCfg.ConfigFile)
489		if err != nil {
490			if _, ok := err.(*os.PathError); !ok {
491				fmt.Fprintf(os.Stderr, "Error parsing config "+
492					"file: %v\n", err)
493				fmt.Fprintln(os.Stderr, usageMessage)
494				return nil, nil, err
495			}
496			configFileError = err
497		}
498	}
499
500	// Don't add peers from the config file when in regression test mode.
501	if preCfg.RegressionTest && len(cfg.AddPeers) > 0 {
502		cfg.AddPeers = nil
503	}
504
505	// Parse command line options again to ensure they take precedence.
506	remainingArgs, err := parser.Parse()
507	if err != nil {
508		if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp {
509			fmt.Fprintln(os.Stderr, usageMessage)
510		}
511		return nil, nil, err
512	}
513
514	// Create the home directory if it doesn't already exist.
515	funcName := "loadConfig"
516	err = os.MkdirAll(defaultHomeDir, 0700)
517	if err != nil {
518		// Show a nicer error message if it's because a symlink is
519		// linked to a directory that does not exist (probably because
520		// it's not mounted).
521		if e, ok := err.(*os.PathError); ok && os.IsExist(err) {
522			if link, lerr := os.Readlink(e.Path); lerr == nil {
523				str := "is symlink %s -> %s mounted?"
524				err = fmt.Errorf(str, e.Path, link)
525			}
526		}
527
528		str := "%s: Failed to create home directory: %v"
529		err := fmt.Errorf(str, funcName, err)
530		fmt.Fprintln(os.Stderr, err)
531		return nil, nil, err
532	}
533
534	// Multiple networks can't be selected simultaneously.
535	numNets := 0
536	// Count number of network flags passed; assign active network params
537	// while we're at it
538	if cfg.TestNet3 {
539		numNets++
540		activeNetParams = &testNet3Params
541	}
542	if cfg.RegressionTest {
543		numNets++
544		activeNetParams = &regressionNetParams
545	}
546	if cfg.SimNet {
547		numNets++
548		// Also disable dns seeding on the simulation test network.
549		activeNetParams = &simNetParams
550		cfg.DisableDNSSeed = true
551	}
552	if numNets > 1 {
553		str := "%s: The testnet, regtest, segnet, and simnet params " +
554			"can't be used together -- choose one of the four"
555		err := fmt.Errorf(str, funcName)
556		fmt.Fprintln(os.Stderr, err)
557		fmt.Fprintln(os.Stderr, usageMessage)
558		return nil, nil, err
559	}
560
561	// Set the default policy for relaying non-standard transactions
562	// according to the default of the active network. The set
563	// configuration value takes precedence over the default value for the
564	// selected network.
565	relayNonStd := activeNetParams.RelayNonStdTxs
566	switch {
567	case cfg.RelayNonStd && cfg.RejectNonStd:
568		str := "%s: rejectnonstd and relaynonstd cannot be used " +
569			"together -- choose only one"
570		err := fmt.Errorf(str, funcName)
571		fmt.Fprintln(os.Stderr, err)
572		fmt.Fprintln(os.Stderr, usageMessage)
573		return nil, nil, err
574	case cfg.RejectNonStd:
575		relayNonStd = false
576	case cfg.RelayNonStd:
577		relayNonStd = true
578	}
579	cfg.RelayNonStd = relayNonStd
580
581	// Append the network type to the data directory so it is "namespaced"
582	// per network.  In addition to the block database, there are other
583	// pieces of data that are saved to disk such as address manager state.
584	// All data is specific to a network, so namespacing the data directory
585	// means each individual piece of serialized data does not have to
586	// worry about changing names per network and such.
587	cfg.DataDir = cleanAndExpandPath(cfg.DataDir)
588	cfg.DataDir = filepath.Join(cfg.DataDir, netName(activeNetParams))
589
590	// Append the network type to the log directory so it is "namespaced"
591	// per network in the same fashion as the data directory.
592	cfg.LogDir = cleanAndExpandPath(cfg.LogDir)
593	cfg.LogDir = filepath.Join(cfg.LogDir, netName(activeNetParams))
594
595	// Special show command to list supported subsystems and exit.
596	if cfg.DebugLevel == "show" {
597		fmt.Println("Supported subsystems", supportedSubsystems())
598		os.Exit(0)
599	}
600
601	// Initialize log rotation.  After log rotation has been initialized, the
602	// logger variables may be used.
603	initLogRotator(filepath.Join(cfg.LogDir, defaultLogFilename))
604
605	// Parse, validate, and set debug log level(s).
606	if err := parseAndSetDebugLevels(cfg.DebugLevel); err != nil {
607		err := fmt.Errorf("%s: %v", funcName, err.Error())
608		fmt.Fprintln(os.Stderr, err)
609		fmt.Fprintln(os.Stderr, usageMessage)
610		return nil, nil, err
611	}
612
613	// Validate database type.
614	if !validDbType(cfg.DbType) {
615		str := "%s: The specified database type [%v] is invalid -- " +
616			"supported types %v"
617		err := fmt.Errorf(str, funcName, cfg.DbType, knownDbTypes)
618		fmt.Fprintln(os.Stderr, err)
619		fmt.Fprintln(os.Stderr, usageMessage)
620		return nil, nil, err
621	}
622
623	// Validate profile port number
624	if cfg.Profile != "" {
625		profilePort, err := strconv.Atoi(cfg.Profile)
626		if err != nil || profilePort < 1024 || profilePort > 65535 {
627			str := "%s: The profile port must be between 1024 and 65535"
628			err := fmt.Errorf(str, funcName)
629			fmt.Fprintln(os.Stderr, err)
630			fmt.Fprintln(os.Stderr, usageMessage)
631			return nil, nil, err
632		}
633	}
634
635	// Don't allow ban durations that are too short.
636	if cfg.BanDuration < time.Second {
637		str := "%s: The banduration option may not be less than 1s -- parsed [%v]"
638		err := fmt.Errorf(str, funcName, cfg.BanDuration)
639		fmt.Fprintln(os.Stderr, err)
640		fmt.Fprintln(os.Stderr, usageMessage)
641		return nil, nil, err
642	}
643
644	// Validate any given whitelisted IP addresses and networks.
645	if len(cfg.Whitelists) > 0 {
646		var ip net.IP
647		cfg.whitelists = make([]*net.IPNet, 0, len(cfg.Whitelists))
648
649		for _, addr := range cfg.Whitelists {
650			_, ipnet, err := net.ParseCIDR(addr)
651			if err != nil {
652				ip = net.ParseIP(addr)
653				if ip == nil {
654					str := "%s: The whitelist value of '%s' is invalid"
655					err = fmt.Errorf(str, funcName, addr)
656					fmt.Fprintln(os.Stderr, err)
657					fmt.Fprintln(os.Stderr, usageMessage)
658					return nil, nil, err
659				}
660				var bits int
661				if ip.To4() == nil {
662					// IPv6
663					bits = 128
664				} else {
665					bits = 32
666				}
667				ipnet = &net.IPNet{
668					IP:   ip,
669					Mask: net.CIDRMask(bits, bits),
670				}
671			}
672			cfg.whitelists = append(cfg.whitelists, ipnet)
673		}
674	}
675
676	// --addPeer and --connect do not mix.
677	if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 {
678		str := "%s: the --addpeer and --connect options can not be " +
679			"mixed"
680		err := fmt.Errorf(str, funcName)
681		fmt.Fprintln(os.Stderr, err)
682		fmt.Fprintln(os.Stderr, usageMessage)
683		return nil, nil, err
684	}
685
686	// --proxy or --connect without --listen disables listening.
687	if (cfg.Proxy != "" || len(cfg.ConnectPeers) > 0) &&
688		len(cfg.Listeners) == 0 {
689		cfg.DisableListen = true
690	}
691
692	// Connect means no DNS seeding.
693	if len(cfg.ConnectPeers) > 0 {
694		cfg.DisableDNSSeed = true
695	}
696
697	// Add the default listener if none were specified. The default
698	// listener is all addresses on the listen port for the network
699	// we are to connect to.
700	if len(cfg.Listeners) == 0 {
701		cfg.Listeners = []string{
702			net.JoinHostPort("", activeNetParams.DefaultPort),
703		}
704	}
705
706	// Check to make sure limited and admin users don't have the same username
707	if cfg.RPCUser == cfg.RPCLimitUser && cfg.RPCUser != "" {
708		str := "%s: --rpcuser and --rpclimituser must not specify the " +
709			"same username"
710		err := fmt.Errorf(str, funcName)
711		fmt.Fprintln(os.Stderr, err)
712		fmt.Fprintln(os.Stderr, usageMessage)
713		return nil, nil, err
714	}
715
716	// Check to make sure limited and admin users don't have the same password
717	if cfg.RPCPass == cfg.RPCLimitPass && cfg.RPCPass != "" {
718		str := "%s: --rpcpass and --rpclimitpass must not specify the " +
719			"same password"
720		err := fmt.Errorf(str, funcName)
721		fmt.Fprintln(os.Stderr, err)
722		fmt.Fprintln(os.Stderr, usageMessage)
723		return nil, nil, err
724	}
725
726	// The RPC server is disabled if no username or password is provided.
727	if (cfg.RPCUser == "" || cfg.RPCPass == "") &&
728		(cfg.RPCLimitUser == "" || cfg.RPCLimitPass == "") {
729		cfg.DisableRPC = true
730	}
731
732	if cfg.DisableRPC {
733		btcdLog.Infof("RPC service is disabled")
734	}
735
736	// Default RPC to listen on localhost only.
737	if !cfg.DisableRPC && len(cfg.RPCListeners) == 0 {
738		addrs, err := net.LookupHost("localhost")
739		if err != nil {
740			return nil, nil, err
741		}
742		cfg.RPCListeners = make([]string, 0, len(addrs))
743		for _, addr := range addrs {
744			addr = net.JoinHostPort(addr, activeNetParams.rpcPort)
745			cfg.RPCListeners = append(cfg.RPCListeners, addr)
746		}
747	}
748
749	if cfg.RPCMaxConcurrentReqs < 0 {
750		str := "%s: The rpcmaxwebsocketconcurrentrequests option may " +
751			"not be less than 0 -- parsed [%d]"
752		err := fmt.Errorf(str, funcName, cfg.RPCMaxConcurrentReqs)
753		fmt.Fprintln(os.Stderr, err)
754		fmt.Fprintln(os.Stderr, usageMessage)
755		return nil, nil, err
756	}
757
758	// Validate the the minrelaytxfee.
759	cfg.minRelayTxFee, err = btcutil.NewAmount(cfg.MinRelayTxFee)
760	if err != nil {
761		str := "%s: invalid minrelaytxfee: %v"
762		err := fmt.Errorf(str, funcName, err)
763		fmt.Fprintln(os.Stderr, err)
764		fmt.Fprintln(os.Stderr, usageMessage)
765		return nil, nil, err
766	}
767
768	// Limit the max block size to a sane value.
769	if cfg.BlockMaxSize < blockMaxSizeMin || cfg.BlockMaxSize >
770		blockMaxSizeMax {
771
772		str := "%s: The blockmaxsize option must be in between %d " +
773			"and %d -- parsed [%d]"
774		err := fmt.Errorf(str, funcName, blockMaxSizeMin,
775			blockMaxSizeMax, cfg.BlockMaxSize)
776		fmt.Fprintln(os.Stderr, err)
777		fmt.Fprintln(os.Stderr, usageMessage)
778		return nil, nil, err
779	}
780
781	// Limit the max block weight to a sane value.
782	if cfg.BlockMaxWeight < blockMaxWeightMin ||
783		cfg.BlockMaxWeight > blockMaxWeightMax {
784
785		str := "%s: The blockmaxweight option must be in between %d " +
786			"and %d -- parsed [%d]"
787		err := fmt.Errorf(str, funcName, blockMaxWeightMin,
788			blockMaxWeightMax, cfg.BlockMaxWeight)
789		fmt.Fprintln(os.Stderr, err)
790		fmt.Fprintln(os.Stderr, usageMessage)
791		return nil, nil, err
792	}
793
794	// Limit the max orphan count to a sane vlue.
795	if cfg.MaxOrphanTxs < 0 {
796		str := "%s: The maxorphantx option may not be less than 0 " +
797			"-- parsed [%d]"
798		err := fmt.Errorf(str, funcName, cfg.MaxOrphanTxs)
799		fmt.Fprintln(os.Stderr, err)
800		fmt.Fprintln(os.Stderr, usageMessage)
801		return nil, nil, err
802	}
803
804	// Limit the block priority and minimum block sizes to max block size.
805	cfg.BlockPrioritySize = minUint32(cfg.BlockPrioritySize, cfg.BlockMaxSize)
806	cfg.BlockMinSize = minUint32(cfg.BlockMinSize, cfg.BlockMaxSize)
807	cfg.BlockMinWeight = minUint32(cfg.BlockMinWeight, cfg.BlockMaxWeight)
808
809	switch {
810	// If the max block size isn't set, but the max weight is, then we'll
811	// set the limit for the max block size to a safe limit so weight takes
812	// precedence.
813	case cfg.BlockMaxSize == defaultBlockMaxSize &&
814		cfg.BlockMaxWeight != defaultBlockMaxWeight:
815
816		cfg.BlockMaxSize = blockchain.MaxBlockBaseSize - 1000
817
818	// If the max block weight isn't set, but the block size is, then we'll
819	// scale the set weight accordingly based on the max block size value.
820	case cfg.BlockMaxSize != defaultBlockMaxSize &&
821		cfg.BlockMaxWeight == defaultBlockMaxWeight:
822
823		cfg.BlockMaxWeight = cfg.BlockMaxSize * blockchain.WitnessScaleFactor
824	}
825
826	// Look for illegal characters in the user agent comments.
827	for _, uaComment := range cfg.UserAgentComments {
828		if strings.ContainsAny(uaComment, "/:()") {
829			err := fmt.Errorf("%s: The following characters must not "+
830				"appear in user agent comments: '/', ':', '(', ')'",
831				funcName)
832			fmt.Fprintln(os.Stderr, err)
833			fmt.Fprintln(os.Stderr, usageMessage)
834			return nil, nil, err
835		}
836	}
837
838	// --txindex and --droptxindex do not mix.
839	if cfg.TxIndex && cfg.DropTxIndex {
840		err := fmt.Errorf("%s: the --txindex and --droptxindex "+
841			"options may  not be activated at the same time",
842			funcName)
843		fmt.Fprintln(os.Stderr, err)
844		fmt.Fprintln(os.Stderr, usageMessage)
845		return nil, nil, err
846	}
847
848	// --addrindex and --dropaddrindex do not mix.
849	if cfg.AddrIndex && cfg.DropAddrIndex {
850		err := fmt.Errorf("%s: the --addrindex and --dropaddrindex "+
851			"options may not be activated at the same time",
852			funcName)
853		fmt.Fprintln(os.Stderr, err)
854		fmt.Fprintln(os.Stderr, usageMessage)
855		return nil, nil, err
856	}
857
858	// --addrindex and --droptxindex do not mix.
859	if cfg.AddrIndex && cfg.DropTxIndex {
860		err := fmt.Errorf("%s: the --addrindex and --droptxindex "+
861			"options may not be activated at the same time "+
862			"because the address index relies on the transaction "+
863			"index",
864			funcName)
865		fmt.Fprintln(os.Stderr, err)
866		fmt.Fprintln(os.Stderr, usageMessage)
867		return nil, nil, err
868	}
869
870	// Check mining addresses are valid and saved parsed versions.
871	cfg.miningAddrs = make([]btcutil.Address, 0, len(cfg.MiningAddrs))
872	for _, strAddr := range cfg.MiningAddrs {
873		addr, err := btcutil.DecodeAddress(strAddr, activeNetParams.Params)
874		if err != nil {
875			str := "%s: mining address '%s' failed to decode: %v"
876			err := fmt.Errorf(str, funcName, strAddr, err)
877			fmt.Fprintln(os.Stderr, err)
878			fmt.Fprintln(os.Stderr, usageMessage)
879			return nil, nil, err
880		}
881		if !addr.IsForNet(activeNetParams.Params) {
882			str := "%s: mining address '%s' is on the wrong network"
883			err := fmt.Errorf(str, funcName, strAddr)
884			fmt.Fprintln(os.Stderr, err)
885			fmt.Fprintln(os.Stderr, usageMessage)
886			return nil, nil, err
887		}
888		cfg.miningAddrs = append(cfg.miningAddrs, addr)
889	}
890
891	// Ensure there is at least one mining address when the generate flag is
892	// set.
893	if cfg.Generate && len(cfg.MiningAddrs) == 0 {
894		str := "%s: the generate flag is set, but there are no mining " +
895			"addresses specified "
896		err := fmt.Errorf(str, funcName)
897		fmt.Fprintln(os.Stderr, err)
898		fmt.Fprintln(os.Stderr, usageMessage)
899		return nil, nil, err
900	}
901
902	// Add default port to all listener addresses if needed and remove
903	// duplicate addresses.
904	cfg.Listeners = normalizeAddresses(cfg.Listeners,
905		activeNetParams.DefaultPort)
906
907	// Add default port to all rpc listener addresses if needed and remove
908	// duplicate addresses.
909	cfg.RPCListeners = normalizeAddresses(cfg.RPCListeners,
910		activeNetParams.rpcPort)
911
912	// Only allow TLS to be disabled if the RPC is bound to localhost
913	// addresses.
914	if !cfg.DisableRPC && cfg.DisableTLS {
915		allowedTLSListeners := map[string]struct{}{
916			"localhost": {},
917			"127.0.0.1": {},
918			"::1":       {},
919		}
920		for _, addr := range cfg.RPCListeners {
921			host, _, err := net.SplitHostPort(addr)
922			if err != nil {
923				str := "%s: RPC listen interface '%s' is " +
924					"invalid: %v"
925				err := fmt.Errorf(str, funcName, addr, err)
926				fmt.Fprintln(os.Stderr, err)
927				fmt.Fprintln(os.Stderr, usageMessage)
928				return nil, nil, err
929			}
930			if _, ok := allowedTLSListeners[host]; !ok {
931				str := "%s: the --notls option may not be used " +
932					"when binding RPC to non localhost " +
933					"addresses: %s"
934				err := fmt.Errorf(str, funcName, addr)
935				fmt.Fprintln(os.Stderr, err)
936				fmt.Fprintln(os.Stderr, usageMessage)
937				return nil, nil, err
938			}
939		}
940	}
941
942	// Add default port to all added peer addresses if needed and remove
943	// duplicate addresses.
944	cfg.AddPeers = normalizeAddresses(cfg.AddPeers,
945		activeNetParams.DefaultPort)
946	cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers,
947		activeNetParams.DefaultPort)
948
949	// --noonion and --onion do not mix.
950	if cfg.NoOnion && cfg.OnionProxy != "" {
951		err := fmt.Errorf("%s: the --noonion and --onion options may "+
952			"not be activated at the same time", funcName)
953		fmt.Fprintln(os.Stderr, err)
954		fmt.Fprintln(os.Stderr, usageMessage)
955		return nil, nil, err
956	}
957
958	// Check the checkpoints for syntax errors.
959	cfg.addCheckpoints, err = parseCheckpoints(cfg.AddCheckpoints)
960	if err != nil {
961		str := "%s: Error parsing checkpoints: %v"
962		err := fmt.Errorf(str, funcName, err)
963		fmt.Fprintln(os.Stderr, err)
964		fmt.Fprintln(os.Stderr, usageMessage)
965		return nil, nil, err
966	}
967
968	// Tor stream isolation requires either proxy or onion proxy to be set.
969	if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" {
970		str := "%s: Tor stream isolation requires either proxy or " +
971			"onionproxy to be set"
972		err := fmt.Errorf(str, funcName)
973		fmt.Fprintln(os.Stderr, err)
974		fmt.Fprintln(os.Stderr, usageMessage)
975		return nil, nil, err
976	}
977
978	// Setup dial and DNS resolution (lookup) functions depending on the
979	// specified options.  The default is to use the standard
980	// net.DialTimeout function as well as the system DNS resolver.  When a
981	// proxy is specified, the dial function is set to the proxy specific
982	// dial function and the lookup is set to use tor (unless --noonion is
983	// specified in which case the system DNS resolver is used).
984	cfg.dial = net.DialTimeout
985	cfg.lookup = net.LookupIP
986	if cfg.Proxy != "" {
987		_, _, err := net.SplitHostPort(cfg.Proxy)
988		if err != nil {
989			str := "%s: Proxy address '%s' is invalid: %v"
990			err := fmt.Errorf(str, funcName, cfg.Proxy, err)
991			fmt.Fprintln(os.Stderr, err)
992			fmt.Fprintln(os.Stderr, usageMessage)
993			return nil, nil, err
994		}
995
996		// Tor isolation flag means proxy credentials will be overridden
997		// unless there is also an onion proxy configured in which case
998		// that one will be overridden.
999		torIsolation := false
1000		if cfg.TorIsolation && cfg.OnionProxy == "" &&
1001			(cfg.ProxyUser != "" || cfg.ProxyPass != "") {
1002
1003			torIsolation = true
1004			fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
1005				"overriding specified proxy user credentials")
1006		}
1007
1008		proxy := &socks.Proxy{
1009			Addr:         cfg.Proxy,
1010			Username:     cfg.ProxyUser,
1011			Password:     cfg.ProxyPass,
1012			TorIsolation: torIsolation,
1013		}
1014		cfg.dial = proxy.DialTimeout
1015
1016		// Treat the proxy as tor and perform DNS resolution through it
1017		// unless the --noonion flag is set or there is an
1018		// onion-specific proxy configured.
1019		if !cfg.NoOnion && cfg.OnionProxy == "" {
1020			cfg.lookup = func(host string) ([]net.IP, error) {
1021				return connmgr.TorLookupIP(host, cfg.Proxy)
1022			}
1023		}
1024	}
1025
1026	// Setup onion address dial function depending on the specified options.
1027	// The default is to use the same dial function selected above.  However,
1028	// when an onion-specific proxy is specified, the onion address dial
1029	// function is set to use the onion-specific proxy while leaving the
1030	// normal dial function as selected above.  This allows .onion address
1031	// traffic to be routed through a different proxy than normal traffic.
1032	if cfg.OnionProxy != "" {
1033		_, _, err := net.SplitHostPort(cfg.OnionProxy)
1034		if err != nil {
1035			str := "%s: Onion proxy address '%s' is invalid: %v"
1036			err := fmt.Errorf(str, funcName, cfg.OnionProxy, err)
1037			fmt.Fprintln(os.Stderr, err)
1038			fmt.Fprintln(os.Stderr, usageMessage)
1039			return nil, nil, err
1040		}
1041
1042		// Tor isolation flag means onion proxy credentials will be
1043		// overridden.
1044		if cfg.TorIsolation &&
1045			(cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") {
1046			fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
1047				"overriding specified onionproxy user "+
1048				"credentials ")
1049		}
1050
1051		cfg.oniondial = func(network, addr string, timeout time.Duration) (net.Conn, error) {
1052			proxy := &socks.Proxy{
1053				Addr:         cfg.OnionProxy,
1054				Username:     cfg.OnionProxyUser,
1055				Password:     cfg.OnionProxyPass,
1056				TorIsolation: cfg.TorIsolation,
1057			}
1058			return proxy.DialTimeout(network, addr, timeout)
1059		}
1060
1061		// When configured in bridge mode (both --onion and --proxy are
1062		// configured), it means that the proxy configured by --proxy is
1063		// not a tor proxy, so override the DNS resolution to use the
1064		// onion-specific proxy.
1065		if cfg.Proxy != "" {
1066			cfg.lookup = func(host string) ([]net.IP, error) {
1067				return connmgr.TorLookupIP(host, cfg.OnionProxy)
1068			}
1069		}
1070	} else {
1071		cfg.oniondial = cfg.dial
1072	}
1073
1074	// Specifying --noonion means the onion address dial function results in
1075	// an error.
1076	if cfg.NoOnion {
1077		cfg.oniondial = func(a, b string, t time.Duration) (net.Conn, error) {
1078			return nil, errors.New("tor has been disabled")
1079		}
1080	}
1081
1082	// Warn about missing config file only after all other configuration is
1083	// done.  This prevents the warning on help messages and invalid
1084	// options.  Note this should go directly before the return.
1085	if configFileError != nil {
1086		btcdLog.Warnf("%v", configFileError)
1087	}
1088
1089	return &cfg, remainingArgs, nil
1090}
1091
1092// createDefaultConfig copies the file sample-btcd.conf to the given destination path,
1093// and populates it with some randomly generated RPC username and password.
1094func createDefaultConfigFile(destinationPath string) error {
1095	// Create the destination directory if it does not exists
1096	err := os.MkdirAll(filepath.Dir(destinationPath), 0700)
1097	if err != nil {
1098		return err
1099	}
1100
1101	// We assume sample config file path is same as binary
1102	path, err := filepath.Abs(filepath.Dir(os.Args[0]))
1103	if err != nil {
1104		return err
1105	}
1106	sampleConfigPath := filepath.Join(path, sampleConfigFilename)
1107
1108	// We generate a random user and password
1109	randomBytes := make([]byte, 20)
1110	_, err = rand.Read(randomBytes)
1111	if err != nil {
1112		return err
1113	}
1114	generatedRPCUser := base64.StdEncoding.EncodeToString(randomBytes)
1115
1116	_, err = rand.Read(randomBytes)
1117	if err != nil {
1118		return err
1119	}
1120	generatedRPCPass := base64.StdEncoding.EncodeToString(randomBytes)
1121
1122	src, err := os.Open(sampleConfigPath)
1123	if err != nil {
1124		return err
1125	}
1126	defer src.Close()
1127
1128	dest, err := os.OpenFile(destinationPath,
1129		os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
1130	if err != nil {
1131		return err
1132	}
1133	defer dest.Close()
1134
1135	// We copy every line from the sample config file to the destination,
1136	// only replacing the two lines for rpcuser and rpcpass
1137	reader := bufio.NewReader(src)
1138	for err != io.EOF {
1139		var line string
1140		line, err = reader.ReadString('\n')
1141		if err != nil && err != io.EOF {
1142			return err
1143		}
1144
1145		if strings.Contains(line, "rpcuser=") {
1146			line = "rpcuser=" + generatedRPCUser + "\n"
1147		} else if strings.Contains(line, "rpcpass=") {
1148			line = "rpcpass=" + generatedRPCPass + "\n"
1149		}
1150
1151		if _, err := dest.WriteString(line); err != nil {
1152			return err
1153		}
1154	}
1155
1156	return nil
1157}
1158
1159// btcdDial connects to the address on the named network using the appropriate
1160// dial function depending on the address and configuration options.  For
1161// example, .onion addresses will be dialed using the onion specific proxy if
1162// one was specified, but will otherwise use the normal dial function (which
1163// could itself use a proxy or not).
1164func btcdDial(addr net.Addr) (net.Conn, error) {
1165	if strings.Contains(addr.String(), ".onion:") {
1166		return cfg.oniondial(addr.Network(), addr.String(),
1167			defaultConnectTimeout)
1168	}
1169	return cfg.dial(addr.Network(), addr.String(), defaultConnectTimeout)
1170}
1171
1172// btcdLookup resolves the IP of the given host using the correct DNS lookup
1173// function depending on the configuration options.  For example, addresses will
1174// be resolved using tor when the --proxy flag was specified unless --noonion
1175// was also specified in which case the normal system DNS resolver will be used.
1176//
1177// Any attempt to resolve a tor address (.onion) will return an error since they
1178// are not intended to be resolved outside of the tor proxy.
1179func btcdLookup(host string) ([]net.IP, error) {
1180	if strings.HasSuffix(host, ".onion") {
1181		return nil, fmt.Errorf("attempt to resolve tor address %s", host)
1182	}
1183
1184	return cfg.lookup(host)
1185}
1186