diff --git a/crates/cli/src/docker_init.rs b/crates/cli/src/docker_init.rs index 5d25736..ad9f98f 100644 --- a/crates/cli/src/docker_init.rs +++ b/crates/cli/src/docker_init.rs @@ -88,7 +88,7 @@ pub async fn handle_docker_init(config_path: String, output_dir: String) -> Resu let mut warnings = Vec::new(); - let mut needs_signer_module = cb_config.pbs.with_signer; + let mut needs_signer_module = cb_config.pbs_modules[0].with_signer; // setup modules if let Some(modules_config) = cb_config.modules { @@ -267,13 +267,13 @@ pub async fn handle_docker_init(config_path: String, output_dir: String) -> Resu // ports let host_endpoint = - SocketAddr::from((cb_config.pbs.pbs_config.host, cb_config.pbs.pbs_config.port)); - let ports = Ports::Short(vec![format!("{}:{}", host_endpoint, cb_config.pbs.pbs_config.port)]); - warnings.push(format!("pbs has an exported port on {}", cb_config.pbs.pbs_config.port)); + SocketAddr::from((cb_config.pbs_modules[0].pbs_config.host, cb_config.pbs_modules[0].pbs_config.port)); + let ports = Ports::Short(vec![format!("{}:{}", host_endpoint, cb_config.pbs_modules[0].pbs_config.port)]); + warnings.push(format!("pbs has an exported port on {}", cb_config.pbs_modules[0].pbs_config.port)); // inside the container expose on 0.0.0.0 let container_endpoint = - SocketAddr::from((Ipv4Addr::UNSPECIFIED, cb_config.pbs.pbs_config.port)); + SocketAddr::from((Ipv4Addr::UNSPECIFIED, cb_config.pbs_modules[0].pbs_config.port)); let (key, val) = get_env_val(PBS_ENDPOINT_ENV, &container_endpoint.to_string()); pbs_envs.insert(key, val); @@ -290,7 +290,7 @@ pub async fn handle_docker_init(config_path: String, output_dir: String) -> Resu let pbs_service = Service { container_name: Some("cb_pbs".to_owned()), - image: Some(cb_config.pbs.docker_image), + image: Some(cb_config.pbs_modules[0].docker_image.clone()), ports, networks: pbs_networs, volumes: pbs_volumes, @@ -298,8 +298,7 @@ pub async fn handle_docker_init(config_path: String, output_dir: String) -> Resu healthcheck: Some(Healthcheck { test: Some(HealthcheckTest::Single(format!( "curl -f http://localhost:{}{}{}", - cb_config.pbs.pbs_config.port, BUILDER_API_PATH, GET_STATUS_PATH - ))), + cb_config.pbs_modules[0].pbs_config.port, BUILDER_API_PATH, GET_STATUS_PATH ))), interval: Some("30s".into()), timeout: Some("5s".into()), retries: 3, diff --git a/crates/common/src/config/mod.rs b/crates/common/src/config/mod.rs index b097d02..1aa098c 100644 --- a/crates/common/src/config/mod.rs +++ b/crates/common/src/config/mod.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use eyre::Result; +use eyre::{ensure, Result}; use serde::{Deserialize, Serialize}; use crate::types::{load_chain_from_file, Chain, ChainLoader, ForkVersion}; @@ -27,7 +27,7 @@ pub use utils::*; pub struct CommitBoostConfig { pub chain: Chain, pub relays: Vec, - pub pbs: StaticPbsConfig, + pub pbs_modules: Vec, #[serde(flatten)] pub muxes: Option, pub modules: Option>, @@ -39,7 +39,9 @@ pub struct CommitBoostConfig { impl CommitBoostConfig { /// Validate config pub async fn validate(&self) -> Result<()> { - self.pbs.pbs_config.validate(self.chain).await?; + ensure!(!self.pbs_modules.is_empty(), "must define at least one pbs_module"); + + self.pbs_modules[0].pbs_config.validate(self.chain).await?; Ok(()) } @@ -74,7 +76,7 @@ impl CommitBoostConfig { let config = CommitBoostConfig { chain, relays: helper_config.relays, - pbs: helper_config.pbs, + pbs_modules: helper_config.pbs, muxes: helper_config.muxes, modules: helper_config.modules, signer: helper_config.signer, @@ -111,7 +113,7 @@ struct ChainConfig { struct HelperConfig { chain: ChainLoader, relays: Vec, - pbs: StaticPbsConfig, + pbs: Vec, #[serde(flatten)] muxes: Option, modules: Option>, diff --git a/crates/common/src/config/module.rs b/crates/common/src/config/module.rs index 2476079..31a3e84 100644 --- a/crates/common/src/config/module.rs +++ b/crates/common/src/config/module.rs @@ -15,7 +15,7 @@ use crate::{ types::{Chain, Jwt, ModuleId}, }; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug,Clone, Deserialize, Serialize)] pub enum ModuleKind { #[serde(alias = "commit")] Commit, @@ -24,7 +24,7 @@ pub enum ModuleKind { } /// Static module config from config file -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug,Clone, Deserialize, Serialize)] pub struct StaticModuleConfig { /// Unique id of the module pub id: ModuleId, diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 32ff8e9..90c8045 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -1,3 +1,5 @@ +pub use crate::config::module::{StaticModuleConfig}; + use std::{ collections::{HashMap, HashSet}, path::{Path, PathBuf}, @@ -28,7 +30,7 @@ pub struct PbsMuxes { #[derive(Debug, Clone)] pub struct RuntimeMuxConfig { pub id: String, - pub config: Arc, + pub pbs_configs: Vec>, pub relays: Vec, } @@ -42,6 +44,7 @@ impl PbsMuxes { for mux in muxes.iter_mut() { ensure!(!mux.relays.is_empty(), "mux config {} must have at least one relay", mux.id); + ensure!(!mux.pbs_modules.is_empty(), "mux config {} must have at least one pbs module", mux.id); if let Some(loader) = &mux.loader { let extra_keys = loader.load(&mux.id, chain, default_pbs.rpc_url.clone()).await?; @@ -72,6 +75,7 @@ impl PbsMuxes { id = mux.id, keys = mux.validator_pubkeys.len(), relays = mux.relays.len(), + pbs_modules = mux.pbs_modules.len(), "using mux" ); @@ -80,18 +84,20 @@ impl PbsMuxes { relay_clients.push(RelayClient::new(config)?); } - let config = PbsConfig { - timeout_get_header_ms: mux - .timeout_get_header_ms - .unwrap_or(default_pbs.timeout_get_header_ms), - late_in_slot_time_ms: mux - .late_in_slot_time_ms - .unwrap_or(default_pbs.late_in_slot_time_ms), - ..default_pbs.clone() - }; - let config = Arc::new(config); - - let runtime_config = RuntimeMuxConfig { id: mux.id, config, relays: relay_clients }; + let mut pbs_configs = Vec::with_capacity(mux.pbs_modules.len().clone()); + + for config in mux.pbs_modules.iter().cloned() { + pbs_configs.push(PbsConfig::new(config)); + } + + let mut pbs_configs = Vec::with_capacity(mux.pbs_modules.len().clone()); + for config in mux.pbs_modules.into_iter() { + pbs_configs.push(Arc::new(PbsConfig::new(config))); + } + + // let config = Arc::new(config); + + let runtime_config = RuntimeMuxConfig { id: mux.id, pbs_configs, relays: relay_clients }; for pubkey in mux.validator_pubkeys.iter() { configs.insert(*pubkey, runtime_config.clone()); } @@ -108,10 +114,13 @@ pub struct MuxConfig { pub id: String, /// Relays to use for this mux config pub relays: Vec, + /// PBS Modules to use for this mux config + pub pbs_modules: Vec, /// Which validator pubkeys to match against this mux config #[serde(default)] pub validator_pubkeys: Vec, /// Loader for extra validator pubkeys + pub loader: Option, pub timeout_get_header_ms: Option, pub late_in_slot_time_ms: Option, @@ -121,6 +130,7 @@ impl MuxConfig { /// Returns the env, actual path, and internal path to use for the file /// loader pub fn loader_env(&self) -> Option<(String, String, String)> { + self.loader.as_ref().and_then(|loader| match loader { MuxKeysLoader::File(path_buf) => { let path = diff --git a/crates/common/src/config/pbs.rs b/crates/common/src/config/pbs.rs index 5e42b6c..f961335 100644 --- a/crates/common/src/config/pbs.rs +++ b/crates/common/src/config/pbs.rs @@ -6,6 +6,8 @@ use std::{ sync::Arc, }; +use super::{constants::PBS_IMAGE_DEFAULT, load_optional_env_var, CommitBoostConfig, RuntimeMuxConfig, StaticModuleConfig, PBS_ENDPOINT_ENV}; + use alloy::{ primitives::{utils::format_ether, U256}, providers::{Provider, ProviderBuilder}, @@ -15,10 +17,7 @@ use eyre::{ensure, Result}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use url::Url; -use super::{ - constants::PBS_IMAGE_DEFAULT, load_optional_env_var, CommitBoostConfig, RuntimeMuxConfig, - PBS_ENDPOINT_ENV, -}; + use crate::{ commit::client::SignerClient, config::{ @@ -101,6 +100,10 @@ pub struct PbsConfig { } impl PbsConfig { + + pub(crate) fn new(p0: StaticModuleConfig) -> PbsConfig { + todo!() + } /// Validate PBS config parameters pub async fn validate(&self, chain: Chain) -> Result<()> { // timeouts must be positive @@ -198,12 +201,12 @@ pub async fn load_pbs_config() -> Result { let endpoint = if let Some(endpoint) = load_optional_env_var(PBS_ENDPOINT_ENV) { endpoint.parse()? } else { - SocketAddr::from((config.pbs.pbs_config.host, config.pbs.pbs_config.port)) + SocketAddr::from((config.pbs_modules[0].pbs_config.host, config.pbs_modules[0].pbs_config.port)) }; let muxes = match config.muxes { Some(muxes) => { - let mux_configs = muxes.validate_and_fill(config.chain, &config.pbs.pbs_config).await?; + let mux_configs = muxes.validate_and_fill(config.chain, &config.pbs_modules[0].pbs_config).await?; Some(mux_configs) } None => None, @@ -235,7 +238,7 @@ pub async fn load_pbs_config() -> Result { Ok(PbsModuleConfig { chain: config.chain, endpoint, - pbs_config: Arc::new(config.pbs.pbs_config), + pbs_config: Arc::new(config.pbs_modules[0].pbs_config.clone()), relays: relay_clients, all_relays, signer_client: None, diff --git a/crates/pbs/src/state.rs b/crates/pbs/src/state.rs index 6b3f15c..d708ee4 100644 --- a/crates/pbs/src/state.rs +++ b/crates/pbs/src/state.rs @@ -58,7 +58,7 @@ where pubkey: &BlsPublicKey, ) -> (&PbsConfig, &[RelayClient], Option<&str>) { match self.config.muxes.as_ref().and_then(|muxes| muxes.get(pubkey)) { - Some(mux) => (&mux.config, mux.relays.as_slice(), Some(&mux.id)), + Some(mux) => (&mux.pbs_configs[0], mux.relays.as_slice(), Some(&mux.id)), // return only the default relays if there's no match None => (self.pbs_config(), &self.config.relays, None), }