diff --git a/build/ci.go b/build/ci.go index 1be9644da..5b829b9b2 100644 --- a/build/ci.go +++ b/build/ci.go @@ -205,6 +205,9 @@ func doInstall(cmdline []string) { gobuild.Args = append(gobuild.Args, "-p", "1") } + // Disable CLI markdown doc generation in release builds. + gobuild.Args = append(gobuild.Args, "-tags", "urfave_cli_no_docs") + // We use -trimpath to avoid leaking local paths into the built executables. gobuild.Args = append(gobuild.Args, "-trimpath") diff --git a/build/deb/ethereum/completions/bash_autocomplete b/build/deb/ethereum/completions/bash_autocomplete new file mode 100644 index 000000000..08997b6a9 --- /dev/null +++ b/build/deb/ethereum/completions/bash_autocomplete @@ -0,0 +1,16 @@ +_geth_bash_autocomplete() { + if [[ "${COMP_WORDS[0]}" != "source" ]]; then + local cur opts base + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + if [[ "$cur" == "-"* ]]; then + opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion ) + else + opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) + fi + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +complete -o bashdefault -o default -o nospace -F _geth_bash_autocomplete geth \ No newline at end of file diff --git a/build/deb/ethereum/completions/zsh_autocomplete b/build/deb/ethereum/completions/zsh_autocomplete new file mode 100644 index 000000000..c7428a00b --- /dev/null +++ b/build/deb/ethereum/completions/zsh_autocomplete @@ -0,0 +1,18 @@ +_geth_zsh_autocomplete() { + local -a opts + local cur + cur=${words[-1]} + if [[ "$cur" == "-"* ]]; then + opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}") + else + opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-bash-completion)}") + fi + + if [[ "${opts[1]}" != "" ]]; then + _describe 'values' opts + else + _files + fi +} + +compdef _geth_zsh_autocomplete geth \ No newline at end of file diff --git a/build/deb/ethereum/deb.install b/build/deb/ethereum/deb.install index e7666ce5f..21f555d9e 100644 --- a/build/deb/ethereum/deb.install +++ b/build/deb/ethereum/deb.install @@ -1 +1,5 @@ build/bin/{{.BinaryName}} usr/bin +{{- if eq .BinaryName "geth" }} +build/deb/ethereum/completions/bash_autocomplete etc/bash_completion.d/geth +build/deb/ethereum/completions/zsh_autocomplete usr/share/zsh/vendor-completions/_geth +{{end -}} \ No newline at end of file diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 21ebc0111..cdfcd61bd 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -32,7 +32,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( @@ -41,60 +41,62 @@ var ( gitDate = "" app *cli.App +) +var ( // Flags needed by abigen - abiFlag = cli.StringFlag{ + abiFlag = &cli.StringFlag{ Name: "abi", Usage: "Path to the Ethereum contract ABI json to bind, - for STDIN", } - binFlag = cli.StringFlag{ + binFlag = &cli.StringFlag{ Name: "bin", Usage: "Path to the Ethereum contract bytecode (generate deploy method)", } - typeFlag = cli.StringFlag{ + typeFlag = &cli.StringFlag{ Name: "type", Usage: "Struct name for the binding (default = package name)", } - jsonFlag = cli.StringFlag{ + jsonFlag = &cli.StringFlag{ Name: "combined-json", Usage: "Path to the combined-json file generated by compiler", } - solFlag = cli.StringFlag{ + solFlag = &cli.StringFlag{ Name: "sol", Usage: "Path to the Ethereum contract Solidity source to build and bind", } - solcFlag = cli.StringFlag{ + solcFlag = &cli.StringFlag{ Name: "solc", Usage: "Solidity compiler to use if source builds are requested", Value: "solc", } - vyFlag = cli.StringFlag{ + vyFlag = &cli.StringFlag{ Name: "vy", Usage: "Path to the Ethereum contract Vyper source to build and bind", } - vyperFlag = cli.StringFlag{ + vyperFlag = &cli.StringFlag{ Name: "vyper", Usage: "Vyper compiler to use if source builds are requested", Value: "vyper", } - excFlag = cli.StringFlag{ + excFlag = &cli.StringFlag{ Name: "exc", Usage: "Comma separated types to exclude from binding", } - pkgFlag = cli.StringFlag{ + pkgFlag = &cli.StringFlag{ Name: "pkg", Usage: "Package name to generate the binding into", } - outFlag = cli.StringFlag{ + outFlag = &cli.StringFlag{ Name: "out", Usage: "Output file for the generated binding (default = stdout)", } - langFlag = cli.StringFlag{ + langFlag = &cli.StringFlag{ Name: "lang", Usage: "Destination language for the bindings (go)", Value: "go", } - aliasFlag = cli.StringFlag{ + aliasFlag = &cli.StringFlag{ Name: "alias", Usage: "Comma separated aliases for function and event renaming, e.g. original1=alias1, original2=alias2", } @@ -102,6 +104,7 @@ var ( func init() { app = flags.NewApp(gitCommit, gitDate, "ethereum checkpoint helper tool") + app.Name = "abigen" app.Flags = []cli.Flag{ abiFlag, binFlag, @@ -117,21 +120,20 @@ func init() { langFlag, aliasFlag, } - app.Action = utils.MigrateFlags(abigen) - cli.CommandHelpTemplate = flags.OriginCommandHelpTemplate + app.Action = abigen } func abigen(c *cli.Context) error { utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected. - if c.GlobalString(pkgFlag.Name) == "" { + if c.String(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") } var lang bind.Lang - switch c.GlobalString(langFlag.Name) { + switch c.String(langFlag.Name) { case "go": lang = bind.LangGo default: - utils.Fatalf("Unsupported destination language \"%s\" (--lang)", c.GlobalString(langFlag.Name)) + utils.Fatalf("Unsupported destination language \"%s\" (--lang)", c.String(langFlag.Name)) } // If the entire solidity code was specified, build and bind based on that var ( @@ -142,13 +144,13 @@ func abigen(c *cli.Context) error { libs = make(map[string]string) aliases = make(map[string]string) ) - if c.GlobalString(abiFlag.Name) != "" { + if c.String(abiFlag.Name) != "" { // Load up the ABI, optional bytecode and type name from the parameters var ( abi []byte err error ) - input := c.GlobalString(abiFlag.Name) + input := c.String(abiFlag.Name) if input == "-" { abi, err = io.ReadAll(os.Stdin) } else { @@ -160,7 +162,7 @@ func abigen(c *cli.Context) error { abis = append(abis, string(abi)) var bin []byte - if binFile := c.GlobalString(binFlag.Name); binFile != "" { + if binFile := c.String(binFlag.Name); binFile != "" { if bin, err = os.ReadFile(binFile); err != nil { utils.Fatalf("Failed to read input bytecode: %v", err) } @@ -170,28 +172,28 @@ func abigen(c *cli.Context) error { } bins = append(bins, string(bin)) - kind := c.GlobalString(typeFlag.Name) + kind := c.String(typeFlag.Name) if kind == "" { - kind = c.GlobalString(pkgFlag.Name) + kind = c.String(pkgFlag.Name) } types = append(types, kind) } else { // Generate the list of types to exclude from binding exclude := make(map[string]bool) - for _, kind := range strings.Split(c.GlobalString(excFlag.Name), ",") { + for _, kind := range strings.Split(c.String(excFlag.Name), ",") { exclude[strings.ToLower(kind)] = true } var err error var contracts map[string]*compiler.Contract switch { - case c.GlobalIsSet(solFlag.Name): - contracts, err = compiler.CompileSolidity(c.GlobalString(solcFlag.Name), c.GlobalString(solFlag.Name)) + case c.IsSet(solFlag.Name): + contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name)) if err != nil { utils.Fatalf("Failed to build Solidity contract: %v", err) } - case c.GlobalIsSet(vyFlag.Name): - output, err := compiler.CompileVyper(c.GlobalString(vyperFlag.Name), c.GlobalString(vyFlag.Name)) + case c.IsSet(vyFlag.Name): + output, err := compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name)) if err != nil { utils.Fatalf("Failed to build Vyper contract: %v", err) } @@ -207,8 +209,8 @@ func abigen(c *cli.Context) error { contracts[name] = contract } - case c.GlobalIsSet(jsonFlag.Name): - jsonOutput, err := os.ReadFile(c.GlobalString(jsonFlag.Name)) + case c.IsSet(jsonFlag.Name): + jsonOutput, err := os.ReadFile(c.String(jsonFlag.Name)) if err != nil { utils.Fatalf("Failed to read combined-json from compiler: %v", err) } @@ -237,28 +239,28 @@ func abigen(c *cli.Context) error { } } // Extract all aliases from the flags - if c.GlobalIsSet(aliasFlag.Name) { + if c.IsSet(aliasFlag.Name) { // We support multi-versions for aliasing // e.g. // foo=bar,foo2=bar2 // foo:bar,foo2:bar2 re := regexp.MustCompile(`(?:(\w+)[:=](\w+))`) - submatches := re.FindAllStringSubmatch(c.GlobalString(aliasFlag.Name), -1) + submatches := re.FindAllStringSubmatch(c.String(aliasFlag.Name), -1) for _, match := range submatches { aliases[match[1]] = match[2] } } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, sigs, c.GlobalString(pkgFlag.Name), lang, libs, aliases) + code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs, aliases) if err != nil { utils.Fatalf("Failed to generate ABI binding: %v", err) } // Either flush it out to a file or display on the standard output - if !c.GlobalIsSet(outFlag.Name) { + if !c.IsSet(outFlag.Name) { fmt.Printf("%s\n", code) return nil } - if err := os.WriteFile(c.GlobalString(outFlag.Name), []byte(code), 0600); err != nil { + if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil { utils.Fatalf("Failed to write ABI binding: %v", err) } return nil diff --git a/cmd/checkpoint-admin/common.go b/cmd/checkpoint-admin/common.go index 05a45dfbf..f86ac24f0 100644 --- a/cmd/checkpoint-admin/common.go +++ b/cmd/checkpoint-admin/common.go @@ -28,12 +28,12 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) // newClient creates a client with specified remote URL. func newClient(ctx *cli.Context) *ethclient.Client { - client, err := ethclient.Dial(ctx.GlobalString(nodeURLFlag.Name)) + client, err := ethclient.Dial(ctx.String(nodeURLFlag.Name)) if err != nil { utils.Fatalf("Failed to connect to Ethereum node: %v", err) } @@ -64,9 +64,9 @@ func getContractAddr(client *rpc.Client) common.Address { func getCheckpoint(ctx *cli.Context, client *rpc.Client) *params.TrustedCheckpoint { var checkpoint *params.TrustedCheckpoint - if ctx.GlobalIsSet(indexFlag.Name) { + if ctx.IsSet(indexFlag.Name) { var result [3]string - index := uint64(ctx.GlobalInt64(indexFlag.Name)) + index := uint64(ctx.Int64(indexFlag.Name)) if err := client.Call(&result, "les_getCheckpoint", index); err != nil { utils.Fatalf("Failed to get local checkpoint %v, please ensure the les API is exposed", err) } diff --git a/cmd/checkpoint-admin/exec.go b/cmd/checkpoint-admin/exec.go index 352a96d9e..cb67d0306 100644 --- a/cmd/checkpoint-admin/exec.go +++ b/cmd/checkpoint-admin/exec.go @@ -36,10 +36,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var commandDeploy = cli.Command{ +var commandDeploy = &cli.Command{ Name: "deploy", Usage: "Deploy a new checkpoint oracle contract", Flags: []cli.Flag{ @@ -49,10 +49,10 @@ var commandDeploy = cli.Command{ signersFlag, thresholdFlag, }, - Action: utils.MigrateFlags(deploy), + Action: deploy, } -var commandSign = cli.Command{ +var commandSign = &cli.Command{ Name: "sign", Usage: "Sign the checkpoint with the specified key", Flags: []cli.Flag{ @@ -63,10 +63,10 @@ var commandSign = cli.Command{ hashFlag, oracleFlag, }, - Action: utils.MigrateFlags(sign), + Action: sign, } -var commandPublish = cli.Command{ +var commandPublish = &cli.Command{ Name: "publish", Usage: "Publish a checkpoint into the oracle", Flags: []cli.Flag{ @@ -76,7 +76,7 @@ var commandPublish = cli.Command{ indexFlag, signaturesFlag, }, - Action: utils.MigrateFlags(publish), + Action: publish, } // deploy deploys the checkpoint registrar contract. @@ -132,7 +132,7 @@ func sign(ctx *cli.Context) error { node *rpc.Client oracle *checkpointoracle.CheckpointOracle ) - if !ctx.GlobalIsSet(nodeURLFlag.Name) { + if !ctx.IsSet(nodeURLFlag.Name) { // Offline mode signing offline = true if !ctx.IsSet(hashFlag.Name) { @@ -151,7 +151,7 @@ func sign(ctx *cli.Context) error { address = common.HexToAddress(ctx.String(oracleFlag.Name)) } else { // Interactive mode signing, retrieve the data from the remote node - node = newRPCClient(ctx.GlobalString(nodeURLFlag.Name)) + node = newRPCClient(ctx.String(nodeURLFlag.Name)) checkpoint := getCheckpoint(ctx, node) chash, cindex, address = checkpoint.Hash(), checkpoint.SectionIndex, getContractAddr(node) @@ -265,7 +265,7 @@ func publish(ctx *cli.Context) error { } // Retrieve the checkpoint we want to sign to sort the signatures var ( - client = newRPCClient(ctx.GlobalString(nodeURLFlag.Name)) + client = newRPCClient(ctx.String(nodeURLFlag.Name)) addr, oracle = newContract(client) checkpoint = getCheckpoint(ctx, client) sighash = sighash(checkpoint.SectionIndex, addr, checkpoint.Hash()) diff --git a/cmd/checkpoint-admin/main.go b/cmd/checkpoint-admin/main.go index 0fb553214..0604ccaad 100644 --- a/cmd/checkpoint-admin/main.go +++ b/cmd/checkpoint-admin/main.go @@ -25,20 +25,20 @@ import ( "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( // Git SHA1 commit hash of the release (set via linker flags) gitCommit = "" gitDate = "" -) -var app *cli.App + app *cli.App +) func init() { app = flags.NewApp(gitCommit, gitDate, "ethereum checkpoint helper tool") - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ commandStatus, commandDeploy, commandSign, @@ -48,46 +48,45 @@ func init() { oracleFlag, nodeURLFlag, } - cli.CommandHelpTemplate = flags.OriginCommandHelpTemplate } // Commonly used command line flags. var ( - indexFlag = cli.Int64Flag{ + indexFlag = &cli.Int64Flag{ Name: "index", Usage: "Checkpoint index (query latest from remote node if not specified)", } - hashFlag = cli.StringFlag{ + hashFlag = &cli.StringFlag{ Name: "hash", Usage: "Checkpoint hash (query latest from remote node if not specified)", } - oracleFlag = cli.StringFlag{ + oracleFlag = &cli.StringFlag{ Name: "oracle", Usage: "Checkpoint oracle address (query from remote node if not specified)", } - thresholdFlag = cli.Int64Flag{ + thresholdFlag = &cli.Int64Flag{ Name: "threshold", Usage: "Minimal number of signatures required to approve a checkpoint", } - nodeURLFlag = cli.StringFlag{ + nodeURLFlag = &cli.StringFlag{ Name: "rpc", Value: "http://localhost:8545", Usage: "The rpc endpoint of a local or remote geth node", } - clefURLFlag = cli.StringFlag{ + clefURLFlag = &cli.StringFlag{ Name: "clef", Value: "http://localhost:8550", Usage: "The rpc endpoint of clef", } - signerFlag = cli.StringFlag{ + signerFlag = &cli.StringFlag{ Name: "signer", Usage: "Signer address for clef signing", } - signersFlag = cli.StringFlag{ + signersFlag = &cli.StringFlag{ Name: "signers", Usage: "Comma separated accounts of trusted checkpoint signers", } - signaturesFlag = cli.StringFlag{ + signaturesFlag = &cli.StringFlag{ Name: "signatures", Usage: "Comma separated checkpoint signatures to submit", } diff --git a/cmd/checkpoint-admin/status.go b/cmd/checkpoint-admin/status.go index f613501eb..bec97aed1 100644 --- a/cmd/checkpoint-admin/status.go +++ b/cmd/checkpoint-admin/status.go @@ -19,24 +19,23 @@ package main import ( "fmt" - "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var commandStatus = cli.Command{ +var commandStatus = &cli.Command{ Name: "status", Usage: "Fetches the signers and checkpoint status of the oracle contract", Flags: []cli.Flag{ nodeURLFlag, }, - Action: utils.MigrateFlags(status), + Action: status, } // status fetches the admin list of specified registrar contract. func status(ctx *cli.Context) error { // Create a wrapper around the checkpoint oracle contract - addr, oracle := newContract(newRPCClient(ctx.GlobalString(nodeURLFlag.Name))) + addr, oracle := newContract(newRPCClient(ctx.String(nodeURLFlag.Name))) fmt.Printf("Oracle => %s\n", addr.Hex()) fmt.Println() diff --git a/cmd/clef/main.go b/cmd/clef/main.go index e8c6f15a3..dab4c7853 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -30,7 +30,6 @@ import ( "os/signal" "path/filepath" "runtime" - "sort" "strings" "syscall" "time" @@ -60,7 +59,7 @@ import ( "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const legalWarning = ` @@ -78,70 +77,70 @@ PURPOSE. See the GNU General Public License for more details. ` var ( - logLevelFlag = cli.IntFlag{ + logLevelFlag = &cli.IntFlag{ Name: "loglevel", Value: 4, Usage: "log level to emit to the screen", } - advancedMode = cli.BoolFlag{ + advancedMode = &cli.BoolFlag{ Name: "advanced", Usage: "If enabled, issues warnings instead of rejections for suspicious requests. Default off", } - acceptFlag = cli.BoolFlag{ + acceptFlag = &cli.BoolFlag{ Name: "suppress-bootwarn", Usage: "If set, does not show the warning during boot", } - keystoreFlag = cli.StringFlag{ + keystoreFlag = &cli.StringFlag{ Name: "keystore", Value: filepath.Join(node.DefaultDataDir(), "keystore"), Usage: "Directory for the keystore", } - configdirFlag = cli.StringFlag{ + configdirFlag = &cli.StringFlag{ Name: "configdir", Value: DefaultConfigDir(), Usage: "Directory for Clef configuration", } - chainIdFlag = cli.Int64Flag{ + chainIdFlag = &cli.Int64Flag{ Name: "chainid", Value: params.MainnetChainConfig.ChainID.Int64(), Usage: "Chain id to use for signing (1=mainnet, 3=Ropsten, 4=Rinkeby, 5=Goerli)", } - rpcPortFlag = cli.IntFlag{ - Name: "http.port", - Usage: "HTTP-RPC server listening port", - Value: node.DefaultHTTPPort + 5, + rpcPortFlag = &cli.IntFlag{ + Name: "http.port", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort + 5, + Category: flags.APICategory, } - signerSecretFlag = cli.StringFlag{ + signerSecretFlag = &cli.StringFlag{ Name: "signersecret", Usage: "A file containing the (encrypted) master seed to encrypt Clef data, e.g. keystore credentials and ruleset hash", } - customDBFlag = cli.StringFlag{ + customDBFlag = &cli.StringFlag{ Name: "4bytedb-custom", Usage: "File used for writing new 4byte-identifiers submitted via API", Value: "./4byte-custom.json", } - auditLogFlag = cli.StringFlag{ + auditLogFlag = &cli.StringFlag{ Name: "auditlog", Usage: "File used to emit audit logs. Set to \"\" to disable", Value: "audit.log", } - ruleFlag = cli.StringFlag{ + ruleFlag = &cli.StringFlag{ Name: "rules", Usage: "Path to the rule file to auto-authorize requests with", } - stdiouiFlag = cli.BoolFlag{ + stdiouiFlag = &cli.BoolFlag{ Name: "stdio-ui", Usage: "Use STDIN/STDOUT as a channel for an external UI. " + "This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user " + "interface, and can be used when Clef is started by an external process.", } - testFlag = cli.BoolFlag{ + testFlag = &cli.BoolFlag{ Name: "stdio-ui-test", Usage: "Mechanism to test interface between Clef and UI. Requires 'stdio-ui'.", } - app = cli.NewApp() - initCommand = cli.Command{ - Action: utils.MigrateFlags(initializeSecrets), + initCommand = &cli.Command{ + Action: initializeSecrets, Name: "init", Usage: "Initialize the signer, generate secret storage", ArgsUsage: "", @@ -153,8 +152,8 @@ var ( The init command generates a master seed which Clef can use to store credentials and data needed for the rule-engine to work.`, } - attestCommand = cli.Command{ - Action: utils.MigrateFlags(attestFile), + attestCommand = &cli.Command{ + Action: attestFile, Name: "attest", Usage: "Attest that a js-file is to be used", ArgsUsage: "", @@ -170,8 +169,8 @@ incoming requests. Whenever you make an edit to the rule file, you need to use attestation to tell Clef that the file is 'safe' to execute.`, } - setCredentialCommand = cli.Command{ - Action: utils.MigrateFlags(setCredential), + setCredentialCommand = &cli.Command{ + Action: setCredential, Name: "setpw", Usage: "Store a credential for a keystore file", ArgsUsage: "
", @@ -183,8 +182,8 @@ Clef that the file is 'safe' to execute.`, Description: ` The setpw command stores a password for a given address (keyfile). `} - delCredentialCommand = cli.Command{ - Action: utils.MigrateFlags(removeCredential), + delCredentialCommand = &cli.Command{ + Action: removeCredential, Name: "delpw", Usage: "Remove a credential for a keystore file", ArgsUsage: "
", @@ -196,8 +195,8 @@ The setpw command stores a password for a given address (keyfile). Description: ` The delpw command removes a password for a given address (keyfile). `} - newAccountCommand = cli.Command{ - Action: utils.MigrateFlags(newAccount), + newAccountCommand = &cli.Command{ + Action: newAccount, Name: "newaccount", Usage: "Create a new account", ArgsUsage: "", @@ -212,7 +211,7 @@ The newaccount command creates a new keystore-backed account. It is a convenienc which can be used in lieu of an external UI.`, } - gendocCommand = cli.Command{ + gendocCommand = &cli.Command{ Action: GenDoc, Name: "gendoc", Usage: "Generate documentation about json-rpc format", @@ -226,41 +225,13 @@ var supportedPlugins = []plugin.PluginInterfaceName{plugin.AccountPluginInterfac // -// AppHelpFlagGroups is the application flags, grouped by functionality. -var AppHelpFlagGroups = []flags.FlagGroup{ - { - Name: "FLAGS", - Flags: []cli.Flag{ - logLevelFlag, - keystoreFlag, - configdirFlag, - chainIdFlag, - utils.LightKDFFlag, - utils.NoUSBFlag, - utils.SmartCardDaemonPathFlag, - utils.HTTPListenAddrFlag, - utils.HTTPVirtualHostsFlag, - utils.IPCDisabledFlag, - utils.IPCPathFlag, - utils.HTTPEnabledFlag, - rpcPortFlag, - signerSecretFlag, - customDBFlag, - auditLogFlag, - ruleFlag, - stdiouiFlag, - testFlag, - advancedMode, - acceptFlag, +var ( + // Git SHA1 commit hash of the release (set via linker flags) + gitCommit = "" + gitDate = "" - // Quorum - utils.PluginSettingsFlag, - utils.PluginLocalVerifyFlag, - utils.PluginPublicKeyFlag, - utils.PluginSkipVerifyFlag, - }, - }, -} + app = flags.NewApp(gitCommit, gitDate, "Manage Ethereum account operations") +) func init() { app.Name = "Clef" @@ -295,46 +266,12 @@ func init() { utils.PluginSkipVerifyFlag, } app.Action = signer - app.Commands = []cli.Command{initCommand, + app.Commands = []*cli.Command{initCommand, attestCommand, setCredentialCommand, delCredentialCommand, newAccountCommand, - gendocCommand} - cli.CommandHelpTemplate = flags.CommandHelpTemplate - // Override the default app help template - cli.AppHelpTemplate = flags.ClefAppHelpTemplate - - // Override the default app help printer, but only for the global app help - originalHelpPrinter := cli.HelpPrinter - cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { - if tmpl == flags.ClefAppHelpTemplate { - // Render out custom usage screen - originalHelpPrinter(w, tmpl, flags.HelpData{App: data, FlagGroups: AppHelpFlagGroups}) - } else if tmpl == flags.CommandHelpTemplate { - // Iterate over all command specific flags and categorize them - categorized := make(map[string][]cli.Flag) - for _, flag := range data.(cli.Command).Flags { - if _, ok := categorized[flag.String()]; !ok { - categorized[flags.FlagCategory(flag, AppHelpFlagGroups)] = append(categorized[flags.FlagCategory(flag, AppHelpFlagGroups)], flag) - } - } - - // sort to get a stable ordering - sorted := make([]flags.FlagGroup, 0, len(categorized)) - for cat, flgs := range categorized { - sorted = append(sorted, flags.FlagGroup{Name: cat, Flags: flgs}) - } - sort.Sort(flags.ByCategory(sorted)) - - // add sorted array to data and render with default printer - originalHelpPrinter(w, tmpl, map[string]interface{}{ - "cmd": data, - "categorizedFlags": sorted, - }) - } else { - originalHelpPrinter(w, tmpl, data) - } + gendocCommand, } } @@ -351,7 +288,7 @@ func initializeSecrets(c *cli.Context) error { return err } // Ensure the master key does not yet exist, we're not willing to overwrite - configDir := c.GlobalString(configdirFlag.Name) + configDir := c.String(configdirFlag.Name) if err := os.Mkdir(configDir, 0700); err != nil && !os.IsExist(err) { return err } @@ -369,7 +306,7 @@ func initializeSecrets(c *cli.Context) error { return fmt.Errorf("failed to read enough random") } n, p := keystore.StandardScryptN, keystore.StandardScryptP - if c.GlobalBool(utils.LightKDFFlag.Name) { + if c.Bool(utils.LightKDFFlag.Name) { n, p = keystore.LightScryptN, keystore.LightScryptP } text := "The master seed of clef will be locked with a password.\nPlease specify a password. Do not forget this password!" @@ -413,7 +350,7 @@ You should treat 'masterseed.json' with utmost secrecy and make a backup of it! return nil } func attestFile(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an argument.") } if err := initialize(ctx); err != nil { @@ -424,7 +361,7 @@ func attestFile(ctx *cli.Context) error { if err != nil { utils.Fatalf(err.Error()) } - configDir := ctx.GlobalString(configdirFlag.Name) + configDir := ctx.String(configdirFlag.Name) vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) confKey := crypto.Keccak256([]byte("config"), stretchedKey) @@ -437,7 +374,7 @@ func attestFile(ctx *cli.Context) error { } func setCredential(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an address to be passed as an argument") } if err := initialize(ctx); err != nil { @@ -455,7 +392,7 @@ func setCredential(ctx *cli.Context) error { if err != nil { utils.Fatalf(err.Error()) } - configDir := ctx.GlobalString(configdirFlag.Name) + configDir := ctx.String(configdirFlag.Name) vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) @@ -467,7 +404,7 @@ func setCredential(ctx *cli.Context) error { } func removeCredential(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an address to be passed as an argument") } if err := initialize(ctx); err != nil { @@ -483,7 +420,7 @@ func removeCredential(ctx *cli.Context) error { if err != nil { utils.Fatalf(err.Error()) } - configDir := ctx.GlobalString(configdirFlag.Name) + configDir := ctx.String(configdirFlag.Name) vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) @@ -503,8 +440,8 @@ func newAccount(c *cli.Context) error { var ( ui = core.NewCommandlineUI() pwStorage storage.Storage = &storage.NoStorage{} - ksLoc = c.GlobalString(keystoreFlag.Name) - lightKdf = c.GlobalBool(utils.LightKDFFlag.Name) + ksLoc = c.String(keystoreFlag.Name) + lightKdf = c.Bool(utils.LightKDFFlag.Name) ) log.Info("Starting clef", "keystore", ksLoc, "light-kdf", lightKdf) am, _, err := startClefAccountManagerWithPlugins(c, ksLoc, true, lightKdf, "") @@ -525,13 +462,13 @@ func newAccount(c *cli.Context) error { func initialize(c *cli.Context) error { // Set up the logger to print everything logOutput := os.Stdout - if c.GlobalBool(stdiouiFlag.Name) { + if c.Bool(stdiouiFlag.Name) { logOutput = os.Stderr // If using the stdioui, we can't do the 'confirm'-flow - if !c.GlobalBool(acceptFlag.Name) { + if !c.Bool(acceptFlag.Name) { fmt.Fprint(logOutput, legalWarning) } - } else if !c.GlobalBool(acceptFlag.Name) { + } else if !c.Bool(acceptFlag.Name) { if !confirm(legalWarning) { return fmt.Errorf("aborted by user") } @@ -570,8 +507,8 @@ func ipcEndpoint(ipcPath, datadir string) string { func signer(c *cli.Context) error { // If we have some unrecognized command, bail out - if args := c.Args(); len(args) > 0 { - return fmt.Errorf("invalid command: %q", args[0]) + if c.NArg() > 0 { + return fmt.Errorf("invalid command: %q", c.Args().First()) } if err := initialize(c); err != nil { return err @@ -579,7 +516,7 @@ func signer(c *cli.Context) error { var ( ui core.UIClientAPI ) - if c.GlobalBool(stdiouiFlag.Name) { + if c.Bool(stdiouiFlag.Name) { log.Info("Using stdin/stdout as UI-channel") ui = core.NewStdIOUI() } else { @@ -587,7 +524,7 @@ func signer(c *cli.Context) error { ui = core.NewCommandlineUI() } // 4bytedb data - fourByteLocal := c.GlobalString(customDBFlag.Name) + fourByteLocal := c.String(customDBFlag.Name) db, err := fourbyte.NewWithFile(fourByteLocal) if err != nil { utils.Fatalf(err.Error()) @@ -599,7 +536,7 @@ func signer(c *cli.Context) error { api core.ExternalAPI pwStorage storage.Storage = &storage.NoStorage{} ) - configDir := c.GlobalString(configdirFlag.Name) + configDir := c.String(configdirFlag.Name) if stretchedKey, err := readMasterKey(c, ui); err != nil { log.Warn("Failed to open master, rules disabled", "err", err) } else { @@ -616,7 +553,7 @@ func signer(c *cli.Context) error { configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confkey) // Do we have a rule-file? - if ruleFile := c.GlobalString(ruleFlag.Name); ruleFile != "" { + if ruleFile := c.String(ruleFlag.Name); ruleFile != "" { ruleJS, err := os.ReadFile(ruleFile) if err != nil { log.Warn("Could not load rules, disabling", "file", ruleFile, "err", err) @@ -640,12 +577,12 @@ func signer(c *cli.Context) error { } } var ( - chainId = c.GlobalInt64(chainIdFlag.Name) - ksLoc = c.GlobalString(keystoreFlag.Name) - lightKdf = c.GlobalBool(utils.LightKDFFlag.Name) - advanced = c.GlobalBool(advancedMode.Name) - nousb = c.GlobalBool(utils.NoUSBFlag.Name) - scpath = c.GlobalString(utils.SmartCardDaemonPathFlag.Name) + chainId = c.Int64(chainIdFlag.Name) + ksLoc = c.String(keystoreFlag.Name) + lightKdf = c.Bool(utils.LightKDFFlag.Name) + advanced = c.Bool(advancedMode.Name) + nousb = c.Bool(utils.NoUSBFlag.Name) + scpath = c.String(utils.SmartCardDaemonPathFlag.Name) ) log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc, "light-kdf", lightKdf, "advanced", advanced) @@ -662,7 +599,7 @@ func signer(c *cli.Context) error { ui.RegisterUIServer(core.NewUIServerAPI(apiImpl)) api = apiImpl // Audit logging - if logfile := c.GlobalString(auditLogFlag.Name); logfile != "" { + if logfile := c.String(auditLogFlag.Name); logfile != "" { api, err = core.NewAuditLogger(logfile, api) if err != nil { utils.Fatalf(err.Error()) @@ -688,9 +625,9 @@ func signer(c *cli.Context) error { } // - if c.GlobalBool(utils.HTTPEnabledFlag.Name) { - vhosts := utils.SplitAndTrim(c.GlobalString(utils.HTTPVirtualHostsFlag.Name)) - cors := utils.SplitAndTrim(c.GlobalString(utils.HTTPCORSDomainFlag.Name)) + if c.Bool(utils.HTTPEnabledFlag.Name) { + vhosts := utils.SplitAndTrim(c.String(utils.HTTPVirtualHostsFlag.Name)) + cors := utils.SplitAndTrim(c.String(utils.HTTPCORSDomainFlag.Name)) srv := rpc.NewServer() err := node.RegisterApisFromWhitelist(rpcAPI, []string{"account", "plugin@account"}, srv, true) @@ -703,7 +640,7 @@ func signer(c *cli.Context) error { port := c.Int(rpcPortFlag.Name) // start http server - httpEndpoint := fmt.Sprintf("%s:%d", c.GlobalString(utils.HTTPListenAddrFlag.Name), port) + httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.HTTPListenAddrFlag.Name), port) httpServer, addr, _, err := node.StartHTTPEndpoint(httpEndpoint, rpc.DefaultHTTPTimeouts, handler, nil) if err != nil { utils.Fatalf("Could not start RPC api: %v", err) @@ -717,8 +654,8 @@ func signer(c *cli.Context) error { log.Info("HTTP endpoint closed", "url", extapiURL) }() } - if !c.GlobalBool(utils.IPCDisabledFlag.Name) { - givenPath := c.GlobalString(utils.IPCPathFlag.Name) + if !c.Bool(utils.IPCDisabledFlag.Name) { + givenPath := c.String(utils.IPCPathFlag.Name) ipcapiURL = ipcEndpoint(filepath.Join(givenPath, "clef.ipc"), configDir) listener, _, err := rpc.StartIPCEndpoint(ipcapiURL, rpcAPI) if err != nil { @@ -731,7 +668,7 @@ func signer(c *cli.Context) error { }() } - if c.GlobalBool(testFlag.Name) { + if c.Bool(testFlag.Name) { log.Info("Performing UI test") go testExternalUI(apiImpl) } @@ -799,7 +736,7 @@ func addPluginAPIs(pm *plugin.PluginManager, rpcAPI []rpc.API, ui core.UIClientA // persistence requirements. func DefaultConfigDir() string { // Try to place the data folder in the user's home dir - home := utils.HomeDir() + home := flags.HomeDir() if home != "" { if runtime.GOOS == "darwin" { return filepath.Join(home, "Library", "Signer") @@ -819,10 +756,10 @@ func DefaultConfigDir() string { func readMasterKey(ctx *cli.Context, ui core.UIClientAPI) ([]byte, error) { var ( file string - configDir = ctx.GlobalString(configdirFlag.Name) + configDir = ctx.String(configdirFlag.Name) ) - if ctx.GlobalIsSet(signerSecretFlag.Name) { - file = ctx.GlobalString(signerSecretFlag.Name) + if ctx.IsSet(signerSecretFlag.Name) { + file = ctx.String(signerSecretFlag.Name) } else { file = filepath.Join(configDir, "masterseed.json") } @@ -1072,7 +1009,7 @@ func decryptSeed(keyjson []byte, auth string) ([]byte, error) { } // GenDoc outputs examples of all structures used in json-rpc communication -func GenDoc(ctx *cli.Context) { +func GenDoc(ctx *cli.Context) error { var ( a = common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef") b = common.HexToAddress("0x1111111122222222222233333333334444444444") @@ -1220,6 +1157,7 @@ These data types are defined in the channel between clef and the UI`) for _, elem := range output { fmt.Println(elem) } + return nil } // Quorum diff --git a/cmd/devp2p/discv4cmd.go b/cmd/devp2p/discv4cmd.go index 3b6dc09a1..9d35880b1 100644 --- a/cmd/devp2p/discv4cmd.go +++ b/cmd/devp2p/discv4cmd.go @@ -25,17 +25,18 @@ import ( "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v4test" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - discv4Command = cli.Command{ + discv4Command = &cli.Command{ Name: "discv4", Usage: "Node Discovery v4 tools", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ discv4PingCommand, discv4RequestRecordCommand, discv4ResolveCommand, @@ -44,39 +45,41 @@ var ( discv4TestCommand, }, } - discv4PingCommand = cli.Command{ + discv4PingCommand = &cli.Command{ Name: "ping", Usage: "Sends ping to a node", Action: discv4Ping, ArgsUsage: "", + Flags: v4NodeFlags, } - discv4RequestRecordCommand = cli.Command{ + discv4RequestRecordCommand = &cli.Command{ Name: "requestenr", Usage: "Requests a node record using EIP-868 enrRequest", Action: discv4RequestRecord, ArgsUsage: "", + Flags: v4NodeFlags, } - discv4ResolveCommand = cli.Command{ + discv4ResolveCommand = &cli.Command{ Name: "resolve", Usage: "Finds a node in the DHT", Action: discv4Resolve, ArgsUsage: "", - Flags: []cli.Flag{bootnodesFlag}, + Flags: v4NodeFlags, } - discv4ResolveJSONCommand = cli.Command{ + discv4ResolveJSONCommand = &cli.Command{ Name: "resolve-json", Usage: "Re-resolves nodes in a nodes.json file", Action: discv4ResolveJSON, - Flags: []cli.Flag{bootnodesFlag}, + Flags: v4NodeFlags, ArgsUsage: "", } - discv4CrawlCommand = cli.Command{ + discv4CrawlCommand = &cli.Command{ Name: "crawl", Usage: "Updates a nodes.json file with random nodes found in the DHT", Action: discv4Crawl, - Flags: []cli.Flag{bootnodesFlag, crawlTimeoutFlag}, + Flags: flags.Merge(v4NodeFlags, []cli.Flag{crawlTimeoutFlag}), } - discv4TestCommand = cli.Command{ + discv4TestCommand = &cli.Command{ Name: "test", Usage: "Runs tests against a node", Action: discv4Test, @@ -91,34 +94,41 @@ var ( ) var ( - bootnodesFlag = cli.StringFlag{ + bootnodesFlag = &cli.StringFlag{ Name: "bootnodes", Usage: "Comma separated nodes used for bootstrapping", } - nodekeyFlag = cli.StringFlag{ + nodekeyFlag = &cli.StringFlag{ Name: "nodekey", Usage: "Hex-encoded node key", } - nodedbFlag = cli.StringFlag{ + nodedbFlag = &cli.StringFlag{ Name: "nodedb", Usage: "Nodes database location", } - listenAddrFlag = cli.StringFlag{ + listenAddrFlag = &cli.StringFlag{ Name: "addr", Usage: "Listening address", } - crawlTimeoutFlag = cli.DurationFlag{ + crawlTimeoutFlag = &cli.DurationFlag{ Name: "timeout", Usage: "Time limit for the crawl.", Value: 30 * time.Minute, } - remoteEnodeFlag = cli.StringFlag{ - Name: "remote", - Usage: "Enode of the remote node under test", - EnvVar: "REMOTE_ENODE", + remoteEnodeFlag = &cli.StringFlag{ + Name: "remote", + Usage: "Enode of the remote node under test", + EnvVars: []string{"REMOTE_ENODE"}, } ) +var v4NodeFlags = []cli.Flag{ + bootnodesFlag, + nodekeyFlag, + nodedbFlag, + listenAddrFlag, +} + func discv4Ping(ctx *cli.Context) error { n := getNodeArg(ctx) disc := startV4(ctx) diff --git a/cmd/devp2p/discv5cmd.go b/cmd/devp2p/discv5cmd.go index e20d7c9cf..4fc98edb9 100644 --- a/cmd/devp2p/discv5cmd.go +++ b/cmd/devp2p/discv5cmd.go @@ -23,14 +23,14 @@ import ( "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v5test" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/p2p/discover" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - discv5Command = cli.Command{ + discv5Command = &cli.Command{ Name: "discv5", Usage: "Node Discovery v5 tools", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ discv5PingCommand, discv5ResolveCommand, discv5CrawlCommand, @@ -38,24 +38,24 @@ var ( discv5ListenCommand, }, } - discv5PingCommand = cli.Command{ + discv5PingCommand = &cli.Command{ Name: "ping", Usage: "Sends ping to a node", Action: discv5Ping, } - discv5ResolveCommand = cli.Command{ + discv5ResolveCommand = &cli.Command{ Name: "resolve", Usage: "Finds a node in the DHT", Action: discv5Resolve, Flags: []cli.Flag{bootnodesFlag}, } - discv5CrawlCommand = cli.Command{ + discv5CrawlCommand = &cli.Command{ Name: "crawl", Usage: "Updates a nodes.json file with random nodes found in the DHT", Action: discv5Crawl, Flags: []cli.Flag{bootnodesFlag, crawlTimeoutFlag}, } - discv5TestCommand = cli.Command{ + discv5TestCommand = &cli.Command{ Name: "test", Usage: "Runs protocol tests against a node", Action: discv5Test, @@ -66,7 +66,7 @@ var ( testListen2Flag, }, } - discv5ListenCommand = cli.Command{ + discv5ListenCommand = &cli.Command{ Name: "listen", Usage: "Runs a node", Action: discv5Listen, diff --git a/cmd/devp2p/dns_cloudflare.go b/cmd/devp2p/dns_cloudflare.go index b9f4d21c5..d5e010935 100644 --- a/cmd/devp2p/dns_cloudflare.go +++ b/cmd/devp2p/dns_cloudflare.go @@ -24,16 +24,16 @@ import ( "github.com/cloudflare/cloudflare-go" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/dnsdisc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - cloudflareTokenFlag = cli.StringFlag{ - Name: "token", - Usage: "CloudFlare API token", - EnvVar: "CLOUDFLARE_API_TOKEN", + cloudflareTokenFlag = &cli.StringFlag{ + Name: "token", + Usage: "CloudFlare API token", + EnvVars: []string{"CLOUDFLARE_API_TOKEN"}, } - cloudflareZoneIDFlag = cli.StringFlag{ + cloudflareZoneIDFlag = &cli.StringFlag{ Name: "zoneid", Usage: "CloudFlare Zone ID (optional)", } diff --git a/cmd/devp2p/dns_route53.go b/cmd/devp2p/dns_route53.go index 1d4f975dd..4aab0856f 100644 --- a/cmd/devp2p/dns_route53.go +++ b/cmd/devp2p/dns_route53.go @@ -32,7 +32,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/route53/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/dnsdisc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( @@ -45,21 +45,21 @@ const ( ) var ( - route53AccessKeyFlag = cli.StringFlag{ - Name: "access-key-id", - Usage: "AWS Access Key ID", - EnvVar: "AWS_ACCESS_KEY_ID", + route53AccessKeyFlag = &cli.StringFlag{ + Name: "access-key-id", + Usage: "AWS Access Key ID", + EnvVars: []string{"AWS_ACCESS_KEY_ID"}, } - route53AccessSecretFlag = cli.StringFlag{ - Name: "access-key-secret", - Usage: "AWS Access Key Secret", - EnvVar: "AWS_SECRET_ACCESS_KEY", + route53AccessSecretFlag = &cli.StringFlag{ + Name: "access-key-secret", + Usage: "AWS Access Key Secret", + EnvVars: []string{"AWS_SECRET_ACCESS_KEY"}, } - route53ZoneIDFlag = cli.StringFlag{ + route53ZoneIDFlag = &cli.StringFlag{ Name: "zone-id", Usage: "Route53 Zone ID", } - route53RegionFlag = cli.StringFlag{ + route53RegionFlag = &cli.StringFlag{ Name: "aws-region", Usage: "AWS Region", Value: "eu-central-1", diff --git a/cmd/devp2p/dnscmd.go b/cmd/devp2p/dnscmd.go index 92267c81c..85f18d5ff 100644 --- a/cmd/devp2p/dnscmd.go +++ b/cmd/devp2p/dnscmd.go @@ -29,14 +29,14 @@ import ( "github.com/ethereum/go-ethereum/console/prompt" "github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/ethereum/go-ethereum/p2p/enode" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - dnsCommand = cli.Command{ + dnsCommand = &cli.Command{ Name: "dns", Usage: "DNS Discovery Commands", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ dnsSyncCommand, dnsSignCommand, dnsTXTCommand, @@ -45,34 +45,34 @@ var ( dnsRoute53NukeCommand, }, } - dnsSyncCommand = cli.Command{ + dnsSyncCommand = &cli.Command{ Name: "sync", Usage: "Download a DNS discovery tree", ArgsUsage: " [ ]", Action: dnsSync, Flags: []cli.Flag{dnsTimeoutFlag}, } - dnsSignCommand = cli.Command{ + dnsSignCommand = &cli.Command{ Name: "sign", Usage: "Sign a DNS discovery tree", ArgsUsage: " ", Action: dnsSign, Flags: []cli.Flag{dnsDomainFlag, dnsSeqFlag}, } - dnsTXTCommand = cli.Command{ + dnsTXTCommand = &cli.Command{ Name: "to-txt", Usage: "Create a DNS TXT records for a discovery tree", ArgsUsage: " ", Action: dnsToTXT, } - dnsCloudflareCommand = cli.Command{ + dnsCloudflareCommand = &cli.Command{ Name: "to-cloudflare", Usage: "Deploy DNS TXT records to CloudFlare", ArgsUsage: "", Action: dnsToCloudflare, Flags: []cli.Flag{cloudflareTokenFlag, cloudflareZoneIDFlag}, } - dnsRoute53Command = cli.Command{ + dnsRoute53Command = &cli.Command{ Name: "to-route53", Usage: "Deploy DNS TXT records to Amazon Route53", ArgsUsage: "", @@ -84,7 +84,7 @@ var ( route53RegionFlag, }, } - dnsRoute53NukeCommand = cli.Command{ + dnsRoute53NukeCommand = &cli.Command{ Name: "nuke-route53", Usage: "Deletes DNS TXT records of a subdomain on Amazon Route53", ArgsUsage: "", @@ -99,15 +99,15 @@ var ( ) var ( - dnsTimeoutFlag = cli.DurationFlag{ + dnsTimeoutFlag = &cli.DurationFlag{ Name: "timeout", Usage: "Timeout for DNS lookups", } - dnsDomainFlag = cli.StringFlag{ + dnsDomainFlag = &cli.StringFlag{ Name: "domain", Usage: "Domain name of the tree", } - dnsSeqFlag = cli.UintFlag{ + dnsSeqFlag = &cli.UintFlag{ Name: "seq", Usage: "New sequence number of the tree", } diff --git a/cmd/devp2p/enrcmd.go b/cmd/devp2p/enrcmd.go index fa1239d93..8f2b1af9f 100644 --- a/cmd/devp2p/enrcmd.go +++ b/cmd/devp2p/enrcmd.go @@ -30,15 +30,15 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var enrdumpCommand = cli.Command{ +var enrdumpCommand = &cli.Command{ Name: "enrdump", Usage: "Pretty-prints node records", Action: enrdump, Flags: []cli.Flag{ - cli.StringFlag{Name: "file"}, + &cli.StringFlag{Name: "file"}, }, } @@ -60,7 +60,7 @@ func enrdump(ctx *cli.Context) error { } source = string(b) } else if ctx.NArg() == 1 { - source = ctx.Args()[0] + source = ctx.Args().First() } else { return fmt.Errorf("need record as argument") } diff --git a/cmd/devp2p/keycmd.go b/cmd/devp2p/keycmd.go index 869b8c2a4..e824abe65 100644 --- a/cmd/devp2p/keycmd.go +++ b/cmd/devp2p/keycmd.go @@ -22,25 +22,25 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enode" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - keyCommand = cli.Command{ + keyCommand = &cli.Command{ Name: "key", Usage: "Operations on node keys", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ keyGenerateCommand, keyToNodeCommand, }, } - keyGenerateCommand = cli.Command{ + keyGenerateCommand = &cli.Command{ Name: "generate", Usage: "Generates node key files", ArgsUsage: "keyfile", Action: genkey, } - keyToNodeCommand = cli.Command{ + keyToNodeCommand = &cli.Command{ Name: "to-enode", Usage: "Creates an enode URL from a node key file", ArgsUsage: "keyfile", @@ -50,17 +50,17 @@ var ( ) var ( - hostFlag = cli.StringFlag{ + hostFlag = &cli.StringFlag{ Name: "ip", Usage: "IP address of the node", Value: "127.0.0.1", } - tcpPortFlag = cli.IntFlag{ + tcpPortFlag = &cli.IntFlag{ Name: "tcp", Usage: "TCP port of the node", Value: 30303, } - udpPortFlag = cli.IntFlag{ + udpPortFlag = &cli.IntFlag{ Name: "udp", Usage: "UDP port of the node", Value: 30303, diff --git a/cmd/devp2p/main.go b/cmd/devp2p/main.go index 4a4e905a4..51b9fdb76 100644 --- a/cmd/devp2p/main.go +++ b/cmd/devp2p/main.go @@ -20,12 +20,12 @@ import ( "fmt" "os" "path/filepath" - "sort" "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( @@ -45,6 +45,7 @@ func init() { // Set up the CLI app. app.Flags = append(app.Flags, debug.Flags...) app.Before = func(ctx *cli.Context) error { + flags.MigrateGlobalFlags(ctx) return debug.Setup(ctx) } app.After = func(ctx *cli.Context) error { @@ -56,7 +57,7 @@ func init() { os.Exit(1) } // Add subcommands. - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ enrdumpCommand, keyCommand, discv4Command, @@ -73,10 +74,17 @@ func main() { // commandHasFlag returns true if the current command supports the given flag. func commandHasFlag(ctx *cli.Context, flag cli.Flag) bool { - flags := ctx.FlagNames() - sort.Strings(flags) - i := sort.SearchStrings(flags, flag.GetName()) - return i != len(flags) && flags[i] == flag.GetName() + names := flag.Names() + set := make(map[string]struct{}, len(names)) + for _, name := range names { + set[name] = struct{}{} + } + for _, fn := range ctx.FlagNames() { + if _, ok := set[fn]; ok { + return true + } + } + return false } // getNodeArg handles the common case of a single node descriptor argument. @@ -84,7 +92,7 @@ func getNodeArg(ctx *cli.Context) *enode.Node { if ctx.NArg() < 1 { exit("missing node as command-line argument") } - n, err := parseNode(ctx.Args()[0]) + n, err := parseNode(ctx.Args().First()) if err != nil { exit(err) } diff --git a/cmd/devp2p/nodesetcmd.go b/cmd/devp2p/nodesetcmd.go index 9e689f97e..3d42eff81 100644 --- a/cmd/devp2p/nodesetcmd.go +++ b/cmd/devp2p/nodesetcmd.go @@ -29,25 +29,25 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - nodesetCommand = cli.Command{ + nodesetCommand = &cli.Command{ Name: "nodeset", Usage: "Node set tools", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ nodesetInfoCommand, nodesetFilterCommand, }, } - nodesetInfoCommand = cli.Command{ + nodesetInfoCommand = &cli.Command{ Name: "info", Usage: "Shows statistics about a node set", Action: nodesetInfo, ArgsUsage: "", } - nodesetFilterCommand = cli.Command{ + nodesetFilterCommand = &cli.Command{ Name: "filter", Usage: "Filters a node set", Action: nodesetFilter, diff --git a/cmd/devp2p/rlpxcmd.go b/cmd/devp2p/rlpxcmd.go index 24a16f0b3..336514a1f 100644 --- a/cmd/devp2p/rlpxcmd.go +++ b/cmd/devp2p/rlpxcmd.go @@ -26,24 +26,24 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/rlpx" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - rlpxCommand = cli.Command{ + rlpxCommand = &cli.Command{ Name: "rlpx", Usage: "RLPx Commands", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ rlpxPingCommand, rlpxEthTestCommand, }, } - rlpxPingCommand = cli.Command{ + rlpxPingCommand = &cli.Command{ Name: "ping", Usage: "ping ", Action: rlpxPing, } - rlpxEthTestCommand = cli.Command{ + rlpxEthTestCommand = &cli.Command{ Name: "eth-test", Usage: "Runs tests against a node", ArgsUsage: " ", @@ -95,7 +95,7 @@ func rlpxEthTest(ctx *cli.Context) error { if ctx.NArg() < 3 { exit("missing path to chain.rlp as command-line argument") } - suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args()[1], ctx.Args()[2]) + suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args().Get(1), ctx.Args().Get(2)) if err != nil { exit(err) } diff --git a/cmd/devp2p/runtest.go b/cmd/devp2p/runtest.go index 4168f8555..f72aa9111 100644 --- a/cmd/devp2p/runtest.go +++ b/cmd/devp2p/runtest.go @@ -22,25 +22,25 @@ import ( "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v4test" "github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - testPatternFlag = cli.StringFlag{ + testPatternFlag = &cli.StringFlag{ Name: "run", Usage: "Pattern of test suite(s) to run", } - testTAPFlag = cli.BoolFlag{ + testTAPFlag = &cli.BoolFlag{ Name: "tap", Usage: "Output TAP", } // These two are specific to the discovery tests. - testListen1Flag = cli.StringFlag{ + testListen1Flag = &cli.StringFlag{ Name: "listen1", Usage: "IP address of the first tester", Value: v4test.Listen1, } - testListen2Flag = cli.StringFlag{ + testListen2Flag = &cli.StringFlag{ Name: "listen2", Usage: "IP address of the second tester", Value: v4test.Listen2, @@ -53,7 +53,7 @@ func runTests(ctx *cli.Context, tests []utesting.Test) error { tests = utesting.MatchTests(tests, ctx.String(testPatternFlag.Name)) } // Disable logging unless explicitly enabled. - if !ctx.GlobalIsSet("verbosity") && !ctx.GlobalIsSet("vmodule") { + if !ctx.IsSet("verbosity") && !ctx.IsSet("vmodule") { log.Root().SetHandler(log.DiscardHandler()) } // Run the tests. diff --git a/cmd/ethkey/changepassword.go b/cmd/ethkey/changepassword.go index bd8745f6d..4298e2b83 100644 --- a/cmd/ethkey/changepassword.go +++ b/cmd/ethkey/changepassword.go @@ -23,15 +23,15 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var newPassphraseFlag = cli.StringFlag{ +var newPassphraseFlag = &cli.StringFlag{ Name: "newpasswordfile", Usage: "the file that contains the new password for the keyfile", } -var commandChangePassphrase = cli.Command{ +var commandChangePassphrase = &cli.Command{ Name: "changepassword", Usage: "change the password on a keyfile", ArgsUsage: "", diff --git a/cmd/ethkey/generate.go b/cmd/ethkey/generate.go index 71dd9eb62..a1292925c 100644 --- a/cmd/ethkey/generate.go +++ b/cmd/ethkey/generate.go @@ -26,7 +26,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" "github.com/google/uuid" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) type outputGenerate struct { @@ -34,7 +34,7 @@ type outputGenerate struct { AddressEIP55 string } -var commandGenerate = cli.Command{ +var commandGenerate = &cli.Command{ Name: "generate", Usage: "generate new keyfile", ArgsUsage: "[ ]", @@ -47,11 +47,11 @@ If you want to encrypt an existing private key, it can be specified by setting Flags: []cli.Flag{ passphraseFlag, jsonFlag, - cli.StringFlag{ + &cli.StringFlag{ Name: "privatekey", Usage: "file containing a raw private key to encrypt", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "lightkdf", Usage: "use less secure scrypt parameters", }, diff --git a/cmd/ethkey/inspect.go b/cmd/ethkey/inspect.go index 6a21808d4..ca507d5bf 100644 --- a/cmd/ethkey/inspect.go +++ b/cmd/ethkey/inspect.go @@ -24,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) type outputInspect struct { @@ -33,7 +33,7 @@ type outputInspect struct { PrivateKey string } -var commandInspect = cli.Command{ +var commandInspect = &cli.Command{ Name: "inspect", Usage: "inspect a keyfile", ArgsUsage: "", @@ -45,7 +45,7 @@ make sure to use this feature with great caution!`, Flags: []cli.Flag{ passphraseFlag, jsonFlag, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "private", Usage: "include the private key in the output", }, diff --git a/cmd/ethkey/main.go b/cmd/ethkey/main.go index 6db39174c..2b21f3cd7 100644 --- a/cmd/ethkey/main.go +++ b/cmd/ethkey/main.go @@ -21,7 +21,7 @@ import ( "os" "github.com/ethereum/go-ethereum/internal/flags" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( @@ -36,23 +36,22 @@ var app *cli.App func init() { app = flags.NewApp(gitCommit, gitDate, "an Ethereum key manager") - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ commandGenerate, commandInspect, commandChangePassphrase, commandSignMessage, commandVerifyMessage, } - cli.CommandHelpTemplate = flags.OriginCommandHelpTemplate } // Commonly used command line flags. var ( - passphraseFlag = cli.StringFlag{ + passphraseFlag = &cli.StringFlag{ Name: "passwordfile", Usage: "the file that contains the password for the keyfile", } - jsonFlag = cli.BoolFlag{ + jsonFlag = &cli.BoolFlag{ Name: "json", Usage: "output JSON instead of human-readable format", } diff --git a/cmd/ethkey/message.go b/cmd/ethkey/message.go index 899d62d5f..1dc3e6469 100644 --- a/cmd/ethkey/message.go +++ b/cmd/ethkey/message.go @@ -25,19 +25,19 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) type outputSign struct { Signature string } -var msgfileFlag = cli.StringFlag{ +var msgfileFlag = &cli.StringFlag{ Name: "msgfile", Usage: "file containing the message to sign/verify", } -var commandSignMessage = cli.Command{ +var commandSignMessage = &cli.Command{ Name: "signmessage", Usage: "sign a message", ArgsUsage: " ", @@ -88,7 +88,7 @@ type outputVerify struct { RecoveredPublicKey string } -var commandVerifyMessage = cli.Command{ +var commandVerifyMessage = &cli.Command{ Name: "verifymessage", Usage: "verify the signature of a signed message", ArgsUsage: "
", @@ -143,7 +143,7 @@ It is possible to refer to a file containing the message.`, func getMessage(ctx *cli.Context, msgarg int) []byte { if file := ctx.String("msgfile"); file != "" { - if len(ctx.Args()) > msgarg { + if ctx.NArg() > msgarg { utils.Fatalf("Can't use --msgfile and message argument at the same time.") } msg, err := os.ReadFile(file) @@ -151,9 +151,9 @@ func getMessage(ctx *cli.Context, msgarg int) []byte { utils.Fatalf("Can't read message file: %v", err) } return msg - } else if len(ctx.Args()) == msgarg+1 { + } else if ctx.NArg() == msgarg+1 { return []byte(ctx.Args().Get(msgarg)) } - utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, len(ctx.Args())) + utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, ctx.NArg()) return nil } diff --git a/cmd/ethkey/utils.go b/cmd/ethkey/utils.go index 6d0169d80..0f186791b 100644 --- a/cmd/ethkey/utils.go +++ b/cmd/ethkey/utils.go @@ -24,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) // getPassphrase obtains a passphrase given by the user. It first checks the diff --git a/cmd/evm/compiler.go b/cmd/evm/compiler.go index 880f995f0..699d434bb 100644 --- a/cmd/evm/compiler.go +++ b/cmd/evm/compiler.go @@ -23,10 +23,10 @@ import ( "github.com/ethereum/go-ethereum/cmd/evm/internal/compiler" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var compileCommand = cli.Command{ +var compileCommand = &cli.Command{ Action: compileCmd, Name: "compile", Usage: "compiles easm source to evm binary", @@ -34,7 +34,7 @@ var compileCommand = cli.Command{ } func compileCmd(ctx *cli.Context) error { - debug := ctx.GlobalBool(DebugFlag.Name) + debug := ctx.Bool(DebugFlag.Name) if len(ctx.Args().First()) == 0 { return errors.New("filename required") diff --git a/cmd/evm/disasm.go b/cmd/evm/disasm.go index 776a9b3dc..c0b3ff313 100644 --- a/cmd/evm/disasm.go +++ b/cmd/evm/disasm.go @@ -23,10 +23,10 @@ import ( "strings" "github.com/ethereum/go-ethereum/core/asm" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var disasmCommand = cli.Command{ +var disasmCommand = &cli.Command{ Action: disasmCmd, Name: "disasm", Usage: "disassembles evm binary", @@ -43,8 +43,8 @@ func disasmCmd(ctx *cli.Context) error { return err } in = string(input) - case ctx.GlobalIsSet(InputFlag.Name): - in = ctx.GlobalString(InputFlag.Name) + case ctx.IsSet(InputFlag.Name): + in = ctx.String(InputFlag.Name) default: return errors.New("Missing filename or --input value") } diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index a599462cc..aeafe396e 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -22,37 +22,37 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/tests" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - TraceFlag = cli.BoolFlag{ + TraceFlag = &cli.BoolFlag{ Name: "trace", Usage: "Output full trace logs to files .jsonl", } - TraceDisableMemoryFlag = cli.BoolFlag{ + TraceDisableMemoryFlag = &cli.BoolFlag{ Name: "trace.nomemory", Usage: "Disable full memory dump in traces", } - TraceDisableStackFlag = cli.BoolFlag{ + TraceDisableStackFlag = &cli.BoolFlag{ Name: "trace.nostack", Usage: "Disable stack output in traces", } - TraceDisableReturnDataFlag = cli.BoolFlag{ + TraceDisableReturnDataFlag = &cli.BoolFlag{ Name: "trace.noreturndata", Usage: "Disable return data output in traces", } - OutputBasedir = cli.StringFlag{ + OutputBasedir = &cli.StringFlag{ Name: "output.basedir", Usage: "Specifies where output files are placed. Will be created if it does not exist.", Value: "", } - OutputBodyFlag = cli.StringFlag{ + OutputBodyFlag = &cli.StringFlag{ Name: "output.body", Usage: "If set, the RLP of the transactions (block body) will be written to this file.", Value: "", } - OutputAllocFlag = cli.StringFlag{ + OutputAllocFlag = &cli.StringFlag{ Name: "output.alloc", Usage: "Determines where to put the `alloc` of the post-state.\n" + "\t`stdout` - into the stdout output\n" + @@ -60,7 +60,7 @@ var ( "\t - into the file ", Value: "alloc.json", } - OutputResultFlag = cli.StringFlag{ + OutputResultFlag = &cli.StringFlag{ Name: "output.result", Usage: "Determines where to put the `result` (stateroot, txroot etc) of the post-state.\n" + "\t`stdout` - into the stdout output\n" + @@ -68,32 +68,32 @@ var ( "\t - into the file ", Value: "result.json", } - InputAllocFlag = cli.StringFlag{ + InputAllocFlag = &cli.StringFlag{ Name: "input.alloc", Usage: "`stdin` or file name of where to find the prestate alloc to use.", Value: "alloc.json", } - InputEnvFlag = cli.StringFlag{ + InputEnvFlag = &cli.StringFlag{ Name: "input.env", Usage: "`stdin` or file name of where to find the prestate env to use.", Value: "env.json", } - InputTxsFlag = cli.StringFlag{ + InputTxsFlag = &cli.StringFlag{ Name: "input.txs", Usage: "`stdin` or file name of where to find the transactions to apply.", Value: "txs.json", } - RewardFlag = cli.Int64Flag{ + RewardFlag = &cli.Int64Flag{ Name: "state.reward", Usage: "Mining reward. Set to -1 to disable", Value: 0, } - ChainIDFlag = cli.Int64Flag{ + ChainIDFlag = &cli.Int64Flag{ Name: "state.chainid", Usage: "ChainID to use", Value: 1, } - ForknameFlag = cli.StringFlag{ + ForknameFlag = &cli.StringFlag{ Name: "state.fork", Usage: fmt.Sprintf("Name of ruleset to use."+ "\n\tAvailable forknames:"+ @@ -105,7 +105,7 @@ var ( strings.Join(vm.ActivateableEips(), ", ")), Value: "Istanbul", } - VerbosityFlag = cli.IntFlag{ + VerbosityFlag = &cli.IntFlag{ Name: "verbosity", Usage: "sets the verbosity level", Value: 3, diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 795d1596a..8d2393826 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -35,7 +35,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 8a3e4e0ea..19e73a56e 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -23,120 +23,121 @@ import ( "os" "github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool" - "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/internal/flags" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) -var gitDate = "" - var ( + gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) + gitDate = "" + app = flags.NewApp(gitCommit, gitDate, "the evm command line interface") +) - DebugFlag = cli.BoolFlag{ +var ( + DebugFlag = &cli.BoolFlag{ Name: "debug", Usage: "output full trace logs", } - MemProfileFlag = cli.StringFlag{ + MemProfileFlag = &cli.StringFlag{ Name: "memprofile", Usage: "creates a memory profile at the given path", } - CPUProfileFlag = cli.StringFlag{ + CPUProfileFlag = &cli.StringFlag{ Name: "cpuprofile", Usage: "creates a CPU profile at the given path", } - StatDumpFlag = cli.BoolFlag{ + StatDumpFlag = &cli.BoolFlag{ Name: "statdump", Usage: "displays stack and heap memory information", } - CodeFlag = cli.StringFlag{ + CodeFlag = &cli.StringFlag{ Name: "code", Usage: "EVM code", } - CodeFileFlag = cli.StringFlag{ + CodeFileFlag = &cli.StringFlag{ Name: "codefile", Usage: "File containing EVM code. If '-' is specified, code is read from stdin ", } - GasFlag = cli.Uint64Flag{ + GasFlag = &cli.Uint64Flag{ Name: "gas", Usage: "gas limit for the evm", Value: 10000000000, } - PriceFlag = utils.BigFlag{ + PriceFlag = &flags.BigFlag{ Name: "price", Usage: "price set for the evm", Value: new(big.Int), } - ValueFlag = utils.BigFlag{ + ValueFlag = &flags.BigFlag{ Name: "value", Usage: "value set for the evm", Value: new(big.Int), } - DumpFlag = cli.BoolFlag{ + DumpFlag = &cli.BoolFlag{ Name: "dump", Usage: "dumps the state after the run", } - InputFlag = cli.StringFlag{ + InputFlag = &cli.StringFlag{ Name: "input", Usage: "input for the EVM", } - InputFileFlag = cli.StringFlag{ + InputFileFlag = &cli.StringFlag{ Name: "inputfile", Usage: "file containing input for the EVM", } - VerbosityFlag = cli.IntFlag{ + VerbosityFlag = &cli.IntFlag{ Name: "verbosity", Usage: "sets the verbosity level", } - BenchFlag = cli.BoolFlag{ + BenchFlag = &cli.BoolFlag{ Name: "bench", Usage: "benchmark the execution", } - CreateFlag = cli.BoolFlag{ + CreateFlag = &cli.BoolFlag{ Name: "create", Usage: "indicates the action should be create rather than call", } - GenesisFlag = cli.StringFlag{ + GenesisFlag = &cli.StringFlag{ Name: "prestate", Usage: "JSON file with prestate (genesis) config", } - MachineFlag = cli.BoolFlag{ + MachineFlag = &cli.BoolFlag{ Name: "json", Usage: "output trace logs in machine readable format (json)", } - SenderFlag = cli.StringFlag{ + SenderFlag = &cli.StringFlag{ Name: "sender", Usage: "The transaction origin", } - ReceiverFlag = cli.StringFlag{ + ReceiverFlag = &cli.StringFlag{ Name: "receiver", Usage: "The transaction receiver (execution context)", } - DisableMemoryFlag = cli.BoolFlag{ + DisableMemoryFlag = &cli.BoolFlag{ Name: "nomemory", Usage: "disable memory output", } - DisableStackFlag = cli.BoolFlag{ + DisableStackFlag = &cli.BoolFlag{ Name: "nostack", Usage: "disable stack output", } - DisableStorageFlag = cli.BoolFlag{ + DisableStorageFlag = &cli.BoolFlag{ Name: "nostorage", Usage: "disable storage output", } - DisableReturnDataFlag = cli.BoolFlag{ + DisableReturnDataFlag = &cli.BoolFlag{ Name: "noreturndata", Usage: "disable return data output", } - EVMInterpreterFlag = cli.StringFlag{ + EVMInterpreterFlag = &cli.StringFlag{ Name: "vm.evm", Usage: "External EVM configuration (default = built-in interpreter)", Value: "", } ) -var stateTransitionCommand = cli.Command{ +var stateTransitionCommand = &cli.Command{ Name: "transition", Aliases: []string{"t8n"}, Usage: "executes a full state transition", @@ -187,14 +188,13 @@ func init() { DisableReturnDataFlag, EVMInterpreterFlag, } - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ compileCommand, disasmCommand, runCommand, stateTestCommand, stateTransitionCommand, } - cli.CommandHelpTemplate = flags.OriginCommandHelpTemplate } func main() { diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 8a2dbd19d..b02c4a169 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -36,12 +36,13 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm/runtime" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var runCommand = cli.Command{ +var runCommand = &cli.Command{ Action: runCmd, Name: "run", Usage: "run arbitrary evm binary", @@ -105,14 +106,14 @@ func timedExec(bench bool, execFunc func() ([]byte, uint64, error)) (output []by func runCmd(ctx *cli.Context) error { glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) - glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name))) + glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) log.Root().SetHandler(glogger) logconfig := &vm.LogConfig{ - DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name), - DisableStack: ctx.GlobalBool(DisableStackFlag.Name), - DisableStorage: ctx.GlobalBool(DisableStorageFlag.Name), - DisableReturnData: ctx.GlobalBool(DisableReturnDataFlag.Name), - Debug: ctx.GlobalBool(DebugFlag.Name), + DisableMemory: ctx.Bool(DisableMemoryFlag.Name), + DisableStack: ctx.Bool(DisableStackFlag.Name), + DisableStorage: ctx.Bool(DisableStorageFlag.Name), + DisableReturnData: ctx.Bool(DisableReturnDataFlag.Name), + Debug: ctx.Bool(DebugFlag.Name), } var ( @@ -124,16 +125,16 @@ func runCmd(ctx *cli.Context) error { receiver = common.BytesToAddress([]byte("receiver")) genesisConfig *core.Genesis ) - if ctx.GlobalBool(MachineFlag.Name) { + if ctx.Bool(MachineFlag.Name) { tracer = vm.NewJSONLogger(logconfig, os.Stdout) - } else if ctx.GlobalBool(DebugFlag.Name) { + } else if ctx.Bool(DebugFlag.Name) { debugLogger = vm.NewStructLogger(logconfig) tracer = debugLogger } else { debugLogger = vm.NewStructLogger(logconfig) } - if ctx.GlobalString(GenesisFlag.Name) != "" { - gen := readGenesis(ctx.GlobalString(GenesisFlag.Name)) + if ctx.String(GenesisFlag.Name) != "" { + gen := readGenesis(ctx.String(GenesisFlag.Name)) genesisConfig = gen db := rawdb.NewMemoryDatabase() genesis := gen.ToBlock(db) @@ -143,18 +144,18 @@ func runCmd(ctx *cli.Context) error { statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) genesisConfig = new(core.Genesis) } - if ctx.GlobalString(SenderFlag.Name) != "" { - sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name)) + if ctx.String(SenderFlag.Name) != "" { + sender = common.HexToAddress(ctx.String(SenderFlag.Name)) } statedb.CreateAccount(sender) - if ctx.GlobalString(ReceiverFlag.Name) != "" { - receiver = common.HexToAddress(ctx.GlobalString(ReceiverFlag.Name)) + if ctx.String(ReceiverFlag.Name) != "" { + receiver = common.HexToAddress(ctx.String(ReceiverFlag.Name)) } var code []byte - codeFileFlag := ctx.GlobalString(CodeFileFlag.Name) - codeFlag := ctx.GlobalString(CodeFlag.Name) + codeFileFlag := ctx.String(CodeFileFlag.Name) + codeFlag := ctx.String(CodeFlag.Name) // The '--code' or '--codefile' flag overrides code in state if codeFileFlag != "" || codeFlag != "" { @@ -196,7 +197,7 @@ func runCmd(ctx *cli.Context) error { } code = common.Hex2Bytes(bin) } - initialGas := ctx.GlobalUint64(GasFlag.Name) + initialGas := ctx.Uint64(GasFlag.Name) if genesisConfig.GasLimit != 0 { initialGas = genesisConfig.GasLimit } @@ -204,20 +205,20 @@ func runCmd(ctx *cli.Context) error { Origin: sender, State: statedb, GasLimit: initialGas, - GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), - Value: utils.GlobalBig(ctx, ValueFlag.Name), + GasPrice: flags.GlobalBig(ctx, PriceFlag.Name), + Value: flags.GlobalBig(ctx, ValueFlag.Name), Difficulty: genesisConfig.Difficulty, Time: new(big.Int).SetUint64(genesisConfig.Timestamp), Coinbase: genesisConfig.Coinbase, BlockNumber: new(big.Int).SetUint64(genesisConfig.Number), EVMConfig: vm.Config{ Tracer: tracer, - Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), - EVMInterpreter: ctx.GlobalString(EVMInterpreterFlag.Name), + Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), + EVMInterpreter: ctx.String(EVMInterpreterFlag.Name), }, } - if cpuProfilePath := ctx.GlobalString(CPUProfileFlag.Name); cpuProfilePath != "" { + if cpuProfilePath := ctx.String(CPUProfileFlag.Name); cpuProfilePath != "" { f, err := os.Create(cpuProfilePath) if err != nil { fmt.Println("could not create CPU profile: ", err) @@ -237,19 +238,19 @@ func runCmd(ctx *cli.Context) error { } var hexInput []byte - if inputFileFlag := ctx.GlobalString(InputFileFlag.Name); inputFileFlag != "" { + if inputFileFlag := ctx.String(InputFileFlag.Name); inputFileFlag != "" { var err error if hexInput, err = os.ReadFile(inputFileFlag); err != nil { fmt.Printf("could not load input from file: %v\n", err) os.Exit(1) } } else { - hexInput = []byte(ctx.GlobalString(InputFlag.Name)) + hexInput = []byte(ctx.String(InputFlag.Name)) } input := common.FromHex(string(bytes.TrimSpace(hexInput))) var execFunc func() ([]byte, uint64, error) - if ctx.GlobalBool(CreateFlag.Name) { + if ctx.Bool(CreateFlag.Name) { input = append(code, input...) execFunc = func() ([]byte, uint64, error) { output, _, gasLeft, err := runtime.Create(input, &runtimeConfig) @@ -264,16 +265,16 @@ func runCmd(ctx *cli.Context) error { } } - bench := ctx.GlobalBool(BenchFlag.Name) + bench := ctx.Bool(BenchFlag.Name) output, leftOverGas, stats, err := timedExec(bench, execFunc) - if ctx.GlobalBool(DumpFlag.Name) { + if ctx.Bool(DumpFlag.Name) { statedb.Commit(true) statedb.IntermediateRoot(true) fmt.Println(string(statedb.Dump(false, false, true))) } - if memProfilePath := ctx.GlobalString(MemProfileFlag.Name); memProfilePath != "" { + if memProfilePath := ctx.String(MemProfileFlag.Name); memProfilePath != "" { f, err := os.Create(memProfilePath) if err != nil { fmt.Println("could not create memory profile: ", err) @@ -286,7 +287,7 @@ func runCmd(ctx *cli.Context) error { f.Close() } - if ctx.GlobalBool(DebugFlag.Name) { + if ctx.Bool(DebugFlag.Name) { if debugLogger != nil { fmt.Fprintln(os.Stderr, "#### TRACE ####") vm.WriteTrace(os.Stderr, debugLogger.StructLogs()) @@ -295,7 +296,7 @@ func runCmd(ctx *cli.Context) error { vm.WriteLogs(os.Stderr, statedb.Logs()) } - if bench || ctx.GlobalBool(StatDumpFlag.Name) { + if bench || ctx.Bool(StatDumpFlag.Name) { fmt.Fprintf(os.Stderr, `EVM gas used: %d execution time: %v allocations: %d diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index b8d10775b..51c21edda 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -27,10 +27,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/tests" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var stateTestCommand = cli.Command{ +var stateTestCommand = &cli.Command{ Action: stateTestCmd, Name: "statetest", Usage: "executes the given state tests", @@ -53,25 +53,25 @@ func stateTestCmd(ctx *cli.Context) error { } // Configure the go-ethereum logger glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) - glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name))) + glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) log.Root().SetHandler(glogger) // Configure the EVM logger config := &vm.LogConfig{ - DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name), - DisableStack: ctx.GlobalBool(DisableStackFlag.Name), - DisableStorage: ctx.GlobalBool(DisableStorageFlag.Name), - DisableReturnData: ctx.GlobalBool(DisableReturnDataFlag.Name), + DisableMemory: ctx.Bool(DisableMemoryFlag.Name), + DisableStack: ctx.Bool(DisableStackFlag.Name), + DisableStorage: ctx.Bool(DisableStorageFlag.Name), + DisableReturnData: ctx.Bool(DisableReturnDataFlag.Name), } var ( tracer vm.Tracer debugger *vm.StructLogger ) switch { - case ctx.GlobalBool(MachineFlag.Name): + case ctx.Bool(MachineFlag.Name): tracer = vm.NewJSONLogger(config, os.Stderr) - case ctx.GlobalBool(DebugFlag.Name): + case ctx.Bool(DebugFlag.Name): debugger = vm.NewStructLogger(config) tracer = debugger @@ -90,7 +90,7 @@ func stateTestCmd(ctx *cli.Context) error { // Iterate over all the tests, run them and aggregate the results cfg := vm.Config{ Tracer: tracer, - Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), + Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), } results := make([]StatetestResult, 0, len(tests)) for key, test := range tests { @@ -99,13 +99,13 @@ func stateTestCmd(ctx *cli.Context) error { result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true} _, state, err := test.Run(st, cfg, false) // print state root for evmlab tracing - if ctx.GlobalBool(MachineFlag.Name) && state != nil { + if ctx.Bool(MachineFlag.Name) && state != nil { fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false)) } if err != nil { // Test failed, mark as so and dump any state to aid debugging result.Pass, result.Error = false, err.Error() - if ctx.GlobalBool(DumpFlag.Name) && state != nil { + if ctx.Bool(DumpFlag.Name) && state != nil { dump := state.RawDump(false, false, true) result.State = &dump } @@ -114,7 +114,7 @@ func stateTestCmd(ctx *cli.Context) error { results = append(results, *result) // Print any structured logs collected - if ctx.GlobalBool(DebugFlag.Name) { + if ctx.Bool(DebugFlag.Name) { if debugger != nil { fmt.Fprintln(os.Stderr, "#### TRACE ####") vm.WriteTrace(os.Stderr, debugger.StructLogs()) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 03e348d40..c57acb474 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -25,29 +25,27 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - walletCommand = cli.Command{ + walletCommand = &cli.Command{ Name: "wallet", Usage: "Manage Ethereum presale wallets", ArgsUsage: "", - Category: "ACCOUNT COMMANDS", Description: ` geth wallet import /path/to/my/presale.wallet will prompt for your password and imports your ether presale account. It can be used non-interactively with the --password option taking a passwordfile as argument containing the wallet password in plaintext.`, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "import", Usage: "Import Ethereum presale wallet", ArgsUsage: "", - Action: utils.MigrateFlags(importWallet), - Category: "ACCOUNT COMMANDS", + Action: importWallet, Flags: []cli.Flag{ utils.DataDirFlag, utils.KeyStoreDirFlag, @@ -64,10 +62,9 @@ passwordfile as argument containing the wallet password in plaintext.`, }, } - accountCommand = cli.Command{ - Name: "account", - Usage: "Manage accounts", - Category: "ACCOUNT COMMANDS", + accountCommand = &cli.Command{ + Name: "account", + Usage: "Manage accounts", Description: ` Manage accounts, list all existing accounts, import a private key into a new @@ -88,11 +85,11 @@ It is safe to transfer the entire directory or the individual keys therein between ethereum nodes by simply copying. Make sure you backup your keys regularly.`, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "list", Usage: "Print summary of existing accounts", - Action: utils.MigrateFlags(accountList), + Action: accountList, Flags: []cli.Flag{ utils.DataDirFlag, utils.KeyStoreDirFlag, @@ -103,7 +100,7 @@ Print a short summary of all accounts`, { Name: "new", Usage: "Create a new account", - Action: utils.MigrateFlags(accountCreate), + Action: accountCreate, Flags: []cli.Flag{ utils.DataDirFlag, utils.KeyStoreDirFlag, @@ -128,7 +125,7 @@ password to file or expose in any other way. { Name: "update", Usage: "Update an existing account", - Action: utils.MigrateFlags(accountUpdate), + Action: accountUpdate, ArgsUsage: "
", Flags: []cli.Flag{ utils.DataDirFlag, @@ -157,7 +154,7 @@ changing your password is only possible interactively. { Name: "import", Usage: "Import a private key into a new account", - Action: utils.MigrateFlags(accountImport), + Action: accountImport, Flags: []cli.Flag{ utils.DataDirFlag, utils.KeyStoreDirFlag, @@ -263,7 +260,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr func accountCreate(ctx *cli.Context) error { cfg := gethConfig{Node: defaultNodeConfig()} // Load config file. - if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if file := ctx.String(configFileFlag.Name); file != "" { if err := loadConfig(file, &cfg); err != nil { utils.Fatalf("%v", err) } @@ -295,13 +292,13 @@ func accountCreate(ctx *cli.Context) error { // accountUpdate transitions an account from a previous format to the current // one, also providing the possibility to change the pass-phrase. func accountUpdate(ctx *cli.Context) error { - if len(ctx.Args()) == 0 { + if ctx.NArg() == 0 { utils.Fatalf("No accounts specified to update") } stack, _ := makeConfigNode(ctx) ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - for _, addr := range ctx.Args() { + for _, addr := range ctx.Args().Slice() { account, oldPassword := unlockAccount(ks, addr, 0, nil) newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil) if err := ks.Update(account, oldPassword, newPassword); err != nil { @@ -312,10 +309,10 @@ func accountUpdate(ctx *cli.Context) error { } func importWallet(ctx *cli.Context) error { - keyfile := ctx.Args().First() - if len(keyfile) == 0 { - utils.Fatalf("keyfile must be given as argument") + if ctx.NArg() != 1 { + utils.Fatalf("keyfile must be given as the only argument") } + keyfile := ctx.Args().First() keyJSON, err := os.ReadFile(keyfile) if err != nil { utils.Fatalf("Could not read wallet file: %v", err) @@ -334,10 +331,10 @@ func importWallet(ctx *cli.Context) error { } func accountImport(ctx *cli.Context) error { - keyfile := ctx.Args().First() - if len(keyfile) == 0 { - utils.Fatalf("keyfile must be given as argument") + if ctx.NArg() != 1 { + utils.Fatalf("keyfile must be given as the only argument") } + keyfile := ctx.Args().First() key, err := crypto.LoadECDSA(keyfile) if err != nil { utils.Fatalf("Failed to load the private key: %v", err) diff --git a/cmd/geth/accountcmd_plugin.go b/cmd/geth/accountcmd_plugin.go index 20b6b8a72..9af762c78 100644 --- a/cmd/geth/accountcmd_plugin.go +++ b/cmd/geth/accountcmd_plugin.go @@ -13,11 +13,11 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/plugin" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - quorumAccountPluginCommands = cli.Command{ + quorumAccountPluginCommands = &cli.Command{ Name: "plugin", Usage: "Manage 'account' plugin accounts", Description: ` @@ -27,11 +27,11 @@ var ( See docs.goquorum.com for more info. `, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "list", Usage: "Print summary of existing 'account' plugin accounts", - Action: utils.MigrateFlags(listPluginAccountsCLIAction), + Action: listPluginAccountsCLIAction, Flags: []cli.Flag{ utils.PluginSettingsFlag, // flag is used implicitly by makeConfigNode() utils.PluginLocalVerifyFlag, @@ -45,7 +45,7 @@ Print a short summary of all accounts for the given plugin settings`, { Name: "new", Usage: "Create a new account using an 'account' plugin", - Action: utils.MigrateFlags(createPluginAccountCLIAction), + Action: createPluginAccountCLIAction, Flags: []cli.Flag{ utils.PluginSettingsFlag, utils.PluginLocalVerifyFlag, @@ -67,7 +67,7 @@ For more info see the documentation for the particular 'account' plugin being us { Name: "import", Usage: "Import a private key into a new account using an 'account' plugin", - Action: utils.MigrateFlags(importPluginAccountCLIAction), + Action: importPluginAccountCLIAction, Flags: []cli.Flag{ utils.PluginSettingsFlag, utils.PluginLocalVerifyFlag, diff --git a/cmd/geth/accountcmd_plugin_test.go b/cmd/geth/accountcmd_plugin_test.go index 858e3e3bb..72932771b 100644 --- a/cmd/geth/accountcmd_plugin_test.go +++ b/cmd/geth/accountcmd_plugin_test.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/plugin" "github.com/stretchr/testify/require" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) // newAccountPluginCLIContext creates a cli.Context setup with the core account plugin CLI flags. diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 7cd0146de..4c4bd37f3 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -60,7 +60,7 @@ func TestAccountListEmpty(t *testing.T) { func TestAccountList(t *testing.T) { datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, "account", "list", "--datadir", datadir) + geth := runGeth(t, "--datadir", datadir, "account", "list") defer geth.ExpectExit() if runtime.GOOS == "windows" { geth.Expect(` @@ -78,7 +78,8 @@ Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/k } func TestAccountNew(t *testing.T) { - geth := runGeth(t, "account", "new", "--lightkdf") + datadir := tmpDatadirWithKeystore(t) + geth := runGeth(t, "account", "new", "--lightkdf", "--datadir", datadir) defer geth.ExpectExit() geth.Expect(` Your new account is locked with a password. Please give a password. Do not forget this password. @@ -131,7 +132,7 @@ func importAccountWithExpect(t *testing.T, key string, expected string) { if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil { t.Error(err) } - geth := runGeth(t, "account", "import", keyfile, "-password", passwordFile) + geth := runGeth(t, "--lightkdf", "--datadir", dir, "account", "import", "-password", passwordFile, keyfile) defer geth.ExpectExit() geth.Expect(expected) } @@ -165,7 +166,7 @@ Repeat password: {{.InputLine "foobar2"}} } func TestWalletImport(t *testing.T) { - geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") + geth := runGeth(t, "--lightkdf", "wallet", "import", "testdata/guswallet.json") defer geth.ExpectExit() geth.Expect(` !! Unsupported terminal, password will be echoed. diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index b63359e95..f807b9ae4 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -39,19 +39,18 @@ import ( "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/private/engine/notinuse" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - initCommand = cli.Command{ - Action: utils.MigrateFlags(initGenesis), + initCommand = &cli.Command{ + Action: initGenesis, Name: "init", Usage: "Bootstrap and initialize a new genesis block", ArgsUsage: "", Flags: []cli.Flag{ utils.DataDirFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The init command initializes a new genesis block and definition for the network. This is a destructive action and changes the network in which you will be @@ -59,8 +58,8 @@ participating. It expects the genesis file as argument.`, } - dumpGenesisCommand = cli.Command{ - Action: utils.MigrateFlags(dumpGenesis), + dumpGenesisCommand = &cli.Command{ + Action: dumpGenesis, Name: "dumpgenesis", Usage: "Dumps genesis block JSON configuration to stdout", ArgsUsage: "", @@ -71,25 +70,23 @@ It expects the genesis file as argument.`, utils.GoerliFlag, utils.YoloV3Flag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The dumpgenesis command dumps the genesis block configuration in JSON format to stdout.`, } - updateCommand = cli.Command{ - Action: utils.MigrateFlags(updateTransitions), + updateCommand = &cli.Command{ + Action: updateTransitions, Name: "update", Usage: "Update genesis block with new transitions", ArgsUsage: "", Flags: []cli.Flag{ utils.DataDirFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The update commands updates the chain data configuration in genesis block for new transition changes. It expects the genesis file as argument.`, } - importCommand = cli.Command{ - Action: utils.MigrateFlags(importChain), + importCommand = &cli.Command{ + Action: importChain, Name: "import", Usage: "Import a blockchain file", ArgsUsage: " ( ... ) ", @@ -113,7 +110,6 @@ It expects the genesis file as argument.`, utils.MetricsInfluxDBTagsFlag, utils.TxLookupLimitFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The import command imports blocks from an RLP-encoded form. The form can be one file with several RLP-encoded blocks, or several files can be used. @@ -121,8 +117,8 @@ with several RLP-encoded blocks, or several files can be used. If only one file is used, import error will result in failure. If several files are used, processing will proceed even if an individual RLP-file import failure occurs.`, } - mpsdbUpgradeCommand = cli.Command{ - Action: utils.MigrateFlags(mpsdbUpgrade), + mpsdbUpgradeCommand = &cli.Command{ + Action: mpsdbUpgrade, Name: "mpsdbupgrade", Usage: "Upgrade a standalone DB to an MPS DB", ArgsUsage: "", @@ -133,10 +129,9 @@ processing will proceed even if an individual RLP-file import failure occurs.`, Checks if the chain config isMPS parameter value. If false, it upgrades the DB to be MPS enabled (builds the trie of private states) and if successful sets isMPS to true. If true, exits displaying an error message that the DB is already MPS.`, - Category: "BLOCKCHAIN COMMANDS", } - exportCommand = cli.Command{ - Action: utils.MigrateFlags(exportChain), + exportCommand = &cli.Command{ + Action: exportChain, Name: "export", Usage: "Export blockchain into file", ArgsUsage: " [ ]", @@ -145,7 +140,6 @@ If true, exits displaying an error message that the DB is already MPS.`, utils.CacheFlag, utils.SyncModeFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` Requires a first argument of the file to write to. Optional second and third arguments control the first and @@ -153,8 +147,8 @@ last block to write. In this mode, the file will be appended if already existing. If the file ends with .gz, the output will be gzipped.`, } - importPreimagesCommand = cli.Command{ - Action: utils.MigrateFlags(importPreimages), + importPreimagesCommand = &cli.Command{ + Action: importPreimages, Name: "import-preimages", Usage: "Import the preimage database from an RLP stream", ArgsUsage: "", @@ -163,12 +157,11 @@ be gzipped.`, utils.CacheFlag, utils.SyncModeFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The import-preimages command imports hash preimages from an RLP encoded stream.`, } - exportPreimagesCommand = cli.Command{ - Action: utils.MigrateFlags(exportPreimages), + exportPreimagesCommand = &cli.Command{ + Action: exportPreimages, Name: "export-preimages", Usage: "Export the preimage database into an RLP stream", ArgsUsage: "", @@ -177,12 +170,11 @@ be gzipped.`, utils.CacheFlag, utils.SyncModeFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The export-preimages command export hash preimages to an RLP encoded stream`, } - dumpCommand = cli.Command{ - Action: utils.MigrateFlags(dump), + dumpCommand = &cli.Command{ + Action: dump, Name: "dump", Usage: "Dump a specific block from storage", ArgsUsage: "[ | ]...", @@ -195,7 +187,6 @@ The export-preimages command export hash preimages to an RLP encoded stream`, utils.ExcludeStorageFlag, utils.IncludeIncompletesFlag, }, - Category: "BLOCKCHAIN COMMANDS", Description: ` The arguments are interpreted as block numbers or hashes. Use "ethereum dump 0" to dump the genesis block.`, @@ -280,10 +271,14 @@ func updateTransitions(ctx *cli.Context) error { // initGenesis will initialise the given JSON format genesis file and writes it as // the zero'd block (i.e. genesis) or will fail hard if it can't succeed. func initGenesis(ctx *cli.Context) error { + if ctx.NArg() != 1 { + utils.Fatalf("need genesis.json file as the only argument") + } + // Make sure we have a valid genesis JSON genesisPath := ctx.Args().First() if len(genesisPath) == 0 { - utils.Fatalf("Must supply path to genesis JSON file") + utils.Fatalf("invalid path to genesis file") } file, err := os.Open(genesisPath) if err != nil { @@ -360,7 +355,7 @@ func dumpGenesis(ctx *cli.Context) error { } func importChain(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an argument.") } // Start metrics export if enabled @@ -394,13 +389,13 @@ func importChain(ctx *cli.Context) error { var importErr error - if len(ctx.Args()) == 1 { + if ctx.NArg() == 1 { if err := utils.ImportChain(chain, ctx.Args().First()); err != nil { importErr = err log.Error("Import error", "err", err) } } else { - for _, arg := range ctx.Args() { + for _, arg := range ctx.Args().Slice() { if err := utils.ImportChain(chain, arg); err != nil { importErr = err log.Error("Import error", "file", arg, "err", err) @@ -422,7 +417,7 @@ func importChain(ctx *cli.Context) error { fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000) fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs)) - if ctx.GlobalBool(utils.NoCompactionFlag.Name) { + if ctx.Bool(utils.NoCompactionFlag.Name) { return nil } @@ -458,7 +453,7 @@ func mpsdbUpgrade(ctx *cli.Context) error { } func exportChain(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an argument.") } @@ -470,7 +465,7 @@ func exportChain(ctx *cli.Context) error { var err error fp := ctx.Args().First() - if len(ctx.Args()) < 3 { + if ctx.NArg() < 3 { err = utils.ExportChain(chain, fp) } else { // This can be improved to allow for numbers larger than 9223372036854775807 @@ -497,7 +492,7 @@ func exportChain(ctx *cli.Context) error { // importPreimages imports preimage data from the specified file. func importPreimages(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an argument.") } @@ -516,7 +511,7 @@ func importPreimages(ctx *cli.Context) error { // exportPreimages dumps the preimage data to specified json file in streaming way. func exportPreimages(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { + if ctx.NArg() < 1 { utils.Fatalf("This command requires an argument.") } @@ -538,7 +533,7 @@ func dump(ctx *cli.Context) error { defer stack.Close() db := utils.MakeChainDatabase(ctx, stack, false) - for _, arg := range ctx.Args() { + for _, arg := range ctx.Args().Slice() { var header *types.Header if hashish(arg) { hash := common.HexToHash(arg) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 147b6e686..c5621e114 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -45,12 +45,12 @@ import ( "github.com/ethereum/go-ethereum/private/engine" "github.com/ethereum/go-ethereum/qlight" "github.com/naoina/toml" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - dumpConfigCommand = cli.Command{ - Action: utils.MigrateFlags(dumpConfig), + dumpConfigCommand = &cli.Command{ + Action: dumpConfig, Name: "dumpconfig", Usage: "Show configuration values", ArgsUsage: "", @@ -59,7 +59,7 @@ var ( Description: `The dumpconfig command shows configuration values.`, } - configFileFlag = cli.StringFlag{ + configFileFlag = &cli.StringFlag{ Name: "config", Usage: "TOML configuration file", } @@ -134,7 +134,7 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { } // Load config file. - if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if file := ctx.String(configFileFlag.Name); file != "" { if err := loadConfig(file, &cfg); err != nil { utils.Fatalf("%v", err) } @@ -149,8 +149,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { utils.Fatalf("Failed to create the protocol stack: %v", err) } utils.SetEthConfig(ctx, stack, &cfg.Eth) - if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) { - cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name) + if ctx.IsSet(utils.EthStatsURLFlag.Name) { + cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name) } applyMetricConfig(ctx, &cfg) @@ -159,10 +159,10 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { p2p.SetQLightTLSConfig(readQLightServerTLSConfig(ctx)) // permissioning for the qlight P2P server stack.QServer().SetNewTransportFunc(p2p.NewQlightServerTransport) - if ctx.GlobalIsSet(utils.QuorumLightServerP2PPermissioningFlag.Name) { + if ctx.IsSet(utils.QuorumLightServerP2PPermissioningFlag.Name) { prefix := "qlight" - if ctx.GlobalIsSet(utils.QuorumLightServerP2PPermissioningPrefixFlag.Name) { - prefix = ctx.GlobalString(utils.QuorumLightServerP2PPermissioningPrefixFlag.Name) + if ctx.IsSet(utils.QuorumLightServerP2PPermissioningPrefixFlag.Name) { + prefix = ctx.String(utils.QuorumLightServerP2PPermissioningPrefixFlag.Name) } fbp := core.NewFileBasedPermissoningWithPrefix(prefix) stack.QServer().SetIsNodePermissioned(fbp.IsNodePermissionedEnode) @@ -180,8 +180,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { // makeFullNode loads geth configuration and creates the Ethereum backend. func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { stack, cfg := makeConfigNode(ctx) - if ctx.GlobalIsSet(utils.OverrideBerlinFlag.Name) { - cfg.Eth.OverrideBerlin = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideBerlinFlag.Name)) + if ctx.IsSet(utils.OverrideBerlinFlag.Name) { + cfg.Eth.OverrideBerlin = new(big.Int).SetUint64(ctx.Uint64(utils.OverrideBerlinFlag.Name)) } // Quorum: Must occur before registering the extension service, as it needs an initialised PTM to be enabled @@ -192,7 +192,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { backend, eth := utils.RegisterEthService(stack, &cfg.Eth) // Configure catalyst. - if ctx.GlobalBool(utils.CatalystFlag.Name) { + if ctx.Bool(utils.CatalystFlag.Name) { if eth == nil { utils.Fatalf("Catalyst does not work in light client mode.") } @@ -217,7 +217,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { utils.RegisterPermissionService(stack, ctx.Bool(utils.RaftDNSEnabledFlag.Name), backend.ChainConfig().ChainID) } - if ctx.GlobalBool(utils.RaftModeFlag.Name) && !cfg.Eth.QuorumLightClient.Enabled() { + if ctx.Bool(utils.RaftModeFlag.Name) && !cfg.Eth.QuorumLightClient.Enabled() { utils.RegisterRaftService(stack, ctx, &cfg.Node, eth) } @@ -227,7 +227,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { // End Quorum // Configure GraphQL if requested - if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) { + if ctx.IsSet(utils.GraphQLEnabledFlag.Name) { utils.RegisterGraphQLService(stack, backend, cfg.Node) } // Add the Ethereum Stats daemon if requested. @@ -267,53 +267,53 @@ func dumpConfig(ctx *cli.Context) error { } func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) { - if ctx.GlobalIsSet(utils.MetricsEnabledFlag.Name) { - cfg.Metrics.Enabled = ctx.GlobalBool(utils.MetricsEnabledFlag.Name) + if ctx.IsSet(utils.MetricsEnabledFlag.Name) { + cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsEnabledExpensiveFlag.Name) { - cfg.Metrics.EnabledExpensive = ctx.GlobalBool(utils.MetricsEnabledExpensiveFlag.Name) + if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) { + cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsHTTPFlag.Name) { - cfg.Metrics.HTTP = ctx.GlobalString(utils.MetricsHTTPFlag.Name) + if ctx.IsSet(utils.MetricsHTTPFlag.Name) { + cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsPortFlag.Name) { - cfg.Metrics.Port = ctx.GlobalInt(utils.MetricsPortFlag.Name) + if ctx.IsSet(utils.MetricsPortFlag.Name) { + cfg.Metrics.Port = ctx.Int(utils.MetricsPortFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsEnableInfluxDBFlag.Name) { - cfg.Metrics.EnableInfluxDB = ctx.GlobalBool(utils.MetricsEnableInfluxDBFlag.Name) + if ctx.IsSet(utils.MetricsEnableInfluxDBFlag.Name) { + cfg.Metrics.EnableInfluxDB = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsInfluxDBEndpointFlag.Name) { - cfg.Metrics.InfluxDBEndpoint = ctx.GlobalString(utils.MetricsInfluxDBEndpointFlag.Name) + if ctx.IsSet(utils.MetricsInfluxDBEndpointFlag.Name) { + cfg.Metrics.InfluxDBEndpoint = ctx.String(utils.MetricsInfluxDBEndpointFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsInfluxDBDatabaseFlag.Name) { - cfg.Metrics.InfluxDBDatabase = ctx.GlobalString(utils.MetricsInfluxDBDatabaseFlag.Name) + if ctx.IsSet(utils.MetricsInfluxDBDatabaseFlag.Name) { + cfg.Metrics.InfluxDBDatabase = ctx.String(utils.MetricsInfluxDBDatabaseFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsInfluxDBUsernameFlag.Name) { - cfg.Metrics.InfluxDBUsername = ctx.GlobalString(utils.MetricsInfluxDBUsernameFlag.Name) + if ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) { + cfg.Metrics.InfluxDBUsername = ctx.String(utils.MetricsInfluxDBUsernameFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsInfluxDBPasswordFlag.Name) { - cfg.Metrics.InfluxDBPassword = ctx.GlobalString(utils.MetricsInfluxDBPasswordFlag.Name) + if ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) { + cfg.Metrics.InfluxDBPassword = ctx.String(utils.MetricsInfluxDBPasswordFlag.Name) } - if ctx.GlobalIsSet(utils.MetricsInfluxDBTagsFlag.Name) { - cfg.Metrics.InfluxDBTags = ctx.GlobalString(utils.MetricsInfluxDBTagsFlag.Name) + if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) { + cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name) } } // Quorum func readQLightClientTLSConfig(ctx *cli.Context) *tls.Config { - if !ctx.GlobalIsSet(utils.QuorumLightTLSFlag.Name) { + if !ctx.IsSet(utils.QuorumLightTLSFlag.Name) { return nil } - if !ctx.GlobalIsSet(utils.QuorumLightTLSCACertsFlag.Name) { + if !ctx.IsSet(utils.QuorumLightTLSCACertsFlag.Name) { utils.Fatalf("QLight tls flag is set but no client certificate authorities has been provided") } tlsConfig, err := qlight.NewTLSConfig(&qlight.TLSConfig{ - CACertFileName: ctx.GlobalString(utils.QuorumLightTLSCACertsFlag.Name), - CertFileName: ctx.GlobalString(utils.QuorumLightTLSCertFlag.Name), - KeyFileName: ctx.GlobalString(utils.QuorumLightTLSKeyFlag.Name), - ServerName: enode.MustParse(ctx.GlobalString(utils.QuorumLightClientServerNodeFlag.Name)).IP().String(), - CipherSuites: ctx.GlobalString(utils.QuorumLightTLSCipherSuitesFlag.Name), + CACertFileName: ctx.String(utils.QuorumLightTLSCACertsFlag.Name), + CertFileName: ctx.String(utils.QuorumLightTLSCertFlag.Name), + KeyFileName: ctx.String(utils.QuorumLightTLSKeyFlag.Name), + ServerName: enode.MustParse(ctx.String(utils.QuorumLightClientServerNodeFlag.Name)).IP().String(), + CipherSuites: ctx.String(utils.QuorumLightTLSCipherSuitesFlag.Name), }) if err != nil { @@ -323,22 +323,22 @@ func readQLightClientTLSConfig(ctx *cli.Context) *tls.Config { } func readQLightServerTLSConfig(ctx *cli.Context) *tls.Config { - if !ctx.GlobalIsSet(utils.QuorumLightTLSFlag.Name) { + if !ctx.IsSet(utils.QuorumLightTLSFlag.Name) { return nil } - if !ctx.GlobalIsSet(utils.QuorumLightTLSCertFlag.Name) { + if !ctx.IsSet(utils.QuorumLightTLSCertFlag.Name) { utils.Fatalf("QLight TLS is enabled but no server certificate has been provided") } - if !ctx.GlobalIsSet(utils.QuorumLightTLSKeyFlag.Name) { + if !ctx.IsSet(utils.QuorumLightTLSKeyFlag.Name) { utils.Fatalf("QLight TLS is enabled but no server key has been provided") } tlsConfig, err := qlight.NewTLSConfig(&qlight.TLSConfig{ - CertFileName: ctx.GlobalString(utils.QuorumLightTLSCertFlag.Name), - KeyFileName: ctx.GlobalString(utils.QuorumLightTLSKeyFlag.Name), - ClientCACertFileName: ctx.GlobalString(utils.QuorumLightTLSCACertsFlag.Name), - ClientAuth: ctx.GlobalInt(utils.QuorumLightTLSClientAuthFlag.Name), - CipherSuites: ctx.GlobalString(utils.QuorumLightTLSCipherSuitesFlag.Name), + CertFileName: ctx.String(utils.QuorumLightTLSCertFlag.Name), + KeyFileName: ctx.String(utils.QuorumLightTLSKeyFlag.Name), + ClientCACertFileName: ctx.String(utils.QuorumLightTLSCACertsFlag.Name), + ClientAuth: ctx.Int(utils.QuorumLightTLSClientAuthFlag.Name), + CipherSuites: ctx.String(utils.QuorumLightTLSCipherSuitesFlag.Name), }) if err != nil { @@ -400,7 +400,7 @@ func quorumInitialisePrivacy(ctx *cli.Context) error { return err } - err = private.InitialiseConnection(cfg, ctx.GlobalIsSet(utils.QuorumLightClientFlag.Name)) + err = private.InitialiseConnection(cfg, ctx.IsSet(utils.QuorumLightClientFlag.Name)) if err != nil { return err } @@ -418,40 +418,40 @@ func QuorumSetupPrivacyConfiguration(ctx *cli.Context) (http.Config, error) { } // override the config with command line parameters - if ctx.GlobalIsSet(utils.QuorumPTMUnixSocketFlag.Name) { - cfg.SetSocket(ctx.GlobalString(utils.QuorumPTMUnixSocketFlag.Name)) + if ctx.IsSet(utils.QuorumPTMUnixSocketFlag.Name) { + cfg.SetSocket(ctx.String(utils.QuorumPTMUnixSocketFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMUrlFlag.Name) { - cfg.SetHttpUrl(ctx.GlobalString(utils.QuorumPTMUrlFlag.Name)) + if ctx.IsSet(utils.QuorumPTMUrlFlag.Name) { + cfg.SetHttpUrl(ctx.String(utils.QuorumPTMUrlFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTimeoutFlag.Name) { - cfg.SetTimeout(ctx.GlobalUint(utils.QuorumPTMTimeoutFlag.Name)) + if ctx.IsSet(utils.QuorumPTMTimeoutFlag.Name) { + cfg.SetTimeout(ctx.Uint(utils.QuorumPTMTimeoutFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMDialTimeoutFlag.Name) { - cfg.SetDialTimeout(ctx.GlobalUint(utils.QuorumPTMDialTimeoutFlag.Name)) + if ctx.IsSet(utils.QuorumPTMDialTimeoutFlag.Name) { + cfg.SetDialTimeout(ctx.Uint(utils.QuorumPTMDialTimeoutFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMHttpIdleTimeoutFlag.Name) { - cfg.SetHttpIdleConnTimeout(ctx.GlobalUint(utils.QuorumPTMHttpIdleTimeoutFlag.Name)) + if ctx.IsSet(utils.QuorumPTMHttpIdleTimeoutFlag.Name) { + cfg.SetHttpIdleConnTimeout(ctx.Uint(utils.QuorumPTMHttpIdleTimeoutFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMHttpWriteBufferSizeFlag.Name) { - cfg.SetHttpWriteBufferSize(ctx.GlobalInt(utils.QuorumPTMHttpWriteBufferSizeFlag.Name)) + if ctx.IsSet(utils.QuorumPTMHttpWriteBufferSizeFlag.Name) { + cfg.SetHttpWriteBufferSize(ctx.Int(utils.QuorumPTMHttpWriteBufferSizeFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMHttpReadBufferSizeFlag.Name) { - cfg.SetHttpReadBufferSize(ctx.GlobalInt(utils.QuorumPTMHttpReadBufferSizeFlag.Name)) + if ctx.IsSet(utils.QuorumPTMHttpReadBufferSizeFlag.Name) { + cfg.SetHttpReadBufferSize(ctx.Int(utils.QuorumPTMHttpReadBufferSizeFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTlsModeFlag.Name) { - cfg.SetTlsMode(ctx.GlobalString(utils.QuorumPTMTlsModeFlag.Name)) + if ctx.IsSet(utils.QuorumPTMTlsModeFlag.Name) { + cfg.SetTlsMode(ctx.String(utils.QuorumPTMTlsModeFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTlsRootCaFlag.Name) { - cfg.SetTlsRootCA(ctx.GlobalString(utils.QuorumPTMTlsRootCaFlag.Name)) + if ctx.IsSet(utils.QuorumPTMTlsRootCaFlag.Name) { + cfg.SetTlsRootCA(ctx.String(utils.QuorumPTMTlsRootCaFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTlsClientCertFlag.Name) { - cfg.SetTlsClientCert(ctx.GlobalString(utils.QuorumPTMTlsClientCertFlag.Name)) + if ctx.IsSet(utils.QuorumPTMTlsClientCertFlag.Name) { + cfg.SetTlsClientCert(ctx.String(utils.QuorumPTMTlsClientCertFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTlsClientKeyFlag.Name) { - cfg.SetTlsClientKey(ctx.GlobalString(utils.QuorumPTMTlsClientKeyFlag.Name)) + if ctx.IsSet(utils.QuorumPTMTlsClientKeyFlag.Name) { + cfg.SetTlsClientKey(ctx.String(utils.QuorumPTMTlsClientKeyFlag.Name)) } - if ctx.GlobalIsSet(utils.QuorumPTMTlsInsecureSkipVerify.Name) { + if ctx.IsSet(utils.QuorumPTMTlsInsecureSkipVerify.Name) { cfg.SetTlsInsecureSkipVerify(ctx.Bool(utils.QuorumPTMTlsInsecureSkipVerify.Name)) } diff --git a/cmd/geth/config_test.go b/cmd/geth/config_test.go deleted file mode 100644 index 9aa1f8ee4..000000000 --- a/cmd/geth/config_test.go +++ /dev/null @@ -1,678 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "math/big" - "os" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/istanbul" - "github.com/ethereum/go-ethereum/eth/downloader" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/netutil" - "github.com/naoina/toml" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gopkg.in/urfave/cli.v1" -) - -func TestFlagsConfig(t *testing.T) { - flags := []interface{}{ - utils.DataDirFlag, - utils.RaftLogDirFlag, - utils.AncientFlag, - utils.MinFreeDiskSpaceFlag, - utils.KeyStoreDirFlag, - utils.NoUSBFlag, - utils.USBFlag, - utils.SmartCardDaemonPathFlag, - utils.NetworkIdFlag, - utils.MainnetFlag, - utils.GoerliFlag, - utils.YoloV3Flag, - utils.RinkebyFlag, - utils.RopstenFlag, - utils.DeveloperFlag, - utils.DeveloperPeriodFlag, - utils.IdentityFlag, - utils.DocRootFlag, - utils.ExitWhenSyncedFlag, - utils.IterativeOutputFlag, - utils.ExcludeStorageFlag, - utils.IncludeIncompletesFlag, - utils.ExcludeCodeFlag, - utils.SyncModeFlag, - utils.GCModeFlag, - utils.SnapshotFlag, - utils.TxLookupLimitFlag, - utils.LightKDFFlag, - utils.DeprecatedAuthorizationListFlag, - utils.AuthorizationListFlag, - utils.BloomFilterSizeFlag, - utils.OverrideBerlinFlag, - utils.LightServeFlag, - utils.LightIngressFlag, - utils.LightEgressFlag, - utils.LightMaxPeersFlag, - utils.UltraLightServersFlag, - utils.UltraLightFractionFlag, - utils.UltraLightOnlyAnnounceFlag, - utils.LightNoPruneFlag, - utils.LightNoSyncServeFlag, - utils.TxPoolLocalsFlag, - utils.TxPoolNoLocalsFlag, - utils.TxPoolJournalFlag, - utils.TxPoolRejournalFlag, - utils.TxPoolPriceLimitFlag, - utils.TxPoolPriceBumpFlag, - utils.TxPoolAccountSlotsFlag, - utils.TxPoolGlobalSlotsFlag, - utils.TxPoolAccountQueueFlag, - utils.TxPoolGlobalQueueFlag, - utils.TxPoolLifetimeFlag, - utils.CacheFlag, - utils.CacheDatabaseFlag, - utils.CacheTrieFlag, - utils.CacheTrieJournalFlag, - utils.CacheTrieRejournalFlag, - utils.CacheGCFlag, - utils.CacheSnapshotFlag, - utils.CacheNoPrefetchFlag, - utils.CachePreimagesFlag, - utils.MiningEnabledFlag, - utils.MinerGasTargetFlag, - utils.MinerGasLimitFlag, - utils.MinerGasPriceFlag, - utils.MinerEtherbaseFlag, - utils.MinerExtraDataFlag, - utils.MinerRecommitIntervalFlag, - utils.UnlockedAccountFlag, - utils.PasswordFileFlag, - utils.ExternalSignerFlag, - utils.VMEnableDebugFlag, - utils.InsecureUnlockAllowedFlag, - utils.RPCGlobalGasCapFlag, - utils.RPCGlobalTxFeeCapFlag, - utils.EthStatsURLFlag, - utils.FakePoWFlag, - utils.NoCompactionFlag, - utils.RPCClientToken, - utils.RPCClientTLSCert, - utils.RPCClientTLSCaCert, - utils.RPCClientTLSCipherSuites, - utils.RPCClientTLSInsecureSkipVerify, - utils.IPCDisabledFlag, - utils.IPCPathFlag, - utils.HTTPEnabledFlag, - utils.HTTPListenAddrFlag, - utils.HTTPPortFlag, - utils.HTTPCORSDomainFlag, - utils.HTTPVirtualHostsFlag, - utils.HTTPApiFlag, - utils.HTTPPathPrefixFlag, - utils.GraphQLEnabledFlag, - utils.GraphQLCORSDomainFlag, - utils.GraphQLVirtualHostsFlag, - utils.WSEnabledFlag, - utils.WSListenAddrFlag, - utils.WSPortFlag, - utils.WSApiFlag, - utils.WSAllowedOriginsFlag, - utils.WSPathPrefixFlag, - utils.ExecFlag, - utils.PreloadJSFlag, - utils.AllowUnprotectedTxs, - utils.MaxPeersFlag, - utils.MaxPendingPeersFlag, - utils.ListenPortFlag, - utils.BootnodesFlag, - utils.NodeKeyFileFlag, - utils.NodeKeyHexFlag, - utils.NATFlag, - utils.NoDiscoverFlag, - utils.DiscoveryV5Flag, - utils.NetrestrictFlag, - utils.DNSDiscoveryFlag, - utils.JSpathFlag, - utils.GpoBlocksFlag, - utils.GpoPercentileFlag, - utils.GpoMaxGasPriceFlag, - utils.MetricsEnabledFlag, - utils.MetricsEnabledExpensiveFlag, - utils.MetricsHTTPFlag, - utils.MetricsPortFlag, - utils.MetricsEnableInfluxDBFlag, - utils.MetricsInfluxDBEndpointFlag, - utils.MetricsInfluxDBDatabaseFlag, - utils.MetricsInfluxDBUsernameFlag, - utils.MetricsInfluxDBPasswordFlag, - utils.MetricsInfluxDBTagsFlag, - utils.EWASMInterpreterFlag, - utils.EVMInterpreterFlag, - utils.EVMCallTimeOutFlag, - utils.QuorumImmutabilityThreshold, - utils.RaftModeFlag, - utils.RaftBlockTimeFlag, - utils.RaftJoinExistingFlag, - utils.EmitCheckpointsFlag, - utils.RaftPortFlag, - utils.RaftDNSEnabledFlag, - utils.EnableNodePermissionFlag, - utils.AllowedFutureBlockTimeFlag, - utils.PluginSettingsFlag, - utils.PluginLocalVerifyFlag, - utils.PluginPublicKeyFlag, - utils.PluginSkipVerifyFlag, - utils.AccountPluginNewAccountConfigFlag, - utils.IstanbulRequestTimeoutFlag, - utils.IstanbulBlockPeriodFlag, - utils.MultitenancyFlag, - utils.RevertReasonFlag, - utils.QuorumEnablePrivacyMarker, - utils.QuorumPTMUnixSocketFlag, - utils.QuorumPTMUrlFlag, - utils.QuorumPTMTimeoutFlag, - utils.QuorumPTMDialTimeoutFlag, - utils.QuorumPTMHttpIdleTimeoutFlag, - utils.QuorumPTMHttpWriteBufferSizeFlag, - utils.QuorumPTMHttpReadBufferSizeFlag, - utils.QuorumPTMTlsModeFlag, - utils.QuorumPTMTlsRootCaFlag, - utils.QuorumPTMTlsClientCertFlag, - utils.QuorumPTMTlsClientKeyFlag, - utils.QuorumPTMTlsInsecureSkipVerify, - } - nodeKeyFile, err := os.CreateTemp("/tmp", "nodekey") - require.NoError(t, err) - defer os.Remove(nodeKeyFile.Name()) - - _, err = nodeKeyFile.WriteString("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\n") - require.NoError(t, err) - - err = nodeKeyFile.Close() - require.NoError(t, err) - - set := flag.NewFlagSet("dumpconfig", flag.ContinueOnError) - for _, f := range flags { - switch f := f.(type) { - case utils.DirectoryFlag: - set.String(f.Name, f.Value.String()+"/custom", f.Usage) - case cli.BoolFlag: - set.Bool(f.Name, true, f.Usage) - case cli.BoolTFlag: - set.Bool(f.Name, false, f.Usage) - case cli.StringFlag: - switch f { - case utils.BootnodesFlag: - set.String(f.Name, "", f.Usage) - case utils.GCModeFlag: - set.String(f.Name, "archive", f.Usage) - case utils.NodeKeyHexFlag: // either hex or file - // set.String(f.Name, "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", f.Usage) // either nodeKeyHex or nodeKeyFile - case utils.NodeKeyFileFlag: - set.String(f.Name, nodeKeyFile.Name(), f.Usage) - case utils.NetrestrictFlag: - set.String(f.Name, "127.0.0.0/16, 23.23.23.23/24,", f.Usage) // TOML problem - case utils.AuthorizationListFlag: - set.String(f.Name, "1=0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,2=0x0123456789ABCDEF0123456789ABCDE00123456789ABCDEF0123456789ABCDEF", f.Usage) - default: - set.String(f.Name, f.Value+"_custom", f.Usage) - } - case cli.Uint64Flag: - set.Uint64(f.Name, f.Value+10, f.Usage) - case cli.IntFlag: - set.Int(f.Name, f.Value+10, f.Usage) - case utils.TextMarshalerFlag: - set.String(f.Name, "light", f.Usage) - case cli.Int64Flag: - set.Int64(f.Name, f.Value+10, f.Usage) - case cli.DurationFlag: - set.Duration(f.Name, f.Value+5*time.Minute, f.Usage) - case utils.BigFlag: - set.Uint64(f.Name, f.Value.Uint64()+10, f.Usage) - case cli.Float64Flag: - set.Float64(f.Name, f.Value+0.1, f.Name) - case cli.UintFlag: - set.Uint(f.Name, f.Value+10, f.Usage) - default: - t.Logf("unknown %t", f) - t.Fail() - } - } - action := utils.MigrateFlags(dumpConfig) - app := &cli.App{ - Name: "dumpconfig", - Usage: "dump config", - Action: action, - } - - ctx := cli.NewContext(app, set, nil) - - out, err := os.CreateTemp("/tmp", "gethCfg") - require.NoError(t, err) - defer out.Close() - defer os.Remove(out.Name()) - - bak := os.Stdout - defer func() { os.Stdout = bak }() - os.Stdout = out - - err = action(ctx) - require.NoError(t, err) - - out2, err := removeComment(out.Name()) - require.NoError(t, err) - defer os.Remove(out2.Name()) - - t.Log(out2.Name()) - val, err := os.ReadFile(out2.Name()) - require.NoError(t, err) - t.Log(string(val)) - - cfg := &gethConfig{} - err = loadConfig(out2.Name(), cfg) - require.NoError(t, err) - - // [Eth] - eth := cfg.Eth - assert.Equal(t, uint64(1), eth.NetworkId) // mainnet true - // Quorum - make full sync the default sync mode in quorum (as opposed to upstream geth) - assert.Equal(t, downloader.FullSync, eth.SyncMode) - // End Quorum - assert.Equal(t, []string{"enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net"}, eth.EthDiscoveryURLs) - assert.Equal(t, false, eth.NoPruning) - assert.Equal(t, false, eth.NoPrefetch) - assert.Equal(t, 100, eth.LightPeers) - assert.Equal(t, 75, eth.UltraLightFraction) - assert.Equal(t, 768, eth.DatabaseCache) - assert.Equal(t, "", eth.DatabaseFreezer) - assert.Equal(t, 256, eth.TrieCleanCache) - assert.Equal(t, "triecache", eth.TrieCleanCacheJournal) - assert.Equal(t, time.Duration(3600000000000), eth.TrieCleanCacheRejournal) - assert.Equal(t, 256, eth.TrieDirtyCache) - assert.Equal(t, time.Duration(3600000000000), eth.TrieTimeout) - assert.Equal(t, 0, eth.SnapshotCache) - assert.Equal(t, false, eth.EnablePreimageRecording) - assert.Equal(t, "", eth.EWASMInterpreter) - assert.Equal(t, "", eth.EVMInterpreter) - assert.Equal(t, uint64(25000000), eth.RPCGasCap) - assert.Equal(t, float64(1), eth.RPCTxFeeCap) - // Quorum - assert.Equal(t, time.Duration(15000000000), eth.EVMCallTimeOut) - // End Quorum - - // [Eth.Miner] - miner := cfg.Eth.Miner - assert.Equal(t, uint64(700000000), miner.GasFloor) - assert.Equal(t, uint64(800000000), miner.GasCeil) - assert.Equal(t, big.NewInt(1000000000), miner.GasPrice) - assert.Equal(t, time.Duration(3000000000), miner.Recommit) - assert.Equal(t, time.Duration(200000000), miner.NewPayloadTimeout) - assert.Equal(t, uint64(0), miner.AllowedFutureBlockTime) - - // [Eth.GPO] - gpo := cfg.Eth.GPO - assert.Equal(t, 2, gpo.Blocks) - assert.Equal(t, 60, gpo.Percentile) - - // [Eth.TxPool] - txPool := cfg.Eth.TxPool - assert.Equal(t, []common.Address{}, txPool.Locals) - assert.Equal(t, false, txPool.NoLocals) - assert.Equal(t, "transactions.rlp", txPool.Journal) - assert.Equal(t, time.Duration(3600000000000), txPool.Rejournal) - assert.Equal(t, uint64(1), txPool.PriceLimit) - assert.Equal(t, uint64(10), txPool.PriceBump) - assert.Equal(t, uint64(16), txPool.AccountSlots) - assert.Equal(t, uint64(4096), txPool.GlobalSlots) - assert.Equal(t, uint64(64), txPool.AccountQueue) - assert.Equal(t, uint64(1024), txPool.GlobalQueue) - assert.Equal(t, time.Duration(10800000000000), txPool.Lifetime) - - // [Node] - node := cfg.Node - assert.Equal(t, "", node.DataDir) - assert.Equal(t, false, node.InsecureUnlockAllowed) - assert.Equal(t, false, node.NoUSB) - assert.Equal(t, "", node.IPCPath) - assert.Equal(t, "127.0.0.1", node.HTTPHost) - assert.Equal(t, 8545, node.HTTPPort) - assert.Equal(t, []string(nil), node.HTTPCors) - assert.Equal(t, []string{"localhost"}, node.HTTPVirtualHosts) - assert.Equal(t, []string{"net", "web3", "eth"}, node.HTTPModules) - assert.Equal(t, "127.0.0.1", node.WSHost) - assert.Equal(t, 8546, node.WSPort) - assert.Equal(t, []string(nil), node.WSOrigins) - assert.Equal(t, []string{"net", "web3", "eth"}, node.WSModules) - assert.Equal(t, []string(nil), node.GraphQLCors) - assert.Equal(t, []string{"localhost"}, node.GraphQLVirtualHosts) - assert.Equal(t, false, node.EnableNodePermission) - - // [Node.P2P] - p2p := cfg.Node.P2P - assert.Equal(t, 0, p2p.MaxPeers) - assert.Equal(t, true, p2p.NoDiscovery) - - assert.Equal(t, bootNodes(t).Nodes, p2p.BootstrapNodes) - //assert.Equal(t, bootNodesV5(t).Nodes, p2p.BootstrapNodesV5) - assert.Equal(t, "", p2p.ListenAddr) - assert.Equal(t, false, p2p.EnableMsgEvents) - - type NetRestrictType struct { - NetRestrict *netutil.Netlist - } - var netRestrict NetRestrictType - err = toml.Unmarshal([]byte(`NetRestrict = ["127.0.0.0/16", "23.23.23.0/24"]`), &netRestrict) - require.NoError(t, err) - assert.Equal(t, netRestrict.NetRestrict, p2p.NetRestrict) - - // [Node.HTTPTimeouts] - httpTimeouts := cfg.Node.HTTPTimeouts - assert.Equal(t, time.Duration(30000000000), httpTimeouts.ReadTimeout) - assert.Equal(t, time.Duration(30000000000), httpTimeouts.WriteTimeout) - assert.Equal(t, time.Duration(120000000000), httpTimeouts.IdleTimeout) - - // QUORUM - // [Eth.Istanbul] - quorumIstanbul := eth.Istanbul - config := quorumIstanbul.GetConfig(nil) - assert.Equal(t, uint64(10000), config.RequestTimeout) - assert.Equal(t, uint64(1), config.BlockPeriod) - assert.Equal(t, uint64(30000), config.Epoch) - assert.Equal(t, big.NewInt(0), quorumIstanbul.Ceil2Nby3Block) - assert.Equal(t, istanbul.RoundRobin, quorumIstanbul.ProposerPolicy.Id) // conflict with genesis? - // END QUORUM -} - -type BootNodesV5Type struct { - Nodes []*enode.Node -} - -func bootNodesV5(t *testing.T) BootNodesV5Type { - var bootNodesV5 BootNodesV5Type - err := toml.Unmarshal([]byte(`Nodes = ["enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", "enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", "enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", "enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303"]`), &bootNodesV5) - require.NoError(t, err) - return bootNodesV5 -} - -type BootNodesType struct { - Nodes []*enode.Node -} - -func bootNodes(t *testing.T) BootNodesType { - var bootNodes BootNodesType - err := toml.Unmarshal([]byte(`Nodes = ["enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", "enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", "enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", "enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303"]`), &bootNodes) - require.NoError(t, err) - return bootNodes -} - -func removeComment(name string) (*os.File, error) { - file, err := os.ReadFile(name) - if err != nil { - return nil, fmt.Errorf("read file: %w", err) - } - out, err := os.CreateTemp("/tmp", "gethCfg") - if err != nil { - return nil, fmt.Errorf("create temp file: %w", err) - } - defer out.Close() - text := string(file) - lines := strings.Split(text, "\n") - first := true - for _, line := range lines { - if strings.Index(line, "#") != 0 && !(first && line == "") { - line = strings.Replace(line, "e+00", ".0", 1) - line = strings.Replace(line, "[[", "[", 1) - line = strings.Replace(line, "]]", "]", 1) - _, err = out.WriteString(line + "\n") - if err != nil { - return nil, fmt.Errorf("write line: %w", err) - } - first = false - } - } - return out, nil -} - -func TestLoadAndDumpGethConfig(t *testing.T) { - out, err := os.CreateTemp("/tmp", "gethCfg") - require.NoError(t, err) - defer out.Close() - _, err = out.WriteString(`[Eth] -NetworkId = 1337 -SyncMode = "full" -EthDiscoveryURLs = ["enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net"] -SnapDiscoveryURLs = [] -NoPruning = false -NoPrefetch = false -LightPeers = 100 -UltraLightFraction = 75 -DatabaseCache = 768 -DatabaseFreezer = "" -TrieCleanCache = 256 -TrieCleanCacheJournal = "triecache-test" -TrieCleanCacheRejournal = 3600000000000 -TrieDirtyCache = 256 -TrieTimeout = 3600000000000 -SnapshotCache = 0 -Preimages = true -EnablePreimageRecording = false -EWASMInterpreter = "" -EVMInterpreter = "" -RPCGasCap = 25000000 -RPCTxFeeCap = 1e+00 -RaftMode = true -EnableNodePermission = true -EVMCallTimeOut = 3600000000000 - -[Eth.Miner] -GasFloor = 700000000 -GasCeil = 800000000 -GasPrice = 0 -Recommit = 3000000000 -NewPayloadTimeout = 200000000 -AllowedFutureBlockTime = 0 - -[Eth.GPO] -Blocks = 20 -Percentile = 60 -MaxPrice = 500000000000 - -[Eth.TxPool] -Locals = [] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Eth.Istanbul] -RequestTimeout = 10000 -BlockPeriod = 5 -ProposerPolicy = "id = 0\n" -Epoch = 30000 -Ceil2Nby3Block = 0 -TestQBFTBlock = 0 - -[Node] -UserIdent = "_custom" -DataDir = "/data" -RaftLogDir = "" -InsecureUnlockAllowed = true -NoUSB = true -IPCPath = "geth.ipc" -HTTPHost = "0.0.0.0" -HTTPPort = 8545 -HTTPCors = ["'*'"] -HTTPVirtualHosts = ["'*'"] -HTTPModules = ["admin", "db", "eth", "debug", "miner", "net", "txpool", "personal", "web3", "quorum", "istanbul"] -WSHost = "0.0.0.0" -WSPort = 8546 -WSOrigins = ["'*'"] -WSModules = ["admin", "db", "eth", "debug", "miner", "net", "txpool", "personal", "web3", "quorum", "istanbul"] -GraphQLCors = ["'*'"] -GraphQLVirtualHosts = ["'*'"] -EnableNodePermission = true - -[Node.P2P] -MaxPeers = 50 -NoDiscovery = true -BootstrapNodes = ["enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", "enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", "enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", "enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303"] -BootstrapNodesV5 = ["enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", "enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", "enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", "enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303"] -StaticNodes = [] -TrustedNodes = [] -NetRestrict = ["127.0.0.0/16", "23.23.23.0/24"] -ListenAddr = ":30303" -EnableMsgEvents = false - -[Node.HTTPTimeouts] -ReadTimeout = 30000000000 -WriteTimeout = 30000000000 -IdleTimeout = 120000000000 - -[Metrics] -HTTP = "127.0.0.1" -Port = 6060 -InfluxDBEndpoint = "http://localhost:8086" -InfluxDBDatabase = "geth" -InfluxDBUsername = "test" -InfluxDBPassword = "test" -InfluxDBTags = "host=localhost" -`) - require.NoError(t, err) - err = out.Close() - require.NoError(t, err) - cfg := &gethConfig{} - - err = loadConfig(out.Name(), cfg) - require.NoError(t, err) - - testConfig(t, cfg) - - out, err = os.CreateTemp("/tmp", "gethCfg") - require.NoError(t, err) - - err = tomlSettings.NewEncoder(out).Encode(cfg) - require.NoError(t, err) - - cfg = &gethConfig{} - err = loadConfig(out.Name(), cfg) - require.NoError(t, err) - - testConfig(t, cfg) -} - -func testConfig(t *testing.T, cfg *gethConfig) { - // [Eth] - eth := cfg.Eth - assert.Equal(t, uint64(1337), eth.NetworkId) - assert.Equal(t, downloader.FullSync, eth.SyncMode) - assert.Equal(t, []string{"enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net"}, eth.EthDiscoveryURLs) - assert.Equal(t, false, eth.NoPruning) - assert.Equal(t, false, eth.NoPrefetch) - assert.Equal(t, 100, eth.LightPeers) - assert.Equal(t, 75, eth.UltraLightFraction) - assert.Equal(t, 768, eth.DatabaseCache) - assert.Equal(t, "", eth.DatabaseFreezer) - assert.Equal(t, 256, eth.TrieCleanCache) - assert.Equal(t, "triecache-test", eth.TrieCleanCacheJournal) - assert.Equal(t, time.Duration(3600000000000), eth.TrieCleanCacheRejournal) - assert.Equal(t, 256, eth.TrieDirtyCache) - assert.Equal(t, time.Duration(3600000000000), eth.TrieTimeout) - assert.Equal(t, 0, eth.SnapshotCache) - assert.Equal(t, false, eth.EnablePreimageRecording) - assert.Equal(t, "", eth.EWASMInterpreter) - assert.Equal(t, "", eth.EVMInterpreter) - assert.Equal(t, uint64(25000000), eth.RPCGasCap) - assert.Equal(t, float64(1), eth.RPCTxFeeCap) - // Quorum - assert.Equal(t, time.Duration(3600000000000), eth.EVMCallTimeOut) - assert.Equal(t, true, eth.EnableNodePermission) - // End Quorum - - // [Eth.Miner] - miner := eth.Miner - assert.Equal(t, uint64(700000000), miner.GasFloor) - assert.Equal(t, uint64(800000000), miner.GasCeil) - assert.Equal(t, big.NewInt(0), miner.GasPrice) - assert.Equal(t, time.Duration(3000000000), miner.Recommit) - assert.Equal(t, uint64(0), miner.AllowedFutureBlockTime) - - // [Eth.GPO] - gpo := eth.GPO - assert.Equal(t, 20, gpo.Blocks) - assert.Equal(t, 60, gpo.Percentile) - - // [Eth.TxPool] - txPool := eth.TxPool - assert.Equal(t, []common.Address{}, txPool.Locals) - assert.Equal(t, false, txPool.NoLocals) - assert.Equal(t, "transactions.rlp", txPool.Journal) - assert.Equal(t, time.Duration(3600000000000), txPool.Rejournal) - assert.Equal(t, uint64(1), txPool.PriceLimit) - assert.Equal(t, uint64(10), txPool.PriceBump) - assert.Equal(t, uint64(16), txPool.AccountSlots) - assert.Equal(t, uint64(4096), txPool.GlobalSlots) - assert.Equal(t, uint64(64), txPool.AccountQueue) - assert.Equal(t, uint64(1024), txPool.GlobalQueue) - assert.Equal(t, time.Duration(10800000000000), txPool.Lifetime) - - // [Node] - node := cfg.Node - assert.Equal(t, "/data", node.DataDir) - assert.Equal(t, true, node.InsecureUnlockAllowed) - assert.Equal(t, true, node.NoUSB) - assert.Equal(t, "geth.ipc", node.IPCPath) - assert.Equal(t, "0.0.0.0", node.HTTPHost) - assert.Equal(t, 8545, node.HTTPPort) - assert.Equal(t, []string{"'*'"}, node.HTTPCors) - assert.Equal(t, []string{"'*'"}, node.HTTPVirtualHosts) - assert.Equal(t, []string{"admin", "db", "eth", "debug", "miner", "net", "txpool", "personal", "web3", "quorum", "istanbul"}, node.HTTPModules) - assert.Equal(t, "0.0.0.0", node.WSHost) - assert.Equal(t, 8546, node.WSPort) - assert.Equal(t, []string{"'*'"}, node.WSOrigins) - assert.Equal(t, []string{"admin", "db", "eth", "debug", "miner", "net", "txpool", "personal", "web3", "quorum", "istanbul"}, node.WSModules) - assert.Equal(t, []string{"'*'"}, node.GraphQLCors) - assert.Equal(t, []string{"'*'"}, node.GraphQLVirtualHosts) - assert.Equal(t, true, node.EnableNodePermission) - - // [Node.P2P] - p2p := cfg.Node.P2P - assert.Equal(t, 50, p2p.MaxPeers) - assert.Equal(t, true, p2p.NoDiscovery) - assert.Equal(t, bootNodes(t).Nodes, p2p.BootstrapNodes) - assert.Equal(t, bootNodesV5(t).Nodes, p2p.BootstrapNodesV5) - - /*assert.Equal(t, []*enode.Node{}, p2p.BootstrapNodes) - if p2p.BootstrapNodesV5 != nil { - assert.Equal(t, []*enode.Node{}, p2p.BootstrapNodesV5) - }*/ - assert.Equal(t, ":30303", p2p.ListenAddr) - assert.Equal(t, false, p2p.EnableMsgEvents) - - // [Node.HTTPTimeouts] - httpTimeouts := cfg.Node.HTTPTimeouts - assert.Equal(t, time.Duration(30000000000), httpTimeouts.ReadTimeout) - assert.Equal(t, time.Duration(30000000000), httpTimeouts.WriteTimeout) - assert.Equal(t, time.Duration(120000000000), httpTimeouts.IdleTimeout) - - // QUORUM - // [Eth.Quorum.Istanbul] - istanbul := cfg.Eth.Istanbul - config := istanbul.GetConfig(nil) - assert.Equal(t, uint64(10000), config.RequestTimeout) - assert.Equal(t, uint64(5), config.BlockPeriod) - assert.Equal(t, uint64(30000), config.Epoch) - assert.Equal(t, big.NewInt(0), istanbul.Ceil2Nby3Block) - // END QUORUM -} diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go index f6aed0f97..8e8ddb229 100644 --- a/cmd/geth/consolecmd.go +++ b/cmd/geth/consolecmd.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/plugin/security" "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( @@ -41,25 +41,23 @@ var ( rpcClientFlags = []cli.Flag{utils.RPCClientToken, utils.RPCClientTLSCert, utils.RPCClientTLSCaCert, utils.RPCClientTLSCipherSuites, utils.RPCClientTLSInsecureSkipVerify} - consoleCommand = cli.Command{ - Action: utils.MigrateFlags(localConsole), - Name: "console", - Usage: "Start an interactive JavaScript environment", - Flags: append(append(nodeFlags, rpcFlags...), consoleFlags...), - Category: "CONSOLE COMMANDS", + consoleCommand = &cli.Command{ + Action: localConsole, + Name: "console", + Usage: "Start an interactive JavaScript environment", + Flags: append(append(nodeFlags, rpcFlags...), consoleFlags...), Description: ` The Geth console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. See https://geth.ethereum.org/docs/interface/javascript-console.`, } - attachCommand = cli.Command{ - Action: utils.MigrateFlags(remoteConsole), + attachCommand = &cli.Command{ + Action: remoteConsole, Name: "attach", Usage: "Start an interactive JavaScript environment (connect to node)", ArgsUsage: "[endpoint]", Flags: append(append(consoleFlags, utils.DataDirFlag), rpcClientFlags...), - Category: "CONSOLE COMMANDS", Description: ` The Geth console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. @@ -67,13 +65,12 @@ See https://geth.ethereum.org/docs/interface/javascript-console. This command allows to open a console on a running geth node.`, } - javascriptCommand = cli.Command{ - Action: utils.MigrateFlags(ephemeralConsole), + javascriptCommand = &cli.Command{ + Action: ephemeralConsole, Name: "js", Usage: "Execute the specified JavaScript files", ArgsUsage: " [jsfile...]", Flags: append(nodeFlags, consoleFlags...), - Category: "CONSOLE COMMANDS", Description: ` The JavaScript VM exposes a node admin interface as well as the Ðapp JavaScript API. See https://geth.ethereum.org/docs/interface/javascript-console`, @@ -164,7 +161,7 @@ func localConsole(ctx *cli.Context) error { } config := console.Config{ DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), + DocRoot: ctx.String(utils.JSpathFlag.Name), Client: client, Preload: utils.MakeConsolePreloads(ctx), } @@ -176,7 +173,7 @@ func localConsole(ctx *cli.Context) error { defer console.Stop(false) // If only a short execution was requested, evaluate and return - if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { + if script := ctx.String(utils.ExecFlag.Name); script != "" { console.Evaluate(script) return nil } @@ -190,15 +187,18 @@ func localConsole(ctx *cli.Context) error { // remoteConsole will connect to a remote geth instance, attaching a JavaScript // console to it. func remoteConsole(ctx *cli.Context) error { - // Attach to a remotely running geth instance and start the JavaScript console + if ctx.Args().Len() > 1 { + utils.Fatalf("invalid command-line: too many arguments") + } + endpoint := ctx.Args().First() if endpoint == "" { path := node.DefaultDataDir() - if ctx.GlobalIsSet(utils.DataDirFlag.Name) { - path = ctx.GlobalString(utils.DataDirFlag.Name) + if ctx.IsSet(utils.DataDirFlag.Name) { + path = ctx.String(utils.DataDirFlag.Name) } if path != "" { - if ctx.GlobalBool(utils.RopstenFlag.Name) { + if ctx.Bool(utils.RopstenFlag.Name) { // Maintain compatibility with older Geth configurations storing the // Ropsten database in `testnet` instead of `ropsten`. legacyPath := filepath.Join(path, "testnet") @@ -207,11 +207,11 @@ func remoteConsole(ctx *cli.Context) error { } else { path = filepath.Join(path, "ropsten") } - } else if ctx.GlobalBool(utils.RinkebyFlag.Name) { + } else if ctx.Bool(utils.RinkebyFlag.Name) { path = filepath.Join(path, "rinkeby") - } else if ctx.GlobalBool(utils.GoerliFlag.Name) { + } else if ctx.Bool(utils.GoerliFlag.Name) { path = filepath.Join(path, "goerli") - } else if ctx.GlobalBool(utils.YoloV3Flag.Name) { + } else if ctx.Bool(utils.YoloV3Flag.Name) { path = filepath.Join(path, "yolo-v3") } } @@ -223,7 +223,7 @@ func remoteConsole(ctx *cli.Context) error { } config := console.Config{ DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), + DocRoot: ctx.String(utils.JSpathFlag.Name), Client: client, Preload: utils.MakeConsolePreloads(ctx), } @@ -234,7 +234,7 @@ func remoteConsole(ctx *cli.Context) error { } defer console.Stop(false) - if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { + if script := ctx.String(utils.ExecFlag.Name); script != "" { console.Evaluate(script) return nil } @@ -325,7 +325,7 @@ func ephemeralConsole(ctx *cli.Context) error { } config := console.Config{ DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), + DocRoot: ctx.String(utils.JSpathFlag.Name), Client: client, Preload: utils.MakeConsolePreloads(ctx), } @@ -337,7 +337,7 @@ func ephemeralConsole(ctx *cli.Context) error { defer console.Stop(false) // Evaluate each of the specified JavaScript files - for _, file := range ctx.Args() { + for _, file := range ctx.Args().Slice() { if err = console.Execute(file); err != nil { utils.Fatalf("Failed to execute %s: %v", file, err) } diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 5ec5618f4..4b418c86c 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -32,7 +32,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/params" testifyassert "github.com/stretchr/testify/assert" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index 3ecdf0658..2fe83edcd 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -32,12 +32,12 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - removedbCommand = cli.Command{ - Action: utils.MigrateFlags(removeDB), + removedbCommand = &cli.Command{ + Action: removeDB, Name: "removedb", Usage: "Remove blockchain and state databases", ArgsUsage: "", @@ -48,12 +48,12 @@ var ( Description: ` Remove blockchain and state databases`, } - dbCommand = cli.Command{ + dbCommand = &cli.Command{ Name: "db", Usage: "Low level database operations", ArgsUsage: "", Category: "DATABASE COMMANDS", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ dbInspectCmd, dbStatCmd, dbCompactCmd, @@ -64,8 +64,8 @@ Remove blockchain and state databases`, dbDumpFreezerIndex, }, } - dbInspectCmd = cli.Command{ - Action: utils.MigrateFlags(inspect), + dbInspectCmd = &cli.Command{ + Action: inspect, Name: "inspect", ArgsUsage: " ", Flags: []cli.Flag{ @@ -80,8 +80,8 @@ Remove blockchain and state databases`, Usage: "Inspect the storage size for each type of data in the database", Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`, } - dbStatCmd = cli.Command{ - Action: utils.MigrateFlags(dbStats), + dbStatCmd = &cli.Command{ + Action: dbStats, Name: "stats", Usage: "Print leveldb statistics", Flags: []cli.Flag{ @@ -94,8 +94,8 @@ Remove blockchain and state databases`, utils.YoloV3Flag, }, } - dbCompactCmd = cli.Command{ - Action: utils.MigrateFlags(dbCompact), + dbCompactCmd = &cli.Command{ + Action: dbCompact, Name: "compact", Usage: "Compact leveldb database. WARNING: May take a very long time", Flags: []cli.Flag{ @@ -113,8 +113,8 @@ Remove blockchain and state databases`, WARNING: This operation may take a very long time to finish, and may cause database corruption if it is aborted during execution'!`, } - dbGetCmd = cli.Command{ - Action: utils.MigrateFlags(dbGet), + dbGetCmd = &cli.Command{ + Action: dbGet, Name: "get", Usage: "Show the value of a database key", ArgsUsage: "", @@ -129,8 +129,8 @@ corruption if it is aborted during execution'!`, }, Description: "This command looks up the specified database key from the database.", } - dbDeleteCmd = cli.Command{ - Action: utils.MigrateFlags(dbDelete), + dbDeleteCmd = &cli.Command{ + Action: dbDelete, Name: "delete", Usage: "Delete a database key (WARNING: may corrupt your database)", ArgsUsage: "", @@ -146,8 +146,8 @@ corruption if it is aborted during execution'!`, Description: `This command deletes the specified database key from the database. WARNING: This is a low-level operation which may cause database corruption!`, } - dbPutCmd = cli.Command{ - Action: utils.MigrateFlags(dbPut), + dbPutCmd = &cli.Command{ + Action: dbPut, Name: "put", Usage: "Set the value of a database key (WARNING: may corrupt your database)", ArgsUsage: " ", @@ -163,8 +163,8 @@ WARNING: This is a low-level operation which may cause database corruption!`, Description: `This command sets a given database key to the given value. WARNING: This is a low-level operation which may cause database corruption!`, } - dbGetSlotsCmd = cli.Command{ - Action: utils.MigrateFlags(dbDumpTrie), + dbGetSlotsCmd = &cli.Command{ + Action: dbDumpTrie, Name: "dumptrie", Usage: "Show the storage key/values of a given storage trie", ArgsUsage: " ", @@ -179,8 +179,8 @@ WARNING: This is a low-level operation which may cause database corruption!`, }, Description: "This command looks up the specified database key from the database.", } - dbDumpFreezerIndex = cli.Command{ - Action: utils.MigrateFlags(freezerInspect), + dbDumpFreezerIndex = &cli.Command{ + Action: freezerInspect, Name: "freezer-index", Usage: "Dump out the index of a given freezer type", ArgsUsage: " ", diff --git a/cmd/geth/les_test.go b/cmd/geth/les_test.go index 8958cf1e1..1a20388f4 100644 --- a/cmd/geth/les_test.go +++ b/cmd/geth/les_test.go @@ -124,7 +124,7 @@ func initGeth(t *testing.T) string { func startLightServer(t *testing.T) *gethrpc { datadir := initGeth(t) t.Logf("Importing keys to geth") - runGeth(t, "--datadir", datadir, "--password", "./testdata/password.txt", "account", "import", "./testdata/key.prv", "--lightkdf").WaitExit() + runGeth(t, "account", "import", "--datadir", datadir, "--password", "./testdata/password.txt", "--lightkdf", "./testdata/key.prv").WaitExit() account := "0x02f0d131f1f97aef08aec6e3291b957d9efe7105" server := startGethWithIpc(t, "lightserver", "--allow-insecure-unlock", "--datadir", datadir, "--password", "./testdata/password.txt", "--unlock", account, "--mine", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1", "--verbosity=4") return server diff --git a/cmd/geth/main.go b/cmd/geth/main.go index c69aa54db..075f0ab69 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -42,7 +42,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/permission" "github.com/ethereum/go-ethereum/plugin" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( @@ -254,7 +254,7 @@ func init() { app.Action = geth app.HideVersion = true // we have a command to print the version app.Copyright = "Copyright 2013-2021 The go-ethereum Authors" - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ // See chaincmd.go: initCommand, updateCommand, @@ -295,6 +295,7 @@ func init() { app.Flags = append(app.Flags, metricsFlags...) app.Before = func(ctx *cli.Context) error { + flags.MigrateGlobalFlags(ctx) return debug.Setup(ctx) } app.After = func(ctx *cli.Context) error { @@ -316,37 +317,37 @@ func main() { func prepare(ctx *cli.Context) { // If we're running a known preset, log it for convenience. switch { - case ctx.GlobalIsSet(utils.RopstenFlag.Name): + case ctx.IsSet(utils.RopstenFlag.Name): log.Info("Starting Geth on Ropsten testnet...") - case ctx.GlobalIsSet(utils.RinkebyFlag.Name): + case ctx.IsSet(utils.RinkebyFlag.Name): log.Info("Starting Geth on Rinkeby testnet...") - case ctx.GlobalIsSet(utils.GoerliFlag.Name): + case ctx.IsSet(utils.GoerliFlag.Name): log.Info("Starting Geth on Görli testnet...") - case ctx.GlobalIsSet(utils.YoloV3Flag.Name): + case ctx.IsSet(utils.YoloV3Flag.Name): log.Info("Starting Geth on YOLOv3 testnet...") - case ctx.GlobalIsSet(utils.DeveloperFlag.Name): + case ctx.IsSet(utils.DeveloperFlag.Name): log.Info("Starting Geth in ephemeral dev mode...") - case !ctx.GlobalIsSet(utils.NetworkIdFlag.Name): + case !ctx.IsSet(utils.NetworkIdFlag.Name): log.Info("Starting Geth on Ethereum mainnet...") } // If we're a full node on mainnet without --cache specified, bump default cache allowance - if ctx.GlobalString(utils.SyncModeFlag.Name) != "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) && !ctx.GlobalIsSet(utils.NetworkIdFlag.Name) { + if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) { // Make sure we're not on any supported preconfigured testnet either - if !ctx.GlobalIsSet(utils.RopstenFlag.Name) && !ctx.GlobalIsSet(utils.RinkebyFlag.Name) && !ctx.GlobalIsSet(utils.GoerliFlag.Name) && !ctx.GlobalIsSet(utils.DeveloperFlag.Name) { + if !ctx.IsSet(utils.RopstenFlag.Name) && !ctx.IsSet(utils.RinkebyFlag.Name) && !ctx.IsSet(utils.GoerliFlag.Name) && !ctx.IsSet(utils.DeveloperFlag.Name) { // Nope, we're really on mainnet. Bump that cache up! - log.Info("Bumping default cache on mainnet", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 4096) - ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(4096)) + log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096) + ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) } } // If we're running a light client on any network, drop the cache to some meaningfully low amount - if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) { - log.Info("Dropping default light client cache", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 128) - ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(128)) + if ctx.String(utils.SyncModeFlag.Name) == "light" && !ctx.IsSet(utils.CacheFlag.Name) { + log.Info("Dropping default light client cache", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 128) + ctx.Set(utils.CacheFlag.Name, strconv.Itoa(128)) } // Start metrics export if enabled @@ -360,7 +361,7 @@ func prepare(ctx *cli.Context) { // It creates a default node based on the command line arguments and runs it in // blocking mode, waiting for it to be shut down. func geth(ctx *cli.Context) error { - if args := ctx.Args(); len(args) > 0 { + if args := ctx.Args().Slice(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } @@ -377,11 +378,11 @@ func geth(ctx *cli.Context) error { // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // miner. func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { - log.DoEmitCheckpoints = ctx.GlobalBool(utils.EmitCheckpointsFlag.Name) + log.DoEmitCheckpoints = ctx.Bool(utils.EmitCheckpointsFlag.Name) debug.Memsize.Add("node", stack) // raft mode does not support --exitwhensynced - if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) && ctx.GlobalBool(utils.RaftModeFlag.Name) { + if ctx.Bool(utils.ExitWhenSyncedFlag.Name) && ctx.Bool(utils.RaftModeFlag.Name) { utils.Fatalf("raft consensus does not support --exitwhensynced") } @@ -411,7 +412,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { ethClient := ethclient.NewClient(rpcClient) // Quorum - if ctx.GlobalBool(utils.MultitenancyFlag.Name) && !stack.PluginManager().IsEnabled(plugin.SecurityPluginInterfaceName) { + if ctx.Bool(utils.MultitenancyFlag.Name) && !stack.PluginManager().IsEnabled(plugin.SecurityPluginInterfaceName) { utils.Fatalf("multitenancy requires RPC Security Plugin to be configured") } // End Quorum @@ -451,7 +452,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { // Spawn a standalone goroutine for status synchronization monitoring, // close the node when synchronization is complete if user required. - if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) { + if ctx.Bool(utils.ExitWhenSyncedFlag.Name) { go func() { sub := stack.EventMux().Subscribe(downloader.DoneEvent{}) defer sub.Unsubscribe() @@ -490,9 +491,9 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { } // Start auxiliary services if enabled - if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { + if ctx.Bool(utils.MiningEnabledFlag.Name) || ctx.Bool(utils.DeveloperFlag.Name) { // Mining only makes sense if a full Ethereum node is running - if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { + if ctx.String(utils.SyncModeFlag.Name) == "light" { utils.Fatalf("Light clients do not support mining") } ethBackend, ok := backend.(*eth.EthAPIBackend) @@ -500,7 +501,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { utils.Fatalf("Ethereum service not running: %v", err) } // Set the gas price to the limits from the CLI and start mining - gasprice := utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name) + gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name) ethBackend.TxPool().SetGasPrice(gasprice) if err := ethBackend.StartMining(); err != nil { utils.Fatalf("Failed to start mining: %v", err) @@ -508,13 +509,13 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { } // checks quorum features that depend on the ethereum service - quorumValidateEthService(stack, ctx.GlobalBool(utils.RaftModeFlag.Name)) + quorumValidateEthService(stack, ctx.Bool(utils.RaftModeFlag.Name)) } // unlockAccounts unlocks any account specifically requested. func unlockAccounts(ctx *cli.Context, stack *node.Node) { var unlocks []string - inputs := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") + inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",") for _, input := range inputs { if trimmed := strings.TrimSpace(input); trimmed != "" { unlocks = append(unlocks, trimmed) diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index 1b11260c6..c00636589 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -22,56 +22,52 @@ import ( "runtime" "strings" - "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var ( - VersionCheckUrlFlag = cli.StringFlag{ + VersionCheckUrlFlag = &cli.StringFlag{ Name: "check.url", Usage: "URL to use when checking vulnerabilities", Value: "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json", } - VersionCheckVersionFlag = cli.StringFlag{ + VersionCheckVersionFlag = &cli.StringFlag{ Name: "check.version", Usage: "Version to check", Value: fmt.Sprintf("Geth/v%v/%v-%v/%v", params.VersionWithCommit(gitCommit, gitDate), runtime.GOOS, runtime.GOARCH, runtime.Version()), } - versionCommand = cli.Command{ - Action: utils.MigrateFlags(version), + versionCommand = &cli.Command{ + Action: version, Name: "version", Usage: "Print version numbers", ArgsUsage: " ", - Category: "MISCELLANEOUS COMMANDS", Description: ` The output of this command is supposed to be machine-readable. `, } - versionCheckCommand = cli.Command{ - Action: utils.MigrateFlags(versionCheck), + versionCheckCommand = &cli.Command{ + Action: versionCheck, Flags: []cli.Flag{ VersionCheckUrlFlag, VersionCheckVersionFlag, }, Name: "version-check", - Usage: "Checks (online) whether the current version suffers from any known security vulnerabilities", + Usage: "Checks (online) for known Geth security vulnerabilities", ArgsUsage: "", - Category: "MISCELLANEOUS COMMANDS", Description: ` The version-check command fetches vulnerability-information from https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json, and displays information about any security vulnerabilities that affect the currently executing version. `, } - licenseCommand = cli.Command{ - Action: utils.MigrateFlags(license), + licenseCommand = &cli.Command{ + Action: license, Name: "license", Usage: "Display license information", ArgsUsage: " ", - Category: "MISCELLANEOUS COMMANDS", } ) diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index 157cec3e2..92c2fbd62 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -31,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - cli "gopkg.in/urfave/cli.v1" + cli "github.com/urfave/cli/v2" ) var ( @@ -43,18 +43,16 @@ var ( ) var ( - snapshotCommand = cli.Command{ + snapshotCommand = &cli.Command{ Name: "snapshot", Usage: "A set of commands based on the snapshot", - Category: "MISCELLANEOUS COMMANDS", Description: "", - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "prune-state", Usage: "Prune stale ethereum state data based on the snapshot", ArgsUsage: "", - Action: utils.MigrateFlags(pruneState), - Category: "MISCELLANEOUS COMMANDS", + Action: pruneState, Flags: []cli.Flag{ utils.DataDirFlag, utils.AncientFlag, @@ -83,8 +81,7 @@ the trie clean cache with default directory will be deleted. Name: "verify-state", Usage: "Recalculate state hash based on the snapshot for verification", ArgsUsage: "", - Action: utils.MigrateFlags(verifyState), - Category: "MISCELLANEOUS COMMANDS", + Action: verifyState, Flags: []cli.Flag{ utils.DataDirFlag, utils.AncientFlag, @@ -103,8 +100,7 @@ In other words, this command does the snapshot to trie conversion. Name: "traverse-state", Usage: "Traverse the state with given root hash for verification", ArgsUsage: "", - Action: utils.MigrateFlags(traverseState), - Category: "MISCELLANEOUS COMMANDS", + Action: traverseState, Flags: []cli.Flag{ utils.DataDirFlag, utils.AncientFlag, @@ -125,8 +121,7 @@ It's also usable without snapshot enabled. Name: "traverse-rawstate", Usage: "Traverse the state with given root hash for verification", ArgsUsage: "", - Action: utils.MigrateFlags(traverseRawState), - Category: "MISCELLANEOUS COMMANDS", + Action: traverseRawState, Flags: []cli.Flag{ utils.DataDirFlag, utils.AncientFlag, @@ -154,7 +149,7 @@ func pruneState(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, false) - pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), stack.ResolvePath(config.Eth.TrieCleanCacheJournal), ctx.GlobalUint64(utils.BloomFilterSizeFlag.Name)) + pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), stack.ResolvePath(config.Eth.TrieCleanCacheJournal), ctx.Uint64(utils.BloomFilterSizeFlag.Name)) if err != nil { log.Error("Failed to open snapshot tree", "err", err) return err @@ -165,7 +160,7 @@ func pruneState(ctx *cli.Context) error { } var targetRoot common.Hash if ctx.NArg() == 1 { - targetRoot, err = parseRoot(ctx.Args()[0]) + targetRoot, err = parseRoot(ctx.Args().First()) if err != nil { log.Error("Failed to resolve state root", "err", err) return err @@ -199,7 +194,7 @@ func verifyState(ctx *cli.Context) error { } var root = headBlock.Root() if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) + root, err = parseRoot(ctx.Args().First()) if err != nil { log.Error("Failed to resolve state root", "err", err) return err @@ -235,7 +230,7 @@ func traverseState(ctx *cli.Context) error { err error ) if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) + root, err = parseRoot(ctx.Args().First()) if err != nil { log.Error("Failed to resolve state root", "err", err) return err @@ -325,7 +320,7 @@ func traverseRawState(ctx *cli.Context) error { err error ) if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) + root, err = parseRoot(ctx.Args().First()) if err != nil { log.Error("Failed to resolve state root", "err", err) return err diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go deleted file mode 100644 index 64a674d8a..000000000 --- a/cmd/geth/usage.go +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -// Contains the geth command usage template and generator. - -package main - -import ( - "io" - "sort" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/internal/debug" - "github.com/ethereum/go-ethereum/internal/flags" - "gopkg.in/urfave/cli.v1" -) - -// Quorum -var quorumAccountFlagGroup = "QUORUM ACCOUNT" - -// End Quorum - -// AppHelpFlagGroups is the application flags, grouped by functionality. -var AppHelpFlagGroups = []flags.FlagGroup{ - { - Name: "ETHEREUM", - Flags: []cli.Flag{ - configFileFlag, - utils.DataDirFlag, - utils.AncientFlag, - utils.MinFreeDiskSpaceFlag, - utils.KeyStoreDirFlag, - utils.USBFlag, - utils.SmartCardDaemonPathFlag, - utils.NetworkIdFlag, - utils.MainnetFlag, - utils.GoerliFlag, - utils.RinkebyFlag, - utils.YoloV3Flag, - utils.RopstenFlag, - utils.SyncModeFlag, - utils.ExitWhenSyncedFlag, - utils.GCModeFlag, - utils.TxLookupLimitFlag, - utils.EthStatsURLFlag, - utils.IdentityFlag, - utils.LightKDFFlag, - utils.AuthorizationListFlag, - }, - }, - { - Name: "LIGHT CLIENT", - Flags: []cli.Flag{ - utils.LightServeFlag, - utils.LightIngressFlag, - utils.LightEgressFlag, - utils.LightMaxPeersFlag, - utils.UltraLightServersFlag, - utils.UltraLightFractionFlag, - utils.UltraLightOnlyAnnounceFlag, - utils.LightNoPruneFlag, - utils.LightNoSyncServeFlag, - }, - }, - { - Name: "DEVELOPER CHAIN", - Flags: []cli.Flag{ - utils.DeveloperFlag, - utils.DeveloperPeriodFlag, - }, - }, - { - Name: "TRANSACTION POOL", - Flags: []cli.Flag{ - utils.TxPoolLocalsFlag, - utils.TxPoolNoLocalsFlag, - utils.TxPoolJournalFlag, - utils.TxPoolRejournalFlag, - utils.TxPoolPriceLimitFlag, - utils.TxPoolPriceBumpFlag, - utils.TxPoolAccountSlotsFlag, - utils.TxPoolGlobalSlotsFlag, - utils.TxPoolAccountQueueFlag, - utils.TxPoolGlobalQueueFlag, - utils.TxPoolLifetimeFlag, - }, - }, - { - Name: "PERFORMANCE TUNING", - Flags: []cli.Flag{ - utils.CacheFlag, - utils.CacheDatabaseFlag, - utils.CacheTrieFlag, - utils.CacheTrieJournalFlag, - utils.CacheTrieRejournalFlag, - utils.CacheGCFlag, - utils.CacheSnapshotFlag, - utils.CacheNoPrefetchFlag, - utils.CachePreimagesFlag, - }, - }, - { - Name: "ACCOUNT", - Flags: []cli.Flag{ - utils.UnlockedAccountFlag, - utils.PasswordFileFlag, - utils.ExternalSignerFlag, - utils.InsecureUnlockAllowedFlag, - }, - }, - { - Name: "API AND CONSOLE", - Flags: []cli.Flag{ - utils.IPCDisabledFlag, - utils.IPCPathFlag, - utils.HTTPEnabledFlag, - utils.HTTPListenAddrFlag, - utils.HTTPPortFlag, - utils.HTTPApiFlag, - utils.HTTPPathPrefixFlag, - utils.HTTPCORSDomainFlag, - utils.HTTPVirtualHostsFlag, - utils.WSEnabledFlag, - utils.WSListenAddrFlag, - utils.WSPortFlag, - utils.WSApiFlag, - utils.WSPathPrefixFlag, - utils.WSAllowedOriginsFlag, - utils.GraphQLEnabledFlag, - utils.GraphQLCORSDomainFlag, - utils.GraphQLVirtualHostsFlag, - utils.RPCGlobalGasCapFlag, - utils.RPCGlobalTxFeeCapFlag, - utils.AllowUnprotectedTxs, - utils.JSpathFlag, - utils.ExecFlag, - utils.PreloadJSFlag, - // Quorum - utils.RPCClientToken, - utils.RPCClientTLSInsecureSkipVerify, - utils.RPCClientTLSCert, - utils.RPCClientTLSCaCert, - utils.RPCClientTLSCipherSuites, - }, - }, - { - Name: "NETWORKING", - Flags: []cli.Flag{ - utils.BootnodesFlag, - utils.DNSDiscoveryFlag, - utils.ListenPortFlag, - utils.MaxPeersFlag, - utils.MaxPendingPeersFlag, - utils.NATFlag, - utils.NoDiscoverFlag, - utils.DiscoveryV5Flag, - utils.NetrestrictFlag, - utils.NodeKeyFileFlag, - utils.NodeKeyHexFlag, - }, - }, - { - Name: "MINER", - Flags: []cli.Flag{ - utils.MinerGasPriceFlag, - utils.MinerGasTargetFlag, - utils.MinerGasLimitFlag, - utils.MinerEtherbaseFlag, - utils.MinerExtraDataFlag, - utils.MinerRecommitIntervalFlag, - }, - }, - { - Name: "GAS PRICE ORACLE", - Flags: []cli.Flag{ - utils.GpoBlocksFlag, - utils.GpoPercentileFlag, - utils.GpoMaxGasPriceFlag, - }, - }, - { - Name: "VIRTUAL MACHINE", - Flags: []cli.Flag{ - utils.VMEnableDebugFlag, - utils.EVMInterpreterFlag, - utils.EWASMInterpreterFlag, - // Quorum - timout for calls - utils.EVMCallTimeOutFlag, - }, - }, - { - Name: "LOGGING AND DEBUGGING", - Flags: append([]cli.Flag{ - utils.FakePoWFlag, - utils.NoCompactionFlag, - }, debug.Flags...), - }, - { - Name: "METRICS AND STATS", - Flags: metricsFlags, - }, - { - Name: "ALIASED (deprecated)", - Flags: []cli.Flag{ - utils.NoUSBFlag, - utils.LegacyRPCEnabledFlag, - utils.LegacyRPCListenAddrFlag, - utils.LegacyRPCPortFlag, - utils.LegacyRPCCORSDomainFlag, - utils.LegacyRPCVirtualHostsFlag, - utils.LegacyRPCApiFlag, - }, - }, - // QUORUM - { - Name: "QUORUM", - Flags: []cli.Flag{ - utils.QuorumImmutabilityThreshold, - utils.EnableNodePermissionFlag, - utils.PluginSettingsFlag, - utils.PluginSkipVerifyFlag, - utils.PluginLocalVerifyFlag, - utils.PluginPublicKeyFlag, - utils.AllowedFutureBlockTimeFlag, - utils.MultitenancyFlag, - utils.RevertReasonFlag, - utils.QuorumEnablePrivateTrieCache, - utils.QuorumEnablePrivacyMarker, - }, - }, - { - Name: "QUORUM LIGHT CLIENT/SERVER", - Flags: []cli.Flag{ - utils.QuorumLightServerFlag, - utils.QuorumLightServerP2PListenPortFlag, - utils.QuorumLightServerP2PMaxPeersFlag, - utils.QuorumLightServerP2PNetrestrictFlag, - utils.QuorumLightServerP2PPermissioningFlag, - utils.QuorumLightServerP2PPermissioningPrefixFlag, - utils.QuorumLightClientFlag, - utils.QuorumLightClientPSIFlag, - utils.QuorumLightClientTokenEnabledFlag, - utils.QuorumLightClientTokenValueFlag, - utils.QuorumLightClientTokenManagementFlag, - utils.QuorumLightClientRPCTLSFlag, - utils.QuorumLightClientRPCTLSInsecureSkipVerifyFlag, - utils.QuorumLightClientRPCTLSCACertFlag, - utils.QuorumLightClientRPCTLSCertFlag, - utils.QuorumLightClientRPCTLSKeyFlag, - utils.QuorumLightClientServerNodeFlag, - utils.QuorumLightClientServerNodeRPCFlag, - utils.QuorumLightTLSFlag, - utils.QuorumLightTLSCertFlag, - utils.QuorumLightTLSKeyFlag, - utils.QuorumLightTLSCACertsFlag, - utils.QuorumLightTLSClientAuthFlag, - utils.QuorumLightTLSCipherSuitesFlag, - }, - }, - { - Name: "QUORUM PRIVATE TRANSACTION MANAGER", - Flags: []cli.Flag{ - utils.QuorumPTMUnixSocketFlag, - utils.QuorumPTMUrlFlag, - utils.QuorumPTMTimeoutFlag, - utils.QuorumPTMDialTimeoutFlag, - utils.QuorumPTMHttpIdleTimeoutFlag, - utils.QuorumPTMHttpWriteBufferSizeFlag, - utils.QuorumPTMHttpReadBufferSizeFlag, - utils.QuorumPTMTlsModeFlag, - utils.QuorumPTMTlsRootCaFlag, - utils.QuorumPTMTlsClientCertFlag, - utils.QuorumPTMTlsClientKeyFlag, - utils.QuorumPTMTlsInsecureSkipVerify, - }, - }, - { - Name: quorumAccountFlagGroup, - Flags: []cli.Flag{ - utils.AccountPluginNewAccountConfigFlag, - }, - }, - { - Name: "RAFT", - Flags: []cli.Flag{ - utils.RaftModeFlag, - utils.RaftBlockTimeFlag, - utils.RaftJoinExistingFlag, - utils.RaftPortFlag, - utils.RaftDNSEnabledFlag, - }, - }, - { - Name: "ISTANBUL", - Flags: []cli.Flag{ - utils.IstanbulRequestTimeoutFlag, - utils.IstanbulBlockPeriodFlag, - }, - }, - // END QUORUM - { - Name: "MISC", - Flags: []cli.Flag{ - utils.SnapshotFlag, - utils.BloomFilterSizeFlag, - cli.HelpFlag, - utils.CatalystFlag, - }, - }, -} - -func init() { - // Override the default app help template - cli.AppHelpTemplate = flags.AppHelpTemplate - - // Override the default app help printer, but only for the global app help - originalHelpPrinter := cli.HelpPrinter - cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { - if tmpl == flags.AppHelpTemplate { - // Iterate over all the flags and add any uncategorized ones - categorized := make(map[string]struct{}) - for _, group := range AppHelpFlagGroups { - for _, flag := range group.Flags { - categorized[flag.String()] = struct{}{} - } - } - deprecated := make(map[string]struct{}) - for _, flag := range utils.DeprecatedFlags { - deprecated[flag.String()] = struct{}{} - } - // Only add uncategorized flags if they are not deprecated - var uncategorized []cli.Flag - for _, flag := range data.(*cli.App).Flags { - if _, ok := categorized[flag.String()]; !ok { - if _, ok := deprecated[flag.String()]; !ok { - uncategorized = append(uncategorized, flag) - } - } - } - if len(uncategorized) > 0 { - // Append all ungategorized options to the misc group - miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) - AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) - - // Make sure they are removed afterwards - defer func() { - AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] - }() - } - - // remove the Quorum account options from the main app usage as these should only be used by the geth account sub commands - for i, group := range AppHelpFlagGroups { - if group.Name == quorumAccountFlagGroup { - AppHelpFlagGroups = append(AppHelpFlagGroups[:i], AppHelpFlagGroups[i+1:]...) - } - } - - // Render out custom usage screen - originalHelpPrinter(w, tmpl, flags.HelpData{App: data, FlagGroups: AppHelpFlagGroups}) - } else if tmpl == flags.CommandHelpTemplate { - // Iterate over all command specific flags and categorize them - categorized := make(map[string][]cli.Flag) - for _, flag := range data.(cli.Command).Flags { - if _, ok := categorized[flag.String()]; !ok { - categorized[flags.FlagCategory(flag, AppHelpFlagGroups)] = append(categorized[flags.FlagCategory(flag, AppHelpFlagGroups)], flag) - } - } - - // sort to get a stable ordering - sorted := make([]flags.FlagGroup, 0, len(categorized)) - for cat, flgs := range categorized { - sorted = append(sorted, flags.FlagGroup{Name: cat, Flags: flgs}) - } - sort.Sort(flags.ByCategory(sorted)) - - // add sorted array to data and render with default printer - originalHelpPrinter(w, tmpl, map[string]interface{}{ - "cmd": data, - "categorizedFlags": sorted, - }) - } else { - originalHelpPrinter(w, tmpl, data) - } - } -} diff --git a/cmd/geth/version_check.go b/cmd/geth/version_check.go index 6eaedf373..237556788 100644 --- a/cmd/geth/version_check.go +++ b/cmd/geth/version_check.go @@ -28,7 +28,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/jedisct1/go-minisign" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var gethPubKeys []string = []string{ diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go index 477e41937..ae0cf6016 100644 --- a/cmd/p2psim/main.go +++ b/cmd/p2psim/main.go @@ -45,32 +45,38 @@ import ( "text/tabwriter" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/simulations" "github.com/ethereum/go-ethereum/p2p/simulations/adapters" "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var client *simulations.Client +var ( + // Git information set by linker when building with ci.go. + gitCommit string + gitDate string +) + func main() { - app := cli.NewApp() - app.Usage = "devp2p simulation command-line client" + app := flags.NewApp(gitCommit, gitDate, "devp2p simulation command-line client") app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "api", - Value: "http://localhost:8888", - Usage: "simulation API URL", - EnvVar: "P2PSIM_API_URL", + &cli.StringFlag{ + Name: "api", + Value: "http://localhost:8888", + Usage: "simulation API URL", + EnvVars: []string{"P2PSIM_API_URL"}, }, } app.Before = func(ctx *cli.Context) error { - client = simulations.NewClient(ctx.GlobalString("api")) + client = simulations.NewClient(ctx.String("api")) return nil } - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ { Name: "show", Usage: "show network information", @@ -81,11 +87,11 @@ func main() { Usage: "stream network events", Action: streamNetwork, Flags: []cli.Flag{ - cli.BoolFlag{ + &cli.BoolFlag{ Name: "current", Usage: "get existing nodes and conns first", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "filter", Value: "", Usage: "message filter", @@ -106,7 +112,7 @@ func main() { Name: "node", Usage: "manage simulation nodes", Action: listNodes, - Subcommands: []cli.Command{ + Subcommands: []*cli.Command{ { Name: "list", Usage: "list nodes", @@ -117,17 +123,17 @@ func main() { Usage: "create a node", Action: createNode, Flags: []cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "name", Value: "", Usage: "node name", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "services", Value: "", Usage: "node services (comma separated)", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "key", Value: "", Usage: "node private key (hex encoded)", @@ -170,7 +176,7 @@ func main() { Usage: "call a node RPC method", Action: rpcNode, Flags: []cli.Flag{ - cli.BoolFlag{ + &cli.BoolFlag{ Name: "subscribe", Usage: "method is a subscription", }, @@ -186,7 +192,7 @@ func main() { } func showNetwork(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } network, err := client.GetNetwork() @@ -201,7 +207,7 @@ func showNetwork(ctx *cli.Context) error { } func streamNetwork(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } events := make(chan *simulations.Event) @@ -227,7 +233,7 @@ func streamNetwork(ctx *cli.Context) error { } func createSnapshot(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } snap, err := client.CreateSnapshot() @@ -238,7 +244,7 @@ func createSnapshot(ctx *cli.Context) error { } func loadSnapshot(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } snap := &simulations.Snapshot{} @@ -249,7 +255,7 @@ func loadSnapshot(ctx *cli.Context) error { } func listNodes(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } nodes, err := client.GetNodes() @@ -274,7 +280,7 @@ func protocolList(node *p2p.NodeInfo) []string { } func createNode(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { + if ctx.NArg() != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } config := adapters.RandomNodeConfig() @@ -299,11 +305,10 @@ func createNode(ctx *cli.Context) error { } func showNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) != 1 { + if ctx.NArg() != 1 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] + nodeName := ctx.Args().First() node, err := client.GetNode(nodeName) if err != nil { return err @@ -324,11 +329,10 @@ func showNode(ctx *cli.Context) error { } func startNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) != 1 { + if ctx.NArg() != 1 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] + nodeName := ctx.Args().First() if err := client.StartNode(nodeName); err != nil { return err } @@ -337,11 +341,10 @@ func startNode(ctx *cli.Context) error { } func stopNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) != 1 { + if ctx.NArg() != 1 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] + nodeName := ctx.Args().First() if err := client.StopNode(nodeName); err != nil { return err } @@ -350,12 +353,12 @@ func stopNode(ctx *cli.Context) error { } func connectNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) != 2 { + if ctx.NArg() != 2 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] - peerName := args[1] + args := ctx.Args() + nodeName := args.Get(0) + peerName := args.Get(1) if err := client.ConnectNode(nodeName, peerName); err != nil { return err } @@ -364,12 +367,12 @@ func connectNode(ctx *cli.Context) error { } func disconnectNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) != 2 { + if ctx.NArg() != 2 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] - peerName := args[1] + args := ctx.Args() + nodeName := args.Get(0) + peerName := args.Get(1) if err := client.DisconnectNode(nodeName, peerName); err != nil { return err } @@ -378,22 +381,22 @@ func disconnectNode(ctx *cli.Context) error { } func rpcNode(ctx *cli.Context) error { - args := ctx.Args() - if len(args) < 2 { + if ctx.NArg() < 2 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - nodeName := args[0] - method := args[1] + args := ctx.Args() + nodeName := args.Get(0) + method := args.Get(1) rpcClient, err := client.RPCClient(context.Background(), nodeName) if err != nil { return err } if ctx.Bool("subscribe") { - return rpcSubscribe(rpcClient, ctx.App.Writer, method, args[3:]...) + return rpcSubscribe(rpcClient, ctx.App.Writer, method, args.Slice()[3:]...) } var result interface{} - params := make([]interface{}, len(args[3:])) - for i, v := range args[3:] { + params := make([]interface{}, len(args.Slice()[3:])) + for i, v := range args.Slice()[3:] { params[i] = v } if err := rpcClient.Call(&result, method, params...); err != nil { diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index d4051e59e..a8fb74a5b 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -39,7 +39,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) const ( @@ -76,10 +76,10 @@ func StartNode(ctx *cli.Context, stack *node.Node) { defer signal.Stop(sigc) minFreeDiskSpace := ethconfig.Defaults.TrieDirtyCache - if ctx.GlobalIsSet(MinFreeDiskSpaceFlag.Name) { - minFreeDiskSpace = ctx.GlobalInt(MinFreeDiskSpaceFlag.Name) - } else if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { - minFreeDiskSpace = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 + if ctx.IsSet(MinFreeDiskSpaceFlag.Name) { + minFreeDiskSpace = ctx.Int(MinFreeDiskSpaceFlag.Name) + } else if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) { + minFreeDiskSpace = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100 } if minFreeDiskSpace > 0 { go monitorFreeDiskSpace(sigc, stack.InstanceDir(), uint64(minFreeDiskSpace)*1024*1024) diff --git a/cmd/utils/customflags.go b/cmd/utils/customflags.go deleted file mode 100644 index 0a72e8034..000000000 --- a/cmd/utils/customflags.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package utils - -import ( - "encoding" - "errors" - "flag" - "math/big" - "os" - "os/user" - "path" - "strings" - - "github.com/ethereum/go-ethereum/common/math" - "gopkg.in/urfave/cli.v1" -) - -// Custom type which is registered in the flags library which cli uses for -// argument parsing. This allows us to expand Value to an absolute path when -// the argument is parsed -type DirectoryString string - -func (s *DirectoryString) String() string { - return string(*s) -} - -func (s *DirectoryString) Set(value string) error { - *s = DirectoryString(expandPath(value)) - return nil -} - -// Custom cli.Flag type which expand the received string to an absolute path. -// e.g. ~/.ethereum -> /home/username/.ethereum -type DirectoryFlag struct { - Name string - Value DirectoryString - Usage string - EnvVar string -} - -func (f DirectoryFlag) String() string { - return cli.FlagStringer(f) -} - -// called by cli library, grabs variable from environment (if in env) -// and adds variable to flag set for parsing. -func (f DirectoryFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var(&f.Value, f.Name, f.Usage) - }) -} - -func (f DirectoryFlag) GetName() string { - return f.Name -} - -func (f *DirectoryFlag) Set(value string) { - f.Value.Set(value) -} - -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - -type TextMarshaler interface { - encoding.TextMarshaler - encoding.TextUnmarshaler -} - -// textMarshalerVal turns a TextMarshaler into a flag.Value -type textMarshalerVal struct { - v TextMarshaler -} - -func (v textMarshalerVal) String() string { - if v.v == nil { - return "" - } - text, _ := v.v.MarshalText() - return string(text) -} - -func (v textMarshalerVal) Set(s string) error { - return v.v.UnmarshalText([]byte(s)) -} - -// TextMarshalerFlag wraps a TextMarshaler value. -type TextMarshalerFlag struct { - Name string - Value TextMarshaler - Usage string - EnvVar string -} - -func (f TextMarshalerFlag) GetName() string { - return f.Name -} - -func (f TextMarshalerFlag) String() string { - return cli.FlagStringer(f) -} - -func (f TextMarshalerFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage) - }) -} - -// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set. -func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler { - val := ctx.GlobalGeneric(name) - if val == nil { - return nil - } - return val.(textMarshalerVal).v -} - -// BigFlag is a command line flag that accepts 256 bit big integers in decimal or -// hexadecimal syntax. -type BigFlag struct { - Name string - Value *big.Int - Usage string - EnvVar string -} - -// bigValue turns *big.Int into a flag.Value -type bigValue big.Int - -func (b *bigValue) String() string { - if b == nil { - return "" - } - return (*big.Int)(b).String() -} - -func (b *bigValue) Set(s string) error { - int, ok := math.ParseBig256(s) - if !ok { - return errors.New("invalid integer syntax") - } - *b = (bigValue)(*int) - return nil -} - -func (f BigFlag) GetName() string { - return f.Name -} - -func (f BigFlag) String() string { - return cli.FlagStringer(f) -} - -func (f BigFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var((*bigValue)(f.Value), f.Name, f.Usage) - }) -} - -// GlobalBig returns the value of a BigFlag from the global flag set. -func GlobalBig(ctx *cli.Context, name string) *big.Int { - val := ctx.GlobalGeneric(name) - if val == nil { - return nil - } - return (*big.Int)(val.(*bigValue)) -} - -// Expands a file path -// 1. replace tilde with users home dir -// 2. expands embedded environment variables -// 3. cleans the path, e.g. /a/b/../c -> /a/c -// Note, it has limitations, e.g. ~someuser/tmp will not be expanded -func expandPath(p string) string { - if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { - if home := HomeDir(); home != "" { - p = home + p[1:] - } - } - return path.Clean(os.ExpandEnv(p)) -} - -func HomeDir() string { - if home := os.Getenv("HOME"); home != "" { - return home - } - if usr, err := user.Current(); err == nil { - return usr.HomeDir - } - return "" -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e033874ad..50269070f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -30,8 +30,6 @@ import ( godebug "runtime/debug" "strconv" "strings" - "text/tabwriter" - "text/template" "time" "github.com/ethereum/go-ethereum/accounts" @@ -79,37 +77,9 @@ import ( "github.com/ethereum/go-ethereum/raft" pcsclite "github.com/gballet/go-libpcsclite" gopsutil "github.com/shirou/gopsutil/mem" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -func init() { - cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] - -VERSION: - {{.Version}} - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{if .Flags}} -GLOBAL OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` - cli.CommandHelpTemplate = flags.CommandHelpTemplate - cli.HelpPrinter = printHelp -} - -func printHelp(out io.Writer, templ string, data interface{}) { - funcMap := template.FuncMap{"join": strings.Join} - t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) - w := tabwriter.NewWriter(out, 38, 8, 2, ' ', 0) - err := t.Execute(w, data) - if err != nil { - panic(err) - } - w.Flush() -} - // These are all the command line flags we support. // If you add to this list, please remember to include the // flag in the appropriate command definition. @@ -119,904 +89,1081 @@ func printHelp(out io.Writer, templ string, data interface{}) { var ( // General settings - DataDirFlag = DirectoryFlag{ - Name: "datadir", - Usage: "Data directory for the databases and keystore", - Value: DirectoryString(node.DefaultDataDir()), + DataDirFlag = &flags.DirectoryFlag{ + Name: "datadir", + Usage: "Data directory for the databases and keystore", + Value: flags.DirectoryString(node.DefaultDataDir()), + Category: flags.EthCategory, } - RaftLogDirFlag = DirectoryFlag{ + RaftLogDirFlag = &flags.DirectoryFlag{ Name: "raftlogdir", Usage: "Raft log directory for the raft-state, raft-snap and raft-wal folders", - Value: DirectoryString(node.DefaultDataDir()), - } - AncientFlag = DirectoryFlag{ - Name: "datadir.ancient", - Usage: "Data directory for ancient chain segments (default = inside chaindata)", - } - MinFreeDiskSpaceFlag = DirectoryFlag{ - Name: "datadir.minfreedisk", - Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", - } - KeyStoreDirFlag = DirectoryFlag{ - Name: "keystore", - Usage: "Directory for the keystore (default = inside the datadir)", - } - NoUSBFlag = cli.BoolFlag{ - Name: "nousb", - Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)", - } - USBFlag = cli.BoolFlag{ - Name: "usb", - Usage: "Enable monitoring and management of USB hardware wallets", - } - SmartCardDaemonPathFlag = cli.StringFlag{ - Name: "pcscdpath", - Usage: "Path to the smartcard daemon (pcscd) socket file", - Value: pcsclite.PCSCDSockName, - } - NetworkIdFlag = cli.Uint64Flag{ - Name: "networkid", - Usage: "Explicitly set network id (integer)(For testnets: use --ropsten, --rinkeby, --goerli instead)", - Value: ethconfig.Defaults.NetworkId, - } - MainnetFlag = cli.BoolFlag{ - Name: "mainnet", - Usage: "Ethereum mainnet", - } - GoerliFlag = cli.BoolFlag{ - Name: "goerli", - Usage: "Görli network: pre-configured proof-of-authority test network", - } - YoloV3Flag = cli.BoolFlag{ + Value: flags.DirectoryString(node.DefaultDataDir()), + } + AncientFlag = &flags.DirectoryFlag{ + Name: "datadir.ancient", + Usage: "Data directory for ancient chain segments (default = inside chaindata)", + Category: flags.EthCategory, + } + MinFreeDiskSpaceFlag = &flags.DirectoryFlag{ + Name: "datadir.minfreedisk", + Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", + Category: flags.EthCategory, + } + KeyStoreDirFlag = &flags.DirectoryFlag{ + Name: "keystore", + Usage: "Directory for the keystore (default = inside the datadir)", + Category: flags.AccountCategory, + } + NoUSBFlag = &cli.BoolFlag{ + Name: "nousb", + Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)", + Category: flags.AccountCategory, + } + USBFlag = &cli.BoolFlag{ + Name: "usb", + Usage: "Enable monitoring and management of USB hardware wallets", + Category: flags.AccountCategory, + } + SmartCardDaemonPathFlag = &cli.StringFlag{ + Name: "pcscdpath", + Usage: "Path to the smartcard daemon (pcscd) socket file", + Value: pcsclite.PCSCDSockName, + Category: flags.AccountCategory, + } + NetworkIdFlag = &cli.Uint64Flag{ + Name: "networkid", + Usage: "Explicitly set network id (integer)(For testnets: use --ropsten, --rinkeby, --goerli instead)", + Value: ethconfig.Defaults.NetworkId, + Category: flags.EthCategory, + } + MainnetFlag = &cli.BoolFlag{ + Name: "mainnet", + Usage: "Ethereum mainnet", + Category: flags.EthCategory, + } + GoerliFlag = &cli.BoolFlag{ + Name: "goerli", + Usage: "Görli network: pre-configured proof-of-authority test network", + Category: flags.EthCategory, + } + YoloV3Flag = &cli.BoolFlag{ Name: "yolov3", Usage: "YOLOv3 network: pre-configured proof-of-authority shortlived test network.", } - RinkebyFlag = cli.BoolFlag{ - Name: "rinkeby", - Usage: "Rinkeby network: pre-configured proof-of-authority test network", - } - RopstenFlag = cli.BoolFlag{ - Name: "ropsten", - Usage: "Ropsten network: pre-configured proof-of-work test network", - } - DeveloperFlag = cli.BoolFlag{ - Name: "dev", - Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled", - } - DeveloperPeriodFlag = cli.IntFlag{ - Name: "dev.period", - Usage: "Block period to use in developer mode (0 = mine only if transaction pending)", - } - IdentityFlag = cli.StringFlag{ - Name: "identity", - Usage: "Custom node name", - } - DocRootFlag = DirectoryFlag{ - Name: "docroot", - Usage: "Document Root for HTTPClient file scheme", - Value: DirectoryString(HomeDir()), - } - ExitWhenSyncedFlag = cli.BoolFlag{ - Name: "exitwhensynced", - Usage: "Exits after block synchronisation completes", - } - IterativeOutputFlag = cli.BoolFlag{ + RinkebyFlag = &cli.BoolFlag{ + Name: "rinkeby", + Usage: "Rinkeby network: pre-configured proof-of-authority test network", + Category: flags.EthCategory, + } + RopstenFlag = &cli.BoolFlag{ + Name: "ropsten", + Usage: "Ropsten network: pre-configured proof-of-work test network", + Category: flags.EthCategory, + } + DeveloperFlag = &cli.BoolFlag{ + Name: "dev", + Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled", + Category: flags.DevCategory, + } + DeveloperPeriodFlag = &cli.IntFlag{ + Name: "dev.period", + Usage: "Block period to use in developer mode (0 = mine only if transaction pending)", + Category: flags.DevCategory, + } + IdentityFlag = &cli.StringFlag{ + Name: "identity", + Usage: "Custom node name", + Category: flags.NetworkingCategory, + } + DocRootFlag = &flags.DirectoryFlag{ + Name: "docroot", + Usage: "Document Root for HTTPClient file scheme", + Value: flags.DirectoryString(flags.HomeDir()), + Category: flags.APICategory, + } + ExitWhenSyncedFlag = &cli.BoolFlag{ + Name: "exitwhensynced", + Usage: "Exits after block synchronisation completes", + Category: flags.EthCategory, + } + IterativeOutputFlag = &cli.BoolFlag{ Name: "iterative", Usage: "Print streaming JSON iteratively, delimited by newlines", + Value: true, } - ExcludeStorageFlag = cli.BoolFlag{ + ExcludeStorageFlag = &cli.BoolFlag{ Name: "nostorage", Usage: "Exclude storage entries (save db lookups)", } - IncludeIncompletesFlag = cli.BoolFlag{ + IncludeIncompletesFlag = &cli.BoolFlag{ Name: "incompletes", Usage: "Include accounts for which we don't have the address (missing preimage)", } - ExcludeCodeFlag = cli.BoolFlag{ + ExcludeCodeFlag = &cli.BoolFlag{ Name: "nocode", Usage: "Exclude contract code (save db lookups)", } defaultSyncMode = ethconfig.Defaults.SyncMode - SyncModeFlag = TextMarshalerFlag{ - Name: "syncmode", - Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`, - Value: &defaultSyncMode, - } - GCModeFlag = cli.StringFlag{ - Name: "gcmode", - Usage: `Blockchain garbage collection mode ("full", "archive")`, - Value: "full", - } - SnapshotFlag = cli.BoolTFlag{ - Name: "snapshot", - Usage: `Enables snapshot-database mode (default = enable)`, - } - TxLookupLimitFlag = cli.Uint64Flag{ - Name: "txlookuplimit", - Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", - Value: ethconfig.Defaults.TxLookupLimit, - } - LightKDFFlag = cli.BoolFlag{ - Name: "lightkdf", - Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", - } - DeprecatedAuthorizationListFlag = cli.StringFlag{ + SyncModeFlag = &flags.TextMarshalerFlag{ + Name: "syncmode", + Usage: `Blockchain sync mode ("snap", "full" or "light")`, + Value: &defaultSyncMode, + Category: flags.EthCategory, + } + GCModeFlag = &cli.StringFlag{ + Name: "gcmode", + Usage: `Blockchain garbage collection mode ("full", "archive")`, + Value: "full", + Category: flags.EthCategory, + } + SnapshotFlag = &cli.BoolFlag{ + Name: "snapshot", + Usage: `Enables snapshot-database mode (default = enable)`, + Category: flags.EthCategory, + } + TxLookupLimitFlag = &cli.Uint64Flag{ + Name: "txlookuplimit", + Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", + Value: ethconfig.Defaults.TxLookupLimit, + Category: flags.EthCategory, + } + LightKDFFlag = &cli.BoolFlag{ + Name: "lightkdf", + Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", + Category: flags.AccountCategory, + } + DeprecatedAuthorizationListFlag = &cli.StringFlag{ Name: "whitelist", Usage: "[DEPRECATED: will be replaced by 'authorizationlist'] Comma separated block number-to-hash mappings to authorize (=)", } - AuthorizationListFlag = cli.StringFlag{ + AuthorizationListFlag = &cli.StringFlag{ Name: "authorizationlist", Usage: "Comma separated block number-to-hash mappings to authorize (=)", } - BloomFilterSizeFlag = cli.Uint64Flag{ - Name: "bloomfilter.size", - Usage: "Megabytes of memory allocated to bloom-filter for pruning", - Value: 2048, + BloomFilterSizeFlag = &cli.Uint64Flag{ + Name: "bloomfilter.size", + Usage: "Megabytes of memory allocated to bloom-filter for pruning", + Value: 2048, + Category: flags.EthCategory, } - OverrideBerlinFlag = cli.Uint64Flag{ + OverrideBerlinFlag = &cli.Uint64Flag{ Name: "override.berlin", Usage: "Manually specify Berlin fork-block, overriding the bundled setting", } // Light server and client settings - LightServeFlag = cli.IntFlag{ - Name: "light.serve", - Usage: "Maximum percentage of time allowed for serving LES requests (multi-threaded processing allows values over 100)", - Value: ethconfig.Defaults.LightServ, - } - LightIngressFlag = cli.IntFlag{ - Name: "light.ingress", - Usage: "Incoming bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)", - Value: ethconfig.Defaults.LightIngress, - } - LightEgressFlag = cli.IntFlag{ - Name: "light.egress", - Usage: "Outgoing bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)", - Value: ethconfig.Defaults.LightEgress, - } - LightMaxPeersFlag = cli.IntFlag{ - Name: "light.maxpeers", - Usage: "Maximum number of light clients to serve, or light servers to attach to", - Value: ethconfig.Defaults.LightPeers, - } - UltraLightServersFlag = cli.StringFlag{ - Name: "ulc.servers", - Usage: "List of trusted ultra-light servers", - Value: strings.Join(ethconfig.Defaults.UltraLightServers, ","), - } - UltraLightFractionFlag = cli.IntFlag{ - Name: "ulc.fraction", - Usage: "Minimum % of trusted ultra-light servers required to announce a new head", - Value: ethconfig.Defaults.UltraLightFraction, - } - UltraLightOnlyAnnounceFlag = cli.BoolFlag{ - Name: "ulc.onlyannounce", - Usage: "Ultra light server sends announcements only", - } - LightNoPruneFlag = cli.BoolFlag{ - Name: "light.nopruning", - Usage: "Disable ancient light chain data pruning", - } - LightNoSyncServeFlag = cli.BoolFlag{ - Name: "light.nosyncserve", - Usage: "Enables serving light clients before syncing", + LightServeFlag = &cli.IntFlag{ + Name: "light.serve", + Usage: "Maximum percentage of time allowed for serving LES requests (multi-threaded processing allows values over 100)", + Value: ethconfig.Defaults.LightServ, + Category: flags.LightCategory, + } + LightIngressFlag = &cli.IntFlag{ + Name: "light.ingress", + Usage: "Incoming bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)", + Value: ethconfig.Defaults.LightIngress, + Category: flags.LightCategory, + } + LightEgressFlag = &cli.IntFlag{ + Name: "light.egress", + Usage: "Outgoing bandwidth limit for serving light clients (kilobytes/sec, 0 = unlimited)", + Value: ethconfig.Defaults.LightEgress, + Category: flags.LightCategory, + } + LightMaxPeersFlag = &cli.IntFlag{ + Name: "light.maxpeers", + Usage: "Maximum number of light clients to serve, or light servers to attach to", + Value: ethconfig.Defaults.LightPeers, + Category: flags.LightCategory, + } + UltraLightServersFlag = &cli.StringFlag{ + Name: "ulc.servers", + Usage: "List of trusted ultra-light servers", + Value: strings.Join(ethconfig.Defaults.UltraLightServers, ","), + Category: flags.LightCategory, + } + UltraLightFractionFlag = &cli.IntFlag{ + Name: "ulc.fraction", + Usage: "Minimum % of trusted ultra-light servers required to announce a new head", + Value: ethconfig.Defaults.UltraLightFraction, + Category: flags.LightCategory, + } + UltraLightOnlyAnnounceFlag = &cli.BoolFlag{ + Name: "ulc.onlyannounce", + Usage: "Ultra light server sends announcements only", + Category: flags.LightCategory, + } + LightNoPruneFlag = &cli.BoolFlag{ + Name: "light.nopruning", + Usage: "Disable ancient light chain data pruning", + Category: flags.LightCategory, + } + LightNoSyncServeFlag = &cli.BoolFlag{ + Name: "light.nosyncserve", + Usage: "Enables serving light clients before syncing", + Category: flags.LightCategory, } // Transaction pool settings - TxPoolLocalsFlag = cli.StringFlag{ - Name: "txpool.locals", - Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + TxPoolLocalsFlag = &cli.StringFlag{ + Name: "txpool.locals", + Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + Category: flags.TxPoolCategory, } - TxPoolNoLocalsFlag = cli.BoolFlag{ - Name: "txpool.nolocals", - Usage: "Disables price exemptions for locally submitted transactions", + TxPoolNoLocalsFlag = &cli.BoolFlag{ + Name: "txpool.nolocals", + Usage: "Disables price exemptions for locally submitted transactions", + Category: flags.TxPoolCategory, } - TxPoolJournalFlag = cli.StringFlag{ + TxPoolJournalFlag = &cli.StringFlag{ Name: "txpool.journal", Usage: "Disk journal for local transaction to survive node restarts", Value: core.DefaultTxPoolConfig.Journal, } - TxPoolRejournalFlag = cli.DurationFlag{ - Name: "txpool.rejournal", - Usage: "Time interval to regenerate the local transaction journal", - Value: core.DefaultTxPoolConfig.Rejournal, - } - TxPoolPriceLimitFlag = cli.Uint64Flag{ - Name: "txpool.pricelimit", - Usage: "Minimum gas price limit to enforce for acceptance into the pool", - Value: ethconfig.Defaults.TxPool.PriceLimit, - } - TxPoolPriceBumpFlag = cli.Uint64Flag{ - Name: "txpool.pricebump", - Usage: "Price bump percentage to replace an already existing transaction", - Value: ethconfig.Defaults.TxPool.PriceBump, - } - TxPoolAccountSlotsFlag = cli.Uint64Flag{ - Name: "txpool.accountslots", - Usage: "Minimum number of executable transaction slots guaranteed per account", - Value: ethconfig.Defaults.TxPool.AccountSlots, - } - TxPoolGlobalSlotsFlag = cli.Uint64Flag{ - Name: "txpool.globalslots", - Usage: "Maximum number of executable transaction slots for all accounts", - Value: ethconfig.Defaults.TxPool.GlobalSlots, - } - TxPoolAccountQueueFlag = cli.Uint64Flag{ - Name: "txpool.accountqueue", - Usage: "Maximum number of non-executable transaction slots permitted per account", - Value: ethconfig.Defaults.TxPool.AccountQueue, - } - TxPoolGlobalQueueFlag = cli.Uint64Flag{ - Name: "txpool.globalqueue", - Usage: "Maximum number of non-executable transaction slots for all accounts", - Value: ethconfig.Defaults.TxPool.GlobalQueue, - } - TxPoolLifetimeFlag = cli.DurationFlag{ - Name: "txpool.lifetime", - Usage: "Maximum amount of time non-executable transaction are queued", - Value: ethconfig.Defaults.TxPool.Lifetime, + TxPoolRejournalFlag = &cli.DurationFlag{ + Name: "txpool.rejournal", + Usage: "Time interval to regenerate the local transaction journal", + Value: core.DefaultTxPoolConfig.Rejournal, + Category: flags.TxPoolCategory, + } + TxPoolPriceLimitFlag = &cli.Uint64Flag{ + Name: "txpool.pricelimit", + Usage: "Minimum gas price limit to enforce for acceptance into the pool", + Value: ethconfig.Defaults.TxPool.PriceLimit, + Category: flags.TxPoolCategory, + } + TxPoolPriceBumpFlag = &cli.Uint64Flag{ + Name: "txpool.pricebump", + Usage: "Price bump percentage to replace an already existing transaction", + Value: ethconfig.Defaults.TxPool.PriceBump, + Category: flags.TxPoolCategory, + } + TxPoolAccountSlotsFlag = &cli.Uint64Flag{ + Name: "txpool.accountslots", + Usage: "Minimum number of executable transaction slots guaranteed per account", + Value: ethconfig.Defaults.TxPool.AccountSlots, + Category: flags.TxPoolCategory, + } + TxPoolGlobalSlotsFlag = &cli.Uint64Flag{ + Name: "txpool.globalslots", + Usage: "Maximum number of executable transaction slots for all accounts", + Value: ethconfig.Defaults.TxPool.GlobalSlots, + Category: flags.TxPoolCategory, + } + TxPoolAccountQueueFlag = &cli.Uint64Flag{ + Name: "txpool.accountqueue", + Usage: "Maximum number of non-executable transaction slots permitted per account", + Value: ethconfig.Defaults.TxPool.AccountQueue, + Category: flags.TxPoolCategory, + } + TxPoolGlobalQueueFlag = &cli.Uint64Flag{ + Name: "txpool.globalqueue", + Usage: "Maximum number of non-executable transaction slots for all accounts", + Value: ethconfig.Defaults.TxPool.GlobalQueue, + Category: flags.TxPoolCategory, + } + TxPoolLifetimeFlag = &cli.DurationFlag{ + Name: "txpool.lifetime", + Usage: "Maximum amount of time non-executable transaction are queued", + Value: ethconfig.Defaults.TxPool.Lifetime, + Category: flags.TxPoolCategory, } // Performance tuning settings - CacheFlag = cli.IntFlag{ - Name: "cache", - Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node, 128 light mode)", - Value: 1024, - } - CacheDatabaseFlag = cli.IntFlag{ - Name: "cache.database", - Usage: "Percentage of cache memory allowance to use for database io", - Value: 50, - } - CacheTrieFlag = cli.IntFlag{ - Name: "cache.trie", - Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)", - Value: 15, - } - CacheTrieJournalFlag = cli.StringFlag{ - Name: "cache.trie.journal", - Usage: "Disk journal directory for trie cache to survive node restarts", - Value: ethconfig.Defaults.TrieCleanCacheJournal, - } - CacheTrieRejournalFlag = cli.DurationFlag{ - Name: "cache.trie.rejournal", - Usage: "Time interval to regenerate the trie cache journal", - Value: ethconfig.Defaults.TrieCleanCacheRejournal, - } - CacheGCFlag = cli.IntFlag{ - Name: "cache.gc", - Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", - Value: 25, - } - CacheSnapshotFlag = cli.IntFlag{ - Name: "cache.snapshot", - Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)", - Value: 10, - } - CacheNoPrefetchFlag = cli.BoolFlag{ - Name: "cache.noprefetch", - Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", - } - CachePreimagesFlag = cli.BoolFlag{ - Name: "cache.preimages", - Usage: "Enable recording the SHA3/keccak preimages of trie keys", + CacheFlag = &cli.IntFlag{ + Name: "cache", + Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node, 128 light mode)", + Value: 1024, + Category: flags.PerfCategory, + } + CacheDatabaseFlag = &cli.IntFlag{ + Name: "cache.database", + Usage: "Percentage of cache memory allowance to use for database io", + Value: 50, + Category: flags.PerfCategory, + } + CacheTrieFlag = &cli.IntFlag{ + Name: "cache.trie", + Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)", + Value: 15, + Category: flags.PerfCategory, + } + CacheTrieJournalFlag = &cli.StringFlag{ + Name: "cache.trie.journal", + Usage: "Disk journal directory for trie cache to survive node restarts", + Value: ethconfig.Defaults.TrieCleanCacheJournal, + Category: flags.PerfCategory, + } + CacheTrieRejournalFlag = &cli.DurationFlag{ + Name: "cache.trie.rejournal", + Usage: "Time interval to regenerate the trie cache journal", + Value: ethconfig.Defaults.TrieCleanCacheRejournal, + Category: flags.PerfCategory, + } + CacheGCFlag = &cli.IntFlag{ + Name: "cache.gc", + Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", + Value: 25, + Category: flags.PerfCategory, + } + CacheSnapshotFlag = &cli.IntFlag{ + Name: "cache.snapshot", + Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)", + Value: 10, + Category: flags.PerfCategory, + } + CacheNoPrefetchFlag = &cli.BoolFlag{ + Name: "cache.noprefetch", + Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", + Category: flags.PerfCategory, + } + CachePreimagesFlag = &cli.BoolFlag{ + Name: "cache.preimages", + Usage: "Enable recording the SHA3/keccak preimages of trie keys", + Category: flags.PerfCategory, } // Miner settings - MiningEnabledFlag = cli.BoolFlag{ - Name: "mine", - Usage: "Enable mining", - } - MinerGasTargetFlag = cli.Uint64Flag{ - Name: "miner.gastarget", - Usage: "Target gas floor for mined blocks", - Value: ethconfig.Defaults.Miner.GasFloor, - } - MinerGasLimitFlag = cli.Uint64Flag{ - Name: "miner.gaslimit", - Usage: "Target gas ceiling for mined blocks", - Value: ethconfig.Defaults.Miner.GasCeil, - } - MinerGasPriceFlag = BigFlag{ - Name: "miner.gasprice", - Usage: "Minimum gas price for mining a transaction", - Value: ethconfig.Defaults.Miner.GasPrice, - } - MinerEtherbaseFlag = cli.StringFlag{ - Name: "miner.etherbase", - Usage: "Public address for block mining rewards (default = first account)", - Value: "0", - } - MinerExtraDataFlag = cli.StringFlag{ - Name: "miner.extradata", - Usage: "Block extra data set by the miner (default = client version)", - } - MinerRecommitIntervalFlag = cli.DurationFlag{ - Name: "miner.recommit", - Usage: "Time interval to recreate the block being mined", - Value: ethconfig.Defaults.Miner.Recommit, + MiningEnabledFlag = &cli.BoolFlag{ + Name: "mine", + Usage: "Enable mining", + Category: flags.MinerCategory, + } + MinerGasTargetFlag = &cli.Uint64Flag{ + Name: "miner.gastarget", + Usage: "Target gas floor for mined blocks", + Value: ethconfig.Defaults.Miner.GasFloor, + Category: flags.MinerCategory, + } + MinerGasLimitFlag = &cli.Uint64Flag{ + Name: "miner.gaslimit", + Usage: "Target gas ceiling for mined blocks", + Value: ethconfig.Defaults.Miner.GasCeil, + Category: flags.MinerCategory, + } + MinerGasPriceFlag = &flags.BigFlag{ + Name: "miner.gasprice", + Usage: "Minimum gas price for mining a transaction", + Value: ethconfig.Defaults.Miner.GasPrice, + Category: flags.MinerCategory, + } + MinerEtherbaseFlag = &cli.StringFlag{ + Name: "miner.etherbase", + Usage: "Public address for block mining rewards (default = first account)", + Value: "0", + Category: flags.MinerCategory, + } + MinerExtraDataFlag = &cli.StringFlag{ + Name: "miner.extradata", + Usage: "Block extra data set by the miner (default = client version)", + Category: flags.MinerCategory, + } + MinerRecommitIntervalFlag = &cli.DurationFlag{ + Name: "miner.recommit", + Usage: "Time interval to recreate the block being mined", + Value: ethconfig.Defaults.Miner.Recommit, + Category: flags.MinerCategory, } MinerNewPayloadTimeout = &cli.DurationFlag{ - Name: "miner.newpayload-timeout", - Usage: "Specify the maximum time allowance for creating a new payload", - Value: ethconfig.Defaults.Miner.NewPayloadTimeout, + Name: "miner.newpayload-timeout", + Usage: "Specify the maximum time allowance for creating a new payload", + Value: ethconfig.Defaults.Miner.NewPayloadTimeout, + Category: flags.MinerCategory, } // Account settings - UnlockedAccountFlag = cli.StringFlag{ - Name: "unlock", - Usage: "Comma separated list of accounts to unlock", - Value: "", - } - PasswordFileFlag = cli.StringFlag{ - Name: "password", - Usage: "Password file to use for non-interactive password input", - Value: "", - } - ExternalSignerFlag = cli.StringFlag{ - Name: "signer", - Usage: "External signer (url or path to ipc file)", - Value: "", - } - VMEnableDebugFlag = cli.BoolFlag{ - Name: "vmdebug", - Usage: "Record information useful for VM and contract debugging", - } - InsecureUnlockAllowedFlag = cli.BoolFlag{ - Name: "allow-insecure-unlock", - Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", - } - RPCGlobalGasCapFlag = cli.Uint64Flag{ - Name: "rpc.gascap", - Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", - Value: ethconfig.Defaults.RPCGasCap, - } - RPCGlobalTxFeeCapFlag = cli.Float64Flag{ - Name: "rpc.txfeecap", - Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", - Value: ethconfig.Defaults.RPCTxFeeCap, + UnlockedAccountFlag = &cli.StringFlag{ + Name: "unlock", + Usage: "Comma separated list of accounts to unlock", + Value: "", + Category: flags.AccountCategory, + } + PasswordFileFlag = &cli.StringFlag{ + Name: "password", + Usage: "Password file to use for non-interactive password input", + Value: "", + Category: flags.AccountCategory, + } + ExternalSignerFlag = &cli.StringFlag{ + Name: "signer", + Usage: "External signer (url or path to ipc file)", + Value: "", + Category: flags.AccountCategory, + } + VMEnableDebugFlag = &cli.BoolFlag{ + Name: "vmdebug", + Usage: "Record information useful for VM and contract debugging", + Category: flags.AccountCategory, + } + InsecureUnlockAllowedFlag = &cli.BoolFlag{ + Name: "allow-insecure-unlock", + Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", + Category: flags.AccountCategory, + } + RPCGlobalGasCapFlag = &cli.Uint64Flag{ + Name: "rpc.gascap", + Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", + Value: ethconfig.Defaults.RPCGasCap, + Category: flags.AccountCategory, + } + RPCGlobalTxFeeCapFlag = &cli.Float64Flag{ + Name: "rpc.txfeecap", + Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", + Value: ethconfig.Defaults.RPCTxFeeCap, + Category: flags.AccountCategory, } // Logging and debug settings - EthStatsURLFlag = cli.StringFlag{ - Name: "ethstats", - Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", + EthStatsURLFlag = &cli.StringFlag{ + Name: "ethstats", + Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", + Category: flags.MetricsCategory, } - FakePoWFlag = cli.BoolFlag{ - Name: "fakepow", - Usage: "Disables proof-of-work verification", + FakePoWFlag = &cli.BoolFlag{ + Name: "fakepow", + Usage: "Disables proof-of-work verification", + Category: flags.LoggingCategory, } - NoCompactionFlag = cli.BoolFlag{ - Name: "nocompaction", - Usage: "Disables db compaction after import", + NoCompactionFlag = &cli.BoolFlag{ + Name: "nocompaction", + Usage: "Disables db compaction after import", + Category: flags.LoggingCategory, } // Quorum // RPC Client Settings - RPCClientToken = cli.StringFlag{ - Name: "rpcclitoken", - Usage: "RPC Client access token", - } - RPCClientTLSCert = cli.StringFlag{ - Name: "rpcclitls.cert", - Usage: "Server's TLS certificate PEM file on connection by client", - } - RPCClientTLSCaCert = cli.StringFlag{ - Name: "rpcclitls.cacert", - Usage: "CA certificate PEM file for provided server's TLS certificate on connection by client", - } - RPCClientTLSCipherSuites = cli.StringFlag{ - Name: "rpcclitls.ciphersuites", - Usage: "Customize supported cipher suites when using TLS connection. Value is a comma-separated cipher suite string", - } - RPCClientTLSInsecureSkipVerify = cli.BoolFlag{ - Name: "rpcclitls.insecureskipverify", - Usage: "Disable verification of server's TLS certificate on connection by client", + RPCClientToken = &cli.StringFlag{ + Name: "rpcclitoken", + Usage: "RPC Client access token", + Category: flags.GoQuorumOptionCategory, + } + RPCClientTLSCert = &cli.StringFlag{ + Name: "rpcclitls.cert", + Usage: "Server's TLS certificate PEM file on connection by client", + Category: flags.GoQuorumOptionCategory, + } + RPCClientTLSCaCert = &cli.StringFlag{ + Name: "rpcclitls.cacert", + Usage: "CA certificate PEM file for provided server's TLS certificate on connection by client", + Category: flags.GoQuorumOptionCategory, + } + RPCClientTLSCipherSuites = &cli.StringFlag{ + Name: "rpcclitls.ciphersuites", + Usage: "Customize supported cipher suites when using TLS connection. Value is a comma-separated cipher suite string", + Category: flags.GoQuorumOptionCategory, + } + RPCClientTLSInsecureSkipVerify = &cli.BoolFlag{ + Name: "rpcclitls.insecureskipverify", + Usage: "Disable verification of server's TLS certificate on connection by client", + Category: flags.GoQuorumOptionCategory, } // End Quorum // RPC settings - IPCDisabledFlag = cli.BoolFlag{ - Name: "ipcdisable", - Usage: "Disable the IPC-RPC server", - } - IPCPathFlag = DirectoryFlag{ - Name: "ipcpath", - Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", - } - HTTPEnabledFlag = cli.BoolFlag{ - Name: "http", - Usage: "Enable the HTTP-RPC server", - } - HTTPListenAddrFlag = cli.StringFlag{ - Name: "http.addr", - Usage: "HTTP-RPC server listening interface", - Value: node.DefaultHTTPHost, - } - HTTPPortFlag = cli.IntFlag{ - Name: "http.port", - Usage: "HTTP-RPC server listening port", - Value: node.DefaultHTTPPort, - } - HTTPCORSDomainFlag = cli.StringFlag{ - Name: "http.corsdomain", - Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", - Value: "", - } - HTTPVirtualHostsFlag = cli.StringFlag{ - Name: "http.vhosts", - Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", - Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","), - } - HTTPApiFlag = cli.StringFlag{ - Name: "http.api", - Usage: "API's offered over the HTTP-RPC interface", - Value: "", - } - HTTPPathPrefixFlag = cli.StringFlag{ - Name: "http.rpcprefix", - Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", - Value: "", - } - GraphQLEnabledFlag = cli.BoolFlag{ - Name: "graphql", - Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.", - } - GraphQLCORSDomainFlag = cli.StringFlag{ - Name: "graphql.corsdomain", - Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", - Value: "", - } - GraphQLVirtualHostsFlag = cli.StringFlag{ - Name: "graphql.vhosts", - Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", - Value: strings.Join(node.DefaultConfig.GraphQLVirtualHosts, ","), - } - WSEnabledFlag = cli.BoolFlag{ - Name: "ws", - Usage: "Enable the WS-RPC server", - } - WSListenAddrFlag = cli.StringFlag{ - Name: "ws.addr", - Usage: "WS-RPC server listening interface", - Value: node.DefaultWSHost, - } - WSPortFlag = cli.IntFlag{ - Name: "ws.port", - Usage: "WS-RPC server listening port", - Value: node.DefaultWSPort, - } - WSApiFlag = cli.StringFlag{ - Name: "ws.api", - Usage: "API's offered over the WS-RPC interface", - Value: "", - } - WSAllowedOriginsFlag = cli.StringFlag{ - Name: "ws.origins", - Usage: "Origins from which to accept websockets requests", - Value: "", - } - WSPathPrefixFlag = cli.StringFlag{ - Name: "ws.rpcprefix", - Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", - Value: "", - } - ExecFlag = cli.StringFlag{ - Name: "exec", - Usage: "Execute JavaScript statement", - } - PreloadJSFlag = cli.StringFlag{ - Name: "preload", - Usage: "Comma separated list of JavaScript files to preload into the console", - } - AllowUnprotectedTxs = cli.BoolFlag{ - Name: "rpc.allow-unprotected-txs", - Usage: "Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC", + IPCDisabledFlag = &cli.BoolFlag{ + Name: "ipcdisable", + Usage: "Disable the IPC-RPC server", + Category: flags.APICategory, + } + IPCPathFlag = &flags.DirectoryFlag{ + Name: "ipcpath", + Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", + Category: flags.APICategory, + } + HTTPEnabledFlag = &cli.BoolFlag{ + Name: "http", + Usage: "Enable the HTTP-RPC server", + Category: flags.APICategory, + } + HTTPListenAddrFlag = &cli.StringFlag{ + Name: "http.addr", + Usage: "HTTP-RPC server listening interface", + Value: node.DefaultHTTPHost, + Category: flags.APICategory, + } + HTTPPortFlag = &cli.IntFlag{ + Name: "http.port", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort, + Category: flags.APICategory, + } + HTTPCORSDomainFlag = &cli.StringFlag{ + Name: "http.corsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: "", + Category: flags.APICategory, + } + HTTPVirtualHostsFlag = &cli.StringFlag{ + Name: "http.vhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","), + Category: flags.APICategory, + } + HTTPApiFlag = &cli.StringFlag{ + Name: "http.api", + Usage: "API's offered over the HTTP-RPC interface", + Value: "", + Category: flags.APICategory, + } + HTTPPathPrefixFlag = &cli.StringFlag{ + Name: "http.rpcprefix", + Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: "", + Category: flags.APICategory, + } + GraphQLEnabledFlag = &cli.BoolFlag{ + Name: "graphql", + Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.", + Category: flags.APICategory, + } + GraphQLCORSDomainFlag = &cli.StringFlag{ + Name: "graphql.corsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: "", + Category: flags.APICategory, + } + GraphQLVirtualHostsFlag = &cli.StringFlag{ + Name: "graphql.vhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: strings.Join(node.DefaultConfig.GraphQLVirtualHosts, ","), + Category: flags.APICategory, + } + WSEnabledFlag = &cli.BoolFlag{ + Name: "ws", + Usage: "Enable the WS-RPC server", + Category: flags.APICategory, + } + WSListenAddrFlag = &cli.StringFlag{ + Name: "ws.addr", + Usage: "WS-RPC server listening interface", + Value: node.DefaultWSHost, + Category: flags.APICategory, + } + WSPortFlag = &cli.IntFlag{ + Name: "ws.port", + Usage: "WS-RPC server listening port", + Value: node.DefaultWSPort, + Category: flags.APICategory, + } + WSApiFlag = &cli.StringFlag{ + Name: "ws.api", + Usage: "API's offered over the WS-RPC interface", + Value: "", + Category: flags.APICategory, + } + WSAllowedOriginsFlag = &cli.StringFlag{ + Name: "ws.origins", + Usage: "Origins from which to accept websockets requests", + Value: "", + Category: flags.APICategory, + } + WSPathPrefixFlag = &cli.StringFlag{ + Name: "ws.rpcprefix", + Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: "", + Category: flags.APICategory, + } + ExecFlag = &cli.StringFlag{ + Name: "exec", + Usage: "Execute JavaScript statement", + Category: flags.APICategory, + } + PreloadJSFlag = &cli.StringFlag{ + Name: "preload", + Usage: "Comma separated list of JavaScript files to preload into the console", + Category: flags.APICategory, + } + AllowUnprotectedTxs = &cli.BoolFlag{ + Name: "rpc.allow-unprotected-txs", + Usage: "Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC", + Category: flags.APICategory, } // Network Settings - MaxPeersFlag = cli.IntFlag{ - Name: "maxpeers", - Usage: "Maximum number of network peers (network disabled if set to 0)", - Value: node.DefaultConfig.P2P.MaxPeers, - } - MaxPendingPeersFlag = cli.IntFlag{ - Name: "maxpendpeers", - Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", - Value: node.DefaultConfig.P2P.MaxPendingPeers, - } - ListenPortFlag = cli.IntFlag{ - Name: "port", - Usage: "Network listening port", - Value: 30303, - } - BootnodesFlag = cli.StringFlag{ - Name: "bootnodes", - Usage: "Comma separated enode URLs for P2P discovery bootstrap", - Value: "", - } - NodeKeyFileFlag = cli.StringFlag{ - Name: "nodekey", - Usage: "P2P node key file", - } - NodeKeyHexFlag = cli.StringFlag{ - Name: "nodekeyhex", - Usage: "P2P node key as hex (for testing)", - } - NATFlag = cli.StringFlag{ - Name: "nat", - Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)", - Value: "any", - } - NoDiscoverFlag = cli.BoolFlag{ - Name: "nodiscover", - Usage: "Disables the peer discovery mechanism (manual peer addition)", - } - DiscoveryV5Flag = cli.BoolFlag{ - Name: "v5disc", - Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", - } - NetrestrictFlag = cli.StringFlag{ - Name: "netrestrict", - Usage: "Restricts network communication to the given IP networks (CIDR masks)", - } - DNSDiscoveryFlag = cli.StringFlag{ - Name: "discovery.dns", - Usage: "Sets DNS discovery entry points (use \"\" to disable DNS)", + MaxPeersFlag = &cli.IntFlag{ + Name: "maxpeers", + Usage: "Maximum number of network peers (network disabled if set to 0)", + Value: node.DefaultConfig.P2P.MaxPeers, + Category: flags.NetworkingCategory, + } + MaxPendingPeersFlag = &cli.IntFlag{ + Name: "maxpendpeers", + Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", + Value: node.DefaultConfig.P2P.MaxPendingPeers, + Category: flags.NetworkingCategory, + } + ListenPortFlag = &cli.IntFlag{ + Name: "port", + Usage: "Network listening port", + Value: 30303, + Category: flags.NetworkingCategory, + } + BootnodesFlag = &cli.StringFlag{ + Name: "bootnodes", + Usage: "Comma separated enode URLs for P2P discovery bootstrap", + Value: "", + Category: flags.NetworkingCategory, + } + NodeKeyFileFlag = &cli.StringFlag{ + Name: "nodekey", + Usage: "P2P node key file", + Category: flags.NetworkingCategory, + } + NodeKeyHexFlag = &cli.StringFlag{ + Name: "nodekeyhex", + Usage: "P2P node key as hex (for testing)", + Category: flags.NetworkingCategory, + } + NATFlag = &cli.StringFlag{ + Name: "nat", + Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)", + Value: "any", + Category: flags.NetworkingCategory, + } + NoDiscoverFlag = &cli.BoolFlag{ + Name: "nodiscover", + Usage: "Disables the peer discovery mechanism (manual peer addition)", + Category: flags.NetworkingCategory, + } + DiscoveryV5Flag = &cli.BoolFlag{ + Name: "v5disc", + Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", + Category: flags.NetworkingCategory, + } + NetrestrictFlag = &cli.StringFlag{ + Name: "netrestrict", + Usage: "Restricts network communication to the given IP networks (CIDR masks)", + Category: flags.NetworkingCategory, + } + DNSDiscoveryFlag = &cli.StringFlag{ + Name: "discovery.dns", + Usage: "Sets DNS discovery entry points (use \"\" to disable DNS)", + Category: flags.NetworkingCategory, } // ATM the url is left to the user and deployment to - JSpathFlag = cli.StringFlag{ - Name: "jspath", - Usage: "JavaScript root path for `loadScript`", - Value: ".", + JSpathFlag = &cli.StringFlag{ + Name: "jspath", + Usage: "JavaScript root path for `loadScript`", + Value: ".", + Category: flags.APICategory, } // Gas price oracle settings - GpoBlocksFlag = cli.IntFlag{ - Name: "gpo.blocks", - Usage: "Number of recent blocks to check for gas prices", - Value: ethconfig.Defaults.GPO.Blocks, + GpoBlocksFlag = &cli.IntFlag{ + Name: "gpo.blocks", + Usage: "Number of recent blocks to check for gas prices", + Value: ethconfig.Defaults.GPO.Blocks, + Category: flags.GasPriceCategory, } - GpoPercentileFlag = cli.IntFlag{ - Name: "gpo.percentile", - Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", - Value: ethconfig.Defaults.GPO.Percentile, + GpoPercentileFlag = &cli.IntFlag{ + Name: "gpo.percentile", + Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", + Value: ethconfig.Defaults.GPO.Percentile, + Category: flags.GasPriceCategory, } - GpoMaxGasPriceFlag = cli.Int64Flag{ - Name: "gpo.maxprice", - Usage: "Maximum gas price will be recommended by gpo", - Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), + GpoMaxGasPriceFlag = &cli.Int64Flag{ + Name: "gpo.maxprice", + Usage: "Maximum gas price will be recommended by gpo", + Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), + Category: flags.GasPriceCategory, } // Metrics flags - MetricsEnabledFlag = cli.BoolFlag{ - Name: "metrics", - Usage: "Enable metrics collection and reporting", + MetricsEnabledFlag = &cli.BoolFlag{ + Name: "metrics", + Usage: "Enable metrics collection and reporting", + Category: flags.MetricsCategory, } - MetricsEnabledExpensiveFlag = cli.BoolFlag{ - Name: "metrics.expensive", - Usage: "Enable expensive metrics collection and reporting", + MetricsEnabledExpensiveFlag = &cli.BoolFlag{ + Name: "metrics.expensive", + Usage: "Enable expensive metrics collection and reporting", + Category: flags.MetricsCategory, } // MetricsHTTPFlag defines the endpoint for a stand-alone metrics HTTP endpoint. // Since the pprof service enables sensitive/vulnerable behavior, this allows a user // to enable a public-OK metrics endpoint without having to worry about ALSO exposing // other profiling behavior or information. - MetricsHTTPFlag = cli.StringFlag{ - Name: "metrics.addr", - Usage: "Enable stand-alone metrics HTTP server listening interface", - Value: metrics.DefaultConfig.HTTP, - } - MetricsPortFlag = cli.IntFlag{ - Name: "metrics.port", - Usage: "Metrics HTTP server listening port", - Value: metrics.DefaultConfig.Port, - } - MetricsEnableInfluxDBFlag = cli.BoolFlag{ - Name: "metrics.influxdb", - Usage: "Enable metrics export/push to an external InfluxDB database", - } - MetricsInfluxDBEndpointFlag = cli.StringFlag{ - Name: "metrics.influxdb.endpoint", - Usage: "InfluxDB API endpoint to report metrics to", - Value: metrics.DefaultConfig.InfluxDBEndpoint, - } - MetricsInfluxDBDatabaseFlag = cli.StringFlag{ - Name: "metrics.influxdb.database", - Usage: "InfluxDB database name to push reported metrics to", - Value: metrics.DefaultConfig.InfluxDBDatabase, - } - MetricsInfluxDBUsernameFlag = cli.StringFlag{ - Name: "metrics.influxdb.username", - Usage: "Username to authorize access to the database", - Value: metrics.DefaultConfig.InfluxDBUsername, - } - MetricsInfluxDBPasswordFlag = cli.StringFlag{ - Name: "metrics.influxdb.password", - Usage: "Password to authorize access to the database", - Value: metrics.DefaultConfig.InfluxDBPassword, + MetricsHTTPFlag = &cli.StringFlag{ + Name: "metrics.addr", + Usage: "Enable stand-alone metrics HTTP server listening interface", + Value: metrics.DefaultConfig.HTTP, + Category: flags.MetricsCategory, + } + MetricsPortFlag = &cli.IntFlag{ + Name: "metrics.port", + Usage: "Metrics HTTP server listening port", + Value: metrics.DefaultConfig.Port, + Category: flags.MetricsCategory, + } + MetricsEnableInfluxDBFlag = &cli.BoolFlag{ + Name: "metrics.influxdb", + Usage: "Enable metrics export/push to an external InfluxDB database", + Category: flags.MetricsCategory, + } + MetricsInfluxDBEndpointFlag = &cli.StringFlag{ + Name: "metrics.influxdb.endpoint", + Usage: "InfluxDB API endpoint to report metrics to", + Value: metrics.DefaultConfig.InfluxDBEndpoint, + Category: flags.MetricsCategory, + } + MetricsInfluxDBDatabaseFlag = &cli.StringFlag{ + Name: "metrics.influxdb.database", + Usage: "InfluxDB database name to push reported metrics to", + Value: metrics.DefaultConfig.InfluxDBDatabase, + Category: flags.MetricsCategory, + } + MetricsInfluxDBUsernameFlag = &cli.StringFlag{ + Name: "metrics.influxdb.username", + Usage: "Username to authorize access to the database", + Value: metrics.DefaultConfig.InfluxDBUsername, + Category: flags.MetricsCategory, + } + MetricsInfluxDBPasswordFlag = &cli.StringFlag{ + Name: "metrics.influxdb.password", + Usage: "Password to authorize access to the database", + Value: metrics.DefaultConfig.InfluxDBPassword, + Category: flags.MetricsCategory, } // Tags are part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB. // For example `host` tag could be used so that we can group all nodes and average a measurement // across all of them, but also so that we can select a specific node and inspect its measurements. // https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key - MetricsInfluxDBTagsFlag = cli.StringFlag{ - Name: "metrics.influxdb.tags", - Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", - Value: metrics.DefaultConfig.InfluxDBTags, + MetricsInfluxDBTagsFlag = &cli.StringFlag{ + Name: "metrics.influxdb.tags", + Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", + Value: metrics.DefaultConfig.InfluxDBTags, + Category: flags.MetricsCategory, } - EWASMInterpreterFlag = cli.StringFlag{ + + EWASMInterpreterFlag = &cli.StringFlag{ Name: "vm.ewasm", Usage: "External ewasm configuration (default = built-in interpreter)", Value: "", } - EVMInterpreterFlag = cli.StringFlag{ + EVMInterpreterFlag = &cli.StringFlag{ Name: "vm.evm", Usage: "External EVM configuration (default = built-in interpreter)", Value: "", } - CatalystFlag = cli.BoolFlag{ + CatalystFlag = &cli.BoolFlag{ Name: "catalyst", Usage: "Catalyst mode (eth2 integration testing)", } // Quorum - added configurable call timeout for execution of calls - EVMCallTimeOutFlag = cli.IntFlag{ - Name: "vm.calltimeout", - Usage: "Timeout duration in seconds for message call execution without creating a transaction. Value 0 means no timeout.", - Value: 5, + EVMCallTimeOutFlag = &cli.IntFlag{ + Name: "vm.calltimeout", + Usage: "Timeout duration in seconds for message call execution without creating a transaction. Value 0 means no timeout.", + Value: 5, + Category: flags.GoQuorumOptionCategory, } // Quorum // immutability threshold which can be passed as a parameter at geth start - QuorumImmutabilityThreshold = cli.IntFlag{ - Name: "immutabilitythreshold", - Usage: "overrides the default immutability threshold for Quorum nodes. Its the threshold beyond which block data will be moved to ancient db", - Value: 3162240, + QuorumImmutabilityThreshold = &cli.IntFlag{ + Name: "immutabilitythreshold", + Usage: "overrides the default immutability threshold for Quorum nodes. Its the threshold beyond which block data will be moved to ancient db", + Value: 3162240, + Category: flags.GoQuorumOptionCategory, } + // Raft flags - RaftModeFlag = cli.BoolFlag{ - Name: "raft", - Usage: "If enabled, uses Raft instead of Quorum Chain for consensus", + RaftModeFlag = &cli.BoolFlag{ + Name: "raft", + Usage: "If enabled, uses Raft instead of Quorum Chain for consensus", + Category: flags.GoQuorumOptionCategory, } - RaftBlockTimeFlag = cli.IntFlag{ - Name: "raftblocktime", - Usage: "Amount of time between raft block creations in milliseconds", - Value: 50, + RaftBlockTimeFlag = &cli.IntFlag{ + Name: "raftblocktime", + Usage: "Amount of time between raft block creations in milliseconds", + Value: 50, + Category: flags.GoQuorumOptionCategory, } - RaftJoinExistingFlag = cli.IntFlag{ - Name: "raftjoinexisting", - Usage: "The raft ID to assume when joining an pre-existing cluster", - Value: 0, + RaftJoinExistingFlag = &cli.IntFlag{ + Name: "raftjoinexisting", + Usage: "The raft ID to assume when joining an pre-existing cluster", + Value: 0, + Category: flags.GoQuorumOptionCategory, } - EmitCheckpointsFlag = cli.BoolFlag{ - Name: "emitcheckpoints", - Usage: "If enabled, emit specially formatted logging checkpoints", + EmitCheckpointsFlag = &cli.BoolFlag{ + Name: "emitcheckpoints", + Usage: "If enabled, emit specially formatted logging checkpoints", + Category: flags.GoQuorumOptionCategory, } - RaftPortFlag = cli.IntFlag{ - Name: "raftport", - Usage: "The port to bind for the raft transport", - Value: 50400, + RaftPortFlag = &cli.IntFlag{ + Name: "raftport", + Usage: "The port to bind for the raft transport", + Value: 50400, + Category: flags.GoQuorumOptionCategory, } - RaftDNSEnabledFlag = cli.BoolFlag{ - Name: "raftdnsenable", - Usage: "Enable DNS resolution of peers", + RaftDNSEnabledFlag = &cli.BoolFlag{ + Name: "raftdnsenable", + Usage: "Enable DNS resolution of peers", + Category: flags.GoQuorumOptionCategory, } // Permission - EnableNodePermissionFlag = cli.BoolFlag{ - Name: "permissioned", - Usage: "If enabled, the node will allow only a defined list of nodes to connect", + EnableNodePermissionFlag = &cli.BoolFlag{ + Name: "permissioned", + Usage: "If enabled, the node will allow only a defined list of nodes to connect", + Category: flags.GoQuorumOptionCategory, } - AllowedFutureBlockTimeFlag = cli.Uint64Flag{ - Name: "allowedfutureblocktime", - Usage: "Max time (in seconds) from current time allowed for blocks, before they're considered future blocks", - Value: 0, + AllowedFutureBlockTimeFlag = &cli.Uint64Flag{ + Name: "allowedfutureblocktime", + Usage: "Max time (in seconds) from current time allowed for blocks, before they're considered future blocks", + Value: 0, + Category: flags.GoQuorumOptionCategory, } // Plugins settings - PluginSettingsFlag = cli.StringFlag{ - Name: "plugins", - Usage: "The URI of configuration which describes plugins being used. E.g.: file:///opt/geth/plugins.json", - } - PluginLocalVerifyFlag = cli.BoolFlag{ - Name: "plugins.localverify", - Usage: "If enabled, verify plugin integrity from local file system. This requires plugin signature file and PGP public key file to be available", - } - PluginPublicKeyFlag = cli.StringFlag{ - Name: "plugins.publickey", - Usage: fmt.Sprintf("The URI of PGP public key for local plugin verification. E.g.: file:///opt/geth/pubkey.pgp.asc. This flag is only valid if --%s is set (default = file:////%s)", PluginLocalVerifyFlag.Name, plugin.DefaultPublicKeyFile), - } - PluginSkipVerifyFlag = cli.BoolFlag{ - Name: "plugins.skipverify", - Usage: "If enabled, plugin integrity is NOT verified", + PluginSettingsFlag = &cli.StringFlag{ + Name: "plugins", + Usage: "The URI of configuration which describes plugins being used. E.g.: file:///opt/geth/plugins.json", + Category: flags.GoQuorumOptionCategory, + } + PluginLocalVerifyFlag = &cli.BoolFlag{ + Name: "plugins.localverify", + Usage: "If enabled, verify plugin integrity from local file system. This requires plugin signature file and PGP public key file to be available", + Category: flags.GoQuorumOptionCategory, + } + PluginPublicKeyFlag = &cli.StringFlag{ + Name: "plugins.publickey", + Usage: fmt.Sprintf("The URI of PGP public key for local plugin verification. E.g.: file:///opt/geth/pubkey.pgp.asc. This flag is only valid if --%s is set (default = file:////%s)", PluginLocalVerifyFlag.Name, plugin.DefaultPublicKeyFile), + Category: flags.GoQuorumOptionCategory, + } + PluginSkipVerifyFlag = &cli.BoolFlag{ + Name: "plugins.skipverify", + Usage: "If enabled, plugin integrity is NOT verified", + Category: flags.GoQuorumOptionCategory, } // account plugin flags - AccountPluginNewAccountConfigFlag = cli.StringFlag{ - Name: "plugins.account.config", - Usage: "Value will be passed to an account plugin if being used. See the account plugin implementation's documentation for further details", + AccountPluginNewAccountConfigFlag = &cli.StringFlag{ + Name: "plugins.account.config", + Usage: "Value will be passed to an account plugin if being used. See the account plugin implementation's documentation for further details", + Category: flags.GoQuorumOptionCategory, } // Istanbul settings - IstanbulRequestTimeoutFlag = cli.Uint64Flag{ + IstanbulRequestTimeoutFlag = &cli.Uint64Flag{ Name: "istanbul.requesttimeout", Usage: "[Deprecated] Timeout for each Istanbul round in milliseconds", Value: ethconfig.Defaults.Istanbul.RequestTimeout, } - IstanbulBlockPeriodFlag = cli.Uint64Flag{ + IstanbulBlockPeriodFlag = &cli.Uint64Flag{ Name: "istanbul.blockperiod", Usage: "[Deprecated] Default minimum difference between two consecutive block's timestamps in seconds", Value: ethconfig.Defaults.Istanbul.BlockPeriod, } // Multitenancy setting - MultitenancyFlag = cli.BoolFlag{ - Name: "multitenancy", - Usage: "Enable multitenancy support for this node. This requires RPC Security Plugin to also be configured.", + MultitenancyFlag = &cli.BoolFlag{ + Name: "multitenancy", + Usage: "Enable multitenancy support for this node. This requires RPC Security Plugin to also be configured.", + Category: flags.GoQuorumOptionCategory, } // Revert Reason - RevertReasonFlag = cli.BoolFlag{ - Name: "revertreason", - Usage: "Enable saving revert reason in the transaction receipts for this node.", + RevertReasonFlag = &cli.BoolFlag{ + Name: "revertreason", + Usage: "Enable saving revert reason in the transaction receipts for this node.", + Category: flags.GoQuorumOptionCategory, } - QuorumEnablePrivateTrieCache = cli.BoolFlag{ - Name: "privatetriecache.enable", - Usage: "Enable use of private trie cache for this node.", + QuorumEnablePrivateTrieCache = &cli.BoolFlag{ + Name: "privatetriecache.enable", + Usage: "Enable use of private trie cache for this node.", + Category: flags.GoQuorumOptionCategory, } - QuorumEnablePrivacyMarker = cli.BoolFlag{ - Name: "privacymarker.enable", - Usage: "Enable use of privacy marker transactions (PMT) for this node.", + QuorumEnablePrivacyMarker = &cli.BoolFlag{ + Name: "privacymarker.enable", + Usage: "Enable use of privacy marker transactions (PMT) for this node.", + Category: flags.GoQuorumOptionCategory, } // Quorum Private Transaction Manager connection options - QuorumPTMUnixSocketFlag = DirectoryFlag{ - Name: "ptm.socket", - Usage: "Path to the ipc file when using unix domain socket for the private transaction manager connection", - } - QuorumPTMUrlFlag = cli.StringFlag{ - Name: "ptm.url", - Usage: "URL when using http connection to private transaction manager", - } - QuorumPTMTimeoutFlag = cli.UintFlag{ - Name: "ptm.timeout", - Usage: "Timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", - Value: http2.DefaultConfig.Timeout, - } - QuorumPTMDialTimeoutFlag = cli.UintFlag{ - Name: "ptm.dialtimeout", - Usage: "Dial timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", - Value: http2.DefaultConfig.DialTimeout, - } - QuorumPTMHttpIdleTimeoutFlag = cli.UintFlag{ - Name: "ptm.http.idletimeout", - Usage: "Idle timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", - Value: http2.DefaultConfig.HttpIdleConnTimeout, - } - QuorumPTMHttpWriteBufferSizeFlag = cli.IntFlag{ - Name: "ptm.http.writebuffersize", - Usage: "Size of the write buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", - Value: 0, - } - QuorumPTMHttpReadBufferSizeFlag = cli.IntFlag{ - Name: "ptm.http.readbuffersize", - Usage: "Size of the read buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", - Value: 0, - } - QuorumPTMTlsModeFlag = cli.StringFlag{ - Name: "ptm.tls.mode", - Usage: `If "off" then TLS disabled (default). If "strict" then will use TLS for http connection to private transaction manager`, - } - QuorumPTMTlsRootCaFlag = DirectoryFlag{ - Name: "ptm.tls.rootca", - Usage: "Path to file containing root CA certificate for TLS connection to private transaction manager (defaults to host's certificates)", - } - QuorumPTMTlsClientCertFlag = DirectoryFlag{ - Name: "ptm.tls.clientcert", - Usage: "Path to file containing client certificate (or chain of certs) for TLS connection to private transaction manager", - } - QuorumPTMTlsClientKeyFlag = DirectoryFlag{ - Name: "ptm.tls.clientkey", - Usage: "Path to file containing client's private key for TLS connection to private transaction manager", - } - QuorumPTMTlsInsecureSkipVerify = cli.BoolFlag{ - Name: "ptm.tls.insecureskipverify", - Usage: "Disable verification of server's TLS certificate on connection to private transaction manager", - } - QuorumLightServerFlag = cli.BoolFlag{ - Name: "qlight.server", - Usage: "If enabled, the quorum light P2P protocol is started in addition to the other P2P protocols", - } - QuorumLightServerP2PListenPortFlag = cli.IntFlag{ - Name: "qlight.server.p2p.port", - Usage: "QLight Network listening port", - Value: 30305, - } - QuorumLightServerP2PMaxPeersFlag = cli.IntFlag{ - Name: "qlight.server.p2p.maxpeers", - Usage: "Maximum number of qlight peers", - Value: 10, - } - QuorumLightServerP2PNetrestrictFlag = cli.StringFlag{ - Name: "qlight.server.p2p.netrestrict", - Usage: "Restricts network communication to the given IP networks (CIDR masks)", - } - QuorumLightServerP2PPermissioningFlag = cli.BoolFlag{ - Name: "qlight.server.p2p.permissioning", - Usage: "If enabled, the qlight peers are checked against a permissioned list and a disallowed list.", - } - QuorumLightServerP2PPermissioningPrefixFlag = cli.StringFlag{ - Name: "qlight.server.p2p.permissioning.prefix", - Usage: "The prefix for the permissioned-nodes.json and disallowed-nodes.json files.", - } - QuorumLightClientFlag = cli.BoolFlag{ - Name: "qlight.client", - Usage: "If enabled, the quorum light client P2P protocol is started (only)", - } - QuorumLightClientPSIFlag = cli.StringFlag{ - Name: "qlight.client.psi", - Usage: "The PSI this client will use to connect to a server node.", - } - QuorumLightClientTokenEnabledFlag = cli.BoolFlag{ - Name: "qlight.client.token.enabled", - Usage: "Whether the client uses a token when connecting to the qlight server.", - } - QuorumLightClientTokenValueFlag = cli.StringFlag{ + QuorumPTMUnixSocketFlag = &flags.DirectoryFlag{ + Name: "ptm.socket", + Usage: "Path to the ipc file when using unix domain socket for the private transaction manager connection", + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMUrlFlag = &cli.StringFlag{ + Name: "ptm.url", + Usage: "URL when using http connection to private transaction manager", + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTimeoutFlag = &cli.UintFlag{ + Name: "ptm.timeout", + Usage: "Timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.Timeout, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMDialTimeoutFlag = &cli.UintFlag{ + Name: "ptm.dialtimeout", + Usage: "Dial timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.DialTimeout, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMHttpIdleTimeoutFlag = &cli.UintFlag{ + Name: "ptm.http.idletimeout", + Usage: "Idle timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.HttpIdleConnTimeout, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMHttpWriteBufferSizeFlag = &cli.IntFlag{ + Name: "ptm.http.writebuffersize", + Usage: "Size of the write buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", + Value: 0, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMHttpReadBufferSizeFlag = &cli.IntFlag{ + Name: "ptm.http.readbuffersize", + Usage: "Size of the read buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", + Value: 0, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTlsModeFlag = &cli.StringFlag{ + Name: "ptm.tls.mode", + Usage: `If "off" then TLS disabled (default). If "strict" then will use TLS for http connection to private transaction manager`, + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTlsRootCaFlag = &flags.DirectoryFlag{ + Name: "ptm.tls.rootca", + Usage: "Path to file containing root CA certificate for TLS connection to private transaction manager (defaults to host's certificates)", + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTlsClientCertFlag = &flags.DirectoryFlag{ + Name: "ptm.tls.clientcert", + Usage: "Path to file containing client certificate (or chain of certs) for TLS connection to private transaction manager", + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTlsClientKeyFlag = &flags.DirectoryFlag{ + Name: "ptm.tls.clientkey", + Usage: "Path to file containing client's private key for TLS connection to private transaction manager", + Category: flags.GoQuorumOptionCategory, + } + QuorumPTMTlsInsecureSkipVerify = &cli.BoolFlag{ + Name: "ptm.tls.insecureskipverify", + Usage: "Disable verification of server's TLS certificate on connection to private transaction manager", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerFlag = &cli.BoolFlag{ + Name: "qlight.server", + Usage: "If enabled, the quorum light P2P protocol is started in addition to the other P2P protocols", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerP2PListenPortFlag = &cli.IntFlag{ + Name: "qlight.server.p2p.port", + Usage: "QLight Network listening port", + Value: 30305, + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerP2PMaxPeersFlag = &cli.IntFlag{ + Name: "qlight.server.p2p.maxpeers", + Usage: "Maximum number of qlight peers", + Value: 10, + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerP2PNetrestrictFlag = &cli.StringFlag{ + Name: "qlight.server.p2p.netrestrict", + Usage: "Restricts network communication to the given IP networks (CIDR masks)", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerP2PPermissioningFlag = &cli.BoolFlag{ + Name: "qlight.server.p2p.permissioning", + Usage: "If enabled, the qlight peers are checked against a permissioned list and a disallowed list.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightServerP2PPermissioningPrefixFlag = &cli.StringFlag{ + Name: "qlight.server.p2p.permissioning.prefix", + Usage: "The prefix for the permissioned-nodes.json and disallowed-nodes.json files.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientFlag = &cli.BoolFlag{ + Name: "qlight.client", + Usage: "If enabled, the quorum light client P2P protocol is started (only)", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientPSIFlag = &cli.StringFlag{ + Name: "qlight.client.psi", + Usage: "The PSI this client will use to connect to a server node.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientTokenEnabledFlag = &cli.BoolFlag{ + Name: "qlight.client.token.enabled", + Usage: "Whether the client uses a token when connecting to the qlight server.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientTokenValueFlag = &cli.StringFlag{ Name: "qlight.client.token.value", Usage: "The token this client will use to connect to a server node.", } - QuorumLightClientTokenManagementFlag = cli.StringFlag{ - Name: "qlight.client.token.management", - Usage: "The mechanism used to refresh the token. Possible values: none (developer mode)/external (new token must be injected via the qlight RPC API)/client-security-plugin (the client security plugin must be deployed/configured).", - } - QuorumLightClientRPCTLSFlag = cli.BoolFlag{ - Name: "qlight.client.rpc.tls", - Usage: "If enabled, the quorum light client RPC connection will be configured to use TLS", - } - QuorumLightClientRPCTLSInsecureSkipVerifyFlag = cli.BoolFlag{ - Name: "qlight.client.rpc.tls.insecureskipverify", - Usage: "If enabled, the quorum light client RPC connection skips TLS verification", - } - QuorumLightClientRPCTLSCACertFlag = cli.StringFlag{ - Name: "qlight.client.rpc.tls.cacert", - Usage: "The quorum light client RPC client certificate authority.", - } - QuorumLightClientRPCTLSCertFlag = cli.StringFlag{ - Name: "qlight.client.rpc.tls.cert", - Usage: "The quorum light client RPC client certificate.", - } - QuorumLightClientRPCTLSKeyFlag = cli.StringFlag{ - Name: "qlight.client.rpc.tls.key", - Usage: "The quorum light client RPC client certificate private key.", - } - QuorumLightClientServerNodeFlag = cli.StringFlag{ - Name: "qlight.client.serverNode", - Usage: "The node ID of the target server node", - } - QuorumLightClientServerNodeRPCFlag = cli.StringFlag{ - Name: "qlight.client.serverNodeRPC", - Usage: "The RPC URL of the target server node", - } - QuorumLightTLSFlag = cli.BoolFlag{ - Name: "qlight.tls", - Usage: "If enabled, the quorum light client P2P protocol will use tls", - } - QuorumLightTLSCertFlag = cli.StringFlag{ - Name: "qlight.tls.cert", - Usage: "The certificate file to use for the qlight P2P connection", - } - QuorumLightTLSKeyFlag = cli.StringFlag{ - Name: "qlight.tls.key", - Usage: "The key file to use for the qlight P2P connection", - } - QuorumLightTLSCACertsFlag = cli.StringFlag{ - Name: "qlight.tls.cacerts", - Usage: "The certificate authorities file to use for validating P2P connection", - } - QuorumLightTLSClientAuthFlag = cli.IntFlag{ - Name: "qlight.tls.clientauth", - Usage: "The way the client is authenticated. Possible values: 0=NoClientCert(default) 1=RequestClientCert 2=RequireAnyClientCert 3=VerifyClientCertIfGiven 4=RequireAndVerifyClientCert", - Value: 0, - } - QuorumLightTLSCipherSuitesFlag = cli.StringFlag{ - Name: "qlight.tls.ciphersuites", - Usage: "The cipher suites to use for the qlight P2P connection", + QuorumLightClientTokenManagementFlag = &cli.StringFlag{ + Name: "qlight.client.token.management", + Usage: "The mechanism used to refresh the token. Possible values: none (developer mode)/external (new token must be injected via the qlight RPC API)/client-security-plugin (the client security plugin must be deployed/configured).", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientRPCTLSFlag = &cli.BoolFlag{ + Name: "qlight.client.rpc.tls", + Usage: "If enabled, the quorum light client RPC connection will be configured to use TLS", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientRPCTLSInsecureSkipVerifyFlag = &cli.BoolFlag{ + Name: "qlight.client.rpc.tls.insecureskipverify", + Usage: "If enabled, the quorum light client RPC connection skips TLS verification", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientRPCTLSCACertFlag = &cli.StringFlag{ + Name: "qlight.client.rpc.tls.cacert", + Usage: "The quorum light client RPC client certificate authority.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientRPCTLSCertFlag = &cli.StringFlag{ + Name: "qlight.client.rpc.tls.cert", + Usage: "The quorum light client RPC client certificate.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientRPCTLSKeyFlag = &cli.StringFlag{ + Name: "qlight.client.rpc.tls.key", + Usage: "The quorum light client RPC client certificate private key.", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientServerNodeFlag = &cli.StringFlag{ + Name: "qlight.client.serverNode", + Usage: "The node ID of the target server node", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightClientServerNodeRPCFlag = &cli.StringFlag{ + Name: "qlight.client.serverNodeRPC", + Usage: "The RPC URL of the target server node", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSFlag = &cli.BoolFlag{ + Name: "qlight.tls", + Usage: "If enabled, the quorum light client P2P protocol will use tls", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSCertFlag = &cli.StringFlag{ + Name: "qlight.tls.cert", + Usage: "The certificate file to use for the qlight P2P connection", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSKeyFlag = &cli.StringFlag{ + Name: "qlight.tls.key", + Usage: "The key file to use for the qlight P2P connection", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSCACertsFlag = &cli.StringFlag{ + Name: "qlight.tls.cacerts", + Usage: "The certificate authorities file to use for validating P2P connection", + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSClientAuthFlag = &cli.IntFlag{ + Name: "qlight.tls.clientauth", + Usage: "The way the client is authenticated. Possible values: 0=NoClientCert(default) 1=RequestClientCert 2=RequireAnyClientCert 3=VerifyClientCertIfGiven 4=RequireAndVerifyClientCert", + Value: 0, + Category: flags.GoQuorumOptionCategory, + } + QuorumLightTLSCipherSuitesFlag = &cli.StringFlag{ + Name: "qlight.tls.ciphersuites", + Usage: "The cipher suites to use for the qlight P2P connection", + Category: flags.GoQuorumOptionCategory, } ) @@ -1024,19 +1171,19 @@ var ( // if none (or the empty string) is specified. If the node is starting a testnet, // then a subdirectory of the specified datadir will be used. func MakeDataDir(ctx *cli.Context) string { - if path := ctx.GlobalString(DataDirFlag.Name); path != "" { - if ctx.GlobalBool(RopstenFlag.Name) { + if path := ctx.String(DataDirFlag.Name); path != "" { + if ctx.Bool(RopstenFlag.Name) { // Maintain compatibility with older Geth configurations storing the // Ropsten database in `testnet` instead of `ropsten`. return filepath.Join(path, "ropsten") } - if ctx.GlobalBool(RinkebyFlag.Name) { + if ctx.Bool(RinkebyFlag.Name) { return filepath.Join(path, "rinkeby") } - if ctx.GlobalBool(GoerliFlag.Name) { + if ctx.Bool(GoerliFlag.Name) { return filepath.Join(path, "goerli") } - if ctx.GlobalBool(YoloV3Flag.Name) { + if ctx.Bool(YoloV3Flag.Name) { return filepath.Join(path, "yolo-v3") } return path @@ -1050,8 +1197,8 @@ func MakeDataDir(ctx *cli.Context) string { // method returns nil and an emphemeral key is to be generated. func setNodeKey(ctx *cli.Context, cfg *p2p.Config) { var ( - hex = ctx.GlobalString(NodeKeyHexFlag.Name) - file = ctx.GlobalString(NodeKeyFileFlag.Name) + hex = ctx.String(NodeKeyHexFlag.Name) + file = ctx.String(NodeKeyFileFlag.Name) key *ecdsa.PrivateKey err error ) @@ -1073,7 +1220,7 @@ func setNodeKey(ctx *cli.Context, cfg *p2p.Config) { // setNodeUserIdent creates the user identifier from CLI flags. func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) { - if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 { + if identity := ctx.String(IdentityFlag.Name); len(identity) > 0 { cfg.UserIdent = identity } } @@ -1083,15 +1230,15 @@ func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) { func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { urls := params.MainnetBootnodes switch { - case ctx.GlobalIsSet(BootnodesFlag.Name): - urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name)) - case ctx.GlobalBool(RopstenFlag.Name): + case ctx.IsSet(BootnodesFlag.Name): + urls = SplitAndTrim(ctx.String(BootnodesFlag.Name)) + case ctx.Bool(RopstenFlag.Name): urls = params.RopstenBootnodes - case ctx.GlobalBool(RinkebyFlag.Name): + case ctx.Bool(RinkebyFlag.Name): urls = params.RinkebyBootnodes - case ctx.GlobalBool(GoerliFlag.Name): + case ctx.Bool(GoerliFlag.Name): urls = params.GoerliBootnodes - case ctx.GlobalBool(YoloV3Flag.Name): + case ctx.Bool(YoloV3Flag.Name): urls = params.YoloV3Bootnodes case cfg.BootstrapNodes != nil: return // already set, don't apply defaults. @@ -1115,8 +1262,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { urls := params.V5Bootnodes switch { - case ctx.GlobalIsSet(BootnodesFlag.Name): - urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name)) + case ctx.IsSet(BootnodesFlag.Name): + urls = SplitAndTrim(ctx.String(BootnodesFlag.Name)) case cfg.BootstrapNodesV5 != nil: return // already set, don't apply defaults. } @@ -1137,15 +1284,15 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { // setListenAddress creates a TCP listening address string from set command // line flags. func setListenAddress(ctx *cli.Context, cfg *p2p.Config) { - if ctx.GlobalIsSet(ListenPortFlag.Name) { - cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name)) + if ctx.IsSet(ListenPortFlag.Name) { + cfg.ListenAddr = fmt.Sprintf(":%d", ctx.Int(ListenPortFlag.Name)) } } // setNAT creates a port mapper from command line flags. func setNAT(ctx *cli.Context, cfg *p2p.Config) { - if ctx.GlobalIsSet(NATFlag.Name) { - natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name)) + if ctx.IsSet(NATFlag.Name) { + natif, err := nat.Parse(ctx.String(NATFlag.Name)) if err != nil { Fatalf("Option %s: %v", NATFlag.Name, err) } @@ -1168,95 +1315,95 @@ func SplitAndTrim(input string) (ret []string) { // setHTTP creates the HTTP RPC listener interface string from the set // command line flags, returning empty if the HTTP endpoint is disabled. func setHTTP(ctx *cli.Context, cfg *node.Config) { - if ctx.GlobalBool(LegacyRPCEnabledFlag.Name) && cfg.HTTPHost == "" { + if ctx.Bool(LegacyRPCEnabledFlag.Name) && cfg.HTTPHost == "" { log.Warn("The flag --rpc is deprecated and will be removed in the future, please use --http") cfg.HTTPHost = "127.0.0.1" - if ctx.GlobalIsSet(LegacyRPCListenAddrFlag.Name) { - cfg.HTTPHost = ctx.GlobalString(LegacyRPCListenAddrFlag.Name) + if ctx.IsSet(LegacyRPCListenAddrFlag.Name) { + cfg.HTTPHost = ctx.String(LegacyRPCListenAddrFlag.Name) log.Warn("The flag --rpcaddr is deprecated and will be removed in the future, please use --http.addr") } } - if ctx.GlobalBool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" { + if ctx.Bool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" { cfg.HTTPHost = "127.0.0.1" - if ctx.GlobalIsSet(HTTPListenAddrFlag.Name) { - cfg.HTTPHost = ctx.GlobalString(HTTPListenAddrFlag.Name) + if ctx.IsSet(HTTPListenAddrFlag.Name) { + cfg.HTTPHost = ctx.String(HTTPListenAddrFlag.Name) } } - if ctx.GlobalIsSet(LegacyRPCPortFlag.Name) { - cfg.HTTPPort = ctx.GlobalInt(LegacyRPCPortFlag.Name) + if ctx.IsSet(LegacyRPCPortFlag.Name) { + cfg.HTTPPort = ctx.Int(LegacyRPCPortFlag.Name) log.Warn("The flag --rpcport is deprecated and will be removed in the future, please use --http.port") } - if ctx.GlobalIsSet(HTTPPortFlag.Name) { - cfg.HTTPPort = ctx.GlobalInt(HTTPPortFlag.Name) + if ctx.IsSet(HTTPPortFlag.Name) { + cfg.HTTPPort = ctx.Int(HTTPPortFlag.Name) } - if ctx.GlobalIsSet(LegacyRPCCORSDomainFlag.Name) { - cfg.HTTPCors = SplitAndTrim(ctx.GlobalString(LegacyRPCCORSDomainFlag.Name)) + if ctx.IsSet(LegacyRPCCORSDomainFlag.Name) { + cfg.HTTPCors = SplitAndTrim(ctx.String(LegacyRPCCORSDomainFlag.Name)) log.Warn("The flag --rpccorsdomain is deprecated and will be removed in the future, please use --http.corsdomain") } - if ctx.GlobalIsSet(HTTPCORSDomainFlag.Name) { - cfg.HTTPCors = SplitAndTrim(ctx.GlobalString(HTTPCORSDomainFlag.Name)) + if ctx.IsSet(HTTPCORSDomainFlag.Name) { + cfg.HTTPCors = SplitAndTrim(ctx.String(HTTPCORSDomainFlag.Name)) } - if ctx.GlobalIsSet(LegacyRPCApiFlag.Name) { - cfg.HTTPModules = SplitAndTrim(ctx.GlobalString(LegacyRPCApiFlag.Name)) + if ctx.IsSet(LegacyRPCApiFlag.Name) { + cfg.HTTPModules = SplitAndTrim(ctx.String(LegacyRPCApiFlag.Name)) log.Warn("The flag --rpcapi is deprecated and will be removed in the future, please use --http.api") } - if ctx.GlobalIsSet(HTTPApiFlag.Name) { - cfg.HTTPModules = SplitAndTrim(ctx.GlobalString(HTTPApiFlag.Name)) + if ctx.IsSet(HTTPApiFlag.Name) { + cfg.HTTPModules = SplitAndTrim(ctx.String(HTTPApiFlag.Name)) } - if ctx.GlobalIsSet(LegacyRPCVirtualHostsFlag.Name) { - cfg.HTTPVirtualHosts = SplitAndTrim(ctx.GlobalString(LegacyRPCVirtualHostsFlag.Name)) + if ctx.IsSet(LegacyRPCVirtualHostsFlag.Name) { + cfg.HTTPVirtualHosts = SplitAndTrim(ctx.String(LegacyRPCVirtualHostsFlag.Name)) log.Warn("The flag --rpcvhosts is deprecated and will be removed in the future, please use --http.vhosts") } - if ctx.GlobalIsSet(HTTPVirtualHostsFlag.Name) { - cfg.HTTPVirtualHosts = SplitAndTrim(ctx.GlobalString(HTTPVirtualHostsFlag.Name)) + if ctx.IsSet(HTTPVirtualHostsFlag.Name) { + cfg.HTTPVirtualHosts = SplitAndTrim(ctx.String(HTTPVirtualHostsFlag.Name)) } - if ctx.GlobalIsSet(HTTPPathPrefixFlag.Name) { - cfg.HTTPPathPrefix = ctx.GlobalString(HTTPPathPrefixFlag.Name) + if ctx.IsSet(HTTPPathPrefixFlag.Name) { + cfg.HTTPPathPrefix = ctx.String(HTTPPathPrefixFlag.Name) } - if ctx.GlobalIsSet(AllowUnprotectedTxs.Name) { - cfg.AllowUnprotectedTxs = ctx.GlobalBool(AllowUnprotectedTxs.Name) + if ctx.IsSet(AllowUnprotectedTxs.Name) { + cfg.AllowUnprotectedTxs = ctx.Bool(AllowUnprotectedTxs.Name) } } // setGraphQL creates the GraphQL listener interface string from the set // command line flags, returning empty if the GraphQL endpoint is disabled. func setGraphQL(ctx *cli.Context, cfg *node.Config) { - if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) { - cfg.GraphQLCors = SplitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name)) + if ctx.IsSet(GraphQLCORSDomainFlag.Name) { + cfg.GraphQLCors = SplitAndTrim(ctx.String(GraphQLCORSDomainFlag.Name)) } - if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) { - cfg.GraphQLVirtualHosts = SplitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name)) + if ctx.IsSet(GraphQLVirtualHostsFlag.Name) { + cfg.GraphQLVirtualHosts = SplitAndTrim(ctx.String(GraphQLVirtualHostsFlag.Name)) } } // setWS creates the WebSocket RPC listener interface string from the set // command line flags, returning empty if the HTTP endpoint is disabled. func setWS(ctx *cli.Context, cfg *node.Config) { - if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" { + if ctx.Bool(WSEnabledFlag.Name) && cfg.WSHost == "" { cfg.WSHost = "127.0.0.1" - if ctx.GlobalIsSet(WSListenAddrFlag.Name) { - cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name) + if ctx.IsSet(WSListenAddrFlag.Name) { + cfg.WSHost = ctx.String(WSListenAddrFlag.Name) } } - if ctx.GlobalIsSet(WSPortFlag.Name) { - cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name) + if ctx.IsSet(WSPortFlag.Name) { + cfg.WSPort = ctx.Int(WSPortFlag.Name) } - if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) { - cfg.WSOrigins = SplitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name)) + if ctx.IsSet(WSAllowedOriginsFlag.Name) { + cfg.WSOrigins = SplitAndTrim(ctx.String(WSAllowedOriginsFlag.Name)) } - if ctx.GlobalIsSet(WSApiFlag.Name) { - cfg.WSModules = SplitAndTrim(ctx.GlobalString(WSApiFlag.Name)) + if ctx.IsSet(WSApiFlag.Name) { + cfg.WSModules = SplitAndTrim(ctx.String(WSApiFlag.Name)) } - if ctx.GlobalIsSet(WSPathPrefixFlag.Name) { - cfg.WSPathPrefix = ctx.GlobalString(WSPathPrefixFlag.Name) + if ctx.IsSet(WSPathPrefixFlag.Name) { + cfg.WSPathPrefix = ctx.String(WSPathPrefixFlag.Name) } } @@ -1265,45 +1412,45 @@ func setWS(ctx *cli.Context, cfg *node.Config) { func setIPC(ctx *cli.Context, cfg *node.Config) { CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag) switch { - case ctx.GlobalBool(IPCDisabledFlag.Name): + case ctx.Bool(IPCDisabledFlag.Name): cfg.IPCPath = "" - case ctx.GlobalIsSet(IPCPathFlag.Name): - cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name) + case ctx.IsSet(IPCPathFlag.Name): + cfg.IPCPath = ctx.String(IPCPathFlag.Name) } } // setLes configures the les server and ultra light client settings from the command line flags. func setLes(ctx *cli.Context, cfg *ethconfig.Config) { - if ctx.GlobalIsSet(LightServeFlag.Name) { - cfg.LightServ = ctx.GlobalInt(LightServeFlag.Name) + if ctx.IsSet(LightServeFlag.Name) { + cfg.LightServ = ctx.Int(LightServeFlag.Name) } - if ctx.GlobalIsSet(LightIngressFlag.Name) { - cfg.LightIngress = ctx.GlobalInt(LightIngressFlag.Name) + if ctx.IsSet(LightIngressFlag.Name) { + cfg.LightIngress = ctx.Int(LightIngressFlag.Name) } - if ctx.GlobalIsSet(LightEgressFlag.Name) { - cfg.LightEgress = ctx.GlobalInt(LightEgressFlag.Name) + if ctx.IsSet(LightEgressFlag.Name) { + cfg.LightEgress = ctx.Int(LightEgressFlag.Name) } - if ctx.GlobalIsSet(LightMaxPeersFlag.Name) { - cfg.LightPeers = ctx.GlobalInt(LightMaxPeersFlag.Name) + if ctx.IsSet(LightMaxPeersFlag.Name) { + cfg.LightPeers = ctx.Int(LightMaxPeersFlag.Name) } - if ctx.GlobalIsSet(UltraLightServersFlag.Name) { - cfg.UltraLightServers = strings.Split(ctx.GlobalString(UltraLightServersFlag.Name), ",") + if ctx.IsSet(UltraLightServersFlag.Name) { + cfg.UltraLightServers = strings.Split(ctx.String(UltraLightServersFlag.Name), ",") } - if ctx.GlobalIsSet(UltraLightFractionFlag.Name) { - cfg.UltraLightFraction = ctx.GlobalInt(UltraLightFractionFlag.Name) + if ctx.IsSet(UltraLightFractionFlag.Name) { + cfg.UltraLightFraction = ctx.Int(UltraLightFractionFlag.Name) } if cfg.UltraLightFraction <= 0 && cfg.UltraLightFraction > 100 { log.Error("Ultra light fraction is invalid", "had", cfg.UltraLightFraction, "updated", ethconfig.Defaults.UltraLightFraction) cfg.UltraLightFraction = ethconfig.Defaults.UltraLightFraction } - if ctx.GlobalIsSet(UltraLightOnlyAnnounceFlag.Name) { - cfg.UltraLightOnlyAnnounce = ctx.GlobalBool(UltraLightOnlyAnnounceFlag.Name) + if ctx.IsSet(UltraLightOnlyAnnounceFlag.Name) { + cfg.UltraLightOnlyAnnounce = ctx.Bool(UltraLightOnlyAnnounceFlag.Name) } - if ctx.GlobalIsSet(LightNoPruneFlag.Name) { - cfg.LightNoPrune = ctx.GlobalBool(LightNoPruneFlag.Name) + if ctx.IsSet(LightNoPruneFlag.Name) { + cfg.LightNoPrune = ctx.Bool(LightNoPruneFlag.Name) } - if ctx.GlobalIsSet(LightNoSyncServeFlag.Name) { - cfg.LightNoSyncServe = ctx.GlobalBool(LightNoSyncServeFlag.Name) + if ctx.IsSet(LightNoSyncServeFlag.Name) { + cfg.LightNoSyncServe = ctx.Bool(LightNoSyncServeFlag.Name) } } @@ -1351,8 +1498,8 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *ethconfig.Config) { // Extract the current etherbase var etherbase string - if ctx.GlobalIsSet(MinerEtherbaseFlag.Name) { - etherbase = ctx.GlobalString(MinerEtherbaseFlag.Name) + if ctx.IsSet(MinerEtherbaseFlag.Name) { + etherbase = ctx.String(MinerEtherbaseFlag.Name) } // Convert the etherbase into an address and configure it if etherbase != "" { @@ -1370,7 +1517,7 @@ func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *ethconfig.Config // MakePasswordList reads password lines from the file specified by the global --password flag. func MakePasswordList(ctx *cli.Context) []string { - path := ctx.GlobalString(PasswordFileFlag.Name) + path := ctx.String(PasswordFileFlag.Name) if path == "" { return nil } @@ -1393,25 +1540,25 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { setBootstrapNodes(ctx, cfg) setBootstrapNodesV5(ctx, cfg) - lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light" - lightServer := (ctx.GlobalInt(LightServeFlag.Name) != 0) + lightClient := ctx.String(SyncModeFlag.Name) == "light" + lightServer := (ctx.Int(LightServeFlag.Name) != 0) - lightPeers := ctx.GlobalInt(LightMaxPeersFlag.Name) - if lightClient && !ctx.GlobalIsSet(LightMaxPeersFlag.Name) { + lightPeers := ctx.Int(LightMaxPeersFlag.Name) + if lightClient && !ctx.IsSet(LightMaxPeersFlag.Name) { // dynamic default - for clients we use 1/10th of the default for servers lightPeers /= 10 } - if ctx.GlobalIsSet(MaxPeersFlag.Name) { - cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name) - if lightServer && !ctx.GlobalIsSet(LightMaxPeersFlag.Name) { + if ctx.IsSet(MaxPeersFlag.Name) { + cfg.MaxPeers = ctx.Int(MaxPeersFlag.Name) + if lightServer && !ctx.IsSet(LightMaxPeersFlag.Name) { cfg.MaxPeers += lightPeers } } else { if lightServer { cfg.MaxPeers += lightPeers } - if lightClient && ctx.GlobalIsSet(LightMaxPeersFlag.Name) && cfg.MaxPeers < lightPeers { + if lightClient && ctx.IsSet(LightMaxPeersFlag.Name) && cfg.MaxPeers < lightPeers { cfg.MaxPeers = lightPeers } } @@ -1424,24 +1571,24 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { } log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers) - if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) { - cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name) + if ctx.IsSet(MaxPendingPeersFlag.Name) { + cfg.MaxPendingPeers = ctx.Int(MaxPendingPeersFlag.Name) } - if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient { + if ctx.IsSet(NoDiscoverFlag.Name) || lightClient { cfg.NoDiscovery = true } // if we're running a light client or server, force enable the v5 peer discovery // unless it is explicitly disabled with --nodiscover note that explicitly specifying // --v5disc overrides --nodiscover, in which case the later only disables v4 discovery - forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name) - if ctx.GlobalIsSet(DiscoveryV5Flag.Name) { - cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name) + forceV5Discovery := (lightClient || lightServer) && !ctx.Bool(NoDiscoverFlag.Name) + if ctx.IsSet(DiscoveryV5Flag.Name) { + cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) } else if forceV5Discovery { cfg.DiscoveryV5 = true } - if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" { + if netrestrict := ctx.String(NetrestrictFlag.Name); netrestrict != "" { list, err := netutil.ParseNetlist(netrestrict) if err != nil { Fatalf("Option %q: %v", NetrestrictFlag.Name, err) @@ -1449,7 +1596,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { cfg.NetRestrict = list } - if ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(CatalystFlag.Name) { + if ctx.Bool(DeveloperFlag.Name) || ctx.Bool(CatalystFlag.Name) { // --dev mode can't use p2p networking. cfg.MaxPeers = 0 cfg.ListenAddr = "" @@ -1463,18 +1610,18 @@ func SetQP2PConfig(ctx *cli.Context, cfg *p2p.Config) { setNodeKey(ctx, cfg) //setNAT(ctx, cfg) cfg.NAT = nil - if ctx.GlobalIsSet(QuorumLightServerP2PListenPortFlag.Name) { - cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(QuorumLightServerP2PListenPortFlag.Name)) + if ctx.IsSet(QuorumLightServerP2PListenPortFlag.Name) { + cfg.ListenAddr = fmt.Sprintf(":%d", ctx.Int(QuorumLightServerP2PListenPortFlag.Name)) } - cfg.EnableNodePermission = ctx.GlobalIsSet(QuorumLightServerP2PPermissioningFlag.Name) + cfg.EnableNodePermission = ctx.IsSet(QuorumLightServerP2PPermissioningFlag.Name) cfg.MaxPeers = 10 - if ctx.GlobalIsSet(QuorumLightServerP2PMaxPeersFlag.Name) { - cfg.MaxPeers = ctx.GlobalInt(QuorumLightServerP2PMaxPeersFlag.Name) + if ctx.IsSet(QuorumLightServerP2PMaxPeersFlag.Name) { + cfg.MaxPeers = ctx.Int(QuorumLightServerP2PMaxPeersFlag.Name) } - if netrestrict := ctx.GlobalString(QuorumLightServerP2PNetrestrictFlag.Name); netrestrict != "" { + if netrestrict := ctx.String(QuorumLightServerP2PNetrestrictFlag.Name); netrestrict != "" { list, err := netutil.ParseNetlist(netrestrict) if err != nil { Fatalf("Option %q: %v", QuorumLightServerP2PNetrestrictFlag.Name, err) @@ -1503,38 +1650,38 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { setRaftLogDir(ctx, cfg) setSmartCard(ctx, cfg) - if ctx.GlobalIsSet(ExternalSignerFlag.Name) { - cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name) + if ctx.IsSet(ExternalSignerFlag.Name) { + cfg.ExternalSigner = ctx.String(ExternalSignerFlag.Name) } - if ctx.GlobalIsSet(KeyStoreDirFlag.Name) { - cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name) + if ctx.IsSet(KeyStoreDirFlag.Name) { + cfg.KeyStoreDir = ctx.String(KeyStoreDirFlag.Name) } - if ctx.GlobalIsSet(LightKDFFlag.Name) { - cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name) + if ctx.IsSet(LightKDFFlag.Name) { + cfg.UseLightweightKDF = ctx.Bool(LightKDFFlag.Name) } - if ctx.GlobalIsSet(NoUSBFlag.Name) || cfg.NoUSB { + if ctx.IsSet(NoUSBFlag.Name) || cfg.NoUSB { log.Warn("Option nousb is deprecated and USB is deactivated by default. Use --usb to enable") } - if ctx.GlobalIsSet(USBFlag.Name) { - cfg.USB = ctx.GlobalBool(USBFlag.Name) + if ctx.IsSet(USBFlag.Name) { + cfg.USB = ctx.Bool(USBFlag.Name) } - if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { - cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) + if ctx.IsSet(InsecureUnlockAllowedFlag.Name) { + cfg.InsecureUnlockAllowed = ctx.Bool(InsecureUnlockAllowedFlag.Name) } // Quorum - if ctx.GlobalIsSet(EnableNodePermissionFlag.Name) { - cfg.EnableNodePermission = ctx.GlobalBool(EnableNodePermissionFlag.Name) + if ctx.IsSet(EnableNodePermissionFlag.Name) { + cfg.EnableNodePermission = ctx.Bool(EnableNodePermissionFlag.Name) } - if ctx.GlobalIsSet(MultitenancyFlag.Name) { - cfg.EnableMultitenancy = ctx.GlobalBool(MultitenancyFlag.Name) + if ctx.IsSet(MultitenancyFlag.Name) { + cfg.EnableMultitenancy = ctx.Bool(MultitenancyFlag.Name) } } func setSmartCard(ctx *cli.Context, cfg *node.Config) { // Skip enabling smartcards if no path is set - path := ctx.GlobalString(SmartCardDaemonPathFlag.Name) + path := ctx.String(SmartCardDaemonPathFlag.Name) if path == "" { return } @@ -1554,11 +1701,11 @@ func setSmartCard(ctx *cli.Context, cfg *node.Config) { func setDataDir(ctx *cli.Context, cfg *node.Config) { switch { - case ctx.GlobalIsSet(DataDirFlag.Name): - cfg.DataDir = ctx.GlobalString(DataDirFlag.Name) - case ctx.GlobalBool(DeveloperFlag.Name): + case ctx.IsSet(DataDirFlag.Name): + cfg.DataDir = ctx.String(DataDirFlag.Name) + case ctx.Bool(DeveloperFlag.Name): cfg.DataDir = "" // unless explicitly requested, use memory databases - case ctx.GlobalBool(RopstenFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + case ctx.Bool(RopstenFlag.Name) && cfg.DataDir == node.DefaultDataDir(): // Maintain compatibility with older Geth configurations storing the // Ropsten database in `testnet` instead of `ropsten`. legacyPath := filepath.Join(node.DefaultDataDir(), "testnet") @@ -1570,11 +1717,11 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) { } cfg.DataDir = filepath.Join(node.DefaultDataDir(), "ropsten") - case ctx.GlobalBool(RinkebyFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + case ctx.Bool(RinkebyFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby") - case ctx.GlobalBool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + case ctx.Bool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli") - case ctx.GlobalBool(YoloV3Flag.Name) && cfg.DataDir == node.DefaultDataDir(): + case ctx.Bool(YoloV3Flag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "yolo-v3") } if err := SetPlugins(ctx, cfg); err != nil { @@ -1583,8 +1730,8 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) { } func setRaftLogDir(ctx *cli.Context, cfg *node.Config) { - if ctx.GlobalIsSet(RaftLogDirFlag.Name) { - cfg.RaftLogDir = ctx.GlobalString(RaftLogDirFlag.Name) + if ctx.IsSet(RaftLogDirFlag.Name) { + cfg.RaftLogDir = ctx.String(RaftLogDirFlag.Name) } else { cfg.RaftLogDir = cfg.DataDir } @@ -1594,15 +1741,15 @@ func setRaftLogDir(ctx *cli.Context, cfg *node.Config) { // // Read plugin settings from --plugins flag. Overwrite settings defined in --config if any func SetPlugins(ctx *cli.Context, cfg *node.Config) error { - if ctx.GlobalIsSet(PluginSettingsFlag.Name) { + if ctx.IsSet(PluginSettingsFlag.Name) { // validate flag combination - if ctx.GlobalBool(PluginSkipVerifyFlag.Name) && ctx.GlobalBool(PluginLocalVerifyFlag.Name) { + if ctx.Bool(PluginSkipVerifyFlag.Name) && ctx.Bool(PluginLocalVerifyFlag.Name) { return fmt.Errorf("only --%s or --%s must be set", PluginSkipVerifyFlag.Name, PluginLocalVerifyFlag.Name) } - if !ctx.GlobalBool(PluginLocalVerifyFlag.Name) && ctx.GlobalIsSet(PluginPublicKeyFlag.Name) { + if !ctx.Bool(PluginLocalVerifyFlag.Name) && ctx.IsSet(PluginPublicKeyFlag.Name) { return fmt.Errorf("--%s is required for setting --%s", PluginLocalVerifyFlag.Name, PluginPublicKeyFlag.Name) } - pluginSettingsURL, err := url.Parse(ctx.GlobalString(PluginSettingsFlag.Name)) + pluginSettingsURL, err := url.Parse(ctx.String(PluginSettingsFlag.Name)) if err != nil { return fmt.Errorf("plugins: Invalid URL for --%s due to %s", PluginSettingsFlag.Name, err) } @@ -1639,20 +1786,20 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { cfg.Blocks = ethconfig.LightClientGPO.Blocks cfg.Percentile = ethconfig.LightClientGPO.Percentile } - if ctx.GlobalIsSet(GpoBlocksFlag.Name) { - cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name) + if ctx.IsSet(GpoBlocksFlag.Name) { + cfg.Blocks = ctx.Int(GpoBlocksFlag.Name) } - if ctx.GlobalIsSet(GpoPercentileFlag.Name) { - cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name) + if ctx.IsSet(GpoPercentileFlag.Name) { + cfg.Percentile = ctx.Int(GpoPercentileFlag.Name) } - if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) { - cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name)) + if ctx.IsSet(GpoMaxGasPriceFlag.Name) { + cfg.MaxPrice = big.NewInt(ctx.Int64(GpoMaxGasPriceFlag.Name)) } } func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { - if ctx.GlobalIsSet(TxPoolLocalsFlag.Name) { - locals := strings.Split(ctx.GlobalString(TxPoolLocalsFlag.Name), ",") + if ctx.IsSet(TxPoolLocalsFlag.Name) { + locals := strings.Split(ctx.String(TxPoolLocalsFlag.Name), ",") for _, account := range locals { if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) { Fatalf("Invalid account in --txpool.locals: %s", trimmed) @@ -1661,66 +1808,66 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { } } } - if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) { - cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name) + if ctx.IsSet(TxPoolNoLocalsFlag.Name) { + cfg.NoLocals = ctx.Bool(TxPoolNoLocalsFlag.Name) } - if ctx.GlobalIsSet(TxPoolJournalFlag.Name) { - cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name) + if ctx.IsSet(TxPoolJournalFlag.Name) { + cfg.Journal = ctx.String(TxPoolJournalFlag.Name) } - if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) { - cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name) + if ctx.IsSet(TxPoolRejournalFlag.Name) { + cfg.Rejournal = ctx.Duration(TxPoolRejournalFlag.Name) } - if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) { - cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name) + if ctx.IsSet(TxPoolPriceLimitFlag.Name) { + cfg.PriceLimit = ctx.Uint64(TxPoolPriceLimitFlag.Name) } - if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) { - cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name) + if ctx.IsSet(TxPoolPriceBumpFlag.Name) { + cfg.PriceBump = ctx.Uint64(TxPoolPriceBumpFlag.Name) } - if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) { - cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name) + if ctx.IsSet(TxPoolAccountSlotsFlag.Name) { + cfg.AccountSlots = ctx.Uint64(TxPoolAccountSlotsFlag.Name) } - if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) { - cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name) + if ctx.IsSet(TxPoolGlobalSlotsFlag.Name) { + cfg.GlobalSlots = ctx.Uint64(TxPoolGlobalSlotsFlag.Name) } - if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) { - cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name) + if ctx.IsSet(TxPoolAccountQueueFlag.Name) { + cfg.AccountQueue = ctx.Uint64(TxPoolAccountQueueFlag.Name) } - if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) { - cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name) + if ctx.IsSet(TxPoolGlobalQueueFlag.Name) { + cfg.GlobalQueue = ctx.Uint64(TxPoolGlobalQueueFlag.Name) } - if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) { - cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name) + if ctx.IsSet(TxPoolLifetimeFlag.Name) { + cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name) } } func setMiner(ctx *cli.Context, cfg *miner.Config) { - if ctx.GlobalIsSet(MinerExtraDataFlag.Name) { - cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name)) + if ctx.IsSet(MinerExtraDataFlag.Name) { + cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name)) } - if ctx.GlobalIsSet(MinerGasTargetFlag.Name) { - cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name) + if ctx.IsSet(MinerGasTargetFlag.Name) { + cfg.GasFloor = ctx.Uint64(MinerGasTargetFlag.Name) } - if ctx.GlobalIsSet(MinerGasLimitFlag.Name) { - cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name) + if ctx.IsSet(MinerGasLimitFlag.Name) { + cfg.GasCeil = ctx.Uint64(MinerGasLimitFlag.Name) } - if ctx.GlobalIsSet(MinerGasPriceFlag.Name) { - cfg.GasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name) + if ctx.IsSet(MinerGasPriceFlag.Name) { + cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name) } - if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) { - cfg.Recommit = ctx.GlobalDuration(MinerRecommitIntervalFlag.Name) + if ctx.IsSet(MinerRecommitIntervalFlag.Name) { + cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) } - if ctx.GlobalIsSet(MinerNewPayloadTimeout.Name) { + if ctx.IsSet(MinerNewPayloadTimeout.Name) { cfg.NewPayloadTimeout = ctx.Duration(MinerNewPayloadTimeout.Name) } - if ctx.GlobalIsSet(AllowedFutureBlockTimeFlag.Name) { - cfg.AllowedFutureBlockTime = ctx.GlobalUint64(AllowedFutureBlockTimeFlag.Name) //Quorum + if ctx.IsSet(AllowedFutureBlockTimeFlag.Name) { + cfg.AllowedFutureBlockTime = ctx.Uint64(AllowedFutureBlockTimeFlag.Name) //Quorum } } func setAuthorizationList(ctx *cli.Context, cfg *ethconfig.Config) { - authorizationList := ctx.GlobalString(AuthorizationListFlag.Name) + authorizationList := ctx.String(AuthorizationListFlag.Name) if authorizationList == "" { - authorizationList = ctx.GlobalString(DeprecatedAuthorizationListFlag.Name) + authorizationList = ctx.String(DeprecatedAuthorizationListFlag.Name) if authorizationList != "" { log.Warn("The flag --whitelist is deprecated and will be removed in the future, please use --authorizationlist") } @@ -1748,25 +1895,25 @@ func setAuthorizationList(ctx *cli.Context, cfg *ethconfig.Config) { // Quorum func setIstanbul(ctx *cli.Context, cfg *eth.Config) { - if ctx.GlobalIsSet(IstanbulRequestTimeoutFlag.Name) { + if ctx.IsSet(IstanbulRequestTimeoutFlag.Name) { log.Warn("WARNING: The flag --istanbul.requesttimeout is deprecated and will be removed in the future, please use ibft.requesttimeoutseconds on genesis file") - cfg.Istanbul.RequestTimeout = ctx.GlobalUint64(IstanbulRequestTimeoutFlag.Name) + cfg.Istanbul.RequestTimeout = ctx.Uint64(IstanbulRequestTimeoutFlag.Name) } - if ctx.GlobalIsSet(IstanbulBlockPeriodFlag.Name) { + if ctx.IsSet(IstanbulBlockPeriodFlag.Name) { log.Warn("WARNING: The flag --istanbul.blockperiod is deprecated and will be removed in the future, please use ibft.blockperiodseconds on genesis file") - cfg.Istanbul.BlockPeriod = ctx.GlobalUint64(IstanbulBlockPeriodFlag.Name) + cfg.Istanbul.BlockPeriod = ctx.Uint64(IstanbulBlockPeriodFlag.Name) } } func setRaft(ctx *cli.Context, cfg *eth.Config) { - cfg.RaftMode = ctx.GlobalBool(RaftModeFlag.Name) + cfg.RaftMode = ctx.Bool(RaftModeFlag.Name) } func setQuorumConfig(ctx *cli.Context, cfg *eth.Config) error { - cfg.EVMCallTimeOut = time.Duration(ctx.GlobalInt(EVMCallTimeOutFlag.Name)) * time.Second - cfg.QuorumChainConfig = core.NewQuorumChainConfig(ctx.GlobalBool(MultitenancyFlag.Name), - ctx.GlobalBool(RevertReasonFlag.Name), ctx.GlobalBool(QuorumEnablePrivacyMarker.Name), - ctx.GlobalBool(QuorumEnablePrivateTrieCache.Name)) + cfg.EVMCallTimeOut = time.Duration(ctx.Int(EVMCallTimeOutFlag.Name)) * time.Second + cfg.QuorumChainConfig = core.NewQuorumChainConfig(ctx.Bool(MultitenancyFlag.Name), + ctx.Bool(RevertReasonFlag.Name), ctx.Bool(QuorumEnablePrivacyMarker.Name), + ctx.Bool(QuorumEnablePrivateTrieCache.Name)) setIstanbul(ctx, cfg) setRaft(ctx, cfg) return nil @@ -1784,13 +1931,13 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i])) } // Check if next arg extends current and expand its name if so - name := flag.GetName() + name := flag.Names()[0] if i+1 < len(args) { switch option := args[i+1].(type) { case string: // Extended flag check, make sure value set doesn't conflict with passed in option - if ctx.GlobalString(flag.GetName()) == option { + if ctx.String(flag.Names()[0]) == option { name += "=" + option set = append(set, "--"+name) } @@ -1804,7 +1951,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { } } // Mark the flag if it's set - if ctx.GlobalIsSet(flag.GetName()) { + if ctx.IsSet(flag.Names()[0]) { set = append(set, "--"+name) } } @@ -1814,8 +1961,8 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { } func SetQLightConfig(ctx *cli.Context, nodeCfg *node.Config, ethCfg *ethconfig.Config) { - if ctx.GlobalIsSet(QuorumLightServerFlag.Name) { - ethCfg.QuorumLightServer = ctx.GlobalBool(QuorumLightServerFlag.Name) + if ctx.IsSet(QuorumLightServerFlag.Name) { + ethCfg.QuorumLightServer = ctx.Bool(QuorumLightServerFlag.Name) } if ethCfg.QuorumLightServer { @@ -1834,68 +1981,68 @@ func SetQLightConfig(ctx *cli.Context, nodeCfg *node.Config, ethCfg *ethconfig.C } ethCfg.QuorumLightClient = ðconfig.QuorumLightClient{} - if ctx.GlobalIsSet(QuorumLightClientFlag.Name) { - ethCfg.QuorumLightClient.Use = ctx.GlobalBool(QuorumLightClientFlag.Name) + if ctx.IsSet(QuorumLightClientFlag.Name) { + ethCfg.QuorumLightClient.Use = ctx.Bool(QuorumLightClientFlag.Name) } if len(ethCfg.QuorumLightClient.PSI) == 0 { ethCfg.QuorumLightClient.PSI = "private" } - if ctx.GlobalIsSet(QuorumLightClientPSIFlag.Name) { - ethCfg.QuorumLightClient.PSI = ctx.GlobalString(QuorumLightClientPSIFlag.Name) + if ctx.IsSet(QuorumLightClientPSIFlag.Name) { + ethCfg.QuorumLightClient.PSI = ctx.String(QuorumLightClientPSIFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientTokenEnabledFlag.Name) { - ethCfg.QuorumLightClient.TokenEnabled = ctx.GlobalBool(QuorumLightClientTokenEnabledFlag.Name) + if ctx.IsSet(QuorumLightClientTokenEnabledFlag.Name) { + ethCfg.QuorumLightClient.TokenEnabled = ctx.Bool(QuorumLightClientTokenEnabledFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientTokenValueFlag.Name) { - ethCfg.QuorumLightClient.TokenValue = ctx.GlobalString(QuorumLightClientTokenValueFlag.Name) + if ctx.IsSet(QuorumLightClientTokenValueFlag.Name) { + ethCfg.QuorumLightClient.TokenValue = ctx.String(QuorumLightClientTokenValueFlag.Name) } if len(ethCfg.QuorumLightClient.TokenManagement) == 0 { ethCfg.QuorumLightClient.TokenManagement = "client-security-plugin" } - if ctx.GlobalIsSet(QuorumLightClientTokenManagementFlag.Name) { - ethCfg.QuorumLightClient.TokenManagement = ctx.GlobalString(QuorumLightClientTokenManagementFlag.Name) + if ctx.IsSet(QuorumLightClientTokenManagementFlag.Name) { + ethCfg.QuorumLightClient.TokenManagement = ctx.String(QuorumLightClientTokenManagementFlag.Name) } if !isValidTokenManagement(ethCfg.QuorumLightClient.TokenManagement) { Fatalf("Invalid value specified '%s' for flag '%s'.", ethCfg.QuorumLightClient.TokenManagement, QuorumLightClientTokenManagementFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientRPCTLSFlag.Name) { - ethCfg.QuorumLightClient.RPCTLS = ctx.GlobalBool(QuorumLightClientRPCTLSFlag.Name) + if ctx.IsSet(QuorumLightClientRPCTLSFlag.Name) { + ethCfg.QuorumLightClient.RPCTLS = ctx.Bool(QuorumLightClientRPCTLSFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientRPCTLSCACertFlag.Name) { - ethCfg.QuorumLightClient.RPCTLSCACert = ctx.GlobalString(QuorumLightClientRPCTLSCACertFlag.Name) + if ctx.IsSet(QuorumLightClientRPCTLSCACertFlag.Name) { + ethCfg.QuorumLightClient.RPCTLSCACert = ctx.String(QuorumLightClientRPCTLSCACertFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientRPCTLSInsecureSkipVerifyFlag.Name) { - ethCfg.QuorumLightClient.RPCTLSInsecureSkipVerify = ctx.GlobalBool(QuorumLightClientRPCTLSInsecureSkipVerifyFlag.Name) + if ctx.IsSet(QuorumLightClientRPCTLSInsecureSkipVerifyFlag.Name) { + ethCfg.QuorumLightClient.RPCTLSInsecureSkipVerify = ctx.Bool(QuorumLightClientRPCTLSInsecureSkipVerifyFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientRPCTLSCertFlag.Name) && ctx.GlobalIsSet(QuorumLightClientRPCTLSKeyFlag.Name) { - ethCfg.QuorumLightClient.RPCTLSCert = ctx.GlobalString(QuorumLightClientRPCTLSCertFlag.Name) - ethCfg.QuorumLightClient.RPCTLSKey = ctx.GlobalString(QuorumLightClientRPCTLSKeyFlag.Name) - } else if ctx.GlobalIsSet(QuorumLightClientRPCTLSCertFlag.Name) { + if ctx.IsSet(QuorumLightClientRPCTLSCertFlag.Name) && ctx.IsSet(QuorumLightClientRPCTLSKeyFlag.Name) { + ethCfg.QuorumLightClient.RPCTLSCert = ctx.String(QuorumLightClientRPCTLSCertFlag.Name) + ethCfg.QuorumLightClient.RPCTLSKey = ctx.String(QuorumLightClientRPCTLSKeyFlag.Name) + } else if ctx.IsSet(QuorumLightClientRPCTLSCertFlag.Name) { Fatalf("'%s' specified without specifying '%s'", QuorumLightClientRPCTLSCertFlag.Name, QuorumLightClientRPCTLSKeyFlag.Name) - } else if ctx.GlobalIsSet(QuorumLightClientRPCTLSKeyFlag.Name) { + } else if ctx.IsSet(QuorumLightClientRPCTLSKeyFlag.Name) { Fatalf("'%s' specified without specifying '%s'", QuorumLightClientRPCTLSKeyFlag.Name, QuorumLightClientRPCTLSCertFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientServerNodeRPCFlag.Name) { - ethCfg.QuorumLightClient.ServerNodeRPC = ctx.GlobalString(QuorumLightClientServerNodeRPCFlag.Name) + if ctx.IsSet(QuorumLightClientServerNodeRPCFlag.Name) { + ethCfg.QuorumLightClient.ServerNodeRPC = ctx.String(QuorumLightClientServerNodeRPCFlag.Name) } - if ctx.GlobalIsSet(QuorumLightClientServerNodeFlag.Name) { - ethCfg.QuorumLightClient.ServerNode = ctx.GlobalString(QuorumLightClientServerNodeFlag.Name) + if ctx.IsSet(QuorumLightClientServerNodeFlag.Name) { + ethCfg.QuorumLightClient.ServerNode = ctx.String(QuorumLightClientServerNodeFlag.Name) // This is already done in geth/config - before the node.New invocation (at which point the StaticNodes is already copied) //stack.Config().P2P.StaticNodes = []*enode.Node{enode.MustParse(ethCfg.QuorumLightClientServerNode)} } if ethCfg.QuorumLightClient.Enabled() { - if ctx.GlobalBool(MiningEnabledFlag.Name) { + if ctx.Bool(MiningEnabledFlag.Name) { Fatalf("QLight clients do not support mining") } if len(ethCfg.QuorumLightClient.ServerNode) == 0 { @@ -1919,11 +2066,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV3Flag) CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light") CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer - if ctx.GlobalString(GCModeFlag.Name) == "archive" && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 { - ctx.GlobalSet(TxLookupLimitFlag.Name, "0") + if ctx.String(GCModeFlag.Name) == "archive" && ctx.Uint64(TxLookupLimitFlag.Name) != 0 { + ctx.Set(TxLookupLimitFlag.Name, "0") log.Warn("Disable transaction unindexing for archive node") } - if ctx.GlobalIsSet(LightServeFlag.Name) && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 { + if ctx.IsSet(LightServeFlag.Name) && ctx.Uint64(TxLookupLimitFlag.Name) != 0 { log.Warn("LES server cannot serve old transaction status and cannot connect below les/4 protocol version if transaction lookup index is limited") } var ks *keystore.KeyStore @@ -1931,7 +2078,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { ks = keystores[0].(*keystore.KeyStore) } setEtherbase(ctx, ks, cfg) - setGPO(ctx, &cfg.GPO, ctx.GlobalString(SyncModeFlag.Name) == "light") + setGPO(ctx, &cfg.GPO, ctx.String(SyncModeFlag.Name) == "light") setTxPool(ctx, &cfg.TxPool) setMiner(ctx, &cfg.Miner) setAuthorizationList(ctx, cfg) @@ -1945,13 +2092,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { mem.Total = 2 * 1024 * 1024 * 1024 } allowance := int(mem.Total / 1024 / 1024 / 3) - if cache := ctx.GlobalInt(CacheFlag.Name); cache > allowance { + if cache := ctx.Int(CacheFlag.Name); cache > allowance { log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) - ctx.GlobalSet(CacheFlag.Name, strconv.Itoa(allowance)) + ctx.Set(CacheFlag.Name, strconv.Itoa(allowance)) } } // Ensure Go's GC ignores the database cache for trigger percentage - cache := ctx.GlobalInt(CacheFlag.Name) + cache := ctx.Int(CacheFlag.Name) gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) @@ -1963,8 +2110,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { Fatalf("Quorum configuration has an error: %v", err) } - if ctx.GlobalIsSet(SyncModeFlag.Name) { - cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) + if ctx.IsSet(SyncModeFlag.Name) { + cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) } // Quorum @@ -1976,51 +2123,51 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } // End Quorum - if ctx.GlobalIsSet(NetworkIdFlag.Name) { - cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name) + if ctx.IsSet(NetworkIdFlag.Name) { + cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name) } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { - cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheDatabaseFlag.Name) { + cfg.DatabaseCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100 } cfg.DatabaseHandles = MakeDatabaseHandles() - if ctx.GlobalIsSet(AncientFlag.Name) { - cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name) + if ctx.IsSet(AncientFlag.Name) { + cfg.DatabaseFreezer = ctx.String(AncientFlag.Name) } - if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { + if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) } - if ctx.GlobalIsSet(GCModeFlag.Name) { - cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive" + if ctx.IsSet(GCModeFlag.Name) { + cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive" } - if ctx.GlobalIsSet(CacheNoPrefetchFlag.Name) { - cfg.NoPrefetch = ctx.GlobalBool(CacheNoPrefetchFlag.Name) + if ctx.IsSet(CacheNoPrefetchFlag.Name) { + cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name) } // Read the value from the flag no matter if it's set or not. - cfg.Preimages = ctx.GlobalBool(CachePreimagesFlag.Name) + cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name) if true || cfg.NoPruning && !cfg.Preimages { // TODO: Quorum; force preimages for contract extension and dump of states compatibility, until a fix is found cfg.Preimages = true log.Info("Enabling recording of key preimages since archive mode is used") } - if ctx.GlobalIsSet(TxLookupLimitFlag.Name) { - cfg.TxLookupLimit = ctx.GlobalUint64(TxLookupLimitFlag.Name) + if ctx.IsSet(TxLookupLimitFlag.Name) { + cfg.TxLookupLimit = ctx.Uint64(TxLookupLimitFlag.Name) } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) { - cfg.TrieCleanCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) { + cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100 } - if ctx.GlobalIsSet(CacheTrieJournalFlag.Name) { - cfg.TrieCleanCacheJournal = ctx.GlobalString(CacheTrieJournalFlag.Name) + if ctx.IsSet(CacheTrieJournalFlag.Name) { + cfg.TrieCleanCacheJournal = ctx.String(CacheTrieJournalFlag.Name) } - if ctx.GlobalIsSet(CacheTrieRejournalFlag.Name) { - cfg.TrieCleanCacheRejournal = ctx.GlobalDuration(CacheTrieRejournalFlag.Name) + if ctx.IsSet(CacheTrieRejournalFlag.Name) { + cfg.TrieCleanCacheRejournal = ctx.Duration(CacheTrieRejournalFlag.Name) } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { - cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) { + cfg.TrieDirtyCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100 } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheSnapshotFlag.Name) { - cfg.SnapshotCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheSnapshotFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) { + cfg.SnapshotCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100 } - if !ctx.GlobalBool(SnapshotFlag.Name) { + if !ctx.Bool(SnapshotFlag.Name) { // If snap-sync is requested, this flag is also required if cfg.SyncMode == downloader.SnapSync { log.Info("Snap sync requested, enabling --snapshot") @@ -2029,36 +2176,36 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.SnapshotCache = 0 // Disabled } } - if ctx.GlobalIsSet(DocRootFlag.Name) { - cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name) + if ctx.IsSet(DocRootFlag.Name) { + cfg.DocRoot = ctx.String(DocRootFlag.Name) } - if ctx.GlobalIsSet(VMEnableDebugFlag.Name) { + if ctx.IsSet(VMEnableDebugFlag.Name) { // TODO(fjl): force-enable this in --dev mode - cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) + cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name) } - if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) { - cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name) + if ctx.IsSet(EWASMInterpreterFlag.Name) { + cfg.EWASMInterpreter = ctx.String(EWASMInterpreterFlag.Name) } - if ctx.GlobalIsSet(EVMInterpreterFlag.Name) { - cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name) + if ctx.IsSet(EVMInterpreterFlag.Name) { + cfg.EVMInterpreter = ctx.String(EVMInterpreterFlag.Name) } - if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) { - cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name) + if ctx.IsSet(RPCGlobalGasCapFlag.Name) { + cfg.RPCGasCap = ctx.Uint64(RPCGlobalGasCapFlag.Name) } if cfg.RPCGasCap != 0 { log.Info("Set global gas cap", "cap", cfg.RPCGasCap) } else { log.Info("Global gas cap disabled") } - if ctx.GlobalIsSet(RPCGlobalTxFeeCapFlag.Name) { - cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) + if ctx.IsSet(RPCGlobalTxFeeCapFlag.Name) { + cfg.RPCTxFeeCap = ctx.Float64(RPCGlobalTxFeeCapFlag.Name) } - if ctx.GlobalIsSet(NoDiscoverFlag.Name) { + if ctx.IsSet(NoDiscoverFlag.Name) { cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs = []string{}, []string{} - } else if ctx.GlobalIsSet(DNSDiscoveryFlag.Name) { - urls := ctx.GlobalString(DNSDiscoveryFlag.Name) + } else if ctx.IsSet(DNSDiscoveryFlag.Name) { + urls := ctx.String(DNSDiscoveryFlag.Name) if urls == "" { cfg.EthDiscoveryURLs = []string{} } else { @@ -2067,41 +2214,41 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } // set immutability threshold in config - params.SetQuorumImmutabilityThreshold(ctx.GlobalInt(QuorumImmutabilityThreshold.Name)) + params.SetQuorumImmutabilityThreshold(ctx.Int(QuorumImmutabilityThreshold.Name)) // Override any default configs for hard coded networks. switch { - case ctx.GlobalBool(MainnetFlag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(MainnetFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 1 } cfg.Genesis = core.DefaultGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) - case ctx.GlobalBool(RopstenFlag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(RopstenFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 3 } cfg.Genesis = core.DefaultRopstenGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.RopstenGenesisHash) - case ctx.GlobalBool(RinkebyFlag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(RinkebyFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 4 } cfg.Genesis = core.DefaultRinkebyGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.RinkebyGenesisHash) - case ctx.GlobalBool(GoerliFlag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(GoerliFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 5 } cfg.Genesis = core.DefaultGoerliGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash) - case ctx.GlobalBool(YoloV3Flag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(YoloV3Flag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = new(big.Int).SetBytes([]byte("yolov3x")).Uint64() // "yolov3x" } cfg.Genesis = core.DefaultYoloV3GenesisBlock() - case ctx.GlobalBool(DeveloperFlag.Name): - if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + case ctx.Bool(DeveloperFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 1337 } // Create new developer account or reuse existing one @@ -2133,8 +2280,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { log.Info("Using developer account", "address", developer.Address) // Create a new developer genesis block or reuse existing one - cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address) - if ctx.GlobalIsSet(DataDirFlag.Name) { + cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.Int(DeveloperPeriodFlag.Name)), developer.Address) + if ctx.IsSet(DataDirFlag.Name) { // Check if we have an already initialized chain and fall back to // that if so. Otherwise we need to generate a new genesis spec. chaindb := MakeChainDatabase(ctx, stack, true) @@ -2143,7 +2290,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } chaindb.Close() } - if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) { + if !ctx.IsSet(MinerGasPriceFlag.Name) { cfg.Miner.GasPrice = big.NewInt(1) } default: @@ -2253,11 +2400,11 @@ func RegisterPermissionService(stack *node.Node, useDns bool, chainID *big.Int) } func RegisterRaftService(stack *node.Node, ctx *cli.Context, nodeCfg *node.Config, ethService *eth.Ethereum) { - blockTimeMillis := ctx.GlobalInt(RaftBlockTimeFlag.Name) + blockTimeMillis := ctx.Int(RaftBlockTimeFlag.Name) raftLogDir := nodeCfg.RaftLogDir // default value is set either 'datadir' or 'raftlogdir' - joinExistingId := ctx.GlobalInt(RaftJoinExistingFlag.Name) - useDns := ctx.GlobalBool(RaftDNSEnabledFlag.Name) - raftPort := uint16(ctx.GlobalInt(RaftPortFlag.Name)) + joinExistingId := ctx.Int(RaftJoinExistingFlag.Name) + useDns := ctx.Bool(RaftDNSEnabledFlag.Name) + raftPort := uint16(ctx.Int(RaftPortFlag.Name)) privkey := nodeCfg.NodeKey() strId := enode.PubkeyToIDV4(&privkey.PublicKey).String() @@ -2314,23 +2461,23 @@ func SetupMetrics(ctx *cli.Context) { log.Info("Enabling metrics collection") var ( - enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name) - endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name) - database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name) - username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name) - password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name) + enableExport = ctx.Bool(MetricsEnableInfluxDBFlag.Name) + endpoint = ctx.String(MetricsInfluxDBEndpointFlag.Name) + database = ctx.String(MetricsInfluxDBDatabaseFlag.Name) + username = ctx.String(MetricsInfluxDBUsernameFlag.Name) + password = ctx.String(MetricsInfluxDBPasswordFlag.Name) ) if enableExport { - tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name)) + tagsMap := SplitTagsFlag(ctx.String(MetricsInfluxDBTagsFlag.Name)) log.Info("Enabling metrics export to InfluxDB") go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) } - if ctx.GlobalIsSet(MetricsHTTPFlag.Name) { - address := fmt.Sprintf("%s:%d", ctx.GlobalString(MetricsHTTPFlag.Name), ctx.GlobalInt(MetricsPortFlag.Name)) + if ctx.IsSet(MetricsHTTPFlag.Name) { + address := fmt.Sprintf("%s:%d", ctx.String(MetricsHTTPFlag.Name), ctx.Int(MetricsPortFlag.Name)) log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address) exp.Setup(address) } @@ -2357,18 +2504,18 @@ func SplitTagsFlag(tagsFlag string) map[string]string { // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database { var ( - cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 + cache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100 handles = MakeDatabaseHandles() err error chainDb ethdb.Database ) - if ctx.GlobalString(SyncModeFlag.Name) == "light" { + if ctx.String(SyncModeFlag.Name) == "light" { name := "lightchaindata" chainDb, err = stack.OpenDatabase(name, cache, handles, "", readonly) } else { name := "chaindata" - chainDb, err = stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "", readonly) + chainDb, err = stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.String(AncientFlag.Name), "", readonly) } if err != nil { Fatalf("Could not open database: %v", err) @@ -2379,17 +2526,17 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. func MakeGenesis(ctx *cli.Context) *core.Genesis { var genesis *core.Genesis switch { - case ctx.GlobalBool(MainnetFlag.Name): + case ctx.Bool(MainnetFlag.Name): genesis = core.DefaultGenesisBlock() - case ctx.GlobalBool(RopstenFlag.Name): + case ctx.Bool(RopstenFlag.Name): genesis = core.DefaultRopstenGenesisBlock() - case ctx.GlobalBool(RinkebyFlag.Name): + case ctx.Bool(RinkebyFlag.Name): genesis = core.DefaultRinkebyGenesisBlock() - case ctx.GlobalBool(GoerliFlag.Name): + case ctx.Bool(GoerliFlag.Name): genesis = core.DefaultGoerliGenesisBlock() - case ctx.GlobalBool(YoloV3Flag.Name): + case ctx.Bool(YoloV3Flag.Name): genesis = core.DefaultYoloV3GenesisBlock() - case ctx.GlobalBool(DeveloperFlag.Name): + case ctx.Bool(DeveloperFlag.Name): Fatalf("Developer chains are ephemeral") } return genesis @@ -2469,37 +2616,37 @@ func MakeChain(ctx *cli.Context, stack *node.Node, useExist bool) (chain *core.B engine = ethash.NewFaker() } - if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { + if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) } cache := &core.CacheConfig{ TrieCleanLimit: ethconfig.Defaults.TrieCleanCache, - TrieCleanNoPrefetch: ctx.GlobalBool(CacheNoPrefetchFlag.Name), + TrieCleanNoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name), TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache, - TrieDirtyDisabled: ctx.GlobalString(GCModeFlag.Name) == "archive", + TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == "archive", TrieTimeLimit: ethconfig.Defaults.TrieTimeout, SnapshotLimit: ethconfig.Defaults.SnapshotCache, - Preimages: ctx.GlobalBool(CachePreimagesFlag.Name), + Preimages: ctx.Bool(CachePreimagesFlag.Name), } if true || cache.TrieDirtyDisabled && !cache.Preimages { // TODO: Quorum; force preimages for contract extension and dump of states compatibility, until a fix is found cache.Preimages = true log.Info("Enabling recording of key preimages since archive mode is used") } - if !ctx.GlobalBool(SnapshotFlag.Name) { + if !ctx.Bool(SnapshotFlag.Name) { cache.SnapshotLimit = 0 // Disabled } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) { - cache.TrieCleanLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) { + cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100 } - if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { - cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 + if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) { + cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100 } - vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)} + vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)} // Quorum var limit *uint64 - if ctx.GlobalIsSet(TxLookupLimitFlag.Name) { - l := ctx.GlobalUint64(TxLookupLimitFlag.Name) + if ctx.IsSet(TxLookupLimitFlag.Name) { + l := ctx.Uint64(TxLookupLimitFlag.Name) limit = &l } // End Quorum @@ -2541,42 +2688,18 @@ func setBFTConfig(bftConfig *params.BFTConfig) *istanbul.Config { // scripts to preload before starting. func MakeConsolePreloads(ctx *cli.Context) []string { // Skip preloading if there's nothing to preload - if ctx.GlobalString(PreloadJSFlag.Name) == "" { + if ctx.String(PreloadJSFlag.Name) == "" { return nil } // Otherwise resolve absolute paths and return them var preloads []string - for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") { + for _, file := range strings.Split(ctx.String(PreloadJSFlag.Name), ",") { preloads = append(preloads, strings.TrimSpace(file)) } return preloads } -// MigrateFlags sets the global flag from a local flag when it's set. -// This is a temporary function used for migrating old command/flags to the -// new format. -// -// e.g. geth account new --keystore /tmp/mykeystore --lightkdf -// -// is equivalent after calling this method with: -// -// geth --keystore /tmp/mykeystore --lightkdf account new -// -// This allows the use of the existing configuration functionality. -// When all flags are migrated this function can be removed and the existing -// configuration functionality must be changed that is uses local flags -func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error { - return func(ctx *cli.Context) error { - for _, name := range ctx.FlagNames() { - if ctx.IsSet(name) { - ctx.GlobalSet(name, ctx.String(name)) - } - } - return action(ctx) - } -} - func isValidTokenManagement(value string) bool { switch value { case diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index 050f760dd..bbdb7ba29 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -21,15 +21,14 @@ import ( "strings" "github.com/ethereum/go-ethereum/node" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var ShowDeprecated = cli.Command{ +var ShowDeprecated = &cli.Command{ Action: showDeprecated, Name: "show-deprecated-flags", Usage: "Show flags that have been deprecated", ArgsUsage: " ", - Category: "MISCELLANEOUS COMMANDS", Description: "Show flags that have been deprecated and will soon be removed", } @@ -37,31 +36,31 @@ var DeprecatedFlags = []cli.Flag{} var ( // (Deprecated May 2020, shown in aliased flags section) - LegacyRPCEnabledFlag = cli.BoolFlag{ + LegacyRPCEnabledFlag = &cli.BoolFlag{ Name: "rpc", Usage: "Enable the HTTP-RPC server (deprecated and will be removed in the future, use --http)", } - LegacyRPCListenAddrFlag = cli.StringFlag{ + LegacyRPCListenAddrFlag = &cli.StringFlag{ Name: "rpcaddr", Usage: "HTTP-RPC server listening interface (deprecated and will be removed in the future, use --http.addr)", Value: node.DefaultHTTPHost, } - LegacyRPCPortFlag = cli.IntFlag{ + LegacyRPCPortFlag = &cli.IntFlag{ Name: "rpcport", Usage: "HTTP-RPC server listening port (deprecated and will be removed in the future, use --http.port)", Value: node.DefaultHTTPPort, } - LegacyRPCCORSDomainFlag = cli.StringFlag{ + LegacyRPCCORSDomainFlag = &cli.StringFlag{ Name: "rpccorsdomain", Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced) (deprecated and will be removed in the future, use --http.corsdomain)", Value: "", } - LegacyRPCVirtualHostsFlag = cli.StringFlag{ + LegacyRPCVirtualHostsFlag = &cli.StringFlag{ Name: "rpcvhosts", Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. (deprecated and will be removed in the future, use --http.vhosts)", Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","), } - LegacyRPCApiFlag = cli.StringFlag{ + LegacyRPCApiFlag = &cli.StringFlag{ Name: "rpcapi", Usage: "API's offered over the HTTP-RPC interface (deprecated and will be removed in the future, use --http.api)", Value: "", @@ -69,7 +68,7 @@ var ( ) // showDeprecated displays deprecated flags that will be soon removed from the codebase. -func showDeprecated(*cli.Context) { +func showDeprecated(*cli.Context) error { fmt.Println("--------------------------------------------------------------------") fmt.Println("The following flags are deprecated and will be removed in the future!") fmt.Println("--------------------------------------------------------------------") @@ -77,4 +76,5 @@ func showDeprecated(*cli.Context) { // TODO remove when there are newly deprecated flags fmt.Println("no deprecated flags to show at this time") fmt.Println() + return nil } diff --git a/cmd/utils/flags_test.go b/cmd/utils/flags_test.go index e1c412b6a..e41ba2cbc 100644 --- a/cmd/utils/flags_test.go +++ b/cmd/utils/flags_test.go @@ -31,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) func TestAuthorizationList(t *testing.T) { @@ -45,14 +45,14 @@ func TestAuthorizationList(t *testing.T) { fs := &flag.FlagSet{} fs.String(AuthorizationListFlag.Name, value, "") arbitraryCLIContext := cli.NewContext(nil, fs, nil) - arbitraryCLIContext.GlobalSet(AuthorizationListFlag.Name, value) + arbitraryCLIContext.Set(AuthorizationListFlag.Name, value) setAuthorizationList(arbitraryCLIContext, arbitraryNodeConfig) assert.Equal(t, result, arbitraryNodeConfig.AuthorizationList) fs = &flag.FlagSet{} fs.String(AuthorizationListFlag.Name, value, "") arbitraryCLIContext = cli.NewContext(nil, fs, nil) - arbitraryCLIContext.GlobalSet(DeprecatedAuthorizationListFlag.Name, value) // old wlist flag + arbitraryCLIContext.Set(DeprecatedAuthorizationListFlag.Name, value) // old wlist flag setAuthorizationList(arbitraryCLIContext, arbitraryNodeConfig) assert.Equal(t, result, arbitraryNodeConfig.AuthorizationList) } @@ -74,13 +74,13 @@ func TestSetPlugins_whenInvalidFlagsCombination(t *testing.T) { fs.Bool(PluginLocalVerifyFlag.Name, true, "") fs.String(PluginPublicKeyFlag.Name, "", "") arbitraryCLIContext := cli.NewContext(nil, fs, nil) - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "arbitrary value")) + assert.NoError(t, arbitraryCLIContext.Set(PluginSettingsFlag.Name, "arbitrary value")) verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "only --plugins.skipverify or --plugins.localverify must be set") - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSkipVerifyFlag.Name, "false")) - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginLocalVerifyFlag.Name, "false")) - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginPublicKeyFlag.Name, "arbitrary value")) + assert.NoError(t, arbitraryCLIContext.Set(PluginSkipVerifyFlag.Name, "false")) + assert.NoError(t, arbitraryCLIContext.Set(PluginLocalVerifyFlag.Name, "false")) + assert.NoError(t, arbitraryCLIContext.Set(PluginPublicKeyFlag.Name, "arbitrary value")) verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "--plugins.localverify is required for setting --plugins.publickey") } @@ -90,7 +90,7 @@ func TestSetPlugins_whenInvalidPluginSettingsURL(t *testing.T) { fs := &flag.FlagSet{} fs.String(PluginSettingsFlag.Name, "", "") arbitraryCLIContext := cli.NewContext(nil, fs, nil) - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "arbitrary value")) + assert.NoError(t, arbitraryCLIContext.Set(PluginSettingsFlag.Name, "arbitrary value")) verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "plugins: unable to create reader due to unsupported scheme ") } @@ -99,9 +99,9 @@ func TestSetImmutabilityThreshold(t *testing.T) { fs := &flag.FlagSet{} fs.Int(QuorumImmutabilityThreshold.Name, 0, "") arbitraryCLIContext := cli.NewContext(nil, fs, nil) - assert.NoError(t, arbitraryCLIContext.GlobalSet(QuorumImmutabilityThreshold.Name, strconv.Itoa(100000))) - assert.True(t, arbitraryCLIContext.GlobalIsSet(QuorumImmutabilityThreshold.Name), "immutability threshold flag not set") - assert.Equal(t, 100000, arbitraryCLIContext.GlobalInt(QuorumImmutabilityThreshold.Name), "immutability threshold value not set") + assert.NoError(t, arbitraryCLIContext.Set(QuorumImmutabilityThreshold.Name, strconv.Itoa(100000))) + assert.True(t, arbitraryCLIContext.IsSet(QuorumImmutabilityThreshold.Name), "immutability threshold flag not set") + assert.Equal(t, 100000, arbitraryCLIContext.Int(QuorumImmutabilityThreshold.Name), "immutability threshold value not set") } func TestSetPlugins_whenTypical(t *testing.T) { @@ -120,7 +120,7 @@ func TestSetPlugins_whenTypical(t *testing.T) { fs := &flag.FlagSet{} fs.String(PluginSettingsFlag.Name, "", "") arbitraryCLIContext := cli.NewContext(nil, fs, nil) - assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "file://"+arbitraryJSONFile)) + assert.NoError(t, arbitraryCLIContext.Set(PluginSettingsFlag.Name, "file://"+arbitraryJSONFile)) assert.NoError(t, SetPlugins(arbitraryCLIContext, arbitraryNodeConfig)) @@ -179,23 +179,23 @@ func TestQuorumConfigFlags(t *testing.T) { arbitraryEthConfig := ð.Config{} fs.Int(EVMCallTimeOutFlag.Name, 0, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(EVMCallTimeOutFlag.Name, strconv.Itoa(12))) + assert.NoError(t, arbitraryCLIContext.Set(EVMCallTimeOutFlag.Name, strconv.Itoa(12))) fs.Bool(MultitenancyFlag.Name, false, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(MultitenancyFlag.Name, "true")) + assert.NoError(t, arbitraryCLIContext.Set(MultitenancyFlag.Name, "true")) fs.Bool(QuorumEnablePrivacyMarker.Name, true, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(QuorumEnablePrivacyMarker.Name, "true")) + assert.NoError(t, arbitraryCLIContext.Set(QuorumEnablePrivacyMarker.Name, "true")) fs.Uint64(IstanbulRequestTimeoutFlag.Name, 0, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(IstanbulRequestTimeoutFlag.Name, "23")) + assert.NoError(t, arbitraryCLIContext.Set(IstanbulRequestTimeoutFlag.Name, "23")) fs.Uint64(IstanbulBlockPeriodFlag.Name, 0, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(IstanbulBlockPeriodFlag.Name, "34")) + assert.NoError(t, arbitraryCLIContext.Set(IstanbulBlockPeriodFlag.Name, "34")) fs.Bool(RaftModeFlag.Name, false, "") - assert.NoError(t, arbitraryCLIContext.GlobalSet(RaftModeFlag.Name, "true")) + assert.NoError(t, arbitraryCLIContext.Set(RaftModeFlag.Name, "true")) require.NoError(t, setQuorumConfig(arbitraryCLIContext, arbitraryEthConfig)) - assert.True(t, arbitraryCLIContext.GlobalIsSet(EVMCallTimeOutFlag.Name), "EVMCallTimeOutFlag not set") - assert.True(t, arbitraryCLIContext.GlobalIsSet(MultitenancyFlag.Name), "MultitenancyFlag not set") - assert.True(t, arbitraryCLIContext.GlobalIsSet(RaftModeFlag.Name), "RaftModeFlag not set") + assert.True(t, arbitraryCLIContext.IsSet(EVMCallTimeOutFlag.Name), "EVMCallTimeOutFlag not set") + assert.True(t, arbitraryCLIContext.IsSet(MultitenancyFlag.Name), "MultitenancyFlag not set") + assert.True(t, arbitraryCLIContext.IsSet(RaftModeFlag.Name), "RaftModeFlag not set") assert.Equal(t, 12*time.Second, arbitraryEthConfig.EVMCallTimeOut, "EVMCallTimeOut value is incorrect") assert.Equal(t, true, arbitraryEthConfig.QuorumChainConfig.MultiTenantEnabled(), "MultitenancyFlag value is incorrect") diff --git a/go.mod b/go.mod index 8e66c1a01..7581eb3e2 100644 --- a/go.mod +++ b/go.mod @@ -67,6 +67,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c github.com/tyler-smith/go-bip39 v1.1.0 + github.com/urfave/cli/v2 v2.27.4 golang.org/x/crypto v0.27.0 golang.org/x/sync v0.8.0 golang.org/x/sys v0.25.0 @@ -79,7 +80,6 @@ require ( gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/oleiade/lane.v1 v1.0.0 - gopkg.in/urfave/cli.v1 v1.20.0 ) require ( @@ -102,6 +102,7 @@ require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/eapache/queue v1.1.0 // indirect @@ -129,10 +130,12 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index 1be6de9c0..d4e0093b4 100644 --- a/go.sum +++ b/go.sum @@ -150,6 +150,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb h1:GIzvVQ9UkUlOhSDlqmrQAAAUd6R3E+caIisNEyWXvNE= github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= @@ -572,6 +574,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -624,11 +628,15 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= +github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -932,8 +940,6 @@ gopkg.in/oleiade/lane.v1 v1.0.0/go.mod h1:e9mCiNjxfTGlkjxn/TPK3JUwhjKjby5cjXuGot gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 7e6bf8d86..914714280 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -30,96 +30,96 @@ import ( "github.com/fjl/memsize/memsizeui" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) var Memsize memsizeui.Handler var ( - verbosityFlag = cli.IntFlag{ + verbosityFlag = &cli.IntFlag{ Name: "verbosity", Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail", Value: 3, } - vmoduleFlag = cli.StringFlag{ + vmoduleFlag = &cli.StringFlag{ Name: "vmodule", Usage: "Per-module verbosity: comma-separated list of = (e.g. eth/*=5,p2p=4)", Value: "", } - logjsonFlag = cli.BoolFlag{ + logjsonFlag = &cli.BoolFlag{ Name: "log.json", Usage: "Format logs with JSON", } - backtraceAtFlag = cli.StringFlag{ + backtraceAtFlag = &cli.StringFlag{ Name: "log.backtrace", Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")", Value: "", } - debugFlag = cli.BoolFlag{ + debugFlag = &cli.BoolFlag{ Name: "log.debug", Usage: "Prepends log messages with call-site location (file and line number)", } - pprofFlag = cli.BoolFlag{ + pprofFlag = &cli.BoolFlag{ Name: "pprof", Usage: "Enable the pprof HTTP server", } - pprofPortFlag = cli.IntFlag{ + pprofPortFlag = &cli.IntFlag{ Name: "pprof.port", Usage: "pprof HTTP server listening port", Value: 6060, } - pprofAddrFlag = cli.StringFlag{ + pprofAddrFlag = &cli.StringFlag{ Name: "pprof.addr", Usage: "pprof HTTP server listening interface", Value: "127.0.0.1", } - memprofilerateFlag = cli.IntFlag{ + memprofilerateFlag = &cli.IntFlag{ Name: "pprof.memprofilerate", Usage: "Turn on memory profiling with the given rate", Value: runtime.MemProfileRate, } - blockprofilerateFlag = cli.IntFlag{ + blockprofilerateFlag = &cli.IntFlag{ Name: "pprof.blockprofilerate", Usage: "Turn on block profiling with the given rate", } - cpuprofileFlag = cli.StringFlag{ + cpuprofileFlag = &cli.StringFlag{ Name: "pprof.cpuprofile", Usage: "Write CPU profile to the given file", } - traceFlag = cli.StringFlag{ + traceFlag = &cli.StringFlag{ Name: "trace", Usage: "Write execution trace to the given file", } // (Deprecated April 2020) - legacyPprofPortFlag = cli.IntFlag{ + legacyPprofPortFlag = &cli.IntFlag{ Name: "pprofport", Usage: "pprof HTTP server listening port (deprecated, use --pprof.port)", Value: 6060, } - legacyPprofAddrFlag = cli.StringFlag{ + legacyPprofAddrFlag = &cli.StringFlag{ Name: "pprofaddr", Usage: "pprof HTTP server listening interface (deprecated, use --pprof.addr)", Value: "127.0.0.1", } - legacyMemprofilerateFlag = cli.IntFlag{ + legacyMemprofilerateFlag = &cli.IntFlag{ Name: "memprofilerate", Usage: "Turn on memory profiling with the given rate (deprecated, use --pprof.memprofilerate)", Value: runtime.MemProfileRate, } - legacyBlockprofilerateFlag = cli.IntFlag{ + legacyBlockprofilerateFlag = &cli.IntFlag{ Name: "blockprofilerate", Usage: "Turn on block profiling with the given rate (deprecated, use --pprof.blockprofilerate)", } - legacyCpuprofileFlag = cli.StringFlag{ + legacyCpuprofileFlag = &cli.StringFlag{ Name: "cpuprofile", Usage: "Write CPU profile to the given file (deprecated, use --pprof.cpuprofile)", } - legacyBacktraceAtFlag = cli.StringFlag{ + legacyBacktraceAtFlag = &cli.StringFlag{ Name: "backtrace", Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\") (deprecated, use --log.backtrace)", Value: "", } - legacyDebugFlag = cli.BoolFlag{ + legacyDebugFlag = &cli.BoolFlag{ Name: "debug", Usage: "Prepends log messages with call-site location (file and line number) (deprecated, use --log.debug)", } @@ -165,7 +165,7 @@ func init() { func Setup(ctx *cli.Context) error { var ostream log.Handler output := io.Writer(os.Stderr) - if ctx.GlobalBool(logjsonFlag.Name) { + if ctx.Bool(logjsonFlag.Name) { ostream = log.StreamHandler(output, log.JSONFormat()) } else { usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" @@ -176,27 +176,27 @@ func Setup(ctx *cli.Context) error { } glogger.SetHandler(ostream) // logging - verbosity := ctx.GlobalInt(verbosityFlag.Name) + verbosity := ctx.Int(verbosityFlag.Name) glogger.Verbosity(log.Lvl(verbosity)) - vmodule := ctx.GlobalString(vmoduleFlag.Name) + vmodule := ctx.String(vmoduleFlag.Name) glogger.Vmodule(vmodule) - debug := ctx.GlobalBool(debugFlag.Name) - if ctx.GlobalIsSet(legacyDebugFlag.Name) { - debug = ctx.GlobalBool(legacyDebugFlag.Name) + debug := ctx.Bool(debugFlag.Name) + if ctx.IsSet(legacyDebugFlag.Name) { + debug = ctx.Bool(legacyDebugFlag.Name) log.Warn("The flag --debug is deprecated and will be removed in the future, please use --log.debug") } - if ctx.GlobalIsSet(debugFlag.Name) { - debug = ctx.GlobalBool(debugFlag.Name) + if ctx.IsSet(debugFlag.Name) { + debug = ctx.Bool(debugFlag.Name) } log.PrintOrigins(debug) - backtrace := ctx.GlobalString(backtraceAtFlag.Name) - if b := ctx.GlobalString(legacyBacktraceAtFlag.Name); b != "" { + backtrace := ctx.String(backtraceAtFlag.Name) + if b := ctx.String(legacyBacktraceAtFlag.Name); b != "" { backtrace = b log.Warn("The flag --backtrace is deprecated and will be removed in the future, please use --log.backtrace") } - if b := ctx.GlobalString(backtraceAtFlag.Name); b != "" { + if b := ctx.String(backtraceAtFlag.Name); b != "" { backtrace = b } glogger.BacktraceAt(backtrace) @@ -205,46 +205,46 @@ func Setup(ctx *cli.Context) error { // profiling, tracing runtime.MemProfileRate = memprofilerateFlag.Value - if ctx.GlobalIsSet(legacyMemprofilerateFlag.Name) { - runtime.MemProfileRate = ctx.GlobalInt(legacyMemprofilerateFlag.Name) + if ctx.IsSet(legacyMemprofilerateFlag.Name) { + runtime.MemProfileRate = ctx.Int(legacyMemprofilerateFlag.Name) log.Warn("The flag --memprofilerate is deprecated and will be removed in the future, please use --pprof.memprofilerate") } - if ctx.GlobalIsSet(memprofilerateFlag.Name) { - runtime.MemProfileRate = ctx.GlobalInt(memprofilerateFlag.Name) + if ctx.IsSet(memprofilerateFlag.Name) { + runtime.MemProfileRate = ctx.Int(memprofilerateFlag.Name) } blockProfileRate := blockprofilerateFlag.Value - if ctx.GlobalIsSet(legacyBlockprofilerateFlag.Name) { - blockProfileRate = ctx.GlobalInt(legacyBlockprofilerateFlag.Name) + if ctx.IsSet(legacyBlockprofilerateFlag.Name) { + blockProfileRate = ctx.Int(legacyBlockprofilerateFlag.Name) log.Warn("The flag --blockprofilerate is deprecated and will be removed in the future, please use --pprof.blockprofilerate") } - if ctx.GlobalIsSet(blockprofilerateFlag.Name) { - blockProfileRate = ctx.GlobalInt(blockprofilerateFlag.Name) + if ctx.IsSet(blockprofilerateFlag.Name) { + blockProfileRate = ctx.Int(blockprofilerateFlag.Name) } Handler.SetBlockProfileRate(blockProfileRate) - if traceFile := ctx.GlobalString(traceFlag.Name); traceFile != "" { + if traceFile := ctx.String(traceFlag.Name); traceFile != "" { if err := Handler.StartGoTrace(traceFile); err != nil { return err } } - if cpuFile := ctx.GlobalString(cpuprofileFlag.Name); cpuFile != "" { + if cpuFile := ctx.String(cpuprofileFlag.Name); cpuFile != "" { if err := Handler.StartCPUProfile(cpuFile); err != nil { return err } } // pprof server - if ctx.GlobalBool(pprofFlag.Name) { - listenHost := ctx.GlobalString(pprofAddrFlag.Name) + if ctx.Bool(pprofFlag.Name) { + listenHost := ctx.String(pprofAddrFlag.Name) - port := ctx.GlobalInt(pprofPortFlag.Name) + port := ctx.Int(pprofPortFlag.Name) address := fmt.Sprintf("%s:%d", listenHost, port) // This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name. // It cannot be imported because it will cause a cyclical dependency. - StartPProf(address, !ctx.GlobalIsSet("metrics.addr")) + StartPProf(address, !ctx.IsSet("metrics.addr")) } return nil } diff --git a/internal/flags/categories.go b/internal/flags/categories.go new file mode 100644 index 000000000..ff064bb48 --- /dev/null +++ b/internal/flags/categories.go @@ -0,0 +1,44 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package flags + +import "github.com/urfave/cli/v2" + +const ( + EthCategory = "ETHEREUM" + LightCategory = "LIGHT CLIENT" + DevCategory = "DEVELOPER CHAIN" + EthashCategory = "ETHASH" + TxPoolCategory = "TRANSACTION POOL" + PerfCategory = "PERFORMANCE TUNING" + AccountCategory = "ACCOUNT" + APICategory = "API AND CONSOLE" + NetworkingCategory = "NETWORKING" + MinerCategory = "MINER" + GasPriceCategory = "GAS PRICE ORACLE" + VMCategory = "VIRTUAL MACHINE" + LoggingCategory = "LOGGING AND DEBUGGING" + MetricsCategory = "METRICS AND STATS" + MiscCategory = "MISC" + DeprecatedCategory = "ALIASED (deprecated)" + GoQuorumOptionCategory = "GOQUORUM OPTIONS" +) + +func init() { + cli.HelpFlag.(*cli.BoolFlag).Category = MiscCategory + cli.VersionFlag.(*cli.BoolFlag).Category = MiscCategory +} diff --git a/internal/flags/flags.go b/internal/flags/flags.go new file mode 100644 index 000000000..0ae2c6a51 --- /dev/null +++ b/internal/flags/flags.go @@ -0,0 +1,340 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package flags + +import ( + "encoding" + "errors" + "flag" + "math/big" + "os" + "os/user" + "path" + "strings" + + "github.com/ethereum/go-ethereum/common/math" + "github.com/urfave/cli/v2" +) + +// DirectoryString is custom type which is registered in the flags library which cli uses for +// argument parsing. This allows us to expand Value to an absolute path when +// the argument is parsed +type DirectoryString string + +func (s *DirectoryString) String() string { + return string(*s) +} + +func (s *DirectoryString) Set(value string) error { + *s = DirectoryString(expandPath(value)) + return nil +} + +var ( + _ cli.Flag = (*DirectoryFlag)(nil) + _ cli.RequiredFlag = (*DirectoryFlag)(nil) + _ cli.VisibleFlag = (*DirectoryFlag)(nil) + _ cli.DocGenerationFlag = (*DirectoryFlag)(nil) + _ cli.CategorizableFlag = (*DirectoryFlag)(nil) +) + +// DirectoryFlag is custom cli.Flag type which expand the received string to an absolute path. +// e.g. ~/.ethereum -> /home/username/.ethereum +type DirectoryFlag struct { + Name string + + Category string + DefaultText string + Usage string + + Required bool + Hidden bool + HasBeenSet bool + + Value DirectoryString + + Aliases []string +} + +// For cli.Flag: + +func (f *DirectoryFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } +func (f *DirectoryFlag) IsSet() bool { return f.HasBeenSet } +func (f *DirectoryFlag) String() string { return cli.FlagStringer(f) } + +// Apply called by cli library, grabs variable from environment (if in env) +// and adds variable to flag set for parsing. +func (f *DirectoryFlag) Apply(set *flag.FlagSet) error { + eachName(f, func(name string) { + set.Var(&f.Value, f.Name, f.Usage) + }) + return nil +} + +// For cli.RequiredFlag: + +func (f *DirectoryFlag) IsRequired() bool { return f.Required } + +// For cli.VisibleFlag: + +func (f *DirectoryFlag) IsVisible() bool { return !f.Hidden } + +// For cli.CategorizableFlag: + +func (f *DirectoryFlag) GetCategory() string { return f.Category } + +// For cli.DocGenerationFlag: + +func (f *DirectoryFlag) TakesValue() bool { return true } +func (f *DirectoryFlag) GetUsage() string { return f.Usage } +func (f *DirectoryFlag) GetValue() string { return f.Value.String() } +func (f *DirectoryFlag) GetEnvVars() []string { return nil } // env not supported + +func (f *DirectoryFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +type TextMarshaler interface { + encoding.TextMarshaler + encoding.TextUnmarshaler +} + +// textMarshalerVal turns a TextMarshaler into a flag.Value +type textMarshalerVal struct { + v TextMarshaler +} + +func (v textMarshalerVal) String() string { + if v.v == nil { + return "" + } + text, _ := v.v.MarshalText() + return string(text) +} + +func (v textMarshalerVal) Set(s string) error { + return v.v.UnmarshalText([]byte(s)) +} + +var ( + _ cli.Flag = (*TextMarshalerFlag)(nil) + _ cli.RequiredFlag = (*TextMarshalerFlag)(nil) + _ cli.VisibleFlag = (*TextMarshalerFlag)(nil) + _ cli.DocGenerationFlag = (*TextMarshalerFlag)(nil) + _ cli.CategorizableFlag = (*TextMarshalerFlag)(nil) +) + +// TextMarshalerFlag wraps a TextMarshaler value. +type TextMarshalerFlag struct { + Name string + + Category string + DefaultText string + Usage string + + Required bool + Hidden bool + HasBeenSet bool + + Value TextMarshaler + + Aliases []string +} + +// For cli.Flag: + +func (f *TextMarshalerFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } +func (f *TextMarshalerFlag) IsSet() bool { return f.HasBeenSet } +func (f *TextMarshalerFlag) String() string { return cli.FlagStringer(f) } + +func (f *TextMarshalerFlag) Apply(set *flag.FlagSet) error { + eachName(f, func(name string) { + set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage) + }) + return nil +} + +// For cli.RequiredFlag: + +func (f *TextMarshalerFlag) IsRequired() bool { return f.Required } + +// For cli.VisibleFlag: + +func (f *TextMarshalerFlag) IsVisible() bool { return !f.Hidden } + +// For cli.CategorizableFlag: + +func (f *TextMarshalerFlag) GetCategory() string { return f.Category } + +// For cli.DocGenerationFlag: + +func (f *TextMarshalerFlag) TakesValue() bool { return true } +func (f *TextMarshalerFlag) GetUsage() string { return f.Usage } +func (f *TextMarshalerFlag) GetEnvVars() []string { return nil } // env not supported + +func (f *TextMarshalerFlag) GetValue() string { + t, err := f.Value.MarshalText() + if err != nil { + return "(ERR: " + err.Error() + ")" + } + return string(t) +} + +func (f *TextMarshalerFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set. +func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler { + val := ctx.Generic(name) + if val == nil { + return nil + } + return val.(textMarshalerVal).v +} + +var ( + _ cli.Flag = (*BigFlag)(nil) + _ cli.RequiredFlag = (*BigFlag)(nil) + _ cli.VisibleFlag = (*BigFlag)(nil) + _ cli.DocGenerationFlag = (*BigFlag)(nil) + _ cli.CategorizableFlag = (*BigFlag)(nil) +) + +// BigFlag is a command line flag that accepts 256 bit big integers in decimal or +// hexadecimal syntax. +type BigFlag struct { + Name string + + Category string + DefaultText string + Usage string + + Required bool + Hidden bool + HasBeenSet bool + + Value *big.Int + + Aliases []string +} + +// For cli.Flag: + +func (f *BigFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } +func (f *BigFlag) IsSet() bool { return f.HasBeenSet } +func (f *BigFlag) String() string { return cli.FlagStringer(f) } + +func (f *BigFlag) Apply(set *flag.FlagSet) error { + eachName(f, func(name string) { + f.Value = new(big.Int) + set.Var((*bigValue)(f.Value), f.Name, f.Usage) + }) + + return nil +} + +// For cli.RequiredFlag: + +func (f *BigFlag) IsRequired() bool { return f.Required } + +// For cli.VisibleFlag: + +func (f *BigFlag) IsVisible() bool { return !f.Hidden } + +// For cli.CategorizableFlag: + +func (f *BigFlag) GetCategory() string { return f.Category } + +// For cli.DocGenerationFlag: + +func (f *BigFlag) TakesValue() bool { return true } +func (f *BigFlag) GetUsage() string { return f.Usage } +func (f *BigFlag) GetValue() string { return f.Value.String() } +func (f *BigFlag) GetEnvVars() []string { return nil } // env not supported + +func (f *BigFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// bigValue turns *big.Int into a flag.Value +type bigValue big.Int + +func (b *bigValue) String() string { + if b == nil { + return "" + } + return (*big.Int)(b).String() +} + +func (b *bigValue) Set(s string) error { + intVal, ok := math.ParseBig256(s) + if !ok { + return errors.New("invalid integer syntax") + } + *b = (bigValue)(*intVal) + return nil +} + +// GlobalBig returns the value of a BigFlag from the global flag set. +func GlobalBig(ctx *cli.Context, name string) *big.Int { + val := ctx.Generic(name) + if val == nil { + return nil + } + return (*big.Int)(val.(*bigValue)) +} + +// Expands a file path +// 1. replace tilde with users home dir +// 2. expands embedded environment variables +// 3. cleans the path, e.g. /a/b/../c -> /a/c +// Note, it has limitations, e.g. ~someuser/tmp will not be expanded +func expandPath(p string) string { + if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { + if home := HomeDir(); home != "" { + p = home + p[1:] + } + } + return path.Clean(os.ExpandEnv(p)) +} + +func HomeDir() string { + if home := os.Getenv("HOME"); home != "" { + return home + } + if usr, err := user.Current(); err == nil { + return usr.HomeDir + } + return "" +} + +func eachName(f cli.Flag, fn func(string)) { + for _, name := range f.Names() { + name = strings.Trim(name, " ") + fn(name) + } +} diff --git a/cmd/utils/customflags_test.go b/internal/flags/flags_test.go similarity index 61% rename from cmd/utils/customflags_test.go rename to internal/flags/flags_test.go index de39ca36a..a0d4af7ca 100644 --- a/cmd/utils/customflags_test.go +++ b/internal/flags/flags_test.go @@ -1,20 +1,20 @@ // Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// GNU Lesser General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . -package utils +package flags import ( "os" diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index 43bbcf020..de1d29ffd 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -1,152 +1,189 @@ // Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// GNU Lesser General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . package flags import ( - "os" - "path/filepath" + "fmt" + "strings" "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" + "github.com/urfave/cli/v2" ) -var ( - CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} {{.cmd.ArgsUsage}} -{{if .cmd.Description}}{{.cmd.Description}} -{{end}}{{if .cmd.Subcommands}} -SUBCOMMANDS: - {{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .categorizedFlags}} -{{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS: -{{range $categorized.Flags}}{{"\t"}}{{.}} -{{end}} -{{end}}{{end}}` - - OriginCommandHelpTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} {{.ArgsUsage}} -{{if .Description}}{{.Description}} -{{end}}{{if .Subcommands}} -SUBCOMMANDS: - {{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .Flags}} -OPTIONS: -{{range $.Flags}} {{.}} -{{end}} -{{end}}` - - // AppHelpTemplate is the test template for the default, global app help topic. - AppHelpTemplate = `NAME: - {{.App.Name}} - {{.App.Usage}} - - Copyright 2013-2021 The go-ethereum Authors - -USAGE: - {{.App.HelpName}} [options]{{if .App.Commands}} [command] [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} - {{if .App.Version}} -VERSION: - {{.App.Version}} - {{end}}{{if len .App.Authors}} -AUTHOR(S): - {{range .App.Authors}}{{ . }}{{end}} - {{end}}{{if .App.Commands}} -COMMANDS: - {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .FlagGroups}} -{{range .FlagGroups}}{{.Name}} OPTIONS: - {{range .Flags}}{{.}} - {{end}} -{{end}}{{end}}{{if .App.Copyright }} -COPYRIGHT: - {{.App.Copyright}} - {{end}} -` - // ClefAppHelpTemplate is the template for the default, global app help topic. - ClefAppHelpTemplate = `NAME: - {{.App.Name}} - {{.App.Usage}} - - Copyright 2013-2021 The go-ethereum Authors - -USAGE: - {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} - {{if .App.Version}} -COMMANDS: - {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .FlagGroups}} -{{range .FlagGroups}}{{.Name}} OPTIONS: - {{range .Flags}}{{.}} - {{end}} -{{end}}{{end}}{{if .App.Copyright }} -COPYRIGHT: - {{.App.Copyright}} - {{end}} -` -) - -// HelpData is a one shot struct to pass to the usage template -type HelpData struct { - App interface{} - FlagGroups []FlagGroup +// NewApp creates an app with sane defaults. +func NewApp(gitCommit, gitDate, usage string) *cli.App { + app := cli.NewApp() + app.EnableBashCompletion = true + app.Version = params.VersionWithCommit(gitCommit, gitDate) + app.Usage = usage + app.Copyright = "Copyright 2013-2022 The go-ethereum Authors" + app.Before = func(ctx *cli.Context) error { + MigrateGlobalFlags(ctx) + return nil + } + return app } -// FlagGroup is a collection of flags belonging to a single topic. -type FlagGroup struct { - Name string - Flags []cli.Flag +// Merge merges the given flag slices. +func Merge(groups ...[]cli.Flag) []cli.Flag { + var ret []cli.Flag + for _, group := range groups { + ret = append(ret, group...) + } + return ret } -// byCategory sorts an array of FlagGroup by Name in the order -// defined in AppHelpFlagGroups. -type ByCategory []FlagGroup +var migrationApplied = map[*cli.Command]struct{}{} -func (a ByCategory) Len() int { return len(a) } -func (a ByCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByCategory) Less(i, j int) bool { - iCat, jCat := a[i].Name, a[j].Name - iIdx, jIdx := len(a), len(a) // ensure non categorized flags come last +// MigrateGlobalFlags makes all global flag values available in the +// context. This should be called as early as possible in app.Before. +// +// Example: +// +// geth account new --keystore /tmp/mykeystore --lightkdf +// +// is equivalent after calling this method with: +// +// geth --keystore /tmp/mykeystore --lightkdf account new +// +// i.e. in the subcommand Action function of 'account new', ctx.Bool("lightkdf) +// will return true even if --lightkdf is set as a global option. +// +// This function may become unnecessary when https://github.com/urfave/cli/pull/1245 is merged. +func MigrateGlobalFlags(ctx *cli.Context) { + var iterate func(cs []*cli.Command, fn func(*cli.Command)) + iterate = func(cs []*cli.Command, fn func(*cli.Command)) { + for _, cmd := range cs { + if _, ok := migrationApplied[cmd]; ok { + continue + } + migrationApplied[cmd] = struct{}{} + fn(cmd) + iterate(cmd.Subcommands, fn) + } + } - for i, group := range a { - if iCat == group.Name { - iIdx = i + // This iterates over all commands and wraps their action function. + iterate(ctx.App.Commands, func(cmd *cli.Command) { + if cmd.Action == nil { + return } - if jCat == group.Name { - jIdx = i + + action := cmd.Action + cmd.Action = func(ctx *cli.Context) error { + doMigrateFlags(ctx) + return action(ctx) + } + }) +} + +func doMigrateFlags(ctx *cli.Context) { + for _, name := range ctx.FlagNames() { + for _, parent := range ctx.Lineage()[1:] { + if parent.IsSet(name) { + ctx.Set(name, parent.String(name)) + break + } } } +} - return iIdx < jIdx +func init() { + cli.FlagStringer = FlagString } -func FlagCategory(flag cli.Flag, flagGroups []FlagGroup) string { - for _, category := range flagGroups { - for _, flg := range category.Flags { - if flg.GetName() == flag.GetName() { - return category.Name +// FlagString prints a single flag in help. +func FlagString(f cli.Flag) string { + df, ok := f.(cli.DocGenerationFlag) + if !ok { + return "" + } + + needsPlaceholder := df.TakesValue() + placeholder := "" + if needsPlaceholder { + placeholder = "value" + } + + namesText := pad(cli.FlagNamePrefixer(df.Names(), placeholder), 30) + + defaultValueString := "" + if s := df.GetDefaultText(); s != "" { + defaultValueString = " (default: " + s + ")" + } + + usage := strings.TrimSpace(df.GetUsage()) + envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), "")) + if len(envHint) > 0 { + usage += " " + envHint + } + + usage = wordWrap(usage, 80) + usage = indent(usage, 10) + + return fmt.Sprintf("\n %s%s\n%s", namesText, defaultValueString, usage) +} + +func pad(s string, length int) string { + if len(s) < length { + s += strings.Repeat(" ", length-len(s)) + } + return s +} + +func indent(s string, nspace int) string { + ind := strings.Repeat(" ", nspace) + return ind + strings.ReplaceAll(s, "\n", "\n"+ind) +} + +func wordWrap(s string, width int) string { + var ( + output strings.Builder + lineLength = 0 + ) + + for { + sp := strings.IndexByte(s, ' ') + var word string + if sp == -1 { + word = s + } else { + word = s[:sp] + } + wlen := len(word) + over := lineLength+wlen >= width + if over { + output.WriteByte('\n') + lineLength = 0 + } else { + if lineLength != 0 { + output.WriteByte(' ') + lineLength++ } } + + output.WriteString(word) + lineLength += wlen + + if sp == -1 { + break + } + s = s[wlen+1:] } - return "MISC" -} -// NewApp creates an app with sane defaults. -func NewApp(gitCommit, gitDate, usage string) *cli.App { - app := cli.NewApp() - app.Name = filepath.Base(os.Args[0]) - app.Author = "" - app.Email = "" - app.Version = params.VersionWithCommit(gitCommit, gitDate) - app.Usage = usage - return app + return output.String() }