diff --git a/lib/src/clients/blobssss.rs b/lib/src/clients/blobssss.rs index 57f4d40..255d466 100644 --- a/lib/src/clients/blobssss.rs +++ b/lib/src/clients/blobssss.rs @@ -1,19 +1,21 @@ -use std::collections::HashMap; use crate::clients::Client; +use crate::clients::CommonArgs; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; use crate::Error; use itertools::Itertools; use serde::Deserialize; +use std::collections::HashMap; #[derive(Deserialize, Debug, Clone)] pub struct Blobssss { - executable: String, - private_key: String, - min_per_slot: u8, - max_per_slot: u8, - start_time: String, + #[serde(flatten)] + pub common: CommonArgs, + pub private_key: String, + pub min_per_slot: u8, + pub max_per_slot: u8, + pub start_time: String, } #[typetag::deserialize(name = "blobssss")] @@ -25,13 +27,14 @@ impl Client for Blobssss { _validators: &[Validator], ) -> Result { Ok(Process { - path: self.executable.clone().into(), + path: self.common.executable_or("blobssss"), args: format!( - "--min {} --max {} --key {} --rpcs {}", + "--min {} --max {} --key {} --rpcs {} {}", self.min_per_slot, self.max_per_slot, self.private_key, ctx.el_http_endpoints().iter().join(","), + self.common.extra_args, ), environment: HashMap::default(), expected_final_state: "running".into(), diff --git a/lib/src/clients/geth.rs b/lib/src/clients/geth.rs index 5d997c6..d6098af 100644 --- a/lib/src/clients/geth.rs +++ b/lib/src/clients/geth.rs @@ -1,10 +1,10 @@ +use crate::clients::CommonArgs; use crate::clients::ENGINE_API_PORT; use crate::clients::{Client, JSON_RPC_PORT}; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::utils::log_and_wait; use crate::validators::Validator; -use crate::CowStr; use crate::Error; use log::debug; use serde::Deserialize; @@ -13,18 +13,11 @@ use std::process::Command; const PORT: &str = "21000"; -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] #[serde(default)] pub struct Geth { - pub executable: CowStr, -} - -impl Default for Geth { - fn default() -> Self { - Self { - executable: "geth".into(), - } - } + #[serde(flatten)] + pub common: CommonArgs, } #[typetag::deserialize(name = "geth")] @@ -41,9 +34,11 @@ impl Client for Geth { let dir = node.dir().join("geth"); let dir = dir.to_str().ok_or(Error::NonUTF8Path)?; + let executable = self.common.executable_or("geth"); + debug!("Calling geth init"); let status = log_and_wait( - Command::new(self.executable.as_ref()) + Command::new(executable.as_ref()) .arg("init") .arg("--datadir") .arg(dir) @@ -56,7 +51,7 @@ impl Client for Geth { ctx.add_el_http_endpoint(format!("http://{}:{JSON_RPC_PORT}", node.ip())); Ok(Process { - path: self.executable.clone(), + path: executable, args: format!( "--datadir {dir} \ --authrpc.port {ENGINE_API_PORT} \ @@ -70,10 +65,11 @@ impl Client for Geth { --nat extip:{} \ --ipcdisable \ --log.file {dir}/geth.log \ - --syncmode full", + --syncmode full {}", ctx.jwt_path().to_str().ok_or(Error::NonUTF8Path)?, ctx.el_bootnode_enodes().join(","), node.ip(), + self.common.extra_args, ), environment: HashMap::new(), expected_final_state: "running".into(), diff --git a/lib/src/clients/geth_bootnode.rs b/lib/src/clients/geth_bootnode.rs index 99ea2a4..b35bfb2 100644 --- a/lib/src/clients/geth_bootnode.rs +++ b/lib/src/clients/geth_bootnode.rs @@ -1,3 +1,4 @@ +use crate::clients::CommonArgs; use std::collections::HashMap; use std::fs::{create_dir, File}; use std::io::Write; @@ -8,23 +9,15 @@ use serde::Deserialize; use crate::clients::{Client, Validator}; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; -use crate::CowStr; use crate::Error; const DISC_PORT: u16 = 30305; -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] #[serde(default)] pub struct GethBootnode { - pub executable: CowStr, -} - -impl Default for GethBootnode { - fn default() -> Self { - Self { - executable: "bootnode".into(), - } - } + #[serde(flatten)] + pub common: CommonArgs, } #[typetag::deserialize(name = "geth_bootnode")] @@ -54,16 +47,17 @@ impl Client for GethBootnode { ctx.add_el_bootnode_enode(format!("enode://{pub_key}@{ip}:0?discport={DISC_PORT}")); Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("bootnode"), args: format!( "-nodekey \"{key_file}\" \ -verbosity 5 \ -addr :{DISC_PORT} \ - -nat extip:{ip}" + -nat extip:{ip} {}", + self.common.extra_args, ), environment: HashMap::new(), expected_final_state: "running".into(), - start_time: "0s".into(), + start_time: "0s".into() }) } } diff --git a/lib/src/clients/lighthouse.rs b/lib/src/clients/lighthouse.rs index 40a6c73..accfe5a 100644 --- a/lib/src/clients/lighthouse.rs +++ b/lib/src/clients/lighthouse.rs @@ -1,9 +1,9 @@ use crate::clients::Client; +use crate::clients::CommonArgs; use crate::clients::{BEACON_API_PORT, CL_PROMETHEUS_PORT, ENGINE_API_PORT}; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; -use crate::CowStr; use crate::Error; use serde::Deserialize; use std::collections::HashMap; @@ -13,16 +13,15 @@ const PORT: &str = "31000"; #[derive(Deserialize, Debug, Clone)] #[serde(default)] pub struct Lighthouse { - pub executable: CowStr, - pub extra_args: String, + #[serde(flatten)] + pub common: CommonArgs, pub lower_target_peers: bool, } impl Default for Lighthouse { fn default() -> Self { Self { - executable: "lighthouse".into(), - extra_args: String::new(), + common: CommonArgs::default(), lower_target_peers: true, } } @@ -66,19 +65,18 @@ impl Client for Lighthouse { --disable-packet-filter \ --metrics-address 0.0.0.0 \ --metrics-port {CL_PROMETHEUS_PORT} \ - --metrics \ - {} ", + --metrics {}", ctx.metadata_path().to_str().ok_or(Error::NonUTF8Path)?, ctx.jwt_path().to_str().ok_or(Error::NonUTF8Path)?, ctx.cl_bootnode_enrs().join(","), - self.extra_args, + self.common.extra_args, ); if self.lower_target_peers && ctx.num_cl_clients() <= 100 { args.push_str(&format!("--target-peers {}", ctx.num_cl_clients() - 1)); } Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("lighthouse"), args, environment: HashMap::new(), expected_final_state: "running".into(), diff --git a/lib/src/clients/lighthouse_bootnode.rs b/lib/src/clients/lighthouse_bootnode.rs index a5495f1..309ac28 100644 --- a/lib/src/clients/lighthouse_bootnode.rs +++ b/lib/src/clients/lighthouse_bootnode.rs @@ -1,3 +1,4 @@ +use crate::clients::CommonArgs; use log::debug; use serde::Deserialize; use std::collections::HashMap; @@ -16,14 +17,15 @@ const PORT: &str = "4011"; #[derive(Deserialize, Debug, Clone)] #[serde(default)] pub struct LighthouseBootnode { - pub executable: CowStr, + #[serde(flatten)] + pub common: CommonArgs, pub lcli_executable: CowStr, } impl Default for LighthouseBootnode { fn default() -> Self { Self { - executable: "lighthouse".into(), + common: CommonArgs::default(), lcli_executable: "lcli".into(), } } @@ -66,15 +68,16 @@ impl Client for LighthouseBootnode { ctx.add_cl_bootnode_enr(enr); Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("lighthouse"), args: format!( "--testnet-dir \"{}\" \ boot_node \ --port {PORT} \ --disable-packet-filter \ - --network-dir {}", + --network-dir {} {}", ctx.metadata_path().to_str().ok_or(Error::NonUTF8Path)?, dir.to_str().ok_or(Error::NonUTF8Path)?, + self.common.extra_args, ), environment: HashMap::new(), expected_final_state: "running".into(), diff --git a/lib/src/clients/lighthouse_vc.rs b/lib/src/clients/lighthouse_vc.rs index d737e4b..0ee96e2 100644 --- a/lib/src/clients/lighthouse_vc.rs +++ b/lib/src/clients/lighthouse_vc.rs @@ -1,31 +1,23 @@ +use crate::clients::CommonArgs; use crate::clients::BEACON_API_PORT; use crate::clients::{Client, ValidatorDemand}; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; -use crate::CowStr; use crate::Error; use serde::Deserialize; use std::collections::HashMap; use std::fs; use std::fs::create_dir; -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] #[serde(default)] pub struct LighthouseValidatorClient { - pub executable: CowStr, + #[serde(flatten)] + pub common: CommonArgs, pub validators: Option, } -impl Default for LighthouseValidatorClient { - fn default() -> Self { - Self { - executable: "lighthouse".into(), - validators: None, - } - } -} - #[typetag::deserialize(name = "lighthouse_vc")] impl Client for LighthouseValidatorClient { fn add_to_node( @@ -62,15 +54,16 @@ impl Client for LighthouseValidatorClient { } Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("lighthouse"), args: format!( "--testnet-dir \"{}\" \ validator_client \ --datadir \"{dir_str}\" \ --beacon-nodes http://localhost:{BEACON_API_PORT} \ --suggested-fee-recipient 0xf97e180c050e5Ab072211Ad2C213Eb5AEE4DF134 \ - --init-slashing-protection", + --init-slashing-protection {}", ctx.metadata_path().to_str().ok_or(Error::NonUTF8Path)?, + self.common.extra_args, ), environment: HashMap::new(), expected_final_state: "running".into(), diff --git a/lib/src/clients/mod.rs b/lib/src/clients/mod.rs index 663f2c7..1780090 100644 --- a/lib/src/clients/mod.rs +++ b/lib/src/clients/mod.rs @@ -1,7 +1,9 @@ use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; +use crate::CowStr; use crate::Error; +use serde::Deserialize; use std::fmt::Debug; const ENGINE_API_PORT: &str = "21001"; @@ -49,3 +51,20 @@ pub trait Client: Debug { false } } + +#[derive(Deserialize, Debug, Clone, Default)] +#[serde(default)] +pub struct CommonArgs { + pub executable: String, + pub extra_args: String, +} + +impl CommonArgs { + pub fn executable_or(&self, default: &'static str) -> CowStr { + if self.executable.is_empty() { + default.into() + } else { + self.executable.clone().into() + } + } +} diff --git a/lib/src/clients/prometheus.rs b/lib/src/clients/prometheus.rs index af8b4c7..f5b8cbb 100644 --- a/lib/src/clients/prometheus.rs +++ b/lib/src/clients/prometheus.rs @@ -1,26 +1,19 @@ use crate::clients::Client; +use crate::clients::CommonArgs; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; -use crate::CowStr; use crate::Error; use serde::{Deserialize, Serialize}; use serde_yaml::to_writer; use std::collections::HashMap; use std::fs::File; -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] #[serde(default)] pub struct Prometheus { - executable: CowStr, -} - -impl Default for Prometheus { - fn default() -> Self { - Self { - executable: "prometheus".into(), - } - } + #[serde(flatten)] + common: CommonArgs, } #[derive(Serialize)] @@ -72,11 +65,12 @@ impl Client for Prometheus { to_writer(File::create_new(&config_file)?, &config)?; Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("prometheus"), args: format!( - "--storage.tsdb.path={} --config.file={}", + "--storage.tsdb.path={} --config.file={} {}", dir.to_str().ok_or(Error::NonUTF8Path)?, config_file.to_str().ok_or(Error::NonUTF8Path)?, + self.common.extra_args, ), environment: HashMap::default(), expected_final_state: "running".into(), diff --git a/lib/src/clients/reth.rs b/lib/src/clients/reth.rs index e9571ba..3572192 100644 --- a/lib/src/clients/reth.rs +++ b/lib/src/clients/reth.rs @@ -1,27 +1,20 @@ +use crate::clients::CommonArgs; use crate::clients::ENGINE_API_PORT; use crate::clients::{Client, JSON_RPC_PORT}; use crate::config::shadow::Process; use crate::node::{NodeInfo, SimulationContext}; use crate::validators::Validator; -use crate::CowStr; use crate::Error; use serde::Deserialize; use std::collections::HashMap; const PORT: &str = "21000"; -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] #[serde(default)] pub struct Reth { - pub executable: CowStr, -} - -impl Default for Reth { - fn default() -> Self { - Self { - executable: "reth".into(), - } - } + #[serde(flatten)] + pub common: CommonArgs, } #[typetag::deserialize(name = "reth")] @@ -41,7 +34,7 @@ impl Client for Reth { ctx.add_el_http_endpoint(format!("http://{}:{JSON_RPC_PORT}", node.ip())); Ok(Process { - path: self.executable.clone(), + path: self.common.executable_or("reth"), args: format!( "node \ --chain {genesis_file} \ @@ -56,10 +49,11 @@ impl Client for Reth { --bootnodes {} \ --nat extip:{} \ --ipcdisable \ - --log.file.directory {dir}", + --log.file.directory {dir} {}", ctx.jwt_path().to_str().ok_or(Error::NonUTF8Path)?, ctx.el_bootnode_enodes().join(","), node.ip(), + self.common.extra_args, ), environment: HashMap::new(), expected_final_state: "running".into(),