From e320c998f69530bf38fddaad8a7cca6da60f1b3f Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 4 Apr 2024 21:06:39 +0300 Subject: [PATCH] update --- Cargo.lock | 11 + Cargo.toml | 2 +- account_manager/src/validator/create.rs | 28 +- account_manager/src/validator/exit.rs | 16 +- account_manager/src/validator/import.rs | 18 +- account_manager/src/validator/mod.rs | 1 + account_manager/src/validator/modify.rs | 16 +- account_manager/src/validator/recover.rs | 17 +- .../src/validator/slashing_protection.rs | 8 +- beacon_node/src/cli.rs | 189 ++++++++++- boot_node/src/cli.rs | 20 +- common/clap_utils/src/lib.rs | 2 + database_manager/src/lib.rs | 53 +++- lcli/src/main.rs | 295 ++++++++++++------ lighthouse/src/main.rs | 59 +++- validator_client/src/cli.rs | 115 +++++-- validator_manager/src/create_validators.rs | 53 +++- validator_manager/src/import_validators.rs | 14 +- validator_manager/src/lib.rs | 3 + 19 files changed, 713 insertions(+), 207 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7235262125a..0fd09dd9a38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1352,6 +1352,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim 0.11.0", + "terminal_size", ] [[package]] @@ -8194,6 +8195,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.31", + "windows-sys 0.48.0", +] + [[package]] name = "test-test_logger" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index e308714eb47..c48251954a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,7 @@ bincode = "1" bitvec = "1" byteorder = "1" bytes = "1" -clap = { version = "4.5.1", features = ["cargo"] } +clap = { version = "4.5.1", features = ["cargo", "wrap_help"] } compare_fields_derive = { path = "common/compare_fields_derive" } criterion = "0.3" delay_map = "0.3" diff --git a/account_manager/src/validator/create.rs b/account_manager/src/validator/create.rs index 2921b2c3d6b..c75669d80cf 100644 --- a/account_manager/src/validator/create.rs +++ b/account_manager/src/validator/create.rs @@ -5,6 +5,7 @@ use account_utils::{ random_password, read_password_from_user, strip_off_newlines, validator_definitions, PlainText, }; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use directory::{ ensure_dir_exists, parse_path_or_default_with_flag, DEFAULT_SECRET_DIR, DEFAULT_WALLET_DIR, }; @@ -37,14 +38,16 @@ pub fn cli_app() -> Command { .long(WALLET_NAME_FLAG) .value_name("WALLET_NAME") .help("Use the wallet identified by this name") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(WALLET_PASSWORD_FLAG) .long(WALLET_PASSWORD_FLAG) .value_name("WALLET_PASSWORD_PATH") .help("A path to a file containing the password which will unlock the wallet.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(WALLETS_DIR_FLAG) @@ -52,7 +55,8 @@ pub fn cli_app() -> Command { .value_name(WALLETS_DIR_FLAG) .help("A path containing Eth2 EIP-2386 wallets. Defaults to ~/.lighthouse/{network}/wallets") .action(ArgAction::Set) - .conflicts_with("datadir"), + .conflicts_with("datadir") + .display_order(0) ) .arg( Arg::new(SECRETS_DIR_FLAG) @@ -63,7 +67,8 @@ pub fn cli_app() -> Command { Defaults to ~/.lighthouse/{network}/secrets", ) .conflicts_with("datadir") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(DEPOSIT_GWEI_FLAG) @@ -73,7 +78,8 @@ pub fn cli_app() -> Command { "The GWEI value of the deposit amount. Defaults to the minimum amount \ required for an active validator (MAX_EFFECTIVE_BALANCE)", ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(STORE_WITHDRAW_FLAG) @@ -84,6 +90,8 @@ pub fn cli_app() -> Command { instead generate them from the wallet seed when required.", ) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new(COUNT_FLAG) @@ -91,7 +99,8 @@ pub fn cli_app() -> Command { .value_name("VALIDATOR_COUNT") .help("The number of validators to create, regardless of how many already exist") .conflicts_with("at-most") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(AT_MOST_FLAG) @@ -102,14 +111,17 @@ pub fn cli_app() -> Command { reach the given count. Never deletes an existing validator.", ) .conflicts_with("count") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(STDIN_INPUTS_FLAG) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .hide(cfg!(windows)) .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), + .help("If present, read all user inputs from stdin instead of tty.") + .display_order(0) ) } diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index c54e1a33b42..a375a290e06 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -1,6 +1,7 @@ use crate::wallet::create::STDIN_INPUTS_FLAG; use bls::{Keypair, PublicKey}; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use environment::Environment; use eth2::{ types::{GenesisData, StateId, ValidatorData, ValidatorId, ValidatorStatus}, @@ -37,14 +38,16 @@ pub fn cli_app() -> Command { .value_name("KEYSTORE_PATH") .help("The path to the EIP-2335 voting keystore for the validator") .action(ArgAction::Set) - .required(true), + .required(true) + .display_order(0) ) .arg( Arg::new(PASSWORD_FILE_FLAG) .long(PASSWORD_FILE_FLAG) .value_name("PASSWORD_FILE_PATH") .help("The path to the password file which unlocks the validator voting keystore") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(BEACON_SERVER_FLAG) @@ -52,24 +55,29 @@ pub fn cli_app() -> Command { .value_name("NETWORK_ADDRESS") .help("Address to a beacon node HTTP API") .default_value(DEFAULT_BEACON_NODE) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(NO_WAIT) .long(NO_WAIT) .help("Exits after publishing the voluntary exit without waiting for confirmation that the exit was included in the beacon chain") + .display_order(0) ) .arg( Arg::new(NO_CONFIRMATION) .long(NO_CONFIRMATION) .help("Exits without prompting for confirmation that you understand the implications of a voluntary exit. This should be used with caution") + .display_order(0) ) .arg( Arg::new(STDIN_INPUTS_FLAG) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .hide(cfg!(windows)) .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), + .help("If present, read all user inputs from stdin instead of tty.") + .display_order(0) ) } diff --git a/account_manager/src/validator/import.rs b/account_manager/src/validator/import.rs index 573442c0b73..a7c72679f74 100644 --- a/account_manager/src/validator/import.rs +++ b/account_manager/src/validator/import.rs @@ -10,6 +10,7 @@ use account_utils::{ ZeroizeString, }; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use slashing_protection::{SlashingDatabase, SLASHING_PROTECTION_FILENAME}; use std::fs; use std::path::PathBuf; @@ -40,7 +41,8 @@ pub fn cli_app() -> Command { .help("Path to a single keystore to be imported.") .conflicts_with(DIR_FLAG) .required_unless_present(DIR_FLAG) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(DIR_FLAG) @@ -54,20 +56,25 @@ pub fn cli_app() -> Command { ) .conflicts_with(KEYSTORE_FLAG) .required_unless_present(KEYSTORE_FLAG) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(STDIN_INPUTS_FLAG) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .hide(cfg!(windows)) .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), + .help("If present, read all user inputs from stdin instead of tty.") + .display_order(0), ) .arg( Arg::new(REUSE_PASSWORD_FLAG) .long(REUSE_PASSWORD_FLAG) .action(ArgAction::SetTrue) - .help("If present, the same password will be used for all imported keystores."), + .help_heading(FLAG_HEADER) + .help("If present, the same password will be used for all imported keystores.") + .display_order(0), ) .arg( Arg::new(PASSWORD_FLAG) @@ -80,7 +87,8 @@ pub fn cli_app() -> Command { The password will be copied to the `validator_definitions.yml` file, so after \ import we strongly recommend you delete the file at KEYSTORE_PASSWORD_PATH.", ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) } diff --git a/account_manager/src/validator/mod.rs b/account_manager/src/validator/mod.rs index 5fd752fb90c..b699301cde3 100644 --- a/account_manager/src/validator/mod.rs +++ b/account_manager/src/validator/mod.rs @@ -17,6 +17,7 @@ pub const CMD: &str = "validator"; pub fn cli_app() -> Command { Command::new(CMD) + .display_order(0) .about("Provides commands for managing Eth2 validators.") .arg( Arg::new(VALIDATOR_DIR_FLAG) diff --git a/account_manager/src/validator/modify.rs b/account_manager/src/validator/modify.rs index 962c40ad87c..571cd28bf5e 100644 --- a/account_manager/src/validator/modify.rs +++ b/account_manager/src/validator/modify.rs @@ -1,6 +1,7 @@ use account_utils::validator_definitions::ValidatorDefinitions; use bls::PublicKey; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use std::{collections::HashSet, path::PathBuf}; pub const CMD: &str = "modify"; @@ -13,6 +14,7 @@ pub const ALL: &str = "all"; pub fn cli_app() -> Command { Command::new(CMD) .about("Modify validator status in validator_definitions.yml.") + .display_order(0) .subcommand( Command::new(ENABLE) .about("Enable validator(s) in validator_definitions.yml.") @@ -21,14 +23,17 @@ pub fn cli_app() -> Command { .long(PUBKEY_FLAG) .value_name("PUBKEY") .help("Validator pubkey to enable") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(ALL) .long(ALL) .help("Enable all validators in the validator directory") .action(ArgAction::SetTrue) - .conflicts_with(PUBKEY_FLAG), + .help_heading(FLAG_HEADER) + .conflicts_with(PUBKEY_FLAG) + .display_order(0), ), ) .subcommand( @@ -39,14 +44,17 @@ pub fn cli_app() -> Command { .long(PUBKEY_FLAG) .value_name("PUBKEY") .help("Validator pubkey to disable") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(ALL) .long(ALL) .help("Disable all validators in the validator directory") .action(ArgAction::SetTrue) - .conflicts_with(PUBKEY_FLAG), + .help_heading(FLAG_HEADER) + .conflicts_with(PUBKEY_FLAG) + .display_order(0), ), ) } diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index cc3359dc775..4677db18df3 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -5,6 +5,7 @@ use crate::SECRETS_DIR_FLAG; use account_utils::eth2_keystore::{keypair_from_secret, Keystore, KeystoreBuilder}; use account_utils::{random_password, read_mnemonic_from_cli}; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use directory::ensure_dir_exists; use directory::{parse_path_or_default_with_flag, DEFAULT_SECRET_DIR}; use eth2_wallet::bip39::Seed; @@ -29,7 +30,8 @@ pub fn cli_app() -> Command { .help("The first of consecutive key indexes you wish to recover.") .action(ArgAction::Set) .required(false) - .default_value("0"), + .default_value("0") + .display_order(0) ) .arg( Arg::new(COUNT_FLAG) @@ -38,7 +40,8 @@ pub fn cli_app() -> Command { .help("The number of validator keys you wish to recover. Counted consecutively from the provided `--first_index`.") .action(ArgAction::Set) .required(false) - .default_value("1"), + .default_value("1") + .display_order(0) ) .arg( Arg::new(MNEMONIC_FLAG) @@ -48,6 +51,7 @@ pub fn cli_app() -> Command { "If present, the mnemonic will be read in from this file.", ) .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(SECRETS_DIR_FLAG) @@ -57,7 +61,8 @@ pub fn cli_app() -> Command { "The path where the validator keystore passwords will be stored. \ Defaults to ~/.lighthouse/{network}/secrets", ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new(STORE_WITHDRAW_FLAG) @@ -68,13 +73,17 @@ pub fn cli_app() -> Command { instead generate them from the wallet seed when required.", ) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new(STDIN_INPUTS_FLAG) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .hide(cfg!(windows)) .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), + .help("If present, read all user inputs from stdin instead of tty.") + .display_order(0) ) } diff --git a/account_manager/src/validator/slashing_protection.rs b/account_manager/src/validator/slashing_protection.rs index 6a29f597b89..bcd860a4847 100644 --- a/account_manager/src/validator/slashing_protection.rs +++ b/account_manager/src/validator/slashing_protection.rs @@ -21,6 +21,7 @@ pub const PUBKEYS_FLAG: &str = "pubkeys"; pub fn cli_app() -> Command { Command::new(CMD) .about("Import or export slashing protection data to or from another client") + .display_order(0) .subcommand( Command::new(IMPORT_CMD) .about("Import an interchange file") @@ -28,6 +29,7 @@ pub fn cli_app() -> Command { Arg::new(IMPORT_FILE_ARG) .action(ArgAction::Set) .value_name("FILE") + .display_order(0) .help("The slashing protection interchange file to import (.json)"), ) ) @@ -38,7 +40,8 @@ pub fn cli_app() -> Command { Arg::new(EXPORT_FILE_ARG) .action(ArgAction::Set) .value_name("FILE") - .help("The filename to export the interchange file to"), + .help("The filename to export the interchange file to") + .display_order(0) ) .arg( Arg::new(PUBKEYS_FLAG) @@ -48,7 +51,8 @@ pub fn cli_app() -> Command { .help( "List of public keys to export history for. Keys should be 0x-prefixed, \ comma-separated. All known keys will be exported if omitted", - ), + ) + .display_order(0) ) ) } diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index 48431b16776..17a09533540 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -1,5 +1,5 @@ use clap::{builder::ArgPredicate, crate_version, Arg, ArgAction, ArgGroup, Command}; -use clap_utils::get_color_style; +use clap_utils::{get_color_style, FLAG_HEADER}; use strum::VariantNames; use types::ProgressiveBalancesMode; @@ -22,6 +22,7 @@ pub fn cli_app() -> Command { .help("Data directory for network keys. Defaults to network/ inside the beacon node \ dir.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("freezer-dir") @@ -29,6 +30,7 @@ pub fn cli_app() -> Command { .value_name("DIR") .help("Data directory for the freezer database.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("blobs-dir") @@ -36,6 +38,7 @@ pub fn cli_app() -> Command { .value_name("DIR") .help("Data directory for the blobs database.") .action(ArgAction::Set) + .display_order(0) ) /* * Network parameters. @@ -44,8 +47,10 @@ pub fn cli_app() -> Command { Arg::new("subscribe-all-subnets") .long("subscribe-all-subnets") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Subscribe to all subnets regardless of validator count. \ This will also advertise the beacon node as being long-lived subscribed to all subnets.") + .display_order(0) ) .arg( Arg::new("import-all-attestations") @@ -54,13 +59,16 @@ pub fn cli_app() -> Command { This will only import attestations from already-subscribed subnets, use with \ --subscribe-all-subnets to ensure all attestations are received for import.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .global(true) + .display_order(0) ) .arg( Arg::new("disable-packet-filter") .long("disable-packet-filter") .help("Disables the discovery packet filter. Useful for testing in smaller networks") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) ) .arg( Arg::new("shutdown-after-sync") @@ -68,6 +76,8 @@ pub fn cli_app() -> Command { .help("Shutdown beacon node as soon as sync is completed. Backfill sync will \ not be performed before shutdown.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("zero-ports") @@ -76,6 +86,8 @@ pub fn cli_app() -> Command { .help("Sets all listening TCP/UDP ports to 0, allowing the OS to choose some \ arbitrary free ports.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("listen-address") @@ -92,6 +104,7 @@ pub fn cli_app() -> Command { .action(ArgAction::Append) .num_args(0..=2) .default_value("0.0.0.0") + .display_order(0) ) .arg( Arg::new("port") @@ -103,6 +116,7 @@ pub fn cli_app() -> Command { will apply to the IPv4 address and --port6 to the IPv6 address.") .default_value("9000") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("port6") @@ -112,6 +126,7 @@ pub fn cli_app() -> Command { IPv6. Defaults to 9090 when required. The Quic UDP port will be set to this value + 1.") .default_value("9090") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("discovery-port") @@ -119,6 +134,7 @@ pub fn cli_app() -> Command { .value_name("PORT") .help("The UDP port that discovery will listen on. Defaults to `port`") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("quic-port") @@ -126,6 +142,7 @@ pub fn cli_app() -> Command { .value_name("PORT") .help("The UDP port that quic will listen on. Defaults to `port` + 1") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("discovery-port6") @@ -134,6 +151,7 @@ pub fn cli_app() -> Command { .help("The UDP port that discovery will listen on over IPv6 if listening over \ both IPv4 and IPv6. Defaults to `port6`") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("quic-port6") @@ -142,12 +160,14 @@ pub fn cli_app() -> Command { .help("The UDP port that quic will listen on over IPv6 if listening over \ both IPv4 and IPv6. Defaults to `port6` + 1") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("target-peers") .long("target-peers") .help("The target number of peers.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("boot-nodes") @@ -156,6 +176,7 @@ pub fn cli_app() -> Command { .value_name("ENR/MULTIADDR LIST") .help("One or more comma-delimited base64-encoded ENR's to bootstrap the p2p network. Multiaddr is also supported.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("network-load") @@ -165,18 +186,23 @@ pub fn cli_app() -> Command { .default_value("3") .hide(true) .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("disable-upnp") .long("disable-upnp") .help("Disables UPnP support. Setting this will prevent Lighthouse from attempting to automatically establish external port mappings.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("private") .long("private") .help("Prevents sending various client identification information.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("enr-udp-port") @@ -185,6 +211,7 @@ pub fn cli_app() -> Command { .help("The UDP4 port of the local ENR. Set this only if you are sure other nodes \ can connect to your local node on this port over IPv4.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-quic-port") @@ -193,6 +220,7 @@ pub fn cli_app() -> Command { .help("The quic UDP4 port that will be set on the local ENR. Set this only if you are sure other nodes \ can connect to your local node on this port over IPv4.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-udp6-port") @@ -201,6 +229,7 @@ pub fn cli_app() -> Command { .help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \ can connect to your local node on this port over IPv6.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-quic6-port") @@ -209,6 +238,7 @@ pub fn cli_app() -> Command { .help("The quic UDP6 port that will be set on the local ENR. Set this only if you are sure other nodes \ can connect to your local node on this port over IPv6.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-tcp-port") @@ -218,6 +248,7 @@ pub fn cli_app() -> Command { can connect to your local node on this port over IPv4. The --port flag is \ used if this is not set.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-tcp6-port") @@ -227,6 +258,7 @@ pub fn cli_app() -> Command { can connect to your local node on this port over IPv6. The --port6 flag is \ used if this is not set.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-address") @@ -240,23 +272,28 @@ pub fn cli_app() -> Command { accordingly. To update both, set this flag twice with the different values.") .action(ArgAction::Append) .num_args(0..=2) + .display_order(0) ) .arg( Arg::new("enr-match") .short('e') .long("enr-match") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Sets the local ENR IP address and port to match those set for lighthouse. \ Specifically, the IP address will be the value of --listen-address and the \ UDP port will be --discovery-port.") + .display_order(0) ) .arg( Arg::new("disable-enr-auto-update") .short('x') .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long("disable-enr-auto-update") .help("Discovery automatically updates the nodes local ENR with an external IP address and port as seen by other peers on the network. \ This disables this feature, fixing the ENR's IP/PORT to those specified on boot.") + .display_order(0) ) .arg( Arg::new("libp2p-addresses") @@ -265,6 +302,7 @@ pub fn cli_app() -> Command { .help("One or more comma-delimited multiaddrs to manually connect to a libp2p peer \ without an ENR.") .action(ArgAction::Set) + .display_order(0) ) // NOTE: This is hide because it is primarily a developer feature for testnets and // debugging. We remove it from the list to avoid clutter. @@ -272,14 +310,18 @@ pub fn cli_app() -> Command { Arg::new("disable-discovery") .long("disable-discovery") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Disables the discv5 discovery protocol. The node will not search for new peers or participate in the discovery protocol.") .hide(true) + .display_order(0) ) .arg( Arg::new("disable-quic") .long("disable-quic") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Disables the quic transport. The node will rely solely on the TCP transport for libp2p connections.") + .display_order(0) ) .arg( Arg::new("disable-peer-scoring") @@ -287,7 +329,9 @@ pub fn cli_app() -> Command { .help("Disables peer scoring in lighthouse. WARNING: This is a dev only flag is only meant to be used in local testing scenarios \ Using this flag on a real network may cause your node to become eclipsed and see a different view of the network") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .hide(true) + .display_order(0) ) .arg( Arg::new("trusted-peers") @@ -295,18 +339,24 @@ pub fn cli_app() -> Command { .value_name("TRUSTED_PEERS") .help("One or more comma-delimited trusted peer ids which always have the highest score according to the peer scoring system.") .action(ArgAction::Set) + .display_order(0) + .display_order(0) ) .arg( Arg::new("genesis-backfill") .long("genesis-backfill") .help("Attempts to download blocks all the way back to genesis when checkpoint syncing.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("enable-private-discovery") .long("enable-private-discovery") .help("Lighthouse by default does not discover private IP addresses. Set this flag to enable connection attempts to local addresses.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("self-limiter") @@ -319,6 +369,8 @@ pub fn cli_app() -> Command { used." ) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("self-limiter-protocols") @@ -335,6 +387,7 @@ pub fn cli_app() -> Command { .action(ArgAction::Append) .value_delimiter(';') .requires("self-limiter") + .display_order(0) ) .arg( Arg::new("proposer-only") @@ -343,6 +396,8 @@ pub fn cli_app() -> Command { This will run the beacon node in a minimal configuration that is sufficient for block publishing only. This flag should be used \ for a beacon node being referenced by validator client using the --proposer-node flag. This configuration is for enabling more secure setups.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("disable-inbound-rate-limiter") @@ -351,6 +406,8 @@ pub fn cli_app() -> Command { "Disables the inbound rate limiter (requests received by this node)." ) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("inbound-rate-limiter-protocols") @@ -367,6 +424,7 @@ pub fn cli_app() -> Command { ) .action(ArgAction::Set) .conflicts_with("disable-inbound-rate-limiter") + .display_order(0) ) .arg( Arg::new("disable-backfill-rate-limiting") @@ -375,6 +433,8 @@ pub fn cli_app() -> Command { as possible, however it can result in resource contention which degrades staking performance. Stakers \ should generally choose to avoid this flag since backfill sync is not required for staking.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* REST API related arguments */ .arg( @@ -382,6 +442,8 @@ pub fn cli_app() -> Command { .long("http") .help("Enable the RESTful HTTP API server. Disabled by default.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("http-address") @@ -391,6 +453,7 @@ pub fn cli_app() -> Command { .help("Set the listen address for the RESTful HTTP API server.") .default_value_if("enable_http", ArgPredicate::IsPresent, "127.0.0.1") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-port") @@ -400,6 +463,7 @@ pub fn cli_app() -> Command { .help("Set the listen TCP port for the RESTful HTTP API server.") .default_value_if("enable_http", ArgPredicate::IsPresent, "5052") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-allow-origin") @@ -411,6 +475,7 @@ pub fn cli_app() -> Command { If no value is supplied, the CORS allowed origin is set to the listen \ address of this server (e.g., http://localhost:5052).") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-spec-fork") @@ -420,6 +485,7 @@ pub fn cli_app() -> Command { .help("Serve the spec for a specific hard fork on /eth/v1/config/spec. It should \ not be necessary to set this flag.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-enable-tls") @@ -427,8 +493,10 @@ pub fn cli_app() -> Command { .help("Serves the RESTful HTTP API server over TLS. This feature is currently \ experimental.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .requires("http-tls-cert") .requires("http-tls-key") + .display_order(0) ) .arg( Arg::new("http-tls-cert") @@ -437,6 +505,7 @@ pub fn cli_app() -> Command { .help("The path of the certificate to be used when serving the HTTP API server \ over TLS.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-tls-key") @@ -445,15 +514,18 @@ pub fn cli_app() -> Command { .help("The path of the private key to be used when serving the HTTP API server \ over TLS. Must not be password-protected.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-allow-sync-stalled") .long("http-allow-sync-stalled") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .requires("enable_http") .help("Forces the HTTP to indicate that the node is synced when sync is actually \ stalled. This is useful for very small testnets. TESTING ONLY. DO NOT USE ON \ MAINNET.") + .display_order(0) ) .arg( Arg::new("http-sse-capacity-multiplier") @@ -464,6 +536,7 @@ pub fn cli_app() -> Command { .value_name("N") .help("Multiplier to apply to the length of HTTP server-sent-event (SSE) channels. \ Increasing this value can prevent messages from being dropped.") + .display_order(0) ) .arg( Arg::new("http-duplicate-block-status") @@ -474,6 +547,7 @@ pub fn cli_app() -> Command { .value_name("STATUS_CODE") .help("Status code to send when a block that is already known is POSTed to the \ HTTP API.") + .display_order(0) ) .arg( Arg::new("http-enable-beacon-processor") @@ -485,6 +559,7 @@ pub fn cli_app() -> Command { alongside other tasks. When set to \"false\", HTTP API responses will be executed \ immediately.") .action(ArgAction::Set) + .display_order(0) .default_value_if("enable_http", ArgPredicate::IsPresent, "true") ) /* Prometheus metrics HTTP server related arguments */ @@ -493,6 +568,8 @@ pub fn cli_app() -> Command { .long("metrics") .help("Enable the Prometheus metrics HTTP server. Disabled by default.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("metrics-address") @@ -502,6 +579,7 @@ pub fn cli_app() -> Command { .help("Set the listen address for the Prometheus metrics HTTP server.") .default_value_if("metrics", ArgPredicate::IsPresent, "127.0.0.1") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("metrics-port") @@ -511,6 +589,7 @@ pub fn cli_app() -> Command { .help("Set the listen TCP port for the Prometheus metrics HTTP server.") .default_value_if("metrics", ArgPredicate::IsPresent, "5054") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("metrics-allow-origin") @@ -522,6 +601,7 @@ pub fn cli_app() -> Command { If no value is supplied, the CORS allowed origin is set to the listen \ address of this server (e.g., http://localhost:5054).") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("shuffling-cache-size") @@ -530,6 +610,7 @@ pub fn cli_app() -> Command { This flag allows the user to set the shuffling cache size in epochs. \ Shufflings are dependent on validator count and setting this value to a large number can consume a large amount of memory.") .action(ArgAction::Set) + .display_order(0) ) /* @@ -547,6 +628,7 @@ pub fn cli_app() -> Command { validators, IP address and other personal information. Always use a HTTPS connection \ and never provide an untrusted URL.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("monitoring-endpoint-period") @@ -556,6 +638,7 @@ pub fn cli_app() -> Command { the monitoring-endpoint. Default: 60s") .requires("monitoring-endpoint") .action(ArgAction::Set) + .display_order(0) ) /* @@ -569,6 +652,8 @@ pub fn cli_app() -> Command { on localhost:5052 and import deposit logs from the execution node. This is \ equivalent to `--http` on merge-ready networks, or `--http --eth1` pre-merge") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* @@ -580,14 +665,18 @@ pub fn cli_app() -> Command { .help("If present the node will connect to an eth1 node. This is required for \ block production, you must use this flag if you wish to serve a validator.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("dummy-eth1") .long("dummy-eth1") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .conflicts_with("eth1") .help("If present, uses an eth1 backend that generates static dummy data.\ Identical to the method used at the 2019 Canada interop.") + .display_order(0) ) .arg( Arg::new("eth1-purge-cache") @@ -595,6 +684,8 @@ pub fn cli_app() -> Command { .value_name("PURGE-CACHE") .help("Purges the eth1 block and deposit caches") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("eth1-blocks-per-log-query") @@ -604,6 +695,7 @@ pub fn cli_app() -> Command { This will reduce the size of responses from the Eth1 endpoint.") .default_value("1000") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("eth1-cache-follow-distance") @@ -614,6 +706,7 @@ pub fn cli_app() -> Command { compensate for irregular Proof-of-Work block times, but setting it too low \ can make the node vulnerable to re-orgs.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slots-per-restore-point") @@ -623,6 +716,7 @@ pub fn cli_app() -> Command { Cannot be changed after initialization. \ [default: 8192 (mainnet) or 64 (minimal)]") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("epochs-per-migration") @@ -633,6 +727,7 @@ pub fn cli_app() -> Command { writes") .default_value("1") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("block-cache-size") @@ -640,6 +735,7 @@ pub fn cli_app() -> Command { .value_name("SIZE") .help("Specifies how many blocks the database should cache in memory [default: 5]") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("historic-state-cache-size") @@ -647,6 +743,7 @@ pub fn cli_app() -> Command { .value_name("SIZE") .help("Specifies how many states from the freezer database should cache in memory [default: 1]") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("state-cache-size") @@ -654,6 +751,7 @@ pub fn cli_app() -> Command { .value_name("STATE_CACHE_SIZE") .help("Specifies the size of the snapshot cache [default: 3]") .action(ArgAction::Set) + .display_order(0) ) /* * Execution Layer Integration @@ -667,6 +765,7 @@ pub fn cli_app() -> Command { JSON-RPC connection. Uses the same endpoint to populate the \ deposit cache.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("execution-jwt") @@ -677,6 +776,7 @@ pub fn cli_app() -> Command { execution endpoint provided in the --execution-endpoint flag.") .requires("execution-endpoint") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("execution-jwt-secret-key") @@ -688,6 +788,7 @@ pub fn cli_app() -> Command { .requires("execution-endpoint") .conflicts_with("execution-jwt") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("execution-jwt-id") @@ -699,6 +800,7 @@ pub fn cli_app() -> Command { Set to empty by default") .requires("execution-jwt") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("execution-jwt-version") @@ -710,6 +812,7 @@ pub fn cli_app() -> Command { Set to empty by default") .requires("execution-jwt") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("suggested-fee-recipient") @@ -720,6 +823,7 @@ pub fn cli_app() -> Command { client instead of (or in addition to) setting it here.") .requires("execution-endpoint") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder") @@ -729,6 +833,7 @@ pub fn cli_app() -> Command { .help("The URL of a service compatible with the MEV-boost API.") .requires("execution-endpoint") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("execution-timeout-multiplier") @@ -737,6 +842,7 @@ pub fn cli_app() -> Command { .help("Unsigned integer to multiply the default execution timeouts by.") .default_value("1") .action(ArgAction::Set) + .display_order(0) ) /* Deneb settings */ .arg( @@ -747,6 +853,7 @@ pub fn cli_app() -> Command { NOTE: This will override the trusted setup that is generated \ from the mainnet kzg ceremony. Use with caution") .action(ArgAction::Set) + .display_order(0) ) /* * Database purging and compaction. @@ -755,14 +862,18 @@ pub fn cli_app() -> Command { Arg::new("purge-db") .long("purge-db") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("If present, the chain database will be deleted. Use with caution.") + .display_order(0) ) .arg( Arg::new("compact-db") .long("compact-db") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("If present, apply compaction to the database on start-up. Use with caution. \ It is generally not recommended unless auto-compaction is disabled.") + .display_order(0) ) .arg( Arg::new("auto-compact-db") @@ -770,6 +881,7 @@ pub fn cli_app() -> Command { .help("Enable or disable automatic compaction of the database on finalization.") .action(ArgAction::Set) .default_value("true") + .display_order(0) ) .arg( Arg::new("prune-payloads") @@ -779,6 +891,7 @@ pub fn cli_app() -> Command { reconstructed and sent to syncing peers.") .action(ArgAction::Set) .default_value("true") + .display_order(0) ) .arg( Arg::new("prune-blobs") @@ -788,6 +901,7 @@ pub fn cli_app() -> Command { data availability boundary relative to the current epoch.") .action(ArgAction::Set) .default_value("true") + .display_order(0) ) .arg( Arg::new("epochs-per-blob-prune") @@ -798,6 +912,7 @@ pub fn cli_app() -> Command { relative to the current epoch.") .action(ArgAction::Set) .default_value("1") + .display_order(0) ) .arg( Arg::new("blob-prune-margin-epochs") @@ -807,6 +922,7 @@ pub fn cli_app() -> Command { up until data_availability_boundary - blob_prune_margin_epochs.") .action(ArgAction::Set) .default_value("0") + .display_order(0) ) /* @@ -821,6 +937,7 @@ pub fn cli_app() -> Command { ) .value_name("GRAFFITI") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("max-skip-slots") @@ -832,6 +949,7 @@ pub fn cli_app() -> Command { ) .value_name("NUM_SLOTS") .action(ArgAction::Set) + .display_order(0) ) /* * Slasher. @@ -845,6 +963,8 @@ pub fn cli_app() -> Command { resources required." ) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("slasher-dir") @@ -855,6 +975,7 @@ pub fn cli_app() -> Command { .value_name("PATH") .action(ArgAction::Set) .requires("slasher") + .display_order(0) ) .arg( Arg::new("slasher-update-period") @@ -865,6 +986,7 @@ pub fn cli_app() -> Command { .value_name("SECONDS") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-slot-offset") @@ -877,6 +999,7 @@ pub fn cli_app() -> Command { .value_name("SECONDS") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-history-length") @@ -888,6 +1011,7 @@ pub fn cli_app() -> Command { .value_name("EPOCHS") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-max-db-size") @@ -898,6 +1022,7 @@ pub fn cli_app() -> Command { .value_name("GIGABYTES") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-att-cache-size") @@ -906,6 +1031,7 @@ pub fn cli_app() -> Command { .value_name("COUNT") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-chunk-size") @@ -916,6 +1042,7 @@ pub fn cli_app() -> Command { .value_name("EPOCHS") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-validator-chunk-size") @@ -926,6 +1053,7 @@ pub fn cli_app() -> Command { .value_name("NUM_VALIDATORS") .requires("slasher") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("slasher-broadcast") @@ -934,6 +1062,7 @@ pub fn cli_app() -> Command { [Enabled by default].") .action(ArgAction::Set) .default_value("true") + .display_order(0) ) .arg( Arg::new("slasher-backend") @@ -943,6 +1072,7 @@ pub fn cli_app() -> Command { .action(ArgAction::Set) .value_parser(slasher::DatabaseBackend::VARIANTS.to_vec()) .requires("slasher") + .display_order(0) ) .arg( Arg::new("wss-checkpoint") @@ -955,6 +1085,7 @@ pub fn cli_app() -> Command { ) .value_name("WSS_CHECKPOINT") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("checkpoint-state") @@ -964,6 +1095,7 @@ pub fn cli_app() -> Command { .value_name("STATE_SSZ") .action(ArgAction::Set) .requires("checkpoint-block") + .display_order(0) ) .arg( Arg::new("checkpoint-block") @@ -973,6 +1105,7 @@ pub fn cli_app() -> Command { .value_name("BLOCK_SSZ") .action(ArgAction::Set) .requires("checkpoint-state") + .display_order(0) ) .arg( Arg::new("checkpoint-blobs") @@ -982,6 +1115,7 @@ pub fn cli_app() -> Command { .value_name("BLOBS_SSZ") .action(ArgAction::Set) .requires("checkpoint-block") + .display_order(0) ) .arg( Arg::new("checkpoint-sync-url") @@ -990,6 +1124,7 @@ pub fn cli_app() -> Command { .value_name("BEACON_NODE") .action(ArgAction::Set) .conflicts_with("checkpoint-state") + .display_order(0) ) .arg( Arg::new("checkpoint-sync-url-timeout") @@ -998,6 +1133,7 @@ pub fn cli_app() -> Command { .value_name("SECONDS") .action(ArgAction::Set) .default_value("180") + .display_order(0) ) .arg( Arg::new("allow-insecure-genesis-sync") @@ -1008,21 +1144,27 @@ pub fn cli_app() -> Command { .conflicts_with("checkpoint-sync-url") .conflicts_with("checkpoint-state") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("reconstruct-historic-states") .long("reconstruct-historic-states") .help("After a checkpoint sync, reconstruct historic states in the database. This requires syncing all the way back to genesis.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("validator-monitor-auto") .long("validator-monitor-auto") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Enables the automatic detection and monitoring of validators connected to the \ HTTP API and using the subnet subscription endpoint. This generally has the \ effect of providing additional logging and metrics for locally controlled \ validators.") + .display_order(0) ) .arg( Arg::new("validator-monitor-pubkeys") @@ -1032,6 +1174,7 @@ pub fn cli_app() -> Command { logging.") .value_name("PUBKEYS") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("validator-monitor-file") @@ -1040,6 +1183,7 @@ pub fn cli_app() -> Command { contained within a file at the given path.") .value_name("PATH") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("validator-monitor-individual-tracking-threshold") @@ -1051,6 +1195,7 @@ pub fn cli_app() -> Command { high log volume when using many validators. Defaults to 64.") .value_name("INTEGER") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("disable-lock-timeouts") @@ -1059,12 +1204,16 @@ pub fn cli_app() -> Command { lead to less spurious failures on slow hardware but is considered \ experimental as it may obscure performance issues.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("disable-proposer-reorgs") .long("disable-proposer-reorgs") .help("Do not attempt to reorg late blocks from other validators when proposing.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("proposer-reorg-threshold") @@ -1074,6 +1223,7 @@ pub fn cli_app() -> Command { .help("Percentage of vote weight below which to attempt a proposer reorg. \ Default: 20%") .conflicts_with("disable-proposer-reorgs") + .display_order(0) ) .arg( Arg::new("proposer-reorg-epochs-since-finalization") @@ -1083,6 +1233,7 @@ pub fn cli_app() -> Command { .help("Maximum number of epochs since finalization at which proposer reorgs are \ allowed. Default: 2") .conflicts_with("disable-proposer-reorgs") + .display_order(0) ) .arg( Arg::new("proposer-reorg-cutoff") @@ -1094,6 +1245,7 @@ pub fn cli_app() -> Command { ample time to propagate and be processed by the network. The default is \ 1/12th of a slot (1 second on mainnet)") .conflicts_with("disable-proposer-reorgs") + .display_order(0) ) .arg( Arg::new("proposer-reorg-disallowed-offsets") @@ -1107,6 +1259,7 @@ pub fn cli_app() -> Command { avoided. Any offsets supplied with this flag will impose additional \ restrictions.") .conflicts_with("disable-proposer-reorgs") + .display_order(0) ) .arg( Arg::new("prepare-payload-lookahead") @@ -1117,6 +1270,7 @@ pub fn cli_app() -> Command { improve their payload after the first call, and high values are useful \ for ensuring the EL is given ample notice. Default: 1/3 of a slot.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("always-prepare-payload") @@ -1126,6 +1280,8 @@ pub fn cli_app() -> Command { recipient on this BN and also consider adjusting the \ --prepare-payload-lookahead flag.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("fork-choice-before-proposal-timeout") @@ -1135,6 +1291,7 @@ pub fn cli_app() -> Command { to 0, however you risk proposing atop the wrong parent block.") .default_value("250") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("paranoid-block-proposal") @@ -1145,6 +1302,8 @@ pub fn cli_app() -> Command { otherwise.") .hide(true) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("builder-fallback-skips") @@ -1154,6 +1313,7 @@ pub fn cli_app() -> Command { and will use the local execution engine for payload construction.") .default_value("3") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder-fallback-skips-per-epoch") @@ -1164,6 +1324,7 @@ pub fn cli_app() -> Command { payload construction.") .default_value("8") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder-fallback-epochs-since-finalization") @@ -1177,6 +1338,7 @@ pub fn cli_app() -> Command { is set to propose.") .default_value("3") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder-fallback-disable-checks") @@ -1185,6 +1347,8 @@ pub fn cli_app() -> Command { API will always be used for payload construction, regardless of recent chain \ conditions.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("builder-profit-threshold") @@ -1192,6 +1356,7 @@ pub fn cli_app() -> Command { .value_name("WEI_VALUE") .help("This flag is deprecated and has no effect.") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder-user-agent") @@ -1201,6 +1366,7 @@ pub fn cli_app() -> Command { default is Lighthouse's version string.") .requires("builder") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("reset-payload-statuses") @@ -1209,6 +1375,8 @@ pub fn cli_app() -> Command { already-imported blocks. This can assist in the recovery from a consensus \ failure caused by the execution layer.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("disable-deposit-contract-sync") @@ -1217,14 +1385,18 @@ pub fn cli_app() -> Command { This overrides any previous option that depends on it. \ Useful if you intend to run a non-validating beacon node.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("disable-optimistic-finalized-sync") .long("disable-optimistic-finalized-sync") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Force Lighthouse to verify every execution block hash with the execution \ client during finalized sync. By default block hashes will be checked in \ Lighthouse and only passed to the EL if initial verification fails.") + .display_order(0) ) .arg( Arg::new("light-client-server") @@ -1232,6 +1404,8 @@ pub fn cli_app() -> Command { .help("Act as a full node supporting light clients on the p2p network \ [experimental]") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("gui") @@ -1239,12 +1413,16 @@ pub fn cli_app() -> Command { .help("Enable the graphical user interface and all its requirements. \ This enables --http and --validator-monitor-auto and enables SSE logging.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("always-prefer-builder-payload") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long("always-prefer-builder-payload") .help("This flag is deprecated and has no effect.") + .display_order(0) ) .arg( Arg::new("invalid-gossip-verified-blocks-path") @@ -1255,6 +1433,7 @@ pub fn cli_app() -> Command { the block SSZ as a file at this path. This feature is only recommended for \ developers. This directory is not pruned, users should be careful to avoid \ filling up their disks.") + .display_order(0) ) .arg( Arg::new("progressive-balances") @@ -1268,6 +1447,7 @@ pub fn cli_app() -> Command { Lighthouse team.") .action(ArgAction::Set) .value_parser(ProgressiveBalancesMode::VARIANTS.to_vec()) + .display_order(0) ) .arg( Arg::new("beacon-processor-max-workers") @@ -1279,6 +1459,7 @@ pub fn cli_app() -> Command { default value is the number of logical CPU cores on the host.") .hide(true) .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("beacon-processor-work-queue-len") @@ -1290,6 +1471,7 @@ pub fn cli_app() -> Command { .default_value("16384") .hide(true) .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("beacon-processor-reprocess-queue-len") @@ -1301,6 +1483,7 @@ pub fn cli_app() -> Command { .hide(true) .default_value("12288") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("beacon-processor-attestation-batch-size") @@ -1312,6 +1495,7 @@ pub fn cli_app() -> Command { .hide(true) .default_value("64") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("beacon-processor-aggregate-batch-size") @@ -1324,12 +1508,15 @@ pub fn cli_app() -> Command { .hide(true) .default_value("64") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("disable-duplicate-warn-logs") .long("disable-duplicate-warn-logs") .help("This flag is deprecated and has no effect.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .group(ArgGroup::new("enable_http").args(["http", "gui", "staking"]).multiple(true)) } diff --git a/boot_node/src/cli.rs b/boot_node/src/cli.rs index 9e1b46d61a3..0854078e281 100644 --- a/boot_node/src/cli.rs +++ b/boot_node/src/cli.rs @@ -1,7 +1,7 @@ //! Simple logic for spawning a Lighthouse BootNode. use clap::{Arg, ArgAction, Command}; -use clap_utils::get_color_style; +use clap_utils::{get_color_style, FLAG_HEADER}; // TODO: Add DOS prevention CLI params pub fn cli_app() -> Command { @@ -26,6 +26,7 @@ pub fn cli_app() -> Command { .num_args(0..=2) .required(true) .conflicts_with("network-dir") + .display_order(0) ) .arg( Arg::new("port") @@ -34,6 +35,7 @@ pub fn cli_app() -> Command { .help("The UDP port to listen on.") .default_value("9000") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("port6") @@ -42,7 +44,8 @@ pub fn cli_app() -> Command { .help("The UDP port to listen on over IpV6 when listening over both Ipv4 and \ Ipv6. Defaults to 9090 when required.") .default_value("9090") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("listen-address") @@ -59,6 +62,7 @@ pub fn cli_app() -> Command { .num_args(0..=2) .default_value("0.0.0.0") .action(ArgAction::Append) + .display_order(0) ) .arg( Arg::new("boot-nodes") @@ -66,7 +70,8 @@ pub fn cli_app() -> Command { .allow_hyphen_values(true) .value_name("ENR-LIST/Multiaddr") .help("One or more comma-delimited base64-encoded ENR's or multiaddr strings of peers to initially add to the local routing table") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enr-udp-port") @@ -75,6 +80,7 @@ pub fn cli_app() -> Command { .help("The UDP port of the boot node's ENR. This is the port that external peers will dial to reach this boot node. Set this only if the external port differs from the listening port.") .action(ArgAction::Set) .conflicts_with("network-dir") + .display_order(0) ) .arg( Arg::new("enr-udp6-port") @@ -83,21 +89,26 @@ pub fn cli_app() -> Command { .help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \ can connect to your local node on this port over IpV6.") .conflicts_with("network-dir") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enable-enr-auto-update") .short('x') .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long("enable-enr-auto-update") .help("Discovery can automatically update the node's local ENR with an external IP address and port as seen by other peers on the network. \ This enables this feature.") + .display_order(0) ) .arg( Arg::new("disable-packet-filter") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long("disable-packet-filter") .help("Disables discv5 packet filter. Useful for testing in smaller networks") + .display_order(0) ) .arg( Arg::new("network-dir") @@ -105,5 +116,6 @@ pub fn cli_app() -> Command { .long("network-dir") .help("The directory which contains the enr and it's associated private key") .action(ArgAction::Set) + .display_order(0) ) } diff --git a/common/clap_utils/src/lib.rs b/common/clap_utils/src/lib.rs index f687c50c37e..ea56e7e672a 100644 --- a/common/clap_utils/src/lib.rs +++ b/common/clap_utils/src/lib.rs @@ -16,6 +16,8 @@ pub const BAD_TESTNET_DIR_MESSAGE: &str = "The hard-coded testnet directory was or when there is no default public network to connect to. \ During these times you must specify a --testnet-dir."; +pub const FLAG_HEADER: &str = "Flags"; + /// Try to parse the eth2 network config from the `network`, `testnet-dir` flags in that order. /// Returns the default hardcoded testnet if neither flags are set. pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result { diff --git a/database_manager/src/lib.rs b/database_manager/src/lib.rs index 5f9b9e9af53..804fc9da2a1 100644 --- a/database_manager/src/lib.rs +++ b/database_manager/src/lib.rs @@ -4,7 +4,7 @@ use beacon_chain::{ }; use beacon_node::{get_data_dir, get_slots_per_restore_point, ClientConfig}; use clap::{Arg, ArgAction, ArgMatches, Command}; -use clap_utils::get_color_style; +use clap_utils::{get_color_style, FLAG_HEADER}; use environment::{Environment, RuntimeContext}; use slog::{info, warn, Logger}; use std::fs; @@ -52,7 +52,8 @@ pub fn inspect_cli_app() -> Command { .value_name("TAG") .help("3-byte column ID (see `DBColumn`)") .action(ArgAction::Set) - .required(true), + .required(true) + .display_order(0), ) .arg( Arg::new("output") @@ -60,40 +61,48 @@ pub fn inspect_cli_app() -> Command { .value_name("TARGET") .help("Select the type of output to show") .default_value("sizes") - .value_parser(InspectTarget::VARIANTS.to_vec()), + .value_parser(InspectTarget::VARIANTS.to_vec()) + .display_order(0), ) .arg( Arg::new("skip") .long("skip") .value_name("N") - .help("Skip over the first N keys"), + .help("Skip over the first N keys") + .display_order(0), ) .arg( Arg::new("limit") .long("limit") .value_name("N") - .help("Output at most N keys"), + .help("Output at most N keys") + .display_order(0), ) .arg( Arg::new("freezer") .long("freezer") .help("Inspect the freezer DB rather than the hot DB") .action(ArgAction::SetTrue) - .conflicts_with("blobs-db"), + .help_heading(FLAG_HEADER) + .conflicts_with("blobs-db") + .display_order(0), ) .arg( Arg::new("blobs-db") .long("blobs-db") .help("Inspect the blobs DB rather than the hot DB") .action(ArgAction::SetTrue) - .conflicts_with("freezer"), + .help_heading(FLAG_HEADER) + .conflicts_with("freezer") + .display_order(0), ) .arg( Arg::new("output-dir") .long("output-dir") .value_name("DIR") .help("Base directory for the output files. Defaults to the current directory") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) } @@ -107,21 +116,26 @@ pub fn compact_cli_app() -> Command { .value_name("TAG") .help("3-byte column ID (see `DBColumn`)") .action(ArgAction::Set) - .required(true), + .required(true) + .display_order(0), ) .arg( Arg::new("freezer") .long("freezer") .help("Inspect the freezer DB rather than the hot DB") .action(ArgAction::SetTrue) - .conflicts_with("blobs-db"), + .help_heading(FLAG_HEADER) + .conflicts_with("blobs-db") + .display_order(0), ) .arg( Arg::new("blobs-db") .long("blobs-db") .help("Inspect the blobs DB rather than the hot DB") .action(ArgAction::SetTrue) - .conflicts_with("freezer"), + .help_heading(FLAG_HEADER) + .conflicts_with("freezer") + .display_order(0), ) } @@ -149,7 +163,9 @@ pub fn prune_states_app() -> Command { "Commit to pruning states irreversably. Without this flag the command will \ just check that the database is capable of being pruned.", ) - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0), ) .styles(get_color_style()) .about("Prune all beacon states from the freezer database") @@ -157,6 +173,7 @@ pub fn prune_states_app() -> Command { pub fn cli_app() -> Command { Command::new(CMD) + .display_order(0) .visible_aliases(["db"]) .styles(get_color_style()) .about("Manage a beacon node database") @@ -169,14 +186,16 @@ pub fn cli_app() -> Command { Cannot be changed after initialization. \ [default: 2048 (mainnet) or 64 (minimal)]", ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new("freezer-dir") .long("freezer-dir") .value_name("DIR") .help("Data directory for the freezer database.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new("blob-prune-margin-epochs") @@ -187,14 +206,16 @@ pub fn cli_app() -> Command { up until data_availability_boundary - blob_prune_margin_epochs.", ) .action(ArgAction::Set) - .default_value("0"), + .default_value("0") + .display_order(0), ) .arg( Arg::new("blobs-dir") .long("blobs-dir") .value_name("DIR") .help("Data directory for the blobs database.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .subcommand(migrate_cli_app()) .subcommand(version_cli_app()) diff --git a/lcli/src/main.rs b/lcli/src/main.rs index d54f6aa3861..8ee6451156d 100644 --- a/lcli/src/main.rs +++ b/lcli/src/main.rs @@ -20,7 +20,7 @@ mod state_root; mod transition_blocks; use clap::{Arg, ArgAction, ArgMatches, Command}; -use clap_utils::parse_optional; +use clap_utils::{parse_optional, FLAG_HEADER}; use environment::{EnvironmentBuilder, LoggerConfig}; use eth2_network_config::Eth2NetworkConfig; use parse_ssz::run_parse_ssz; @@ -34,6 +34,7 @@ fn main() { let matches = Command::new("Lighthouse CLI Tool") .version(lighthouse_version::VERSION) + .display_order(0) .about("Performs various testing-related tasks, including defining testnets.") .arg( Arg::new("spec") @@ -43,7 +44,8 @@ fn main() { .action(ArgAction::Set) .value_parser(["minimal", "mainnet", "gnosis"]) .default_value("mainnet") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("testnet-dir") @@ -52,7 +54,8 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .global(true) - .help("The testnet dir."), + .help("The testnet dir.") + .display_order(0) ) .arg( Arg::new("network") @@ -62,6 +65,7 @@ fn main() { .global(true) .help("The network to use. Defaults to mainnet.") .conflicts_with("testnet-dir") + .display_order(0) ) .subcommand( Command::new("skip-slots") @@ -73,7 +77,8 @@ fn main() { .long("output-path") .value_name("PATH") .action(ArgAction::Set) - .help("Path to output a SSZ file."), + .help("Path to output a SSZ file.") + .display_order(0) ) .arg( Arg::new("pre-state-path") @@ -81,14 +86,16 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .conflicts_with("beacon-url") - .help("Path to a SSZ file of the pre-state."), + .help("Path to a SSZ file of the pre-state.") + .display_order(0) ) .arg( Arg::new("beacon-url") .long("beacon-url") .value_name("URL") .action(ArgAction::Set) - .help("URL to a beacon-API provider."), + .help("URL to a beacon-API provider.") + .display_order(0) ) .arg( Arg::new("state-id") @@ -96,7 +103,8 @@ fn main() { .value_name("STATE_ID") .action(ArgAction::Set) .requires("beacon-url") - .help("Identifier for a state as per beacon-API standards (slot, root, etc.)"), + .help("Identifier for a state as per beacon-API standards (slot, root, etc.)") + .display_order(0) ) .arg( Arg::new("runs") @@ -104,27 +112,32 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .default_value("1") - .help("Number of repeat runs, useful for benchmarking."), + .help("Number of repeat runs, useful for benchmarking.") + .display_order(0) ) .arg( Arg::new("state-root") .long("state-root") .value_name("HASH256") .action(ArgAction::Set) - .help("Tree hash root of the provided state, to avoid computing it."), + .help("Tree hash root of the provided state, to avoid computing it.") + .display_order(0) ) .arg( Arg::new("slots") .long("slots") .value_name("INTEGER") .action(ArgAction::Set) - .help("Number of slots to skip forward."), + .help("Number of slots to skip forward.") + .display_order(0) ) .arg( Arg::new("partial-state-advance") .long("partial-state-advance") .action(ArgAction::SetTrue) - .help("If present, don't compute state roots when skipping forward."), + .help_heading(FLAG_HEADER) + .help("If present, don't compute state roots when skipping forward.") + .display_order(0) ) ) .subcommand( @@ -137,7 +150,8 @@ fn main() { .action(ArgAction::Set) .conflicts_with("beacon-url") .requires("block-path") - .help("Path to load a BeaconState from as SSZ."), + .help("Path to load a BeaconState from as SSZ.") + .display_order(0) ) .arg( Arg::new("block-path") @@ -146,35 +160,40 @@ fn main() { .action(ArgAction::Set) .conflicts_with("beacon-url") .requires("pre-state-path") - .help("Path to load a SignedBeaconBlock from as SSZ."), + .help("Path to load a SignedBeaconBlock from as SSZ.") + .display_order(0) ) .arg( Arg::new("post-state-output-path") .long("post-state-output-path") .value_name("PATH") .action(ArgAction::Set) - .help("Path to output the post-state."), + .help("Path to output the post-state.") + .display_order(0) ) .arg( Arg::new("pre-state-output-path") .long("pre-state-output-path") .value_name("PATH") .action(ArgAction::Set) - .help("Path to output the pre-state, useful when used with --beacon-url."), + .help("Path to output the pre-state, useful when used with --beacon-url.") + .display_order(0) ) .arg( Arg::new("block-output-path") .long("block-output-path") .value_name("PATH") .action(ArgAction::Set) - .help("Path to output the block, useful when used with --beacon-url."), + .help("Path to output the block, useful when used with --beacon-url.") + .display_order(0) ) .arg( Arg::new("beacon-url") .long("beacon-url") .value_name("URL") .action(ArgAction::Set) - .help("URL to a beacon-API provider."), + .help("URL to a beacon-API provider.") + .display_order(0) ) .arg( Arg::new("block-id") @@ -182,7 +201,8 @@ fn main() { .value_name("BLOCK_ID") .action(ArgAction::Set) .requires("beacon-url") - .help("Identifier for a block as per beacon-API standards (slot, root, etc.)"), + .help("Identifier for a block as per beacon-API standards (slot, root, etc.)") + .display_order(0) ) .arg( Arg::new("runs") @@ -190,27 +210,34 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .default_value("1") - .help("Number of repeat runs, useful for benchmarking."), + .help("Number of repeat runs, useful for benchmarking.") + .display_order(0) ) .arg( Arg::new("no-signature-verification") .long("no-signature-verification") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("Disable signature verification.") + .display_order(0) ) .arg( Arg::new("exclude-cache-builds") .long("exclude-cache-builds") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("If present, pre-build the committee and tree-hash caches without \ - including them in the timings."), + including them in the timings.") + .display_order(0) ) .arg( Arg::new("exclude-post-block-thc") .long("exclude-post-block-thc") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("If present, don't rebuild the tree-hash-cache after applying \ - the block."), + the block.") + .display_order(0) ) ) .subcommand( @@ -226,20 +253,23 @@ fn main() { .default_value("json") .value_parser(["json", "yaml"]) .help("Output format to use") + .display_order(0) ) .arg( Arg::new("type") .value_name("TYPE") .action(ArgAction::Set) .required(true) - .help("Type to decode"), + .help("Type to decode") + .display_order(0) ) .arg( Arg::new("ssz-file") .value_name("FILE") .action(ArgAction::Set) .required(true) - .help("Path to SSZ bytes"), + .help("Path to SSZ bytes") + .display_order(0) ) ) .subcommand( @@ -255,6 +285,7 @@ fn main() { .help("Path to an Eth1 JSON-RPC IPC endpoint") .action(ArgAction::Set) .required(true) + .display_order(0) ) .arg( Arg::new("confirmations") @@ -262,7 +293,8 @@ fn main() { .long("confirmations") .action(ArgAction::Set) .default_value("3") - .help("The number of block confirmations before declaring the contract deployed."), + .help("The number of block confirmations before declaring the contract deployed.") + .display_order(0) ) .arg( Arg::new("validator-count") @@ -271,7 +303,8 @@ fn main() { .action(ArgAction::Set) .help("If present, makes `validator_count` number of INSECURE deterministic deposits after \ deploying the deposit contract." - ), + ) + .display_order(0) ) ) .subcommand( @@ -283,7 +316,8 @@ fn main() { .long("eth1-endpoint") .value_name("HTTP_SERVER") .action(ArgAction::Set) - .help("Deprecated. Use --eth1-endpoints."), + .help("Deprecated. Use --eth1-endpoints.") + .display_order(0) ) .arg( Arg::new("eth1-endpoints") @@ -295,7 +329,8 @@ fn main() { "One or more comma-delimited URLs to eth1 JSON-RPC http APIs. \ If multiple endpoints are given the endpoints are used as \ fallback in the given order.", - ), + ) + .display_order(0) ), ) .subcommand( @@ -308,7 +343,8 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .default_value("1024") - .help("The number of validators in the genesis state."), + .help("The number of validators in the genesis state.") + .display_order(0) ) .arg( Arg::new("genesis-time") @@ -316,7 +352,8 @@ fn main() { .short('t') .value_name("UNIX_EPOCH") .action(ArgAction::Set) - .help("The value for state.genesis_time. Defaults to now."), + .help("The value for state.genesis_time. Defaults to now.") + .display_order(0) ) .arg( Arg::new("genesis-fork-version") @@ -326,7 +363,8 @@ fn main() { .help( "Used to avoid reply attacks between testnets. Recommended to set to non-default.", - ), + ) + .display_order(0) ), ) .subcommand( @@ -340,7 +378,8 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .required(true) - .help("The path to the SSZ file"), + .help("The path to the SSZ file") + .display_order(0) ) .arg( Arg::new("genesis-time") @@ -348,7 +387,8 @@ fn main() { .value_name("UNIX_EPOCH") .action(ArgAction::Set) .required(true) - .help("The value for state.genesis_time."), + .help("The value for state.genesis_time.") + .display_order(0) ), ) .subcommand( @@ -365,7 +405,8 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .required(true) - .help("The path to the SSZ file"), + .help("The path to the SSZ file") + .display_order(0) ) .arg( Arg::new("mnemonic") @@ -376,7 +417,8 @@ fn main() { "replace nephew blur decorate waste convince soup column \ orient excite play baby", ) - .help("The mnemonic for key derivation."), + .help("The mnemonic for key derivation.") + .display_order(0) ), ) .subcommand( @@ -394,7 +436,8 @@ fn main() { `execution_payload_header.random`") .default_value( "0x0000000000000000000000000000000000000000000000000000000000000000", - ), + ) + .display_order(0) ) .arg( Arg::new("genesis-time") @@ -402,6 +445,7 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .help("The genesis time when generating an execution payload.") + .display_order(0) ) .arg( Arg::new("base-fee-per-gas") @@ -409,7 +453,8 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .help("The base fee per gas field in the execution payload generated.") - .default_value("1000000000"), + .default_value("1000000000") + .display_order(0) ) .arg( Arg::new("gas-limit") @@ -417,7 +462,8 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .help("The gas limit field in the execution payload generated.") - .default_value("30000000"), + .default_value("30000000") + .display_order(0) ) .arg( Arg::new("file") @@ -425,7 +471,8 @@ fn main() { .value_name("FILE") .action(ArgAction::Set) .required(true) - .help("Output file"), + .help("Output file") + .display_order(0) ).arg( Arg::new("fork") .long("fork") @@ -434,6 +481,7 @@ fn main() { .default_value("bellatrix") .help("The fork for which the execution payload header should be created.") .value_parser(["merge", "bellatrix", "capella", "deneb", "capella"]) + .display_order(0) ) ) .subcommand( @@ -447,23 +495,29 @@ fn main() { .long("force") .short('f') .action(ArgAction::SetTrue) - .help("Overwrites any previous testnet configurations"), + .help_heading(FLAG_HEADER) + .help("Overwrites any previous testnet configurations") + .display_order(0) ) .arg( Arg::new("interop-genesis-state") .long("interop-genesis-state") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help( "If present, a interop-style genesis.ssz file will be generated.", - ), + ) + .display_order(0) ) .arg( Arg::new("derived-genesis-state") .long("derived-genesis-state") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help( "If present, a genesis.ssz file will be generated with keys generated from a given mnemonic.", - ), + ) + .display_order(0) ) .arg( Arg::new("mnemonic-phrase") @@ -471,7 +525,8 @@ fn main() { .value_name("MNEMONIC_PHRASE") .action(ArgAction::Set) .requires("derived-genesis-state") - .help("The mnemonic with which we generate the validator keys for a derived genesis state"), + .help("The mnemonic with which we generate the validator keys for a derived genesis state") + .display_order(0) ) .arg( Arg::new("min-genesis-time") @@ -481,56 +536,64 @@ fn main() { .help( "The minimum permitted genesis time. For non-eth1 testnets will be the genesis time. Defaults to now.", - ), + ) + .display_order(0) ) .arg( Arg::new("min-genesis-active-validator-count") .long("min-genesis-active-validator-count") .value_name("INTEGER") .action(ArgAction::Set) - .help("The number of validators required to trigger eth2 genesis."), + .help("The number of validators required to trigger eth2 genesis.") + .display_order(0) ) .arg( Arg::new("genesis-delay") .long("genesis-delay") .value_name("SECONDS") .action(ArgAction::Set) - .help("The delay between sufficient eth1 deposits and eth2 genesis."), + .help("The delay between sufficient eth1 deposits and eth2 genesis.") + .display_order(0) ) .arg( Arg::new("min-deposit-amount") .long("min-deposit-amount") .value_name("GWEI") .action(ArgAction::Set) - .help("The minimum permitted deposit amount."), + .help("The minimum permitted deposit amount.") + .display_order(0) ) .arg( Arg::new("max-effective-balance") .long("max-effective-balance") .value_name("GWEI") .action(ArgAction::Set) - .help("The amount required to become a validator."), + .help("The amount required to become a validator.") + .display_order(0) ) .arg( Arg::new("effective-balance-increment") .long("effective-balance-increment") .value_name("GWEI") .action(ArgAction::Set) - .help("The steps in effective balance calculation."), + .help("The steps in effective balance calculation.") + .display_order(0) ) .arg( Arg::new("ejection-balance") .long("ejection-balance") .value_name("GWEI") .action(ArgAction::Set) - .help("The balance at which a validator gets ejected."), + .help("The balance at which a validator gets ejected.") + .display_order(0) ) .arg( Arg::new("eth1-follow-distance") .long("eth1-follow-distance") .value_name("ETH1_BLOCKS") .action(ArgAction::Set) - .help("The distance to follow behind the eth1 chain head."), + .help("The distance to follow behind the eth1 chain head.") + .display_order(0) ) .arg( Arg::new("genesis-fork-version") @@ -540,28 +603,32 @@ fn main() { .help( "Used to avoid reply attacks between testnets. Recommended to set to non-default.", - ), + ) + .display_order(0) ) .arg( Arg::new("seconds-per-slot") .long("seconds-per-slot") .value_name("SECONDS") .action(ArgAction::Set) - .help("Eth2 slot time"), + .help("Eth2 slot time") + .display_order(0) ) .arg( Arg::new("seconds-per-eth1-block") .long("seconds-per-eth1-block") .value_name("SECONDS") .action(ArgAction::Set) - .help("Eth1 block time"), + .help("Eth1 block time") + .display_order(0) ) .arg( Arg::new("eth1-id") .long("eth1-id") .value_name("ETH1_ID") .action(ArgAction::Set) - .help("The chain id and network id for the eth1 testnet."), + .help("The chain id and network id for the eth1 testnet.") + .display_order(0) ) .arg( Arg::new("deposit-contract-address") @@ -569,7 +636,8 @@ fn main() { .value_name("ETH1_ADDRESS") .action(ArgAction::Set) .required(true) - .help("The address of the deposit contract."), + .help("The address of the deposit contract.") + .display_order(0) ) .arg( Arg::new("deposit-contract-deploy-block") @@ -580,7 +648,8 @@ fn main() { .help( "The block the deposit contract was deployed. Setting this is a huge optimization for nodes, please do it.", - ), + ) + .display_order(0) ) .arg( Arg::new("altair-fork-epoch") @@ -589,7 +658,8 @@ fn main() { .action(ArgAction::Set) .help( "The epoch at which to enable the Altair hard fork", - ), + ) + .display_order(0) ) .arg( Arg::new("bellatrix-fork-epoch") @@ -598,7 +668,8 @@ fn main() { .action(ArgAction::Set) .help( "The epoch at which to enable the Bellatrix hard fork", - ), + ) + .display_order(0) ) .arg( Arg::new("capella-fork-epoch") @@ -607,7 +678,8 @@ fn main() { .action(ArgAction::Set) .help( "The epoch at which to enable the Capella hard fork", - ), + ) + .display_order(0) ) .arg( Arg::new("deneb-fork-epoch") @@ -616,7 +688,8 @@ fn main() { .action(ArgAction::Set) .help( "The epoch at which to enable the Deneb hard fork", - ), + ) + .display_order(0) ) .arg( Arg::new("electra-fork-epoch") @@ -625,7 +698,8 @@ fn main() { .action(ArgAction::Set) .help( "The epoch at which to enable the Electra hard fork", - ), + ) + .display_order(0) ) .arg( Arg::new("ttd") @@ -634,14 +708,16 @@ fn main() { .action(ArgAction::Set) .help( "The terminal total difficulty", - ), + ) + .display_order(0) ) .arg( Arg::new("eth1-block-hash") .long("eth1-block-hash") .value_name("BLOCK_HASH") .action(ArgAction::Set) - .help("The eth1 block hash used when generating a genesis state."), + .help("The eth1 block hash used when generating a genesis state.") + .display_order(0) ) .arg( Arg::new("execution-payload-header") @@ -650,28 +726,32 @@ fn main() { .action(ArgAction::Set) .required(false) .help("Path to file containing `ExecutionPayloadHeader` SSZ bytes to be \ - used in the genesis state."), + used in the genesis state.") + .display_order(0) ) .arg( Arg::new("validator-count") .long("validator-count") .value_name("INTEGER") .action(ArgAction::Set) - .help("The number of validators when generating a genesis state."), + .help("The number of validators when generating a genesis state.") + .display_order(0) ) .arg( Arg::new("genesis-time") .long("genesis-time") .value_name("INTEGER") .action(ArgAction::Set) - .help("The genesis time when generating a genesis state."), + .help("The genesis time when generating a genesis state.") + .display_order(0) ) .arg( Arg::new("proposer-score-boost") .long("proposer-score-boost") .value_name("INTEGER") .action(ArgAction::Set) - .help("The proposer score boost to apply as a percentage, e.g. 70 = 70%"), + .help("The proposer score boost to apply as a percentage, e.g. 70 = 70%") + .display_order(0) ) ) @@ -684,7 +764,8 @@ fn main() { .value_name("GWEI") .action(ArgAction::Set) .required(true) - .help("The amount (in Gwei) that was deposited"), + .help("The amount (in Gwei) that was deposited") + .display_order(0) ) .arg( Arg::new("deposit-data") @@ -695,7 +776,8 @@ fn main() { .help( "A 0x-prefixed hex string of the deposit data. Should include the function signature.", - ), + ) + .display_order(0) ), ) .subcommand( @@ -707,7 +789,8 @@ fn main() { .value_name("IP_ADDRESS") .action(ArgAction::Set) .required(true) - .help("The IP address to be included in the ENR and used for discovery"), + .help("The IP address to be included in the ENR and used for discovery") + .display_order(0) ) .arg( Arg::new("udp-port") @@ -715,7 +798,8 @@ fn main() { .value_name("UDP_PORT") .action(ArgAction::Set) .required(true) - .help("The UDP port to be included in the ENR and used for discovery"), + .help("The UDP port to be included in the ENR and used for discovery") + .display_order(0) ) .arg( Arg::new("tcp-port") @@ -725,7 +809,8 @@ fn main() { .required(true) .help( "The TCP port to be included in the ENR and used for application comms", - ), + ) + .display_order(0) ) .arg( Arg::new("output-dir") @@ -733,7 +818,8 @@ fn main() { .value_name("OUTPUT_DIRECTORY") .action(ArgAction::Set) .required(true) - .help("The directory in which to create the network dir"), + .help("The directory in which to create the network dir") + .display_order(0) ) .arg( Arg::new("genesis-fork-version") @@ -744,7 +830,8 @@ fn main() { .help( "Used to avoid reply attacks between testnets. Recommended to set to non-default.", - ), + ) + .display_order(0) ), ) .subcommand( @@ -756,7 +843,8 @@ fn main() { .value_name("COUNT") .action(ArgAction::Set) .required(true) - .help("Produces validators in the range of 0..count."), + .help("Produces validators in the range of 0..count.") + .display_order(0) ) .arg( Arg::new("base-dir") @@ -764,14 +852,16 @@ fn main() { .value_name("BASE_DIR") .action(ArgAction::Set) .required(true) - .help("The base directory where validator keypairs and secrets are stored"), + .help("The base directory where validator keypairs and secrets are stored") + .display_order(0) ) .arg( Arg::new("node-count") .long("node-count") .value_name("NODE_COUNT") .action(ArgAction::Set) - .help("The number of nodes to divide the validator keys to"), + .help("The number of nodes to divide the validator keys to") + .display_order(0) ) ) .subcommand( @@ -785,7 +875,8 @@ fn main() { .value_name("COUNT") .action(ArgAction::Set) .required(true) - .help("Produces validators in the range of 0..count."), + .help("Produces validators in the range of 0..count.") + .display_order(0) ) .arg( Arg::new("base-dir") @@ -793,14 +884,16 @@ fn main() { .value_name("BASE_DIR") .action(ArgAction::Set) .required(true) - .help("The base directory where validator keypairs and secrets are stored"), + .help("The base directory where validator keypairs and secrets are stored") + .display_order(0) ) .arg( Arg::new("node-count") .long("node-count") .value_name("NODE_COUNT") .action(ArgAction::Set) - .help("The number of nodes to divide the validator keys to"), + .help("The number of nodes to divide the validator keys to") + .display_order(0) ) .arg( Arg::new("mnemonic-phrase") @@ -808,7 +901,8 @@ fn main() { .value_name("MNEMONIC_PHRASE") .action(ArgAction::Set) .required(true) - .help("The mnemonic with which we generate the validator keys"), + .help("The mnemonic with which we generate the validator keys") + .display_order(0) ) ) .subcommand( @@ -820,7 +914,8 @@ fn main() { .value_name("SSZ_STATE") .action(ArgAction::Set) .required(true) - .help("BeaconState to generate committees from (SSZ)"), + .help("BeaconState to generate committees from (SSZ)") + .display_order(0) ) .arg( Arg::new("attestations") @@ -828,7 +923,8 @@ fn main() { .value_name("JSON_ATTESTATIONS") .action(ArgAction::Set) .required(true) - .help("List of Attestations to convert to indexed form (JSON)"), + .help("List of Attestations to convert to indexed form (JSON)") + .display_order(0) ) ) .subcommand( @@ -840,14 +936,16 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .conflicts_with("beacon-url") - .help("Path to load a SignedBeaconBlock from as SSZ."), + .help("Path to load a SignedBeaconBlock from as SSZ.") + .display_order(0) ) .arg( Arg::new("beacon-url") .long("beacon-url") .value_name("URL") .action(ArgAction::Set) - .help("URL to a beacon-API provider."), + .help("URL to a beacon-API provider.") + .display_order(0) ) .arg( Arg::new("block-id") @@ -855,7 +953,8 @@ fn main() { .value_name("BLOCK_ID") .action(ArgAction::Set) .requires("beacon-url") - .help("Identifier for a block as per beacon-API standards (slot, root, etc.)"), + .help("Identifier for a block as per beacon-API standards (slot, root, etc.)") + .display_order(0) ) .arg( Arg::new("runs") @@ -863,7 +962,8 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .default_value("1") - .help("Number of repeat runs, useful for benchmarking."), + .help("Number of repeat runs, useful for benchmarking.") + .display_order(0) ) ) .subcommand( @@ -875,14 +975,16 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .conflicts_with("beacon-url") - .help("Path to load a BeaconState from as SSZ."), + .help("Path to load a BeaconState from as SSZ.") + .display_order(0) ) .arg( Arg::new("beacon-url") .long("beacon-url") .value_name("URL") .action(ArgAction::Set) - .help("URL to a beacon-API provider."), + .help("URL to a beacon-API provider.") + .display_order(0) ) .arg( Arg::new("state-id") @@ -890,7 +992,8 @@ fn main() { .value_name("BLOCK_ID") .action(ArgAction::Set) .requires("beacon-url") - .help("Identifier for a state as per beacon-API standards (slot, root, etc.)"), + .help("Identifier for a state as per beacon-API standards (slot, root, etc.)") + .display_order(0) ) .arg( Arg::new("runs") @@ -898,7 +1001,8 @@ fn main() { .value_name("INTEGER") .action(ArgAction::Set) .default_value("1") - .help("Number of repeat runs, useful for benchmarking."), + .help("Number of repeat runs, useful for benchmarking.") + .display_order(0) ) ) .subcommand( @@ -912,7 +1016,8 @@ fn main() { .value_name("PATH") .action(ArgAction::Set) .required(true) - .help("Path to write the JWT secret."), + .help("Path to write the JWT secret.") + .display_order(0) ) .arg( Arg::new("listen-address") @@ -921,6 +1026,7 @@ fn main() { .action(ArgAction::Set) .help("The server will listen on this address.") .default_value("127.0.0.1") + .display_order(0) ) .arg( Arg::new("listen-port") @@ -929,6 +1035,7 @@ fn main() { .action(ArgAction::Set) .help("The server will listen on this port.") .default_value("8551") + .display_order(0) ) .arg( Arg::new("all-payloads-valid") @@ -938,6 +1045,7 @@ fn main() { Set to 'true' to return VALID. Set to 'false' to return SYNCING.") .default_value("false") .hide(true) + .display_order(0) ) .arg( Arg::new("shanghai-time") @@ -946,6 +1054,7 @@ fn main() { .action(ArgAction::Set) .help("The payload timestamp that enables Shanghai. Defaults to the mainnet value.") .default_value("1681338479") + .display_order(0) ) .arg( Arg::new("cancun-time") @@ -954,6 +1063,7 @@ fn main() { .action(ArgAction::Set) .help("The payload timestamp that enables Cancun. No default is provided \ until Cancun is triggered on mainnet.") + .display_order(0) ) .arg( Arg::new("prague-time") @@ -962,6 +1072,7 @@ fn main() { .action(ArgAction::Set) .help("The payload timestamp that enables Prague. No default is provided \ until Prague is triggered on mainnet.") + .display_order(0) ) ) .get_matches(); diff --git a/lighthouse/src/main.rs b/lighthouse/src/main.rs index c27a9724a29..118e2dd9bf7 100644 --- a/lighthouse/src/main.rs +++ b/lighthouse/src/main.rs @@ -83,13 +83,15 @@ fn main() { node, a validator client and utilities for managing validator accounts.", ) .long_version(LONG_VERSION.as_str()) + .display_order(0) .arg( Arg::new("env_log") .short('l') .help( "DEPRECATED Enables environment logging giving access to sub-protocol logs such as discv5 and libp2p", ) - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .display_order(0) ) .arg( Arg::new("logfile") @@ -102,7 +104,8 @@ fn main() { Once the number of log files exceeds the value specified in \ `--logfile-max-number` the oldest log file will be overwritten.") .action(ArgAction::Set) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("logfile-debug-level") @@ -112,7 +115,8 @@ fn main() { .action(ArgAction::Set) .value_parser(["info", "debug", "trace", "warn", "error", "crit"]) .default_value("debug") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("logfile-format") @@ -122,6 +126,7 @@ fn main() { .value_parser(["DEFAULT", "JSON"]) .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("logfile-max-size") @@ -132,7 +137,8 @@ fn main() { to 0, background file logging is disabled.") .action(ArgAction::Set) .default_value("200") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("logfile-max-number") @@ -143,7 +149,8 @@ fn main() { background file logging is disabled.") .action(ArgAction::Set) .default_value("5") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("logfile-compress") @@ -152,7 +159,8 @@ fn main() { .help( "If present, compress old log files. This can help reduce the space needed \ to store old logs.") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("logfile-no-restricted-perms") @@ -163,7 +171,8 @@ fn main() { any user on the machine. Note that logs can often contain sensitive information \ about your validator and so this flag should be used with caution. For Windows users, \ the log file permissions will be inherited from the parent folder.") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("log-format") @@ -172,7 +181,8 @@ fn main() { .help("Specifies the log format used when emitting logs to the terminal.") .value_parser(["JSON"]) .action(ArgAction::Set) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("log-color") @@ -180,14 +190,16 @@ fn main() { .alias("log-colour") .help("Force outputting colors when emitting logs to the terminal.") .action(ArgAction::SetTrue) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("disable-log-timestamp") .long("disable-log-timestamp") .action(ArgAction::SetTrue) .help("If present, do not include timestamps in logging output.") - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("debug-level") @@ -197,7 +209,8 @@ fn main() { .action(ArgAction::Set) .value_parser(["info", "debug", "trace", "warn", "error", "crit"]) .global(true) - .default_value("info"), + .default_value("info") + .display_order(0) ) .arg( Arg::new("datadir") @@ -209,7 +222,8 @@ fn main() { "Used to specify a custom root data directory for lighthouse keys and databases. \ Defaults to $HOME/.lighthouse/{network} where network is the value of the `network` flag \ Note: Users should specify separate custom datadirs for different networks.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("testnet-dir") @@ -222,7 +236,8 @@ fn main() { existing database.", ) .action(ArgAction::Set) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("network") @@ -233,7 +248,7 @@ fn main() { .conflicts_with("testnet-dir") .action(ArgAction::Set) .global(true) - + .display_order(0) ) .arg( Arg::new("dump-config") @@ -242,6 +257,7 @@ fn main() { .help("Dumps the config to a desired location. Used for testing only.") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("dump-chain-config") @@ -250,6 +266,7 @@ fn main() { .help("Dumps the chain config to a desired location. Used for testing only.") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("immediate-shutdown") @@ -260,6 +277,7 @@ fn main() { "Shuts down immediately after the Beacon Node or Validator has successfully launched. \ Used for testing only, DO NOT USE IN PRODUCTION.") .global(true) + .display_order(0) ) .arg( Arg::new(DISABLE_MALLOC_TUNING_FLAG) @@ -270,7 +288,8 @@ fn main() { specific memory allocation issues." ) .action(ArgAction::SetTrue) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("terminal-total-difficulty-override") @@ -284,6 +303,7 @@ fn main() { failure. Be extremely careful with this flag.") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("terminal-block-hash-override") @@ -297,6 +317,7 @@ fn main() { .requires("terminal-block-hash-epoch-override") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("terminal-block-hash-epoch-override") @@ -310,6 +331,7 @@ fn main() { .requires("terminal-block-hash-override") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("safe-slots-to-import-optimistically") @@ -323,6 +345,7 @@ fn main() { this flag.") .action(ArgAction::Set) .global(true) + .display_order(0) ) .arg( Arg::new("genesis-state-url") @@ -335,7 +358,8 @@ fn main() { If the genesis state is already included in this binary then this value will be ignored.", ) .action(ArgAction::Set) - .global(true), + .global(true) + .display_order(0) ) .arg( Arg::new("genesis-state-url-timeout") @@ -346,7 +370,8 @@ fn main() { ) .action(ArgAction::Set) .default_value("180") - .global(true), + .global(true) + .display_order(0) ) .subcommand(beacon_node::cli_app()) .subcommand(boot_node::cli_app()) diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index 70e6ee7bcb7..ed91712b056 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -1,5 +1,5 @@ use clap::{builder::ArgPredicate, Arg, ArgAction, Command}; -use clap_utils::get_color_style; +use clap_utils::{get_color_style, FLAG_HEADER}; pub fn cli_app() -> Command { Command::new("validator_client") @@ -16,7 +16,8 @@ pub fn cli_app() -> Command { .help("Comma-separated addresses to one or more beacon node HTTP APIs. \ Default is http://localhost:5052." ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("proposer-nodes") @@ -25,7 +26,8 @@ pub fn cli_app() -> Command { .help("Comma-separated addresses to one or more beacon node HTTP APIs. \ These specify nodes that are used to send beacon block proposals. A failure will revert back to the standard beacon nodes specified in --beacon-nodes." ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) // TODO remove this flag in a future release .arg( @@ -37,7 +39,9 @@ pub fn cli_app() -> Command { and proposer preparation messages to all beacon nodes provided in the \ `--beacon-nodes flag`. This option changes that behaviour such that these \ api calls only go out to the first available and synced beacon node") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("broadcast") @@ -48,7 +52,8 @@ pub fn cli_app() -> Command { sync-committee. Default (when flag is omitted) is to broadcast \ subscriptions only." ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("validators-dir") @@ -62,6 +67,7 @@ pub fn cli_app() -> Command { ) .action(ArgAction::Set) .conflicts_with("datadir") + .display_order(0) ) .arg( Arg::new("secrets-dir") @@ -75,11 +81,13 @@ pub fn cli_app() -> Command { ) .action(ArgAction::Set) .conflicts_with("datadir") + .display_order(0) ) .arg( Arg::new("init-slashing-protection") .long("init-slashing-protection") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help( "If present, do not require the slashing protection database to exist before \ running. You SHOULD NOT use this flag unless you're certain that a new \ @@ -87,23 +95,28 @@ pub fn cli_app() -> Command { will have been initialized when you imported your validator keys. If you \ misplace your database and then run with this flag you risk being slashed." ) + .display_order(0) ) .arg( Arg::new("disable-auto-discover") .long("disable-auto-discover") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help( "If present, do not attempt to discover new validators in the validators-dir. Validators \ will need to be manually added to the validator_definitions.yml file." ) + .display_order(0) ) .arg( Arg::new("use-long-timeouts") .long("use-long-timeouts") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .help("If present, the validator client will use longer timeouts for requests \ made to the beacon node. This flag is generally not recommended, \ longer timeouts can cause missed duties when fallbacks are used.") + .display_order(0) ) .arg( Arg::new("beacon-nodes-tls-certs") @@ -114,6 +127,7 @@ pub fn cli_app() -> Command { to a beacon node (and/or proposer node). These certificates must be in PEM format and are used \ in addition to the OS trust store. Commas must only be used as a \ delimiter, and must not be part of the certificate path.") + .display_order(0) ) // This overwrites the graffiti configured in the beacon node. .arg( @@ -122,6 +136,7 @@ pub fn cli_app() -> Command { .help("Specify your custom graffiti to be included in blocks.") .value_name("GRAFFITI") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("graffiti-file") @@ -130,6 +145,7 @@ pub fn cli_app() -> Command { .value_name("GRAFFITI-FILE") .action(ArgAction::Set) .conflicts_with("graffiti") + .display_order(0) ) .arg( Arg::new("suggested-fee-recipient") @@ -139,6 +155,7 @@ pub fn cli_app() -> Command { configured in the validator definitions it takes priority over this value.") .value_name("FEE-RECIPIENT") .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("produce-block-v3") @@ -148,19 +165,25 @@ pub fn cli_app() -> Command { that has this endpoint implemented. This flag will be enabled by default in \ future.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("distributed") .long("distributed") .help("Enables functionality required for running the validator in a distributed validator cluster.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* REST API related arguments */ .arg( Arg::new("http") .long("http") .help("Enable the RESTful HTTP API server. Disabled by default.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* * Note: The HTTP server is **not** encrypted (i.e., not HTTPS) and therefore it is @@ -180,7 +203,8 @@ pub fn cli_app() -> Command { `--unencrypted-http-transport` flag to ensure the user is aware of the \ risks involved. For access via the Internet, users should apply \ transport-layer security like a HTTPS reverse-proxy or SSH tunnelling.") - .requires("unencrypted-http-transport"), + .requires("unencrypted-http-transport") + .display_order(0) ) .arg( Arg::new("unencrypted-http-transport") @@ -188,7 +212,9 @@ pub fn cli_app() -> Command { .help("This is a safety flag to ensure that the user is aware that the http \ transport is unencrypted and using a custom HTTP address is unsafe.") .action(ArgAction::SetTrue) - .requires("http-address"), + .help_heading(FLAG_HEADER) + .requires("http-address") + .display_order(0) ) .arg( Arg::new("http-port") @@ -197,7 +223,8 @@ pub fn cli_app() -> Command { .value_name("PORT") .help("Set the listen TCP port for the RESTful HTTP API server.") .default_value_if("http", ArgPredicate::IsPresent, "5062") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-allow-origin") @@ -208,7 +235,8 @@ pub fn cli_app() -> Command { Use * to allow any origin (not recommended in production). \ If no value is supplied, the CORS allowed origin is set to the listen \ address of this server (e.g., http://localhost:5062).") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("http-allow-keystore-export") @@ -219,7 +247,9 @@ pub fn cli_app() -> Command { consumers who have access to the API token. This method is useful for \ exporting validators, however it should be used with caution since it \ exposes private key data to authorized users.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("http-store-passwords-in-secrets-dir") @@ -228,14 +258,18 @@ pub fn cli_app() -> Command { .help("If present, any validators created via the HTTP will have keystore \ passwords stored in the secrets-dir rather than the validator \ definitions file.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* Prometheus metrics HTTP server related arguments */ .arg( Arg::new("metrics") .long("metrics") .help("Enable the Prometheus metrics HTTP server. Disabled by default.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("metrics-address") @@ -244,7 +278,8 @@ pub fn cli_app() -> Command { .value_name("ADDRESS") .help("Set the listen address for the Prometheus metrics HTTP server.") .default_value_if("metrics", ArgPredicate::IsPresent, "127.0.0.1") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("metrics-port") @@ -253,7 +288,8 @@ pub fn cli_app() -> Command { .value_name("PORT") .help("Set the listen TCP port for the Prometheus metrics HTTP server.") .default_value_if("metrics", ArgPredicate::IsPresent, "5064") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("metrics-allow-origin") @@ -264,7 +300,8 @@ pub fn cli_app() -> Command { Use * to allow any origin (not recommended in production). \ If no value is supplied, the CORS allowed origin is set to the listen \ address of this server (e.g., http://localhost:5064).") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enable-high-validator-count-metrics") @@ -273,7 +310,9 @@ pub fn cli_app() -> Command { Note: This flag is automatically enabled for <= 64 validators. \ Enabling this metric for higher validator counts will lead to higher volume \ of prometheus metrics being collected.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* * Explorer metrics @@ -288,7 +327,8 @@ pub fn cli_app() -> Command { Note: This will send information to a remote sever which may identify and associate your \ validators, IP address and other personal information. Always use a HTTPS connection \ and never provide an untrusted URL.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("monitoring-endpoint-period") @@ -297,7 +337,8 @@ pub fn cli_app() -> Command { .help("Defines how many seconds to wait between each message sent to \ the monitoring-endpoint. Default: 60s") .requires("monitoring-endpoint") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("enable-doppelganger-protection") @@ -312,7 +353,9 @@ pub fn cli_app() -> Command { to avoid potentially committing a slashable offense. Use this flag in order to \ ENABLE this functionality, without this flag Lighthouse will begin attesting \ immediately.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("builder-proposals") @@ -321,7 +364,9 @@ pub fn cli_app() -> Command { .help("If this flag is set, Lighthouse will query the Beacon Node for only block \ headers during proposals and will sign over headers. Useful for outsourcing \ execution payload construction during proposals.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("builder-registration-timestamp-override") @@ -329,7 +374,8 @@ pub fn cli_app() -> Command { .alias("builder-registration-timestamp-override") .help("This flag takes a unix timestamp value that will be used to override the \ timestamp used in the builder api registration") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("gas-limit") @@ -339,14 +385,17 @@ pub fn cli_app() -> Command { .help("The gas limit to be used in all builder proposals for all validators managed \ by this validator client. Note this will not necessarily be used if the gas limit \ set here moves too far from the previous block's gas limit. [default: 30,000,000]") - .requires("builder-proposals"), + .requires("builder-proposals") + .display_order(0) ) .arg( // TODO take note here Arg::new("disable-latency-measurement-service") .long("disable-latency-measurement-service") .help("Disables the service that periodically attempts to measure latency to BNs.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("validator-registration-batch-size") @@ -356,7 +405,8 @@ pub fn cli_app() -> Command { validator/register_validator request sent to the BN. This value \ can be reduced to avoid timeouts from builders.") .default_value("500") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("builder-boost-factor") @@ -367,14 +417,17 @@ pub fn cli_app() -> Command { when choosing between a builder payload header and payload from \ the local execution node.") .conflicts_with("prefer-builder-proposals") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("prefer-builder-proposals") .long("prefer-builder-proposals") .help("If this flag is set, Lighthouse will always prefer blocks \ constructed by builders, regardless of payload value.") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) .arg( Arg::new("disable-slashing-protection-web3signer") @@ -386,6 +439,8 @@ pub fn cli_app() -> Command { THE REMOTE SIGNER. YOU WILL GET SLASHED IF YOU USE THIS FLAG WITHOUT \ ENABLING WEB3SIGNER'S SLASHING PROTECTION.") .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0) ) /* * Experimental/development options. @@ -397,7 +452,8 @@ pub fn cli_app() -> Command { .default_value("90000") .help("Keep-alive timeout for each web3signer connection. Set to 'null' to never \ timeout") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) .arg( Arg::new("web3-signer-max-idle-connections") @@ -405,6 +461,7 @@ pub fn cli_app() -> Command { .value_name("COUNT") .help("Maximum number of idle connections to maintain per web3signer host. Default \ is unlimited.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0) ) } diff --git a/validator_manager/src/create_validators.rs b/validator_manager/src/create_validators.rs index 1ddb6da9cad..762cef9bc0f 100644 --- a/validator_manager/src/create_validators.rs +++ b/validator_manager/src/create_validators.rs @@ -2,6 +2,7 @@ use super::common::*; use crate::DumpConfig; use account_utils::{random_password_string, read_mnemonic_from_cli, read_password_from_user}; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use eth2::{ lighthouse_vc::std_types::KeystoreJsonStr, types::{StateId, ValidatorId}, @@ -53,7 +54,8 @@ pub fn cli_app() -> Command { files will be created. The directory will be created if it does not exist.", ) .required(true) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(DEPOSIT_GWEI_FLAG) @@ -64,7 +66,8 @@ pub fn cli_app() -> Command { required for an active validator (MAX_EFFECTIVE_BALANCE)", ) .conflicts_with(DISABLE_DEPOSITS_FLAG) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(FIRST_INDEX_FLAG) @@ -73,7 +76,8 @@ pub fn cli_app() -> Command { .help("The first of consecutive key indexes you wish to create.") .action(ArgAction::Set) .required(false) - .default_value("0"), + .default_value("0") + .display_order(0), ) .arg( Arg::new(COUNT_FLAG) @@ -81,21 +85,25 @@ pub fn cli_app() -> Command { .value_name("VALIDATOR_COUNT") .help("The number of validators to create, regardless of how many already exist") .conflicts_with("at-most") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(MNEMONIC_FLAG) .long(MNEMONIC_FLAG) .value_name("MNEMONIC_PATH") .help("If present, the mnemonic will be read in from this file.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(STDIN_INPUTS_FLAG) .action(ArgAction::SetTrue) .hide(cfg!(windows)) .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), + .help("If present, read all user inputs from stdin instead of tty.") + .display_order(0) + .help_heading(FLAG_HEADER), ) .arg( Arg::new(DISABLE_DEPOSITS_FLAG) @@ -106,7 +114,9 @@ pub fn cli_app() -> Command { Using this flag will save several seconds per validator if the \ user has an alternate strategy for submitting deposits.", ) - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0), ) .arg( Arg::new(SPECIFY_VOTING_KEYSTORE_PASSWORD_FLAG) @@ -118,7 +128,9 @@ pub fn cli_app() -> Command { necessary to keep backups of voting keystore passwords if the \ mnemonic is safely backed up.", ) - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) + .display_order(0), ) .arg( Arg::new(ETH1_WITHDRAWAL_ADDRESS_FLAG) @@ -130,7 +142,8 @@ pub fn cli_app() -> Command { with the mnemonic-derived withdrawal public key in EIP-2334 format.", ) .conflicts_with(DISABLE_DEPOSITS_FLAG) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(GAS_LIMIT_FLAG) @@ -141,7 +154,8 @@ pub fn cli_app() -> Command { to leave this as the default value by not specifying this flag.", ) .required(false) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(FEE_RECIPIENT_FLAG) @@ -152,7 +166,8 @@ pub fn cli_app() -> Command { fee recipient. Omit this flag to use the default value from the VC.", ) .required(false) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(BUILDER_PROPOSALS_FLAG) @@ -163,7 +178,8 @@ pub fn cli_app() -> Command { ) .required(false) .value_parser(["true", "false"]) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(BEACON_NODE_FLAG) @@ -176,16 +192,19 @@ pub fn cli_app() -> Command { prevent the same validator being created twice and therefore slashable \ conditions.", ) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(FORCE_BLS_WITHDRAWAL_CREDENTIALS) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long(FORCE_BLS_WITHDRAWAL_CREDENTIALS) .help( "If present, allows BLS withdrawal credentials rather than an execution \ address. This is not recommended.", - ), + ) + .display_order(0), ) .arg( Arg::new(BUILDER_BOOST_FACTOR_FLAG) @@ -198,7 +217,8 @@ pub fn cli_app() -> Command { a percentage multiplier to apply to the builder's payload value \ when choosing between a builder payload header and payload from \ the local execution node.", - ), + ) + .display_order(0), ) .arg( Arg::new(PREFER_BUILDER_PROPOSALS_FLAG) @@ -209,7 +229,8 @@ pub fn cli_app() -> Command { ) .required(false) .value_parser(["true", "false"]) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) } diff --git a/validator_manager/src/import_validators.rs b/validator_manager/src/import_validators.rs index e5bb7343785..b72ecf1f55e 100644 --- a/validator_manager/src/import_validators.rs +++ b/validator_manager/src/import_validators.rs @@ -1,6 +1,7 @@ use super::common::*; use crate::DumpConfig; use clap::{Arg, ArgAction, ArgMatches, Command}; +use clap_utils::FLAG_HEADER; use eth2::{lighthouse_vc::std_types::ImportKeystoreStatus, SensitiveUrl}; use serde::{Deserialize, Serialize}; use std::fs; @@ -30,7 +31,8 @@ pub fn cli_app() -> Command { \"validators.json\".", ) .required(true) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(VC_URL_FLAG) @@ -43,18 +45,21 @@ pub fn cli_app() -> Command { ) .default_value("http://localhost:5062") .requires(VC_TOKEN_FLAG) - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(VC_TOKEN_FLAG) .long(VC_TOKEN_FLAG) .value_name("PATH") .help("The file containing a token required by the validator client.") - .action(ArgAction::Set), + .action(ArgAction::Set) + .display_order(0), ) .arg( Arg::new(IGNORE_DUPLICATES_FLAG) .action(ArgAction::SetTrue) + .help_heading(FLAG_HEADER) .long(IGNORE_DUPLICATES_FLAG) .help( "If present, ignore any validators which already exist on the VC. \ @@ -63,7 +68,8 @@ pub fn cli_app() -> Command { slashable conditions, it might be an indicator that something is amiss. \ Users should also be careful to avoid submitting duplicate deposits for \ validators that already exist on the VC.", - ), + ) + .display_order(0), ) } diff --git a/validator_manager/src/lib.rs b/validator_manager/src/lib.rs index bf1f7898201..297bf397f5e 100644 --- a/validator_manager/src/lib.rs +++ b/validator_manager/src/lib.rs @@ -1,4 +1,5 @@ use clap::{ArgMatches, Command}; +use clap_utils::get_color_style; use common::write_to_json_file; use environment::Environment; use serde::Serialize; @@ -40,6 +41,8 @@ impl DumpConfig { pub fn cli_app() -> Command { Command::new(CMD) .visible_aliases(["vm", "validator-manager", CMD]) + .display_order(0) + .styles(get_color_style()) .about("Utilities for managing a Lighthouse validator client via the HTTP API.") .subcommand(create_validators::cli_app()) .subcommand(import_validators::cli_app())