Skip to content

Commit 50ff52c

Browse files
authored
CBST 06: dont expose ports by default (#179)
* pbs endpoint * fix test * metrics host
1 parent 49effd5 commit 50ff52c

File tree

10 files changed

+109
-29
lines changed

10 files changed

+109
-29
lines changed

config.example.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ docker_image = "ghcr.io/commit-boost/pbs:latest"
1515
# Whether to enable the PBS module to request signatures from the Signer module (not used in the default PBS image)
1616
# OPTIONAL, DEFAULT: false
1717
with_signer = false
18+
# Host to receive BuilderAPI calls from beacon node
19+
# OPTIONAL, DEFAULT: 127.0.0.1
20+
host = "127.0.0.1"
1821
# Port to receive BuilderAPI calls from beacon node
22+
# OPTIONAL, DEFAULT: 18550
1923
port = 18550
2024
# Whether to forward `status` calls to relays or skip and return 200
2125
# OPTIONAL, DEFAULT: true
@@ -138,6 +142,9 @@ SOME_ENV_VAR = "some_value"
138142
# Configuration for how metrics should be collected and scraped
139143
# OPTIONAL, skip metrics collection if missing
140144
[metrics]
145+
# Host for prometheus, grafana, and cadvisor
146+
# OPTIONAL, DEFAULT: 127.0.0.1
147+
host = "127.0.0.1"
141148
# Path to a `prometheus.yml` file to use in Prometheus. If using a custom config file, be sure to add a
142149
# file discovery section as follows:
143150
# ```yml

crates/cli/src/docker_init.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
use std::{path::Path, vec};
1+
use std::{
2+
net::{Ipv4Addr, SocketAddr},
3+
path::Path,
4+
vec,
5+
};
26

37
use cb_common::{
48
config::{
59
CommitBoostConfig, LogsSettings, ModuleKind, BUILDER_PORT_ENV, BUILDER_URLS_ENV,
610
CHAIN_SPEC_ENV, CONFIG_DEFAULT, CONFIG_ENV, JWTS_ENV, LOGS_DIR_DEFAULT, LOGS_DIR_ENV,
7-
METRICS_PORT_ENV, MODULE_ID_ENV, MODULE_JWT_ENV, PBS_MODULE_NAME, PROXY_DIR_DEFAULT,
8-
PROXY_DIR_ENV, SIGNER_DEFAULT, SIGNER_DIR_KEYS_DEFAULT, SIGNER_DIR_KEYS_ENV,
9-
SIGNER_DIR_SECRETS_DEFAULT, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV, SIGNER_MODULE_NAME,
10-
SIGNER_PORT_ENV, SIGNER_URL_ENV,
11+
METRICS_PORT_ENV, MODULE_ID_ENV, MODULE_JWT_ENV, PBS_ENDPOINT_ENV, PBS_MODULE_NAME,
12+
PROXY_DIR_DEFAULT, PROXY_DIR_ENV, SIGNER_DEFAULT, SIGNER_DIR_KEYS_DEFAULT,
13+
SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_DEFAULT, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV,
14+
SIGNER_MODULE_NAME, SIGNER_PORT_ENV, SIGNER_URL_ENV,
1115
},
1216
signer::{ProxyStore, SignerLoader},
1317
types::ModuleId,
@@ -233,6 +237,19 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
233237
pbs_envs.insert(k, v);
234238
}
235239

240+
// ports
241+
let host_endpoint =
242+
SocketAddr::from((cb_config.pbs.pbs_config.host, cb_config.pbs.pbs_config.port));
243+
let ports = Ports::Short(vec![format!("{}:{}", host_endpoint, cb_config.pbs.pbs_config.port)]);
244+
exposed_ports_warn
245+
.push(format!("pbs has an exported port on {}", cb_config.pbs.pbs_config.port));
246+
247+
// inside the container expose on 0.0.0.0
248+
let container_endpoint =
249+
SocketAddr::from((Ipv4Addr::UNSPECIFIED, cb_config.pbs.pbs_config.port));
250+
let (key, val) = get_env_val(PBS_ENDPOINT_ENV, &container_endpoint.to_string());
251+
pbs_envs.insert(key, val);
252+
236253
// volumes
237254
let mut pbs_volumes = vec![config_volume.clone()];
238255
pbs_volumes.extend(chain_spec_volume.clone());
@@ -245,16 +262,10 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
245262
Networks::default()
246263
};
247264

248-
exposed_ports_warn
249-
.push(format!("pbs has an exported port on {}", cb_config.pbs.pbs_config.port));
250-
251265
let pbs_service = Service {
252266
container_name: Some("cb_pbs".to_owned()),
253267
image: Some(cb_config.pbs.docker_image),
254-
ports: Ports::Short(vec![format!(
255-
"{}:{}",
256-
cb_config.pbs.pbs_config.port, cb_config.pbs.pbs_config.port
257-
)]),
268+
ports,
258269
networks: pbs_networs,
259270
volumes: pbs_volumes,
260271
environment: Environment::KvPair(pbs_envs),
@@ -408,7 +419,7 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
408419
image: Some("prom/prometheus:latest".to_owned()),
409420
volumes: vec![prom_volume, targets_volume, data_volume],
410421
// to inspect prometheus from localhost
411-
ports: Ports::Short(vec!["9090:9090".to_owned()]),
422+
ports: Ports::Short(vec![format!("{}:9090", metrics_config.host)]),
412423
networks: Networks::Simple(vec![METRICS_NETWORK.to_owned()]),
413424
..Service::default()
414425
};
@@ -435,7 +446,7 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
435446
let grafana_service = Service {
436447
container_name: Some("cb_grafana".to_owned()),
437448
image: Some("grafana/grafana:latest".to_owned()),
438-
ports: Ports::Short(vec!["3000:3000".to_owned()]),
449+
ports: Ports::Short(vec![format!("{}:3000", metrics_config.host)]),
439450
networks: Networks::Simple(vec![METRICS_NETWORK.to_owned()]),
440451
depends_on: DependsOnOptions::Simple(vec!["cb_prometheus".to_owned()]),
441452
environment: Environment::List(vec!["GF_SECURITY_ADMIN_PASSWORD=admin".to_owned()]),
@@ -475,7 +486,7 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
475486
Some(Service {
476487
container_name: Some("cb_cadvisor".to_owned()),
477488
image: Some("gcr.io/cadvisor/cadvisor".to_owned()),
478-
ports: Ports::Short(vec![format!("{cadvisor_port}:8080")]),
489+
ports: Ports::Short(vec![format!("{}:8080", metrics_config.host)]),
479490
networks: Networks::Simple(vec![METRICS_NETWORK.to_owned()]),
480491
volumes: vec![
481492
Volumes::Simple("/var/run/docker.sock:/var/run/docker.sock:ro".to_owned()),
@@ -540,17 +551,17 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
540551
Ok(())
541552
}
542553

543-
// FOO=${FOO}
554+
/// FOO=${FOO}
544555
fn get_env_same(k: &str) -> (String, Option<SingleValue>) {
545556
get_env_interp(k, k)
546557
}
547558

548-
// FOO=${BAR}
559+
/// FOO=${BAR}
549560
fn get_env_interp(k: &str, v: &str) -> (String, Option<SingleValue>) {
550561
get_env_val(k, &format!("${{{v}}}"))
551562
}
552563

553-
// FOO=bar
564+
/// FOO=bar
554565
fn get_env_val(k: &str, v: &str) -> (String, Option<SingleValue>) {
555566
(k.into(), Some(SingleValue::String(v.into())))
556567
}

crates/common/src/config/constants.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub const PBS_MODULE_NAME: &str = "pbs";
2222
/// Urls the pbs modules should post events to (comma separated)
2323
pub const BUILDER_URLS_ENV: &str = "CB_BUILDER_URLS";
2424

25+
/// Where to receive BuilderAPI calls from beacon node
26+
pub const PBS_ENDPOINT_ENV: &str = "CB_PBS_ENDPOINT";
27+
2528
///////////////////////// SIGNER /////////////////////////
2629

2730
pub const SIGNER_IMAGE_DEFAULT: &str = "ghcr.io/commit-boost/signer:latest";

crates/common/src/config/metrics.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
use std::net::Ipv4Addr;
2+
13
use eyre::Result;
24
use serde::{Deserialize, Serialize};
35

46
use super::{constants::METRICS_PORT_ENV, load_optional_env_var};
5-
use crate::utils::default_bool;
7+
use crate::utils::{default_bool, default_host};
68

79
#[derive(Debug, Serialize, Deserialize, Clone)]
810
pub struct MetricsConfig {
11+
/// Host for prometheus, grafana, and cadvisor
12+
#[serde(default = "default_host")]
13+
pub host: Ipv4Addr,
914
/// Path to prometheus config file
1015
pub prometheus_config: String,
1116
/// Whether to start the grafana service

crates/common/src/config/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl CommitBoostConfig {
4848
// When loading the config from the environment, it's important that every path
4949
// is replaced with the correct value if the config is loaded inside a container
5050
pub fn from_env_path() -> Result<Self> {
51-
let config = if let Ok(path) = std::env::var(CHAIN_SPEC_ENV) {
51+
let config = if let Some(path) = load_optional_env_var(CHAIN_SPEC_ENV) {
5252
// if the chain spec file is set, load it separately
5353
let chain: Chain = load_chain_from_file(path.parse()?)?;
5454
let rest_config: HelperConfig = load_file_from_env(CONFIG_ENV)?;

crates/common/src/config/pbs.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
//! Configuration for the PBS module
22
3-
use std::{collections::HashMap, sync::Arc};
3+
use std::{
4+
collections::HashMap,
5+
net::{Ipv4Addr, SocketAddr},
6+
sync::Arc,
7+
};
48

59
use alloy::primitives::{utils::format_ether, U256};
610
use eyre::{ensure, Result};
711
use serde::{de::DeserializeOwned, Deserialize, Serialize};
812
use url::Url;
913

10-
use super::{constants::PBS_IMAGE_DEFAULT, CommitBoostConfig};
14+
use super::{
15+
constants::PBS_IMAGE_DEFAULT, load_optional_env_var, CommitBoostConfig, PBS_ENDPOINT_ENV,
16+
};
1117
use crate::{
1218
commit::client::SignerClient,
1319
config::{load_env_var, load_file_from_env, CONFIG_ENV, MODULE_JWT_ENV, SIGNER_URL_ENV},
14-
pbs::{BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, LATE_IN_SLOT_TIME_MS},
20+
pbs::{
21+
BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, DEFAULT_PBS_PORT,
22+
LATE_IN_SLOT_TIME_MS,
23+
},
1524
types::Chain,
16-
utils::{as_eth_str, default_bool, default_u256, default_u64, WEI_PER_ETH},
25+
utils::{
26+
as_eth_str, default_bool, default_host, default_u16, default_u256, default_u64, WEI_PER_ETH,
27+
},
1728
};
1829

1930
#[derive(Debug, Clone, Deserialize, Serialize)]
@@ -36,7 +47,11 @@ pub struct RelayConfig {
3647

3748
#[derive(Debug, Clone, Deserialize, Serialize)]
3849
pub struct PbsConfig {
50+
/// Host to receive BuilderAPI calls from beacon node
51+
#[serde(default = "default_host")]
52+
pub host: Ipv4Addr,
3953
/// Port to receive BuilderAPI calls from beacon node
54+
#[serde(default = "default_u16::<DEFAULT_PBS_PORT>")]
4055
pub port: u16,
4156
/// Whether to forward `get_status` to relays or skip it
4257
#[serde(default = "default_bool::<true>")]
@@ -112,6 +127,8 @@ pub struct StaticPbsConfig {
112127
pub struct PbsModuleConfig {
113128
/// Chain spec
114129
pub chain: Chain,
130+
/// Endpoint to receive BuilderAPI calls from beacon node
131+
pub endpoint: SocketAddr,
115132
/// Pbs default config
116133
pub pbs_config: Arc<PbsConfig>,
117134
/// List of relays
@@ -130,12 +147,20 @@ fn default_pbs() -> String {
130147
pub fn load_pbs_config() -> Result<PbsModuleConfig> {
131148
let config = CommitBoostConfig::from_env_path()?;
132149

150+
// use endpoint from env if set, otherwise use default host and port
151+
let endpoint = if let Some(endpoint) = load_optional_env_var(PBS_ENDPOINT_ENV) {
152+
endpoint.parse()?
153+
} else {
154+
SocketAddr::from((config.pbs.pbs_config.host, config.pbs.pbs_config.port))
155+
};
156+
133157
let relay_clients =
134158
config.relays.into_iter().map(RelayClient::new).collect::<Result<Vec<_>>>()?;
135159
let maybe_publiher = BuilderEventPublisher::new_from_env()?;
136160

137161
Ok(PbsModuleConfig {
138162
chain: config.chain,
163+
endpoint,
139164
pbs_config: Arc::new(config.pbs.pbs_config),
140165
relays: relay_clients,
141166
signer_client: None,
@@ -164,6 +189,16 @@ pub fn load_pbs_custom_config<T: DeserializeOwned>() -> Result<(PbsModuleConfig,
164189
let cb_config: StubConfig<T> = load_file_from_env(CONFIG_ENV)?;
165190
cb_config.pbs.static_config.pbs_config.validate()?;
166191

192+
// use endpoint from env if set, otherwise use default host and port
193+
let endpoint = if let Some(endpoint) = load_optional_env_var(PBS_ENDPOINT_ENV) {
194+
endpoint.parse()?
195+
} else {
196+
SocketAddr::from((
197+
cb_config.pbs.static_config.pbs_config.host,
198+
cb_config.pbs.static_config.pbs_config.port,
199+
))
200+
};
201+
167202
let relay_clients =
168203
cb_config.relays.into_iter().map(RelayClient::new).collect::<Result<Vec<_>>>()?;
169204
let maybe_publiher = BuilderEventPublisher::new_from_env()?;
@@ -180,6 +215,7 @@ pub fn load_pbs_custom_config<T: DeserializeOwned>() -> Result<(PbsModuleConfig,
180215
Ok((
181216
PbsModuleConfig {
182217
chain: cb_config.chain,
218+
endpoint,
183219
pbs_config: Arc::new(cb_config.pbs.static_config.pbs_config),
184220
relays: relay_clients,
185221
signer_client,

crates/common/src/pbs/constants.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub const HEADER_START_TIME_UNIX_MS: &str = "X-MEVBoost-StartTimeUnixMS";
1717
pub const BUILDER_EVENTS_PATH: &str = "/builder_events";
1818
pub const DEFAULT_PBS_JWT_KEY: &str = "DEFAULT_PBS";
1919

20+
pub const DEFAULT_PBS_PORT: u16 = 18550;
21+
2022
#[non_exhaustive]
2123
pub struct DefaultTimeout;
2224
impl DefaultTimeout {

crates/common/src/utils.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::time::{SystemTime, UNIX_EPOCH};
1+
use std::{
2+
net::Ipv4Addr,
3+
time::{SystemTime, UNIX_EPOCH},
4+
};
25

36
use alloy::{
47
primitives::U256,
@@ -135,10 +138,18 @@ pub const fn default_u64<const U: u64>() -> u64 {
135138
U
136139
}
137140

141+
pub const fn default_u16<const U: u16>() -> u16 {
142+
U
143+
}
144+
138145
pub const fn default_bool<const U: bool>() -> bool {
139146
U
140147
}
141148

149+
pub const fn default_host() -> Ipv4Addr {
150+
Ipv4Addr::LOCALHOST
151+
}
152+
142153
pub const fn default_u256() -> U256 {
143154
U256::ZERO
144155
}

crates/pbs/src/service.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::net::SocketAddr;
2-
31
use cb_common::constants::COMMIT_BOOST_VERSION;
42
use cb_metrics::provider::MetricsProvider;
53
use eyre::{Context, Result};
@@ -18,7 +16,7 @@ pub struct PbsService;
1816

1917
impl PbsService {
2018
pub async fn run<S: BuilderApiState, A: BuilderApi<S>>(state: PbsState<S>) -> Result<()> {
21-
let address = SocketAddr::from(([0, 0, 0, 0], state.config.pbs_config.port));
19+
let address = state.config.endpoint;
2220
let events_subs =
2321
state.config.event_publisher.as_ref().map(|e| e.n_subscribers()).unwrap_or_default();
2422
info!(version = COMMIT_BOOST_VERSION, ?address, events_subs, chain =? state.config.chain, "starting PBS service");

tests/tests/pbs_integration.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
use std::{sync::Arc, time::Duration, u64};
1+
use std::{
2+
net::{Ipv4Addr, SocketAddr},
3+
sync::Arc,
4+
time::Duration,
5+
u64,
6+
};
27

38
use alloy::primitives::U256;
49
use cb_common::{
@@ -19,6 +24,7 @@ use tracing::info;
1924

2025
fn get_pbs_static_config(port: u16) -> PbsConfig {
2126
PbsConfig {
27+
host: Ipv4Addr::UNSPECIFIED,
2228
port,
2329
wait_all_registrations: true,
2430
relay_check: true,
@@ -35,6 +41,7 @@ fn get_pbs_static_config(port: u16) -> PbsConfig {
3541
fn to_pbs_config(chain: Chain, pbs_config: PbsConfig, relays: Vec<RelayClient>) -> PbsModuleConfig {
3642
PbsModuleConfig {
3743
chain,
44+
endpoint: SocketAddr::new(pbs_config.host.into(), pbs_config.port),
3845
pbs_config: Arc::new(pbs_config),
3946
signer_client: None,
4047
event_publisher: None,

0 commit comments

Comments
 (0)