github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/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/ioutil"
    24  	"math/big"
    25  	"os"
    26  	"path/filepath"
    27  	"strconv"
    28  	"strings"
    29  	"time"
    30  
    31  	"github.com/PlatONnetwork/PlatON-Go/accounts"
    32  	"github.com/PlatONnetwork/PlatON-Go/accounts/keystore"
    33  	"github.com/PlatONnetwork/PlatON-Go/common"
    34  	"github.com/PlatONnetwork/PlatON-Go/common/fdlimit"
    35  	"github.com/PlatONnetwork/PlatON-Go/consensus"
    36  	"github.com/PlatONnetwork/PlatON-Go/core"
    37  	"github.com/PlatONnetwork/PlatON-Go/core/state"
    38  	"github.com/PlatONnetwork/PlatON-Go/core/vm"
    39  	"github.com/PlatONnetwork/PlatON-Go/crypto"
    40  	"github.com/PlatONnetwork/PlatON-Go/dashboard"
    41  	"github.com/PlatONnetwork/PlatON-Go/eth"
    42  	"github.com/PlatONnetwork/PlatON-Go/eth/downloader"
    43  	"github.com/PlatONnetwork/PlatON-Go/eth/gasprice"
    44  	"github.com/PlatONnetwork/PlatON-Go/ethdb"
    45  	"github.com/PlatONnetwork/PlatON-Go/ethstats"
    46  	"github.com/PlatONnetwork/PlatON-Go/les"
    47  	"github.com/PlatONnetwork/PlatON-Go/log"
    48  	"github.com/PlatONnetwork/PlatON-Go/metrics"
    49  	"github.com/PlatONnetwork/PlatON-Go/metrics/influxdb"
    50  	"github.com/PlatONnetwork/PlatON-Go/node"
    51  	"github.com/PlatONnetwork/PlatON-Go/p2p"
    52  	"github.com/PlatONnetwork/PlatON-Go/p2p/discover"
    53  	"github.com/PlatONnetwork/PlatON-Go/p2p/discv5"
    54  	"github.com/PlatONnetwork/PlatON-Go/p2p/nat"
    55  	"github.com/PlatONnetwork/PlatON-Go/p2p/netutil"
    56  	"github.com/PlatONnetwork/PlatON-Go/params"
    57  	whisper "github.com/PlatONnetwork/PlatON-Go/whisper/whisperv6"
    58  	"gopkg.in/urfave/cli.v1"
    59  )
    60  
    61  var (
    62  	CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} [arguments...]
    63  {{if .cmd.Description}}{{.cmd.Description}}
    64  {{end}}{{if .cmd.Subcommands}}
    65  SUBCOMMANDS:
    66  	{{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
    67  	{{end}}{{end}}{{if .categorizedFlags}}
    68  {{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS:
    69  {{range $categorized.Flags}}{{"\t"}}{{.}}
    70  {{end}}
    71  {{end}}{{end}}`
    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  
    88  	cli.CommandHelpTemplate = CommandHelpTemplate
    89  }
    90  
    91  // NewApp creates an app with sane defaults.
    92  func NewApp(gitCommit, usage string) *cli.App {
    93  	app := cli.NewApp()
    94  	app.Name = filepath.Base(os.Args[0])
    95  	app.Author = ""
    96  	//app.Authors = nil
    97  	app.Email = ""
    98  	app.Version = params.VersionWithMeta
    99  	if len(gitCommit) >= 8 {
   100  		app.Version += "-" + gitCommit[:8]
   101  	}
   102  	app.Usage = usage
   103  	return app
   104  }
   105  
   106  // These are all the command line flags we support.
   107  // If you add to this list, please remember to include the
   108  // flag in the appropriate command definition.
   109  //
   110  // The flags are defined here so their names and help texts
   111  // are the same for all commands.
   112  
   113  var (
   114  	// General settings
   115  	DataDirFlag = DirectoryFlag{
   116  		Name:  "datadir",
   117  		Usage: "Data directory for the databases and keystore",
   118  		Value: DirectoryString{node.DefaultDataDir()},
   119  	}
   120  	KeyStoreDirFlag = DirectoryFlag{
   121  		Name:  "keystore",
   122  		Usage: "Directory for the keystore (default = inside the datadir)",
   123  	}
   124  	NoUSBFlag = cli.BoolFlag{
   125  		Name:  "nousb",
   126  		Usage: "Disables monitoring for and managing USB hardware wallets",
   127  	}
   128  	NetworkIdFlag = cli.Uint64Flag{
   129  		Name:  "networkid",
   130  		Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby)",
   131  		Value: eth.DefaultConfig.NetworkId,
   132  	}
   133  	TestnetFlag = cli.BoolFlag{
   134  		Name:  "testnet",
   135  		Usage: "Testnet network: pre-configured alpha test network",
   136  	}
   137  	BetanetFlag = cli.BoolFlag{
   138  		Name:  "betanet",
   139  		Usage: "Betanet network: pre-configured beta test network",
   140  	}
   141  	InnerTestnetFlag = cli.BoolFlag{
   142  		Name:  "innertestnet",
   143  		Usage: "Ropsten network: pre-configured proof-of-work test network",
   144  	}
   145  	InnerDevnetFlag = cli.BoolFlag{
   146  		Name:  "innerdevnet",
   147  		Usage: "Ropsten network: pre-configured proof-of-work dev network",
   148  	}
   149  	DeveloperFlag = cli.BoolFlag{
   150  		Name:  "dev",
   151  		Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
   152  	}
   153  	DeveloperPeriodFlag = cli.IntFlag{
   154  		Name:  "dev.period",
   155  		Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
   156  	}
   157  	IdentityFlag = cli.StringFlag{
   158  		Name:  "identity",
   159  		Usage: "Custom node name",
   160  	}
   161  	DocRootFlag = DirectoryFlag{
   162  		Name:  "docroot",
   163  		Usage: "Document Root for HTTPClient file scheme",
   164  		Value: DirectoryString{homeDir()},
   165  	}
   166  	defaultSyncMode = eth.DefaultConfig.SyncMode
   167  	InnerTimeFlag = cli.Uint64Flag{
   168  		Name:  "innertime",
   169  		Usage: "inner time",
   170  		Value: 1546300800000,
   171  	}
   172  	SyncModeFlag    = TextMarshalerFlag{
   173  		Name:  "syncmode",
   174  		Usage: `Blockchain sync mode ("fast", "full", or "light")`,
   175  		Value: &defaultSyncMode,
   176  	}
   177  	GCModeFlag = cli.StringFlag{
   178  		Name:  "gcmode",
   179  		Usage: `Blockchain garbage collection mode ("full", "archive")`,
   180  		Value: "full",
   181  	}
   182  	LightServFlag = cli.IntFlag{
   183  		Name:  "lightserv",
   184  		Usage: "Maximum percentage of time allowed for serving LES requests (0-90)",
   185  		Value: 0,
   186  	}
   187  	LightPeersFlag = cli.IntFlag{
   188  		Name:  "lightpeers",
   189  		Usage: "Maximum number of LES client peers",
   190  		Value: eth.DefaultConfig.LightPeers,
   191  	}
   192  	LightKDFFlag = cli.BoolFlag{
   193  		Name:  "lightkdf",
   194  		Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength",
   195  	}
   196  	// Dashboard settings
   197  	DashboardEnabledFlag = cli.BoolFlag{
   198  		Name:  metrics.DashboardEnabledFlag,
   199  		Usage: "Enable the dashboard",
   200  	}
   201  	DashboardAddrFlag = cli.StringFlag{
   202  		Name:  "dashboard.addr",
   203  		Usage: "Dashboard listening interface",
   204  		Value: dashboard.DefaultConfig.Host,
   205  	}
   206  	DashboardPortFlag = cli.IntFlag{
   207  		Name:  "dashboard.host",
   208  		Usage: "Dashboard listening port",
   209  		Value: dashboard.DefaultConfig.Port,
   210  	}
   211  	DashboardRefreshFlag = cli.DurationFlag{
   212  		Name:  "dashboard.refresh",
   213  		Usage: "Dashboard metrics collection refresh rate",
   214  		Value: dashboard.DefaultConfig.Refresh,
   215  	}
   216  	// Transaction pool settings
   217  	TxPoolLocalsFlag = cli.StringFlag{
   218  		Name:  "txpool.locals",
   219  		Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)",
   220  	}
   221  	TxPoolNoLocalsFlag = cli.BoolFlag{
   222  		Name:  "txpool.nolocals",
   223  		Usage: "Disables price exemptions for locally submitted transactions",
   224  	}
   225  	TxPoolJournalFlag = cli.StringFlag{
   226  		Name:  "txpool.journal",
   227  		Usage: "Disk journal for local transaction to survive node restarts",
   228  		Value: core.DefaultTxPoolConfig.Journal,
   229  	}
   230  	TxPoolRejournalFlag = cli.DurationFlag{
   231  		Name:  "txpool.rejournal",
   232  		Usage: "Time interval to regenerate the local transaction journal",
   233  		Value: core.DefaultTxPoolConfig.Rejournal,
   234  	}
   235  	TxPoolPriceLimitFlag = cli.Uint64Flag{
   236  		Name:  "txpool.pricelimit",
   237  		Usage: "Minimum gas price limit to enforce for acceptance into the pool",
   238  		Value: eth.DefaultConfig.TxPool.PriceLimit,
   239  	}
   240  	TxPoolPriceBumpFlag = cli.Uint64Flag{
   241  		Name:  "txpool.pricebump",
   242  		Usage: "Price bump percentage to replace an already existing transaction",
   243  		Value: eth.DefaultConfig.TxPool.PriceBump,
   244  	}
   245  	TxPoolAccountSlotsFlag = cli.Uint64Flag{
   246  		Name:  "txpool.accountslots",
   247  		Usage: "Minimum number of executable transaction slots guaranteed per account",
   248  		Value: eth.DefaultConfig.TxPool.AccountSlots,
   249  	}
   250  	TxPoolGlobalSlotsFlag = cli.Uint64Flag{
   251  		Name:  "txpool.globalslots",
   252  		Usage: "Maximum number of executable transaction slots for all accounts",
   253  		Value: eth.DefaultConfig.TxPool.GlobalSlots,
   254  	}
   255  	TxPoolAccountQueueFlag = cli.Uint64Flag{
   256  		Name:  "txpool.accountqueue",
   257  		Usage: "Maximum number of non-executable transaction slots permitted per account",
   258  		Value: eth.DefaultConfig.TxPool.AccountQueue,
   259  	}
   260  	TxPoolGlobalQueueFlag = cli.Uint64Flag{
   261  		Name:  "txpool.globalqueue",
   262  		Usage: "Maximum number of non-executable transaction slots for all accounts",
   263  		Value: eth.DefaultConfig.TxPool.GlobalQueue,
   264  	}
   265  	TxPoolGlobalTxCountFlag = cli.Uint64Flag{
   266  		Name:  "txpool.globaltxcount",
   267  		Usage: "Maximum number of transactions for package",
   268  		Value: eth.DefaultConfig.TxPool.GlobalTxCount,
   269  	}
   270  	TxPoolLifetimeFlag = cli.DurationFlag{
   271  		Name:  "txpool.lifetime",
   272  		Usage: "Maximum amount of time non-executable transaction are queued",
   273  		Value: eth.DefaultConfig.TxPool.Lifetime,
   274  	}
   275  	// Performance tuning settings
   276  	CacheFlag = cli.IntFlag{
   277  		Name:  "cache",
   278  		Usage: "Megabytes of memory allocated to internal caching",
   279  		Value: 1024,
   280  	}
   281  	CacheDatabaseFlag = cli.IntFlag{
   282  		Name:  "cache.database",
   283  		Usage: "Percentage of cache memory allowance to use for database io",
   284  		Value: 75,
   285  	}
   286  	CacheGCFlag = cli.IntFlag{
   287  		Name:  "cache.gc",
   288  		Usage: "Percentage of cache memory allowance to use for trie pruning",
   289  		Value: 25,
   290  	}
   291  	TrieCacheGenFlag = cli.IntFlag{
   292  		Name:  "trie-cache-gens",
   293  		Usage: "Number of trie node generations to keep in memory",
   294  		Value: int(state.MaxTrieCacheGen),
   295  	}
   296  	// Miner settings
   297  	MiningEnabledFlag = cli.BoolFlag{
   298  		Name:  "mine",
   299  		Usage: "Enable mining",
   300  	}
   301  	MinerThreadsFlag = cli.IntFlag{
   302  		Name:  "miner.threads",
   303  		Usage: "Number of CPU threads to use for mining",
   304  		Value: 0,
   305  	}
   306  	MinerLegacyThreadsFlag = cli.IntFlag{
   307  		Name:  "minerthreads",
   308  		Usage: "Number of CPU threads to use for mining (deprecated, use --miner.threads)",
   309  		Value: 0,
   310  	}
   311  	MinerNotifyFlag = cli.StringFlag{
   312  		Name:  "miner.notify",
   313  		Usage: "Comma separated HTTP URL list to notify of new work packages",
   314  	}
   315  	MinerGasTargetFlag = cli.Uint64Flag{
   316  		Name:  "miner.gastarget",
   317  		Usage: "Target gas floor for mined blocks",
   318  		Value: eth.DefaultConfig.MinerGasFloor,
   319  	}
   320  	MinerLegacyGasTargetFlag = cli.Uint64Flag{
   321  		Name:  "targetgaslimit",
   322  		Usage: "Target gas floor for mined blocks (deprecated, use --miner.gastarget)",
   323  		Value: eth.DefaultConfig.MinerGasFloor,
   324  	}
   325  	MinerGasLimitFlag = cli.Uint64Flag{
   326  		Name:  "miner.gaslimit",
   327  		Usage: "Target gas ceiling for mined blocks",
   328  		Value: eth.DefaultConfig.MinerGasCeil,
   329  	}
   330  	MinerGasPriceFlag = BigFlag{
   331  		Name:  "miner.gasprice",
   332  		Usage: "Minimum gas price for mining a transaction",
   333  		Value: eth.DefaultConfig.MinerGasPrice,
   334  	}
   335  	MinerLegacyGasPriceFlag = BigFlag{
   336  		Name:  "gasprice",
   337  		Usage: "Minimum gas price for mining a transaction (deprecated, use --miner.gasprice)",
   338  		Value: eth.DefaultConfig.MinerGasPrice,
   339  	}
   340  	MinerEtherbaseFlag = cli.StringFlag{
   341  		Name:  "miner.etherbase",
   342  		Usage: "Public address for block mining rewards (default = first account)",
   343  		Value: "0",
   344  	}
   345  	MinerLegacyEtherbaseFlag = cli.StringFlag{
   346  		Name:  "etherbase",
   347  		Usage: "Public address for block mining rewards (default = first account, deprecated, use --miner.etherbase)",
   348  		Value: "0",
   349  	}
   350  	MinerExtraDataFlag = cli.StringFlag{
   351  		Name:  "miner.extradata",
   352  		Usage: "Block extra data set by the miner (default = client version)",
   353  	}
   354  	MinerLegacyExtraDataFlag = cli.StringFlag{
   355  		Name:  "extradata",
   356  		Usage: "Block extra data set by the miner (default = client version, deprecated, use --miner.extradata)",
   357  	}
   358  	MinerRecommitIntervalFlag = cli.DurationFlag{
   359  		Name:  "miner.recommit",
   360  		Usage: "Time interval to recreate the block being mined",
   361  		Value: eth.DefaultConfig.MinerRecommit,
   362  	}
   363  	MinerNoVerfiyFlag = cli.BoolFlag{
   364  		Name:  "miner.noverify",
   365  		Usage: "Disable remote sealing verification",
   366  	}
   367  	// Account settings
   368  	UnlockedAccountFlag = cli.StringFlag{
   369  		Name:  "unlock",
   370  		Usage: "Comma separated list of accounts to unlock",
   371  		Value: "",
   372  	}
   373  	PasswordFileFlag = cli.StringFlag{
   374  		Name:  "password",
   375  		Usage: "Password file to use for non-interactive password input",
   376  		Value: "",
   377  	}
   378  
   379  	VMEnableDebugFlag = cli.BoolFlag{
   380  		Name:  "vmdebug",
   381  		Usage: "Record information useful for VM and contract debugging",
   382  	}
   383  	// Logging and debug settings
   384  	EthStatsURLFlag = cli.StringFlag{
   385  		Name:  "ethstats",
   386  		Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)",
   387  	}
   388  	FakePoWFlag = cli.BoolFlag{
   389  		Name:  "fakepow",
   390  		Usage: "Disables proof-of-work verification",
   391  	}
   392  	NoCompactionFlag = cli.BoolFlag{
   393  		Name:  "nocompaction",
   394  		Usage: "Disables db compaction after import",
   395  	}
   396  	// RPC settings
   397  	RPCEnabledFlag = cli.BoolFlag{
   398  		Name:  "rpc",
   399  		Usage: "Enable the HTTP-RPC server",
   400  	}
   401  	RPCListenAddrFlag = cli.StringFlag{
   402  		Name:  "rpcaddr",
   403  		Usage: "HTTP-RPC server listening interface",
   404  		Value: node.DefaultHTTPHost,
   405  	}
   406  	RPCPortFlag = cli.IntFlag{
   407  		Name:  "rpcport",
   408  		Usage: "HTTP-RPC server listening port",
   409  		Value: node.DefaultHTTPPort,
   410  	}
   411  	RPCCORSDomainFlag = cli.StringFlag{
   412  		Name:  "rpccorsdomain",
   413  		Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
   414  		Value: "",
   415  	}
   416  	RPCVirtualHostsFlag = cli.StringFlag{
   417  		Name:  "rpcvhosts",
   418  		Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
   419  		Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
   420  	}
   421  	RPCApiFlag = cli.StringFlag{
   422  		Name:  "rpcapi",
   423  		Usage: "API's offered over the HTTP-RPC interface",
   424  		Value: "",
   425  	}
   426  	IPCDisabledFlag = cli.BoolFlag{
   427  		Name:  "ipcdisable",
   428  		Usage: "Disable the IPC-RPC server",
   429  	}
   430  	IPCPathFlag = DirectoryFlag{
   431  		Name:  "ipcpath",
   432  		Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)",
   433  	}
   434  	WSEnabledFlag = cli.BoolFlag{
   435  		Name:  "ws",
   436  		Usage: "Enable the WS-RPC server",
   437  	}
   438  	WSListenAddrFlag = cli.StringFlag{
   439  		Name:  "wsaddr",
   440  		Usage: "WS-RPC server listening interface",
   441  		Value: node.DefaultWSHost,
   442  	}
   443  	WSPortFlag = cli.IntFlag{
   444  		Name:  "wsport",
   445  		Usage: "WS-RPC server listening port",
   446  		Value: node.DefaultWSPort,
   447  	}
   448  	WSApiFlag = cli.StringFlag{
   449  		Name:  "wsapi",
   450  		Usage: "API's offered over the WS-RPC interface",
   451  		Value: "",
   452  	}
   453  	WSAllowedOriginsFlag = cli.StringFlag{
   454  		Name:  "wsorigins",
   455  		Usage: "Origins from which to accept websockets requests",
   456  		Value: "",
   457  	}
   458  	ExecFlag = cli.StringFlag{
   459  		Name:  "exec",
   460  		Usage: "Execute JavaScript statement",
   461  	}
   462  	PreloadJSFlag = cli.StringFlag{
   463  		Name:  "preload",
   464  		Usage: "Comma separated list of JavaScript files to preload into the console",
   465  	}
   466  
   467  	// Network Settings
   468  	MaxPeersFlag = cli.IntFlag{
   469  		Name:  "maxpeers",
   470  		Usage: "Maximum number of network peers (network disabled if set to 0)",
   471  		Value: 50,
   472  	}
   473  	MaxConsensusPeersFlag = cli.IntFlag{
   474  		Name:  "maxconsensuspeers",
   475  		Usage: "Maximum number of network consensus peers (network disabled if set to 0)",
   476  		Value: 75,
   477  	}
   478  	MaxPendingPeersFlag = cli.IntFlag{
   479  		Name:  "maxpendpeers",
   480  		Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
   481  		Value: 0,
   482  	}
   483  	ListenPortFlag = cli.IntFlag{
   484  		Name:  "port",
   485  		Usage: "Network listening port",
   486  		Value: 16789,
   487  	}
   488  	BootnodesFlag = cli.StringFlag{
   489  		Name:  "bootnodes",
   490  		Usage: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)",
   491  		Value: "",
   492  	}
   493  	BootnodesV4Flag = cli.StringFlag{
   494  		Name:  "bootnodesv4",
   495  		Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)",
   496  		Value: "",
   497  	}
   498  	BootnodesV5Flag = cli.StringFlag{
   499  		Name:  "bootnodesv5",
   500  		Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)",
   501  		Value: "",
   502  	}
   503  	NodeKeyFileFlag = cli.StringFlag{
   504  		Name:  "nodekey",
   505  		Usage: "P2P node key file",
   506  	}
   507  	NodeKeyHexFlag = cli.StringFlag{
   508  		Name:  "nodekeyhex",
   509  		Usage: "P2P node key as hex (for testing)",
   510  	}
   511  	NATFlag = cli.StringFlag{
   512  		Name:  "nat",
   513  		Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
   514  		Value: "any",
   515  	}
   516  	NoDiscoverFlag = cli.BoolFlag{
   517  		Name:  "nodiscover",
   518  		Usage: "Disables the peer discovery mechanism (manual peer addition)",
   519  	}
   520  	DiscoveryV5Flag = cli.BoolFlag{
   521  		Name:  "v5disc",
   522  		Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
   523  	}
   524  	NetrestrictFlag = cli.StringFlag{
   525  		Name:  "netrestrict",
   526  		Usage: "Restricts network communication to the given IP networks (CIDR masks)",
   527  	}
   528  
   529  	// ATM the url is left to the user and deployment to
   530  	JSpathFlag = cli.StringFlag{
   531  		Name:  "jspath",
   532  		Usage: "JavaScript root path for `loadScript`",
   533  		Value: ".",
   534  	}
   535  
   536  	// Gas price oracle settings
   537  	GpoBlocksFlag = cli.IntFlag{
   538  		Name:  "gpoblocks",
   539  		Usage: "Number of recent blocks to check for gas prices",
   540  		Value: eth.DefaultConfig.GPO.Blocks,
   541  	}
   542  	GpoPercentileFlag = cli.IntFlag{
   543  		Name:  "gpopercentile",
   544  		Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
   545  		Value: eth.DefaultConfig.GPO.Percentile,
   546  	}
   547  	WhisperEnabledFlag = cli.BoolFlag{
   548  		Name:  "shh",
   549  		Usage: "Enable Whisper",
   550  	}
   551  	WhisperMaxMessageSizeFlag = cli.IntFlag{
   552  		Name:  "shh.maxmessagesize",
   553  		Usage: "Max message size accepted",
   554  		Value: int(whisper.DefaultMaxMessageSize),
   555  	}
   556  	WhisperMinPOWFlag = cli.Float64Flag{
   557  		Name:  "shh.pow",
   558  		Usage: "Minimum POW accepted",
   559  		Value: whisper.DefaultMinimumPoW,
   560  	}
   561  	WhisperRestrictConnectionBetweenLightClientsFlag = cli.BoolFlag{
   562  		Name:  "shh.restrict-light",
   563  		Usage: "Restrict connection between two whisper light clients",
   564  	}
   565  
   566  	// Metrics flags
   567  	MetricsEnabledFlag = cli.BoolFlag{
   568  		Name:  metrics.MetricsEnabledFlag,
   569  		Usage: "Enable metrics collection and reporting",
   570  	}
   571  	MetricsEnableInfluxDBFlag = cli.BoolFlag{
   572  		Name:  "metrics.influxdb",
   573  		Usage: "Enable metrics export/push to an external InfluxDB database",
   574  	}
   575  	MetricsInfluxDBEndpointFlag = cli.StringFlag{
   576  		Name:  "metrics.influxdb.endpoint",
   577  		Usage: "InfluxDB API endpoint to report metrics to",
   578  		Value: "http://localhost:8086",
   579  	}
   580  	MetricsInfluxDBDatabaseFlag = cli.StringFlag{
   581  		Name:  "metrics.influxdb.database",
   582  		Usage: "InfluxDB database name to push reported metrics to",
   583  		Value: "platon",
   584  	}
   585  	MetricsInfluxDBUsernameFlag = cli.StringFlag{
   586  		Name:  "metrics.influxdb.username",
   587  		Usage: "Username to authorize access to the database",
   588  		Value: "test",
   589  	}
   590  	MetricsInfluxDBPasswordFlag = cli.StringFlag{
   591  		Name:  "metrics.influxdb.password",
   592  		Usage: "Password to authorize access to the database",
   593  		Value: "test",
   594  	}
   595  	// The `host` tag is part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB.
   596  	// It is used so that we can group all nodes and average a measurement across all of them, but also so
   597  	// that we can select a specific node and inspect its measurements.
   598  	// https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key
   599  	MetricsInfluxDBHostTagFlag = cli.StringFlag{
   600  		Name:  "metrics.influxdb.host.tag",
   601  		Usage: "InfluxDB `host` tag attached to all measurements",
   602  		Value: "localhost",
   603  	}
   604  
   605  	EWASMInterpreterFlag = cli.StringFlag{
   606  		Name:  "vm.ewasm",
   607  		Usage: "External ewasm configuration (default = built-in interpreter)",
   608  		Value: "",
   609  	}
   610  	EVMInterpreterFlag = cli.StringFlag{
   611  		Name:  "vm.evm",
   612  		Usage: "External EVM configuration (default = built-in interpreter)",
   613  		Value: "",
   614  	}
   615  
   616  	// mpc compute
   617  	MPCIceFileFlag = cli.StringFlag{
   618  		Name:  "mpc.ice",
   619  		Usage: "Filename for ice to init mvm",
   620  		Value: "",
   621  	}
   622  	MPCActorFlag = cli.StringFlag{
   623  		Name:  "mpc.actor",
   624  		Usage: "The address of actor to exec mpc compute",
   625  		Value: "",
   626  	}
   627  	MPCEnabledFlag = cli.BoolFlag{
   628  		Name:  "mpc",
   629  		Usage: "Enable mpc compute",
   630  	}
   631  	VCEnabledFlag = cli.BoolFlag{
   632  		Name:  "vc",
   633  		Usage: "Enable vc compute",
   634  	}
   635  	VCActorFlag = cli.StringFlag{
   636  		Name:  "vc.actor",
   637  		Usage: "The address of vc to exec set result",
   638  		Value: "",
   639  	}
   640  
   641  	VCPasswordFlag = cli.StringFlag{
   642  		Name:  "vc.password",
   643  		Usage: "the pwd of unlock actor",
   644  		Value: "",
   645  	}
   646  )
   647  
   648  // MakeDataDir retrieves the currently requested data directory, terminating
   649  // if none (or the empty string) is specified. If the node is starting a testnet,
   650  // the a subdirectory of the specified datadir will be used.
   651  func MakeDataDir(ctx *cli.Context) string {
   652  	if path := ctx.GlobalString(DataDirFlag.Name); path != "" {
   653  		if ctx.GlobalBool(TestnetFlag.Name) {
   654  			return filepath.Join(path, "testnet")
   655  		}
   656  		if ctx.GlobalBool(BetanetFlag.Name) {
   657  			return filepath.Join(path, "betanet")
   658  		}
   659  		if ctx.GlobalBool(InnerTestnetFlag.Name) {
   660  			return filepath.Join(path, "innertestnet")
   661  		}
   662  		if ctx.GlobalBool(InnerDevnetFlag.Name) {
   663  			return filepath.Join(path, "innerdevnet")
   664  		}
   665  		return path
   666  	}
   667  	Fatalf("Cannot determine default data directory, please set manually (--datadir)")
   668  	return ""
   669  }
   670  
   671  // setNodeKey creates a node key from set command line flags, either loading it
   672  // from a file or as a specified hex value. If neither flags were provided, this
   673  // method returns nil and an emphemeral key is to be generated.
   674  func setNodeKey(ctx *cli.Context, cfg *p2p.Config) {
   675  	var (
   676  		hex  = ctx.GlobalString(NodeKeyHexFlag.Name)
   677  		file = ctx.GlobalString(NodeKeyFileFlag.Name)
   678  		key  *ecdsa.PrivateKey
   679  		err  error
   680  	)
   681  	switch {
   682  	case file != "" && hex != "":
   683  		Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
   684  	case file != "":
   685  		if key, err = crypto.LoadECDSA(file); err != nil {
   686  			Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
   687  		}
   688  		cfg.PrivateKey = key
   689  	case hex != "":
   690  		if key, err = crypto.HexToECDSA(hex); err != nil {
   691  			Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
   692  		}
   693  		cfg.PrivateKey = key
   694  	}
   695  }
   696  
   697  // setNodeUserIdent creates the user identifier from CLI flags.
   698  func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
   699  	if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 {
   700  		cfg.UserIdent = identity
   701  	}
   702  }
   703  
   704  // setBootstrapNodes creates a list of bootstrap nodes from the command line
   705  // flags, reverting to pre-configured ones if none have been specified.
   706  func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
   707  	urls := params.MainnetBootnodes
   708  	switch {
   709  	case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name):
   710  		if ctx.GlobalIsSet(BootnodesV4Flag.Name) {
   711  			urls = strings.Split(ctx.GlobalString(BootnodesV4Flag.Name), ",")
   712  		} else {
   713  			urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
   714  		}
   715  	case ctx.GlobalBool(TestnetFlag.Name):
   716  		urls = params.TestnetBootnodes
   717  	case ctx.GlobalBool(BetanetFlag.Name):
   718  		urls = params.BetanetBootnodes
   719  	case ctx.GlobalBool(InnerTestnetFlag.Name):
   720  		urls = params.InnerTestnetBootnodes
   721  	case ctx.GlobalBool(InnerDevnetFlag.Name):
   722  		urls = params.InnerDevnetBootnodes
   723  	case cfg.BootstrapNodes != nil:
   724  		return // already set, don't apply defaults.
   725  	}
   726  
   727  	cfg.BootstrapNodes = make([]*discover.Node, 0, len(urls))
   728  	for _, url := range urls {
   729  		node, err := discover.ParseNode(url)
   730  		if err != nil {
   731  			log.Crit("Bootstrap URL invalid", "enode", url, "err", err)
   732  		}
   733  		cfg.BootstrapNodes = append(cfg.BootstrapNodes, node)
   734  	}
   735  }
   736  
   737  // setBootstrapNodesV5 creates a list of bootstrap nodes from the command line
   738  // flags, reverting to pre-configured ones if none have been specified.
   739  func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
   740  	urls := params.DiscoveryV5Bootnodes
   741  	switch {
   742  	case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name):
   743  		if ctx.GlobalIsSet(BootnodesV5Flag.Name) {
   744  			urls = strings.Split(ctx.GlobalString(BootnodesV5Flag.Name), ",")
   745  		} else {
   746  			urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
   747  		}
   748  	case ctx.GlobalBool(BetanetFlag.Name):
   749  		urls = params.BetanetBootnodes
   750  	case cfg.BootstrapNodesV5 != nil:
   751  		return // already set, don't apply defaults.
   752  	}
   753  
   754  	cfg.BootstrapNodesV5 = make([]*discv5.Node, 0, len(urls))
   755  	for _, url := range urls {
   756  		node, err := discv5.ParseNode(url)
   757  		if err != nil {
   758  			log.Error("Bootstrap URL invalid", "enode", url, "err", err)
   759  			continue
   760  		}
   761  		cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node)
   762  	}
   763  }
   764  
   765  // setListenAddress creates a TCP listening address string from set command
   766  // line flags.
   767  func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
   768  	if ctx.GlobalIsSet(ListenPortFlag.Name) {
   769  		cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name))
   770  	}
   771  }
   772  
   773  // setNAT creates a port mapper from command line flags.
   774  func setNAT(ctx *cli.Context, cfg *p2p.Config) {
   775  	if ctx.GlobalIsSet(NATFlag.Name) {
   776  		natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
   777  		if err != nil {
   778  			Fatalf("Option %s: %v", NATFlag.Name, err)
   779  		}
   780  		cfg.NAT = natif
   781  	}
   782  }
   783  
   784  // splitAndTrim splits input separated by a comma
   785  // and trims excessive white space from the substrings.
   786  func splitAndTrim(input string) []string {
   787  	result := strings.Split(input, ",")
   788  	for i, r := range result {
   789  		result[i] = strings.TrimSpace(r)
   790  	}
   791  	return result
   792  }
   793  
   794  // setHTTP creates the HTTP RPC listener interface string from the set
   795  // command line flags, returning empty if the HTTP endpoint is disabled.
   796  func setHTTP(ctx *cli.Context, cfg *node.Config) {
   797  	if ctx.GlobalBool(RPCEnabledFlag.Name) && cfg.HTTPHost == "" {
   798  		cfg.HTTPHost = "127.0.0.1"
   799  		if ctx.GlobalIsSet(RPCListenAddrFlag.Name) {
   800  			cfg.HTTPHost = ctx.GlobalString(RPCListenAddrFlag.Name)
   801  		}
   802  	}
   803  
   804  	if ctx.GlobalIsSet(RPCPortFlag.Name) {
   805  		cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name)
   806  	}
   807  	if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) {
   808  		cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name))
   809  	}
   810  	if ctx.GlobalIsSet(RPCApiFlag.Name) {
   811  		cfg.HTTPModules = splitAndTrim(ctx.GlobalString(RPCApiFlag.Name))
   812  	}
   813  	if ctx.GlobalIsSet(RPCVirtualHostsFlag.Name) {
   814  		cfg.HTTPVirtualHosts = splitAndTrim(ctx.GlobalString(RPCVirtualHostsFlag.Name))
   815  	}
   816  }
   817  
   818  // setWS creates the WebSocket RPC listener interface string from the set
   819  // command line flags, returning empty if the HTTP endpoint is disabled.
   820  func setWS(ctx *cli.Context, cfg *node.Config) {
   821  	if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" {
   822  		cfg.WSHost = "127.0.0.1"
   823  		if ctx.GlobalIsSet(WSListenAddrFlag.Name) {
   824  			cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name)
   825  		}
   826  	}
   827  
   828  	if ctx.GlobalIsSet(WSPortFlag.Name) {
   829  		cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name)
   830  	}
   831  	if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) {
   832  		cfg.WSOrigins = splitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name))
   833  	}
   834  	if ctx.GlobalIsSet(WSApiFlag.Name) {
   835  		cfg.WSModules = splitAndTrim(ctx.GlobalString(WSApiFlag.Name))
   836  	}
   837  }
   838  
   839  // setIPC creates an IPC path configuration from the set command line flags,
   840  // returning an empty string if IPC was explicitly disabled, or the set path.
   841  func setIPC(ctx *cli.Context, cfg *node.Config) {
   842  	checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
   843  	switch {
   844  	case ctx.GlobalBool(IPCDisabledFlag.Name):
   845  		cfg.IPCPath = ""
   846  	case ctx.GlobalIsSet(IPCPathFlag.Name):
   847  		cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name)
   848  	}
   849  }
   850  
   851  // makeDatabaseHandles raises out the number of allowed file handles per process
   852  // for Geth and returns half of the allowance to assign to the database.
   853  func makeDatabaseHandles() int {
   854  	limit, err := fdlimit.Current()
   855  	if err != nil {
   856  		Fatalf("Failed to retrieve file descriptor allowance: %v", err)
   857  	}
   858  	if limit < 2048 {
   859  		if err := fdlimit.Raise(2048); err != nil {
   860  			Fatalf("Failed to raise file descriptor allowance: %v", err)
   861  		}
   862  	}
   863  	if limit > 2048 { // cap database file descriptors even if more is available
   864  		limit = 2048
   865  	}
   866  	return limit / 2 // Leave half for networking and other stuff
   867  }
   868  
   869  // MakeAddress converts an account specified directly as a hex encoded string or
   870  // a key index in the key store to an internal account representation.
   871  func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) {
   872  	// If the specified account is a valid address, return it
   873  	if common.IsHexAddress(account) {
   874  		return accounts.Account{Address: common.HexToAddress(account)}, nil
   875  	}
   876  	// Otherwise try to interpret the account as a keystore index
   877  	index, err := strconv.Atoi(account)
   878  	if err != nil || index < 0 {
   879  		return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account)
   880  	}
   881  	log.Warn("-------------------------------------------------------------------")
   882  	log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
   883  	log.Warn("This functionality is deprecated and will be removed in the future!")
   884  	log.Warn("Please use explicit addresses! (can search via `platon account list`)")
   885  	log.Warn("-------------------------------------------------------------------")
   886  
   887  	accs := ks.Accounts()
   888  	if len(accs) <= index {
   889  		return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs))
   890  	}
   891  	return accs[index], nil
   892  }
   893  
   894  // setEtherbase retrieves the etherbase either from the directly specified
   895  // command line flags or from the keystore if CLI indexed.
   896  func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) {
   897  	// Extract the current etherbase, new flag overriding legacy one
   898  	var etherbase string
   899  	if ctx.GlobalIsSet(MinerLegacyEtherbaseFlag.Name) {
   900  		etherbase = ctx.GlobalString(MinerLegacyEtherbaseFlag.Name)
   901  	}
   902  	if ctx.GlobalIsSet(MinerEtherbaseFlag.Name) {
   903  		etherbase = ctx.GlobalString(MinerEtherbaseFlag.Name)
   904  	}
   905  	// Convert the etherbase into an address and configure it
   906  	if etherbase != "" {
   907  		account, err := MakeAddress(ks, etherbase)
   908  		if err != nil {
   909  			Fatalf("Invalid miner etherbase: %v", err)
   910  		}
   911  		cfg.Etherbase = account.Address
   912  	}
   913  }
   914  
   915  // MakePasswordList reads password lines from the file specified by the global --password flag.
   916  func MakePasswordList(ctx *cli.Context) []string {
   917  	path := ctx.GlobalString(PasswordFileFlag.Name)
   918  	if path == "" {
   919  		return nil
   920  	}
   921  	text, err := ioutil.ReadFile(path)
   922  	if err != nil {
   923  		Fatalf("Failed to read password file: %v", err)
   924  	}
   925  	lines := strings.Split(string(text), "\n")
   926  	// Sanitise DOS line endings.
   927  	for i := range lines {
   928  		lines[i] = strings.TrimRight(lines[i], "\r")
   929  	}
   930  	return lines
   931  }
   932  
   933  func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
   934  	setNodeKey(ctx, cfg)
   935  	setNAT(ctx, cfg)
   936  	setListenAddress(ctx, cfg)
   937  	setBootstrapNodes(ctx, cfg)
   938  	setBootstrapNodesV5(ctx, cfg)
   939  
   940  	lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light"
   941  	lightServer := ctx.GlobalInt(LightServFlag.Name) != 0
   942  	lightPeers := ctx.GlobalInt(LightPeersFlag.Name)
   943  
   944  	if ctx.GlobalIsSet(MaxConsensusPeersFlag.Name) {
   945  		cfg.MaxConsensusPeers = ctx.GlobalInt(MaxConsensusPeersFlag.Name)
   946  	}
   947  	if ctx.GlobalIsSet(MaxPeersFlag.Name) {
   948  		cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name)
   949  		if lightServer && !ctx.GlobalIsSet(LightPeersFlag.Name) {
   950  			cfg.MaxPeers += lightPeers
   951  		}
   952  	} else {
   953  		if lightServer {
   954  			cfg.MaxPeers += lightPeers
   955  		}
   956  		if lightClient && ctx.GlobalIsSet(LightPeersFlag.Name) && cfg.MaxPeers < lightPeers {
   957  			cfg.MaxPeers = lightPeers
   958  		}
   959  	}
   960  	if !(lightClient || lightServer) {
   961  		lightPeers = 0
   962  	}
   963  	ethPeers := cfg.MaxPeers - lightPeers
   964  	if lightClient {
   965  		ethPeers = 0
   966  	}
   967  	log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers)
   968  
   969  	if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) {
   970  		cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name)
   971  	}
   972  	if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient {
   973  		cfg.NoDiscovery = true
   974  	}
   975  
   976  	// if we're running a light client or server, force enable the v5 peer discovery
   977  	// unless it is explicitly disabled with --nodiscover note that explicitly specifying
   978  	// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
   979  	forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name)
   980  	if ctx.GlobalIsSet(DiscoveryV5Flag.Name) {
   981  		cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name)
   982  	} else if forceV5Discovery {
   983  		cfg.DiscoveryV5 = true
   984  	}
   985  
   986  	if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" {
   987  		list, err := netutil.ParseNetlist(netrestrict)
   988  		if err != nil {
   989  			Fatalf("Option %q: %v", NetrestrictFlag.Name, err)
   990  		}
   991  		cfg.NetRestrict = list
   992  	}
   993  
   994  	if ctx.GlobalBool(DeveloperFlag.Name) {
   995  		// --dev mode can't use p2p networking.
   996  		cfg.MaxPeers = 0
   997  		cfg.ListenAddr = ":0"
   998  		cfg.NoDiscovery = true
   999  		cfg.DiscoveryV5 = false
  1000  	}
  1001  }
  1002  
  1003  // SetNodeConfig applies node-related command line flags to the config.
  1004  func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
  1005  	SetP2PConfig(ctx, &cfg.P2P)
  1006  	setIPC(ctx, cfg)
  1007  	setHTTP(ctx, cfg)
  1008  	setWS(ctx, cfg)
  1009  	setNodeUserIdent(ctx, cfg)
  1010  
  1011  	switch {
  1012  	case ctx.GlobalIsSet(DataDirFlag.Name):
  1013  		cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
  1014  	case ctx.GlobalBool(DeveloperFlag.Name):
  1015  		cfg.DataDir = "" // unless explicitly requested, use memory databases
  1016  	case ctx.GlobalBool(TestnetFlag.Name):
  1017  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet")
  1018  	case ctx.GlobalBool(BetanetFlag.Name):
  1019  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "betanet")
  1020  	case ctx.GlobalBool(InnerTestnetFlag.Name):
  1021  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "innertestnet")
  1022  	case ctx.GlobalBool(InnerDevnetFlag.Name):
  1023  		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "innerdevnet")
  1024  	}
  1025  
  1026  	if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
  1027  		cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name)
  1028  	}
  1029  	if ctx.GlobalIsSet(LightKDFFlag.Name) {
  1030  		cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name)
  1031  	}
  1032  	if ctx.GlobalIsSet(NoUSBFlag.Name) {
  1033  		cfg.NoUSB = ctx.GlobalBool(NoUSBFlag.Name)
  1034  	}
  1035  }
  1036  
  1037  func setGPO(ctx *cli.Context, cfg *gasprice.Config) {
  1038  	if ctx.GlobalIsSet(GpoBlocksFlag.Name) {
  1039  		cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name)
  1040  	}
  1041  	if ctx.GlobalIsSet(GpoPercentileFlag.Name) {
  1042  		cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name)
  1043  	}
  1044  }
  1045  
  1046  func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
  1047  	if ctx.GlobalIsSet(TxPoolLocalsFlag.Name) {
  1048  		locals := strings.Split(ctx.GlobalString(TxPoolLocalsFlag.Name), ",")
  1049  		for _, account := range locals {
  1050  			if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) {
  1051  				Fatalf("Invalid account in --txpool.locals: %s", trimmed)
  1052  			} else {
  1053  				cfg.Locals = append(cfg.Locals, common.HexToAddress(account))
  1054  			}
  1055  		}
  1056  	}
  1057  	if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) {
  1058  		cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name)
  1059  	}
  1060  	if ctx.GlobalIsSet(TxPoolJournalFlag.Name) {
  1061  		cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name)
  1062  	}
  1063  	if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) {
  1064  		cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name)
  1065  	}
  1066  	if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) {
  1067  		cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name)
  1068  	}
  1069  	if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) {
  1070  		cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name)
  1071  	}
  1072  	if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) {
  1073  		cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name)
  1074  	}
  1075  	if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) {
  1076  		cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name)
  1077  	}
  1078  	if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) {
  1079  		cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name)
  1080  	}
  1081  	if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) {
  1082  		cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name)
  1083  	}
  1084  	if ctx.GlobalIsSet(TxPoolGlobalTxCountFlag.Name) {
  1085  		cfg.GlobalTxCount = ctx.GlobalUint64(TxPoolGlobalTxCountFlag.Name)
  1086  	}
  1087  	if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) {
  1088  		cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name)
  1089  	}
  1090  }
  1091  
  1092  func setMpcPool(ctx *cli.Context, cfg *core.MPCPoolConfig) {
  1093  	if ctx.GlobalIsSet(MPCEnabledFlag.Name) {
  1094  		cfg.MPCEnable = ctx.GlobalBool(MPCEnabledFlag.Name)
  1095  	}
  1096  	if ctx.GlobalIsSet(MPCActorFlag.Name) {
  1097  		cfg.MpcActor = common.HexToAddress(ctx.GlobalString(MPCActorFlag.Name))
  1098  	}
  1099  	if file := ctx.GlobalString(MPCIceFileFlag.Name); file != "" {
  1100  		if _, err := os.Stat(file); err != nil {
  1101  			fmt.Println("ice conf not exists.")
  1102  			return
  1103  		}
  1104  		if b := filepath.IsAbs(file); !b {
  1105  			absPath, err := filepath.Abs(file)
  1106  			if err != nil {
  1107  				fmt.Println("Read abs path of ice conf fail: ", err.Error())
  1108  				return
  1109  			}
  1110  			cfg.IceConf = absPath
  1111  		} else {
  1112  			cfg.IceConf = file
  1113  		}
  1114  	}
  1115  }
  1116  
  1117  func setVcPool(ctx *cli.Context, cfg *core.VCPoolConfig) {
  1118  	if ctx.GlobalIsSet(VCEnabledFlag.Name) {
  1119  		cfg.VCEnable = ctx.GlobalBool(VCEnabledFlag.Name)
  1120  	}
  1121  	if ctx.GlobalIsSet(VCActorFlag.Name) {
  1122  		cfg.VcActor = common.HexToAddress(ctx.GlobalString(VCActorFlag.Name))
  1123  		fmt.Println("cfg.VcActor", cfg.VcActor)
  1124  	}
  1125  
  1126  	if ctx.GlobalIsSet(VCPasswordFlag.Name) {
  1127  		cfg.VcPassword = ctx.GlobalString(VCPasswordFlag.Name)
  1128  	}
  1129  
  1130  }
  1131  
  1132  // checkExclusive verifies that only a single instance of the provided flags was
  1133  // set by the user. Each flag might optionally be followed by a string type to
  1134  // specialize it further.
  1135  func checkExclusive(ctx *cli.Context, args ...interface{}) {
  1136  	set := make([]string, 0, 1)
  1137  	for i := 0; i < len(args); i++ {
  1138  		// Make sure the next argument is a flag and skip if not set
  1139  		flag, ok := args[i].(cli.Flag)
  1140  		if !ok {
  1141  			panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i]))
  1142  		}
  1143  		// Check if next arg extends current and expand its name if so
  1144  		name := flag.GetName()
  1145  
  1146  		if i+1 < len(args) {
  1147  			switch option := args[i+1].(type) {
  1148  			case string:
  1149  				// Extended flag, expand the name and shift the arguments
  1150  				if ctx.GlobalString(flag.GetName()) == option {
  1151  					name += "=" + option
  1152  				}
  1153  				i++
  1154  
  1155  			case cli.Flag:
  1156  			default:
  1157  				panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1]))
  1158  			}
  1159  		}
  1160  		// Mark the flag if it's set
  1161  		if ctx.GlobalIsSet(flag.GetName()) {
  1162  			set = append(set, "--"+name)
  1163  		}
  1164  	}
  1165  	if len(set) > 1 {
  1166  		Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", "))
  1167  	}
  1168  }
  1169  
  1170  // SetShhConfig applies shh-related command line flags to the config.
  1171  func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
  1172  	if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) {
  1173  		cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name))
  1174  	}
  1175  	if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) {
  1176  		cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name)
  1177  	}
  1178  	if ctx.GlobalIsSet(WhisperRestrictConnectionBetweenLightClientsFlag.Name) {
  1179  		cfg.RestrictConnectionBetweenLightClients = true
  1180  	}
  1181  }
  1182  
  1183  // SetEthConfig applies eth-related command line flags to the config.
  1184  func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
  1185  	// Avoid conflicting network flags
  1186  	checkExclusive(ctx, DeveloperFlag, TestnetFlag, BetanetFlag, InnerTestnetFlag, InnerDevnetFlag)
  1187  	checkExclusive(ctx, LightServFlag, SyncModeFlag, "light")
  1188  
  1189  	ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
  1190  	setEtherbase(ctx, ks, cfg)
  1191  	setGPO(ctx, &cfg.GPO)
  1192  	setTxPool(ctx, &cfg.TxPool)
  1193  	// for mpc compute
  1194  	setMpcPool(ctx, &cfg.MPCPool)
  1195  	setVcPool(ctx, &cfg.VCPool)
  1196  
  1197  	if ctx.GlobalIsSet(SyncModeFlag.Name) {
  1198  		cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
  1199  	}
  1200  	if ctx.GlobalIsSet(LightServFlag.Name) {
  1201  		cfg.LightServ = ctx.GlobalInt(LightServFlag.Name)
  1202  	}
  1203  	if ctx.GlobalIsSet(LightPeersFlag.Name) {
  1204  		cfg.LightPeers = ctx.GlobalInt(LightPeersFlag.Name)
  1205  	}
  1206  	if ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1207  		cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
  1208  	}
  1209  
  1210  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
  1211  		cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1212  	}
  1213  	cfg.DatabaseHandles = makeDatabaseHandles()
  1214  
  1215  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1216  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1217  	}
  1218  	cfg.NoPruning = /*ctx.GlobalString(GCModeFlag.Name) == "archive"*/ true
  1219  
  1220  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1221  		cfg.TrieCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1222  	}
  1223  	if ctx.GlobalIsSet(MinerNotifyFlag.Name) {
  1224  		cfg.MinerNotify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",")
  1225  	}
  1226  	if ctx.GlobalIsSet(DocRootFlag.Name) {
  1227  		cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name)
  1228  	}
  1229  	if ctx.GlobalIsSet(MinerLegacyExtraDataFlag.Name) {
  1230  		cfg.MinerExtraData = []byte(ctx.GlobalString(MinerLegacyExtraDataFlag.Name))
  1231  	}
  1232  	if ctx.GlobalIsSet(MinerExtraDataFlag.Name) {
  1233  		cfg.MinerExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name))
  1234  	}
  1235  	if ctx.GlobalIsSet(MinerLegacyGasTargetFlag.Name) {
  1236  		cfg.MinerGasFloor = ctx.GlobalUint64(MinerLegacyGasTargetFlag.Name)
  1237  	}
  1238  	if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
  1239  		cfg.MinerGasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name)
  1240  	}
  1241  	if ctx.GlobalIsSet(MinerGasLimitFlag.Name) {
  1242  		cfg.MinerGasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name)
  1243  	}
  1244  	if ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
  1245  		cfg.MinerGasPrice = GlobalBig(ctx, MinerLegacyGasPriceFlag.Name)
  1246  	}
  1247  	if ctx.GlobalIsSet(MinerGasPriceFlag.Name) {
  1248  		cfg.MinerGasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name)
  1249  	}
  1250  	if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) {
  1251  		cfg.MinerRecommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
  1252  	}
  1253  	if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) {
  1254  		cfg.MinerNoverify = ctx.Bool(MinerNoVerfiyFlag.Name)
  1255  	}
  1256  	if ctx.GlobalIsSet(VMEnableDebugFlag.Name) {
  1257  		// TODO(fjl): force-enable this in --dev mode
  1258  		cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
  1259  	}
  1260  
  1261  	if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
  1262  		cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
  1263  	}
  1264  
  1265  	if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
  1266  		cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
  1267  	}
  1268  
  1269  	// TODO inner time
  1270  	if ctx.GlobalIsSet(InnerTimeFlag.Name) {
  1271  		InnerTimeFlag.Value = ctx.GlobalUint64(InnerTimeFlag.Name)
  1272  	}
  1273  
  1274  	// Override any default configs for hard coded networks.
  1275  	switch {
  1276  	case ctx.GlobalBool(TestnetFlag.Name):
  1277  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1278  			cfg.NetworkId = 103
  1279  		}
  1280  		cfg.Genesis = core.DefaultTestnetGenesisBlock()
  1281  	case ctx.GlobalBool(BetanetFlag.Name):
  1282  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1283  			cfg.NetworkId = 104
  1284  		}
  1285  		cfg.Genesis = core.DefaultBetanetGenesisBlock()
  1286  	case ctx.GlobalBool(InnerTestnetFlag.Name):
  1287  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1288  			cfg.NetworkId = 203
  1289  		}
  1290  		cfg.Genesis = core.DefaultInnerTestnetGenesisBlock(InnerTimeFlag.Value)
  1291  	case ctx.GlobalBool(InnerDevnetFlag.Name):
  1292  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1293  			cfg.NetworkId = 204
  1294  		}
  1295  		cfg.Genesis = core.DefaultInnerDevnetGenesisBlock(InnerTimeFlag.Value)
  1296  	case ctx.GlobalBool(DeveloperFlag.Name):
  1297  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1298  			cfg.NetworkId = 1337
  1299  		}
  1300  		// Create new developer account or reuse existing one
  1301  		var (
  1302  			developer accounts.Account
  1303  			err       error
  1304  		)
  1305  		if accs := ks.Accounts(); len(accs) > 0 {
  1306  			developer = ks.Accounts()[0]
  1307  		} else {
  1308  			developer, err = ks.NewAccount("")
  1309  			if err != nil {
  1310  				Fatalf("Failed to create developer account: %v", err)
  1311  			}
  1312  		}
  1313  		if err := ks.Unlock(developer, ""); err != nil {
  1314  			Fatalf("Failed to unlock developer account: %v", err)
  1315  		}
  1316  		log.Info("Using developer account", "address", developer.Address)
  1317  
  1318  		cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
  1319  		if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
  1320  			cfg.MinerGasPrice = big.NewInt(1)
  1321  		}
  1322  	}
  1323  	// TODO(fjl): move trie cache generations into config
  1324  	if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
  1325  		state.MaxTrieCacheGen = uint16(gen)
  1326  	}
  1327  }
  1328  
  1329  // SetDashboardConfig applies dashboard related command line flags to the config.
  1330  func SetDashboardConfig(ctx *cli.Context, cfg *dashboard.Config) {
  1331  	cfg.Host = ctx.GlobalString(DashboardAddrFlag.Name)
  1332  	cfg.Port = ctx.GlobalInt(DashboardPortFlag.Name)
  1333  	cfg.Refresh = ctx.GlobalDuration(DashboardRefreshFlag.Name)
  1334  }
  1335  
  1336  // RegisterEthService adds an Ethereum client to the stack.
  1337  func RegisterEthService(stack *node.Node, cfg *eth.Config) {
  1338  	var err error
  1339  	if cfg.SyncMode == downloader.LightSync {
  1340  		err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1341  			return les.New(ctx, cfg)
  1342  		})
  1343  	} else {
  1344  		err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1345  			fullNode, err := eth.New(ctx, cfg)
  1346  			if fullNode != nil && cfg.LightServ > 0 {
  1347  				ls, _ := les.NewLesServer(fullNode, cfg)
  1348  				fullNode.AddLesServer(ls)
  1349  			}
  1350  			return fullNode, err
  1351  		})
  1352  	}
  1353  	if err != nil {
  1354  		Fatalf("Failed to register the Ethereum service: %v", err)
  1355  	}
  1356  }
  1357  
  1358  // RegisterDashboardService adds a dashboard to the stack.
  1359  func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
  1360  	stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1361  		return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil
  1362  	})
  1363  }
  1364  
  1365  // RegisterShhService configures Whisper and adds it to the given node.
  1366  func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
  1367  	if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
  1368  		return whisper.New(cfg), nil
  1369  	}); err != nil {
  1370  		Fatalf("Failed to register the Whisper service: %v", err)
  1371  	}
  1372  }
  1373  
  1374  // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
  1375  // the given node.
  1376  func RegisterEthStatsService(stack *node.Node, url string) {
  1377  	if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1378  		// Retrieve both eth and les services
  1379  		var ethServ *eth.Ethereum
  1380  		ctx.Service(&ethServ)
  1381  
  1382  		var lesServ *les.LightEthereum
  1383  		ctx.Service(&lesServ)
  1384  
  1385  		return ethstats.New(url, ethServ, lesServ)
  1386  	}); err != nil {
  1387  		Fatalf("Failed to register the Ethereum Stats service: %v", err)
  1388  	}
  1389  }
  1390  
  1391  func SetupMetrics(ctx *cli.Context) {
  1392  	if metrics.Enabled {
  1393  		log.Info("Enabling metrics collection")
  1394  		var (
  1395  			enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
  1396  			endpoint     = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
  1397  			database     = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
  1398  			username     = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
  1399  			password     = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
  1400  			hosttag      = ctx.GlobalString(MetricsInfluxDBHostTagFlag.Name)
  1401  		)
  1402  
  1403  		if enableExport {
  1404  			log.Info("Enabling metrics export to InfluxDB")
  1405  			go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "platon.", map[string]string{
  1406  				"host": hosttag,
  1407  			})
  1408  		}
  1409  	}
  1410  }
  1411  
  1412  // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
  1413  func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
  1414  	var (
  1415  		cache   = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1416  		handles = makeDatabaseHandles()
  1417  	)
  1418  	name := "chaindata"
  1419  	if ctx.GlobalString(SyncModeFlag.Name) == "light" {
  1420  		name = "lightchaindata"
  1421  	}
  1422  	chainDb, err := stack.OpenDatabase(name, cache, handles)
  1423  	if err != nil {
  1424  		Fatalf("Could not open database: %v", err)
  1425  	}
  1426  	return chainDb
  1427  }
  1428  
  1429  func MakeGenesis(ctx *cli.Context) *core.Genesis {
  1430  	var genesis *core.Genesis
  1431  	switch {
  1432  	case ctx.GlobalBool(TestnetFlag.Name):
  1433  		genesis = core.DefaultTestnetGenesisBlock()
  1434  	case ctx.GlobalBool(BetanetFlag.Name):
  1435  		genesis = core.DefaultBetanetGenesisBlock()
  1436  	case ctx.GlobalBool(InnerTestnetFlag.Name):
  1437  		genesis = core.DefaultInnerTestnetGenesisBlock(InnerTimeFlag.Value)
  1438  	case ctx.GlobalBool(InnerDevnetFlag.Name):
  1439  		genesis = core.DefaultInnerDevnetGenesisBlock(InnerTimeFlag.Value)
  1440  	case ctx.GlobalBool(DeveloperFlag.Name):
  1441  		Fatalf("Developer chains are ephemeral")
  1442  	}
  1443  	return genesis
  1444  }
  1445  
  1446  // MakeChain creates a chain manager from set command line flags.
  1447  func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
  1448  	var err error
  1449  	chainDb = MakeChainDatabase(ctx, stack)
  1450  
  1451  	config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
  1452  	if err != nil {
  1453  		Fatalf("%v", err)
  1454  	}
  1455  	var engine consensus.Engine
  1456  
  1457  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1458  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1459  	}
  1460  	cache := &core.CacheConfig{
  1461  		Disabled:/*ctx.GlobalString(GCModeFlag.Name) == "archive"*/ true,
  1462  		TrieNodeLimit: eth.DefaultConfig.TrieCache,
  1463  		TrieTimeLimit: eth.DefaultConfig.TrieTimeout,
  1464  	}
  1465  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1466  		cache.TrieNodeLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1467  	}
  1468  	vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
  1469  	chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil)
  1470  	if err != nil {
  1471  		Fatalf("Can't create BlockChain: %v", err)
  1472  	}
  1473  	return chain, chainDb
  1474  }
  1475  
  1476  // MakeConsolePreloads retrieves the absolute paths for the console JavaScript
  1477  // scripts to preload before starting.
  1478  func MakeConsolePreloads(ctx *cli.Context) []string {
  1479  	// Skip preloading if there's nothing to preload
  1480  	if ctx.GlobalString(PreloadJSFlag.Name) == "" {
  1481  		return nil
  1482  	}
  1483  	// Otherwise resolve absolute paths and return them
  1484  	preloads := []string{}
  1485  
  1486  	assets := ctx.GlobalString(JSpathFlag.Name)
  1487  	for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") {
  1488  		preloads = append(preloads, common.AbsolutePath(assets, strings.TrimSpace(file)))
  1489  	}
  1490  	return preloads
  1491  }
  1492  
  1493  // MigrateFlags sets the global flag from a local flag when it's set.
  1494  // This is a temporary function used for migrating old command/flags to the
  1495  // new format.
  1496  //
  1497  // e.g. platon account new --keystore /tmp/mykeystore --lightkdf
  1498  //
  1499  // is equivalent after calling this method with:
  1500  //
  1501  // platon --keystore /tmp/mykeystore --lightkdf account new
  1502  //
  1503  // This allows the use of the existing configuration functionality.
  1504  // When all flags are migrated this function can be removed and the existing
  1505  // configuration functionality must be changed that is uses local flags
  1506  func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error {
  1507  	return func(ctx *cli.Context) error {
  1508  		for _, name := range ctx.FlagNames() {
  1509  			if ctx.IsSet(name) {
  1510  				ctx.GlobalSet(name, ctx.String(name))
  1511  			}
  1512  		}
  1513  		return action(ctx)
  1514  	}
  1515  }