github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/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 intchain commands.
    18  package utils
    19  
    20  import (
    21  	"crypto/ecdsa"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"strconv"
    27  	"strings"
    28  
    29  	"github.com/intfoundation/intchain/accounts"
    30  	"github.com/intfoundation/intchain/accounts/keystore"
    31  	"github.com/intfoundation/intchain/common"
    32  	"github.com/intfoundation/intchain/common/fdlimit"
    33  	"github.com/intfoundation/intchain/consensus"
    34  	"github.com/intfoundation/intchain/core"
    35  	"github.com/intfoundation/intchain/core/vm"
    36  	"github.com/intfoundation/intchain/crypto"
    37  	"github.com/intfoundation/intchain/intdb"
    38  	"github.com/intfoundation/intchain/intprotocol"
    39  	"github.com/intfoundation/intchain/intprotocol/downloader"
    40  	"github.com/intfoundation/intchain/intprotocol/gasprice"
    41  	"github.com/intfoundation/intchain/log"
    42  	"github.com/intfoundation/intchain/metrics"
    43  	"github.com/intfoundation/intchain/node"
    44  	"github.com/intfoundation/intchain/p2p"
    45  	"github.com/intfoundation/intchain/p2p/discover"
    46  	"github.com/intfoundation/intchain/p2p/nat"
    47  	"github.com/intfoundation/intchain/p2p/netutil"
    48  	"github.com/intfoundation/intchain/params"
    49  	"gopkg.in/urfave/cli.v1"
    50  
    51  	// import tendermint config
    52  	cfg "github.com/intfoundation/go-config"
    53  	tmcfg "github.com/intfoundation/intchain/consensus/ipbft/config/tendermint"
    54  )
    55  
    56  var (
    57  	CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} [arguments...]
    58  {{if .cmd.Description}}{{.cmd.Description}}
    59  {{end}}{{if .cmd.Subcommands}}
    60  SUBCOMMANDS:
    61  	{{range .cmd.Subcommands}}{{.cmd.Name}}{{with .cmd.ShortName}}, {{.cmd}}{{end}}{{ "\t" }}{{.cmd.Usage}}
    62  	{{end}}{{end}}{{if .categorizedFlags}}
    63  {{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS:
    64  {{range $categorized.Flags}}{{"\t"}}{{.}}
    65  {{end}}
    66  {{end}}{{end}}`
    67  )
    68  
    69  func init() {
    70  	cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
    71  
    72  VERSION:
    73     {{.Version}}
    74  
    75  COMMANDS:
    76     {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
    77     {{end}}{{if .Flags}}
    78  GLOBAL OPTIONS:
    79     {{range .Flags}}{{.}}
    80     {{end}}{{end}}
    81  `
    82  
    83  	cli.CommandHelpTemplate = CommandHelpTemplate
    84  }
    85  
    86  // NewApp creates an app with sane defaults.
    87  func NewApp(gitCommit, usage string) *cli.App {
    88  	app := cli.NewApp()
    89  	app.Name = filepath.Base(os.Args[0])
    90  	app.Author = ""
    91  	//app.Authors = nil
    92  	app.Email = ""
    93  	app.Version = params.Version
    94  	if len(gitCommit) >= 8 {
    95  		app.Version += "-" + gitCommit[:8]
    96  	}
    97  	app.Usage = usage
    98  	return app
    99  }
   100  
   101  // These are all the command line flags we support.
   102  // If you add to this list, please remember to include the
   103  // flag in the appropriate command definition.
   104  //
   105  // The flags are defined here so their names and help texts
   106  // are the same for all commands.
   107  
   108  var (
   109  	// General settings
   110  	DataDirFlag = DirectoryFlag{
   111  		Name:  "datadir",
   112  		Usage: "Data directory for the databases and keystore",
   113  		Value: DirectoryString{node.DefaultDataDir()},
   114  	}
   115  	KeyStoreDirFlag = DirectoryFlag{
   116  		Name:  "keystore",
   117  		Usage: "Directory for the keystore (default = inside the datadir)",
   118  	}
   119  	NoUSBFlag = cli.BoolFlag{
   120  		Name:  "nousb",
   121  		Usage: "Disables monitoring for and managing USB hardware wallets",
   122  	}
   123  	NetworkIdFlag = cli.Uint64Flag{
   124  		Name:  "networkid",
   125  		Usage: "Network identifier (integer, mainnet=2047, testnet=2048)",
   126  		Value: intprotocol.DefaultConfig.NetworkId,
   127  	}
   128  	TestnetFlag = cli.BoolFlag{
   129  		Name:  "testnet",
   130  		Usage: "Test network",
   131  	}
   132  
   133  	DeveloperFlag = cli.BoolFlag{
   134  		Name:  "dev",
   135  		Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
   136  	}
   137  
   138  	IdentityFlag = cli.StringFlag{
   139  		Name:  "identity",
   140  		Usage: "Custom node name",
   141  	}
   142  	DocRootFlag = DirectoryFlag{
   143  		Name:  "docroot",
   144  		Usage: "Document Root for HTTPClient file scheme",
   145  		Value: DirectoryString{homeDir()},
   146  	}
   147  	FastSyncFlag = cli.BoolFlag{
   148  		Name:  "fast",
   149  		Usage: "Enable fast syncing through state downloads",
   150  	}
   151  
   152  	defaultSyncMode = intprotocol.DefaultConfig.SyncMode
   153  	SyncModeFlag    = TextMarshalerFlag{
   154  		Name: "syncmode",
   155  		//Usage: `Blockchain sync mode ("fast", "full", or "light")`,
   156  		Usage: `Blockchain sync mode ("full")`,
   157  		Value: &defaultSyncMode,
   158  	}
   159  	GCModeFlag = cli.StringFlag{
   160  		Name:  "gcmode",
   161  		Usage: `Blockchain garbage collection mode ("full", "archive")`,
   162  		Value: "archive",
   163  	}
   164  
   165  	// Transaction pool settings
   166  	TxPoolNoLocalsFlag = cli.BoolFlag{
   167  		Name:  "txpool.nolocals",
   168  		Usage: "Disables price exemptions for locally submitted transactions",
   169  	}
   170  	TxPoolJournalFlag = cli.StringFlag{
   171  		Name:  "txpool.journal",
   172  		Usage: "Disk journal for local transaction to survive node restarts",
   173  		Value: core.DefaultTxPoolConfig.Journal,
   174  	}
   175  	TxPoolRejournalFlag = cli.DurationFlag{
   176  		Name:  "txpool.rejournal",
   177  		Usage: "Time interval to regenerate the local transaction journal",
   178  		Value: core.DefaultTxPoolConfig.Rejournal,
   179  	}
   180  	TxPoolPriceLimitFlag = cli.Uint64Flag{
   181  		Name:  "txpool.pricelimit",
   182  		Usage: "Minimum gas price limit to enforce for acceptance into the pool",
   183  		Value: intprotocol.DefaultConfig.TxPool.PriceLimit,
   184  	}
   185  	TxPoolPriceBumpFlag = cli.Uint64Flag{
   186  		Name:  "txpool.pricebump",
   187  		Usage: "Price bump percentage to replace an already existing transaction",
   188  		Value: intprotocol.DefaultConfig.TxPool.PriceBump,
   189  	}
   190  	TxPoolAccountSlotsFlag = cli.Uint64Flag{
   191  		Name:  "txpool.accountslots",
   192  		Usage: "Minimum number of executable transaction slots guaranteed per account",
   193  		Value: intprotocol.DefaultConfig.TxPool.AccountSlots,
   194  	}
   195  	TxPoolGlobalSlotsFlag = cli.Uint64Flag{
   196  		Name:  "txpool.globalslots",
   197  		Usage: "Maximum number of executable transaction slots for all accounts",
   198  		Value: intprotocol.DefaultConfig.TxPool.GlobalSlots,
   199  	}
   200  	TxPoolAccountQueueFlag = cli.Uint64Flag{
   201  		Name:  "txpool.accountqueue",
   202  		Usage: "Maximum number of non-executable transaction slots permitted per account",
   203  		Value: intprotocol.DefaultConfig.TxPool.AccountQueue,
   204  	}
   205  	TxPoolGlobalQueueFlag = cli.Uint64Flag{
   206  		Name:  "txpool.globalqueue",
   207  		Usage: "Maximum number of non-executable transaction slots for all accounts",
   208  		Value: intprotocol.DefaultConfig.TxPool.GlobalQueue,
   209  	}
   210  	TxPoolLifetimeFlag = cli.DurationFlag{
   211  		Name:  "txpool.lifetime",
   212  		Usage: "Maximum amount of time non-executable transaction are queued",
   213  		Value: intprotocol.DefaultConfig.TxPool.Lifetime,
   214  	}
   215  	// Performance tuning settings
   216  	CacheFlag = cli.IntFlag{
   217  		Name:  "cache",
   218  		Usage: "Megabytes of memory allocated to internal caching",
   219  		Value: 1024,
   220  	}
   221  	CacheDatabaseFlag = cli.IntFlag{
   222  		Name:  "cache.database",
   223  		Usage: "Percentage of cache memory allowance to use for database io",
   224  		Value: 50,
   225  	}
   226  	CacheTrieFlag = cli.IntFlag{
   227  		Name:  "cache.trie",
   228  		Usage: "Percentage of cache memory allowance to use for trie caching (default = 25% full mode, 50% archive mode)",
   229  		Value: 25,
   230  	}
   231  	CacheGCFlag = cli.IntFlag{
   232  		Name:  "cache.gc",
   233  		Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)",
   234  		Value: 25,
   235  	}
   236  	// Miner settings
   237  	MiningEnabledFlag = cli.BoolFlag{
   238  		Name:  "mine",
   239  		Usage: "Enable mining",
   240  	}
   241  	MinerThreadsFlag = cli.IntFlag{
   242  		Name:  "miner.threads",
   243  		Usage: "Number of CPU threads to use for mining",
   244  		Value: 0,
   245  	}
   246  	MinerGasTargetFlag = cli.Uint64Flag{
   247  		Name:  "miner.gastarget",
   248  		Usage: "Target gas floor for mined blocks",
   249  		Value: intprotocol.DefaultConfig.MinerGasFloor,
   250  	}
   251  	MinerGasLimitFlag = cli.Uint64Flag{
   252  		Name:  "miner.gaslimit",
   253  		Usage: "Target gas ceiling for mined blocks",
   254  		Value: intprotocol.DefaultConfig.MinerGasCeil,
   255  	}
   256  	MinerGasPriceFlag = BigFlag{
   257  		Name:  "miner.gasprice",
   258  		Usage: "Minimal gas price for mining a transactions",
   259  		Value: intprotocol.DefaultConfig.MinerGasPrice,
   260  	}
   261  	MinerCoinbaseFlag = cli.StringFlag{
   262  		Name:  "miner.etherbase",
   263  		Usage: "Public address for block mining rewards (default = first account)",
   264  		Value: "0",
   265  	}
   266  	ExtraDataFlag = cli.StringFlag{
   267  		Name:  "extradata",
   268  		Usage: "Block extra data set by the miner (default = client version)",
   269  	}
   270  	// Account settings
   271  	UnlockedAccountFlag = cli.StringFlag{
   272  		Name:  "unlock",
   273  		Usage: "Comma separated list of accounts to unlock",
   274  		Value: "",
   275  	}
   276  	PasswordFileFlag = cli.StringFlag{
   277  		Name:  "password",
   278  		Usage: "Password file to use for non-interactive password input",
   279  		Value: "",
   280  	}
   281  
   282  	VMEnableDebugFlag = cli.BoolFlag{
   283  		Name:  "vmdebug",
   284  		Usage: "Record information useful for VM and contract debugging",
   285  	}
   286  	// Logging and debug settings
   287  	EthStatsURLFlag = cli.StringFlag{
   288  		Name:  "intstats",
   289  		Usage: "Reporting URL of a intstats service (nodename:secret@host:port)",
   290  	}
   291  	MetricsEnabledFlag = cli.BoolFlag{
   292  		Name:  metrics.MetricsEnabledFlag,
   293  		Usage: "Enable metrics collection and reporting",
   294  	}
   295  
   296  	NoCompactionFlag = cli.BoolFlag{
   297  		Name:  "nocompaction",
   298  		Usage: "Disables db compaction after import",
   299  	}
   300  	// RPC settings
   301  	RPCEnabledFlag = cli.BoolFlag{
   302  		Name:  "rpc",
   303  		Usage: "Enable the HTTP-RPC server",
   304  	}
   305  	RPCListenAddrFlag = cli.StringFlag{
   306  		Name:  "rpcaddr",
   307  		Usage: "HTTP-RPC server listening interface",
   308  		Value: node.DefaultHTTPHost,
   309  	}
   310  	RPCPortFlag = cli.IntFlag{
   311  		Name:  "rpcport",
   312  		Usage: "HTTP-RPC server listening port",
   313  		Value: node.DefaultHTTPPort,
   314  	}
   315  	RPCCORSDomainFlag = cli.StringFlag{
   316  		Name:  "rpccorsdomain",
   317  		Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
   318  		Value: "",
   319  	}
   320  	RPCVirtualHostsFlag = cli.StringFlag{
   321  		Name:  "rpcvhosts",
   322  		Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
   323  		Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
   324  	}
   325  	RPCApiFlag = cli.StringFlag{
   326  		Name:  "rpcapi",
   327  		Usage: "API's offered over the HTTP-RPC interface",
   328  		Value: "",
   329  	}
   330  	IPCDisabledFlag = cli.BoolFlag{
   331  		Name:  "ipcdisable",
   332  		Usage: "Disable the IPC-RPC server",
   333  	}
   334  	IPCPathFlag = DirectoryFlag{
   335  		Name:  "ipcpath",
   336  		Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)",
   337  	}
   338  	WSEnabledFlag = cli.BoolFlag{
   339  		Name:  "ws",
   340  		Usage: "Enable the WS-RPC server",
   341  	}
   342  	WSListenAddrFlag = cli.StringFlag{
   343  		Name:  "wsaddr",
   344  		Usage: "WS-RPC server listening interface",
   345  		Value: node.DefaultWSHost,
   346  	}
   347  	WSPortFlag = cli.IntFlag{
   348  		Name:  "wsport",
   349  		Usage: "WS-RPC server listening port",
   350  		Value: node.DefaultWSPort,
   351  	}
   352  	WSApiFlag = cli.StringFlag{
   353  		Name:  "wsapi",
   354  		Usage: "API is offered over the WS-RPC interface",
   355  		Value: "",
   356  	}
   357  	WSAllowedOriginsFlag = cli.StringFlag{
   358  		Name:  "wsorigins",
   359  		Usage: "Origins from which to accept websockets requests",
   360  		Value: "",
   361  	}
   362  	ExecFlag = cli.StringFlag{
   363  		Name:  "exec",
   364  		Usage: "Execute JavaScript statement",
   365  	}
   366  	PreloadJSFlag = cli.StringFlag{
   367  		Name:  "preload",
   368  		Usage: "Comma separated list of JavaScript files to preload into the console",
   369  	}
   370  
   371  	// Network Settings
   372  	MaxPeersFlag = cli.IntFlag{
   373  		Name:  "maxpeers",
   374  		Usage: "Maximum number of network peers (network disabled if set to 0)",
   375  		Value: 25,
   376  	}
   377  	MaxPendingPeersFlag = cli.IntFlag{
   378  		Name:  "maxpendpeers",
   379  		Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
   380  		Value: 0,
   381  	}
   382  	ListenPortFlag = cli.IntFlag{
   383  		Name:  "port",
   384  		Usage: "Network listening port",
   385  		Value: 8550,
   386  	}
   387  	BootnodesFlag = cli.StringFlag{
   388  		Name:  "bootnodes",
   389  		Usage: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)",
   390  		Value: "",
   391  	}
   392  	BootnodesV4Flag = cli.StringFlag{
   393  		Name:  "bootnodesv4",
   394  		Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)",
   395  		Value: "",
   396  	}
   397  	BootnodesV5Flag = cli.StringFlag{
   398  		Name:  "bootnodesv5",
   399  		Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)",
   400  		Value: "",
   401  	}
   402  	NodeKeyFileFlag = cli.StringFlag{
   403  		Name:  "nodekey",
   404  		Usage: "P2P node key file",
   405  	}
   406  	NodeKeyHexFlag = cli.StringFlag{
   407  		Name:  "nodekeyhex",
   408  		Usage: "P2P node key as hex (for testing)",
   409  	}
   410  	NATFlag = cli.StringFlag{
   411  		Name:  "nat",
   412  		Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
   413  		Value: "any",
   414  	}
   415  	NoDiscoverFlag = cli.BoolFlag{
   416  		Name:  "nodiscover",
   417  		Usage: "Disables the peer discovery mechanism (manual peer addition)",
   418  	}
   419  	DiscoveryV5Flag = cli.BoolFlag{
   420  		Name:  "v5disc",
   421  		Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
   422  	}
   423  	NetrestrictFlag = cli.StringFlag{
   424  		Name:  "netrestrict",
   425  		Usage: "Restricts network communication to the given IP networks (CIDR masks)",
   426  	}
   427  
   428  	// ATM the url is left to the user and deployment to
   429  	JSpathFlag = cli.StringFlag{
   430  		Name:  "jspath",
   431  		Usage: "JavaScript root path for `loadScript`",
   432  		Value: ".",
   433  	}
   434  
   435  	SolcPathFlag = cli.StringFlag{
   436  		Name:  "solc",
   437  		Usage: "Solidity compiler command to be used",
   438  		Value: "solc",
   439  	}
   440  
   441  	// Gas price oracle settings
   442  	GpoBlocksFlag = cli.IntFlag{
   443  		Name:  "gpoblocks",
   444  		Usage: "Number of recent blocks to check for gas prices",
   445  		Value: intprotocol.DefaultConfig.GPO.Blocks,
   446  	}
   447  	GpoPercentileFlag = cli.IntFlag{
   448  		Name:  "gpopercentile",
   449  		Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
   450  		Value: intprotocol.DefaultConfig.GPO.Percentile,
   451  	}
   452  
   453  	// Data Reduction Flag
   454  	PruneFlag = cli.BoolFlag{
   455  		Name:  "prune",
   456  		Usage: "Enable the Data Reduction feature, history state data will be pruned by default",
   457  	}
   458  
   459  	//for performance test
   460  	PerfTestFlag = cli.BoolFlag{
   461  		Name:  "perftest",
   462  		Usage: "Whether doing performance test, will remove some limitations and cause system more frigile",
   463  	}
   464  
   465  	// ----------------------------
   466  	// IntChain Flags
   467  
   468  	// Log Folder
   469  	//LogDirFlag = DirectoryFlag{
   470  	//	Name:  "logDir",
   471  	//	Usage: "IntChain Log Data directory",
   472  	//	Value: DirectoryString{"log"},
   473  	//}
   474  
   475  	// Child Chain Flag
   476  	ChildChainFlag = cli.StringFlag{
   477  		Name:  "childChain",
   478  		Usage: "Specify one or more child chain should be start. Ex: child-1,child-2",
   479  	}
   480  
   481  	// ----------------------------
   482  	// Tendermint Flags
   483  
   484  	MonikerFlag = cli.StringFlag{
   485  		Name:  "moniker",
   486  		Value: "",
   487  		Usage: "Node's moniker",
   488  	}
   489  
   490  	NodeLaddrFlag = cli.StringFlag{
   491  		Name:  "node_laddr",
   492  		Value: "tcp://0.0.0.0:46656",
   493  		Usage: "Node listen address. (0.0.0.0:0 means any interface, any port)",
   494  	}
   495  
   496  	SeedsFlag = cli.StringFlag{
   497  		Name:  "seeds",
   498  		Value: "",
   499  		Usage: "Comma delimited host:port seed nodes",
   500  	}
   501  
   502  	//FastSyncFlag = cli.BoolFlag{
   503  	//	Name:  "fast_sync",
   504  	//	Usage: "Fast blockchain syncing",
   505  	//}
   506  
   507  	SkipUpnpFlag = cli.BoolFlag{
   508  		Name:  "skip_upnp",
   509  		Usage: "Skip UPNP configuration",
   510  	}
   511  
   512  	RpcLaddrFlag = cli.StringFlag{
   513  		Name:  "rpc_laddr",
   514  		Value: "unix://@intchainrpcunixsock", //"tcp://0.0.0.0:46657",
   515  		Usage: "RPC listen address. Port required",
   516  	}
   517  
   518  	AddrFlag = cli.StringFlag{
   519  		Name:  "addr",
   520  		Value: "unix://@intchainappunixsock", //"tcp://0.0.0.0:46658",
   521  		Usage: "TMSP app listen address",
   522  	}
   523  
   524  	// Flags holds all command-line flags required for debugging.
   525  	//DebugFlags = []cli.Flag{
   526  	//	verbosityFlag, vmoduleFlag, backtraceAtFlag, debugFlag,
   527  	//	pprofFlag, pprofAddrFlag, pprofPortFlag,
   528  	//	memprofilerateFlag, blockprofilerateFlag, cpuprofileFlag, traceFlag,
   529  	//}
   530  
   531  	//from debug module
   532  	//verbosityFlag = cli.IntFlag{
   533  	//	Name:  "verbosity",
   534  	//	Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
   535  	//	Value: 3,
   536  	//}
   537  	//vmoduleFlag = cli.StringFlag{
   538  	//	Name:  "vmodule",
   539  	//	Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,intp2p=4)",
   540  	//	Value: "",
   541  	//}
   542  	//backtraceAtFlag = cli.StringFlag{
   543  	//	Name:  "backtrace",
   544  	//	Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")",
   545  	//	Value: "",
   546  	//}
   547  	//debugFlag = cli.BoolFlag{
   548  	//	Name:  "debug",
   549  	//	Usage: "Prepends log messages with call-site location (file and line number)",
   550  	//}
   551  	//pprofFlag = cli.BoolFlag{
   552  	//	Name:  "pprof",
   553  	//	Usage: "Enable the pprof HTTP server",
   554  	//}
   555  	//pprofPortFlag = cli.IntFlag{
   556  	//	Name:  "pprofport",
   557  	//	Usage: "pprof HTTP server listening port",
   558  	//	Value: 6060,
   559  	//}
   560  	//pprofAddrFlag = cli.StringFlag{
   561  	//	Name:  "pprofaddr",
   562  	//	Usage: "pprof HTTP server listening interface",
   563  	//	Value: "127.0.0.1",
   564  	//}
   565  	//memprofilerateFlag = cli.IntFlag{
   566  	//	Name:  "memprofilerate",
   567  	//	Usage: "Turn on memory profiling with the given rate",
   568  	//	Value: runtime.MemProfileRate,
   569  	//}
   570  	//blockprofilerateFlag = cli.IntFlag{
   571  	//	Name:  "blockprofilerate",
   572  	//	Usage: "Turn on block profiling with the given rate",
   573  	//}
   574  	//cpuprofileFlag = cli.StringFlag{
   575  	//	Name:  "cpuprofile",
   576  	//	Usage: "Write CPU profile to the given file",
   577  	//}
   578  	//traceFlag = cli.StringFlag{
   579  	//	Name:  "trace",
   580  	//	Usage: "Write execution trace to the given file",
   581  	//}
   582  )
   583  
   584  // MakeDataDir retrieves the currently requested data directory, terminating
   585  // if none (or the empty string) is specified. If the node is starting a testnet,
   586  // the a subdirectory of the specified datadir will be used.
   587  func MakeDataDir(ctx *cli.Context) string {
   588  	if path := ctx.GlobalString(DataDirFlag.Name); path != "" {
   589  		return path
   590  	}
   591  	Fatalf("Cannot determine default data directory, please set manually (--datadir)")
   592  	return ""
   593  }
   594  
   595  // setNodeKey creates a node key from set command line flags, either loading it
   596  // from a file or as a specified hex value. If neither flags were provided, this
   597  // method returns nil and an emphemeral key is to be generated.
   598  func setNodeKey(ctx *cli.Context, cfg *p2p.Config) {
   599  	var (
   600  		hex  = ctx.GlobalString(NodeKeyHexFlag.Name)
   601  		file = ctx.GlobalString(NodeKeyFileFlag.Name)
   602  		key  *ecdsa.PrivateKey
   603  		err  error
   604  	)
   605  	switch {
   606  	case file != "" && hex != "":
   607  		Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
   608  	case file != "":
   609  		if key, err = crypto.LoadECDSA(file); err != nil {
   610  			Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
   611  		}
   612  		cfg.PrivateKey = key
   613  	case hex != "":
   614  		if key, err = crypto.HexToECDSA(hex); err != nil {
   615  			Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
   616  		}
   617  		cfg.PrivateKey = key
   618  	}
   619  }
   620  
   621  // setNodeUserIdent creates the user identifier from CLI flags.
   622  func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
   623  	if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 {
   624  		cfg.UserIdent = identity
   625  	}
   626  }
   627  
   628  // setBootstrapNodes creates a list of bootstrap nodes from the command line
   629  // flags, reverting to pre-configured ones if none have been specified.
   630  func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
   631  	urls := params.MainnetBootnodes
   632  	switch {
   633  	case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name):
   634  		if ctx.GlobalIsSet(BootnodesV4Flag.Name) {
   635  			urls = strings.Split(ctx.GlobalString(BootnodesV4Flag.Name), ",")
   636  		} else {
   637  			urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
   638  		}
   639  	case ctx.GlobalBool(TestnetFlag.Name):
   640  		urls = params.TestnetBootnodes
   641  	case cfg.BootstrapNodes != nil:
   642  		return // already set, don't apply defaults.
   643  	}
   644  
   645  	cfg.BootstrapNodes = make([]*discover.Node, 0, len(urls))
   646  	for _, url := range urls {
   647  		node, err := discover.ParseNode(url)
   648  		if err != nil {
   649  			log.Error("Bootstrap URL invalid", "enode", url, "err", err)
   650  			continue
   651  		}
   652  		cfg.BootstrapNodes = append(cfg.BootstrapNodes, node)
   653  	}
   654  }
   655  
   656  // setBootstrapNodesV5 creates a list of bootstrap nodes from the command line
   657  // flags, reverting to pre-configured ones if none have been specified.
   658  //func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
   659  //	urls := params.DiscoveryV5Bootnodes
   660  //	switch {
   661  //	case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name):
   662  //		if ctx.GlobalIsSet(BootnodesV5Flag.Name) {
   663  //			urls = strings.Split(ctx.GlobalString(BootnodesV5Flag.Name), ",")
   664  //		} else {
   665  //			urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
   666  //		}
   667  //	case cfg.BootstrapNodesV5 != nil:
   668  //		return // already set, don't apply defaults.
   669  //	}
   670  //
   671  //	cfg.BootstrapNodesV5 = make([]*discv5.Node, 0, len(urls))
   672  //	for _, url := range urls {
   673  //		node, err := discv5.ParseNode(url)
   674  //		if err != nil {
   675  //			log.Error("Bootstrap URL invalid", "enode", url, "err", err)
   676  //			continue
   677  //		}
   678  //		cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node)
   679  //	}
   680  //}
   681  
   682  // setListenAddress creates a TCP listening address string from set command
   683  // line flags.
   684  func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
   685  	if ctx.GlobalIsSet(ListenPortFlag.Name) {
   686  		cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name))
   687  	}
   688  }
   689  
   690  // setNAT creates a port mapper from command line flags.
   691  func setNAT(ctx *cli.Context, cfg *p2p.Config) {
   692  	if ctx.GlobalIsSet(NATFlag.Name) {
   693  		natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
   694  		if err != nil {
   695  			Fatalf("Option %s: %v", NATFlag.Name, err)
   696  		}
   697  		cfg.NAT = natif
   698  	}
   699  }
   700  
   701  // splitAndTrim splits input separated by a comma
   702  // and trims excessive white space from the substrings.
   703  func splitAndTrim(input string) []string {
   704  	result := strings.Split(input, ",")
   705  	for i, r := range result {
   706  		result[i] = strings.TrimSpace(r)
   707  	}
   708  	return result
   709  }
   710  
   711  // setHTTP creates the HTTP RPC listener interface string from the set
   712  // command line flags, returning empty if the HTTP endpoint is disabled.
   713  func SetHTTP(ctx *cli.Context, cfg *node.Config) {
   714  	if ctx.GlobalBool(RPCEnabledFlag.Name) && cfg.HTTPHost == "" {
   715  		cfg.HTTPHost = "127.0.0.1"
   716  		if ctx.GlobalIsSet(RPCListenAddrFlag.Name) {
   717  			cfg.HTTPHost = ctx.GlobalString(RPCListenAddrFlag.Name)
   718  		}
   719  	}
   720  
   721  	if ctx.GlobalIsSet(RPCPortFlag.Name) {
   722  		cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name)
   723  	}
   724  	if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) {
   725  		cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name))
   726  	}
   727  	if ctx.GlobalIsSet(RPCApiFlag.Name) {
   728  		cfg.HTTPModules = splitAndTrim(ctx.GlobalString(RPCApiFlag.Name))
   729  	}
   730  	if ctx.GlobalIsSet(RPCVirtualHostsFlag.Name) {
   731  		cfg.HTTPVirtualHosts = splitAndTrim(ctx.GlobalString(RPCVirtualHostsFlag.Name))
   732  	}
   733  }
   734  
   735  // setWS creates the WebSocket RPC listener interface string from the set
   736  // command line flags, returning empty if the HTTP endpoint is disabled.
   737  func SetWS(ctx *cli.Context, cfg *node.Config) {
   738  	if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" {
   739  		cfg.WSHost = "127.0.0.1"
   740  		if ctx.GlobalIsSet(WSListenAddrFlag.Name) {
   741  			cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name)
   742  		}
   743  	}
   744  
   745  	if ctx.GlobalIsSet(WSPortFlag.Name) {
   746  		cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name)
   747  	}
   748  	if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) {
   749  		cfg.WSOrigins = splitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name))
   750  	}
   751  	if ctx.GlobalIsSet(WSApiFlag.Name) {
   752  		cfg.WSModules = splitAndTrim(ctx.GlobalString(WSApiFlag.Name))
   753  	}
   754  }
   755  
   756  // setIPC creates an IPC path configuration from the set command line flags,
   757  // returning an empty string if IPC was explicitly disabled, or the set path.
   758  func setIPC(ctx *cli.Context, cfg *node.Config) {
   759  	checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
   760  	switch {
   761  	case ctx.GlobalBool(IPCDisabledFlag.Name):
   762  		cfg.IPCPath = ""
   763  	case ctx.GlobalIsSet(IPCPathFlag.Name):
   764  		cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name)
   765  	}
   766  }
   767  
   768  // makeDatabaseHandles raises out the number of allowed file handles per process
   769  // for Geth and returns half of the allowance to assign to the database.
   770  func makeDatabaseHandles() int {
   771  	limit, err := fdlimit.Current()
   772  	if err != nil {
   773  		Fatalf("Failed to retrieve file descriptor allowance: %v", err)
   774  	}
   775  	if limit < 2048 {
   776  		if err := fdlimit.Raise(2048); err != nil {
   777  			Fatalf("Failed to raise file descriptor allowance: %v", err)
   778  		}
   779  	}
   780  	if limit > 2048 { // cap database file descriptors even if more is available
   781  		limit = 2048
   782  	}
   783  	return limit / 2 // Leave half for networking and other stuff
   784  }
   785  
   786  // MakeAddress converts an account specified directly as a hex encoded string or
   787  // a key index in the key store to an internal account representation.
   788  func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) {
   789  	// If the specified account is a valid address, return it
   790  	if common.IsHexAddress(account) {
   791  		return accounts.Account{Address: common.HexToAddress(account)}, nil
   792  	}
   793  	// Otherwise try to interpret the account as a keystore index
   794  	index, err := strconv.Atoi(account)
   795  	if err != nil || index < 0 {
   796  		return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account)
   797  	}
   798  	log.Warn("-------------------------------------------------------------------")
   799  	log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
   800  	log.Warn("This functionality is deprecated and will be removed in the future!")
   801  	log.Warn("Please use explicit addresses! (can search via `intchain account list`)")
   802  	log.Warn("-------------------------------------------------------------------")
   803  
   804  	accs := ks.Accounts()
   805  	if len(accs) <= index {
   806  		return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs))
   807  	}
   808  	return accs[index], nil
   809  }
   810  
   811  // setCoinbase retrieves the etherbase either from the directly specified
   812  // command line flags or from the keystore if CLI indexed.
   813  func setCoinbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *intprotocol.Config) {
   814  	var coinbase string
   815  	if ctx.GlobalIsSet(MinerCoinbaseFlag.Name) {
   816  		coinbase = ctx.GlobalString(MinerCoinbaseFlag.Name)
   817  	}
   818  	// Convert the coinbase into an address and configure it
   819  	if coinbase != "" {
   820  		if ks != nil {
   821  			account, err := MakeAddress(ks, coinbase)
   822  			if err != nil {
   823  				Fatalf("Invalid miner coinbase: %v", err)
   824  			}
   825  			cfg.Coinbase = account.Address
   826  		} else {
   827  			Fatalf("No coinbase configured")
   828  		}
   829  	}
   830  }
   831  
   832  // MakePasswordList reads password lines from the file specified by the global --password flag.
   833  func MakePasswordList(ctx *cli.Context) []string {
   834  	path := ctx.GlobalString(PasswordFileFlag.Name)
   835  	if path == "" {
   836  		return nil
   837  	}
   838  	text, err := ioutil.ReadFile(path)
   839  	if err != nil {
   840  		Fatalf("Failed to read password file: %v", err)
   841  	}
   842  	lines := strings.Split(string(text), "\n")
   843  	// Sanitise DOS line endings.
   844  	for i := range lines {
   845  		lines[i] = strings.TrimRight(lines[i], "\r")
   846  	}
   847  	return lines
   848  }
   849  
   850  func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
   851  	setNodeKey(ctx, cfg)
   852  	setNAT(ctx, cfg)
   853  	setListenAddress(ctx, cfg)
   854  	setBootstrapNodes(ctx, cfg)
   855  	//setBootstrapNodesV5(ctx, cfg)
   856  
   857  	if ctx.GlobalIsSet(MaxPeersFlag.Name) {
   858  		cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name)
   859  
   860  	}
   861  	if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) {
   862  		cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name)
   863  	}
   864  	if ctx.GlobalIsSet(NoDiscoverFlag.Name) {
   865  		cfg.NoDiscovery = true
   866  	}
   867  
   868  	// if we're running a light client or server, force enable the v5 peer discovery
   869  	// unless it is explicitly disabled with --nodiscover note that explicitly specifying
   870  	// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
   871  	if ctx.GlobalIsSet(DiscoveryV5Flag.Name) {
   872  		cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name)
   873  	}
   874  
   875  	if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" {
   876  		list, err := netutil.ParseNetlist(netrestrict)
   877  		if err != nil {
   878  			Fatalf("Option %q: %v", NetrestrictFlag.Name, err)
   879  		}
   880  		cfg.NetRestrict = list
   881  	}
   882  }
   883  
   884  // SetNodeConfig applies node-related command line flags to the config.
   885  func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
   886  	SetP2PConfig(ctx, &cfg.P2P)
   887  	setIPC(ctx, cfg)
   888  	SetHTTP(ctx, cfg)
   889  	SetWS(ctx, cfg)
   890  	setNodeUserIdent(ctx, cfg)
   891  
   892  	switch {
   893  	case ctx.GlobalIsSet(DataDirFlag.Name):
   894  		cfg.GeneralDataDir = ctx.GlobalString(DataDirFlag.Name)
   895  		cfg.DataDir = filepath.Join(cfg.GeneralDataDir, cfg.ChainId)
   896  	case !ctx.GlobalIsSet(DataDirFlag.Name):
   897  		cfg.DataDir = filepath.Join(cfg.GeneralDataDir, cfg.ChainId)
   898  	case ctx.GlobalBool(TestnetFlag.Name):
   899  		cfg.DataDir = filepath.Join(cfg.GeneralDataDir, ctx.GlobalString(TestnetFlag.Name))
   900  	}
   901  
   902  	if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
   903  		cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name)
   904  	}
   905  
   906  	if ctx.GlobalIsSet(NoUSBFlag.Name) {
   907  		cfg.NoUSB = ctx.GlobalBool(NoUSBFlag.Name)
   908  	}
   909  }
   910  
   911  func setGPO(ctx *cli.Context, cfg *gasprice.Config) {
   912  	if ctx.GlobalIsSet(GpoBlocksFlag.Name) {
   913  		cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name)
   914  	}
   915  	if ctx.GlobalIsSet(GpoPercentileFlag.Name) {
   916  		cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name)
   917  	}
   918  }
   919  
   920  func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
   921  	if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) {
   922  		cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name)
   923  	}
   924  	if ctx.GlobalIsSet(TxPoolJournalFlag.Name) {
   925  		cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name)
   926  	}
   927  	if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) {
   928  		cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name)
   929  	}
   930  	if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) {
   931  		cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name)
   932  	}
   933  	if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) {
   934  		cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name)
   935  	}
   936  	if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) {
   937  		cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name)
   938  	}
   939  	if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) {
   940  		cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name)
   941  	}
   942  	if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) {
   943  		cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name)
   944  	}
   945  	if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) {
   946  		cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name)
   947  	}
   948  	if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) {
   949  		cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name)
   950  	}
   951  }
   952  
   953  // checkExclusive verifies that only a single isntance of the provided flags was
   954  // set by the user. Each flag might optionally be followed by a string type to
   955  // specialize it further.
   956  func checkExclusive(ctx *cli.Context, args ...interface{}) {
   957  	set := make([]string, 0, 1)
   958  	for i := 0; i < len(args); i++ {
   959  		// Make sure the next argument is a flag and skip if not set
   960  		flag, ok := args[i].(cli.Flag)
   961  		if !ok {
   962  			panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i]))
   963  		}
   964  		// Check if next arg extends current and expand its name if so
   965  		name := flag.GetName()
   966  
   967  		if i+1 < len(args) {
   968  			switch option := args[i+1].(type) {
   969  			case string:
   970  				// Extended flag, expand the name and shift the arguments
   971  				if ctx.GlobalString(flag.GetName()) == option {
   972  					name += "=" + option
   973  				}
   974  				i++
   975  
   976  			case cli.Flag:
   977  			default:
   978  				panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1]))
   979  			}
   980  		}
   981  		// Mark the flag if it's set
   982  		if ctx.GlobalIsSet(flag.GetName()) {
   983  			set = append(set, "--"+name)
   984  		}
   985  	}
   986  	if len(set) > 1 {
   987  		Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", "))
   988  	}
   989  }
   990  
   991  // SetShhConfig applies shh-related command line flags to the config.
   992  //func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
   993  //	if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) {
   994  //		cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name))
   995  //	}
   996  //	if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) {
   997  //		cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name)
   998  //	}
   999  //}
  1000  
  1001  // SetEthConfig applies intprotocol-related command line flags to the config.
  1002  func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *intprotocol.Config) {
  1003  	// Avoid conflicting network flags
  1004  	checkExclusive(ctx, TestnetFlag)
  1005  	checkExclusive(ctx, FastSyncFlag, SyncModeFlag)
  1006  
  1007  	ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
  1008  	setCoinbase(ctx, ks, cfg)
  1009  	setGPO(ctx, &cfg.GPO)
  1010  	setTxPool(ctx, &cfg.TxPool)
  1011  
  1012  	switch {
  1013  	case ctx.GlobalIsSet(SyncModeFlag.Name):
  1014  		cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
  1015  	case ctx.GlobalBool(FastSyncFlag.Name):
  1016  		cfg.SyncMode = downloader.FastSync
  1017  	}
  1018  
  1019  	if ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1020  		cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
  1021  	}
  1022  
  1023  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
  1024  		cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1025  	}
  1026  	cfg.DatabaseHandles = makeDatabaseHandles()
  1027  
  1028  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1029  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1030  	}
  1031  	cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive"
  1032  
  1033  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
  1034  		cfg.TrieCleanCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
  1035  	}
  1036  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1037  		cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1038  	}
  1039  	if ctx.GlobalIsSet(DocRootFlag.Name) {
  1040  		cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name)
  1041  	}
  1042  	if ctx.GlobalIsSet(ExtraDataFlag.Name) {
  1043  		cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name))
  1044  	}
  1045  	if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
  1046  		cfg.MinerGasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name)
  1047  	}
  1048  	if ctx.GlobalIsSet(MinerGasLimitFlag.Name) {
  1049  		cfg.MinerGasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name)
  1050  	}
  1051  	if ctx.GlobalIsSet(MinerGasPriceFlag.Name) {
  1052  		cfg.MinerGasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name)
  1053  	}
  1054  	if ctx.GlobalIsSet(VMEnableDebugFlag.Name) {
  1055  		// TODO(fjl): force-enable this in --dev mode
  1056  		cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
  1057  	}
  1058  
  1059  	// Override any default configs for hard coded networks.
  1060  	switch {
  1061  	case ctx.GlobalBool(TestnetFlag.Name):
  1062  		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
  1063  			cfg.NetworkId = 2048
  1064  		}
  1065  		//
  1066  		//cfg.Genesis = core.DefaultTestnetGenesisBlock()
  1067  	}
  1068  
  1069  	// Data Reduction Config
  1070  	cfg.PruneStateData = ctx.GlobalBool(PruneFlag.Name)
  1071  	//cfg.PruneBlockData = ctx.GlobalBool(PruneBlockFlag.Name)
  1072  }
  1073  
  1074  func SetGeneralConfig(ctx *cli.Context) {
  1075  	params.GenCfg.PerfTest = ctx.GlobalBool(PerfTestFlag.Name)
  1076  }
  1077  
  1078  // registerIntService adds an INT Chain client to the stack.
  1079  func RegisterIntService(stack *node.Node, cfg *intprotocol.Config, cliCtx *cli.Context, cch core.CrossChainHelper) {
  1080  	var err error
  1081  	err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1082  		//return NewBackend(ctx, cfg, cliCtx, pNode, cch)
  1083  		fullNode, err := intprotocol.New(ctx, cfg, cliCtx, cch, stack.GetLogger(), cliCtx.GlobalBool(TestnetFlag.Name))
  1084  		//if fullNode != nil && cfg.LightServ > 0 {
  1085  		//	ls, _ := les.NewLesServer(fullNode, cfg)
  1086  		//	fullNode.AddLesServer(ls)
  1087  		//}
  1088  		return fullNode, err
  1089  	})
  1090  	if err != nil {
  1091  		Fatalf("Failed to register the intchain service: %v", err)
  1092  	}
  1093  }
  1094  
  1095  //// RegisterEthService adds an INT Chain client to the stack.
  1096  //func RegisterIntService(stack *node.Node, cfg *intprotocol.Config) {
  1097  //	var err error
  1098  //	err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
  1099  //		fullNode, err := intprotocol.New(ctx, cfg, nil, nil, stack.GetLogger(), false)
  1100  //		//if fullNode != nil && cfg.LightServ > 0 {
  1101  //		//	ls, _ := les.NewLesServer(fullNode, cfg)
  1102  //		//	fullNode.AddLesServer(ls)
  1103  //		//}
  1104  //		return fullNode, err
  1105  //	})
  1106  //	if err != nil {
  1107  //		Fatalf("Failed to register the intchain service: %v", err)
  1108  //	}
  1109  //}
  1110  
  1111  // RegisterShhService configures Whisper and adds it to the given node.
  1112  //func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
  1113  //	if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
  1114  //		return whisper.New(cfg), nil
  1115  //	}); err != nil {
  1116  //		Fatalf("Failed to register the Whisper service: %v", err)
  1117  //	}
  1118  //}
  1119  
  1120  // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
  1121  func MakeChainDatabase(ctx *cli.Context, stack *node.Node) intdb.Database {
  1122  	var (
  1123  		cache   = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
  1124  		handles = makeDatabaseHandles()
  1125  	)
  1126  	name := "chaindata"
  1127  	chainDb, err := stack.OpenDatabase(name, cache, handles, "")
  1128  	if err != nil {
  1129  		Fatalf("Could not open database: %v", err)
  1130  	}
  1131  	return chainDb
  1132  }
  1133  
  1134  func MakeGenesis(ctx *cli.Context) *core.Genesis {
  1135  	var genesis *core.Genesis
  1136  	//switch {
  1137  	///*
  1138  	//	case ctx.GlobalBool(TestnetFlag.Name):
  1139  	//		genesis = core.DefaultTestnetGenesisBlock()
  1140  	//*/
  1141  	//case ctx.GlobalBool(RinkebyFlag.Name):
  1142  	//	genesis = core.DefaultRinkebyGenesisBlock()
  1143  	//case ctx.GlobalBool(DeveloperFlag.Name):
  1144  	//	Fatalf("Developer chains are ephemeral")
  1145  	//case ctx.GlobalBool(OttomanFlag.Name):
  1146  	//	genesis = core.DefaultOttomanGenesisBlock()
  1147  	//}
  1148  	return genesis
  1149  }
  1150  
  1151  // MakeChain creates a chain manager from set command line flags.
  1152  func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb intdb.Database) {
  1153  	var err error
  1154  	chainDb = MakeChainDatabase(ctx, stack)
  1155  	config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
  1156  	if err != nil {
  1157  		Fatalf("%v", err)
  1158  	}
  1159  	var engine consensus.Engine
  1160  
  1161  	if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
  1162  		Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
  1163  	}
  1164  	cache := &core.CacheConfig{
  1165  		TrieCleanLimit: intprotocol.DefaultConfig.TrieCleanCache,
  1166  
  1167  		TrieDirtyLimit:    intprotocol.DefaultConfig.TrieDirtyCache,
  1168  		TrieDirtyDisabled: ctx.GlobalString(GCModeFlag.Name) == "archive",
  1169  		TrieTimeLimit:     intprotocol.DefaultConfig.TrieTimeout,
  1170  	}
  1171  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
  1172  		cache.TrieCleanLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
  1173  	}
  1174  	if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
  1175  		cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
  1176  	}
  1177  	vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
  1178  	chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil)
  1179  	if err != nil {
  1180  		Fatalf("Can't create BlockChain: %v", err)
  1181  	}
  1182  	return chain, chainDb
  1183  }
  1184  
  1185  // MakeConsolePreloads retrieves the absolute paths for the console JavaScript
  1186  // scripts to preload before starting.
  1187  func MakeConsolePreloads(ctx *cli.Context) []string {
  1188  	// Skip preloading if there's nothing to preload
  1189  	if ctx.GlobalString(PreloadJSFlag.Name) == "" {
  1190  		return nil
  1191  	}
  1192  	// Otherwise resolve absolute paths and return them
  1193  	preloads := []string{}
  1194  
  1195  	assets := ctx.GlobalString(JSpathFlag.Name)
  1196  	for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") {
  1197  		preloads = append(preloads, common.AbsolutePath(assets, strings.TrimSpace(file)))
  1198  	}
  1199  	return preloads
  1200  }
  1201  
  1202  // MigrateFlags sets the global flag from a local flag when it's set.
  1203  // This is a temporary function used for migrating old command/flags to the
  1204  // new format.
  1205  //
  1206  // e.g. intchain account new --keystore /tmp/mykeystore --lightkdf
  1207  //
  1208  // is equivalent after calling this method with:
  1209  //
  1210  // intchain --keystore /tmp/mykeystore --lightkdf account new
  1211  //
  1212  // This allows the use of the existing configuration functionality.
  1213  // When all flags are migrated this function can be removed and the existing
  1214  // configuration functionality must be changed that is uses local flags
  1215  func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error {
  1216  	return func(ctx *cli.Context) error {
  1217  		for _, name := range ctx.FlagNames() {
  1218  			if ctx.IsSet(name) {
  1219  				if !ctx.GlobalIsSet(name) {
  1220  					ctx.GlobalSet(name, ctx.String(name))
  1221  				}
  1222  			}
  1223  		}
  1224  		return action(ctx)
  1225  	}
  1226  }
  1227  
  1228  var (
  1229  	// ipbft config
  1230  	Config cfg.Config
  1231  )
  1232  
  1233  func GetTendermintConfig(chainId string, ctx *cli.Context) cfg.Config {
  1234  	datadir := ctx.GlobalString(DataDirFlag.Name)
  1235  	config := tmcfg.GetConfig(datadir, chainId)
  1236  
  1237  	return config
  1238  }