mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-18 12:22:51 +00:00
## Issue Addressed NA ## Proposed Changes Myself and others (#3678) have observed that when running with lots of validators (e.g., 1000s) the cardinality is too much for Prometheus. I've seen Prometheus instances just grind to a halt when we turn the validator monitor on for our testnet validators (we have 10,000s of Goerli validators). Additionally, the debug log volume can get very high with one log per validator, per attestation. To address this, the `bn --validator-monitor-individual-tracking-threshold <INTEGER>` flag has been added to *disable* per-validator (i.e., non-aggregated) metrics/logging once the validator monitor exceeds the threshold of validators. The default value is `64`, which is a finger-to-the-wind value. I don't actually know the value at which Prometheus starts to become overwhelmed, but I've seen it work with ~64 validators and I've seen it *not* work with 1000s of validators. A default of `64` seems like it will result in a breaking change to users who are running millions of dollars worth of validators whilst resulting in a no-op for low-validator-count users. I'm open to changing this number, though. Additionally, this PR starts collecting aggregated Prometheus metrics (e.g., total count of head hits across all validators), so that high-validator-count validators still have some interesting metrics. We already had logging for aggregated values, so nothing has been added there. I've opted to make this a breaking change since it can be rather damaging to your Prometheus instance to accidentally enable the validator monitor with large numbers of validators. I've crashed a Prometheus instance myself and had a report from another user who's done the same thing. ## Additional Info NA ## Breaking Changes Note A new label has been added to the validator monitor Prometheus metrics: `total`. This label tracks the aggregated metrics of all validators in the validator monitor (as opposed to each validator being tracking individually using its pubkey as the label). Additionally, a new flag has been added to the Beacon Node: `--validator-monitor-individual-tracking-threshold`. The default value is `64`, which means that when the validator monitor is tracking more than 64 validators then it will stop tracking per-validator metrics and only track the `all_validators` metric. It will also stop logging per-validator logs and only emit aggregated logs (the exception being that exit and slashing logs are always emitted). These changes were introduced in #3728 to address issues with untenable Prometheus cardinality and log volume when using the validator monitor with high validator counts (e.g., 1000s of validators). Users with less than 65 validators will see no change in behavior (apart from the added `all_validators` metric). Users with more than 65 validators who wish to maintain the previous behavior can set something like `--validator-monitor-individual-tracking-threshold 999999`.
1744 lines
59 KiB
Rust
1744 lines
59 KiB
Rust
use beacon_node::{beacon_chain::CountUnrealizedFull, ClientConfig as Config};
|
|
|
|
use crate::exec::{CommandLineTestExec, CompletedTest};
|
|
use beacon_node::beacon_chain::chain_config::{
|
|
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_RE_ORG_THRESHOLD,
|
|
};
|
|
use eth1::Eth1Endpoint;
|
|
use lighthouse_network::PeerId;
|
|
use std::fs::File;
|
|
use std::io::{Read, Write};
|
|
use std::net::IpAddr;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::str::FromStr;
|
|
use std::string::ToString;
|
|
use std::time::Duration;
|
|
use tempfile::TempDir;
|
|
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, ForkName, Hash256, MainnetEthSpec};
|
|
use unused_port::{unused_tcp_port, unused_udp_port};
|
|
|
|
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
|
|
|
/// Returns the `lighthouse beacon_node` command.
|
|
fn base_cmd() -> Command {
|
|
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
|
let path = lighthouse_bin
|
|
.parse::<PathBuf>()
|
|
.expect("should parse CARGO_TARGET_DIR");
|
|
|
|
let mut cmd = Command::new(path);
|
|
cmd.arg("beacon_node");
|
|
cmd
|
|
}
|
|
|
|
// Wrapper around `Command` for easier Command Line Testing.
|
|
struct CommandLineTest {
|
|
cmd: Command,
|
|
}
|
|
impl CommandLineTest {
|
|
fn new() -> CommandLineTest {
|
|
let base_cmd = base_cmd();
|
|
CommandLineTest { cmd: base_cmd }
|
|
}
|
|
|
|
fn run_with_zero_port(&mut self) -> CompletedTest<Config> {
|
|
self.cmd.arg("-z");
|
|
self.run()
|
|
}
|
|
}
|
|
|
|
impl CommandLineTestExec for CommandLineTest {
|
|
type Config = Config;
|
|
|
|
fn cmd_mut(&mut self) -> &mut Command {
|
|
&mut self.cmd
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn datadir_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config_and_dir(|config, dir| {
|
|
assert_eq!(*config.data_dir(), dir.path().join("beacon"))
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn staking_flag() {
|
|
CommandLineTest::new()
|
|
.flag("staking", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.http_api.enabled);
|
|
assert!(config.sync_eth1_chain);
|
|
assert_eq!(
|
|
config.eth1.endpoint.get_endpoint().to_string(),
|
|
DEFAULT_ETH1_ENDPOINT
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn wss_checkpoint_flag() {
|
|
let state = Some(Checkpoint {
|
|
epoch: Epoch::new(1010),
|
|
root: Hash256::from_str("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
|
|
.unwrap(),
|
|
});
|
|
CommandLineTest::new()
|
|
.flag(
|
|
"wss-checkpoint",
|
|
Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:1010"),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.chain.weak_subjectivity_checkpoint, state));
|
|
}
|
|
#[test]
|
|
fn max_skip_slots_flag() {
|
|
CommandLineTest::new()
|
|
.flag("max-skip-slots", Some("10"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.chain.import_max_skip_slots, Some(10)));
|
|
}
|
|
|
|
#[test]
|
|
fn enable_lock_timeouts_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.enable_lock_timeouts));
|
|
}
|
|
|
|
#[test]
|
|
fn disable_lock_timeouts_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-lock-timeouts", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.chain.enable_lock_timeouts));
|
|
}
|
|
|
|
#[test]
|
|
fn fork_choice_before_proposal_timeout_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.fork_choice_before_proposal_timeout_ms,
|
|
beacon_node::beacon_chain::chain_config::DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn fork_choice_before_proposal_timeout_zero() {
|
|
CommandLineTest::new()
|
|
.flag("fork-choice-before-proposal-timeout", Some("0"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.chain.fork_choice_before_proposal_timeout_ms, 0));
|
|
}
|
|
|
|
#[test]
|
|
fn checkpoint_sync_url_timeout_flag() {
|
|
CommandLineTest::new()
|
|
.flag("checkpoint-sync-url-timeout", Some("300"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.chain.checkpoint_sync_url_timeout, 300);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn checkpoint_sync_url_timeout_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.chain.checkpoint_sync_url_timeout, 60);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn prepare_payload_lookahead_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.prepare_payload_lookahead,
|
|
Duration::from_secs(4),
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn prepare_payload_lookahead_shorter() {
|
|
CommandLineTest::new()
|
|
.flag("prepare-payload-lookahead", Some("1500"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.prepare_payload_lookahead,
|
|
Duration::from_millis(1500)
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn paranoid_block_proposal_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.chain.paranoid_block_proposal));
|
|
}
|
|
|
|
#[test]
|
|
fn paranoid_block_proposal_on() {
|
|
CommandLineTest::new()
|
|
.flag("paranoid-block-proposal", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.paranoid_block_proposal));
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.count_unrealized));
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_no_arg() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.count_unrealized));
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_false() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized", Some("false"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.chain.count_unrealized));
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_true() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized", Some("true"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.count_unrealized));
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_full_no_arg() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized-full", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.count_unrealized_full,
|
|
CountUnrealizedFull::False
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_full_false() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized-full", Some("false"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.count_unrealized_full,
|
|
CountUnrealizedFull::False
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn count_unrealized_full_true() {
|
|
CommandLineTest::new()
|
|
.flag("count-unrealized-full", Some("true"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.count_unrealized_full,
|
|
CountUnrealizedFull::True
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn reset_payload_statuses_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.chain.always_reset_payload_statuses));
|
|
}
|
|
|
|
#[test]
|
|
fn reset_payload_statuses_present() {
|
|
CommandLineTest::new()
|
|
.flag("reset-payload-statuses", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.always_reset_payload_statuses));
|
|
}
|
|
|
|
#[test]
|
|
fn freezer_dir_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("freezer-dir", dir.path().as_os_str().to_str())
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.freezer_db_path, Some(dir.path().to_path_buf())));
|
|
}
|
|
|
|
#[test]
|
|
fn graffiti_flag() {
|
|
CommandLineTest::new()
|
|
.flag("graffiti", Some("nice-graffiti"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.graffiti.to_string(),
|
|
"0x6e6963652d677261666669746900000000000000000000000000000000000000"
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn trusted_peers_flag() {
|
|
let peers = vec![PeerId::random(), PeerId::random()];
|
|
CommandLineTest::new()
|
|
.flag(
|
|
"trusted-peers",
|
|
Some(format!("{},{}", peers[0].to_string(), peers[1].to_string()).as_str()),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
PeerId::from(config.network.trusted_peers[0].clone()).to_bytes(),
|
|
peers[0].to_bytes()
|
|
);
|
|
assert_eq!(
|
|
PeerId::from(config.network.trusted_peers[1].clone()).to_bytes(),
|
|
peers[1].to_bytes()
|
|
);
|
|
});
|
|
}
|
|
|
|
// Tests for Eth1 flags.
|
|
#[test]
|
|
fn dummy_eth1_flag() {
|
|
CommandLineTest::new()
|
|
.flag("dummy-eth1", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.dummy_eth1_backend));
|
|
}
|
|
#[test]
|
|
fn eth1_flag() {
|
|
CommandLineTest::new()
|
|
.flag("eth1", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.sync_eth1_chain));
|
|
}
|
|
#[test]
|
|
fn eth1_endpoints_flag() {
|
|
CommandLineTest::new()
|
|
.flag("eth1-endpoints", Some("http://localhost:9545"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.eth1.endpoint.get_endpoint().full.to_string(),
|
|
"http://localhost:9545/"
|
|
);
|
|
assert_eq!(
|
|
config.eth1.endpoint.get_endpoint().to_string(),
|
|
"http://localhost:9545/"
|
|
);
|
|
assert!(config.sync_eth1_chain);
|
|
});
|
|
}
|
|
#[test]
|
|
fn eth1_blocks_per_log_query_flag() {
|
|
CommandLineTest::new()
|
|
.flag("eth1-blocks-per-log-query", Some("500"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.eth1.blocks_per_log_query, 500));
|
|
}
|
|
#[test]
|
|
fn eth1_purge_cache_flag() {
|
|
CommandLineTest::new()
|
|
.flag("eth1-purge-cache", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.eth1.purge_cache));
|
|
}
|
|
#[test]
|
|
fn eth1_cache_follow_distance_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.eth1.cache_follow_distance, None);
|
|
assert_eq!(config.eth1.cache_follow_distance(), 3 * 2048 / 4);
|
|
});
|
|
}
|
|
#[test]
|
|
fn eth1_cache_follow_distance_manual() {
|
|
CommandLineTest::new()
|
|
.flag("eth1-cache-follow-distance", Some("128"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.eth1.cache_follow_distance, Some(128));
|
|
assert_eq!(config.eth1.cache_follow_distance(), 128);
|
|
});
|
|
}
|
|
|
|
// Tests for Bellatrix flags.
|
|
fn run_merge_execution_endpoints_flag_test(flag: &str) {
|
|
use sensitive_url::SensitiveUrl;
|
|
let urls = vec!["http://sigp.io/no-way:1337", "http://infura.not_real:4242"];
|
|
// we don't support redundancy for execution-endpoints
|
|
// only the first provided endpoint is parsed.
|
|
|
|
let mut endpoint_arg = urls[0].to_string();
|
|
for url in urls.iter().skip(1) {
|
|
endpoint_arg.push(',');
|
|
endpoint_arg.push_str(url);
|
|
}
|
|
|
|
let (_dirs, jwts): (Vec<_>, Vec<_>) = (0..2)
|
|
.map(|i| {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let path = dir.path().join(format!("jwt-{}", i));
|
|
(dir, path)
|
|
})
|
|
.unzip();
|
|
|
|
let mut jwts_arg = jwts[0].as_os_str().to_str().unwrap().to_string();
|
|
for jwt in jwts.iter().skip(1) {
|
|
jwts_arg.push(',');
|
|
jwts_arg.push_str(jwt.as_os_str().to_str().unwrap());
|
|
}
|
|
|
|
// this is way better but intersperse is still a nightly feature :/
|
|
// let endpoint_arg: String = urls.into_iter().intersperse(",").collect();
|
|
CommandLineTest::new()
|
|
.flag(flag, Some(&endpoint_arg))
|
|
.flag("execution-jwt", Some(&jwts_arg))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(config.execution_endpoints.len(), 1);
|
|
assert_eq!(
|
|
config.execution_endpoints[0],
|
|
SensitiveUrl::parse(&urls[0]).unwrap()
|
|
);
|
|
// Only the first secret file should be used.
|
|
assert_eq!(config.secret_files, vec![jwts[0].clone()]);
|
|
});
|
|
}
|
|
#[test]
|
|
fn run_execution_jwt_secret_key_is_persisted() {
|
|
let jwt_secret_key = "0x3cbc11b0d8fa16f3344eacfd6ff6430b9d30734450e8adcf5400f88d327dcb33";
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoint", Some("http://localhost:8551/"))
|
|
.flag("execution-jwt-secret-key", Some(jwt_secret_key))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(
|
|
config.execution_endpoints[0].full.to_string(),
|
|
"http://localhost:8551/"
|
|
);
|
|
let mut file_jwt_secret_key = String::new();
|
|
File::open(config.secret_files[0].clone())
|
|
.expect("could not open jwt_secret_key file")
|
|
.read_to_string(&mut file_jwt_secret_key)
|
|
.expect("could not read from file");
|
|
assert_eq!(file_jwt_secret_key, jwt_secret_key);
|
|
});
|
|
}
|
|
#[test]
|
|
fn execution_timeout_multiplier_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoint", Some("http://meow.cats"))
|
|
.flag(
|
|
"execution-jwt",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.flag("execution-timeout-multiplier", Some("3"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(config.execution_timeout_multiplier, Some(3));
|
|
});
|
|
}
|
|
#[test]
|
|
fn merge_execution_endpoints_flag() {
|
|
run_merge_execution_endpoints_flag_test("execution-endpoints")
|
|
}
|
|
#[test]
|
|
fn merge_execution_endpoint_flag() {
|
|
run_merge_execution_endpoints_flag_test("execution-endpoint")
|
|
}
|
|
fn run_execution_endpoints_overrides_eth1_endpoints_test(eth1_flag: &str, execution_flag: &str) {
|
|
use sensitive_url::SensitiveUrl;
|
|
|
|
let eth1_endpoint = "http://bad.bad";
|
|
let execution_endpoint = "http://good.good";
|
|
|
|
assert!(eth1_endpoint != execution_endpoint);
|
|
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let jwt_path = dir.path().join("jwt-file");
|
|
|
|
CommandLineTest::new()
|
|
.flag(eth1_flag, Some(ð1_endpoint))
|
|
.flag(execution_flag, Some(&execution_endpoint))
|
|
.flag("execution-jwt", jwt_path.as_os_str().to_str())
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.execution_layer.as_ref().unwrap().execution_endpoints,
|
|
vec![SensitiveUrl::parse(execution_endpoint).unwrap()]
|
|
);
|
|
|
|
// The eth1 endpoint should have been set to the --execution-endpoint value in defiance
|
|
// of --eth1-endpoints.
|
|
assert_eq!(
|
|
config.eth1.endpoint,
|
|
Eth1Endpoint::Auth {
|
|
endpoint: SensitiveUrl::parse(execution_endpoint).unwrap(),
|
|
jwt_path: jwt_path.clone(),
|
|
jwt_id: None,
|
|
jwt_version: None,
|
|
}
|
|
);
|
|
});
|
|
}
|
|
#[test]
|
|
fn execution_endpoints_overrides_eth1_endpoints() {
|
|
run_execution_endpoints_overrides_eth1_endpoints_test("eth1-endpoints", "execution-endpoints");
|
|
}
|
|
#[test]
|
|
fn execution_endpoint_overrides_eth1_endpoint() {
|
|
run_execution_endpoints_overrides_eth1_endpoints_test("eth1-endpoint", "execution-endpoint");
|
|
}
|
|
#[test]
|
|
fn merge_jwt_secrets_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let mut file = File::create(dir.path().join("jwtsecrets")).expect("Unable to create file");
|
|
file.write_all(b"0x3cbc11b0d8fa16f3344eacfd6ff6430b9d30734450e8adcf5400f88d327dcb33")
|
|
.expect("Unable to write to file");
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoints", Some("http://localhost:8551/"))
|
|
.flag(
|
|
"jwt-secrets",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(
|
|
config.execution_endpoints[0].full.to_string(),
|
|
"http://localhost:8551/"
|
|
);
|
|
assert_eq!(config.secret_files[0], dir.path().join("jwt-file"));
|
|
});
|
|
}
|
|
#[test]
|
|
fn merge_fee_recipient_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoint", Some("http://meow.cats"))
|
|
.flag(
|
|
"execution-jwt",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.flag(
|
|
"suggested-fee-recipient",
|
|
Some("0x00000000219ab540356cbb839cbe05303d7705fa"),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(
|
|
config.suggested_fee_recipient,
|
|
Some(Address::from_str("0x00000000219ab540356cbb839cbe05303d7705fa").unwrap())
|
|
);
|
|
});
|
|
}
|
|
fn run_payload_builder_flag_test(flag: &str, builders: &str) {
|
|
use sensitive_url::SensitiveUrl;
|
|
|
|
let all_builders: Vec<_> = builders
|
|
.split(",")
|
|
.map(|builder| SensitiveUrl::parse(builder).expect("valid builder url"))
|
|
.collect();
|
|
run_payload_builder_flag_test_with_config(flag, builders, None, None, |config| {
|
|
let config = config.execution_layer.as_ref().unwrap();
|
|
// Only first provided endpoint is parsed as we don't support
|
|
// redundancy.
|
|
assert_eq!(config.builder_url, all_builders.get(0).cloned());
|
|
})
|
|
}
|
|
fn run_payload_builder_flag_test_with_config<F: Fn(&Config)>(
|
|
flag: &str,
|
|
builders: &str,
|
|
additional_flag: Option<&str>,
|
|
additional_flag_value: Option<&str>,
|
|
f: F,
|
|
) {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let mut test = CommandLineTest::new();
|
|
test.flag("execution-endpoint", Some("http://meow.cats"))
|
|
.flag(
|
|
"execution-jwt",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.flag(flag, Some(builders));
|
|
if let Some(additional_flag_name) = additional_flag {
|
|
test.flag(additional_flag_name, additional_flag_value);
|
|
}
|
|
test.run_with_zero_port().with_config(f);
|
|
}
|
|
|
|
#[test]
|
|
fn payload_builder_flags() {
|
|
run_payload_builder_flag_test("builder", "http://meow.cats");
|
|
run_payload_builder_flag_test("payload-builder", "http://meow.cats");
|
|
run_payload_builder_flag_test("payload-builders", "http://meow.cats,http://woof.dogs");
|
|
}
|
|
|
|
#[test]
|
|
fn builder_fallback_flags() {
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
Some("builder-fallback-skips"),
|
|
Some("7"),
|
|
|config| {
|
|
assert_eq!(config.chain.builder_fallback_skips, 7);
|
|
},
|
|
);
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
Some("builder-fallback-skips-per-epoch"),
|
|
Some("11"),
|
|
|config| {
|
|
assert_eq!(config.chain.builder_fallback_skips_per_epoch, 11);
|
|
},
|
|
);
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
Some("builder-fallback-epochs-since-finalization"),
|
|
Some("4"),
|
|
|config| {
|
|
assert_eq!(config.chain.builder_fallback_epochs_since_finalization, 4);
|
|
},
|
|
);
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
Some("builder-fallback-disable-checks"),
|
|
None,
|
|
|config| {
|
|
assert_eq!(config.chain.builder_fallback_disable_checks, true);
|
|
},
|
|
);
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
Some("builder-profit-threshold"),
|
|
Some("1000000000000000000000000"),
|
|
|config| {
|
|
assert_eq!(
|
|
config
|
|
.execution_layer
|
|
.as_ref()
|
|
.unwrap()
|
|
.builder_profit_threshold,
|
|
1000000000000000000000000
|
|
);
|
|
},
|
|
);
|
|
run_payload_builder_flag_test_with_config(
|
|
"builder",
|
|
"http://meow.cats",
|
|
None,
|
|
None,
|
|
|config| {
|
|
assert_eq!(
|
|
config
|
|
.execution_layer
|
|
.as_ref()
|
|
.unwrap()
|
|
.builder_profit_threshold,
|
|
0
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
fn run_jwt_optional_flags_test(jwt_flag: &str, jwt_id_flag: &str, jwt_version_flag: &str) {
|
|
use sensitive_url::SensitiveUrl;
|
|
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let execution_endpoint = "http://meow.cats";
|
|
let jwt_file = "jwt-file";
|
|
let id = "bn-1";
|
|
let version = "Lighthouse-v2.1.3";
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoint", Some(execution_endpoint.clone()))
|
|
.flag(jwt_flag, dir.path().join(jwt_file).as_os_str().to_str())
|
|
.flag(jwt_id_flag, Some(id))
|
|
.flag(jwt_version_flag, Some(version))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let el_config = config.execution_layer.as_ref().unwrap();
|
|
assert_eq!(el_config.jwt_id, Some(id.to_string()));
|
|
assert_eq!(el_config.jwt_version, Some(version.to_string()));
|
|
assert_eq!(
|
|
config.eth1.endpoint,
|
|
Eth1Endpoint::Auth {
|
|
endpoint: SensitiveUrl::parse(execution_endpoint).unwrap(),
|
|
jwt_path: dir.path().join(jwt_file),
|
|
jwt_id: Some(id.to_string()),
|
|
jwt_version: Some(version.to_string()),
|
|
}
|
|
);
|
|
});
|
|
}
|
|
#[test]
|
|
fn jwt_optional_flags() {
|
|
run_jwt_optional_flags_test("execution-jwt", "execution-jwt-id", "execution-jwt-version");
|
|
}
|
|
#[test]
|
|
fn jwt_optional_alias_flags() {
|
|
run_jwt_optional_flags_test("jwt-secrets", "jwt-id", "jwt-version");
|
|
}
|
|
#[test]
|
|
fn terminal_total_difficulty_override_flag() {
|
|
use beacon_node::beacon_chain::types::Uint256;
|
|
CommandLineTest::new()
|
|
.flag("terminal-total-difficulty-override", Some("1337424242"))
|
|
.run_with_zero_port()
|
|
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
assert_eq!(spec.terminal_total_difficulty, Uint256::from(1337424242))
|
|
});
|
|
}
|
|
#[test]
|
|
fn terminal_block_hash_and_activation_epoch_override_flags() {
|
|
CommandLineTest::new()
|
|
.flag("terminal-block-hash-epoch-override", Some("1337"))
|
|
.flag(
|
|
"terminal-block-hash-override",
|
|
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
assert_eq!(
|
|
spec.terminal_block_hash,
|
|
ExecutionBlockHash::from_str(
|
|
"0x4242424242424242424242424242424242424242424242424242424242424242"
|
|
)
|
|
.unwrap()
|
|
);
|
|
assert_eq!(spec.terminal_block_hash_activation_epoch, 1337);
|
|
});
|
|
}
|
|
#[test]
|
|
#[should_panic]
|
|
fn terminal_block_hash_missing_activation_epoch() {
|
|
CommandLineTest::new()
|
|
.flag(
|
|
"terminal-block-hash-override",
|
|
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
|
|
)
|
|
.run_with_zero_port();
|
|
}
|
|
#[test]
|
|
#[should_panic]
|
|
fn epoch_override_missing_terminal_block_hash() {
|
|
CommandLineTest::new()
|
|
.flag("terminal-block-hash-epoch-override", Some("1337"))
|
|
.run_with_zero_port();
|
|
}
|
|
#[test]
|
|
fn safe_slots_to_import_optimistically_flag() {
|
|
CommandLineTest::new()
|
|
.flag("safe-slots-to-import-optimistically", Some("421337"))
|
|
.run_with_zero_port()
|
|
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
assert_eq!(spec.safe_slots_to_import_optimistically, 421337)
|
|
});
|
|
}
|
|
|
|
// Tests for Network flags.
|
|
#[test]
|
|
fn network_dir_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("network-dir", dir.path().as_os_str().to_str())
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.network_dir, dir.path()));
|
|
}
|
|
#[test]
|
|
fn network_target_peers_flag() {
|
|
CommandLineTest::new()
|
|
.flag("target-peers", Some("55"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.target_peers, "55".parse::<usize>().unwrap());
|
|
});
|
|
}
|
|
#[test]
|
|
fn network_subscribe_all_subnets_flag() {
|
|
CommandLineTest::new()
|
|
.flag("subscribe-all-subnets", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.subscribe_all_subnets));
|
|
}
|
|
#[test]
|
|
fn network_import_all_attestations_flag() {
|
|
CommandLineTest::new()
|
|
.flag("import-all-attestations", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.import_all_attestations));
|
|
}
|
|
#[test]
|
|
fn network_shutdown_after_sync_flag() {
|
|
CommandLineTest::new()
|
|
.flag("shutdown-after-sync", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.shutdown_after_sync));
|
|
}
|
|
#[test]
|
|
fn network_shutdown_after_sync_disabled_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
|
}
|
|
#[test]
|
|
fn network_listen_address_flag() {
|
|
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
|
CommandLineTest::new()
|
|
.flag("listen-address", Some("127.0.0.2"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.listen_address, addr));
|
|
}
|
|
#[test]
|
|
fn network_port_flag() {
|
|
let port = unused_tcp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("port", Some(port.to_string().as_str()))
|
|
.run()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.libp2p_port, port);
|
|
assert_eq!(config.network.discovery_port, port);
|
|
});
|
|
}
|
|
#[test]
|
|
fn network_port_and_discovery_port_flags() {
|
|
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
|
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("port", Some(port1.to_string().as_str()))
|
|
.flag("discovery-port", Some(port2.to_string().as_str()))
|
|
.run()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.libp2p_port, port1);
|
|
assert_eq!(config.network.discovery_port, port2);
|
|
});
|
|
}
|
|
#[test]
|
|
fn disable_discovery_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-discovery", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.disable_discovery));
|
|
}
|
|
#[test]
|
|
fn disable_upnp_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-upnp", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.network.upnp_enabled));
|
|
}
|
|
#[test]
|
|
fn default_boot_nodes() {
|
|
let mainnet = vec![
|
|
// Lighthouse Team (Sigma Prime)
|
|
"enr:-Jq4QItoFUuug_n_qbYbU0OY04-np2wT8rUCauOOXNi0H3BWbDj-zbfZb7otA7jZ6flbBpx1LNZK2TDebZ9dEKx84LYBhGV0aDKQtTA_KgEAAAD__________4JpZIJ2NIJpcISsaa0ZiXNlY3AyNTZrMaEDHAD2JKYevx89W0CcFJFiskdcEzkH_Wdv9iW42qLK79ODdWRwgiMo",
|
|
"enr:-Jq4QN_YBsUOqQsty1OGvYv48PMaiEt1AzGD1NkYQHaxZoTyVGqMYXg0K9c0LPNWC9pkXmggApp8nygYLsQwScwAgfgBhGV0aDKQtTA_KgEAAAD__________4JpZIJ2NIJpcISLosQxiXNlY3AyNTZrMaEDBJj7_dLFACaxBfaI8KZTh_SSJUjhyAyfshimvSqo22WDdWRwgiMo",
|
|
// EF Team
|
|
"enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg",
|
|
"enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg",
|
|
"enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg",
|
|
"enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg",
|
|
// Teku team (Consensys)
|
|
"enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA",
|
|
"enr:-KG4QDyytgmE4f7AnvW-ZaUOIi9i79qX4JwjRAiXBZCU65wOfBu-3Nb5I7b_Rmg3KCOcZM_C3y5pg7EBU5XGrcLTduQEhGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQ2_DUbiXNlY3AyNTZrMaEDKnz_-ps3UUOfHWVYaskI5kWYO_vtYMGYCQRAR3gHDouDdGNwgiMog3VkcIIjKA",
|
|
// Prysm team (Prysmatic Labs)
|
|
"enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg",
|
|
"enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA",
|
|
"enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg",
|
|
// Nimbus team
|
|
"enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM",
|
|
"enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM"
|
|
];
|
|
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
// Lighthouse Team (Sigma Prime)
|
|
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), mainnet[0]);
|
|
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), mainnet[1]);
|
|
// EF Team
|
|
assert_eq!(config.network.boot_nodes_enr[2].to_base64(), mainnet[2]);
|
|
assert_eq!(config.network.boot_nodes_enr[3].to_base64(), mainnet[3]);
|
|
assert_eq!(config.network.boot_nodes_enr[4].to_base64(), mainnet[4]);
|
|
assert_eq!(config.network.boot_nodes_enr[5].to_base64(), mainnet[5]);
|
|
// Teku team (Consensys)
|
|
assert_eq!(config.network.boot_nodes_enr[6].to_base64(), mainnet[6]);
|
|
assert_eq!(config.network.boot_nodes_enr[7].to_base64(), mainnet[7]);
|
|
// Prysm team (Prysmatic Labs)
|
|
assert_eq!(config.network.boot_nodes_enr[8].to_base64(), mainnet[8]);
|
|
assert_eq!(config.network.boot_nodes_enr[9].to_base64(), mainnet[9]);
|
|
assert_eq!(config.network.boot_nodes_enr[10].to_base64(), mainnet[10]);
|
|
// Nimbus team
|
|
assert_eq!(config.network.boot_nodes_enr[11].to_base64(), mainnet[11]);
|
|
assert_eq!(config.network.boot_nodes_enr[12].to_base64(), mainnet[12]);
|
|
});
|
|
}
|
|
#[test]
|
|
fn boot_nodes_flag() {
|
|
let nodes = "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8,\
|
|
enr:-LK4QFOFWca5ABQzxiCRcy37G7wy1K6zD4qMYBSN5ozzanwze_XVvXVhCk9JvF0cHXOBZrHK1E4vU7Gn-a0bHVczoDU6h2F0dG5ldHOIAAAAAAAAAACEZXRoMpA7CIeVAAAgCf__________gmlkgnY0gmlwhNIy-4iJc2VjcDI1NmsxoQJA3AXQJ6M3NpBWtJS3HPtbXG14t7qHjXuIaL6IOz89T4N0Y3CCIyiDdWRwgiMo";
|
|
let enr: Vec<&str> = nodes.split(',').collect();
|
|
CommandLineTest::new()
|
|
.flag("boot-nodes", Some(nodes))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), enr[0]);
|
|
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), enr[1]);
|
|
});
|
|
}
|
|
#[test]
|
|
fn boot_nodes_multiaddr_flag() {
|
|
let nodes = "/ip4/0.0.0.0/tcp/9000/p2p/16Uiu2HAkynrfLjeoAP7R3WFySad2NfduShkTpx8f8ygpSSfP1yen,\
|
|
/ip4/192.167.55.55/tcp/9000/p2p/16Uiu2HAkynrfLjeoBP7R3WFyDad2NfduVhkWpx8f8ygpSSfP1yen";
|
|
let multiaddr: Vec<&str> = nodes.split(',').collect();
|
|
CommandLineTest::new()
|
|
.flag("boot-nodes", Some(nodes))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.network.boot_nodes_multiaddr[0].to_string(),
|
|
multiaddr[0]
|
|
);
|
|
assert_eq!(
|
|
config.network.boot_nodes_multiaddr[1].to_string(),
|
|
multiaddr[1]
|
|
);
|
|
});
|
|
}
|
|
#[test]
|
|
fn private_flag() {
|
|
CommandLineTest::new()
|
|
.flag("private", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.private));
|
|
}
|
|
#[test]
|
|
fn zero_ports_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.enr_address, None);
|
|
assert_eq!(config.http_api.listen_port, 0);
|
|
assert_eq!(config.http_metrics.listen_port, 0);
|
|
});
|
|
}
|
|
#[test]
|
|
fn network_load_flag() {
|
|
CommandLineTest::new()
|
|
.flag("network-load", Some("4"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.network_load, 4);
|
|
});
|
|
}
|
|
|
|
// Tests for ENR flags.
|
|
#[test]
|
|
fn enr_udp_port_flags() {
|
|
let port = unused_udp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port)));
|
|
}
|
|
#[test]
|
|
fn enr_tcp_port_flags() {
|
|
let port = unused_tcp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port)));
|
|
}
|
|
#[test]
|
|
fn enr_match_flag() {
|
|
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
|
let port1 = unused_udp_port().expect("Unable to find unused port.");
|
|
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("enr-match", None)
|
|
.flag("listen-address", Some("127.0.0.2"))
|
|
.flag("discovery-port", Some(port1.to_string().as_str()))
|
|
.flag("port", Some(port2.to_string().as_str()))
|
|
.run()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.listen_address, addr);
|
|
assert_eq!(config.network.enr_address, Some(addr));
|
|
assert_eq!(config.network.discovery_port, port1);
|
|
assert_eq!(config.network.enr_udp_port, Some(port1));
|
|
});
|
|
}
|
|
#[test]
|
|
fn enr_address_flag() {
|
|
let addr = "192.167.1.1".parse::<IpAddr>().unwrap();
|
|
let port = unused_udp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("enr-address", Some("192.167.1.1"))
|
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.network.enr_address, Some(addr));
|
|
assert_eq!(config.network.enr_udp_port, Some(port));
|
|
});
|
|
}
|
|
#[test]
|
|
fn enr_address_dns_flag() {
|
|
let addr = "127.0.0.1".parse::<IpAddr>().unwrap();
|
|
let ipv6addr = "::1".parse::<IpAddr>().unwrap();
|
|
let port = unused_udp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("enr-address", Some("localhost"))
|
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(
|
|
config.network.enr_address == Some(addr)
|
|
|| config.network.enr_address == Some(ipv6addr)
|
|
);
|
|
assert_eq!(config.network.enr_udp_port, Some(port));
|
|
});
|
|
}
|
|
#[test]
|
|
fn disable_enr_auto_update_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-enr-auto-update", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.network.discv5_config.enr_update));
|
|
}
|
|
|
|
// Tests for HTTP flags.
|
|
#[test]
|
|
fn http_flag() {
|
|
CommandLineTest::new()
|
|
.flag("http", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.http_api.enabled));
|
|
}
|
|
#[test]
|
|
fn http_address_flag() {
|
|
let addr = "127.0.0.99".parse::<IpAddr>().unwrap();
|
|
CommandLineTest::new()
|
|
.flag("http-address", Some("127.0.0.99"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.listen_addr, addr));
|
|
}
|
|
#[test]
|
|
fn http_address_ipv6_flag() {
|
|
let addr = "::1".parse::<IpAddr>().unwrap();
|
|
CommandLineTest::new()
|
|
.flag("http-address", Some("::1"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.listen_addr, addr));
|
|
}
|
|
#[test]
|
|
fn http_port_flag() {
|
|
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
|
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("http-port", Some(port1.to_string().as_str()))
|
|
.flag("port", Some(port2.to_string().as_str()))
|
|
.run()
|
|
.with_config(|config| assert_eq!(config.http_api.listen_port, port1));
|
|
}
|
|
#[test]
|
|
fn http_allow_origin_flag() {
|
|
CommandLineTest::new()
|
|
.flag("http-allow-origin", Some("127.0.0.99"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.http_api.allow_origin, Some("127.0.0.99".to_string()));
|
|
});
|
|
}
|
|
#[test]
|
|
fn http_allow_origin_all_flag() {
|
|
CommandLineTest::new()
|
|
.flag("http-allow-origin", Some("*"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string())));
|
|
}
|
|
#[test]
|
|
fn http_allow_sync_stalled_flag() {
|
|
CommandLineTest::new()
|
|
.flag("http-allow-sync-stalled", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.allow_sync_stalled, true));
|
|
}
|
|
#[test]
|
|
fn http_tls_flags() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("http-enable-tls", None)
|
|
.flag(
|
|
"http-tls-cert",
|
|
dir.path().join("certificate.crt").as_os_str().to_str(),
|
|
)
|
|
.flag(
|
|
"http-tls-key",
|
|
dir.path().join("private.key").as_os_str().to_str(),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let tls_config = config
|
|
.http_api
|
|
.tls_config
|
|
.as_ref()
|
|
.expect("tls_config was empty.");
|
|
assert_eq!(tls_config.cert, dir.path().join("certificate.crt"));
|
|
assert_eq!(tls_config.key, dir.path().join("private.key"));
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn http_spec_fork_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.spec_fork_name, None));
|
|
}
|
|
|
|
#[test]
|
|
fn http_spec_fork_override() {
|
|
CommandLineTest::new()
|
|
.flag("http-spec-fork", Some("altair"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_api.spec_fork_name, Some(ForkName::Altair)));
|
|
}
|
|
|
|
// Tests for Metrics flags.
|
|
#[test]
|
|
fn metrics_flag() {
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.http_metrics.enabled);
|
|
assert!(config.network.metrics_enabled);
|
|
});
|
|
}
|
|
#[test]
|
|
fn metrics_address_flag() {
|
|
let addr = "127.0.0.99".parse::<IpAddr>().unwrap();
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.flag("metrics-address", Some("127.0.0.99"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr));
|
|
}
|
|
#[test]
|
|
fn metrics_address_ipv6_flag() {
|
|
let addr = "::1".parse::<IpAddr>().unwrap();
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.flag("metrics-address", Some("::1"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr));
|
|
}
|
|
#[test]
|
|
fn metrics_port_flag() {
|
|
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
|
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.flag("metrics-port", Some(port1.to_string().as_str()))
|
|
.flag("port", Some(port2.to_string().as_str()))
|
|
.run()
|
|
.with_config(|config| assert_eq!(config.http_metrics.listen_port, port1));
|
|
}
|
|
#[test]
|
|
fn metrics_allow_origin_flag() {
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.flag("metrics-allow-origin", Some("http://localhost:5059"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.http_metrics.allow_origin,
|
|
Some("http://localhost:5059".to_string())
|
|
)
|
|
});
|
|
}
|
|
#[test]
|
|
fn metrics_allow_origin_all_flag() {
|
|
CommandLineTest::new()
|
|
.flag("metrics", None)
|
|
.flag("metrics-allow-origin", Some("*"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.http_metrics.allow_origin, Some("*".to_string())));
|
|
}
|
|
|
|
// Tests for Validator Monitor flags.
|
|
#[test]
|
|
fn validator_monitor_auto_flag() {
|
|
CommandLineTest::new()
|
|
.flag("validator-monitor-auto", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.validator_monitor_auto));
|
|
}
|
|
#[test]
|
|
fn validator_monitor_pubkeys_flag() {
|
|
CommandLineTest::new()
|
|
.flag("validator-monitor-pubkeys", Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\
|
|
0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
|
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
|
});
|
|
}
|
|
#[test]
|
|
fn validator_monitor_file_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
let mut file = File::create(dir.path().join("pubkeys.txt")).expect("Unable to create file");
|
|
file.write_all(b"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\
|
|
0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
|
|
.expect("Unable to write to file");
|
|
CommandLineTest::new()
|
|
.flag("validator-monitor-file", dir.path().join("pubkeys.txt").as_os_str().to_str())
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
|
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
|
});
|
|
}
|
|
#[test]
|
|
fn validator_monitor_metrics_threshold_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.validator_monitor_individual_tracking_threshold,
|
|
// If this value changes make sure to update the help text for
|
|
// the CLI command.
|
|
64
|
|
)
|
|
});
|
|
}
|
|
#[test]
|
|
fn validator_monitor_metrics_threshold_custom() {
|
|
CommandLineTest::new()
|
|
.flag(
|
|
"validator-monitor-individual-tracking-threshold",
|
|
Some("42"),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert_eq!(config.validator_monitor_individual_tracking_threshold, 42)
|
|
});
|
|
}
|
|
|
|
// Tests for Store flags.
|
|
#[test]
|
|
fn slots_per_restore_point_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slots-per-restore-point", Some("64"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.store.slots_per_restore_point, 64));
|
|
}
|
|
#[test]
|
|
fn slots_per_restore_point_update_prev_default() {
|
|
use beacon_node::beacon_chain::store::config::{
|
|
DEFAULT_SLOTS_PER_RESTORE_POINT, PREV_DEFAULT_SLOTS_PER_RESTORE_POINT,
|
|
};
|
|
|
|
CommandLineTest::new()
|
|
.flag("slots-per-restore-point", Some("2048"))
|
|
.run_with_zero_port()
|
|
.with_config_and_dir(|config, dir| {
|
|
// Check that 2048 is the previous default.
|
|
assert_eq!(
|
|
config.store.slots_per_restore_point,
|
|
PREV_DEFAULT_SLOTS_PER_RESTORE_POINT
|
|
);
|
|
|
|
// Restart the BN with the same datadir and the new default SPRP. It should
|
|
// allow this.
|
|
CommandLineTest::new()
|
|
.flag("datadir", Some(&dir.path().display().to_string()))
|
|
.flag("zero-ports", None)
|
|
.run_with_no_datadir()
|
|
.with_config(|config| {
|
|
// The dumped config will have the new default 8192 value, but the fact that
|
|
// the BN started and ran (with the same datadir) means that the override
|
|
// was successful.
|
|
assert_eq!(
|
|
config.store.slots_per_restore_point,
|
|
DEFAULT_SLOTS_PER_RESTORE_POINT
|
|
);
|
|
});
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn block_cache_size_flag() {
|
|
CommandLineTest::new()
|
|
.flag("block-cache-size", Some("4"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.store.block_cache_size, 4_usize));
|
|
}
|
|
#[test]
|
|
fn auto_compact_db_flag() {
|
|
CommandLineTest::new()
|
|
.flag("auto-compact-db", Some("false"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.store.compact_on_prune));
|
|
}
|
|
#[test]
|
|
fn compact_db_flag() {
|
|
CommandLineTest::new()
|
|
.flag("auto-compact-db", Some("false"))
|
|
.flag("compact-db", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.store.compact_on_init));
|
|
}
|
|
#[test]
|
|
fn prune_payloads_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.store.prune_payloads));
|
|
}
|
|
#[test]
|
|
fn prune_payloads_on_startup_false() {
|
|
CommandLineTest::new()
|
|
.flag("prune-payloads", Some("false"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.store.prune_payloads));
|
|
}
|
|
#[test]
|
|
fn reconstruct_historic_states_flag() {
|
|
CommandLineTest::new()
|
|
.flag("reconstruct-historic-states", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(config.chain.reconstruct_historic_states));
|
|
}
|
|
#[test]
|
|
fn no_reconstruct_historic_states_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert!(!config.chain.reconstruct_historic_states));
|
|
}
|
|
|
|
// Tests for Slasher flags.
|
|
#[test]
|
|
fn slasher_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.run_with_zero_port()
|
|
.with_config_and_dir(|config, dir| {
|
|
if let Some(slasher_config) = &config.slasher {
|
|
assert_eq!(
|
|
slasher_config.database_path,
|
|
dir.path().join("beacon").join("slasher_db")
|
|
)
|
|
} else {
|
|
panic!("Slasher config was parsed incorrectly");
|
|
}
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_dir_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-dir", dir.path().as_os_str().to_str())
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
if let Some(slasher_config) = &config.slasher {
|
|
assert_eq!(slasher_config.database_path, dir.path());
|
|
} else {
|
|
panic!("Slasher config was parsed incorrectly");
|
|
}
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_update_period_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-update-period", Some("100"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
if let Some(slasher_config) = &config.slasher {
|
|
assert_eq!(slasher_config.update_period, 100);
|
|
} else {
|
|
panic!("Slasher config was parsed incorrectly");
|
|
}
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_slot_offset_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-slot-offset", Some("11.25"))
|
|
.run()
|
|
.with_config(|config| {
|
|
let slasher_config = config.slasher.as_ref().unwrap();
|
|
assert_eq!(slasher_config.slot_offset, 11.25);
|
|
});
|
|
}
|
|
#[test]
|
|
#[should_panic]
|
|
fn slasher_slot_offset_nan_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-slot-offset", Some("NaN"))
|
|
.run();
|
|
}
|
|
#[test]
|
|
fn slasher_history_length_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-history-length", Some("2048"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
if let Some(slasher_config) = &config.slasher {
|
|
assert_eq!(slasher_config.history_length, 2048);
|
|
} else {
|
|
panic!("Slasher config was parsed incorrectly");
|
|
}
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_max_db_size_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-max-db-size", Some("10"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert_eq!(slasher_config.max_db_size_mbs, 10240);
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_attestation_cache_size_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-att-cache-size", Some("10000"))
|
|
.run()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert_eq!(slasher_config.attestation_root_cache_size, 10000);
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_chunk_size_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-chunk-size", Some("32"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert_eq!(slasher_config.chunk_size, 32);
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_validator_chunk_size_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-validator-chunk-size", Some("512"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert_eq!(slasher_config.validator_chunk_size, 512);
|
|
});
|
|
}
|
|
#[test]
|
|
fn slasher_broadcast_flag() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-broadcast", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert!(slasher_config.broadcast);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn slasher_backend_default() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config.slasher.as_ref().unwrap();
|
|
assert_eq!(slasher_config.backend, slasher::DatabaseBackend::Mdbx);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn slasher_backend_override_to_default() {
|
|
// Hard to test this flag because all but one backend is disabled by default and the backend
|
|
// called "disabled" results in a panic.
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-backend", Some("mdbx"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config.slasher.as_ref().unwrap();
|
|
assert_eq!(slasher_config.backend, slasher::DatabaseBackend::Mdbx);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn malloc_tuning_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-malloc-tuning", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(!config.http_metrics.allocator_metrics_enabled);
|
|
});
|
|
}
|
|
#[test]
|
|
#[should_panic]
|
|
fn ensure_panic_on_failed_launch() {
|
|
CommandLineTest::new()
|
|
.flag("slasher", None)
|
|
.flag("slasher-chunk-size", Some("10"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let slasher_config = config
|
|
.slasher
|
|
.as_ref()
|
|
.expect("Unable to parse Slasher config");
|
|
assert_eq!(slasher_config.chunk_size, 10);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn enable_proposer_re_orgs_default() {
|
|
CommandLineTest::new().run().with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.re_org_threshold,
|
|
Some(DEFAULT_RE_ORG_THRESHOLD)
|
|
);
|
|
assert_eq!(
|
|
config.chain.re_org_max_epochs_since_finalization,
|
|
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION,
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn disable_proposer_re_orgs() {
|
|
CommandLineTest::new()
|
|
.flag("disable-proposer-reorgs", None)
|
|
.run()
|
|
.with_config(|config| assert_eq!(config.chain.re_org_threshold, None));
|
|
}
|
|
|
|
#[test]
|
|
fn proposer_re_org_threshold() {
|
|
CommandLineTest::new()
|
|
.flag("proposer-reorg-threshold", Some("90"))
|
|
.run()
|
|
.with_config(|config| assert_eq!(config.chain.re_org_threshold.unwrap().0, 90));
|
|
}
|
|
|
|
#[test]
|
|
fn proposer_re_org_max_epochs_since_finalization() {
|
|
CommandLineTest::new()
|
|
.flag("proposer-reorg-epochs-since-finalization", Some("8"))
|
|
.run()
|
|
.with_config(|config| {
|
|
assert_eq!(
|
|
config.chain.re_org_max_epochs_since_finalization.as_u64(),
|
|
8
|
|
)
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn monitoring_endpoint() {
|
|
CommandLineTest::new()
|
|
.flag("monitoring-endpoint", Some("http://example:8000"))
|
|
.flag("monitoring-endpoint-period", Some("30"))
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
let api_conf = config.monitoring_api.as_ref().unwrap();
|
|
assert_eq!(api_conf.monitoring_endpoint.as_str(), "http://example:8000");
|
|
assert_eq!(api_conf.update_period_secs, Some(30));
|
|
});
|
|
}
|
|
|
|
// Tests for Logger flags.
|
|
#[test]
|
|
fn default_log_color_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(!config.logger_config.log_color);
|
|
});
|
|
}
|
|
#[test]
|
|
fn enabled_log_color_flag() {
|
|
CommandLineTest::new()
|
|
.flag("log-color", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.logger_config.log_color);
|
|
});
|
|
}
|
|
#[test]
|
|
fn default_disable_log_timestamp_flag() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(!config.logger_config.disable_log_timestamp);
|
|
});
|
|
}
|
|
#[test]
|
|
fn enabled_disable_log_timestamp_flag() {
|
|
CommandLineTest::new()
|
|
.flag("disable-log-timestamp", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.logger_config.disable_log_timestamp);
|
|
});
|
|
}
|
|
#[test]
|
|
fn logfile_restricted_perms_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.logger_config.is_restricted);
|
|
});
|
|
}
|
|
#[test]
|
|
fn logfile_no_restricted_perms_flag() {
|
|
CommandLineTest::new()
|
|
.flag("logfile-no-restricted-perms", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.logger_config.is_restricted == false);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn sync_eth1_chain_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.sync_eth1_chain, false));
|
|
}
|
|
|
|
#[test]
|
|
fn sync_eth1_chain_execution_endpoints_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("execution-endpoints", Some("http://localhost:8551/"))
|
|
.flag(
|
|
"execution-jwt",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.sync_eth1_chain, true));
|
|
}
|
|
|
|
#[test]
|
|
fn sync_eth1_chain_disable_deposit_contract_sync_flag() {
|
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
|
CommandLineTest::new()
|
|
.flag("disable-deposit-contract-sync", None)
|
|
.flag("execution-endpoints", Some("http://localhost:8551/"))
|
|
.flag(
|
|
"execution-jwt",
|
|
dir.path().join("jwt-file").as_os_str().to_str(),
|
|
)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.sync_eth1_chain, false));
|
|
}
|
|
|
|
#[test]
|
|
fn light_client_server_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.enable_light_client_server, false));
|
|
}
|
|
|
|
#[test]
|
|
fn light_client_server_enabled() {
|
|
CommandLineTest::new()
|
|
.flag("light-client-server", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| assert_eq!(config.network.enable_light_client_server, true));
|
|
}
|
|
|
|
#[test]
|
|
fn gui_flag() {
|
|
CommandLineTest::new()
|
|
.flag("gui", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.http_api.enabled);
|
|
assert!(config.validator_monitor_auto);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn optimistic_finalized_sync_default() {
|
|
CommandLineTest::new()
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(config.chain.optimistic_finalized_sync);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn disable_optimistic_finalized_sync() {
|
|
CommandLineTest::new()
|
|
.flag("disable-optimistic-finalized-sync", None)
|
|
.run_with_zero_port()
|
|
.with_config(|config| {
|
|
assert!(!config.chain.optimistic_finalized_sync);
|
|
});
|
|
}
|