github.com/phillinzzz/newBsc@v1.1.6/cmd/utils/flags.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package utils contains internal helper functions for go-ethereum commands.
    18  package utils
    19  
    20  import (
    21  	"crypto/ecdsa"
    22  	"fmt"
    23  	"io"
    24  	"io/ioutil"
    25  	"math"
    26  	"math/big"
    27  	"os"
    28  	"path/filepath"
    29  	godebug "runtime/debug"
    30  	"strconv"
    31  	"strings"
    32  	"text/tabwriter"
    33  	"text/template"
    34  	"time"
    35  
    36  	"github.com/phillinzzz/newBsc/accounts"
    37  	"github.com/phillinzzz/newBsc/accounts/keystore"
    38  	"github.com/phillinzzz/newBsc/common"
    39  	"github.com/phillinzzz/newBsc/common/fdlimit"
    40  	"github.com/phillinzzz/newBsc/consensus"
    41  	"github.com/phillinzzz/newBsc/consensus/clique"
    42  	"github.com/phillinzzz/newBsc/consensus/ethash"
    43  	"github.com/phillinzzz/newBsc/core"
    44  	"github.com/phillinzzz/newBsc/core/rawdb"
    45  	"github.com/phillinzzz/newBsc/core/vm"
    46  	"github.com/phillinzzz/newBsc/crypto"
    47  	"github.com/phillinzzz/newBsc/eth"
    48  	"github.com/phillinzzz/newBsc/eth/downloader"
    49  	"github.com/phillinzzz/newBsc/eth/ethconfig"
    50  	"github.com/phillinzzz/newBsc/eth/gasprice"
    51  	"github.com/phillinzzz/newBsc/eth/tracers"
    52  	"github.com/phillinzzz/newBsc/ethdb"
    53  	"github.com/phillinzzz/newBsc/ethstats"
    54  	"github.com/phillinzzz/newBsc/graphql"
    55  	"github.com/phillinzzz/newBsc/internal/ethapi"
    56  	"github.com/phillinzzz/newBsc/internal/flags"
    57  	"github.com/phillinzzz/newBsc/les"
    58  	"github.com/phillinzzz/newBsc/log"
    59  	"github.com/phillinzzz/newBsc/metrics"
    60  	"github.com/phillinzzz/newBsc/metrics/exp"
    61  	"github.com/phillinzzz/newBsc/metrics/influxdb"
    62  	"github.com/phillinzzz/newBsc/miner"
    63  	"github.com/phillinzzz/newBsc/node"
    64  	"github.com/phillinzzz/newBsc/p2p"
    65  	"github.com/phillinzzz/newBsc/p2p/enode"
    66  	"github.com/phillinzzz/newBsc/p2p/nat"
    67  	"github.com/phillinzzz/newBsc/p2p/netutil"
    68  	"github.com/phillinzzz/newBsc/params"
    69  	pcsclite "github.com/gballet/go-libpcsclite"
    70  	gopsutil "github.com/shirou/gopsutil/mem"
    71  	"gopkg.in/urfave/cli.v1"
    72  )
    73  
    74  func init() {
    75  	cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
    76  
    77  VERSION:
    78     {{.Version}}
    79  
    80  COMMANDS:
    81     {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
    82     {{end}}{{if .Flags}}
    83  GLOBAL OPTIONS:
    84     {{range .Flags}}{{.}}
    85     {{end}}{{end}}
    86  `
    87  	cli.CommandHelpTemplate = flags.CommandHelpTemplate
    88  	cli.HelpPrinter = printHelp
    89  }
    90  
    91  func printHelp(out io.Writer, templ string, data interface{}) {
    92  	funcMap := template.FuncMap{"join": strings.Join}
    93  	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
    94  	w := tabwriter.NewWriter(out, 38, 8, 2, ' ', 0)
    95  	err := t.Execute(w, data)
    96  	if err != nil {
    97  		panic(err)
    98  	}
    99  	w.Flush()
   100  }
   101  
   102  // These are all the command line flags we support.
   103  // If you add to this list, please remember to include the
   104  // flag in the appropriate command definition.
   105  //
   106  // The flags are defined here so their names and help texts
   107  // are the same for all commands.
   108  
   109  var (
   110  	// General settings
   111  	DataDirFlag = DirectoryFlag{
   112  		Name:  "datadir",
   113  		Usage: "Data directory for the databases and keystore",
   114  		Value: DirectoryString(node.DefaultDataDir()),
   115  	}
   116  	DirectBroadcastFlag = cli.BoolFlag{
   117  		Name:  "directbroadcast",
   118  		Usage: "Enable directly broadcast mined block to all peers",
   119  	}
   120  	DisableSnapProtocolFlag = cli.BoolFlag{
   121  		Name:  "disablesnapprotocol",
   122  		Usage: "Disable snap protocol",
   123  	}
   124  	DiffSyncFlag = cli.BoolFlag{
   125  		Name: "diffsync",
   126  		Usage: "Enable diffy sync, Please note that enable diffsync will improve the syncing speed, " +
   127  			"but will degrade the security to light client level",
   128  	}
   129  	RangeLimitFlag = cli.BoolFlag{
   130  		Name:  "rangelimit",
   131  		Usage: "Enable 5000 blocks limit for range query",
   132  	}
   133  	AncientFlag = DirectoryFlag{
   134  		Name:  "datadir.ancient",
   135  		Usage: "Data directory for ancient chain segments (default = inside chaindata)",
   136  	}
   137  	DiffFlag = DirectoryFlag{
   138  		Name:  "datadir.diff",
   139  		Usage: "Data directory for difflayer segments (default = inside chaindata)",
   140  	}
   141  	MinFreeDiskSpaceFlag = DirectoryFlag{
   142  		Name:  "datadir.minfreedisk",
   143  		Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)",
   144  	}
   145  	KeyStoreDirFlag = DirectoryFlag{
   146  		Name:  "keystore",
   147  		Usage: "Directory for the keystore (default = inside the datadir)",
   148  	}
   149  	NoUSBFlag = cli.BoolFlag{
   150  		Name:  "nousb",
   151  		Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)",
   152  	}
   153  	USBFlag = cli.BoolFlag{
   154  		Name:  "usb",
   155  		Usage: "Enable monitoring and management of USB hardware wallets",
   156  	}
   157  	SmartCardDaemonPathFlag = cli.StringFlag{
   158  		Name:  "pcscdpath",
   159  		Usage: "Path to the smartcard daemon (pcscd) socket file",
   160  		Value: pcsclite.PCSCDSockName,
   161  	}
   162  	NetworkIdFlag = cli.Uint64Flag{
   163  		Name:  "networkid",
   164  		Usage: "Explicitly set network id (integer)(For testnets: use --ropsten, --rinkeby, --goerli instead)",
   165  		Value: ethconfig.Defaults.NetworkId,
   166  	}
   167  	MainnetFlag = cli.BoolFlag{
   168  		Name:  "mainnet",
   169  		Usage: "Ethereum mainnet",
   170  	}
   171  	GoerliFlag = cli.BoolFlag{
   172  		Name:  "goerli",
   173  		Usage: "Görli network: pre-configured proof-of-authority test network",
   174  	}
   175  	YoloV3Flag = cli.BoolFlag{
   176  		Name:  "yolov3",
   177  		Usage: "YOLOv3 network: pre-configured proof-of-authority shortlived test network.",
   178  	}
   179  	RinkebyFlag = cli.BoolFlag{
   180  		Name:  "rinkeby",
   181  		Usage: "Rinkeby network: pre-configured proof-of-authority test network",
   182  	}
   183  	RopstenFlag = cli.BoolFlag{
   184  		Name:  "ropsten",
   185  		Usage: "Ropsten network: pre-configured proof-of-work test network",
   186  	}
   187  	DeveloperFlag = cli.BoolFlag{
   188  		Name:  "dev",
   189  		Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
   190  	}
   191  	DeveloperPeriodFlag = cli.IntFlag{
   192  		Name:  "dev.period",
   193  		Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
   194  	}
   195  	IdentityFlag = cli.StringFlag{
   196  		Name:  "identity",
   197  		Usage: "Custom node name",
   198  	}
   199  	DocRootFlag = DirectoryFlag{
   200  		Name:  "docroot",
   201  		Usage: "Document Root for HTTPClient file scheme",
   202  		Value: DirectoryString(HomeDir()),
   203  	}
   204  	ExitWhenSyncedFlag = cli.BoolFlag{
   205  		Name:  "exitwhensynced",
   206  		Usage: "Exits after block synchronisation completes",
   207  	}
   208  	IterativeOutputFlag = cli.BoolFlag{
   209  		Name:  "iterative",
   210  		Usage: "Print streaming JSON iteratively, delimited by newlines",
   211  	}
   212  	ExcludeStorageFlag = cli.BoolFlag{
   213  		Name:  "nostorage",
   214  		Usage: "Exclude storage entries (save db lookups)",
   215  	}
   216  	IncludeIncompletesFlag = cli.BoolFlag{
   217  		Name:  "incompletes",
   218  		Usage: "Include accounts for which we don't have the address (missing preimage)",
   219  	}
   220  	ExcludeCodeFlag = cli.BoolFlag{
   221  		Name:  "nocode",
   222  		Usage: "Exclude contract code (save db lookups)",
   223  	}
   224  	defaultSyncMode = ethconfig.Defaults.SyncMode
   225  	SyncModeFlag    = TextMarshalerFlag{
   226  		Name:  "syncmode",
   227  		Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`,
   228  		Value: &defaultSyncMode,
   229  	}
   230  	GCModeFlag = cli.StringFlag{
   231  		Name:  "gcmode",
   232  		Usage: `Blockchain garbage collection mode ("full", "archive")`,
   233  		Value: "full",
   234  	}
   235  	SnapshotFlag = cli.BoolTFlag{
   236  		Name:  "snapshot",
   237  		Usage: `Enables snapshot-database mode (default = enable)`,
   238  	}
   239  	TxLookupLimitFlag = cli.Uint64Flag{
   240  		Name:  "txlookuplimit",
   241  		Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)",
   242  		Value: ethconfig.Defaults.TxLookupLimit,
   243  	}
   244  	LightKDFFlag = cli.BoolFlag{
   245  		Name:  "lightkdf",
   246  		Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength",
   247  	}
   248  	WhitelistFlag = cli.StringFlag{
   249  		Name:  "whitelist",
   250  		Usage: "Comma separated block number-to-hash mappings to enforce (<number>=<hash>)",
   251  	}
   252  	BloomFilterSizeFlag = cli.Uint64Flag{
   253  		Name:  "bloomfilter.size",
   254  		Usage: "Megabytes of memory allocated to bloom-filter for pruning",
   255  		Value: 2048,
   256  	}
   257  	TriesInMemoryFlag = cli.Uint64Flag{
   258  		Name:  "triesInMemory",
   259  		Usage: "The layer of tries trees that keep in memory",
   260  		Value: 128,
   261  	}
   262  	OverrideBerlinFlag = cli.Uint64Flag{
   263  		Name:  "override.berlin",
   264  		Usage: "Manually specify Berlin fork-block, overriding the bundled setting",
   265  	}
   266  	// Light server and client settings
   267  	LightServeFlag = cli.IntFlag{
   268  		Name:  "light.serve",
   269  		Usage: "Maximum percentage of time allowed for serving LES requests (multi-threaded processing allows values over 100)",
   270  		Value: ethconfig.Defaults.LightServ,
   271  	}
   272  	LightIngressFlag = cli.IntFlag{
   273  		Name:  "light.ingress",
   274  		Usage: "Incoming bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)",
   275  		Value: ethconfig.Defaults.LightIngress,
   276  	}
   277  	LightEgressFlag = cli.IntFlag{
   278  		Name:  "light.egress",
   279  		Usage: "Outgoing bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)",
   280  		Value: ethconfig.Defaults.LightEgress,
   281  	}
   282  	LightMaxPeersFlag = cli.IntFlag{
   283  		Name:  "light.maxpeers",
   284  		Usage: "Maximum number of light clients to serve, or light servers to attach to",
   285  		Value: ethconfig.Defaults.LightPeers,
   286  	}
   287  	UltraLightServersFlag = cli.StringFlag{
   288  		Name:  "ulc.servers",
   289  		Usage: "List of trusted ultra-light servers",
   290  		Value: strings.Join(ethconfig.Defaults.UltraLightServers, ","),
   291  	}
   292  	UltraLightFractionFlag = cli.IntFlag{
   293  		Name:  "ulc.fraction",
   294  		Usage: "Minimum % of trusted ultra-light servers required to announce a new head",
   295  		Value: ethconfig.Defaults.UltraLightFraction,
   296  	}
   297  	UltraLightOnlyAnnounceFlag = cli.BoolFlag{
   298  		Name:  "ulc.onlyannounce",
   299  		Usage: "Ultra light server sends announcements only",
   300  	}
   301  	LightNoPruneFlag = cli.BoolFlag{
   302  		Name:  "light.nopruning",
   303  		Usage: "Disable ancient light chain data pruning",
   304  	}
   305  	LightNoSyncServeFlag = cli.BoolFlag{
   306  		Name:  "light.nosyncserve",
   307  		Usage: "Enables serving light clients before syncing",
   308  	}
   309  	// Ethash settings
   310  	EthashCacheDirFlag = DirectoryFlag{
   311  		Name:  "ethash.cachedir",
   312  		Usage: "Directory to store the ethash verification caches (default = inside the datadir)",
   313  	}
   314  	EthashCachesInMemoryFlag = cli.IntFlag{
   315  		Name:  "ethash.cachesinmem",
   316  		Usage: "Number of recent ethash caches to keep in memory (16MB each)",
   317  		Value: ethconfig.Defaults.Ethash.CachesInMem,
   318  	}
   319  	EthashCachesOnDiskFlag = cli.IntFlag{
   320  		Name:  "ethash.cachesondisk",
   321  		Usage: "Number of recent ethash caches to keep on disk (16MB each)",
   322  		Value: ethconfig.Defaults.Ethash.CachesOnDisk,
   323  	}
   324  	EthashCachesLockMmapFlag = cli.BoolFlag{
   325  		Name:  "ethash.cacheslockmmap",
   326  		Usage: "Lock memory maps of recent ethash caches",
   327  	}
   328  	EthashDatasetDirFlag = DirectoryFlag{
   329  		Name:  "ethash.dagdir",
   330  		Usage: "Directory to store the ethash mining DAGs",
   331  		Value: DirectoryString(ethconfig.Defaults.Ethash.DatasetDir),
   332  	}
   333  	EthashDatasetsInMemoryFlag = cli.IntFlag{
   334  		Name:  "ethash.dagsinmem",
   335  		Usage: "Number of recent ethash mining DAGs to keep in memory (1+GB each)",
   336  		Value: ethconfig.Defaults.Ethash.DatasetsInMem,
   337  	}
   338  	EthashDatasetsOnDiskFlag = cli.IntFlag{
   339  		Name:  "ethash.dagsondisk",
   340  		Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)",
   341  		Value: ethconfig.Defaults.Ethash.DatasetsOnDisk,
   342  	}
   343  	EthashDatasetsLockMmapFlag = cli.BoolFlag{
   344  		Name:  "ethash.dagslockmmap",
   345  		Usage: "Lock memory maps for recent ethash mining DAGs",
   346  	}
   347  	// Transaction pool settings
   348  	TxPoolLocalsFlag = cli.StringFlag{
   349  		Name:  "txpool.locals",
   350  		Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)",
   351  	}
   352  	TxPoolNoLocalsFlag = cli.BoolFlag{
   353  		Name:  "txpool.nolocals",
   354  		Usage: "Disables price exemptions for locally submitted transactions",
   355  	}
   356  	TxPoolJournalFlag = cli.StringFlag{
   357  		Name:  "txpool.journal",
   358  		Usage: "Disk journal for local transaction to survive node restarts",
   359  		Value: core.DefaultTxPoolConfig.Journal,
   360  	}
   361  	TxPoolRejournalFlag = cli.DurationFlag{
   362  		Name:  "txpool.rejournal",
   363  		Usage: "Time interval to regenerate the local transaction journal",
   364  		Value: core.DefaultTxPoolConfig.Rejournal,
   365  	}
   366  	TxPoolPriceLimitFlag = cli.Uint64Flag{
   367  		Name:  "txpool.pricelimit",
   368  		Usage: "Minimum gas price limit to enforce for acceptance into the pool",
   369  		Value: ethconfig.Defaults.TxPool.PriceLimit,
   370  	}
   371  	TxPoolPriceBumpFlag = cli.Uint64Flag{
   372  		Name:  "txpool.pricebump",
   373  		Usage: "Price bump percentage to replace an already existing transaction",
   374  		Value: ethconfig.Defaults.TxPool.PriceBump,
   375  	}
   376  	TxPoolAccountSlotsFlag = cli.Uint64Flag{
   377  		Name:  "txpool.accountslots",
   378  		Usage: "Minimum number of executable transaction slots guaranteed per account",
   379  		Value: ethconfig.Defaults.TxPool.AccountSlots,
   380  	}
   381  	TxPoolGlobalSlotsFlag = cli.Uint64Flag{
   382  		Name:  "txpool.globalslots",
   383  		Usage: "Maximum number of executable transaction slots for all accounts",
   384  		Value: ethconfig.Defaults.TxPool.GlobalSlots,
   385  	}
   386  	TxPoolAccountQueueFlag = cli.Uint64Flag{
   387  		Name:  "txpool.accountqueue",
   388  		Usage: "Maximum number of non-executable transaction slots permitted per account",
   389  		Value: ethconfig.Defaults.TxPool.AccountQueue,
   390  	}
   391  	TxPoolGlobalQueueFlag = cli.Uint64Flag{
   392  		Name:  "txpool.globalqueue",
   393  		Usage: "Maximum number of non-executable transaction slots for all accounts",
   394  		Value: ethconfig.Defaults.TxPool.GlobalQueue,
   395  	}
   396  	TxPoolLifetimeFlag = cli.DurationFlag{
   397  		Name:  "txpool.lifetime",
   398  		Usage: "Maximum amount of time non-executable transaction are queued",
   399  		Value: ethconfig.Defaults.TxPool.Lifetime,
   400  	}
   401  	// Performance tuning settings
   402  	CacheFlag = cli.IntFlag{
   403  		Name:  "cache",
   404  		Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node, 128 light mode)",
   405  		Value: 1024,
   406  	}
   407  	CacheDatabaseFlag = cli.IntFlag{
   408  		Name:  "cache.database",
   409  		Usage: "Percentage of cache memory allowance to use for database io",
   410  		Value: 40,
   411  	}
   412  	CacheTrieFlag = cli.IntFlag{
   413  		Name:  "cache.trie",
   414  		Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)",
   415  		Value: 15,
   416  	}
   417  	CacheTrieJournalFlag = cli.StringFlag{
   418  		Name:  "cache.trie.journal",
   419  		Usage: "Disk journal directory for trie cache to survive node restarts",
   420  		Value: ethconfig.Defaults.TrieCleanCacheJournal,
   421  	}
   422  	CacheTrieRejournalFlag = cli.DurationFlag{
   423  		Name:  "cache.trie.rejournal",
   424  		Usage: "Time interval to regenerate the trie cache journal",
   425  		Value: ethconfig.Defaults.TrieCleanCacheRejournal,
   426  	}
   427  	CacheGCFlag = cli.IntFlag{
   428  		Name:  "cache.gc",
   429  		Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)",
   430  		Value: 25,
   431  	}
   432  	CacheSnapshotFlag = cli.IntFlag{
   433  		Name:  "cache.snapshot",
   434  		Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 20%)",
   435  		Value: 20,
   436  	}
   437  	CachePreimagesFlag = cli.BoolFlag{
   438  		Name:  "cache.preimages",
   439  		Usage: "Enable recording the SHA3/keccak preimages of trie keys",
   440  	}
   441  	PersistDiffFlag = cli.BoolFlag{
   442  		Name:  "persistdiff",
   443  		Usage: "Enable persistence of the diff layer",
   444  	}
   445  	DiffBlockFlag = cli.Uint64Flag{
   446  		Name:  "diffblock",
   447  		Usage: "The number of blocks should be persisted in db (default = 864000 )",
   448  		Value: uint64(864000),
   449  	}
   450  	// Miner settings
   451  	MiningEnabledFlag = cli.BoolFlag{
   452  		Name:  "mine",
   453  		Usage: "Enable mining",
   454  	}
   455  	MinerThreadsFlag = cli.IntFlag{
   456  		Name:  "miner.threads",
   457  		Usage: "Number of CPU threads to use for mining",
   458  		Value: 0,
   459  	}
   460  	MinerNotifyFlag = cli.StringFlag{
   461  		Name:  "miner.notify",
   462  		Usage: "Comma separated HTTP URL list to notify of new work packages",
   463  	}
   464  	MinerNotifyFullFlag = cli.BoolFlag{
   465  		Name:  "miner.notify.full",
   466  		Usage: "Notify with pending block headers instead of work packages",
   467  	}
   468  	MinerGasTargetFlag = cli.Uint64Flag{
   469  		Name:  "miner.gastarget",
   470  		Usage: "Target gas floor for mined blocks",
   471  		Value: ethconfig.Defaults.Miner.GasFloor,
   472  	}
   473  	MinerGasLimitFlag = cli.Uint64Flag{
   474  		Name:  "miner.gaslimit",
   475  		Usage: "Target gas ceiling for mined blocks",
   476  		Value: ethconfig.Defaults.Miner.GasCeil,
   477  	}
   478  	MinerGasPriceFlag = BigFlag{
   479  		Name:  "miner.gasprice",
   480  		Usage: "Minimum gas price for mining a transaction",
   481  		Value: ethconfig.Defaults.Miner.GasPrice,
   482  	}
   483  	MinerEtherbaseFlag = cli.StringFlag{
   484  		Name:  "miner.etherbase",
   485  		Usage: "Public address for block mining rewards (default = first account)",
   486  		Value: "0",
   487  	}
   488  	MinerExtraDataFlag = cli.StringFlag{
   489  		Name:  "miner.extradata",
   490  		Usage: "Block extra data set by the miner (default = client version)",
   491  	}
   492  	MinerRecommitIntervalFlag = cli.DurationFlag{
   493  		Name:  "miner.recommit",
   494  		Usage: "Time interval to recreate the block being mined",
   495  		Value: ethconfig.Defaults.Miner.Recommit,
   496  	}
   497  	MinerDelayLeftoverFlag = cli.DurationFlag{
   498  		Name:  "miner.delayleftover",
   499  		Usage: "Time interval to for broadcast block",
   500  		Value: ethconfig.Defaults.Miner.DelayLeftOver,
   501  	}
   502  	MinerNoVerfiyFlag = cli.BoolFlag{
   503  		Name:  "miner.noverify",
   504  		Usage: "Disable remote sealing verification",
   505  	}
   506  	// Account settings
   507  	UnlockedAccountFlag = cli.StringFlag{
   508  
   509  		Name:  "unlock",
   510  		Usage: "Comma separated list of accounts to unlock",
   511  		Value: "",
   512  	}
   513  	PasswordFileFlag = cli.StringFlag{
   514  		Name:  "password",
   515  		Usage: "Password file to use for non-interactive password input",
   516  		Value: "",
   517  	}
   518  	ExternalSignerFlag = cli.StringFlag{
   519  		Name:  "signer",
   520  		Usage: "External signer (url or path to ipc file)",
   521  		Value: "",
   522  	}
   523  	VMEnableDebugFlag = cli.BoolFlag{
   524  		Name:  "vmdebug",
   525  		Usage: "Record information useful for VM and contract debugging",
   526  	}
   527  	InsecureUnlockAllowedFlag = cli.BoolFlag{
   528  		Name:  "allow-insecure-unlock",
   529  		Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http",
   530  	}
   531  	RPCGlobalGasCapFlag = cli.Uint64Flag{
   532  		Name:  "rpc.gascap",
   533  		Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)",
   534  		Value: ethconfig.Defaults.RPCGasCap,
   535  	}
   536  	RPCGlobalTxFeeCapFlag = cli.Float64Flag{
   537  		Name:  "rpc.txfeecap",
   538  		Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)",
   539  		Value: ethconfig.Defaults.RPCTxFeeCap,
   540  	}
   541  	// Logging and debug settings
   542  	EthStatsURLFlag = cli.StringFlag{
   543  		Name:  "ethstats",
   544  		Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)",
   545  	}
   546  	FakePoWFlag = cli.BoolFlag{
   547  		Name:  "fakepow",
   548  		Usage: "Disables proof-of-work verification",
   549  	}
   550  	NoCompactionFlag = cli.BoolFlag{
   551  		Name:  "nocompaction",
   552  		Usage: "Disables db compaction after import",
   553  	}
   554  	// RPC settings
   555  	IPCDisabledFlag = cli.BoolFlag{
   556  		Name:  "ipcdisable",
   557  		Usage: "Disable the IPC-RPC server",
   558  	}
   559  	IPCPathFlag = DirectoryFlag{
   560  		Name:  "ipcpath",
   561  		Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)",
   562  	}
   563  	HTTPEnabledFlag = cli.BoolFlag{
   564  		Name:  "http",
   565  		Usage: "Enable the HTTP-RPC server",
   566  	}
   567  	HTTPListenAddrFlag = cli.StringFlag{
   568  		Name:  "http.addr",
   569  		Usage: "HTTP-RPC server listening interface",
   570  		Value: node.DefaultHTTPHost,
   571  	}
   572  	HTTPPortFlag = cli.IntFlag{
   573  		Name:  "http.port",
   574  		Usage: "HTTP-RPC server listening port",
   575  		Value: node.DefaultHTTPPort,
   576  	}
   577  	HTTPCORSDomainFlag = cli.StringFlag{
   578  		Name:  "http.corsdomain",
   579  		Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
   580  		Value: "",
   581  	}
   582  	HTTPVirtualHostsFlag = cli.StringFlag{
   583  		Name:  "http.vhosts",
   584  		Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
   585  		Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
   586  	}
   587  	HTTPApiFlag = cli.StringFlag{
   588  		Name:  "http.api",
   589  		Usage: "API's offered over the HTTP-RPC interface",
   590  		Value: "",
   591  	}
   592  	HTTPPathPrefixFlag = cli.StringFlag{
   593  		Name:  "http.rpcprefix",
   594  		Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.",
   595  		Value: "",
   596  	}
   597  	GraphQLEnabledFlag = cli.BoolFlag{
   598  		Name:  "graphql",
   599  		Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.",
   600  	}
   601  	GraphQLCORSDomainFlag = cli.StringFlag{
   602  		Name:  "graphql.corsdomain",
   603  		Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
   604  		Value: "",
   605  	}
   606  	GraphQLVirtualHostsFlag = cli.StringFlag{
   607  		Name:  "graphql.vhosts",
   608  		Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
   609  		Value: strings.Join(node.DefaultConfig.GraphQLVirtualHosts, ","),
   610  	}
   611  	WSEnabledFlag = cli.BoolFlag{
   612  		Name:  "ws",
   613  		Usage: "Enable the WS-RPC server",
   614  	}
   615  	WSListenAddrFlag = cli.StringFlag{
   616  		Name:  "ws.addr",
   617  		Usage: "WS-RPC server listening interface",
   618  		Value: node.DefaultWSHost,
   619  	}
   620  	WSPortFlag = cli.IntFlag{
   621  		Name:  "ws.port",
   622  		Usage: "WS-RPC server listening port",
   623  		Value: node.DefaultWSPort,
   624  	}
   625  	WSApiFlag = cli.StringFlag{
   626  		Name:  "ws.api",
   627  		Usage: "API's offered over the WS-RPC interface",
   628  		Value: "",
   629  	}
   630  	WSAllowedOriginsFlag = cli.StringFlag{
   631  		Name:  "ws.origins",
   632  		Usage: "Origins from which to accept websockets requests",
   633  		Value: "",
   634  	}
   635  	WSPathPrefixFlag = cli.StringFlag{
   636  		Name:  "ws.rpcprefix",
   637  		Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.",
   638  		Value: "",
   639  	}
   640  	ExecFlag = cli.StringFlag{
   641  		Name:  "exec",
   642  		Usage: "Execute JavaScript statement",
   643  	}
   644  	PreloadJSFlag = cli.StringFlag{
   645  		Name:  "preload",
   646  		Usage: "Comma separated list of JavaScript files to preload into the console",
   647  	}
   648  	AllowUnprotectedTxs = cli.BoolFlag{
   649  		Name:  "rpc.allow-unprotected-txs",
   650  		Usage: "Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC",
   651  	}
   652  
   653  	// Network Settings
   654  	MaxPeersFlag = cli.IntFlag{
   655  		Name:  "maxpeers",
   656  		Usage: "Maximum number of network peers (network disabled if set to 0)",
   657  		Value: node.DefaultConfig.P2P.MaxPeers,
   658  	}
   659  	MaxPendingPeersFlag = cli.IntFlag{
   660  		Name:  "maxpendpeers",
   661  		Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
   662  		Value: node.DefaultConfig.P2P.MaxPendingPeers,
   663  	}
   664  	ListenPortFlag = cli.IntFlag{
   665  		Name:  "port",
   666  		Usage: "Network listening port",
   667  		Value: 30303,
   668  	}
   669  	BootnodesFlag = cli.StringFlag{
   670  		Name:  "bootnodes",
   671  		Usage: "Comma separated enode URLs for P2P discovery bootstrap",
   672  		Value: "",
   673  	}
   674  	NodeKeyFileFlag = cli.StringFlag{
   675  		Name:  "nodekey",
   676  		Usage: "P2P node key file",
   677  	}
   678  	NodeKeyHexFlag = cli.StringFlag{
   679  		Name:  "nodekeyhex",
   680  		Usage: "P2P node key as hex (for testing)",
   681  	}
   682  	NATFlag = cli.StringFlag{
   683  		Name:  "nat",
   684  		Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
   685  		Value: "any",
   686  	}
   687  	NoDiscoverFlag = cli.BoolFlag{
   688  		Name:  "nodiscover",
   689  		Usage: "Disables the peer discovery mechanism (manual peer addition)",
   690  	}
   691  	DiscoveryV5Flag = cli.BoolFlag{
   692  		Name:  "v5disc",
   693  		Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
   694  	}
   695  	NetrestrictFlag = cli.StringFlag{
   696  		Name:  "netrestrict",
   697  		Usage: "Restricts network communication to the given IP networks (CIDR masks)",
   698  	}
   699  	DNSDiscoveryFlag = cli.StringFlag{
   700  		Name:  "discovery.dns",
   701  		Usage: "Sets DNS discovery entry points (use \"\" to disable DNS)",
   702  	}
   703  
   704  	// ATM the url is left to the user and deployment to
   705  	JSpathFlag = cli.StringFlag{
   706  		Name:  "jspath",
   707  		Usage: "JavaScript root path for `loadScript`",
   708  		Value: ".",
   709  	}
   710  
   711  	// Gas price oracle settings
   712  	GpoBlocksFlag = cli.IntFlag{
   713  		Name:  "gpo.blocks",
   714  		Usage: "Number of recent blocks to check for gas prices",
   715  		Value: ethconfig.Defaults.GPO.Blocks,
   716  	}
   717  	GpoPercentileFlag = cli.IntFlag{
   718  		Name:  "gpo.percentile",
   719  		Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
   720  		Value: ethconfig.Defaults.GPO.Percentile,
   721  	}
   722  	GpoMaxGasPriceFlag = cli.Int64Flag{
   723  		Name:  "gpo.maxprice",
   724  		Usage: "Maximum gas price will be recommended by gpo",
   725  		Value: ethconfig.Defaults.GPO.MaxPrice.Int64(),
   726  	}
   727  
   728  	// Metrics flags
   729  	MetricsEnabledFlag = cli.BoolFlag{
   730  		Name:  "metrics",
   731  		Usage: "Enable metrics collection and reporting",
   732  	}
   733  	MetricsEnabledExpensiveFlag = cli.BoolFlag{
   734  		Name:  "metrics.expensive",
   735  		Usage: "Enable expensive metrics collection and reporting",
   736  	}
   737  
   738  	// MetricsHTTPFlag defines the endpoint for a stand-alone metrics HTTP endpoint.
   739  	// Since the pprof service enables sensitive/vulnerable behavior, this allows a user
   740  	// to enable a public-OK metrics endpoint without having to worry about ALSO exposing
   741  	// other profiling behavior or information.
   742  	MetricsHTTPFlag = cli.StringFlag{
   743  		Name:  "metrics.addr",
   744  		Usage: "Enable stand-alone metrics HTTP server listening interface",
   745  		Value: metrics.DefaultConfig.HTTP,
   746  	}
   747  	MetricsPortFlag = cli.IntFlag{
   748  		Name:  "metrics.port",
   749  		Usage: "Metrics HTTP server listening port",
   750  		Value: metrics.DefaultConfig.Port,
   751  	}
   752  	MetricsEnableInfluxDBFlag = cli.BoolFlag{
   753  		Name:  "metrics.influxdb",
   754  		Usage: "Enable metrics export/push to an external InfluxDB database",
   755  	}
   756  	MetricsInfluxDBEndpointFlag = cli.StringFlag{
   757  		Name:  "metrics.influxdb.endpoint",
   758  		Usage: "InfluxDB API endpoint to report metrics to",
   759  		Value: metrics.DefaultConfig.InfluxDBEndpoint,
   760  	}
   761  	MetricsInfluxDBDatabaseFlag = cli.StringFlag{
   762  		Name:  "metrics.influxdb.database",
   763  		Usage: "InfluxDB database name to push reported metrics to",
   764  		Value: metrics.DefaultConfig.InfluxDBDatabase,
   765  	}
   766  	MetricsInfluxDBUsernameFlag = cli.StringFlag{
   767  		Name:  "metrics.influxdb.username",
   768  		Usage: "Username to authorize access to the database",
   769  		Value: metrics.DefaultConfig.InfluxDBUsername,
   770  	}
   771  	MetricsInfluxDBPasswordFlag = cli.StringFlag{
   772  		Name:  "metrics.influxdb.password",
   773  		Usage: "Password to authorize access to the database",
   774  		Value: metrics.DefaultConfig.InfluxDBPassword,
   775  	}
   776  	// Tags are part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB.
   777  	// For example `host` tag could be used so that we can group all nodes and average a measurement
   778  	// across all of them, but also so that we can select a specific node and inspect its measurements.
   779  	// https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key
   780  	MetricsInfluxDBTagsFlag = cli.StringFlag{
   781  		Name:  "metrics.influxdb.tags",
   782  		Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
   783  		Value: metrics.DefaultConfig.InfluxDBTags,
   784  	}
   785  	EWASMInterpreterFlag = cli.StringFlag{
   786  		Name:  "vm.ewasm",
   787  		Usage: "External ewasm configuration (default = built-in interpreter)",
   788  		Value: "",
   789  	}
   790  	EVMInterpreterFlag = cli.StringFlag{
   791  		Name:  "vm.evm",
   792  		Usage: "External EVM configuration (default = built-in interpreter)",
   793  		Value: "",
   794  	}
   795  
   796  	// Init network
   797  	InitNetworkSize = cli.IntFlag{
   798  		Name:  "init.size",
   799  		Usage: "the size of the network",
   800  		Value: 1,
   801  	}
   802  
   803  	InitNetworkDir = cli.StringFlag{
   804  		Name:  "init.dir",
   805  		Usage: "the direction to store initial network data",
   806  		Value: "",
   807  	}
   808  
   809  	InitNetworkIps = cli.StringFlag{
   810  		Name:  "init.ips",
   811  		Usage: "the ips of each node in the network, example '192.168.0.1,192.168.0.2'",
   812  		Value: "",
   813  	}
   814  
   815  	InitNetworkPort = cli.IntFlag{
   816  		Name:  "init.p2p-port",
   817  		Usage: "the p2p port of the nodes in the network",
   818  		Value: 30311,
   819  	}
   820  
   821  	CatalystFlag = cli.BoolFlag{
   822  		Name:  "catalyst",
   823  		Usage: "Catalyst mode (eth2 integration testing)",
   824  	}
   825  )
   826  
   827  // MakeDataDir retrieves the currently requested data directory, terminating
   828  // if none (or the empty string) is specified. If the node is starting a testnet,
   829  // then a subdirectory of the specified datadir will be used.
   830  func MakeDataDir(ctx *cli.Context) string {
   831  	if path := ctx.GlobalString(DataDirFlag.Name); path != "" {
   832  		if ctx.GlobalBool(RopstenFlag.Name) {
   833  			// Maintain compatibility with older Geth configurations storing the
   834  			// Ropsten database in `testnet` instead of `ropsten`.
   835  			return filepath.Join(path, "ropsten")
   836  		}
   837  		if ctx.GlobalBool(RinkebyFlag.Name) {
   838  			return filepath.Join(path, "rinkeby")
   839  		}
   840  		if ctx.GlobalBool(GoerliFlag.Name) {
   841  			return filepath.Join(path, "goerli")
   842  		}
   843  		if ctx.GlobalBool(YoloV3Flag.Name) {
   844  			return filepath.Join(path, "yolo-v3")
   845  		}
   846  		return path
   847  	}
   848  	Fatalf("Cannot determine default data directory, please set manually (--datadir)")
   849  	return ""
   850  }
   851  
   852  // setNodeKey creates a node key from set command line flags, either loading it
   853  // from a file or as a specified hex value. If neither flags were provided, this
   854  // method returns nil and an emphemeral key is to be generated.
   855  func setNodeKey(ctx *cli.Context, cfg *p2p.Config) {
   856  	var (
   857  		hex  = ctx.GlobalString(NodeKeyHexFlag.Name)
   858  		file = ctx.GlobalString(NodeKeyFileFlag.Name)
   859  		key  *ecdsa.PrivateKey
   860  		err  error
   861  	)
   862  	switch {
   863  	case file != "" && hex != "":
   864  		Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
   865  	case file != "":
   866  		if key, err = crypto.LoadECDSA(file); err != nil {
   867  			Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
   868  		}
   869  		cfg.PrivateKey = key
   870  	case hex != "":
   871  		if key, err = crypto.HexToECDSA(hex); err != nil {
   872  			Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
   873  		}
   874  		cfg.PrivateKey = key
   875  	}
   876  }
   877  
   878  // setNodeUserIdent creates the user identifier from CLI flags.
   879  func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
   880  	if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 {
   881  		cfg.UserIdent = identity
   882  	}
   883  }
   884  
   885  // setBootstrapNodes creates a list of bootstrap nodes from the command line
   886  // flags, reverting to pre-configured ones if none have been specified.
   887  func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
   888  	urls := params.MainnetBootnodes
   889  	switch {
   890  	case ctx.GlobalIsSet(BootnodesFlag.Name):
   891  		urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
   892  	case ctx.GlobalBool(RopstenFlag.Name):
   893  		urls = params.RopstenBootnodes
   894  	case ctx.GlobalBool(RinkebyFlag.Name):
   895  		urls = params.RinkebyBootnodes
   896  	case ctx.GlobalBool(GoerliFlag.Name):
   897  		urls = params.GoerliBootnodes
   898  	case ctx.GlobalBool(YoloV3Flag.Name):
   899  		urls = params.YoloV3Bootnodes
   900  	case cfg.BootstrapNodes != nil:
   901  		return // already set, don't apply defaults.
   902  	}
   903  
   904  	cfg.BootstrapNodes = make([]*enode.Node, 0, len(urls))
   905  	for _, url := range urls {
   906  		if url != "" {
   907  			node, err := enode.Parse(enode.ValidSchemes, url)
   908  			if err != nil {
   909  				log.Crit("Bootstrap URL invalid", "enode", url, "err", err)
   910  				continue
   911  			}
   912  			cfg.BootstrapNodes = append(cfg.BootstrapNodes, node)
   913  		}
   914  	}
   915  }
   916  
   917  // setBootstrapNodesV5 creates a list of bootstrap nodes from the command line
   918  // flags, reverting to pre-configured ones if none have been specified.
   919  func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
   920  	urls := params.V5Bootnodes
   921  	switch {
   922  	case ctx.GlobalIsSet(BootnodesFlag.Name):
   923  		urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
   924  	case cfg.BootstrapNodesV5 != nil:
   925  		return // already set, don't apply defaults.
   926  	}
   927  
   928  	cfg.BootstrapNodesV5 = make([]*enode.Node, 0, len(urls))
   929  	for _, url := range urls {
   930  		if url != "" {
   931  			node, err := enode.Parse(enode.ValidSchemes, url)
   932  			if err != nil {
   933  				log.Error("Bootstrap URL invalid", "enode", url, "err", err)
   934  				continue
   935  			}
   936  			cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node)
   937  		}
   938  	}
   939  }
   940  
   941  // setListenAddress creates a TCP listening address string from set command
   942  // line flags.
   943  func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
   944  	if ctx.GlobalIsSet(ListenPortFlag.Name) {
   945  		cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name))
   946  	}
   947  }
   948  
   949  // setNAT creates a port mapper from command line flags.
   950  func setNAT(ctx *cli.Context, cfg *p2p.Config) {
   951  	if ctx.GlobalIsSet(NATFlag.Name) {
   952  		natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
   953  		if err != nil {
   954  			Fatalf("Option %s: %v", NATFlag.Name, err)
   955  		}
   956  		cfg.NAT = natif
   957  	}
   958  }
   959  
   960  // SplitAndTrim splits input separated by a comma
   961  // and trims excessive white space from the substrings.
   962  func SplitAndTrim(input string) (ret []string) {
   963  	l := strings.Split(input, ",")
   964  	for _, r := range l {
   965  		if r = strings.TrimSpace(r); r != "" {
   966  			ret = append(ret, r)
   967  		}
   968  	}
   969  	return ret
   970  }
   971  
   972  // setHTTP creates the HTTP RPC listener interface string from the set
   973  // command line flags, returning empty if the HTTP endpoint is disabled.
   974  func setHTTP(ctx *cli.Context, cfg *node.Config) {
   975  	if ctx.GlobalBool(LegacyRPCEnabledFlag.Name) && cfg.HTTPHost == "" {
   976  		log.Warn("The flag --rpc is deprecated and will be removed June 2021, please use --http")
   977  		cfg.HTTPHost = "127.0.0.1"
   978  		if ctx.GlobalIsSet(LegacyRPCListenAddrFlag.Name) {
   979  			cfg.HTTPHost = ctx.GlobalString(LegacyRPCListenAddrFlag.Name)
   980  			log.Warn("The flag --rpcaddr is deprecated and will be removed June 2021, please use --http.addr")
   981  		}
   982  	}
   983  	if ctx.GlobalBool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" {
   984  		cfg.HTTPHost = "127.0.0.1"
   985  		if ctx.GlobalIsSet(HTTPListenAddrFlag.Name) {
   986  			cfg.HTTPHost = ctx.GlobalString(HTTPListenAddrFlag.Name)
   987  		}
   988  	}
   989  
   990  	if ctx.GlobalIsSet(LegacyRPCPortFlag.Name) {
   991  		cfg.HTTPPort = ctx.GlobalInt(LegacyRPCPortFlag.Name)
   992  		log.Warn("The flag --rpcport is deprecated and will be removed June 2021, please use --http.port")
   993  	}
   994  	if ctx.GlobalIsSet(HTTPPortFlag.Name) {
   995  		cfg.HTTPPort = ctx.GlobalInt(HTTPPortFlag.Name)
   996  	}
   997  
   998  	if ctx.GlobalIsSet(LegacyRPCCORSDomainFlag.Name) {
   999  		cfg.HTTPCors = SplitAndTrim(ctx.GlobalString(LegacyRPCCORSDomainFlag.Name))
  1000  		log.Warn("The flag --rpccorsdomain is deprecated and will be removed June 2021, please use --http.corsdomain")
  1001  	}
  1002  	if ctx.GlobalIsSet(HTTPCORSDomainFlag.Name) {
  1003  		cfg.HTTPCors = SplitAndTrim(ctx.GlobalString(HTTPCORSDomainFlag.Name))
  1004  	}
  1005  
  1006  	if ctx.GlobalIsSet(LegacyRPCApiFlag.Name) {
  1007  		cfg.HTTPModules = SplitAndTrim(ctx.GlobalString(LegacyRPCApiFlag.Name))
  1008  		log.Warn("The flag --rpcapi is deprecated and will be removed June 2021, please use --http.api")
  1009  	}
  1010  	if ctx.GlobalIsSet(HTTPApiFlag.Name) {
  1011  		cfg.HTTPModules = SplitAndTrim(ctx.GlobalString(HTTPApiFlag.Name))
  1012  	}
  1013  
  1014  	if ctx.GlobalIsSet(LegacyRPCVirtualHostsFlag.Name) {
  1015  		cfg.HTTPVirtualHosts = SplitAndTrim(ctx.GlobalString(LegacyRPCVirtualHostsFlag.Name))
  1016  		log.Warn("The flag --rpcvhosts is deprecated and will be removed June 2021, please use --http.vhosts")
  1017  	}
  1018  	if ctx.GlobalIsSet(HTTPVirtualHostsFlag.Name) {
  1019  		cfg.HTTPVirtualHosts = SplitAndTrim(ctx.GlobalString(HTTPVirtualHostsFlag.Name))
  1020  	}
  1021  
  1022  	if ctx.GlobalIsSet(HTTPPathPrefixFlag.Name) {
  1023  		cfg.HTTPPathPrefix = ctx.GlobalString(HTTPPathPrefixFlag.Name)
  1024  	}
  1025  	if ctx.GlobalIsSet(AllowUnprotectedTxs.Name) {
  1026  		cfg.AllowUnprotectedTxs = ctx.GlobalBool(AllowUnprotectedTxs.Name)
  1027  	}
  1028  }
  1029  
  1030  // setGraphQL creates the GraphQL listener interface string from the set
  1031  // command line flags, returning empty if the GraphQL endpoint is disabled.
  1032  func setGraphQL(ctx *cli.Context, cfg *node.Config) {
  1033  	if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) {
  1034  		cfg.GraphQLCors = SplitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name))
  1035  	}
  1036  	if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) {
  1037  		cfg.GraphQLVirtualHosts = SplitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name))
  1038  	}
  1039  }
  1040  
  1041  // setWS creates the WebSocket RPC listener interface string from the set
  1042  // command line flags, returning empty if the HTTP endpoint is disabled.
  1043  func setWS(ctx *cli.Context, cfg *node.Config) {
  1044  	if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" {
  1045  		cfg.WSHost = "127.0.0.1"
  1046  		if ctx.GlobalIsSet(WSListenAddrFlag.Name) {
  1047  			cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name)
  1048  		}
  1049  	}
  1050  	if ctx.GlobalIsSet(WSPortFlag.Name) {
  1051  		cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name)
  1052  	}
  1053  
  1054  	if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) {
  1055  		cfg.WSOrigins = SplitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name))
  1056  	}
  1057  
  1058  	if ctx.GlobalIsSet(WSApiFlag.Name) {
  1059  		cfg.WSModules = SplitAndTrim(ctx.GlobalString(WSApiFlag.Name))
  1060  	}
  1061  
  1062  	if ctx.GlobalIsSet(WSPathPrefixFlag.Name) {
  1063  		cfg.WSPathPrefix = ctx.GlobalString(WSPathPrefixFlag.Name)
  1064  	}
  1065  }
  1066  
  1067  // setIPC creates an IPC path configuration from the set command line flags,
  1068  // returning an empty string if IPC was explicitly disabled, or the set path.
  1069  func setIPC(ctx *cli.Context, cfg *node.Config) {
  1070  	CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
  1071  	switch {
  1072  	case ctx.GlobalBool(IPCDisabledFlag.Name):
  1073  		cfg.IPCPath = ""
  1074  	case ctx.GlobalIsSet(IPCPathFlag.Name):
  1075  		cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name)
  1076  	}
  1077  }
  1078  
  1079  // setLes configures the les server and ultra light client settings from the command line flags.
  1080  func setLes(ctx *cli.Context, cfg *ethconfig.Config) {
  1081  	if ctx.GlobalIsSet(LightServeFlag.Name) {
  1082  		cfg.LightServ = ctx.GlobalInt(LightServeFlag.Name)
  1083  	}
  1084  	if ctx.GlobalIsSet(LightIngressFlag.Name) {
  1085  		cfg.LightIngress = ctx.GlobalInt(LightIngressFlag.Name)
  1086  	}
  1087  	if ctx.GlobalIsSet(LightEgressFlag.Name) {
  1088  		cfg.LightEgress = ctx.GlobalInt(LightEgressFlag.Name)
  1089  	}
  1090  	if ctx.GlobalIsSet(LightMaxPeersFlag.Name) {
  1091  		cfg.LightPeers = ctx.GlobalInt(LightMaxPeersFlag.Name)
  1092  	}
  1093  	if ctx.GlobalIsSet(UltraLightServersFlag.Name) {
  1094  		cfg.UltraLightServers = strings.Split(ctx.GlobalString(UltraLightServersFlag.Name), ",")
  1095  	}
  1096  	if ctx.GlobalIsSet(UltraLightFractionFlag.Name) {
  1097  		cfg.UltraLightFraction = ctx.GlobalInt(UltraLightFractionFlag.Name)
  1098  	}
  1099  	if cfg.UltraLightFraction <= 0 && cfg.UltraLightFraction > 100 {
  1100  		log.Error("Ultra light fraction is invalid", "had", cfg.UltraLightFraction, "updated", ethconfig.Defaults.UltraLightFraction)
  1101  		cfg.UltraLightFraction = ethconfig.Defaults.UltraLightFraction
  1102  	}
  1103  	if ctx.GlobalIsSet(UltraLightOnlyAnnounceFlag.Name) {
  1104  		cfg.UltraLightOnlyAnnounce = ctx.GlobalBool(UltraLightOnlyAnnounceFlag.Name)
  1105  	}
  1106  	if ctx.GlobalIsSet(LightNoPruneFlag.Name) {
  1107  		cfg.LightNoPrune = ctx.GlobalBool(LightNoPruneFlag.Name)
  1108  	}
  1109  	if ctx.GlobalIsSet(LightNoSyncServeFlag.Name) {
  1110  		cfg.LightNoSyncServe = ctx.GlobalBool(LightNoSyncServeFlag.Name)
  1111  	}
  1112  }
  1113  
  1114  // MakeDatabaseHandles raises out the number of allowed file handles per process
  1115  // for Geth and returns half of the allowance to assign to the database.
  1116  func MakeDatabaseHandles() int {
  1117  	limit, err := fdlimit.Maximum()
  1118  	if err != nil {
  1119  		Fatalf("Failed to retrieve file descriptor allowance: %v", err)
  1120  	}
  1121  	raised, err := fdlimit.Raise(uint64(limit))
  1122  	if err != nil {
  1123  		Fatalf("Failed to raise file descriptor allowance: %v", err)
  1124  	}
  1125  	return int(raised / 2) // Leave half for networking and other stuff
  1126  }
  1127  
  1128  // MakeAddress converts an account specified directly as a hex encoded string or
  1129  // a key index in the key store to an internal account representation.
  1130  func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) {
  1131  	// If the specified account is a valid address, return it
  1132  	if common.IsHexAddress(account) {
  1133  		return accounts.Account{Address: common.HexToAddress(account)}, nil
  1134  	}
  1135  	// Otherwise try to interpret the account as a keystore index
  1136  	index, err := strconv.Atoi(account)
  1137  	if err != nil || index < 0 {
  1138  		return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account)
  1139  	}
  1140  	log.Warn("-------------------------------------------------------------------")
  1141  	log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
  1142  	log.Warn("This functionality is deprecated and will be removed in the future!")
  1143  	log.Warn("Please use explicit addresses! (can search via `geth account list`)")
  1144  	log.Warn("-------------------------------------------------------------------")
  1145  
  1146  	accs := ks.Accounts()
  1147  	if len(accs) <= index {
  1148  		return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs))
  1149  	}
  1150  	return accs[index], nil
  1151  }
  1152  
  1153  // setEtherbase retrieves the etherbase either from the directly specified
  1154  // command line flags or from the keystore if CLI indexed.
  1155  func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *ethconfig.Config) {
  1156  	// Extract the current etherbase
  1157  	var etherbase string
  1158  	if ctx.GlobalIsSet(MinerEtherbaseFlag.Name) {
  1159  		etherbase = ctx.GlobalString(MinerEtherbaseFlag.Name)
  1160  	}
  1161  	// Convert the etherbase into an address and configure it
  1162  	if etherbase != "" {
  1163  		if ks != nil {
  1164  			account, err := MakeAddress(ks, etherbase)
  1165  			if err != nil {
  1166  				Fatalf("Invalid miner etherbase: %v", err)
  1167  			}
  1168  			cfg.Miner.Etherbase = account.Address
  1169  		} else {
  1170  			Fatalf("No etherbase configured")
  1171  		}
  1172  	}
  1173  }
  1174  
  1175  // MakePasswordList reads password lines from the file specified by the global --password flag.
  1176  func MakePasswordList(ctx *cli.Context) []string {
  1177  	path := ctx.GlobalString(PasswordFileFlag.Name)
  1178  	if path == "" {
  1179  		return nil
  1180  	}
  1181  	text, err := ioutil.ReadFile(path)
  1182  	if err != nil {
  1183  		Fatalf("Failed to read password file: %v", err)
  1184  	}
  1185  	lines := strings.Split(string(text), "\n")
  1186  	// Sanitise DOS line endings.
  1187  	for i := range lines {
  1188  		lines[i] = strings.TrimRight(lines[i], "\r")
  1189  	}
  1190  	return lines
  1191  }
  1192  
  1193  func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
  1194  	setNodeKey(ctx, cfg)
  1195  	setNAT(ctx, cfg)
  1196  	setListenAddress(ctx, cfg)
  1197  	setBootstrapNodes(ctx, cfg)
  1198  	setBootstrapNodesV5(ctx, cfg)
  1199  
  1200  	lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light"
  1201  	lightServer := (ctx.GlobalInt(LightServeFlag.Name) != 0)
  1202  
  1203  	lightPeers := ctx.GlobalInt(LightMaxPeersFlag.Name)
  1204  	if lightClient && !ctx.GlobalIsSet(LightMaxPeersFlag.Name) {
  1205  		// dynamic default - for clients we use 1/10th of the default for servers
  1206  		lightPeers /= 10
  1207  	}
  1208  
  1209  	if ctx.GlobalIsSet(MaxPeersFlag.Name) {
  1210  		cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name)
  1211  		if lightServer && !ctx.GlobalIsSet(LightMaxPeersFlag.Name) {
  1212  			cfg.MaxPeers += lightPeers
  1213  		}
  1214  	} else {
  1215  		if lightServer {
  1216  			cfg.MaxPeers += lightPeers
  1217  		}
  1218  		if lightClient && ctx.GlobalIsSet(LightMaxPeersFlag.Name) && cfg.MaxPeers < lightPeers {
  1219  			cfg.MaxPeers = lightPeers
  1220  		}
  1221  	}
  1222  	if !(lightClient || lightServer) {
  1223  		lightPeers = 0
  1224  	}
  1225  	ethPeers := cfg.MaxPeers - lightPeers
  1226  	if lightClient {
  1227  		ethPeers = 0
  1228  	}
  1229  	log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers)
  1230  
  1231  	if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) {
  1232  		cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name)
  1233  	}
  1234  	if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient {
  1235  		cfg.NoDiscovery = true
  1236  	}
  1237  
  1238  	// if we're running a light client or server, force enable the v5 peer discovery
  1239  	// unless it is explicitly disabled with --nodiscover note that explicitly specifying
  1240  	// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
  1241  	forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name)
  1242  	if ctx.GlobalIsSet(DiscoveryV5Flag.Name) {
  1243  		cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name)
  1244  	} else if forceV5Discovery {
  1245  		cfg.DiscoveryV5 = true
  1246  	}
  1247  
  1248  	if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" {
  1249  		list, err := netutil.ParseNetlist(netrestrict)
  1250  		if err != nil {
  1251  			Fatalf("Option %q: %v", NetrestrictFlag.Name, err)
  1252  		}
  1253  		cfg.NetRestrict = list
  1254  	}
  1255  
  1256  	if ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(CatalystFlag.Name) {
  1257  		// --dev mode can't use p2p networking.
  1258  		cfg.MaxPeers = 0
  1259  		cfg.ListenAddr = ""
  1260  		cfg.NoDial = true
  1261  		cfg.NoDiscovery = true
  1262  		cfg.DiscoveryV5 = false
  1263  	}
  1264  }
  1265  
  1266  // SetNodeConfig applies node-related command line flags to the config.
  1267  func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
  1268  	SetP2PConfig(ctx, &cfg.P2P)
  1269  	setIPC(ctx, cfg)
  1270  	setHTTP(ctx, cfg)
  1271  	setGraphQL(ctx, cfg)
  1272  	setWS(ctx, cfg)
  1273  	setNodeUserIdent(ctx, cfg)
  1274  	setDataDir(ctx, cfg)
  1275  	setSmartCard(ctx, cfg)
  1276  
  1277  	if ctx.GlobalIsSet(ExternalSignerFlag.Name) {
  1278  		cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name)
  1279  	}
  1280  
  1281  	if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
  1282  		cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name)
  1283  	}
  1284  	if ctx.GlobalIsSet(LightKDFFlag.Name) {
  1285  		cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name)
  1286  	}
  1287  	if ctx.GlobalIsSet(NoUSBFlag.Name) || cfg.NoUSB {
  1288  		log.Warn("Option nousb is deprecated and USB is deactivated by default. Use --usb to enable")
  1289  	}
  1290  	if ctx.GlobalIsSet(USBFlag.Name) {
  1291  		cfg.USB = ctx.GlobalBool(USBFlag.Name)
  1292  	}
  1293  	if ctx.GlobalIsSet(DirectBroadcastFlag.Name) {
  1294  		cfg.DirectBroadcast = ctx.GlobalBool(DirectBroadcastFlag.Name)
  1295  	}
  1296  	if ctx.GlobalIsSet(DisableSnapProtocolFlag.Name) {
  1297  		cfg.DisableSnapProtocol = ctx.GlobalBool(DisableSnapProtocolFlag.Name)
  1298  	}
  1299  	if ctx.GlobalIsSet(RangeLimitFlag.Name) {
  1300  		cfg.RangeLimit = ctx.GlobalBool(RangeLimitFlag.Name)
  1301  	}
  1302  	if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) {
  1303  		cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name)
  1304  	}
  1305  }
  1306  
  1307  func setSmartCard(ctx *cli.Context, cfg *node.Config) {
  1308  	// Skip enabling smartcards if no path is set
  1309  	path := ctx.GlobalString(SmartCardDaemonPathFlag.Name)
  1310  	if path == "" {
  1311  		return
  1312  	}
  1313  	// Sanity check that the smartcard path is valid
  1314  	fi, err := os.Stat(path)
  1315  	if err != nil {
  1316  		log.Info("Smartcard socket not found, disabling", "err", err)
  1317  		return
  1318  	}
  1319  	if fi.Mode()&os.ModeType != os.ModeSocket {
  1320  		log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String())
  1321  		return
  1322  	}
  1323  	// Smartcard daemon path exists and is a socket, enable it
  1324  	cfg.SmartCardDaemonPath = path
  1325  }
  1326  
  1327  func setDataDir(ctx *cli.Context, cfg *node.Config) {
  1328  	switch {
  1329  	case ctx.GlobalIsSet(DataDirFlag.Name):
  1330  		cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
  1331  	case ctx.GlobalBool(DeveloperFlag.Name):
  1332  		cfg.DataDir = "" // unless explicitly requested, use memory databases
  1333  	case ctx.GlobalBool(RopstenFlag.Name) && cfg.DataDir == node.DefaultDataDir():
  1334  		// Maintain compatibility with older Geth configurations storing the
  1335  		// Ropsten database in `testnet` instead of `ropsten`.
  1336  		legacyPath := filepath.Join(node.DefaultDataDir(), "testnet")
  1337  		if _, err := os.Stat(legacyPath); !os.IsNotExist(err) {
  1338  			log.Warn("Using the deprecated `testnet` datadir. Future versions will store the Ropsten chain in `ropsten`.")
  1339  			cfg.DataDir = legacyPath
  1340  		} else {
  1341  			cfg.DataDir = filepath.Join(node.DefaultDataDir(), "ropsten")
  1342  		}
  1343  
  1344  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "ropsten")
  1345  	case ctx.GlobalBool(RinkebyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
  1346  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby")
  1347  	case ctx.GlobalBool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir():
  1348  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
  1349  	case ctx.GlobalBool(YoloV3Flag.Name) && cfg.DataDir == node.DefaultDataDir():
  1350  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "yolo-v3")
  1351  	}
  1352  }
  1353  
  1354  func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
  1355  	// If we are running the light client, apply another group
  1356  	// settings for gas oracle.
  1357  	if light {
  1358  		cfg.Blocks = ethconfig.LightClientGPO.Blocks
  1359  		cfg.Percentile = ethconfig.LightClientGPO.Percentile
  1360  	}
  1361  	if ctx.GlobalIsSet(GpoBlocksFlag.Name) {
  1362  		cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name)
  1363  	}
  1364  	if ctx.GlobalIsSet(GpoPercentileFlag.Name) {
  1365  		cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name)
  1366  	}
  1367  	if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) {
  1368  		cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name))
  1369  	}
  1370  }
  1371  
  1372  func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
  1373  	if ctx.GlobalIsSet(TxPoolLocalsFlag.Name) {
  1374  		locals := strings.Split(ctx.GlobalString(TxPoolLocalsFlag.Name), ",")
  1375  		for _, account := range locals {
  1376  			if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) {
  1377  				Fatalf("Invalid account in --txpool.locals: %s", trimmed)
  1378  			} else {
  1379  				cfg.Locals = append(cfg.Locals, common.HexToAddress(account))
  1380  			}
  1381  		}
  1382  	}
  1383  	if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) {
  1384  		cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name)
  1385  	}
  1386  	if ctx.GlobalIsSet(TxPoolJournalFlag.Name) {
  1387  		cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name)
  1388  	}
  1389  	if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) {
  1390  		cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name)
  1391  	}
  1392  	if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) {
  1393  		cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name)
  1394  	}
  1395  	if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) {
  1396  		cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name)
  1397  	}
  1398  	if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) {
  1399  		cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name)
  1400  	}
  1401  	if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) {
  1402  		cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name)
  1403  	}
  1404  	if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) {
  1405  		cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name)
  1406  	}
  1407  	if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) {
  1408  		cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name)
  1409  	}
  1410  	if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) {
  1411  		cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name)
  1412  	}
  1413  }
  1414  
  1415  func setEthash(ctx *cli.Context, cfg *ethconfig.Config) {
  1416  	if ctx.GlobalIsSet(EthashCacheDirFlag.Name) {
  1417  		cfg.Ethash.CacheDir = ctx.GlobalString(EthashCacheDirFlag.Name)
  1418  	}
  1419  	if ctx.GlobalIsSet(EthashDatasetDirFlag.Name) {
  1420  		cfg.Ethash.DatasetDir = ctx.GlobalString(EthashDatasetDirFlag.Name)
  1421  	}
  1422  	if ctx.GlobalIsSet(EthashCachesInMemoryFlag.Name) {
  1423  		cfg.Ethash.CachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name)
  1424  	}
  1425  	if ctx.GlobalIsSet(EthashCachesOnDiskFlag.Name) {
  1426  		cfg.Ethash.CachesOnDisk = ctx.GlobalInt(EthashCachesOnDiskFlag.Name)
  1427  	}
  1428  	if ctx.GlobalIsSet(EthashCachesLockMmapFlag.Name) {
  1429  		cfg.Ethash.CachesLockMmap = ctx.GlobalBool(EthashCachesLockMmapFlag.Name)
  1430  	}
  1431  	if ctx.GlobalIsSet(EthashDatasetsInMemoryFlag.Name) {
  1432  		cfg.Ethash.DatasetsInMem = ctx.GlobalInt(EthashDatasetsInMemoryFlag.Name)
  1433  	}
  1434  	if ctx.GlobalIsSet(EthashDatasetsOnDiskFlag.Name) {
  1435  		cfg.Ethash.DatasetsOnDisk = ctx.GlobalInt(EthashDatasetsOnDiskFlag.Name)
  1436  	}
  1437  	if ctx.GlobalIsSet(EthashDatasetsLockMmapFlag.Name) {
  1438  		cfg.Ethash.DatasetsLockMmap = ctx.GlobalBool(EthashDatasetsLockMmapFlag.Name)
  1439  	}
  1440  }
  1441  
  1442  func setMiner(ctx *cli.Context, cfg *miner.Config) {
  1443  	if ctx.GlobalIsSet(MinerNotifyFlag.Name) {
  1444  		cfg.Notify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",")
  1445  	}
  1446  	cfg.NotifyFull = ctx.GlobalBool(MinerNotifyFullFlag.Name)
  1447  	if ctx.GlobalIsSet(MinerExtraDataFlag.Name) {
  1448  		cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name))
  1449  	}
  1450  	if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
  1451  		cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name)
  1452  	}
  1453  	if ctx.GlobalIsSet(MinerGasLimitFlag.Name) {
  1454  		cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name)
  1455  	}
  1456  	if ctx.GlobalIsSet(MinerGasPriceFlag.Name) {
  1457  		cfg.GasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name)
  1458  	}
  1459  	if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) {
  1460  		cfg.Recommit = ctx.GlobalDuration(MinerRecommitIntervalFlag.Name)
  1461  	}
  1462  	if ctx.GlobalIsSet(MinerDelayLeftoverFlag.Name) {
  1463  		cfg.DelayLeftOver = ctx.Duration(MinerDelayLeftoverFlag.Name)
  1464  	}
  1465  	if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) {
  1466  		cfg.Noverify = ctx.GlobalBool(MinerNoVerfiyFlag.Name)
  1467  	}
  1468  }
  1469  
  1470  func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) {
  1471  	whitelist := ctx.GlobalString(WhitelistFlag.Name)
  1472  	if whitelist == "" {
  1473  		return
  1474  	}
  1475  	cfg.Whitelist = make(map[uint64]common.Hash)
  1476  	for _, entry := range strings.Split(whitelist, ",") {
  1477  		parts := strings.Split(entry, "=")
  1478  		if len(parts) != 2 {
  1479  			Fatalf("Invalid whitelist entry: %s", entry)
  1480  		}
  1481  		number, err := strconv.ParseUint(parts[0], 0, 64)
  1482  		if err != nil {
  1483  			Fatalf("Invalid whitelist block number %s: %v", parts[0], err)
  1484  		}
  1485  		var hash common.Hash
  1486  		if err = hash.UnmarshalText([]byte(parts[1])); err != nil {
  1487  			Fatalf("Invalid whitelist hash %s: %v", parts[1], err)
  1488  		}
  1489  		cfg.Whitelist[number] = hash
  1490  	}
  1491  }
  1492  
  1493  // CheckExclusive verifies that only a single instance of the provided flags was
  1494  // set by the user. Each flag might optionally be followed by a string type to
  1495  // specialize it further.
  1496  func CheckExclusive(ctx *cli.Context, args ...interface{}) {
  1497  	set := make([]string, 0, 1)
  1498  	for i := 0; i < len(args); i++ {
  1499  		// Make sure the next argument is a flag and skip if not set
  1500  		flag, ok := args[i].(cli.Flag)
  1501  		if !ok {
  1502  			panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i]))
  1503  		}
  1504  		// Check if next arg extends current and expand its name if so
  1505  		name := flag.GetName()
  1506  
  1507  		if i+1 < len(args) {
  1508  			switch option := args[i+1].(type) {
  1509  			case string:
  1510  				// Extended flag check, make sure value set doesn't conflict with passed in option
  1511  				if ctx.GlobalString(flag.GetName()) == option {
  1512  					name += "=" + option
  1513  					set = append(set, "--"+name)
  1514  				}
  1515  				// shift arguments and continue
  1516  				i++
  1517  				continue
  1518  
  1519  			case cli.Flag:
  1520  			default:
  1521  				panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1]))
  1522  			}
  1523  		}
  1524  		// Mark the flag if it's set
  1525  		if ctx.GlobalIsSet(flag.GetName()) {
  1526  			set = append(set, "--"+name)
  1527  		}
  1528  	}
  1529  	if len(set) > 1 {
  1530  		Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", "))
  1531  	}
  1532  }
  1533  
  1534  // SetEthConfig applies eth-related command line flags to the config.
  1535  func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
  1536  	// Avoid conflicting network flags
  1537  	CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV3Flag)
  1538  	CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
  1539  	CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
  1540  	if ctx.GlobalString(GCModeFlag.Name) == "archive" && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 {
  1541  		ctx.GlobalSet(TxLookupLimitFlag.Name, "0")
  1542  		log.Warn("Disable transaction unindexing for archive node")
  1543  	}
  1544  	if ctx.GlobalIsSet(LightServeFlag.Name) && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 {
  1545  		log.Warn("LES server cannot serve old transaction status and cannot connect below les/4 protocol version if transaction lookup index is limited")
  1546  	}
  1547  	var ks *keystore.KeyStore
  1548  	if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
  1549  		ks = keystores[0].(*keystore.KeyStore)
  1550  	}
  1551  	setEtherbase(ctx, ks, cfg)
  1552  	setGPO(ctx, &cfg.GPO, ctx.GlobalString(SyncModeFlag.Name) == "light")
  1553  	setTxPool(ctx, &cfg.TxPool)
  1554  	setEthash(ctx, cfg)
  1555  	setMiner(ctx, &cfg.Miner)
  1556  	setWhitelist(ctx, cfg)
  1557  	setLes(ctx, cfg)
  1558  
  1559  	// Cap the cache allowance and tune the garbage collector
  1560  	mem, err := gopsutil.VirtualMemory()
  1561  	if err == nil {
  1562  		if 32<<(^uintptr(0)>>63) == 32 && mem.Total > 2*1024*1024*1024 {
  1563  			log.Warn("Lowering memory allowance on 32bit arch", "available", mem.Total/1024/1024, "addressable", 2*1024)
  1564  			mem.Total = 2 * 1024 * 1024 * 1024
  1565  		}
  1566  		allowance := int(mem.Total / 1024 / 1024 / 3)
  1567  		if cache := ctx.GlobalInt(CacheFlag.Name); cache > allowance {
  1568  			log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
  1569  			ctx.GlobalSet(CacheFlag.Name, strconv.Itoa(allowance))
  1570  		}
  1571  	}
  1572  	// Ensure Go's GC ignores the database cache for trigger percentage
  1573  	cache := ctx.GlobalInt(CacheFlag.Name)
  1574  	gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024)))
  1575  
  1576  	log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
  1577  	godebug.SetGCPercent(int(gogc))
  1578  
  1579  	if ctx.GlobalIsSet(SyncModeFlag.Name) {
  1580  		cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
  1581  	}
  1582  	if ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1583  		cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
  1584  	}
  1585  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
  1586  		cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1587  	}
  1588  	cfg.DatabaseHandles = MakeDatabaseHandles()
  1589  	if ctx.GlobalIsSet(AncientFlag.Name) {
  1590  		cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name)
  1591  	}
  1592  	if ctx.GlobalIsSet(DiffFlag.Name) {
  1593  		cfg.DatabaseDiff = ctx.GlobalString(DiffFlag.Name)
  1594  	}
  1595  	if ctx.GlobalIsSet(PersistDiffFlag.Name) {
  1596  		cfg.PersistDiff = ctx.GlobalBool(PersistDiffFlag.Name)
  1597  	}
  1598  	if ctx.GlobalIsSet(DiffBlockFlag.Name) {
  1599  		cfg.DiffBlock = ctx.GlobalUint64(DiffBlockFlag.Name)
  1600  	}
  1601  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1602  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1603  	}
  1604  	if ctx.GlobalIsSet(GCModeFlag.Name) {
  1605  		cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive"
  1606  	}
  1607  	if ctx.GlobalIsSet(DirectBroadcastFlag.Name) {
  1608  		cfg.DirectBroadcast = ctx.GlobalBool(DirectBroadcastFlag.Name)
  1609  	}
  1610  	if ctx.GlobalIsSet(DisableSnapProtocolFlag.Name) {
  1611  		cfg.DisableSnapProtocol = ctx.GlobalBool(DisableSnapProtocolFlag.Name)
  1612  	}
  1613  	if ctx.GlobalIsSet(DiffSyncFlag.Name) {
  1614  		cfg.DiffSync = ctx.GlobalBool(DiffSyncFlag.Name)
  1615  	}
  1616  	if ctx.GlobalIsSet(RangeLimitFlag.Name) {
  1617  		cfg.RangeLimit = ctx.GlobalBool(RangeLimitFlag.Name)
  1618  	}
  1619  	// Read the value from the flag no matter if it's set or not.
  1620  	cfg.Preimages = ctx.GlobalBool(CachePreimagesFlag.Name)
  1621  	if cfg.NoPruning && !cfg.Preimages {
  1622  		cfg.Preimages = true
  1623  		log.Info("Enabling recording of key preimages since archive mode is used")
  1624  	}
  1625  	if ctx.GlobalIsSet(TxLookupLimitFlag.Name) {
  1626  		cfg.TxLookupLimit = ctx.GlobalUint64(TxLookupLimitFlag.Name)
  1627  	}
  1628  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
  1629  		cfg.TrieCleanCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
  1630  	}
  1631  	if ctx.GlobalIsSet(CacheTrieJournalFlag.Name) {
  1632  		cfg.TrieCleanCacheJournal = ctx.GlobalString(CacheTrieJournalFlag.Name)
  1633  	}
  1634  	if ctx.GlobalIsSet(CacheTrieRejournalFlag.Name) {
  1635  		cfg.TrieCleanCacheRejournal = ctx.GlobalDuration(CacheTrieRejournalFlag.Name)
  1636  	}
  1637  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1638  		cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1639  	}
  1640  	if ctx.GlobalIsSet(TriesInMemoryFlag.Name) {
  1641  		cfg.TriesInMemory = ctx.GlobalUint64(TriesInMemoryFlag.Name)
  1642  	}
  1643  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheSnapshotFlag.Name) {
  1644  		cfg.SnapshotCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheSnapshotFlag.Name) / 100
  1645  	}
  1646  	if !ctx.GlobalBool(SnapshotFlag.Name) {
  1647  		// If snap-sync is requested, this flag is also required
  1648  		if cfg.SyncMode == downloader.SnapSync {
  1649  			log.Info("Snap sync requested, enabling --snapshot")
  1650  		} else {
  1651  			cfg.TrieCleanCache += cfg.SnapshotCache
  1652  			cfg.SnapshotCache = 0 // Disabled
  1653  		}
  1654  	}
  1655  	if ctx.GlobalIsSet(DocRootFlag.Name) {
  1656  		cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name)
  1657  	}
  1658  	if ctx.GlobalIsSet(VMEnableDebugFlag.Name) {
  1659  		// TODO(fjl): force-enable this in --dev mode
  1660  		cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
  1661  	}
  1662  
  1663  	if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
  1664  		cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
  1665  	}
  1666  
  1667  	if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
  1668  		cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
  1669  	}
  1670  	if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) {
  1671  		cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name)
  1672  	}
  1673  	if cfg.RPCGasCap != 0 {
  1674  		log.Info("Set global gas cap", "cap", cfg.RPCGasCap)
  1675  	} else {
  1676  		log.Info("Global gas cap disabled")
  1677  	}
  1678  	if ctx.GlobalIsSet(RPCGlobalTxFeeCapFlag.Name) {
  1679  		cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name)
  1680  	}
  1681  	if ctx.GlobalIsSet(NoDiscoverFlag.Name) {
  1682  		cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs = []string{}, []string{}
  1683  	} else if ctx.GlobalIsSet(DNSDiscoveryFlag.Name) {
  1684  		urls := ctx.GlobalString(DNSDiscoveryFlag.Name)
  1685  		if urls == "" {
  1686  			cfg.EthDiscoveryURLs = []string{}
  1687  		} else {
  1688  			cfg.EthDiscoveryURLs = SplitAndTrim(urls)
  1689  		}
  1690  	}
  1691  	// Override any default configs for hard coded networks.
  1692  	switch {
  1693  	case ctx.GlobalBool(MainnetFlag.Name):
  1694  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1695  			cfg.NetworkId = 1
  1696  		}
  1697  		cfg.Genesis = core.DefaultGenesisBlock()
  1698  		SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
  1699  	case ctx.GlobalBool(RopstenFlag.Name):
  1700  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1701  			cfg.NetworkId = 3
  1702  		}
  1703  		cfg.Genesis = core.DefaultRopstenGenesisBlock()
  1704  		SetDNSDiscoveryDefaults(cfg, params.RopstenGenesisHash)
  1705  	case ctx.GlobalBool(RinkebyFlag.Name):
  1706  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1707  			cfg.NetworkId = 4
  1708  		}
  1709  		cfg.Genesis = core.DefaultRinkebyGenesisBlock()
  1710  		SetDNSDiscoveryDefaults(cfg, params.RinkebyGenesisHash)
  1711  	case ctx.GlobalBool(GoerliFlag.Name):
  1712  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1713  			cfg.NetworkId = 5
  1714  		}
  1715  		cfg.Genesis = core.DefaultGoerliGenesisBlock()
  1716  		SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
  1717  	case ctx.GlobalBool(YoloV3Flag.Name):
  1718  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1719  			cfg.NetworkId = new(big.Int).SetBytes([]byte("yolov3x")).Uint64() // "yolov3x"
  1720  		}
  1721  		cfg.Genesis = core.DefaultYoloV3GenesisBlock()
  1722  	case ctx.GlobalBool(DeveloperFlag.Name):
  1723  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1724  			cfg.NetworkId = 1337
  1725  		}
  1726  		// Create new developer account or reuse existing one
  1727  		var (
  1728  			developer  accounts.Account
  1729  			passphrase string
  1730  			err        error
  1731  		)
  1732  		if list := MakePasswordList(ctx); len(list) > 0 {
  1733  			// Just take the first value. Although the function returns a possible multiple values and
  1734  			// some usages iterate through them as attempts, that doesn't make sense in this setting,
  1735  			// when we're definitely concerned with only one account.
  1736  			passphrase = list[0]
  1737  		}
  1738  		// setEtherbase has been called above, configuring the miner address from command line flags.
  1739  		if cfg.Miner.Etherbase != (common.Address{}) {
  1740  			developer = accounts.Account{Address: cfg.Miner.Etherbase}
  1741  		} else if accs := ks.Accounts(); len(accs) > 0 {
  1742  			developer = ks.Accounts()[0]
  1743  		} else {
  1744  			developer, err = ks.NewAccount(passphrase)
  1745  			if err != nil {
  1746  				Fatalf("Failed to create developer account: %v", err)
  1747  			}
  1748  		}
  1749  		if err := ks.Unlock(developer, passphrase); err != nil {
  1750  			Fatalf("Failed to unlock developer account: %v", err)
  1751  		}
  1752  		log.Info("Using developer account", "address", developer.Address)
  1753  
  1754  		// Create a new developer genesis block or reuse existing one
  1755  		cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
  1756  		if ctx.GlobalIsSet(DataDirFlag.Name) {
  1757  			// Check if we have an already initialized chain and fall back to
  1758  			// that if so. Otherwise we need to generate a new genesis spec.
  1759  			chaindb := MakeChainDatabase(ctx, stack, false) // TODO (MariusVanDerWijden) make this read only
  1760  			if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) {
  1761  				cfg.Genesis = nil // fallback to db content
  1762  			}
  1763  			chaindb.Close()
  1764  		}
  1765  		if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) {
  1766  			cfg.Miner.GasPrice = big.NewInt(1)
  1767  		}
  1768  	default:
  1769  		if cfg.NetworkId == 1 {
  1770  			SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
  1771  		}
  1772  	}
  1773  }
  1774  
  1775  // SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
  1776  // no URLs are set.
  1777  func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) {
  1778  	if cfg.EthDiscoveryURLs != nil {
  1779  		return // already set through flags/config
  1780  	}
  1781  	protocol := "all"
  1782  	if cfg.SyncMode == downloader.LightSync {
  1783  		protocol = "les"
  1784  	}
  1785  	if url := params.KnownDNSNetwork(genesis, protocol); url != "" {
  1786  		cfg.EthDiscoveryURLs = []string{url}
  1787  		cfg.SnapDiscoveryURLs = cfg.EthDiscoveryURLs
  1788  	}
  1789  }
  1790  
  1791  // RegisterEthService adds an Ethereum client to the stack.
  1792  // The second return value is the full node instance, which may be nil if the
  1793  // node is running as a light client.
  1794  func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend, *eth.Ethereum) {
  1795  	if cfg.SyncMode == downloader.LightSync {
  1796  		backend, err := les.New(stack, cfg)
  1797  		if err != nil {
  1798  			Fatalf("Failed to register the Ethereum service: %v", err)
  1799  		}
  1800  		stack.RegisterAPIs(tracers.APIs(backend.ApiBackend))
  1801  		return backend.ApiBackend, nil
  1802  	}
  1803  	backend, err := eth.New(stack, cfg)
  1804  	if err != nil {
  1805  		Fatalf("Failed to register the Ethereum service: %v", err)
  1806  	}
  1807  	if cfg.LightServ > 0 {
  1808  		_, err := les.NewLesServer(stack, backend, cfg)
  1809  		if err != nil {
  1810  			Fatalf("Failed to create the LES server: %v", err)
  1811  		}
  1812  	}
  1813  	stack.RegisterAPIs(tracers.APIs(backend.APIBackend))
  1814  	return backend.APIBackend, backend
  1815  }
  1816  
  1817  // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
  1818  // the given node.
  1819  func RegisterEthStatsService(stack *node.Node, backend ethapi.Backend, url string) {
  1820  	if err := ethstats.New(stack, backend, backend.Engine(), url); err != nil {
  1821  		Fatalf("Failed to register the Ethereum Stats service: %v", err)
  1822  	}
  1823  }
  1824  
  1825  // RegisterGraphQLService is a utility function to construct a new service and register it against a node.
  1826  func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, cfg node.Config) {
  1827  	if err := graphql.New(stack, backend, cfg.GraphQLCors, cfg.GraphQLVirtualHosts); err != nil {
  1828  		Fatalf("Failed to register the GraphQL service: %v", err)
  1829  	}
  1830  }
  1831  
  1832  func SetupMetrics(ctx *cli.Context) {
  1833  	if metrics.Enabled {
  1834  		log.Info("Enabling metrics collection")
  1835  
  1836  		var (
  1837  			enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
  1838  			endpoint     = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
  1839  			database     = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
  1840  			username     = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
  1841  			password     = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
  1842  		)
  1843  
  1844  		if enableExport {
  1845  			tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name))
  1846  
  1847  			log.Info("Enabling metrics export to InfluxDB")
  1848  
  1849  			go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
  1850  		}
  1851  
  1852  		if ctx.GlobalIsSet(MetricsHTTPFlag.Name) {
  1853  			address := fmt.Sprintf("%s:%d", ctx.GlobalString(MetricsHTTPFlag.Name), ctx.GlobalInt(MetricsPortFlag.Name))
  1854  			log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address)
  1855  			exp.Setup(address)
  1856  		}
  1857  	}
  1858  }
  1859  
  1860  func SplitTagsFlag(tagsFlag string) map[string]string {
  1861  	tags := strings.Split(tagsFlag, ",")
  1862  	tagsMap := map[string]string{}
  1863  
  1864  	for _, t := range tags {
  1865  		if t != "" {
  1866  			kv := strings.Split(t, "=")
  1867  
  1868  			if len(kv) == 2 {
  1869  				tagsMap[kv[0]] = kv[1]
  1870  			}
  1871  		}
  1872  	}
  1873  
  1874  	return tagsMap
  1875  }
  1876  
  1877  // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
  1878  func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database {
  1879  	var (
  1880  		cache   = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1881  		handles = MakeDatabaseHandles()
  1882  
  1883  		err     error
  1884  		chainDb ethdb.Database
  1885  	)
  1886  	if ctx.GlobalString(SyncModeFlag.Name) == "light" {
  1887  		name := "lightchaindata"
  1888  		chainDb, err = stack.OpenDatabase(name, cache, handles, "", readonly)
  1889  	} else {
  1890  		name := "chaindata"
  1891  		chainDb, err = stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "", readonly)
  1892  	}
  1893  	if err != nil {
  1894  		Fatalf("Could not open database: %v", err)
  1895  	}
  1896  	return chainDb
  1897  }
  1898  
  1899  func MakeGenesis(ctx *cli.Context) *core.Genesis {
  1900  	var genesis *core.Genesis
  1901  	switch {
  1902  	case ctx.GlobalBool(MainnetFlag.Name):
  1903  		genesis = core.DefaultGenesisBlock()
  1904  	case ctx.GlobalBool(RopstenFlag.Name):
  1905  		genesis = core.DefaultRopstenGenesisBlock()
  1906  	case ctx.GlobalBool(RinkebyFlag.Name):
  1907  		genesis = core.DefaultRinkebyGenesisBlock()
  1908  	case ctx.GlobalBool(GoerliFlag.Name):
  1909  		genesis = core.DefaultGoerliGenesisBlock()
  1910  	case ctx.GlobalBool(YoloV3Flag.Name):
  1911  		genesis = core.DefaultYoloV3GenesisBlock()
  1912  	case ctx.GlobalBool(DeveloperFlag.Name):
  1913  		Fatalf("Developer chains are ephemeral")
  1914  	}
  1915  	return genesis
  1916  }
  1917  
  1918  // MakeChain creates a chain manager from set command line flags.
  1919  func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
  1920  	var err error
  1921  	chainDb = MakeChainDatabase(ctx, stack, false) // TODO(rjl493456442) support read-only database
  1922  	config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
  1923  	if err != nil {
  1924  		Fatalf("%v", err)
  1925  	}
  1926  	var engine consensus.Engine
  1927  	if config.Clique != nil {
  1928  		engine = clique.New(config.Clique, chainDb)
  1929  	} else {
  1930  		engine = ethash.NewFaker()
  1931  		if !ctx.GlobalBool(FakePoWFlag.Name) {
  1932  			engine = ethash.New(ethash.Config{
  1933  				CacheDir:         stack.ResolvePath(ethconfig.Defaults.Ethash.CacheDir),
  1934  				CachesInMem:      ethconfig.Defaults.Ethash.CachesInMem,
  1935  				CachesOnDisk:     ethconfig.Defaults.Ethash.CachesOnDisk,
  1936  				CachesLockMmap:   ethconfig.Defaults.Ethash.CachesLockMmap,
  1937  				DatasetDir:       stack.ResolvePath(ethconfig.Defaults.Ethash.DatasetDir),
  1938  				DatasetsInMem:    ethconfig.Defaults.Ethash.DatasetsInMem,
  1939  				DatasetsOnDisk:   ethconfig.Defaults.Ethash.DatasetsOnDisk,
  1940  				DatasetsLockMmap: ethconfig.Defaults.Ethash.DatasetsLockMmap,
  1941  			}, nil, false)
  1942  		}
  1943  	}
  1944  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1945  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1946  	}
  1947  	cache := &core.CacheConfig{
  1948  		TrieCleanLimit:    ethconfig.Defaults.TrieCleanCache,
  1949  		TrieDirtyLimit:    ethconfig.Defaults.TrieDirtyCache,
  1950  		TrieDirtyDisabled: ctx.GlobalString(GCModeFlag.Name) == "archive",
  1951  		TrieTimeLimit:     ethconfig.Defaults.TrieTimeout,
  1952  		TriesInMemory:     ethconfig.Defaults.TriesInMemory,
  1953  		SnapshotLimit:     ethconfig.Defaults.SnapshotCache,
  1954  		Preimages:         ctx.GlobalBool(CachePreimagesFlag.Name),
  1955  	}
  1956  	if cache.TrieDirtyDisabled && !cache.Preimages {
  1957  		cache.Preimages = true
  1958  		log.Info("Enabling recording of key preimages since archive mode is used")
  1959  	}
  1960  	if !ctx.GlobalBool(SnapshotFlag.Name) {
  1961  		cache.SnapshotLimit = 0 // Disabled
  1962  	}
  1963  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
  1964  		cache.TrieCleanLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
  1965  	}
  1966  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1967  		cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1968  	}
  1969  	if ctx.GlobalIsSet(TriesInMemoryFlag.Name) {
  1970  		cache.TriesInMemory = ctx.GlobalUint64(TriesInMemoryFlag.Name)
  1971  	}
  1972  	vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
  1973  
  1974  	// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
  1975  	// Disable transaction indexing/unindexing by default.
  1976  	chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil)
  1977  	if err != nil {
  1978  		Fatalf("Can't create BlockChain: %v", err)
  1979  	}
  1980  	return chain, chainDb
  1981  }
  1982  
  1983  // MakeConsolePreloads retrieves the absolute paths for the console JavaScript
  1984  // scripts to preload before starting.
  1985  func MakeConsolePreloads(ctx *cli.Context) []string {
  1986  	// Skip preloading if there's nothing to preload
  1987  	if ctx.GlobalString(PreloadJSFlag.Name) == "" {
  1988  		return nil
  1989  	}
  1990  	// Otherwise resolve absolute paths and return them
  1991  	var preloads []string
  1992  
  1993  	for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") {
  1994  		preloads = append(preloads, strings.TrimSpace(file))
  1995  	}
  1996  	return preloads
  1997  }
  1998  
  1999  // MigrateFlags sets the global flag from a local flag when it's set.
  2000  // This is a temporary function used for migrating old command/flags to the
  2001  // new format.
  2002  //
  2003  // e.g. geth account new --keystore /tmp/mykeystore --lightkdf
  2004  //
  2005  // is equivalent after calling this method with:
  2006  //
  2007  // geth --keystore /tmp/mykeystore --lightkdf account new
  2008  //
  2009  // This allows the use of the existing configuration functionality.
  2010  // When all flags are migrated this function can be removed and the existing
  2011  // configuration functionality must be changed that is uses local flags
  2012  func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error {
  2013  	return func(ctx *cli.Context) error {
  2014  		for _, name := range ctx.FlagNames() {
  2015  			if ctx.IsSet(name) {
  2016  				ctx.GlobalSet(name, ctx.String(name))
  2017  			}
  2018  		}
  2019  		return action(ctx)
  2020  	}
  2021  }