diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index f5322dcc3..8d2b7f625 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -5,7 +5,10 @@ package addrmgr import ( + "bou.ke/monkey" "fmt" + "github.com/daglabs/btcd/config" + "github.com/daglabs/btcd/dagconfig" "github.com/pkg/errors" "net" "reflect" @@ -113,6 +116,16 @@ func TestStartStop(t *testing.T) { } func TestAddAddressByIP(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + fmtErr := errors.Errorf("") addrErr := &net.AddrError{} var tests = []struct { @@ -157,6 +170,16 @@ func TestAddAddressByIP(t *testing.T) { } func TestAddLocalAddress(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + var tests = []struct { address wire.NetAddress priority AddressPriority @@ -210,6 +233,16 @@ func TestAddLocalAddress(t *testing.T) { } func TestAttempt(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + n := New("testattempt", lookupFunc, nil) // Add a new address and get it @@ -232,6 +265,16 @@ func TestAttempt(t *testing.T) { } func TestConnected(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + n := New("testconnected", lookupFunc, nil) // Add a new address and get it @@ -252,6 +295,16 @@ func TestConnected(t *testing.T) { } func TestNeedMoreAddresses(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + n := New("testneedmoreaddresses", lookupFunc, nil) addrsToAdd := 1500 b := n.NeedMoreAddresses() @@ -284,6 +337,16 @@ func TestNeedMoreAddresses(t *testing.T) { } func TestGood(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + n := New("testgood", lookupFunc, nil) addrsToAdd := 64 * 64 addrs := make([]*wire.NetAddress, addrsToAdd) @@ -331,6 +394,16 @@ func TestGood(t *testing.T) { } func TestGoodChangeSubnetworkID(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + n := New("test_good_change_subnetwork_id", lookupFunc, nil) addr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0) addrKey := NetAddressKey(addr) @@ -400,6 +473,16 @@ func TestGoodChangeSubnetworkID(t *testing.T) { } func TestGetAddress(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + localSubnetworkID := &subnetworkid.SubnetworkID{0xff} n := New("testgetaddress", lookupFunc, localSubnetworkID) @@ -472,6 +555,16 @@ func TestGetAddress(t *testing.T) { } func TestGetBestLocalAddress(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + localAddrs := []wire.NetAddress{ {IP: net.ParseIP("192.168.0.100")}, {IP: net.ParseIP("::1")}, diff --git a/addrmgr/network.go b/addrmgr/network.go index ea373968b..6a698407d 100644 --- a/addrmgr/network.go +++ b/addrmgr/network.go @@ -225,7 +225,7 @@ func IsValid(na *wire.NetAddress) bool { // the public internet. This is true as long as the address is valid and is not // in any reserved ranges. func IsRoutable(na *wire.NetAddress) bool { - if config.ActiveNetParams().AcceptUnroutable { + if config.ActiveConfig().NetParams().AcceptUnroutable { return !IsLocal(na) } diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 5b16ffc62..b22bc1578 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -5,6 +5,9 @@ package addrmgr_test import ( + "bou.ke/monkey" + "github.com/daglabs/btcd/config" + "github.com/daglabs/btcd/dagconfig" "net" "testing" @@ -15,6 +18,16 @@ import ( // TestIPTypes ensures the various functions which determine the type of an IP // address based on RFCs work as intended. func TestIPTypes(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + type ipTest struct { in wire.NetAddress rfc1918 bool @@ -145,6 +158,16 @@ func TestIPTypes(t *testing.T) { // TestGroupKey tests the GroupKey function to ensure it properly groups various // IP addresses. func TestGroupKey(t *testing.T) { + activeConfigPatch := monkey.Patch(config.ActiveConfig, func() *config.Config { + return &config.Config{ + Flags: &config.Flags{ + NetworkFlags: config.NetworkFlags{ + ActiveNetParams: &dagconfig.SimNetParams}, + }, + } + }) + defer activeConfigPatch.Unpatch() + tests := []struct { name string ip string diff --git a/apiserver/config/config.go b/apiserver/config/config.go index ef3fd1655..4ea74b1e9 100644 --- a/apiserver/config/config.go +++ b/apiserver/config/config.go @@ -2,7 +2,7 @@ package config import ( "github.com/daglabs/btcd/apiserver/logger" - "github.com/daglabs/btcd/dagconfig" + "github.com/daglabs/btcd/config" "github.com/daglabs/btcd/util" "github.com/jessevdk/go-flags" "github.com/pkg/errors" @@ -14,18 +14,19 @@ const ( defaultErrLogFilename = "apiserver_err.log" ) -var ( - // activeNetParams are the currently active net params - activeNetParams dagconfig.Params -) - var ( // Default configuration options defaultLogDir = util.AppDataDir("apiserver", false) defaultDBAddress = "localhost:3306" defaultHTTPListen = "0.0.0.0:8080" + activeConfig *Config ) +// ActiveConfig returns the active configuration struct +func ActiveConfig() *Config { + return activeConfig +} + // Config defines the configuration options for the API server. type Config struct { LogDir string `long:"logdir" description:"Directory to log output."` @@ -40,87 +41,50 @@ type Config struct { DBName string `long:"dbname" description:"Database name" required:"true"` HTTPListen string `long:"listen" description:"HTTP address to listen on (default: 0.0.0.0:8080)"` Migrate bool `long:"migrate" description:"Migrate the database to the latest version. The server will not start when using this flag."` - TestNet bool `long:"testnet" description:"Connect to testnet"` - SimNet bool `long:"simnet" description:"Connect to the simulation test network"` - DevNet bool `long:"devnet" description:"Connect to the development test network"` + config.NetworkFlags } // Parse parses the CLI arguments and returns a config struct. func Parse() (*Config, error) { - cfg := &Config{ + activeConfig = &Config{ LogDir: defaultLogDir, DBAddress: defaultDBAddress, HTTPListen: defaultHTTPListen, } - parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag) + parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) _, err := parser.Parse() if err != nil { return nil, err } - if !cfg.Migrate { - if cfg.RPCUser == "" { + if !activeConfig.Migrate { + if activeConfig.RPCUser == "" { return nil, errors.New("--rpcuser is required if --migrate flag is not used") } - if cfg.RPCPassword == "" { + if activeConfig.RPCPassword == "" { return nil, errors.New("--rpcpass is required if --migrate flag is not used") } - if cfg.RPCServer == "" { + if activeConfig.RPCServer == "" { return nil, errors.New("--rpcserver is required if --migrate flag is not used") } } - if cfg.RPCCert == "" && !cfg.DisableTLS { + if activeConfig.RPCCert == "" && !activeConfig.DisableTLS { return nil, errors.New("--notls has to be disabled if --cert is used") } - if cfg.RPCCert != "" && cfg.DisableTLS { + if activeConfig.RPCCert != "" && activeConfig.DisableTLS { return nil, errors.New("--cert should be omitted if --notls is used") } - err = resolveNetwork(cfg) + err = activeConfig.ResolveNetwork(parser) if err != nil { return nil, err } - logFile := filepath.Join(cfg.LogDir, defaultLogFilename) - errLogFile := filepath.Join(cfg.LogDir, defaultErrLogFilename) + logFile := filepath.Join(activeConfig.LogDir, defaultLogFilename) + errLogFile := filepath.Join(activeConfig.LogDir, defaultErrLogFilename) logger.InitLog(logFile, errLogFile) - return cfg, nil -} - -func resolveNetwork(cfg *Config) error { - // Multiple networks can't be selected simultaneously. - numNets := 0 - if cfg.TestNet { - numNets++ - } - if cfg.SimNet { - numNets++ - } - if cfg.DevNet { - numNets++ - } - if numNets > 1 { - return errors.New("multiple net params (testnet, simnet, devnet, etc.) can't be used " + - "together -- choose one of them") - } - - activeNetParams = dagconfig.MainNetParams - switch { - case cfg.TestNet: - activeNetParams = dagconfig.TestNetParams - case cfg.SimNet: - activeNetParams = dagconfig.SimNetParams - case cfg.DevNet: - activeNetParams = dagconfig.DevNetParams - } - - return nil -} - -// ActiveNetParams returns the currently active net params -func ActiveNetParams() *dagconfig.Params { - return &activeNetParams + return activeConfig, nil } diff --git a/apiserver/sync.go b/apiserver/sync.go index 4ee37add3..f823d456c 100644 --- a/apiserver/sync.go +++ b/apiserver/sync.go @@ -3,12 +3,12 @@ package main import ( "bytes" "encoding/hex" - "github.com/daglabs/btcd/apiserver/config" "github.com/daglabs/btcd/apiserver/database" "github.com/daglabs/btcd/apiserver/dbmodels" "github.com/daglabs/btcd/apiserver/jsonrpc" "github.com/daglabs/btcd/blockdag" "github.com/daglabs/btcd/btcjson" + "github.com/daglabs/btcd/config" "github.com/daglabs/btcd/httpserverutils" "github.com/daglabs/btcd/txscript" "github.com/daglabs/btcd/util" @@ -648,7 +648,7 @@ func insertTransactionOutputs(dbTx *gorm.DB, transaction *btcjson.TxRawResult, d } func insertAddress(dbTx *gorm.DB, scriptPubKey []byte) (*dbmodels.Address, error) { - _, addr, err := txscript.ExtractScriptPubKeyAddress(scriptPubKey, config.ActiveNetParams()) + _, addr, err := txscript.ExtractScriptPubKeyAddress(scriptPubKey, config.ActiveConfig().NetParams()) if err != nil { return nil, err } diff --git a/btcd.go b/btcd.go index 52d563457..67e75ba86 100644 --- a/btcd.go +++ b/btcd.go @@ -52,11 +52,11 @@ var winServiceMain func() (bool, error) func btcdMain(serverChan chan<- *server.Server) error { // Load configuration and parse command line. This function also // initializes logging and configures it accordingly. - err := config.LoadAndSetMainConfig() + err := config.LoadAndSetActiveConfig() if err != nil { return err } - cfg = config.MainConfig() + cfg = config.ActiveConfig() defer panics.HandlePanic(btcdLog, logger.BackendLog) // Get a channel that will be closed when a shutdown signal has been @@ -166,7 +166,7 @@ func btcdMain(serverChan chan<- *server.Server) error { } // Create server and start it. - server, err := server.NewServer(cfg.Listeners, db, config.ActiveNetParams(), + server, err := server.NewServer(cfg.Listeners, db, config.ActiveConfig().NetParams(), interrupt) if err != nil { // TODO: this logging could do with some beautifying. @@ -297,7 +297,7 @@ func loadBlockDB() (database.DB, error) { removeRegressionDB(dbPath) btcdLog.Infof("Loading block database from '%s'", dbPath) - db, err := database.Open(cfg.DbType, dbPath, config.ActiveNetParams().Net) + db, err := database.Open(cfg.DbType, dbPath, config.ActiveConfig().NetParams().Net) if err != nil { // Return the error if it's not because the database doesn't // exist. @@ -312,7 +312,7 @@ func loadBlockDB() (database.DB, error) { if err != nil { return nil, err } - db, err = database.Create(cfg.DbType, dbPath, config.ActiveNetParams().Net) + db, err = database.Create(cfg.DbType, dbPath, config.ActiveConfig().NetParams().Net) if err != nil { return nil, err } diff --git a/cmd/addblock/addblock.go b/cmd/addblock/addblock.go index 5313acb43..2464fa8fb 100644 --- a/cmd/addblock/addblock.go +++ b/cmd/addblock/addblock.go @@ -21,7 +21,7 @@ const ( ) var ( - cfg *config + cfg *ConfigFlags log logs.Logger spawn func(func()) ) @@ -33,7 +33,7 @@ func loadBlockDB() (database.DB, error) { dbPath := filepath.Join(cfg.DataDir, dbName) log.Infof("Loading block database from '%s'", dbPath) - db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net) + db, err := database.Open(cfg.DbType, dbPath, ActiveConfig().NetParams().Net) if err != nil { // Return the error if it's not because the database doesn't // exist. @@ -48,7 +48,7 @@ func loadBlockDB() (database.DB, error) { if err != nil { return nil, err } - db, err = database.Create(cfg.DbType, dbPath, activeNetParams.Net) + db, err = database.Create(cfg.DbType, dbPath, ActiveConfig().NetParams().Net) if err != nil { return nil, err } diff --git a/cmd/addblock/config.go b/cmd/addblock/config.go index 48d2ab02d..c39d60077 100644 --- a/cmd/addblock/config.go +++ b/cmd/addblock/config.go @@ -6,12 +6,12 @@ package main import ( "fmt" + "github.com/daglabs/btcd/config" "github.com/pkg/errors" "os" "path/filepath" "strings" - "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/database" _ "github.com/daglabs/btcd/database/ffldb" "github.com/daglabs/btcd/util" @@ -25,26 +25,28 @@ const ( ) var ( - btcdHomeDir = util.AppDataDir("btcd", false) - defaultDataDir = filepath.Join(btcdHomeDir, "data") - knownDbTypes = database.SupportedDrivers() - activeNetParams = &dagconfig.MainNetParams + btcdHomeDir = util.AppDataDir("btcd", false) + defaultDataDir = filepath.Join(btcdHomeDir, "data") + knownDbTypes = database.SupportedDrivers() + activeConfig *ConfigFlags ) -// config defines the configuration options for findcheckpoint. +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig +} + +// ConfigFlags defines the configuration options for findcheckpoint. // // See loadConfig for details on the configuration load process. -type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` - DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` - TestNet bool `long:"testnet" description:"Use the test network"` - RegressionTest bool `long:"regtest" description:"Use the regression test network"` - SimNet bool `long:"simnet" description:"Use the simulation test network"` - DevNet bool `long:"devnet" description:"Use the development test network"` - InFile string `short:"i" long:"infile" description:"File containing the block(s)"` - TxIndex bool `long:"txindex" description:"Build a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"` - AddrIndex bool `long:"addrindex" description:"Build a full address-based transaction index which makes the searchrawtransactions RPC available"` - Progress int `short:"p" long:"progress" description:"Show a progress message each time this number of seconds have passed -- Use 0 to disable progress announcements"` +type ConfigFlags struct { + DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` + InFile string `short:"i" long:"infile" description:"File containing the block(s)"` + TxIndex bool `long:"txindex" description:"Build a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"` + AddrIndex bool `long:"addrindex" description:"Build a full address-based transaction index which makes the searchrawtransactions RPC available"` + Progress int `short:"p" long:"progress" description:"Show a progress message each time this number of seconds have passed -- Use 0 to disable progress announcements"` + config.NetworkFlags } // filesExists reports whether the named file or directory exists. @@ -69,9 +71,9 @@ func validDbType(dbType string) bool { } // loadConfig initializes and parses the config using command line options. -func loadConfig() (*config, []string, error) { +func loadConfig() (*ConfigFlags, []string, error) { // Default config. - cfg := config{ + activeConfig = &ConfigFlags{ DataDir: defaultDataDir, DbType: defaultDbType, InFile: defaultDataFile, @@ -79,7 +81,7 @@ func loadConfig() (*config, []string, error) { } // Parse command line options. - parser := flags.NewParser(&cfg, flags.Default) + parser := flags.NewParser(&activeConfig, flags.Default) remainingArgs, err := parser.Parse() if err != nil { if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { @@ -88,41 +90,16 @@ func loadConfig() (*config, []string, error) { return nil, nil, err } - // Multiple networks can't be selected simultaneously. - funcName := "loadConfig" - numNets := 0 - // Count number of network flags passed; assign active network params - // while we're at it - if cfg.TestNet { - numNets++ - activeNetParams = &dagconfig.TestNetParams - } - if cfg.RegressionTest { - numNets++ - activeNetParams = &dagconfig.RegressionNetParams - } - if cfg.SimNet { - numNets++ - activeNetParams = &dagconfig.SimNetParams - } - if cfg.DevNet { - numNets++ - activeNetParams = &dagconfig.DevNetParams - } - if numNets > 1 { - str := "%s: The testnet, regtest, simnet and devent params can't be " + - "used together -- choose one of the four" - err := errors.Errorf(str, funcName) - fmt.Fprintln(os.Stderr, err) - parser.WriteHelp(os.Stderr) + err = activeConfig.ResolveNetwork(parser) + if err != nil { return nil, nil, err } // Validate database type. - if !validDbType(cfg.DbType) { + if !validDbType(activeConfig.DbType) { str := "%s: The specified database type [%s] is invalid -- " + "supported types %s" - err := errors.Errorf(str, "loadConfig", cfg.DbType, strings.Join(knownDbTypes, ", ")) + err := errors.Errorf(str, "loadConfig", activeConfig.DbType, strings.Join(knownDbTypes, ", ")) fmt.Fprintln(os.Stderr, err) parser.WriteHelp(os.Stderr) return nil, nil, err @@ -134,7 +111,7 @@ func loadConfig() (*config, []string, error) { // All data is specific to a network, so namespacing the data directory // means each individual piece of serialized data does not have to // worry about changing names per network and such. - cfg.DataDir = filepath.Join(cfg.DataDir, activeNetParams.Name) + cfg.DataDir = filepath.Join(cfg.DataDir, ActiveConfig().NetParams().Name) // Ensure the specified block file exists. if !fileExists(cfg.InFile) { @@ -145,5 +122,5 @@ func loadConfig() (*config, []string, error) { return nil, nil, err } - return &cfg, remainingArgs, nil + return cfg, remainingArgs, nil } diff --git a/cmd/addblock/import.go b/cmd/addblock/import.go index ea2733a1d..af0ab4bf2 100644 --- a/cmd/addblock/import.go +++ b/cmd/addblock/import.go @@ -59,9 +59,9 @@ func (bi *blockImporter) readBlock() ([]byte, error) { // No block and no error means there are no more blocks to read. return nil, nil } - if net != uint32(activeNetParams.Net) { + if net != uint32(ActiveConfig().NetParams().Net) { return nil, errors.Errorf("network mismatch -- got %x, want %x", - net, uint32(activeNetParams.Net)) + net, uint32(ActiveConfig().NetParams().Net)) } // Read the block length and ensure it is sane. @@ -311,7 +311,7 @@ func newBlockImporter(db database.DB, r io.ReadSeeker) (*blockImporter, error) { } if cfg.AddrIndex { log.Info("Address index is enabled") - indexes = append(indexes, indexers.NewAddrIndex(activeNetParams)) + indexes = append(indexes, indexers.NewAddrIndex(ActiveConfig().NetParams())) } // Create an index manager if any of the optional indexes are enabled. @@ -322,7 +322,7 @@ func newBlockImporter(db database.DB, r io.ReadSeeker) (*blockImporter, error) { dag, err := blockdag.New(&blockdag.Config{ DB: db, - DAGParams: activeNetParams, + DAGParams: ActiveConfig().NetParams(), TimeSource: blockdag.NewMedianTime(), IndexManager: indexManager, }) diff --git a/cmd/addsubnetwork/config.go b/cmd/addsubnetwork/config.go index 4127bf75d..b9dbd2e22 100644 --- a/cmd/addsubnetwork/config.go +++ b/cmd/addsubnetwork/config.go @@ -1,23 +1,29 @@ package main import ( - "github.com/daglabs/btcd/dagconfig" + "github.com/daglabs/btcd/config" "github.com/jessevdk/go-flags" "github.com/pkg/errors" ) -type config struct { +var activeConfig *ConfigFlags + +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig +} + +// ConfigFlags holds the configurations set by the command line argument +type ConfigFlags struct { PrivateKey string `short:"k" long:"private-key" description:"Private key" required:"true"` RPCUser string `short:"u" long:"rpcuser" description:"RPC username" required:"true"` RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password" required:"true"` RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to" required:"true"` RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` DisableTLS bool `long:"notls" description:"Disable TLS"` - TestNet bool `long:"testnet" description:"Connect to testnet"` - SimNet bool `long:"simnet" description:"Connect to the simulation test network"` - DevNet bool `long:"devnet" description:"Connect to the development test network"` GasLimit uint64 `long:"gaslimit" description:"The gas limit of the new subnetwork"` RegistryTxFee uint64 `long:"regtxfee" description:"The fee for the subnetwork registry transaction"` + config.NetworkFlags } const ( @@ -25,66 +31,41 @@ const ( defaultRegistryTxFee = 3000 ) -var ( - activeNetParams dagconfig.Params -) - -func parseConfig() (*config, error) { - cfg := &config{} - parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag) +func parseConfig() (*ConfigFlags, error) { + activeConfig = &ConfigFlags{} + parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) _, err := parser.Parse() if err != nil { return nil, err } - if cfg.RPCCert == "" && !cfg.DisableTLS { + if activeConfig.RPCCert == "" && !activeConfig.DisableTLS { return nil, errors.New("--notls has to be disabled if --cert is used") } - if cfg.RPCCert != "" && cfg.DisableTLS { + if activeConfig.RPCCert != "" && activeConfig.DisableTLS { return nil, errors.New("--cert should be omitted if --notls is used") } - // Multiple networks can't be selected simultaneously. - numNets := 0 - if cfg.TestNet { - numNets++ - } - if cfg.SimNet { - numNets++ - } - if cfg.DevNet { - numNets++ - } - if numNets > 1 { - return nil, errors.New("multiple net params (testnet, simnet, devnet, etc.) can't be used " + - "together -- choose one of them") + err = activeConfig.ResolveNetwork(parser) + if err != nil { + return nil, err } - activeNetParams = dagconfig.MainNetParams - switch { - case cfg.TestNet: - activeNetParams = dagconfig.TestNetParams - case cfg.SimNet: - activeNetParams = dagconfig.SimNetParams - case cfg.DevNet: - activeNetParams = dagconfig.DevNetParams - } - - if cfg.GasLimit < 0 { + if activeConfig.GasLimit < 0 { return nil, errors.Errorf("gaslimit may not be smaller than 0") } - if cfg.GasLimit == 0 { - cfg.GasLimit = defaultSubnetworkGasLimit + if activeConfig.GasLimit == 0 { + activeConfig.GasLimit = defaultSubnetworkGasLimit } - if cfg.RegistryTxFee < 0 { + if activeConfig.RegistryTxFee < 0 { return nil, errors.Errorf("regtxfee may not be smaller than 0") } - if cfg.RegistryTxFee == 0 { - cfg.RegistryTxFee = defaultRegistryTxFee + if activeConfig.RegistryTxFee == 0 { + activeConfig.RegistryTxFee = defaultRegistryTxFee } - return cfg, nil + return activeConfig, nil } diff --git a/cmd/addsubnetwork/connect.go b/cmd/addsubnetwork/connect.go index 8258fd7ef..76b4963d0 100644 --- a/cmd/addsubnetwork/connect.go +++ b/cmd/addsubnetwork/connect.go @@ -6,7 +6,7 @@ import ( "io/ioutil" ) -func connect(cfg *config) (*rpcclient.Client, error) { +func connect(cfg *ConfigFlags) (*rpcclient.Client, error) { var cert []byte if !cfg.DisableTLS { var err error diff --git a/cmd/addsubnetwork/keys.go b/cmd/addsubnetwork/keys.go index 6ecf872fd..48cb2092c 100644 --- a/cmd/addsubnetwork/keys.go +++ b/cmd/addsubnetwork/keys.go @@ -6,12 +6,12 @@ import ( "github.com/daglabs/btcd/util/base58" ) -func decodeKeys(cfg *config) (*btcec.PrivateKey, *util.AddressPubKeyHash, error) { +func decodeKeys(cfg *ConfigFlags) (*btcec.PrivateKey, *util.AddressPubKeyHash, error) { privateKeyBytes := base58.Decode(cfg.PrivateKey) privateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privateKeyBytes) serializedPrivateKey := privateKey.PubKey().SerializeCompressed() - addr, err := util.NewAddressPubKeyHashFromPublicKey(serializedPrivateKey, activeNetParams.Prefix) + addr, err := util.NewAddressPubKeyHashFromPublicKey(serializedPrivateKey, ActiveConfig().NetParams().Prefix) if err != nil { return nil, nil, err } diff --git a/cmd/addsubnetwork/registrytx.go b/cmd/addsubnetwork/registrytx.go index 0b8c2ce25..df6eac0dc 100644 --- a/cmd/addsubnetwork/registrytx.go +++ b/cmd/addsubnetwork/registrytx.go @@ -7,7 +7,7 @@ import ( "github.com/pkg/errors" ) -func buildSubnetworkRegistryTx(cfg *config, fundingOutpoint *wire.Outpoint, fundingTx *wire.MsgTx, privateKey *btcec.PrivateKey) (*wire.MsgTx, error) { +func buildSubnetworkRegistryTx(cfg *ConfigFlags, fundingOutpoint *wire.Outpoint, fundingTx *wire.MsgTx, privateKey *btcec.PrivateKey) (*wire.MsgTx, error) { txIn := &wire.TxIn{ PreviousOutpoint: *fundingOutpoint, Sequence: wire.MaxTxInSequenceNum, diff --git a/cmd/addsubnetwork/utxo.go b/cmd/addsubnetwork/utxo.go index 3b7a9e958..aae297546 100644 --- a/cmd/addsubnetwork/utxo.go +++ b/cmd/addsubnetwork/utxo.go @@ -15,7 +15,7 @@ const ( minConfirmations = 10 ) -func findUnspentTXO(cfg *config, client *rpcclient.Client, addrPubKeyHash *util.AddressPubKeyHash) (*wire.Outpoint, *wire.MsgTx, error) { +func findUnspentTXO(cfg *ConfigFlags, client *rpcclient.Client, addrPubKeyHash *util.AddressPubKeyHash) (*wire.Outpoint, *wire.MsgTx, error) { txs, err := collectTransactions(client, addrPubKeyHash) if err != nil { return nil, nil, err @@ -92,7 +92,7 @@ func isTxMatured(tx *wire.MsgTx, confirmations uint64) bool { if !tx.IsCoinBase() { return confirmations >= minConfirmations } - return confirmations >= activeNetParams.BlockCoinbaseMaturity + return confirmations >= ActiveConfig().NetParams().BlockCoinbaseMaturity } func buildUTXOs(txs []*wire.MsgTx) map[wire.Outpoint]*wire.MsgTx { diff --git a/cmd/btcctl/config.go b/cmd/btcctl/config.go index 78e61ba09..371eda11f 100644 --- a/cmd/btcctl/config.go +++ b/cmd/btcctl/config.go @@ -6,7 +6,7 @@ package main import ( "fmt" - "github.com/pkg/errors" + "github.com/daglabs/btcd/config" "io/ioutil" "net" "os" @@ -32,8 +32,14 @@ var ( defaultConfigFile = filepath.Join(btcctlHomeDir, "btcctl.conf") defaultRPCServer = "localhost" defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert") + activeConfig *ConfigFlags ) +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig +} + // listCommands categorizes and lists all of the usable commands along with // their one-line usage. func listCommands() { @@ -82,10 +88,10 @@ func listCommands() { } } -// config defines the configuration options for btcctl. +// ConfigFlags defines the configuration options for btcctl. // // See loadConfig for details on the configuration load process. -type config struct { +type ConfigFlags struct { ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` ListCommands bool `short:"l" long:"listcommands" description:"List all of the supported commands and exit"` ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` @@ -97,10 +103,8 @@ type config struct { Proxy string `long:"proxy" description:"Connect via SOCKS5 proxy (eg. 127.0.0.1:9050)"` ProxyUser string `long:"proxyuser" description:"Username for proxy server"` ProxyPass string `long:"proxypass" default-mask:"-" description:"Password for proxy server"` - TestNet bool `long:"testnet" description:"Connect to testnet"` - SimNet bool `long:"simnet" description:"Connect to the simulation test network"` - DevNet bool `long:"devnet" description:"Connect to the development test network"` TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` + config.NetworkFlags } // normalizeAddress returns addr with the passed default port appended if @@ -151,9 +155,9 @@ func cleanAndExpandPath(path string) string { // The above results in functioning properly without any config settings // while still allowing the user to override settings with config files and // command line options. Command line options always take precedence. -func loadConfig() (*config, []string, error) { +func loadConfig() (*ConfigFlags, []string, error) { // Default config. - cfg := config{ + activeConfig = &ConfigFlags{ ConfigFile: defaultConfigFile, RPCServer: defaultRPCServer, RPCCert: defaultRPCCertFile, @@ -163,7 +167,7 @@ func loadConfig() (*config, []string, error) { // file, the version flag, or the list commands flag was specified. Any // errors aside from the help message error can be ignored here since // they will be caught by the final parse below. - preCfg := cfg + preCfg := activeConfig preParser := flags.NewParser(&preCfg, flags.HelpFlag) _, err := preParser.Parse() if err != nil { @@ -205,7 +209,7 @@ func loadConfig() (*config, []string, error) { } // Load additional config from file. - parser := flags.NewParser(&cfg, flags.Default) + parser := flags.NewParser(&activeConfig, flags.Default) err = flags.NewIniParser(parser).ParseFile(preCfg.ConfigFile) if err != nil { if _, ok := err.(*os.PathError); !ok { @@ -225,34 +229,19 @@ func loadConfig() (*config, []string, error) { return nil, nil, err } - // Multiple networks can't be selected simultaneously. - numNets := 0 - if cfg.TestNet { - numNets++ - } - if cfg.SimNet { - numNets++ - } - if cfg.DevNet { - numNets++ - } - if numNets > 1 { - str := "%s: The multiple net params (testnet, simnet, devnet etc.) can't be used " + - "together -- choose one of them" - err := errors.Errorf(str, "loadConfig") - fmt.Fprintln(os.Stderr, err) + err = activeConfig.ResolveNetwork(parser) + if err != nil { return nil, nil, err } - // Handle environment variable expansion in the RPC certificate path. - cfg.RPCCert = cleanAndExpandPath(cfg.RPCCert) + activeConfig.RPCCert = cleanAndExpandPath(activeConfig.RPCCert) // Add default port to RPC server based on --testnet and --simnet flags // if needed. - cfg.RPCServer = normalizeAddress(cfg.RPCServer, cfg.TestNet, - cfg.SimNet, cfg.DevNet) + activeConfig.RPCServer = normalizeAddress(activeConfig.RPCServer, activeConfig.TestNet, + activeConfig.SimNet, activeConfig.DevNet) - return &cfg, remainingArgs, nil + return activeConfig, remainingArgs, nil } // createDefaultConfig creates a basic config file at the given destination path. diff --git a/cmd/btcctl/httpclient.go b/cmd/btcctl/httpclient.go index 0129c8ef6..ec6b7ceb6 100644 --- a/cmd/btcctl/httpclient.go +++ b/cmd/btcctl/httpclient.go @@ -16,7 +16,7 @@ import ( // newHTTPClient returns a new HTTP client that is configured according to the // proxy and TLS settings in the associated connection configuration. -func newHTTPClient(cfg *config) (*http.Client, error) { +func newHTTPClient(cfg *ConfigFlags) (*http.Client, error) { // Configure proxy if needed. var dial func(network, addr string) (net.Conn, error) if cfg.Proxy != "" { @@ -65,7 +65,7 @@ func newHTTPClient(cfg *config) (*http.Client, error) { // to the server described in the passed config struct. It also attempts to // unmarshal the response as a JSON-RPC response and returns either the result // field or the error field depending on whether or not there is an error. -func sendPostRequest(marshalledJSON []byte, cfg *config) ([]byte, error) { +func sendPostRequest(marshalledJSON []byte, cfg *ConfigFlags) ([]byte, error) { // Generate a request to the configured RPC server. protocol := "http" if !cfg.NoTLS { diff --git a/cmd/findcheckpoint/config.go b/cmd/findcheckpoint/config.go index c393b75f4..ac3c74c1d 100644 --- a/cmd/findcheckpoint/config.go +++ b/cmd/findcheckpoint/config.go @@ -6,12 +6,12 @@ package main import ( "fmt" + "github.com/daglabs/btcd/config" "github.com/pkg/errors" "os" "path/filepath" "strings" - "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/database" _ "github.com/daglabs/btcd/database/ffldb" "github.com/daglabs/btcd/util" @@ -26,24 +26,26 @@ const ( ) var ( - btcdHomeDir = util.AppDataDir("btcd", false) - defaultDataDir = filepath.Join(btcdHomeDir, "data") - knownDbTypes = database.SupportedDrivers() - activeNetParams = &dagconfig.MainNetParams + btcdHomeDir = util.AppDataDir("btcd", false) + defaultDataDir = filepath.Join(btcdHomeDir, "data") + knownDbTypes = database.SupportedDrivers() + activeConfig *ConfigFlags ) -// config defines the configuration options for findcheckpoint. +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig +} + +// ConfigFlags defines the configuration options for findcheckpoint. // // See loadConfig for details on the configuration load process. -type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` - DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` - TestNet bool `long:"testnet" description:"Use the test network"` - RegressionTest bool `long:"regtest" description:"Use the regression test network"` - SimNet bool `long:"simnet" description:"Use the simulation test network"` - DevNet bool `long:"devnet" description:"Use the development test network"` - NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"` - UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"` +type ConfigFlags struct { + DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` + NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"` + UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"` + config.NetworkFlags } // validDbType returns whether or not dbType is a supported database type. @@ -58,16 +60,16 @@ func validDbType(dbType string) bool { } // loadConfig initializes and parses the config using command line options. -func loadConfig() (*config, []string, error) { +func loadConfig() (*ConfigFlags, []string, error) { // Default config. - cfg := config{ + activeConfig = &ConfigFlags{ DataDir: defaultDataDir, DbType: defaultDbType, NumCandidates: defaultNumCandidates, } // Parse command line options. - parser := flags.NewParser(&cfg, flags.Default) + parser := flags.NewParser(&activeConfig, flags.Default) remainingArgs, err := parser.Parse() if err != nil { if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { @@ -76,41 +78,17 @@ func loadConfig() (*config, []string, error) { return nil, nil, err } - // Multiple networks can't be selected simultaneously. funcName := "loadConfig" - numNets := 0 - // Count number of network flags passed; assign active network params - // while we're at it - if cfg.TestNet { - numNets++ - activeNetParams = &dagconfig.TestNetParams - } - if cfg.RegressionTest { - numNets++ - activeNetParams = &dagconfig.RegressionNetParams - } - if cfg.SimNet { - numNets++ - activeNetParams = &dagconfig.SimNetParams - } - if cfg.DevNet { - numNets++ - activeNetParams = &dagconfig.DevNetParams - } - if numNets > 1 { - str := "%s: The testnet, regtest, simnet and devnet params can't be " + - "used together -- choose one of the four" - err := errors.Errorf(str, funcName) - fmt.Fprintln(os.Stderr, err) - parser.WriteHelp(os.Stderr) + + err = activeConfig.ResolveNetwork(parser) + if err != nil { return nil, nil, err } - // Validate database type. - if !validDbType(cfg.DbType) { + if !validDbType(activeConfig.DbType) { str := "%s: The specified database type [%s] is invalid -- " + "supported types %s" - err := errors.Errorf(str, funcName, cfg.DbType, strings.Join(knownDbTypes, ", ")) + err := errors.Errorf(str, funcName, activeConfig.DbType, strings.Join(knownDbTypes, ", ")) fmt.Fprintln(os.Stderr, err) parser.WriteHelp(os.Stderr) return nil, nil, err @@ -122,17 +100,17 @@ func loadConfig() (*config, []string, error) { // All data is specific to a network, so namespacing the data directory // means each individual piece of serialized data does not have to // worry about changing names per network and such. - cfg.DataDir = filepath.Join(cfg.DataDir, activeNetParams.Name) + activeConfig.DataDir = filepath.Join(activeConfig.DataDir, activeConfig.NetParams().Name) // Validate the number of candidates. - if cfg.NumCandidates < minCandidates || cfg.NumCandidates > maxCandidates { + if activeConfig.NumCandidates < minCandidates || activeConfig.NumCandidates > maxCandidates { str := "%s: The specified number of candidates is out of " + "range -- parsed [%d]" - err = errors.Errorf(str, funcName, cfg.NumCandidates) + err = errors.Errorf(str, funcName, activeConfig.NumCandidates) fmt.Fprintln(os.Stderr, err) parser.WriteHelp(os.Stderr) return nil, nil, err } - return &cfg, remainingArgs, nil + return activeConfig, remainingArgs, nil } diff --git a/cmd/findcheckpoint/findcheckpoint.go b/cmd/findcheckpoint/findcheckpoint.go index 357ebe81b..44671304a 100644 --- a/cmd/findcheckpoint/findcheckpoint.go +++ b/cmd/findcheckpoint/findcheckpoint.go @@ -19,7 +19,7 @@ import ( const blockDbNamePrefix = "blocks" var ( - cfg *config + cfg *ConfigFlags ) // loadBlockDB opens the block database and returns a handle to it. @@ -28,7 +28,7 @@ func loadBlockDB() (database.DB, error) { dbName := blockDbNamePrefix + "_" + cfg.DbType dbPath := filepath.Join(cfg.DataDir, dbName) fmt.Printf("Loading block database from '%s'\n", dbPath) - db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net) + db, err := database.Open(cfg.DbType, dbPath, ActiveConfig().NetParams().Net) if err != nil { return nil, err } @@ -52,7 +52,7 @@ func findCandidates(dag *blockdag.BlockDAG, highestTipHash *daghash.Hash) ([]*da // Set the latest checkpoint to the genesis block if there isn't // already one. latestCheckpoint = &dagconfig.Checkpoint{ - Hash: activeNetParams.GenesisHash, + Hash: ActiveConfig().NetParams().GenesisHash, ChainHeight: 0, } } @@ -72,7 +72,7 @@ func findCandidates(dag *blockdag.BlockDAG, highestTipHash *daghash.Hash) ([]*da // For the first checkpoint, the required height is any block after the // genesis block, so long as the DAG has at least the required number // of confirmations (which is enforced above). - if len(activeNetParams.Checkpoints) == 0 { + if len(ActiveConfig().NetParams().Checkpoints) == 0 { requiredChainHeight = 1 } @@ -153,7 +153,7 @@ func main() { // util. dag, err := blockdag.New(&blockdag.Config{ DB: db, - DAGParams: activeNetParams, + DAGParams: ActiveConfig().NetParams(), TimeSource: blockdag.NewMedianTime(), }) if err != nil { diff --git a/cmd/txgen/config.go b/cmd/txgen/config.go index fb3281afe..770b5c60e 100644 --- a/cmd/txgen/config.go +++ b/cmd/txgen/config.go @@ -22,7 +22,7 @@ var ( defaultTargetNumberOfInputs uint64 = 1 ) -type config struct { +type configFlags struct { Address string `long:"address" description:"An address to a JSON-RPC endpoints" required:"true"` PrivateKey string `long:"private-key" description:"Private key" required:"true"` SecondaryAddress string `long:"secondary-address" description:"An address that gets paid once per txgen run"` @@ -36,8 +36,8 @@ type config struct { AverageFeeRate float64 `long:"fee-rate" description:"Average coins per gram fee rate"` } -func parseConfig() (*config, error) { - cfg := &config{} +func parseConfig() (*configFlags, error) { + cfg := &configFlags{} parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag) _, err := parser.Parse() diff --git a/cmd/txgen/connect.go b/cmd/txgen/connect.go index 47149b2e9..c6d1f5ee0 100644 --- a/cmd/txgen/connect.go +++ b/cmd/txgen/connect.go @@ -6,7 +6,7 @@ import ( "io/ioutil" ) -func connectToServer(cfg *config) (*txgenClient, error) { +func connectToServer(cfg *configFlags) (*txgenClient, error) { var cert []byte if !cfg.DisableTLS { var err error diff --git a/cmd/txgen/txloop.go b/cmd/txgen/txloop.go index 0a0134a81..8f4151995 100644 --- a/cmd/txgen/txloop.go +++ b/cmd/txgen/txloop.go @@ -61,7 +61,7 @@ var ( ) // txLoop performs main loop of transaction generation -func txLoop(client *txgenClient, cfg *config) error { +func txLoop(client *txgenClient, cfg *configFlags) error { filterAddresses := []util.Address{p2pkhAddress} var err error primaryScriptPubKey, err = txscript.PayToAddrScript(p2pkhAddress) @@ -217,7 +217,7 @@ func randomIntegerWithAverageTarget(target uint64, allowZero bool) uint64 { return uint64(math.Round(randomNum)) } -func createRandomTxFromFunds(walletUTXOSet utxoSet, cfg *config, gasLimitMap map[subnetworkid.SubnetworkID]uint64, funds uint64) (tx *wire.MsgTx, isSecondaryAddress bool, err error) { +func createRandomTxFromFunds(walletUTXOSet utxoSet, cfg *configFlags, gasLimitMap map[subnetworkid.SubnetworkID]uint64, funds uint64) (tx *wire.MsgTx, isSecondaryAddress bool, err error) { if secondaryScriptPubKey != nil && !sentToSecondaryAddress && funds > minSecondaryTxAmount { tx, err = createTx(walletUTXOSet, minSecondaryTxAmount, cfg.AverageFeeRate, 1, 1, subnetworkid.SubnetworkIDNative, 0, 0, secondaryScriptPubKey) if err != nil { @@ -266,7 +266,7 @@ func createRandomTxFromFunds(walletUTXOSet utxoSet, cfg *config, gasLimitMap map } func enqueueTransactions(client *txgenClient, blockAdded *blockAddedMsg, walletUTXOSet utxoSet, walletTxs map[daghash.TxID]*walletTransaction, - txChan chan *wire.MsgTx, cfg *config, gasLimitMap map[subnetworkid.SubnetworkID]uint64) error { + txChan chan *wire.MsgTx, cfg *configFlags, gasLimitMap map[subnetworkid.SubnetworkID]uint64) error { if err := applyConfirmedTransactionsAndResendNonAccepted(client, walletTxs, walletUTXOSet, blockAdded.chainHeight, txChan); err != nil { return err } diff --git a/cmd/txsigner/config.go b/cmd/txsigner/config.go index 268ecd970..ab230b8ac 100644 --- a/cmd/txsigner/config.go +++ b/cmd/txsigner/config.go @@ -1,57 +1,36 @@ package main import ( - "fmt" - "github.com/daglabs/btcd/dagconfig" + "github.com/daglabs/btcd/config" "github.com/jessevdk/go-flags" - "github.com/pkg/errors" - "os" ) -var activeNetParams = &dagconfig.MainNetParams +var activeConfig *ConfigFlags -type config struct { - Transaction string `long:"transaction" short:"t" description:"Unsigned transaction in HEX format" required:"true"` - PrivateKey string `long:"private-key" short:"p" description:"Private key" required:"true"` - TestNet bool `long:"testnet" description:"Use the test network"` - RegressionTest bool `long:"regtest" description:"Use the regression test network"` - SimNet bool `long:"simnet" description:"Use the simulation test network"` - DevNet bool `long:"devnet" description:"Use the development test network"` +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig } -func parseCommandLine() (*config, error) { - cfg := &config{} - parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag) +// ConfigFlags holds the configurations set by the command line argument +type ConfigFlags struct { + Transaction string `long:"transaction" short:"t" description:"Unsigned transaction in HEX format" required:"true"` + PrivateKey string `long:"private-key" short:"p" description:"Private key" required:"true"` + config.NetworkFlags +} + +func parseCommandLine() (*ConfigFlags, error) { + activeConfig = &ConfigFlags{} + parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) _, err := parser.Parse() - // Multiple networks can't be selected simultaneously. - funcName := "loadConfig" - numNets := 0 - // Count number of network flags passed; assign active network params - // while we're at it - if cfg.TestNet { - numNets++ - activeNetParams = &dagconfig.TestNetParams - } - if cfg.RegressionTest { - numNets++ - activeNetParams = &dagconfig.RegressionNetParams - } - if cfg.SimNet { - numNets++ - activeNetParams = &dagconfig.SimNetParams - } - if cfg.DevNet { - numNets++ - activeNetParams = &dagconfig.DevNetParams - } - if numNets > 1 { - str := "%s: The testnet, regtest, simnet and devent params can't be " + - "used together -- choose one of the four" - err := errors.Errorf(str, funcName) - fmt.Fprintln(os.Stderr, err) - parser.WriteHelp(os.Stderr) + if err != nil { return nil, err } - return cfg, err + err = activeConfig.ResolveNetwork(parser) + if err != nil { + return nil, err + } + + return activeConfig, nil } diff --git a/cmd/txsigner/txsigner.go b/cmd/txsigner/txsigner.go index 55c191bcc..15a4583cf 100644 --- a/cmd/txsigner/txsigner.go +++ b/cmd/txsigner/txsigner.go @@ -59,7 +59,7 @@ func parseTransaction(transactionHex string) (*wire.MsgTx, error) { } func createScriptPubKey(publicKey *btcec.PublicKey) ([]byte, error) { - p2pkhAddress, err := util.NewAddressPubKeyHashFromPublicKey(publicKey.SerializeCompressed(), activeNetParams.Prefix) + p2pkhAddress, err := util.NewAddressPubKeyHashFromPublicKey(publicKey.SerializeCompressed(), ActiveConfig().NetParams().Prefix) scriptPubKey, err := txscript.PayToAddrScript(p2pkhAddress) return scriptPubKey, err } diff --git a/config/config.go b/config/config.go index e55aa34bb..1b72267f5 100644 --- a/config/config.go +++ b/config/config.go @@ -74,11 +74,7 @@ var ( defaultLogDir = filepath.Join(DefaultHomeDir, defaultLogDirname) ) -// activeNetParams is a pointer to the parameters specific to the -// currently active bitcoin network. -var activeNetParams = &dagconfig.MainNetParams - -var mainCfg *Config +var activeConfig *Config // RunServiceCommand is only set to a real function on Windows. It is used // to parse and execute service commands specified via the -s flag. @@ -93,10 +89,10 @@ func minUint32(a, b uint32) uint32 { return b } -// Config defines the configuration options for btcd. +// Flags defines the configuration options for btcd. // // See loadConfig for details on the configuration load process. -type configFlags struct { +type Flags struct { ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` DataDir string `short:"b" long:"datadir" description:"Directory to store data"` @@ -134,10 +130,6 @@ type configFlags struct { OnionProxyPass string `long:"onionpass" default-mask:"-" description:"Password for onion proxy server"` NoOnion bool `long:"noonion" description:"Disable connecting to tor hidden services"` TorIsolation bool `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."` - TestNet bool `long:"testnet" description:"Use the test network"` - RegressionTest bool `long:"regtest" description:"Use the regression test network"` - SimNet bool `long:"simnet" description:"Use the simulation test network"` - DevNet bool `long:"devnet" description:"Use the development test network"` AddCheckpoints []string `long:"addcheckpoint" description:"Add a custom checkpoint. Format: ':'"` DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."` DbType string `long:"dbtype" description:"Database backend to use for the Block DAG"` @@ -166,13 +158,14 @@ type configFlags struct { RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."` Subnetwork string `long:"subnetwork" description:"If subnetwork ID is specified, than node will request and process only payloads from specified subnetwork. And if subnetwork ID is ommited, than payloads of all subnetworks are processed. Subnetworks with IDs 2 through 255 are reserved for future use and are currently not allowed."` ResetDatabase bool `long:"reset-db" description:"Reset database before starting node. It's needed when switching between subnetworks."` + NetworkFlags } // Config defines the configuration options for btcd. // // See loadConfig for details on the configuration load process. type Config struct { - *configFlags + *Flags Lookup func(string) ([]net.IP, error) OnionDial func(string, string, time.Duration) (net.Conn, error) Dial func(string, string, time.Duration) (net.Conn, error) @@ -263,7 +256,7 @@ func parseCheckpoints(checkpointStrings []string) ([]dagconfig.Checkpoint, error } // newConfigParser returns a new command line flags parser. -func newConfigParser(cfgFlags *configFlags, so *serviceOptions, options flags.Options) *flags.Parser { +func newConfigParser(cfgFlags *Flags, so *serviceOptions, options flags.Options) *flags.Parser { parser := flags.NewParser(cfgFlags, options) if runtime.GOOS == "windows" { parser.AddGroup("Service Options", "Service Options", so) @@ -271,19 +264,19 @@ func newConfigParser(cfgFlags *configFlags, so *serviceOptions, options flags.Op return parser } -//LoadAndSetMainConfig loads the config that can be afterward be accesible through MainConfig() -func LoadAndSetMainConfig() error { +//LoadAndSetActiveConfig loads the config that can be afterward be accesible through ActiveConfig() +func LoadAndSetActiveConfig() error { tcfg, _, err := loadConfig() if err != nil { return err } - mainCfg = tcfg + activeConfig = tcfg return nil } -// MainConfig is a getter to the main config -func MainConfig() *Config { - return mainCfg +// ActiveConfig is a getter to the main config +func ActiveConfig() *Config { + return activeConfig } // loadConfig initializes and parses the config using a config file and command @@ -300,7 +293,7 @@ func MainConfig() *Config { // command line options. Command line options always take precedence. func loadConfig() (*Config, []string, error) { // Default config. - cfgFlags := configFlags{ + cfgFlags := Flags{ ConfigFile: defaultConfigFile, DebugLevel: defaultLogLevel, MaxPeers: defaultMaxPeers, @@ -364,8 +357,8 @@ func loadConfig() (*Config, []string, error) { // Load additional config from file. var configFileError error parser := newConfigParser(&cfgFlags, &serviceOpts, flags.Default) - cfg := Config{ - configFlags: &cfgFlags, + activeConfig = &Config{ + Flags: &cfgFlags, } if !(preCfg.RegressionTest || preCfg.SimNet) || preCfg.ConfigFile != defaultConfigFile { @@ -391,8 +384,8 @@ func loadConfig() (*Config, []string, error) { } // Don't add peers from the config file when in regression test mode. - if preCfg.RegressionTest && len(cfg.AddPeers) > 0 { - cfg.AddPeers = nil + if preCfg.RegressionTest && len(activeConfig.AddPeers) > 0 { + activeConfig.AddPeers = nil } // Parse command line options again to ensure they take precedence. @@ -424,34 +417,8 @@ func loadConfig() (*Config, []string, error) { return nil, nil, err } - // Multiple networks can't be selected simultaneously. - numNets := 0 - // Count number of network flags passed; assign active network params - // while we're at it - if cfg.TestNet { - numNets++ - activeNetParams = &dagconfig.TestNetParams - } - if cfg.RegressionTest { - numNets++ - activeNetParams = &dagconfig.RegressionNetParams - } - if cfg.SimNet { - numNets++ - // Also disable dns seeding on the simulation test network. - activeNetParams = &dagconfig.SimNetParams - cfg.DisableDNSSeed = true - } - if cfg.DevNet { - numNets++ - activeNetParams = &dagconfig.DevNetParams - } - if numNets > 1 { - str := "%s: The testnet, regtest, devnet, and simnet params " + - "can't be used together -- choose one of the four" - err := errors.Errorf(str, funcName) - fmt.Fprintln(os.Stderr, err) - fmt.Fprintln(os.Stderr, usageMessage) + err = activeConfig.ResolveNetwork(parser) + if err != nil { return nil, nil, err } @@ -459,21 +426,21 @@ func loadConfig() (*Config, []string, error) { // according to the default of the active network. The set // configuration value takes precedence over the default value for the // selected network. - relayNonStd := activeNetParams.RelayNonStdTxs + relayNonStd := activeConfig.NetParams().RelayNonStdTxs switch { - case cfg.RelayNonStd && cfg.RejectNonStd: + case activeConfig.RelayNonStd && activeConfig.RejectNonStd: str := "%s: rejectnonstd and relaynonstd cannot be used " + "together -- choose only one" err := errors.Errorf(str, funcName) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err - case cfg.RejectNonStd: + case activeConfig.RejectNonStd: relayNonStd = false - case cfg.RelayNonStd: + case activeConfig.RelayNonStd: relayNonStd = true } - cfg.RelayNonStd = relayNonStd + activeConfig.RelayNonStd = relayNonStd // Append the network type to the data directory so it is "namespaced" // per network. In addition to the block database, there are other @@ -481,26 +448,26 @@ func loadConfig() (*Config, []string, error) { // All data is specific to a network, so namespacing the data directory // means each individual piece of serialized data does not have to // worry about changing names per network and such. - cfg.DataDir = cleanAndExpandPath(cfg.DataDir) - cfg.DataDir = filepath.Join(cfg.DataDir, activeNetParams.Name) + activeConfig.DataDir = cleanAndExpandPath(activeConfig.DataDir) + activeConfig.DataDir = filepath.Join(activeConfig.DataDir, activeConfig.NetParams().Name) // Append the network type to the log directory so it is "namespaced" // per network in the same fashion as the data directory. - cfg.LogDir = cleanAndExpandPath(cfg.LogDir) - cfg.LogDir = filepath.Join(cfg.LogDir, activeNetParams.Name) + activeConfig.LogDir = cleanAndExpandPath(activeConfig.LogDir) + activeConfig.LogDir = filepath.Join(activeConfig.LogDir, activeConfig.NetParams().Name) // Special show command to list supported subsystems and exit. - if cfg.DebugLevel == "show" { + if activeConfig.DebugLevel == "show" { fmt.Println("Supported subsystems", logger.SupportedSubsystems()) os.Exit(0) } // Initialize log rotation. After log rotation has been initialized, the // logger variables may be used. - logger.InitLog(filepath.Join(cfg.LogDir, defaultLogFilename), filepath.Join(cfg.LogDir, defaultErrLogFilename)) + logger.InitLog(filepath.Join(activeConfig.LogDir, defaultLogFilename), filepath.Join(activeConfig.LogDir, defaultErrLogFilename)) // Parse, validate, and set debug log level(s). - if err := logger.ParseAndSetDebugLevels(cfg.DebugLevel); err != nil { + if err := logger.ParseAndSetDebugLevels(activeConfig.DebugLevel); err != nil { err := errors.Errorf("%s: %s", funcName, err.Error()) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) @@ -508,18 +475,18 @@ func loadConfig() (*Config, []string, error) { } // Validate database type. - if !validDbType(cfg.DbType) { + if !validDbType(activeConfig.DbType) { str := "%s: The specified database type [%s] is invalid -- " + "supported types %s" - err := errors.Errorf(str, funcName, cfg.DbType, knownDbTypes) + err := errors.Errorf(str, funcName, activeConfig.DbType, knownDbTypes) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Validate profile port number - if cfg.Profile != "" { - profilePort, err := strconv.Atoi(cfg.Profile) + if activeConfig.Profile != "" { + profilePort, err := strconv.Atoi(activeConfig.Profile) if err != nil || profilePort < 1024 || profilePort > 65535 { str := "%s: The profile port must be between 1024 and 65535" err := errors.Errorf(str, funcName) @@ -530,20 +497,20 @@ func loadConfig() (*Config, []string, error) { } // Don't allow ban durations that are too short. - if cfg.BanDuration < time.Second { + if activeConfig.BanDuration < time.Second { str := "%s: The banduration option may not be less than 1s -- parsed [%s]" - err := errors.Errorf(str, funcName, cfg.BanDuration) + err := errors.Errorf(str, funcName, activeConfig.BanDuration) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Validate any given whitelisted IP addresses and networks. - if len(cfg.Whitelists) > 0 { + if len(activeConfig.Whitelists) > 0 { var ip net.IP - cfg.Whitelists = make([]*net.IPNet, 0, len(cfg.configFlags.Whitelists)) + activeConfig.Whitelists = make([]*net.IPNet, 0, len(activeConfig.Flags.Whitelists)) - for _, addr := range cfg.configFlags.Whitelists { + for _, addr := range activeConfig.Flags.Whitelists { _, ipnet, err := net.ParseCIDR(addr) if err != nil { ip = net.ParseIP(addr) @@ -566,12 +533,12 @@ func loadConfig() (*Config, []string, error) { Mask: net.CIDRMask(bits, bits), } } - cfg.Whitelists = append(cfg.Whitelists, ipnet) + activeConfig.Whitelists = append(activeConfig.Whitelists, ipnet) } } // --addPeer and --connect do not mix. - if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 { + if len(activeConfig.AddPeers) > 0 && len(activeConfig.ConnectPeers) > 0 { str := "%s: the --addpeer and --connect options can not be " + "mixed" err := errors.Errorf(str, funcName) @@ -581,27 +548,27 @@ func loadConfig() (*Config, []string, error) { } // --proxy or --connect without --listen disables listening. - if (cfg.Proxy != "" || len(cfg.ConnectPeers) > 0) && - len(cfg.Listeners) == 0 { - cfg.DisableListen = true + if (activeConfig.Proxy != "" || len(activeConfig.ConnectPeers) > 0) && + len(activeConfig.Listeners) == 0 { + activeConfig.DisableListen = true } // Connect means no DNS seeding. - if len(cfg.ConnectPeers) > 0 { - cfg.DisableDNSSeed = true + if len(activeConfig.ConnectPeers) > 0 { + activeConfig.DisableDNSSeed = true } // Add the default listener if none were specified. The default // listener is all addresses on the listen port for the network // we are to connect to. - if len(cfg.Listeners) == 0 { - cfg.Listeners = []string{ - net.JoinHostPort("", activeNetParams.DefaultPort), + if len(activeConfig.Listeners) == 0 { + activeConfig.Listeners = []string{ + net.JoinHostPort("", activeConfig.NetParams().DefaultPort), } } // Check to make sure limited and admin users don't have the same username - if cfg.RPCUser == cfg.RPCLimitUser && cfg.RPCUser != "" { + if activeConfig.RPCUser == activeConfig.RPCLimitUser && activeConfig.RPCUser != "" { str := "%s: --rpcuser and --rpclimituser must not specify the " + "same username" err := errors.Errorf(str, funcName) @@ -611,7 +578,7 @@ func loadConfig() (*Config, []string, error) { } // Check to make sure limited and admin users don't have the same password - if cfg.RPCPass == cfg.RPCLimitPass && cfg.RPCPass != "" { + if activeConfig.RPCPass == activeConfig.RPCLimitPass && activeConfig.RPCPass != "" { str := "%s: --rpcpass and --rpclimitpass must not specify the " + "same password" err := errors.Errorf(str, funcName) @@ -621,39 +588,39 @@ func loadConfig() (*Config, []string, error) { } // The RPC server is disabled if no username or password is provided. - if (cfg.RPCUser == "" || cfg.RPCPass == "") && - (cfg.RPCLimitUser == "" || cfg.RPCLimitPass == "") { - cfg.DisableRPC = true + if (activeConfig.RPCUser == "" || activeConfig.RPCPass == "") && + (activeConfig.RPCLimitUser == "" || activeConfig.RPCLimitPass == "") { + activeConfig.DisableRPC = true } - if cfg.DisableRPC { + if activeConfig.DisableRPC { log.Infof("RPC service is disabled") } // Default RPC to listen on localhost only. - if !cfg.DisableRPC && len(cfg.RPCListeners) == 0 { + if !activeConfig.DisableRPC && len(activeConfig.RPCListeners) == 0 { addrs, err := net.LookupHost("localhost") if err != nil { return nil, nil, err } - cfg.RPCListeners = make([]string, 0, len(addrs)) + activeConfig.RPCListeners = make([]string, 0, len(addrs)) for _, addr := range addrs { - addr = net.JoinHostPort(addr, activeNetParams.RPCPort) - cfg.RPCListeners = append(cfg.RPCListeners, addr) + addr = net.JoinHostPort(addr, activeConfig.NetParams().RPCPort) + activeConfig.RPCListeners = append(activeConfig.RPCListeners, addr) } } - if cfg.RPCMaxConcurrentReqs < 0 { + if activeConfig.RPCMaxConcurrentReqs < 0 { str := "%s: The rpcmaxwebsocketconcurrentrequests option may " + "not be less than 0 -- parsed [%d]" - err := errors.Errorf(str, funcName, cfg.RPCMaxConcurrentReqs) + err := errors.Errorf(str, funcName, activeConfig.RPCMaxConcurrentReqs) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Validate the the minrelaytxfee. - cfg.MinRelayTxFee, err = util.NewAmount(cfg.configFlags.MinRelayTxFee) + activeConfig.MinRelayTxFee, err = util.NewAmount(activeConfig.Flags.MinRelayTxFee) if err != nil { str := "%s: invalid minrelaytxfee: %s" err := errors.Errorf(str, funcName, err) @@ -663,39 +630,39 @@ func loadConfig() (*Config, []string, error) { } // Disallow 0 and negative min tx fees. - if cfg.MinRelayTxFee <= 0 { + if activeConfig.MinRelayTxFee <= 0 { str := "%s: The minrelaytxfee option must be greater than 0 -- parsed [%d]" - err := errors.Errorf(str, funcName, cfg.MinRelayTxFee) + err := errors.Errorf(str, funcName, activeConfig.MinRelayTxFee) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Limit the max block mass to a sane value. - if cfg.BlockMaxMass < blockMaxMassMin || cfg.BlockMaxMass > + if activeConfig.BlockMaxMass < blockMaxMassMin || activeConfig.BlockMaxMass > blockMaxMassMax { str := "%s: The blockmaxmass option must be in between %d " + "and %d -- parsed [%d]" err := errors.Errorf(str, funcName, blockMaxMassMin, - blockMaxMassMax, cfg.BlockMaxMass) + blockMaxMassMax, activeConfig.BlockMaxMass) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Limit the max orphan count to a sane value. - if cfg.MaxOrphanTxs < 0 { + if activeConfig.MaxOrphanTxs < 0 { str := "%s: The maxorphantx option may not be less than 0 " + "-- parsed [%d]" - err := errors.Errorf(str, funcName, cfg.MaxOrphanTxs) + err := errors.Errorf(str, funcName, activeConfig.MaxOrphanTxs) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } // Look for illegal characters in the user agent comments. - for _, uaComment := range cfg.UserAgentComments { + for _, uaComment := range activeConfig.UserAgentComments { if strings.ContainsAny(uaComment, "/:()") { err := errors.Errorf("%s: The following characters must not "+ "appear in user agent comments: '/', ':', '(', ')'", @@ -707,7 +674,7 @@ func loadConfig() (*Config, []string, error) { } // --txindex and --droptxindex do not mix. - if cfg.TxIndex && cfg.DropTxIndex { + if activeConfig.TxIndex && activeConfig.DropTxIndex { err := errors.Errorf("%s: the --txindex and --droptxindex "+ "options may not be activated at the same time", funcName) @@ -717,7 +684,7 @@ func loadConfig() (*Config, []string, error) { } // --addrindex and --dropaddrindex do not mix. - if cfg.AddrIndex && cfg.DropAddrIndex { + if activeConfig.AddrIndex && activeConfig.DropAddrIndex { err := errors.Errorf("%s: the --addrindex and --dropaddrindex "+ "options may not be activated at the same time", funcName) @@ -727,7 +694,7 @@ func loadConfig() (*Config, []string, error) { } // --addrindex and --droptxindex do not mix. - if cfg.AddrIndex && cfg.DropTxIndex { + if activeConfig.AddrIndex && activeConfig.DropTxIndex { err := errors.Errorf("%s: the --addrindex and --droptxindex "+ "options may not be activated at the same time "+ "because the address index relies on the transaction "+ @@ -739,7 +706,7 @@ func loadConfig() (*Config, []string, error) { } // --acceptanceindex and --dropacceptanceindex do not mix. - if cfg.AcceptanceIndex && cfg.DropAcceptanceIndex { + if activeConfig.AcceptanceIndex && activeConfig.DropAcceptanceIndex { err := errors.Errorf("%s: the --acceptanceindex and --dropacceptanceindex "+ "options may not be activated at the same time", funcName) @@ -749,9 +716,9 @@ func loadConfig() (*Config, []string, error) { } // Check mining addresses are valid and saved parsed versions. - cfg.MiningAddrs = make([]util.Address, 0, len(cfg.configFlags.MiningAddrs)) - for _, strAddr := range cfg.configFlags.MiningAddrs { - addr, err := util.DecodeAddress(strAddr, activeNetParams.Prefix) + activeConfig.MiningAddrs = make([]util.Address, 0, len(activeConfig.Flags.MiningAddrs)) + for _, strAddr := range activeConfig.Flags.MiningAddrs { + addr, err := util.DecodeAddress(strAddr, activeConfig.NetParams().Prefix) if err != nil { str := "%s: mining address '%s' failed to decode: %s" err := errors.Errorf(str, funcName, strAddr, err) @@ -759,27 +726,27 @@ func loadConfig() (*Config, []string, error) { fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } - if !addr.IsForPrefix(activeNetParams.Prefix) { + if !addr.IsForPrefix(activeConfig.NetParams().Prefix) { str := "%s: mining address '%s' is on the wrong network" err := errors.Errorf(str, funcName, strAddr) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } - cfg.MiningAddrs = append(cfg.MiningAddrs, addr) + activeConfig.MiningAddrs = append(activeConfig.MiningAddrs, addr) } - if cfg.configFlags.Subnetwork != "" { - cfg.SubnetworkID, err = subnetworkid.NewFromStr(cfg.configFlags.Subnetwork) + if activeConfig.Flags.Subnetwork != "" { + activeConfig.SubnetworkID, err = subnetworkid.NewFromStr(activeConfig.Flags.Subnetwork) if err != nil { return nil, nil, err } } else { - cfg.SubnetworkID = nil + activeConfig.SubnetworkID = nil } // Check that 'generate' and 'subnetwork' flags do not conflict - if cfg.Generate && cfg.SubnetworkID != nil { + if activeConfig.Generate && activeConfig.SubnetworkID != nil { str := "%s: both generate flag and subnetwork filtering are set " err := errors.Errorf(str, funcName) fmt.Fprintln(os.Stderr, err) @@ -789,7 +756,7 @@ func loadConfig() (*Config, []string, error) { // Ensure there is at least one mining address when the generate flag is // set. - if cfg.Generate && len(cfg.MiningAddrs) == 0 { + if activeConfig.Generate && len(activeConfig.MiningAddrs) == 0 { str := "%s: the generate flag is set, but there are no mining " + "addresses specified " err := errors.Errorf(str, funcName) @@ -800,23 +767,23 @@ func loadConfig() (*Config, []string, error) { // Add default port to all listener addresses if needed and remove // duplicate addresses. - cfg.Listeners = network.NormalizeAddresses(cfg.Listeners, - activeNetParams.DefaultPort) + activeConfig.Listeners = network.NormalizeAddresses(activeConfig.Listeners, + activeConfig.NetParams().DefaultPort) // Add default port to all rpc listener addresses if needed and remove // duplicate addresses. - cfg.RPCListeners = network.NormalizeAddresses(cfg.RPCListeners, - activeNetParams.RPCPort) + activeConfig.RPCListeners = network.NormalizeAddresses(activeConfig.RPCListeners, + activeConfig.NetParams().RPCPort) // Only allow TLS to be disabled if the RPC is bound to localhost // addresses. - if !cfg.DisableRPC && cfg.DisableTLS { + if !activeConfig.DisableRPC && activeConfig.DisableTLS { allowedTLSListeners := map[string]struct{}{ "localhost": {}, "127.0.0.1": {}, "::1": {}, } - for _, addr := range cfg.RPCListeners { + for _, addr := range activeConfig.RPCListeners { host, _, err := net.SplitHostPort(addr) if err != nil { str := "%s: RPC listen interface '%s' is " + @@ -840,13 +807,13 @@ func loadConfig() (*Config, []string, error) { // Add default port to all added peer addresses if needed and remove // duplicate addresses. - cfg.AddPeers = network.NormalizeAddresses(cfg.AddPeers, - activeNetParams.DefaultPort) - cfg.ConnectPeers = network.NormalizeAddresses(cfg.ConnectPeers, - activeNetParams.DefaultPort) + activeConfig.AddPeers = network.NormalizeAddresses(activeConfig.AddPeers, + activeConfig.NetParams().DefaultPort) + activeConfig.ConnectPeers = network.NormalizeAddresses(activeConfig.ConnectPeers, + activeConfig.NetParams().DefaultPort) // --noonion and --onion do not mix. - if cfg.NoOnion && cfg.OnionProxy != "" { + if activeConfig.NoOnion && activeConfig.OnionProxy != "" { err := errors.Errorf("%s: the --noonion and --onion options may "+ "not be activated at the same time", funcName) fmt.Fprintln(os.Stderr, err) @@ -855,7 +822,7 @@ func loadConfig() (*Config, []string, error) { } // Check the checkpoints for syntax errors. - cfg.AddCheckpoints, err = parseCheckpoints(cfg.configFlags.AddCheckpoints) + activeConfig.AddCheckpoints, err = parseCheckpoints(activeConfig.Flags.AddCheckpoints) if err != nil { str := "%s: Error parsing checkpoints: %s" err := errors.Errorf(str, funcName, err) @@ -865,7 +832,7 @@ func loadConfig() (*Config, []string, error) { } // Tor stream isolation requires either proxy or onion proxy to be set. - if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" { + if activeConfig.TorIsolation && activeConfig.Proxy == "" && activeConfig.OnionProxy == "" { str := "%s: Tor stream isolation requires either proxy or " + "onionproxy to be set" err := errors.Errorf(str, funcName) @@ -880,13 +847,13 @@ func loadConfig() (*Config, []string, error) { // proxy is specified, the dial function is set to the proxy specific // dial function and the lookup is set to use tor (unless --noonion is // specified in which case the system DNS resolver is used). - cfg.Dial = net.DialTimeout - cfg.Lookup = net.LookupIP - if cfg.Proxy != "" { - _, _, err := net.SplitHostPort(cfg.Proxy) + activeConfig.Dial = net.DialTimeout + activeConfig.Lookup = net.LookupIP + if activeConfig.Proxy != "" { + _, _, err := net.SplitHostPort(activeConfig.Proxy) if err != nil { str := "%s: Proxy address '%s' is invalid: %s" - err := errors.Errorf(str, funcName, cfg.Proxy, err) + err := errors.Errorf(str, funcName, activeConfig.Proxy, err) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err @@ -896,8 +863,8 @@ func loadConfig() (*Config, []string, error) { // unless there is also an onion proxy configured in which case // that one will be overridden. torIsolation := false - if cfg.TorIsolation && cfg.OnionProxy == "" && - (cfg.ProxyUser != "" || cfg.ProxyPass != "") { + if activeConfig.TorIsolation && activeConfig.OnionProxy == "" && + (activeConfig.ProxyUser != "" || activeConfig.ProxyPass != "") { torIsolation = true fmt.Fprintln(os.Stderr, "Tor isolation set -- "+ @@ -905,19 +872,19 @@ func loadConfig() (*Config, []string, error) { } proxy := &socks.Proxy{ - Addr: cfg.Proxy, - Username: cfg.ProxyUser, - Password: cfg.ProxyPass, + Addr: activeConfig.Proxy, + Username: activeConfig.ProxyUser, + Password: activeConfig.ProxyPass, TorIsolation: torIsolation, } - cfg.Dial = proxy.DialTimeout + activeConfig.Dial = proxy.DialTimeout // Treat the proxy as tor and perform DNS resolution through it // unless the --noonion flag is set or there is an // onion-specific proxy configured. - if !cfg.NoOnion && cfg.OnionProxy == "" { - cfg.Lookup = func(host string) ([]net.IP, error) { - return network.TorLookupIP(host, cfg.Proxy) + if !activeConfig.NoOnion && activeConfig.OnionProxy == "" { + activeConfig.Lookup = func(host string) ([]net.IP, error) { + return network.TorLookupIP(host, activeConfig.Proxy) } } } @@ -928,11 +895,11 @@ func loadConfig() (*Config, []string, error) { // function is set to use the onion-specific proxy while leaving the // normal dial function as selected above. This allows .onion address // traffic to be routed through a different proxy than normal traffic. - if cfg.OnionProxy != "" { - _, _, err := net.SplitHostPort(cfg.OnionProxy) + if activeConfig.OnionProxy != "" { + _, _, err := net.SplitHostPort(activeConfig.OnionProxy) if err != nil { str := "%s: Onion proxy address '%s' is invalid: %s" - err := errors.Errorf(str, funcName, cfg.OnionProxy, err) + err := errors.Errorf(str, funcName, activeConfig.OnionProxy, err) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err @@ -940,19 +907,19 @@ func loadConfig() (*Config, []string, error) { // Tor isolation flag means onion proxy credentials will be // overridden. - if cfg.TorIsolation && - (cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") { + if activeConfig.TorIsolation && + (activeConfig.OnionProxyUser != "" || activeConfig.OnionProxyPass != "") { fmt.Fprintln(os.Stderr, "Tor isolation set -- "+ "overriding specified onionproxy user "+ "credentials ") } - cfg.OnionDial = func(network, addr string, timeout time.Duration) (net.Conn, error) { + activeConfig.OnionDial = func(network, addr string, timeout time.Duration) (net.Conn, error) { proxy := &socks.Proxy{ - Addr: cfg.OnionProxy, - Username: cfg.OnionProxyUser, - Password: cfg.OnionProxyPass, - TorIsolation: cfg.TorIsolation, + Addr: activeConfig.OnionProxy, + Username: activeConfig.OnionProxyUser, + Password: activeConfig.OnionProxyPass, + TorIsolation: activeConfig.TorIsolation, } return proxy.DialTimeout(network, addr, timeout) } @@ -961,19 +928,19 @@ func loadConfig() (*Config, []string, error) { // configured), it means that the proxy configured by --proxy is // not a tor proxy, so override the DNS resolution to use the // onion-specific proxy. - if cfg.Proxy != "" { - cfg.Lookup = func(host string) ([]net.IP, error) { - return network.TorLookupIP(host, cfg.OnionProxy) + if activeConfig.Proxy != "" { + activeConfig.Lookup = func(host string) ([]net.IP, error) { + return network.TorLookupIP(host, activeConfig.OnionProxy) } } } else { - cfg.OnionDial = cfg.Dial + activeConfig.OnionDial = activeConfig.Dial } // Specifying --noonion means the onion address dial function results in // an error. - if cfg.NoOnion { - cfg.OnionDial = func(a, b string, t time.Duration) (net.Conn, error) { + if activeConfig.NoOnion { + activeConfig.OnionDial = func(a, b string, t time.Duration) (net.Conn, error) { return nil, errors.New("tor has been disabled") } } @@ -985,7 +952,7 @@ func loadConfig() (*Config, []string, error) { log.Warnf("%s", configFileError) } - return &cfg, remainingArgs, nil + return activeConfig, remainingArgs, nil } // createDefaultConfig copies the file sample-btcd.conf to the given destination path, @@ -1054,8 +1021,3 @@ func createDefaultConfigFile(destinationPath string) error { return nil } - -//ActiveNetParams returns a pointer to the current active net params -func ActiveNetParams() *dagconfig.Params { - return activeNetParams -} diff --git a/config/network.go b/config/network.go new file mode 100644 index 000000000..117e97d1d --- /dev/null +++ b/config/network.go @@ -0,0 +1,60 @@ +package config + +import ( + "fmt" + "github.com/daglabs/btcd/dagconfig" + "github.com/jessevdk/go-flags" + "github.com/pkg/errors" + "os" +) + +// NetworkFlags holds the network configuration, that is which network is selected. +type NetworkFlags struct { + TestNet bool `long:"testnet" description:"Use the test network"` + RegressionTest bool `long:"regtest" description:"Use the regression test network"` + SimNet bool `long:"simnet" description:"Use the simulation test network"` + DevNet bool `long:"devnet" description:"Use the development test network"` + ActiveNetParams *dagconfig.Params +} + +// ResolveNetwork parses the network command line argument and sets NetParams accordingly. +// It returns error if more than one network was selected, nil otherwise. +func (networkFlags *NetworkFlags) ResolveNetwork(parser *flags.Parser) error { + //NetParams holds the selected network parameters. Default value is main-net. + networkFlags.ActiveNetParams = &dagconfig.MainNetParams + // Multiple networks can't be selected simultaneously. + numNets := 0 + // default net is main net + // Count number of network flags passed; assign active network params + // while we're at it + if networkFlags.TestNet { + numNets++ + networkFlags.ActiveNetParams = &dagconfig.TestNetParams + } + if networkFlags.RegressionTest { + numNets++ + networkFlags.ActiveNetParams = &dagconfig.RegressionNetParams + } + if networkFlags.SimNet { + numNets++ + networkFlags.ActiveNetParams = &dagconfig.SimNetParams + } + if networkFlags.DevNet { + numNets++ + networkFlags.ActiveNetParams = &dagconfig.DevNetParams + } + if numNets > 1 { + message := "Multiple networks parameters (testnet, simnet, devnet, etc.) cannot be used" + + "together. Please choose only one network" + err := errors.Errorf(message) + fmt.Fprintln(os.Stderr, err) + parser.WriteHelp(os.Stderr) + return err + } + return nil +} + +// NetParams returns the ActiveNetParams +func (networkFlags *NetworkFlags) NetParams() *dagconfig.Params { + return networkFlags.ActiveNetParams +} diff --git a/connmgr/seed.go b/connmgr/seed.go index 6db6afb96..ceeb707db 100644 --- a/connmgr/seed.go +++ b/connmgr/seed.go @@ -43,7 +43,7 @@ func SeedFromDNS(dagParams *dagconfig.Params, reqServices wire.ServiceFlag, incl subnetworkID *subnetworkid.SubnetworkID, lookupFn LookupFunc, seedFn OnSeed) { var dnsSeeds []string - mainConfig := config.MainConfig() + mainConfig := config.ActiveConfig() if mainConfig != nil && mainConfig.DNSSeed != "" { dnsSeeds = []string{mainConfig.DNSSeed} } else { diff --git a/dnsseeder/config.go b/dnsseeder/config.go index 8d4557a0b..7d41eb194 100644 --- a/dnsseeder/config.go +++ b/dnsseeder/config.go @@ -6,13 +6,13 @@ package main import ( "fmt" + "github.com/daglabs/btcd/config" "github.com/pkg/errors" "net" "os" "path/filepath" "strings" - "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/util" "github.com/jessevdk/go-flags" ) @@ -25,9 +25,6 @@ const ( ) var ( - // Default network parameters - activeNetParams = &dagconfig.MainNetParams - // Default configuration options defaultHomeDir = util.AppDataDir("dnsseeder", false) defaultConfigFile = filepath.Join(defaultHomeDir, defaultConfigFilename) @@ -35,19 +32,23 @@ var ( defaultErrLogFile = filepath.Join(defaultHomeDir, defaultErrLogFilename) ) -// config defines the configuration options for hardforkdemo. -// -// See loadConfig for details on the configuration load process. -type config struct { +var activeConfig *ConfigFlags + +// ActiveConfig returns the active configuration struct +func ActiveConfig() *ConfigFlags { + return activeConfig +} + +// ConfigFlags holds the configurations set by the command line argument +type ConfigFlags struct { Host string `short:"H" long:"host" description:"Seed DNS address"` Listen string `long:"listen" short:"l" description:"Listen on address:port"` Nameserver string `short:"n" long:"nameserver" description:"hostname of nameserver"` Seeder string `short:"s" long:"default seeder" description:"IP address of a working node"` - TestNet bool `long:"testnet" description:"Use testnet"` - DevNet bool `long:"devnet" description:"Use devnet"` + config.NetworkFlags } -func loadConfig() (*config, error) { +func loadConfig() (*ConfigFlags, error) { err := os.MkdirAll(defaultHomeDir, 0700) if err != nil { // Show a nicer error message if it's because a symlink is @@ -67,11 +68,11 @@ func loadConfig() (*config, error) { } // Default config. - cfg := config{ + activeConfig = &ConfigFlags{ Listen: normalizeAddress("localhost", defaultListenPort), } - preCfg := cfg + preCfg := activeConfig preParser := flags.NewParser(&preCfg, flags.Default) _, err = preParser.Parse() if err != nil { @@ -88,11 +89,11 @@ func loadConfig() (*config, error) { usageMessage := fmt.Sprintf("Use %s -h to show usage", appName) // Load additional config from file. - parser := flags.NewParser(&cfg, flags.Default) + parser := flags.NewParser(&activeConfig, flags.Default) err = flags.NewIniParser(parser).ParseFile(defaultConfigFile) if err != nil { if _, ok := err.(*os.PathError); !ok { - fmt.Fprintf(os.Stderr, "Error parsing config "+ + fmt.Fprintf(os.Stderr, "Error parsing ConfigFlags "+ "file: %v\n", err) fmt.Fprintln(os.Stderr, usageMessage) return nil, err @@ -108,36 +109,30 @@ func loadConfig() (*config, error) { return nil, err } - if len(cfg.Host) == 0 { + if len(activeConfig.Host) == 0 { str := "Please specify a hostname" err := errors.Errorf(str) fmt.Fprintln(os.Stderr, err) return nil, err } - if len(cfg.Nameserver) == 0 { + if len(activeConfig.Nameserver) == 0 { str := "Please specify a nameserver" err := errors.Errorf(str) fmt.Fprintln(os.Stderr, err) return nil, err } - cfg.Listen = normalizeAddress(cfg.Listen, defaultListenPort) + activeConfig.Listen = normalizeAddress(activeConfig.Listen, defaultListenPort) - if cfg.TestNet && cfg.DevNet { - str := "Both testnet and devnet are specified" - err := errors.Errorf(str) - fmt.Fprintln(os.Stderr, err) + err = activeConfig.ResolveNetwork(parser) + if err != nil { return nil, err - } else if cfg.TestNet { - activeNetParams = &dagconfig.TestNetParams - } else if cfg.DevNet { - activeNetParams = &dagconfig.DevNetParams } initLog(defaultLogFile, defaultErrLogFile) - return &cfg, nil + return activeConfig, nil } // normalizeAddress returns addr with the passed default port appended if diff --git a/dnsseeder/dnsseed.go b/dnsseeder/dnsseed.go index c7b2c18e4..1dc087639 100644 --- a/dnsseeder/dnsseed.go +++ b/dnsseeder/dnsseed.go @@ -55,12 +55,12 @@ func creep() { onAddr := make(chan struct{}) onVersion := make(chan struct{}) - config := peer.Config{ + cfg := peer.Config{ UserAgentName: "daglabs-sniffer", UserAgentVersion: "0.0.1", - DAGParams: activeNetParams, + DAGParams: ActiveConfig().NetParams(), DisableRelayTx: true, - SelectedTip: func() *daghash.Hash { return activeNetParams.GenesisBlock.BlockHash() }, + SelectedTip: func() *daghash.Hash { return ActiveConfig().NetParams().GenesisBlock.BlockHash() }, Listeners: peer.MessageListeners{ OnAddr: func(p *peer.Peer, msg *wire.MsgAddr) { @@ -87,7 +87,7 @@ func creep() { peers := amgr.Addresses() if len(peers) == 0 && amgr.AddressCount() == 0 { // Add peers discovered through DNS to the address manager. - connmgr.SeedFromDNS(activeNetParams, requiredServices, true, nil, hostLookup, func(addrs []*wire.NetAddress) { + connmgr.SeedFromDNS(ActiveConfig().NetParams(), requiredServices, true, nil, hostLookup, func(addrs []*wire.NetAddress) { amgr.AddAddresses(addrs) }) peers = amgr.Addresses() @@ -116,7 +116,7 @@ func creep() { defer wgCreep.Done() host := net.JoinHostPort(addr.IP.String(), strconv.Itoa(int(addr.Port))) - p, err := peer.NewOutboundPeer(&config, host) + p, err := peer.NewOutboundPeer(&cfg, host) if err != nil { log.Warnf("NewOutboundPeer on %v: %v", host, err) @@ -168,9 +168,9 @@ func main() { os.Exit(1) } - peersDefaultPort, err = strconv.Atoi(activeNetParams.DefaultPort) + peersDefaultPort, err = strconv.Atoi(ActiveConfig().NetParams().DefaultPort) if err != nil { - fmt.Fprintf(os.Stderr, "Invalid peers default port %s: %v\n", activeNetParams.DefaultPort, err) + fmt.Fprintf(os.Stderr, "Invalid peers default port %s: %v\n", ActiveConfig().NetParams().DefaultPort, err) os.Exit(1) } diff --git a/dnsseeder/manager.go b/dnsseeder/manager.go index 408e3692e..dc5488a9d 100644 --- a/dnsseeder/manager.go +++ b/dnsseeder/manager.go @@ -101,7 +101,7 @@ func ipNet(ip string, ones, bits int) net.IPNet { } func isRoutable(addr net.IP) bool { - if activeNetParams.AcceptUnroutable { + if ActiveConfig().NetParams().AcceptUnroutable { return true } diff --git a/server/p2p/on_addr.go b/server/p2p/on_addr.go index 59ca80357..1757acd8e 100644 --- a/server/p2p/on_addr.go +++ b/server/p2p/on_addr.go @@ -14,7 +14,7 @@ func (sp *Peer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) { // helps prevent the network from becoming another public test network // since it will not be able to learn about other peers that have not // specifically been provided. - if config.MainConfig().SimNet { + if config.ActiveConfig().SimNet { return } @@ -31,9 +31,9 @@ func (sp *Peer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) { msg.Command(), sp.Peer) sp.Disconnect() return - } else if !msg.SubnetworkID.IsEqual(config.MainConfig().SubnetworkID) && msg.SubnetworkID != nil { + } else if !msg.SubnetworkID.IsEqual(config.ActiveConfig().SubnetworkID) && msg.SubnetworkID != nil { peerLog.Errorf("Only full nodes and %s subnetwork IDs are allowed in [%s] command, but got subnetwork ID %s from %s", - config.MainConfig().SubnetworkID, msg.Command(), msg.SubnetworkID, sp.Peer) + config.ActiveConfig().SubnetworkID, msg.Command(), msg.SubnetworkID, sp.Peer) sp.Disconnect() return } diff --git a/server/p2p/on_get_addr.go b/server/p2p/on_get_addr.go index 1961d186e..eb78532e6 100644 --- a/server/p2p/on_get_addr.go +++ b/server/p2p/on_get_addr.go @@ -14,7 +14,7 @@ func (sp *Peer) OnGetAddr(_ *peer.Peer, msg *wire.MsgGetAddr) { // network. This helps prevent the network from becoming another // public test network since it will not be able to learn about other // peers that have not specifically been provided. - if config.MainConfig().SimNet { + if config.ActiveConfig().SimNet { return } diff --git a/server/p2p/on_inv.go b/server/p2p/on_inv.go index d521744ab..c102fc337 100644 --- a/server/p2p/on_inv.go +++ b/server/p2p/on_inv.go @@ -11,7 +11,7 @@ import ( // accordingly. We pass the message down to blockmanager which will call // QueueMessage with any appropriate responses. func (sp *Peer) OnInv(_ *peer.Peer, msg *wire.MsgInv) { - if !config.MainConfig().BlocksOnly { + if !config.ActiveConfig().BlocksOnly { if len(msg.InvList) > 0 { sp.server.SyncManager.QueueInv(msg, sp.Peer) } diff --git a/server/p2p/on_tx.go b/server/p2p/on_tx.go index 7051a77be..2809f7a3d 100644 --- a/server/p2p/on_tx.go +++ b/server/p2p/on_tx.go @@ -13,7 +13,7 @@ import ( // handler this does not serialize all transactions through a single thread // transactions don't rely on the previous one in a linear fashion like blocks. func (sp *Peer) OnTx(_ *peer.Peer, msg *wire.MsgTx) { - if config.MainConfig().BlocksOnly { + if config.ActiveConfig().BlocksOnly { peerLog.Tracef("Ignoring tx %s from %s - blocksonly enabled", msg.TxID(), sp) return diff --git a/server/p2p/on_version.go b/server/p2p/on_version.go index 84954bac1..311797423 100644 --- a/server/p2p/on_version.go +++ b/server/p2p/on_version.go @@ -27,14 +27,14 @@ func (sp *Peer) OnVersion(_ *peer.Peer, msg *wire.MsgVersion) { // on the simulation test network since it is only intended to connect // to specified peers and actively avoids advertising and connecting to // discovered peers. - if !config.MainConfig().SimNet { + if !config.ActiveConfig().SimNet { addrManager := sp.server.addrManager // Outbound connections. if !sp.Inbound() { // TODO(davec): Only do this if not doing the initial block // download and the local address is routable. - if !config.MainConfig().DisableListen /* && isCurrent? */ { + if !config.ActiveConfig().DisableListen /* && isCurrent? */ { // Get address that best matches. lna := addrManager.GetBestLocalAddress(sp.NA()) if addrmgr.IsRoutable(lna) { diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index c8d3c1e18..5a048a1fd 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -384,7 +384,7 @@ func (sp *Peer) pushAddrMsg(addresses []*wire.NetAddress, subnetworkID *subnetwo // disconnected. func (sp *Peer) addBanScore(persistent, transient uint32, reason string) { // No warning is logged and no score is calculated if banning is disabled. - if config.MainConfig().DisableBanning { + if config.ActiveConfig().DisableBanning { return } if sp.isWhitelisted { @@ -392,7 +392,7 @@ func (sp *Peer) addBanScore(persistent, transient uint32, reason string) { return } - warnThreshold := config.MainConfig().BanThreshold >> 1 + warnThreshold := config.ActiveConfig().BanThreshold >> 1 if transient == 0 && persistent == 0 { // The score is not being increased, but a warning message is still // logged if the score is above the warn threshold. @@ -407,7 +407,7 @@ func (sp *Peer) addBanScore(persistent, transient uint32, reason string) { if score > warnThreshold { peerLog.Warnf("Misbehaving peer %s: %s -- ban score increased to %d", sp, reason, score) - if score > config.MainConfig().BanThreshold { + if score > config.ActiveConfig().BanThreshold { peerLog.Warnf("Misbehaving peer %s -- banning and disconnecting", sp) sp.server.BanPeer(sp) @@ -426,7 +426,7 @@ func (sp *Peer) enforceNodeBloomFlag(cmd string) bool { // whether or not banning is enabled, it is checked here as well // to ensure the violation is logged and the peer is // disconnected regardless. - if !config.MainConfig().DisableBanning { + if !config.ActiveConfig().DisableBanning { // Disconnect the peer regardless of whether it was // banned. @@ -687,9 +687,9 @@ func (s *Server) handleAddPeerMsg(state *peerState, sp *Peer) bool { // TODO: Check for max peers from a single IP. // Limit max number of total peers. - if state.Count() >= config.MainConfig().MaxPeers { + if state.Count() >= config.ActiveConfig().MaxPeers { srvrLog.Infof("Max peers reached [%d] - disconnecting peer %s", - config.MainConfig().MaxPeers, sp) + config.ActiveConfig().MaxPeers, sp) sp.Disconnect() // TODO: how to handle permanent peers here? // they should be rescheduled. @@ -758,8 +758,8 @@ func (s *Server) handleBanPeerMsg(state *peerState, sp *Peer) { } direction := logger.DirectionString(sp.Inbound()) srvrLog.Infof("Banned peer %s (%s) for %s", host, direction, - config.MainConfig().BanDuration) - state.banned[host] = time.Now().Add(config.MainConfig().BanDuration) + config.ActiveConfig().BanDuration) + state.banned[host] = time.Now().Add(config.ActiveConfig().BanDuration) } // handleRelayInvMsg deals with relaying inventory to peers that are not already @@ -938,7 +938,7 @@ func (s *Server) handleQuery(state *peerState, querymsg interface{}) { case ConnectNodeMsg: // TODO: duplicate oneshots? // Limit max number of total peers. - if state.Count() >= config.MainConfig().MaxPeers { + if state.Count() >= config.ActiveConfig().MaxPeers { msg.Reply <- errors.New("max peers reached") return } @@ -1084,15 +1084,15 @@ func newPeerConfig(sp *Peer) *peer.Config { SelectedTip: sp.selectedTip, BlockExists: sp.blockExists, HostToNetAddress: sp.server.addrManager.HostToNetAddress, - Proxy: config.MainConfig().Proxy, + Proxy: config.ActiveConfig().Proxy, UserAgentName: userAgentName, UserAgentVersion: userAgentVersion, - UserAgentComments: config.MainConfig().UserAgentComments, + UserAgentComments: config.ActiveConfig().UserAgentComments, DAGParams: sp.server.DAGParams, Services: sp.server.services, - DisableRelayTx: config.MainConfig().BlocksOnly, + DisableRelayTx: config.ActiveConfig().BlocksOnly, ProtocolVersion: peer.MaxProtocolVersion, - SubnetworkID: config.MainConfig().SubnetworkID, + SubnetworkID: config.ActiveConfig().SubnetworkID, } } @@ -1176,9 +1176,9 @@ func (s *Server) peerHandler() { outboundGroups: make(map[string]int), } - if !config.MainConfig().DisableDNSSeed { + if !config.ActiveConfig().DisableDNSSeed { seedFromSubNetwork := func(subnetworkID *subnetworkid.SubnetworkID) { - connmgr.SeedFromDNS(config.ActiveNetParams(), defaultRequiredServices, + connmgr.SeedFromDNS(config.ActiveConfig().NetParams(), defaultRequiredServices, false, subnetworkID, serverutils.BTCDLookup, func(addrs []*wire.NetAddress) { // Bitcoind uses a lookup of the dns seeder here. Since seeder returns // IPs of nodes and not its own IP, we can not know real IP of @@ -1190,9 +1190,9 @@ func (s *Server) peerHandler() { // Add full nodes discovered through DNS to the address manager. seedFromSubNetwork(nil) - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { // Node is partial - fetch nodes with same subnetwork - seedFromSubNetwork(config.MainConfig().SubnetworkID) + seedFromSubNetwork(config.ActiveConfig().SubnetworkID) } } spawn(s.connManager.Start) @@ -1403,7 +1403,7 @@ func (s *Server) Start() { spawn(s.upnpUpdateThread) } - cfg := config.MainConfig() + cfg := config.ActiveConfig() if !cfg.DisableRPC { s.wg.Add(1) @@ -1522,7 +1522,7 @@ func (s *Server) upnpUpdateThread() { // Go off immediately to prevent code duplication, thereafter we renew // lease every 15 minutes. timer := time.NewTimer(0 * time.Second) - lport, _ := strconv.ParseInt(config.ActiveNetParams().DefaultPort, 10, 16) + lport, _ := strconv.ParseInt(config.ActiveConfig().NetParams().DefaultPort, 10, 16) first := true out: for { @@ -1577,18 +1577,18 @@ out: // connections from peers. func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params, interrupt <-chan struct{}, notifyNewTransactions func(txns []*mempool.TxDesc)) (*Server, error) { services := defaultServices - if config.MainConfig().NoPeerBloomFilters { + if config.ActiveConfig().NoPeerBloomFilters { services &^= wire.SFNodeBloom } - if !config.MainConfig().EnableCFilters { + if !config.ActiveConfig().EnableCFilters { services &^= wire.SFNodeCF } - amgr := addrmgr.New(config.MainConfig().DataDir, serverutils.BTCDLookup, config.MainConfig().SubnetworkID) + amgr := addrmgr.New(config.ActiveConfig().DataDir, serverutils.BTCDLookup, config.ActiveConfig().SubnetworkID) var listeners []net.Listener var nat serverutils.NAT - if !config.MainConfig().DisableListen { + if !config.ActiveConfig().DisableListen { var err error listeners, nat, err = initListeners(amgr, listenAddrs, services) if err != nil { @@ -1602,12 +1602,12 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params s := Server{ DAGParams: dagParams, addrManager: amgr, - newPeers: make(chan *Peer, config.MainConfig().MaxPeers), - donePeers: make(chan *Peer, config.MainConfig().MaxPeers), - banPeers: make(chan *Peer, config.MainConfig().MaxPeers), + newPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), + donePeers: make(chan *Peer, config.ActiveConfig().MaxPeers), + banPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), Query: make(chan interface{}), - relayInv: make(chan relayMsg, config.MainConfig().MaxPeers), - broadcast: make(chan broadcastMsg, config.MainConfig().MaxPeers), + relayInv: make(chan relayMsg, config.ActiveConfig().MaxPeers), + broadcast: make(chan broadcastMsg, config.ActiveConfig().MaxPeers), quit: make(chan struct{}), modifyRebroadcastInv: make(chan interface{}), newOutboundConnection: make(chan *outboundPeerConnectedMsg), @@ -1615,7 +1615,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params db: db, TimeSource: blockdag.NewMedianTime(), services: services, - SigCache: txscript.NewSigCache(config.MainConfig().SigCacheMaxSize), + SigCache: txscript.NewSigCache(config.ActiveConfig().SigCacheMaxSize), cfCheckptCaches: make(map[wire.FilterType][]cfHeaderKV), notifyNewTransactions: notifyNewTransactions, } @@ -1627,13 +1627,13 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // addrindex is run first, it may not have the transactions from the // current block indexed. var indexes []indexers.Indexer - if config.MainConfig().TxIndex || config.MainConfig().AddrIndex { + if config.ActiveConfig().TxIndex || config.ActiveConfig().AddrIndex { // Enable transaction index if address index is enabled since it // requires it. - if !config.MainConfig().TxIndex { + if !config.ActiveConfig().TxIndex { indxLog.Infof("Transaction index enabled because it " + "is required by the address index") - config.MainConfig().TxIndex = true + config.ActiveConfig().TxIndex = true } else { indxLog.Info("Transaction index is enabled") } @@ -1641,17 +1641,17 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params s.TxIndex = indexers.NewTxIndex() indexes = append(indexes, s.TxIndex) } - if config.MainConfig().AddrIndex { + if config.ActiveConfig().AddrIndex { indxLog.Info("Address index is enabled") s.AddrIndex = indexers.NewAddrIndex(dagParams) indexes = append(indexes, s.AddrIndex) } - if config.MainConfig().AcceptanceIndex { + if config.ActiveConfig().AcceptanceIndex { indxLog.Info("acceptance index is enabled") s.AcceptanceIndex = indexers.NewAcceptanceIndex() indexes = append(indexes, s.AcceptanceIndex) } - if config.MainConfig().EnableCFilters { + if config.ActiveConfig().EnableCFilters { indxLog.Info("cf index is enabled") s.CfIndex = indexers.NewCfIndex(dagParams) indexes = append(indexes, s.CfIndex) @@ -1665,8 +1665,8 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // Merge given checkpoints with the default ones unless they are disabled. var checkpoints []dagconfig.Checkpoint - if !config.MainConfig().DisableCheckpoints { - checkpoints = mergeCheckpoints(s.DAGParams.Checkpoints, config.MainConfig().AddCheckpoints) + if !config.ActiveConfig().DisableCheckpoints { + checkpoints = mergeCheckpoints(s.DAGParams.Checkpoints, config.ActiveConfig().AddCheckpoints) } // Create a new block chain instance with the appropriate configuration. @@ -1679,7 +1679,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params TimeSource: s.TimeSource, SigCache: s.SigCache, IndexManager: indexManager, - SubnetworkID: config.MainConfig().SubnetworkID, + SubnetworkID: config.ActiveConfig().SubnetworkID, }) if err != nil { return nil, err @@ -1687,10 +1687,10 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params txC := mempool.Config{ Policy: mempool.Policy{ - AcceptNonStd: config.MainConfig().RelayNonStd, - MaxOrphanTxs: config.MainConfig().MaxOrphanTxs, + AcceptNonStd: config.ActiveConfig().RelayNonStd, + MaxOrphanTxs: config.ActiveConfig().MaxOrphanTxs, MaxOrphanTxSize: config.DefaultMaxOrphanTxSize, - MinRelayTxFee: config.MainConfig().MinRelayTxFee, + MinRelayTxFee: config.ActiveConfig().MinRelayTxFee, MaxTxVersion: 1, }, DAGParams: dagParams, @@ -1706,7 +1706,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params } s.TxMemPool = mempool.New(&txC) - cfg := config.MainConfig() + cfg := config.ActiveConfig() s.SyncManager, err = netsync.New(&netsync.Config{ PeerNotifier: &s, @@ -1727,7 +1727,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // discovered peers in order to prevent it from becoming a public test // network. var newAddressFunc func() (net.Addr, error) - if !config.MainConfig().SimNet && len(config.MainConfig().ConnectPeers) == 0 { + if !config.ActiveConfig().SimNet && len(config.ActiveConfig().ConnectPeers) == 0 { newAddressFunc = func() (net.Addr, error) { for tries := 0; tries < 100; tries++ { addr := s.addrManager.GetAddress() @@ -1745,7 +1745,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // Networks that accept unroutable connections are exempt // from this rule, since they're meant to run within a // private subnet, like 10.0.0.0/16. - if !config.ActiveNetParams().AcceptUnroutable { + if !config.ActiveConfig().NetParams().AcceptUnroutable { key := addrmgr.GroupKey(addr.NetAddress()) if s.OutboundGroupCount(key) != 0 { continue @@ -1760,7 +1760,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // allow nondefault ports after 50 failed tries. if tries < 50 && fmt.Sprintf("%d", addr.NetAddress().Port) != - config.ActiveNetParams().DefaultPort { + config.ActiveConfig().NetParams().DefaultPort { continue } @@ -1773,8 +1773,8 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // Create a connection manager. targetOutbound := defaultTargetOutbound - if config.MainConfig().MaxPeers < targetOutbound { - targetOutbound = config.MainConfig().MaxPeers + if config.ActiveConfig().MaxPeers < targetOutbound { + targetOutbound = config.ActiveConfig().MaxPeers } cmgr, err := connmgr.New(&connmgr.Config{ Listeners: listeners, @@ -1796,9 +1796,9 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params s.connManager = cmgr // Start up persistent peers. - permanentPeers := config.MainConfig().ConnectPeers + permanentPeers := config.ActiveConfig().ConnectPeers if len(permanentPeers) == 0 { - permanentPeers = config.MainConfig().AddPeers + permanentPeers = config.ActiveConfig().AddPeers } for _, addr := range permanentPeers { netAddr, err := addrStringToNetAddr(addr) @@ -1836,15 +1836,15 @@ func initListeners(amgr *addrmgr.AddrManager, listenAddrs []string, services wir } var nat serverutils.NAT - if len(config.MainConfig().ExternalIPs) != 0 { - defaultPort, err := strconv.ParseUint(config.ActiveNetParams().DefaultPort, 10, 16) + if len(config.ActiveConfig().ExternalIPs) != 0 { + defaultPort, err := strconv.ParseUint(config.ActiveConfig().NetParams().DefaultPort, 10, 16) if err != nil { srvrLog.Errorf("Can not parse default port %s for active chain: %s", - config.ActiveNetParams().DefaultPort, err) + config.ActiveConfig().NetParams().DefaultPort, err) return nil, nil, err } - for _, sip := range config.MainConfig().ExternalIPs { + for _, sip := range config.ActiveConfig().ExternalIPs { eport := uint16(defaultPort) host, portstr, err := net.SplitHostPort(sip) if err != nil { @@ -1871,7 +1871,7 @@ func initListeners(amgr *addrmgr.AddrManager, listenAddrs []string, services wir } } } else { - if config.MainConfig().Upnp { + if config.ActiveConfig().Upnp { var err error nat, err = serverutils.Discover() if err != nil { @@ -1919,7 +1919,7 @@ func addrStringToNetAddr(addr string) (net.Addr, error) { // Tor addresses cannot be resolved to an IP, so just return an onion // address instead. if strings.HasSuffix(host, ".onion") { - if config.MainConfig().NoOnion { + if config.ActiveConfig().NoOnion { return nil, errors.New("tor has been disabled") } @@ -2012,7 +2012,7 @@ func dynamicTickDuration(remaining time.Duration) time.Duration { // isWhitelisted returns whether the IP address is included in the whitelisted // networks and IPs. func isWhitelisted(addr net.Addr) bool { - if len(config.MainConfig().Whitelists) == 0 { + if len(config.ActiveConfig().Whitelists) == 0 { return false } @@ -2027,7 +2027,7 @@ func isWhitelisted(addr net.Addr) bool { return false } - for _, ipnet := range config.MainConfig().Whitelists { + for _, ipnet := range config.ActiveConfig().Whitelists { if ipnet.Contains(ip) { return true } @@ -2107,7 +2107,7 @@ func (s *Server) AnnounceNewTransactions(txns []*mempool.TxDesc) { // longer needing rebroadcasting. func (s *Server) TransactionConfirmed(tx *util.Tx) { // Rebroadcasting is only necessary when the RPC server is active. - if config.MainConfig().DisableRPC { + if config.ActiveConfig().DisableRPC { return } diff --git a/server/rpc/handle_generate.go b/server/rpc/handle_generate.go index 21aeacdb0..c3e5c66c9 100644 --- a/server/rpc/handle_generate.go +++ b/server/rpc/handle_generate.go @@ -10,7 +10,7 @@ import ( func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Respond with an error if there are no addresses to pay the // created blocks to. - if len(config.MainConfig().MiningAddrs) == 0 { + if len(config.ActiveConfig().MiningAddrs) == 0 { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, Message: "No payment addresses specified " + @@ -18,7 +18,7 @@ func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte } } - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, Message: "`generate` is not supported on partial nodes.", diff --git a/server/rpc/handle_get_block.go b/server/rpc/handle_get_block.go index 783f4f4dd..bde9ce7f1 100644 --- a/server/rpc/handle_get_block.go +++ b/server/rpc/handle_get_block.go @@ -53,7 +53,7 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte Message: "invalid subnetwork string", } } - nodeSubnetworkID := config.MainConfig().SubnetworkID + nodeSubnetworkID := config.ActiveConfig().SubnetworkID if requestSubnetworkID != nil { if nodeSubnetworkID != nil { diff --git a/server/rpc/handle_get_block_template.go b/server/rpc/handle_get_block_template.go index f94778e05..9df451291 100644 --- a/server/rpc/handle_get_block_template.go +++ b/server/rpc/handle_get_block_template.go @@ -163,7 +163,7 @@ func handleGetBlockTemplateRequest(s *Server, request *btcjson.TemplateRequest, // When a coinbase transaction has been requested, respond with an error // if there are no addresses to pay the created block template to. - if !useCoinbaseValue && len(config.MainConfig().MiningAddrs) == 0 { + if !useCoinbaseValue && len(config.ActiveConfig().MiningAddrs) == 0 { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, Message: "A coinbase transaction has been requested, " + @@ -176,7 +176,7 @@ func handleGetBlockTemplateRequest(s *Server, request *btcjson.TemplateRequest, // way to relay a found block or receive transactions to work on. // However, allow this state when running in the regression test or // simulation test mode. - if !(config.MainConfig().RegressionTest || config.MainConfig().SimNet) && + if !(config.ActiveConfig().RegressionTest || config.ActiveConfig().SimNet) && s.cfg.ConnMgr.ConnectedCount() == 0 { return nil, &btcjson.RPCError{ @@ -607,7 +607,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *Server, useCoinbaseValue bool) // to create their own coinbase. var payAddr util.Address if !useCoinbaseValue { - payAddr = config.MainConfig().MiningAddrs[rand.Intn(len(config.MainConfig().MiningAddrs))] + payAddr = config.ActiveConfig().MiningAddrs[rand.Intn(len(config.ActiveConfig().MiningAddrs))] } // Create a new block template that has a coinbase which anyone @@ -661,7 +661,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *Server, useCoinbaseValue bool) // returned if none have been specified. if !useCoinbaseValue && !template.ValidPayAddress { // Choose a payment address at random. - payToAddr := config.MainConfig().MiningAddrs[rand.Intn(len(config.MainConfig().MiningAddrs))] + payToAddr := config.ActiveConfig().MiningAddrs[rand.Intn(len(config.ActiveConfig().MiningAddrs))] // Update the block coinbase output of the template to // pay to the randomly selected payment address. diff --git a/server/rpc/handle_get_hashes_per_sec.go b/server/rpc/handle_get_hashes_per_sec.go index 0e9e504f3..2aeca4e3a 100644 --- a/server/rpc/handle_get_hashes_per_sec.go +++ b/server/rpc/handle_get_hashes_per_sec.go @@ -7,7 +7,7 @@ import ( // handleGetHashesPerSec implements the getHashesPerSec command. func handleGetHashesPerSec(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, Message: "`getHashesPerSec` is not supported on partial nodes.", diff --git a/server/rpc/handle_get_info.go b/server/rpc/handle_get_info.go index 155c9c83b..7afa8a93f 100644 --- a/server/rpc/handle_get_info.go +++ b/server/rpc/handle_get_info.go @@ -15,11 +15,11 @@ func handleGetInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (inter Blocks: s.cfg.DAG.BlockCount(), TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()), Connections: s.cfg.ConnMgr.ConnectedCount(), - Proxy: config.MainConfig().Proxy, + Proxy: config.ActiveConfig().Proxy, Difficulty: getDifficultyRatio(s.cfg.DAG.CurrentBits(), s.cfg.DAGParams), - TestNet: config.MainConfig().TestNet, - DevNet: config.MainConfig().DevNet, - RelayFee: config.MainConfig().MinRelayTxFee.ToBTC(), + TestNet: config.ActiveConfig().TestNet, + DevNet: config.ActiveConfig().DevNet, + RelayFee: config.ActiveConfig().MinRelayTxFee.ToBTC(), } return ret, nil diff --git a/server/rpc/handle_get_mining_info.go b/server/rpc/handle_get_mining_info.go index 2ec238a67..8da0e65db 100644 --- a/server/rpc/handle_get_mining_info.go +++ b/server/rpc/handle_get_mining_info.go @@ -8,7 +8,7 @@ import ( // handleGetMiningInfo implements the getMiningInfo command. We only return the // fields that are not related to wallet functionality. func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, Message: "`getMiningInfo` is not supported on partial nodes.", @@ -50,8 +50,8 @@ func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) HashesPerSec: int64(s.cfg.CPUMiner.HashesPerSecond()), NetworkHashPS: networkHashesPerSec, PooledTx: uint64(s.cfg.TxMemPool.Count()), - TestNet: config.MainConfig().TestNet, - DevNet: config.MainConfig().DevNet, + TestNet: config.ActiveConfig().TestNet, + DevNet: config.ActiveConfig().DevNet, } return &result, nil } diff --git a/server/rpc/handle_get_network_hash_ps.go b/server/rpc/handle_get_network_hash_ps.go index 034f51f05..f8932b834 100644 --- a/server/rpc/handle_get_network_hash_ps.go +++ b/server/rpc/handle_get_network_hash_ps.go @@ -9,7 +9,7 @@ import ( // This command had been (possibly temporarily) dropped. // Originally it relied on height, which no longer makes sense. func handleGetNetworkHashPS(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, Message: "`getNetworkHashPS` is not supported on partial nodes.", diff --git a/server/rpc/handle_set_generate.go b/server/rpc/handle_set_generate.go index 67d11aa2c..ffb6b84fa 100644 --- a/server/rpc/handle_set_generate.go +++ b/server/rpc/handle_set_generate.go @@ -7,7 +7,7 @@ import ( // handleSetGenerate implements the setGenerate command. func handleSetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - if config.MainConfig().SubnetworkID != nil { + if config.ActiveConfig().SubnetworkID != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, Message: "`setGenerate` is not supported on partial nodes.", @@ -33,7 +33,7 @@ func handleSetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (i } else { // Respond with an error if there are no addresses to pay the // created blocks to. - if len(config.MainConfig().MiningAddrs) == 0 { + if len(config.ActiveConfig().MiningAddrs) == 0 { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, Message: "No payment addresses specified " + diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 0a3008adc..62536da89 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -294,9 +294,9 @@ func (s *Server) NotifyNewTransactions(txns []*mempool.TxDesc) { // // This function is safe for concurrent access. func (s *Server) limitConnections(w http.ResponseWriter, remoteAddr string) bool { - if int(atomic.LoadInt32(&s.numClients)+1) > config.MainConfig().RPCMaxClients { + if int(atomic.LoadInt32(&s.numClients)+1) > config.ActiveConfig().RPCMaxClients { log.Infof("Max RPC clients exceeded [%d] - "+ - "disconnecting client %s", config.MainConfig().RPCMaxClients, + "disconnecting client %s", config.ActiveConfig().RPCMaxClients, remoteAddr) http.Error(w, "503 Too busy. Try again later.", http.StatusServiceUnavailable) @@ -514,7 +514,7 @@ func (s *Server) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin boo // // RPC quirks can be enabled by the user to avoid compatibility issues // with software relying on Core's behavior. - if request.ID == nil && !(config.MainConfig().RPCQuirks && request.JSONRPC == "") { + if request.ID == nil && !(config.ActiveConfig().RPCQuirks && request.JSONRPC == "") { return } @@ -819,16 +819,16 @@ type rpcserverConfig struct { func setupRPCListeners() ([]net.Listener, error) { // Setup TLS if not disabled. listenFunc := net.Listen - if !config.MainConfig().DisableTLS { + if !config.ActiveConfig().DisableTLS { // Generate the TLS cert and key file if both don't already // exist. - if !fs.FileExists(config.MainConfig().RPCKey) && !fs.FileExists(config.MainConfig().RPCCert) { - err := serverutils.GenCertPair(config.MainConfig().RPCCert, config.MainConfig().RPCKey) + if !fs.FileExists(config.ActiveConfig().RPCKey) && !fs.FileExists(config.ActiveConfig().RPCCert) { + err := serverutils.GenCertPair(config.ActiveConfig().RPCCert, config.ActiveConfig().RPCKey) if err != nil { return nil, err } } - keypair, err := tls.LoadX509KeyPair(config.MainConfig().RPCCert, config.MainConfig().RPCKey) + keypair, err := tls.LoadX509KeyPair(config.ActiveConfig().RPCCert, config.ActiveConfig().RPCKey) if err != nil { return nil, err } @@ -844,7 +844,7 @@ func setupRPCListeners() ([]net.Listener, error) { } } - netAddrs, err := p2p.ParseListeners(config.MainConfig().RPCListeners) + netAddrs, err := p2p.ParseListeners(config.ActiveConfig().RPCListeners) if err != nil { return nil, err } @@ -905,13 +905,13 @@ func NewRPCServer( requestProcessShutdown: make(chan struct{}), quit: make(chan int), } - if config.MainConfig().RPCUser != "" && config.MainConfig().RPCPass != "" { - login := config.MainConfig().RPCUser + ":" + config.MainConfig().RPCPass + if config.ActiveConfig().RPCUser != "" && config.ActiveConfig().RPCPass != "" { + login := config.ActiveConfig().RPCUser + ":" + config.ActiveConfig().RPCPass auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) rpc.authsha = sha256.Sum256([]byte(auth)) } - if config.MainConfig().RPCLimitUser != "" && config.MainConfig().RPCLimitPass != "" { - login := config.MainConfig().RPCLimitUser + ":" + config.MainConfig().RPCLimitPass + if config.ActiveConfig().RPCLimitUser != "" && config.ActiveConfig().RPCLimitPass != "" { + login := config.ActiveConfig().RPCLimitUser + ":" + config.ActiveConfig().RPCLimitPass auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) rpc.limitauthsha = sha256.Sum256([]byte(auth)) } diff --git a/server/rpc/rpcwebsocket.go b/server/rpc/rpcwebsocket.go index efe3460af..23275894b 100644 --- a/server/rpc/rpcwebsocket.go +++ b/server/rpc/rpcwebsocket.go @@ -90,9 +90,9 @@ func (s *Server) WebsocketHandler(conn *websocket.Conn, remoteAddr string, // Limit max number of websocket clients. log.Infof("New websocket client %s", remoteAddr) - if s.ntfnMgr.NumClients()+1 > config.MainConfig().RPCMaxWebsockets { + if s.ntfnMgr.NumClients()+1 > config.ActiveConfig().RPCMaxWebsockets { log.Infof("Max websocket clients exceeded [%d] - "+ - "disconnecting client %s", config.MainConfig().RPCMaxWebsockets, + "disconnecting client %s", config.ActiveConfig().RPCMaxWebsockets, remoteAddr) conn.Close() return @@ -1000,7 +1000,7 @@ out: // // RPC quirks can be enabled by the user to avoid compatibility issues // with software relying on Core's behavior. - if request.ID == nil && !(config.MainConfig().RPCQuirks && request.JSONRPC == "") { + if request.ID == nil && !(config.ActiveConfig().RPCQuirks && request.JSONRPC == "") { if !c.authenticated { break out } @@ -1361,7 +1361,7 @@ func newWebsocketClient(server *Server, conn *websocket.Conn, isAdmin: isAdmin, sessionID: sessionID, server: server, - serviceRequestSem: makeSemaphore(config.MainConfig().RPCMaxConcurrentReqs), + serviceRequestSem: makeSemaphore(config.ActiveConfig().RPCMaxConcurrentReqs), ntfnChan: make(chan []byte, 1), // nonblocking sync sendChan: make(chan wsResponse, websocketSendBufferSize), quit: make(chan struct{}), diff --git a/server/server.go b/server/server.go index f6b3e158b..3918f122b 100644 --- a/server/server.go +++ b/server/server.go @@ -40,7 +40,7 @@ func (s *Server) Start() { s.p2pServer.Start() // Start the CPU miner if generation is enabled. - cfg := config.MainConfig() + cfg := config.ActiveConfig() if cfg.Generate { s.cpuminer.Start() } @@ -68,7 +68,7 @@ func (s *Server) Stop() error { s.p2pServer.Stop() // Shutdown the RPC server if it's not disabled. - if !config.MainConfig().DisableRPC { + if !config.ActiveConfig().DisableRPC { s.rpcServer.Stop() } @@ -93,7 +93,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params return nil, err } - cfg := config.MainConfig() + cfg := config.ActiveConfig() // Create the mining policy and block template generator based on the // configuration options. diff --git a/server/serverutils/utils.go b/server/serverutils/utils.go index a0bd431d6..83fe10a80 100644 --- a/server/serverutils/utils.go +++ b/server/serverutils/utils.go @@ -45,7 +45,7 @@ func BTCDLookup(host string) ([]net.IP, error) { return nil, errors.Errorf("attempt to resolve tor address %s", host) } - return config.MainConfig().Lookup(host) + return config.ActiveConfig().Lookup(host) } // GenCertPair generates a key/cert pair to the paths provided. @@ -79,8 +79,8 @@ func GenCertPair(certFile, keyFile string) error { // could itself use a proxy or not). func BTCDDial(addr net.Addr) (net.Conn, error) { if strings.Contains(addr.String(), ".onion:") { - return config.MainConfig().OnionDial(addr.Network(), addr.String(), + return config.ActiveConfig().OnionDial(addr.Network(), addr.String(), config.DefaultConnectTimeout) } - return config.MainConfig().Dial(addr.Network(), addr.String(), config.DefaultConnectTimeout) + return config.ActiveConfig().Dial(addr.Network(), addr.String(), config.DefaultConnectTimeout) }