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