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