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