upgrade clap to v4.5 (#5273)

* upgrade clap to v4.5

* cli fixes

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into upgrade-clap-cli

* value parser for mnemonic

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into upgrade-clap-cli

* merge unstable

* default --format val

* fix eth sim

* fix eth sim

* merge conflicts

* resolve beta compiler issue

* add num args, version

* add custom flag parser, make rate limiter flags clap friendly

* remove unneeded check

* fmt

* update

* alphabetic order

* resolve merge conflict

* fix test

* resolve conflicts

* fix test

* revert removed if statement

* fmt got me again

* fix broken flag

* make cli

* make cli

* update

* remove -e files

* update

* cli help updates

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into upgrade-clap-cli

* cli help updates

* md files

* merge conflict

* merge conflicts

* md

* help text, text width, and a few flag fixes

* fmt

* merge

* revert

* revert

* resolve merge conflicts

* merge conflicts

* revert simulator changes

* require at least one arg

* fix eth sim cli

* resolve merge conflicts

* book changes

* md changes

* cli check

* cli check

* retry cli check

* retry cli check

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into upgrade-clap-cli

* cli

* Merge remote-tracking branch 'origin/unstable' into upgrade-clap-cli

* Update CLI docs for Goerli removal

* Fix cargo lock
This commit is contained in:
Eitan Seri-Levi
2024-05-28 07:46:39 +02:00
committed by GitHub
parent 6a7305a487
commit df983a83e1
61 changed files with 4036 additions and 2868 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -5,9 +5,9 @@ use beacon_chain::chain_config::{
};
use beacon_chain::graffiti_calculator::GraffitiOrigin;
use beacon_chain::TrustedSetup;
use clap::ArgMatches;
use clap::{parser::ValueSource, ArgMatches, Id};
use clap_utils::flags::DISABLE_MALLOC_TUNING_FLAG;
use clap_utils::parse_required;
use clap_utils::{parse_flag, parse_required};
use client::{ClientConfig, ClientGenesis};
use directory::{DEFAULT_BEACON_NODE_DIR, DEFAULT_NETWORK_DIR, DEFAULT_ROOT_DIR};
use environment::RuntimeContext;
@@ -50,7 +50,7 @@ pub fn get_config<E: EthSpec>(
client_config.set_data_dir(get_data_dir(cli_args));
// If necessary, remove any existing database and configuration
if client_config.data_dir().exists() && cli_args.is_present("purge-db") {
if client_config.data_dir().exists() && cli_args.get_flag("purge-db") {
// Remove the chain_db.
let chain_db = client_config.get_db_path();
if chain_db.exists() {
@@ -96,7 +96,7 @@ pub fn get_config<E: EthSpec>(
* Note: the config values set here can be overwritten by other more specific cli params
*/
if cli_args.is_present("staking") {
if cli_args.get_flag("staking") {
client_config.http_api.enabled = true;
client_config.sync_eth1_chain = true;
}
@@ -105,22 +105,22 @@ pub fn get_config<E: EthSpec>(
* Http API server
*/
if cli_args.is_present("enable_http") {
if cli_args.get_one::<Id>("enable_http").is_some() {
client_config.http_api.enabled = true;
if let Some(address) = cli_args.value_of("http-address") {
if let Some(address) = cli_args.get_one::<String>("http-address") {
client_config.http_api.listen_addr = address
.parse::<IpAddr>()
.map_err(|_| "http-address is not a valid IP address.")?;
}
if let Some(port) = cli_args.value_of("http-port") {
if let Some(port) = cli_args.get_one::<String>("http-port") {
client_config.http_api.listen_port = port
.parse::<u16>()
.map_err(|_| "http-port is not a valid u16.")?;
}
if let Some(allow_origin) = cli_args.value_of("http-allow-origin") {
if let Some(allow_origin) = cli_args.get_one::<String>("http-allow-origin") {
// Pre-validate the config value to give feedback to the user on node startup, instead of
// as late as when the first API response is produced.
hyper::header::HeaderValue::from_str(allow_origin)
@@ -129,7 +129,7 @@ pub fn get_config<E: EthSpec>(
client_config.http_api.allow_origin = Some(allow_origin.to_string());
}
if cli_args.is_present("http-spec-fork") {
if cli_args.get_one::<String>("http-spec-fork").is_some() {
warn!(
log,
"Ignoring --http-spec-fork";
@@ -137,22 +137,22 @@ pub fn get_config<E: EthSpec>(
);
}
if cli_args.is_present("http-enable-tls") {
if cli_args.get_flag("http-enable-tls") {
client_config.http_api.tls_config = Some(TlsConfig {
cert: cli_args
.value_of("http-tls-cert")
.get_one::<String>("http-tls-cert")
.ok_or("--http-tls-cert was not provided.")?
.parse::<PathBuf>()
.map_err(|_| "http-tls-cert is not a valid path name.")?,
key: cli_args
.value_of("http-tls-key")
.get_one::<String>("http-tls-key")
.ok_or("--http-tls-key was not provided.")?
.parse::<PathBuf>()
.map_err(|_| "http-tls-key is not a valid path name.")?,
});
}
if cli_args.is_present("http-allow-sync-stalled") {
if cli_args.get_flag("http-allow-sync-stalled") {
warn!(
log,
"Ignoring --http-allow-sync-stalled";
@@ -170,10 +170,10 @@ pub fn get_config<E: EthSpec>(
parse_required(cli_args, "http-duplicate-block-status")?;
client_config.http_api.enable_light_client_server =
cli_args.is_present("light-client-server");
cli_args.get_flag("light-client-server");
}
if cli_args.is_present("light-client-server") {
if cli_args.get_flag("light-client-server") {
client_config.chain.enable_light_client_server = true;
}
@@ -185,23 +185,23 @@ pub fn get_config<E: EthSpec>(
* Prometheus metrics HTTP server
*/
if cli_args.is_present("metrics") {
if cli_args.get_flag("metrics") {
client_config.http_metrics.enabled = true;
}
if let Some(address) = cli_args.value_of("metrics-address") {
if let Some(address) = cli_args.get_one::<String>("metrics-address") {
client_config.http_metrics.listen_addr = address
.parse::<IpAddr>()
.map_err(|_| "metrics-address is not a valid IP address.")?;
}
if let Some(port) = cli_args.value_of("metrics-port") {
if let Some(port) = cli_args.get_one::<String>("metrics-port") {
client_config.http_metrics.listen_port = port
.parse::<u16>()
.map_err(|_| "metrics-port is not a valid u16.")?;
}
if let Some(allow_origin) = cli_args.value_of("metrics-allow-origin") {
if let Some(allow_origin) = cli_args.get_one::<String>("metrics-allow-origin") {
// Pre-validate the config value to give feedback to the user on node startup, instead of
// as late as when the first API response is produced.
hyper::header::HeaderValue::from_str(allow_origin)
@@ -213,7 +213,7 @@ pub fn get_config<E: EthSpec>(
/*
* Explorer metrics
*/
if let Some(monitoring_endpoint) = cli_args.value_of("monitoring-endpoint") {
if let Some(monitoring_endpoint) = cli_args.get_one::<String>("monitoring-endpoint") {
let update_period_secs =
clap_utils::parse_optional(cli_args, "monitoring-endpoint-period")?;
@@ -227,7 +227,7 @@ pub fn get_config<E: EthSpec>(
// Log a warning indicating an open HTTP server if it wasn't specified explicitly
// (e.g. using the --staking flag).
if cli_args.is_present("staking") {
if cli_args.get_flag("staking") {
warn!(
log,
"Running HTTP server on port {}", client_config.http_api.listen_port
@@ -235,7 +235,7 @@ pub fn get_config<E: EthSpec>(
}
// Do not scrape for malloc metrics if we've disabled tuning malloc as it may cause panics.
if cli_args.is_present(DISABLE_MALLOC_TUNING_FLAG) {
if cli_args.get_flag(DISABLE_MALLOC_TUNING_FLAG) {
client_config.http_metrics.allocator_metrics_enabled = false;
}
@@ -246,24 +246,24 @@ pub fn get_config<E: EthSpec>(
// When present, use an eth1 backend that generates deterministic junk.
//
// Useful for running testnets without the overhead of a deposit contract.
if cli_args.is_present("dummy-eth1") {
if cli_args.get_flag("dummy-eth1") {
client_config.dummy_eth1_backend = true;
}
// When present, attempt to sync to an eth1 node.
//
// Required for block production.
if cli_args.is_present("eth1") {
if cli_args.get_flag("eth1") {
client_config.sync_eth1_chain = true;
}
if let Some(val) = cli_args.value_of("eth1-blocks-per-log-query") {
if let Some(val) = cli_args.get_one::<String>("eth1-blocks-per-log-query") {
client_config.eth1.blocks_per_log_query = val
.parse()
.map_err(|_| "eth1-blocks-per-log-query is not a valid integer".to_string())?;
}
if cli_args.is_present("eth1-purge-cache") {
if cli_args.get_flag("eth1-purge-cache") {
client_config.eth1.purge_cache = true;
}
@@ -273,7 +273,7 @@ pub fn get_config<E: EthSpec>(
client_config.eth1.cache_follow_distance = Some(follow_distance);
}
if let Some(endpoints) = cli_args.value_of("execution-endpoint") {
if let Some(endpoints) = cli_args.get_one::<String>("execution-endpoint") {
let mut el_config = execution_layer::Config::default();
// Always follow the deposit contract when there is an execution endpoint.
@@ -296,13 +296,14 @@ pub fn get_config<E: EthSpec>(
let secret_file: PathBuf;
// Parse a single JWT secret from a given file_path, logging warnings if multiple are supplied.
if let Some(secret_files) = cli_args.value_of("execution-jwt") {
if let Some(secret_files) = cli_args.get_one::<String>("execution-jwt") {
secret_file =
parse_only_one_value(secret_files, PathBuf::from_str, "--execution-jwt", log)?;
// Check if the JWT secret key is passed directly via cli flag and persist it to the default
// file location.
} else if let Some(jwt_secret_key) = cli_args.value_of("execution-jwt-secret-key") {
} else if let Some(jwt_secret_key) = cli_args.get_one::<String>("execution-jwt-secret-key")
{
use std::fs::File;
use std::io::Write;
secret_file = client_config.data_dir().join(DEFAULT_JWT_FILE);
@@ -321,7 +322,7 @@ pub fn get_config<E: EthSpec>(
}
// Parse and set the payload builder, if any.
if let Some(endpoint) = cli_args.value_of("builder") {
if let Some(endpoint) = cli_args.get_one::<String>("builder") {
let payload_builder =
parse_only_one_value(endpoint, SensitiveUrl::parse, "--builder", log)?;
el_config.builder_url = Some(payload_builder);
@@ -330,14 +331,14 @@ pub fn get_config<E: EthSpec>(
clap_utils::parse_optional(cli_args, "builder-user-agent")?;
}
if cli_args.is_present("builder-profit-threshold") {
if parse_flag(cli_args, "builder-profit-threshold") {
warn!(
log,
"Ignoring --builder-profit-threshold";
"info" => "this flag is deprecated and will be removed"
);
}
if cli_args.is_present("always-prefer-builder-payload") {
if cli_args.get_flag("always-prefer-builder-payload") {
warn!(
log,
"Ignoring --always-prefer-builder-payload";
@@ -380,7 +381,8 @@ pub fn get_config<E: EthSpec>(
.map_err(|e| format!("Unable to read trusted setup file: {}", e))?;
// Override default trusted setup file if required
if let Some(trusted_setup_file_path) = cli_args.value_of("trusted-setup-file-override") {
if let Some(trusted_setup_file_path) = cli_args.get_one::<String>("trusted-setup-file-override")
{
let file = std::fs::File::open(trusted_setup_file_path)
.map_err(|e| format!("Failed to open trusted setup file: {}", e))?;
let trusted_setup: TrustedSetup = serde_json::from_reader(file)
@@ -388,11 +390,11 @@ pub fn get_config<E: EthSpec>(
client_config.trusted_setup = Some(trusted_setup);
}
if let Some(freezer_dir) = cli_args.value_of("freezer-dir") {
if let Some(freezer_dir) = cli_args.get_one::<String>("freezer-dir") {
client_config.freezer_db_path = Some(PathBuf::from(freezer_dir));
}
if let Some(blobs_db_dir) = cli_args.value_of("blobs-dir") {
if let Some(blobs_db_dir) = cli_args.get_one::<String>("blobs-dir") {
client_config.blobs_db_path = Some(PathBuf::from(blobs_db_dir));
}
@@ -400,24 +402,27 @@ pub fn get_config<E: EthSpec>(
client_config.store.slots_per_restore_point = sprp;
client_config.store.slots_per_restore_point_set_explicitly = sprp_explicit;
if let Some(block_cache_size) = cli_args.value_of("block-cache-size") {
if let Some(block_cache_size) = cli_args.get_one::<String>("block-cache-size") {
client_config.store.block_cache_size = block_cache_size
.parse()
.map_err(|_| "block-cache-size is not a valid integer".to_string())?;
}
if let Some(cache_size) = clap_utils::parse_optional(cli_args, "state-cache-size")? {
client_config.store.state_cache_size = cache_size;
if let Some(cache_size) = cli_args.get_one::<String>("state-cache-size") {
client_config.store.state_cache_size = cache_size
.parse()
.map_err(|_| "state-cache-size is not a valid integer".to_string())?;
}
if let Some(historic_state_cache_size) = cli_args.value_of("historic-state-cache-size") {
if let Some(historic_state_cache_size) = cli_args.get_one::<String>("historic-state-cache-size")
{
client_config.store.historic_state_cache_size = historic_state_cache_size
.parse()
.map_err(|_| "historic-state-cache-size is not a valid integer".to_string())?;
}
client_config.store.compact_on_init = cli_args.is_present("compact-db");
if let Some(compact_on_prune) = cli_args.value_of("auto-compact-db") {
client_config.store.compact_on_init = cli_args.get_flag("compact-db");
if let Some(compact_on_prune) = cli_args.get_one::<String>("auto-compact-db") {
client_config.store.compact_on_prune = compact_on_prune
.parse()
.map_err(|_| "auto-compact-db takes a boolean".to_string())?;
@@ -458,7 +463,7 @@ pub fn get_config<E: EthSpec>(
* from lighthouse.
* Discovery address is set to localhost by default.
*/
if cli_args.is_present("zero-ports") {
if cli_args.get_flag("zero-ports") {
client_config.http_api.listen_port = 0;
client_config.http_metrics.listen_port = 0;
}
@@ -524,14 +529,14 @@ pub fn get_config<E: EthSpec>(
None
};
client_config.allow_insecure_genesis_sync = cli_args.is_present("allow-insecure-genesis-sync");
client_config.allow_insecure_genesis_sync = cli_args.get_flag("allow-insecure-genesis-sync");
client_config.genesis = if eth2_network_config.genesis_state_is_known() {
// Set up weak subjectivity sync, or start from the hardcoded genesis state.
if let (Some(initial_state_path), Some(initial_block_path), opt_initial_blobs_path) = (
cli_args.value_of("checkpoint-state"),
cli_args.value_of("checkpoint-block"),
cli_args.value_of("checkpoint-blobs"),
cli_args.get_one::<String>("checkpoint-state"),
cli_args.get_one::<String>("checkpoint-block"),
cli_args.get_one::<String>("checkpoint-blobs"),
) {
let read = |path: &str| {
use std::fs::File;
@@ -547,14 +552,14 @@ pub fn get_config<E: EthSpec>(
let anchor_state_bytes = read(initial_state_path)?;
let anchor_block_bytes = read(initial_block_path)?;
let anchor_blobs_bytes = opt_initial_blobs_path.map(read).transpose()?;
let anchor_blobs_bytes = opt_initial_blobs_path.map(|s| read(s)).transpose()?;
ClientGenesis::WeakSubjSszBytes {
anchor_state_bytes,
anchor_block_bytes,
anchor_blobs_bytes,
}
} else if let Some(remote_bn_url) = cli_args.value_of("checkpoint-sync-url") {
} else if let Some(remote_bn_url) = cli_args.get_one::<String>("checkpoint-sync-url") {
let url = SensitiveUrl::parse(remote_bn_url)
.map_err(|e| format!("Invalid checkpoint sync URL: {:?}", e))?;
@@ -563,7 +568,7 @@ pub fn get_config<E: EthSpec>(
ClientGenesis::GenesisState
}
} else {
if cli_args.is_present("checkpoint-state") || cli_args.is_present("checkpoint-sync-url") {
if parse_flag(cli_args, "checkpoint-state") || parse_flag(cli_args, "checkpoint-sync-url") {
return Err(
"Checkpoint sync is not available for this network as no genesis state is known"
.to_string(),
@@ -572,14 +577,14 @@ pub fn get_config<E: EthSpec>(
ClientGenesis::DepositContract
};
if cli_args.is_present("reconstruct-historic-states") {
if cli_args.get_flag("reconstruct-historic-states") {
client_config.chain.reconstruct_historic_states = true;
client_config.chain.genesis_backfill = true;
}
let beacon_graffiti = if let Some(graffiti) = cli_args.value_of("graffiti") {
let beacon_graffiti = if let Some(graffiti) = cli_args.get_one::<String>("graffiti") {
GraffitiOrigin::UserSpecified(GraffitiString::from_str(graffiti)?.into())
} else if cli_args.is_present("private") {
} else if cli_args.get_flag("private") {
// When 'private' flag is present, use a zero-initialized bytes array.
GraffitiOrigin::UserSpecified(GraffitiString::empty().into())
} else {
@@ -588,7 +593,7 @@ pub fn get_config<E: EthSpec>(
};
client_config.beacon_graffiti = beacon_graffiti;
if let Some(wss_checkpoint) = cli_args.value_of("wss-checkpoint") {
if let Some(wss_checkpoint) = cli_args.get_one::<String>("wss-checkpoint") {
let mut split = wss_checkpoint.split(':');
let root_str = split
.next()
@@ -623,8 +628,8 @@ pub fn get_config<E: EthSpec>(
client_config.chain.weak_subjectivity_checkpoint = Some(Checkpoint { epoch, root })
}
if let Some(max_skip_slots) = cli_args.value_of("max-skip-slots") {
client_config.chain.import_max_skip_slots = match max_skip_slots {
if let Some(max_skip_slots) = cli_args.get_one::<String>("max-skip-slots") {
client_config.chain.import_max_skip_slots = match max_skip_slots.as_str() {
"none" => None,
n => Some(
n.parse()
@@ -638,8 +643,8 @@ pub fn get_config<E: EthSpec>(
spec.gossip_max_size as usize,
);
if cli_args.is_present("slasher") {
let slasher_dir = if let Some(slasher_dir) = cli_args.value_of("slasher-dir") {
if cli_args.get_flag("slasher") {
let slasher_dir = if let Some(slasher_dir) = cli_args.get_one::<String>("slasher-dir") {
PathBuf::from(slasher_dir)
} else {
client_config.data_dir().join("slasher_db")
@@ -704,11 +709,11 @@ pub fn get_config<E: EthSpec>(
client_config.slasher = Some(slasher_config);
}
if cli_args.is_present("validator-monitor-auto") {
if cli_args.get_flag("validator-monitor-auto") {
client_config.validator_monitor.auto_register = true;
}
if let Some(pubkeys) = cli_args.value_of("validator-monitor-pubkeys") {
if let Some(pubkeys) = cli_args.get_one::<String>("validator-monitor-pubkeys") {
let pubkeys = pubkeys
.split(',')
.map(PublicKeyBytes::from_str)
@@ -720,7 +725,7 @@ pub fn get_config<E: EthSpec>(
.extend_from_slice(&pubkeys);
}
if let Some(path) = cli_args.value_of("validator-monitor-file") {
if let Some(path) = cli_args.get_one::<String>("validator-monitor-file") {
let string = fs::read(path)
.map_err(|e| format!("Unable to read --validator-monitor-file: {}", e))
.and_then(|bytes| {
@@ -747,11 +752,11 @@ pub fn get_config<E: EthSpec>(
.individual_tracking_threshold = count;
}
if cli_args.is_present("disable-lock-timeouts") {
if cli_args.get_flag("disable-lock-timeouts") {
client_config.chain.enable_lock_timeouts = false;
}
if cli_args.is_present("disable-proposer-reorgs") {
if cli_args.get_flag("disable-proposer-reorgs") {
client_config.chain.re_org_head_threshold = None;
client_config.chain.re_org_parent_threshold = None;
} else {
@@ -789,7 +794,7 @@ pub fn get_config<E: EthSpec>(
}
// Note: This overrides any previous flags that enable this option.
if cli_args.is_present("disable-deposit-contract-sync") {
if cli_args.get_flag("disable-deposit-contract-sync") {
client_config.sync_eth1_chain = false;
}
@@ -801,7 +806,7 @@ pub fn get_config<E: EthSpec>(
/ DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR
});
client_config.chain.always_prepare_payload = cli_args.is_present("always-prepare-payload");
client_config.chain.always_prepare_payload = cli_args.get_flag("always-prepare-payload");
if let Some(timeout) =
clap_utils::parse_optional(cli_args, "fork-choice-before-proposal-timeout")?
@@ -809,10 +814,9 @@ pub fn get_config<E: EthSpec>(
client_config.chain.fork_choice_before_proposal_timeout_ms = timeout;
}
client_config.chain.always_reset_payload_statuses =
cli_args.is_present("reset-payload-statuses");
client_config.chain.always_reset_payload_statuses = cli_args.get_flag("reset-payload-statuses");
client_config.chain.paranoid_block_proposal = cli_args.is_present("paranoid-block-proposal");
client_config.chain.paranoid_block_proposal = cli_args.get_flag("paranoid-block-proposal");
/*
* Builder fallback configs.
@@ -826,32 +830,32 @@ pub fn get_config<E: EthSpec>(
.builder_fallback_epochs_since_finalization =
clap_utils::parse_required(cli_args, "builder-fallback-epochs-since-finalization")?;
client_config.chain.builder_fallback_disable_checks =
cli_args.is_present("builder-fallback-disable-checks");
cli_args.get_flag("builder-fallback-disable-checks");
// Graphical user interface config.
if cli_args.is_present("gui") {
if cli_args.get_flag("gui") {
client_config.http_api.enabled = true;
client_config.validator_monitor.auto_register = true;
}
// Optimistic finalized sync.
client_config.chain.optimistic_finalized_sync =
!cli_args.is_present("disable-optimistic-finalized-sync");
!cli_args.get_flag("disable-optimistic-finalized-sync");
if cli_args.is_present("genesis-backfill") {
if cli_args.get_flag("genesis-backfill") {
client_config.chain.genesis_backfill = true;
}
// Backfill sync rate-limiting
client_config.beacon_processor.enable_backfill_rate_limiting =
!cli_args.is_present("disable-backfill-rate-limiting");
!cli_args.get_flag("disable-backfill-rate-limiting");
if let Some(path) = clap_utils::parse_optional(cli_args, "invalid-gossip-verified-blocks-path")?
{
client_config.network.invalid_block_storage = Some(path);
}
if cli_args.is_present("progressive-balances") {
if cli_args.get_one::<String>("progressive-balances").is_some() {
warn!(
log,
"Progressive balances mode is deprecated";
@@ -890,10 +894,9 @@ pub fn parse_listening_addresses(
log: &Logger,
) -> Result<ListenAddress, String> {
let listen_addresses_str = cli_args
.values_of("listen-address")
.get_many::<String>("listen-address")
.expect("--listen_addresses has a default value");
let use_zero_ports = cli_args.is_present("zero-ports");
let use_zero_ports = parse_flag(cli_args, "zero-ports");
// parse the possible ips
let mut maybe_ipv4 = None;
@@ -927,28 +930,28 @@ pub fn parse_listening_addresses(
// parse the possible tcp ports
let port = cli_args
.value_of("port")
.get_one::<String>("port")
.expect("--port has a default value")
.parse::<u16>()
.map_err(|parse_error| format!("Failed to parse --port as an integer: {parse_error}"))?;
let port6 = cli_args
.value_of("port6")
.map(str::parse::<u16>)
.get_one::<String>("port6")
.map(|s| str::parse::<u16>(s))
.transpose()
.map_err(|parse_error| format!("Failed to parse --port6 as an integer: {parse_error}"))?
.unwrap_or(9090);
// parse the possible discovery ports.
let maybe_disc_port = cli_args
.value_of("discovery-port")
.map(str::parse::<u16>)
.get_one::<String>("discovery-port")
.map(|s| str::parse::<u16>(s))
.transpose()
.map_err(|parse_error| {
format!("Failed to parse --discovery-port as an integer: {parse_error}")
})?;
let maybe_disc6_port = cli_args
.value_of("discovery-port6")
.map(str::parse::<u16>)
.get_one::<String>("discovery-port6")
.map(|s| str::parse::<u16>(s))
.transpose()
.map_err(|parse_error| {
format!("Failed to parse --discovery-port6 as an integer: {parse_error}")
@@ -956,8 +959,8 @@ pub fn parse_listening_addresses(
// parse the possible quic port.
let maybe_quic_port = cli_args
.value_of("quic-port")
.map(str::parse::<u16>)
.get_one::<String>("quic-port")
.map(|s| str::parse::<u16>(s))
.transpose()
.map_err(|parse_error| {
format!("Failed to parse --quic-port as an integer: {parse_error}")
@@ -965,8 +968,8 @@ pub fn parse_listening_addresses(
// parse the possible quic port.
let maybe_quic6_port = cli_args
.value_of("quic-port6")
.map(str::parse::<u16>)
.get_one::<String>("quic-port6")
.map(|s| str::parse::<u16>(s))
.transpose()
.map_err(|parse_error| {
format!("Failed to parse --quic6-port as an integer: {parse_error}")
@@ -980,10 +983,10 @@ pub fn parse_listening_addresses(
}
(None, Some(ipv6)) => {
// A single ipv6 address was provided. Set the ports
if cli_args.is_present("port6") {
warn!(log, "When listening only over IPv6, use the --port flag. The value of --port6 will be ignored.")
if cli_args.value_source("port6") == Some(ValueSource::CommandLine) {
warn!(log, "When listening only over IPv6, use the --port flag. The value of --port6 will be ignored.");
}
// use zero ports if required. If not, use the given port.
let tcp_port = use_zero_ports
.then(unused_port::unused_tcp6_port)
@@ -1117,41 +1120,41 @@ pub fn set_network_config(
log: &Logger,
) -> Result<(), String> {
// If a network dir has been specified, override the `datadir` definition.
if let Some(dir) = cli_args.value_of("network-dir") {
if let Some(dir) = cli_args.get_one::<String>("network-dir") {
config.network_dir = PathBuf::from(dir);
} else {
config.network_dir = data_dir.join(DEFAULT_NETWORK_DIR);
};
if cli_args.is_present("subscribe-all-subnets") {
if parse_flag(cli_args, "subscribe-all-subnets") {
config.subscribe_all_subnets = true;
}
if cli_args.is_present("import-all-attestations") {
if parse_flag(cli_args, "import-all-attestations") {
config.import_all_attestations = true;
}
if cli_args.is_present("shutdown-after-sync") {
if parse_flag(cli_args, "shutdown-after-sync") {
config.shutdown_after_sync = true;
}
config.set_listening_addr(parse_listening_addresses(cli_args, log)?);
// A custom target-peers command will overwrite the --proposer-only default.
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
if let Some(target_peers_str) = cli_args.get_one::<String>("target-peers") {
config.target_peers = target_peers_str
.parse::<usize>()
.map_err(|_| format!("Invalid number of target peers: {}", target_peers_str))?;
}
if let Some(value) = cli_args.value_of("network-load") {
if let Some(value) = cli_args.get_one::<String>("network-load") {
let network_load = value
.parse::<u8>()
.map_err(|_| format!("Invalid integer: {}", value))?;
config.network_load = network_load;
}
if let Some(boot_enr_str) = cli_args.value_of("boot-nodes") {
if let Some(boot_enr_str) = cli_args.get_one::<String>("boot-nodes") {
let mut enrs: Vec<Enr> = vec![];
let mut multiaddrs: Vec<Multiaddr> = vec![];
for addr in boot_enr_str.split(',') {
@@ -1176,7 +1179,7 @@ pub fn set_network_config(
config.boot_nodes_multiaddr = multiaddrs;
}
if let Some(libp2p_addresses_str) = cli_args.value_of("libp2p-addresses") {
if let Some(libp2p_addresses_str) = cli_args.get_one::<String>("libp2p-addresses") {
config.libp2p_nodes = libp2p_addresses_str
.split(',')
.map(|multiaddr| {
@@ -1187,11 +1190,11 @@ pub fn set_network_config(
.collect::<Result<Vec<Multiaddr>, _>>()?;
}
if cli_args.is_present("disable-peer-scoring") {
if parse_flag(cli_args, "disable-peer-scoring") {
config.disable_peer_scoring = true;
}
if let Some(trusted_peers_str) = cli_args.value_of("trusted-peers") {
if let Some(trusted_peers_str) = cli_args.get_one::<String>("trusted-peers") {
config.trusted_peers = trusted_peers_str
.split(',')
.map(|peer_id| {
@@ -1205,7 +1208,7 @@ pub fn set_network_config(
}
}
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
if let Some(enr_udp_port_str) = cli_args.get_one::<String>("enr-udp-port") {
config.enr_udp4_port = Some(
enr_udp_port_str
.parse::<NonZeroU16>()
@@ -1213,7 +1216,7 @@ pub fn set_network_config(
);
}
if let Some(enr_quic_port_str) = cli_args.value_of("enr-quic-port") {
if let Some(enr_quic_port_str) = cli_args.get_one::<String>("enr-quic-port") {
config.enr_quic4_port = Some(
enr_quic_port_str
.parse::<NonZeroU16>()
@@ -1221,7 +1224,7 @@ pub fn set_network_config(
);
}
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp-port") {
if let Some(enr_tcp_port_str) = cli_args.get_one::<String>("enr-tcp-port") {
config.enr_tcp4_port = Some(
enr_tcp_port_str
.parse::<NonZeroU16>()
@@ -1229,7 +1232,7 @@ pub fn set_network_config(
);
}
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp6-port") {
if let Some(enr_udp_port_str) = cli_args.get_one::<String>("enr-udp6-port") {
config.enr_udp6_port = Some(
enr_udp_port_str
.parse::<NonZeroU16>()
@@ -1237,7 +1240,7 @@ pub fn set_network_config(
);
}
if let Some(enr_quic_port_str) = cli_args.value_of("enr-quic6-port") {
if let Some(enr_quic_port_str) = cli_args.get_one::<String>("enr-quic6-port") {
config.enr_quic6_port = Some(
enr_quic_port_str
.parse::<NonZeroU16>()
@@ -1245,7 +1248,7 @@ pub fn set_network_config(
);
}
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp6-port") {
if let Some(enr_tcp_port_str) = cli_args.get_one::<String>("enr-tcp6-port") {
config.enr_tcp6_port = Some(
enr_tcp_port_str
.parse::<NonZeroU16>()
@@ -1253,7 +1256,7 @@ pub fn set_network_config(
);
}
if cli_args.is_present("enr-match") {
if parse_flag(cli_args, "enr-match") {
// Match the IP and UDP port in the ENR.
if let Some(ipv4_addr) = config.listen_addrs().v4().cloned() {
@@ -1291,7 +1294,7 @@ pub fn set_network_config(
}
}
if let Some(enr_addresses) = cli_args.values_of("enr-address") {
if let Some(enr_addresses) = cli_args.get_many::<String>("enr-address") {
let mut enr_ip4 = None;
let mut enr_ip6 = None;
let mut resolved_enr_ip4 = None;
@@ -1369,79 +1372,78 @@ pub fn set_network_config(
}
}
if cli_args.is_present("disable-enr-auto-update") {
if parse_flag(cli_args, "disable-enr-auto-update") {
config.discv5_config.enr_update = false;
}
if cli_args.is_present("disable-packet-filter") {
if parse_flag(cli_args, "disable-packet-filter") {
warn!(log, "Discv5 packet filter is disabled");
config.discv5_config.enable_packet_filter = false;
}
if cli_args.is_present("disable-discovery") {
if parse_flag(cli_args, "disable-discovery") {
config.disable_discovery = true;
warn!(log, "Discovery is disabled. New peers will not be found");
}
if cli_args.is_present("disable-quic") {
if parse_flag(cli_args, "disable-quic") {
config.disable_quic_support = true;
}
if cli_args.is_present("disable-upnp") {
if parse_flag(cli_args, "disable-upnp") {
config.upnp_enabled = false;
}
if cli_args.is_present("private") {
if parse_flag(cli_args, "private") {
config.private = true;
}
if cli_args.is_present("metrics") {
if parse_flag(cli_args, "metrics") {
config.metrics_enabled = true;
}
if cli_args.is_present("enable-private-discovery") {
if parse_flag(cli_args, "enable-private-discovery") {
config.discv5_config.table_filter = |_| true;
}
// Light client server config.
config.enable_light_client_server = cli_args.is_present("light-client-server");
config.enable_light_client_server = parse_flag(cli_args, "light-client-server");
// The self limiter is disabled by default.
// This flag can be used both with or without a value. Try to parse it first with a value, if
// no value is defined but the flag is present, use the default params.
config.outbound_rate_limiter_config = clap_utils::parse_optional(cli_args, "self-limiter")?;
if cli_args.is_present("self-limiter") && config.outbound_rate_limiter_config.is_none() {
config.outbound_rate_limiter_config = Some(Default::default());
// The self limiter is disabled by default. If the `self-limiter` flag is provided
// without the `self-limiter-protocols` flag, the default params will be used.
if parse_flag(cli_args, "self-limiter") {
config.outbound_rate_limiter_config =
if let Some(protocols) = cli_args.get_one::<String>("self-limiter-protocols") {
Some(protocols.parse()?)
} else {
Some(Default::default())
};
}
// Proposer-only mode overrides a number of previous configuration parameters.
// Specifically, we avoid subscribing to long-lived subnets and wish to maintain a minimal set
// of peers.
if cli_args.is_present("proposer-only") {
if parse_flag(cli_args, "proposer-only") {
config.subscribe_all_subnets = false;
if cli_args.value_of("target-peers").is_none() {
if cli_args.get_one::<String>("target-peers").is_none() {
// If a custom value is not set, change the default to 15
config.target_peers = 15;
}
config.proposer_only = true;
warn!(log, "Proposer-only mode enabled"; "info"=> "Do not connect a validator client to this node unless via the --proposer-nodes flag");
}
// The inbound rate limiter is enabled by default unless `disabled` is passed to the
// `inbound-rate-limiter` flag. Any other value should be parsed as a configuration string.
config.inbound_rate_limiter_config = match cli_args.value_of("inbound-rate-limiter") {
None => {
// Enabled by default, with default values
// The inbound rate limiter is enabled by default unless `disabled` via the
// `disable-inbound-rate-limiter` flag.
config.inbound_rate_limiter_config = if parse_flag(cli_args, "disable-inbound-rate-limiter") {
None
} else {
// Use the default unless values are provided via the `inbound-rate-limiter-protocols`
if let Some(protocols) = cli_args.get_one::<String>("inbound-rate-limiter-protocols") {
Some(protocols.parse()?)
} else {
Some(Default::default())
}
Some("disabled") => {
// Explicitly disabled
None
}
Some(config_str) => {
// Enabled with a custom configuration
Some(config_str.parse()?)
}
};
Ok(())
}
@@ -1454,7 +1456,7 @@ pub fn get_data_dir(cli_args: &ArgMatches) -> PathBuf {
// directory and the testnet name onto it.
cli_args
.value_of("datadir")
.get_one::<String>("datadir")
.map(|path| PathBuf::from(path).join(DEFAULT_BEACON_NODE_DIR))
.or_else(|| {
dirs::home_dir().map(|home| {

View File

@@ -1,4 +1,3 @@
#[macro_use]
extern crate clap;
mod cli;
@@ -44,7 +43,7 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
/// configurations hosted remotely.
pub async fn new_from_cli(
context: RuntimeContext<E>,
matches: ArgMatches<'static>,
matches: ArgMatches,
) -> Result<Self, String> {
let client_config = get_config::<E>(&matches, &context)?;
Self::new(context, client_config).await