Skip to content

Commit 91137e9

Browse files
ltitanbfbrv
andcommitted
Update config and docs (Commit-Boost#54)
* update docs * add comments in example config * add max level logs + fixes --------- Co-authored-by: fbrv <[email protected]>
1 parent 7649c89 commit 91137e9

File tree

10 files changed

+260
-194
lines changed

10 files changed

+260
-194
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ Cargo.lock
1717
*.docker-compose.yml
1818
targets.json
1919
.idea/
20+
logs

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ serde_yaml = "0.9.33"
5353

5454
# telemetry
5555
tracing = "0.1.40"
56-
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
56+
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] }
5757
tracing-appender = "0.2.3"
5858
prometheus = "0.13.4"
5959

config.example.toml

Lines changed: 112 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,145 @@
1+
# The main configuration file for the Commit-Boost sidecar.
2+
# Some fields are optional and can be omitted, in which case the default value, if present, will be used.
3+
4+
# Chain spec id. Supported values: Mainnet, Holesky, Helder
15
chain = "Holesky"
26

7+
# Configuration for the PBS module
38
[pbs]
9+
# Docker image to use for the PBS module. This currently defaults to the image built in `scripts/build_local_images.sh` and will be
10+
# replaced by the official Commit-Boost PBS module once published in a public registry
11+
# OPTIONAL, DEFAULT: commitboost_pbs_default
12+
docker_image = "commitboost_pbs_default"
13+
# Whether to enable the PBS module to request signatures from the Signer module (not used in the default PBS image)
14+
# OPTIONAL, DEFAULT: false
15+
with_signer = false
16+
# Port to receive BuilderAPI calls from beacon node
417
port = 18550
18+
# Whether to forward `status` calls to relays or skip and return 200
19+
# OPTIONAL, DEFAULT: true
520
relay_check = true
21+
# Timeout in milliseconds for the `get_header` call to relays. Note that the CL has also a timeout (e.g. 1 second) so
22+
# this should be lower than that, leaving some margin for overhead
23+
# OPTIONAL, DEFAULT: 950
624
timeout_get_header_ms = 950
25+
# Timeout in milliseconds for the `submit_blinded_block` call to relays.
26+
# OPTIONAL, DEFAULT: 4000
727
timeout_get_payload_ms = 4000
28+
# Timeout in milliseconds for the `register_validator` call to relays.
29+
# OPTIONAL, DEFAULT: 3000
830
timeout_register_validator_ms = 3000
9-
skip_sigverify = true
31+
# Whether to skip signature verification of headers against the relay pubkey
32+
# OPTIONAL, DEFAULT: false
33+
skip_sigverify = false
34+
# Minimum bid in ETH that will be accepted from `get_header`
35+
# OPTIONAL, DEFAULT: 0.0
1036
min_bid_eth = 0.0
11-
37+
# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to
38+
# relays and make sure a header is returned within this deadline. If the request from the CL comes later in the slot, then fetching headers is skipped
39+
# to force local building and miniminzing the risk of missed slots. See also the timing games section below
40+
# OPTIONAL, DEFAULT: 2000
1241
late_in_slot_time_ms = 2000
1342

43+
# The PBS module needs one or more [[relays]] as defined below.
1444
[[relays]]
45+
# Relay ID to use in telemetry
46+
# OPTIONAL, DEFAULT: URL hostname
1547
id = "example-relay"
48+
# Relay URL in the format scheme://pubkey@host
1649
url = "http://0xa1cec75a3f0661e99299274182938151e8433c61a19222347ea1313d839229cb4ce4e3e5aa2bdeb71c8fcf1b084963c2@abc.xyz"
50+
# Headers to send with each request for this relay
51+
# OPTIONAL
1752
headers = { X-MyCustomHeader = "MyCustomValue" }
53+
# Whether to enable timing games, as tuned by `target_first_request_ms` and `frequency_get_header_ms`.
54+
# These values should be carefully chosen for each relay, as each relay has different latency and timing games setups.
55+
# They should only be used by advanced users, and if mis-configured can result in unforeseen effects, e.g. fetching a lower header value,
56+
# or getting a temporary IP ban.
57+
#
58+
# EXAMPLES
59+
# Assuming: timeout_get_header_ms = 950, frequency_get_header_ms = 300, target_first_request_ms = 200, late_in_slot_time_ms = 2000
60+
#
61+
# 1) CL request comes at 100ms in the slot (max timeout 1050ms in the slot), then:
62+
# - sleep for 100ms
63+
# - send request at 200ms with 850ms timeout
64+
# - send request at 500ms with 550ms timeout
65+
# - send request at 800ms with 250ms timeout
66+
# 2) CL request comes at 1500ms in the slot (max timeout 2000ms in the slot), then:
67+
# - send request at 1500ms with 500ms timeout
68+
# - send request at 1800ms with 200ms timeout
69+
# 3) CL request comes 2500ms in the slot then:
70+
# - return 204 and force local build
71+
#
72+
# OPTIONAL, DEFAULT: false
1873
enable_timing_games = false
74+
# Target time in slot when to send the first header request
75+
# OPTIONAL
1976
target_first_request_ms = 200
77+
# Frequency in ms to send get_header requests
78+
# OPTIONAL
2079
frequency_get_header_ms = 300
2180

81+
# Configuration for the Signer Module, only required if any `commit` module is present, or if `pbs.with_signer = true`
82+
# OPTIONAL
2283
[signer]
84+
# Docker image to use for the Signer module. This currently defaults to the image built in `scripts/build_local_images.sh` and will be
85+
# replaced by the official Commit-Boost Signer module once published in a public registry
86+
# OPTIONAL, DEFAULT: commitboost_signer
87+
docker_image = "commitboost_signer"
88+
# Configuration for how the Signer module should load validator keys. Currently two types of loaders are supported:
89+
# - File: load keys from a plain text file (unsafe, use only for testing purposes)
90+
# - ValidatorsDir: load keys from a `keys` and `secrets` folder (ERC-2335 style keystores as used in Lighthouse)
2391
[signer.loader]
92+
# File: path to the keys file
2493
key_path = "./keys.example.json"
94+
# ValidatorsDir: path to the keys directory
2595
# keys_path = ""
96+
# ValidatorsDir: path to the secrets directory
2697
# secrets_path = ""
2798

28-
[metrics]
29-
prometheus_config = "./docker/prometheus.yml"
30-
use_grafana = true
31-
99+
# Commit-Boost can optionally run "modules" which extend the capabilities of the sidecar.
100+
# Currently, two types of modules are supported:
101+
# - "commit": modules which request commitment signatures from the validator keys
102+
# - "events": modules which callback to BuilderAPI events as triggered from the PBS modules, used e.g. for monitoring
103+
# If any "commit" module is present, then the [signer] section should also be configured
104+
# OPTIONAL
32105
[[modules]]
106+
# Unique ID of the module
33107
id = "DA_COMMIT"
108+
# Type of the module. Supported values: commit, events
34109
type = "commit"
110+
# Docker image of the module
35111
docker_image = "test_da_commit"
112+
# Additional config needed by the business logic of the module should also be set here.
113+
# See also `examples/da_commit/src/main.rs` for more information
36114
sleep_secs = 5
37115

38-
[[modules]]
39-
id = "BUILDER_LOG"
40-
type = "events"
41-
docker_image = "test_builder_log"
116+
# Configuration for how metrics should be collected and scraped
117+
[metrics]
118+
# Path to a `prometheus.yml` file to use in Prometheus. If using a custom config file, be sure to add a
119+
# file discovery section as follows:
120+
# ```yml
121+
# file_sd_configs:
122+
# - files:
123+
# - /etc/prometheus/targets.json
124+
# ```
125+
# and use the `targets.json` file generated by `commit-boost init`
126+
prometheus_config = "./docker/prometheus.yml"
127+
# Whether to start Grafana with built-in dashboards
128+
# OPTIONAL, DEFAULT: true
129+
use_grafana = true
42130

131+
# Configuration for how logs should be collected and stored
132+
# OPTIONAL
43133
[logs]
44-
duration = "daily"
45-
host-path="./logs"
46-
rust-log="info"
134+
# Log rotation policy. Supported values: hourly, daily, never
135+
# OPTIONAL, DEFAULT: daily
136+
rotation = "daily"
137+
# Path to the log directory
138+
# OPTIONAL, DEFAULT: /var/logs/commit-boost
139+
log_dir_path = "./logs"
140+
# Log level. Supported values: trace, debug, info, warn, error
141+
# OPTIONAL, DEFAULT: debug to file, info to stdout
142+
log_level = "debug"
143+
# Maximum number of log files to keep
144+
# OPTIONAL
145+
max_log_files = 30

crates/cli/src/docker_init.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use cb_common::{
88
SIGNER_KEYS, SIGNER_KEYS_ENV, SIGNER_SERVER_ENV,
99
},
1010
loader::SignerLoader,
11-
utils::{random_jwt, ENV_ROLLING_DURATION},
11+
utils::{random_jwt, MAX_LOG_FILES_ENV, ROLLING_DURATION_ENV, RUST_LOG_ENV},
1212
};
1313
use docker_compose_types::{
1414
Compose, ComposeVolume, DependsOnOptions, Environment, Labels, LoggingParameters, MapOrEmpty,
@@ -27,8 +27,6 @@ pub(super) const PROMETHEUS_DATA_VOLUME: &str = "prometheus-data";
2727
const METRICS_NETWORK: &str = "monitoring_network";
2828
const SIGNER_NETWORK: &str = "signer_network";
2929

30-
const ENV_RUST_LOG: &str = "RUST_LOG";
31-
3230
/// Builds the docker compose file for the Commit-Boost services
3331
3432
// TODO: do more validation for paths, images, etc
@@ -45,15 +43,14 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
4543
let config_volume = Volumes::Simple(format!("./{}:{}:ro", config_path, CB_CONFIG_NAME));
4644
let log_volume = Volumes::Simple(format!(
4745
"{}:{}",
48-
cb_config.logs.host_path.to_str().unwrap(),
46+
cb_config.logs.log_dir_path.to_str().unwrap(),
4947
CB_BASE_LOG_PATH
5048
));
5149

5250
let mut jwts = IndexMap::new();
5351
// envs to write in .env file
5452
let mut envs = IndexMap::from([(CB_CONFIG_ENV.into(), CB_CONFIG_NAME.into())]);
55-
envs.insert(ENV_ROLLING_DURATION.into(), cb_config.logs.duration.to_string());
56-
envs.insert(ENV_RUST_LOG.into(), cb_config.logs.rust_log);
53+
5754
// targets to pass to prometheus
5855
let mut targets = Vec::new();
5956
let metrics_port = 10000;
@@ -73,8 +70,14 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
7370

7471
let mut pbs_envs = IndexMap::from([
7572
get_env_same(CB_CONFIG_ENV),
76-
get_env_val(METRICS_SERVER_ENV, &metrics_port.to_string()),
73+
get_env_uval(METRICS_SERVER_ENV, metrics_port as u64),
74+
get_env_val(ROLLING_DURATION_ENV, &cb_config.logs.rotation.to_string()),
75+
get_env_val(RUST_LOG_ENV, &cb_config.logs.log_level),
7776
]);
77+
if let Some(max_files) = cb_config.logs.max_log_files {
78+
let (key, val) = get_env_uval(MAX_LOG_FILES_ENV, max_files as u64);
79+
pbs_envs.insert(key, val);
80+
}
7881

7982
let mut needs_signer_module = cb_config.pbs.with_signer;
8083

@@ -98,13 +101,19 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
98101
let jwt_name = format!("CB_JWT_{}", module.id.to_uppercase());
99102

100103
// module ids are assumed unique, so envs dont override each other
101-
let module_envs = IndexMap::from([
104+
let mut module_envs = IndexMap::from([
102105
get_env_val(MODULE_ID_ENV, &module.id),
103106
get_env_same(CB_CONFIG_ENV),
104107
get_env_interp(MODULE_JWT_ENV, &jwt_name),
105-
get_env_val(METRICS_SERVER_ENV, &metrics_port.to_string()),
108+
get_env_uval(METRICS_SERVER_ENV, metrics_port as u64),
106109
get_env_val(SIGNER_SERVER_ENV, &signer_server),
110+
get_env_val(ROLLING_DURATION_ENV, &cb_config.logs.rotation.to_string()),
111+
get_env_val(RUST_LOG_ENV, &cb_config.logs.log_level),
107112
]);
113+
if let Some(max_files) = cb_config.logs.max_log_files {
114+
let (key, val) = get_env_uval(MAX_LOG_FILES_ENV, max_files as u64);
115+
module_envs.insert(key, val);
116+
}
108117

109118
envs.insert(jwt_name.clone(), jwt.clone());
110119
jwts.insert(module.id.clone(), jwt);
@@ -126,12 +135,18 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
126135
// an event module just needs a port to listen on
127136
ModuleKind::Events => {
128137
// module ids are assumed unique, so envs dont override each other
129-
let module_envs = IndexMap::from([
138+
let mut module_envs = IndexMap::from([
130139
get_env_val(MODULE_ID_ENV, &module.id),
131140
get_env_same(CB_CONFIG_ENV),
132-
get_env_val(METRICS_SERVER_ENV, &metrics_port.to_string()),
141+
get_env_uval(METRICS_SERVER_ENV, metrics_port as u64),
133142
get_env_val(BUILDER_SERVER_ENV, &builder_events_port.to_string()),
143+
get_env_val(ROLLING_DURATION_ENV, &cb_config.logs.rotation.to_string()),
144+
get_env_val(RUST_LOG_ENV, &cb_config.logs.log_level),
134145
]);
146+
if let Some(max_files) = cb_config.logs.max_log_files {
147+
let (key, val) = get_env_uval(MAX_LOG_FILES_ENV, max_files as u64);
148+
module_envs.insert(key, val);
149+
}
135150

136151
builder_events_modules.push(format!("{module_cid}:{builder_events_port}"));
137152

@@ -188,9 +203,15 @@ pub fn handle_docker_init(config_path: String, output_dir: String) -> Result<()>
188203
let mut signer_envs = IndexMap::from([
189204
get_env_same(CB_CONFIG_ENV),
190205
get_env_same(JWTS_ENV),
191-
get_env_val(METRICS_SERVER_ENV, &metrics_port.to_string()),
192-
get_env_val(SIGNER_SERVER_ENV, &signer_port.to_string()),
206+
get_env_uval(METRICS_SERVER_ENV, metrics_port as u64),
207+
get_env_uval(SIGNER_SERVER_ENV, signer_port as u64),
208+
get_env_val(ROLLING_DURATION_ENV, &cb_config.logs.rotation.to_string()),
209+
get_env_val(RUST_LOG_ENV, &cb_config.logs.log_level),
193210
]);
211+
if let Some(max_files) = cb_config.logs.max_log_files {
212+
let (key, val) = get_env_uval(MAX_LOG_FILES_ENV, max_files as u64);
213+
signer_envs.insert(key, val);
214+
}
194215

195216
// TODO: generalize this, different loaders may not need volumes but eg ports
196217
match signer_config.loader {
@@ -362,6 +383,10 @@ fn get_env_val(k: &str, v: &str) -> (String, Option<SingleValue>) {
362383
(k.into(), Some(SingleValue::String(v.into())))
363384
}
364385

386+
fn get_env_uval(k: &str, v: u64) -> (String, Option<SingleValue>) {
387+
(k.into(), Some(SingleValue::Unsigned(v)))
388+
}
389+
365390
/// A prometheus target, use to dynamically add targets to the prometheus config
366391
#[derive(Debug, Serialize)]
367392
struct PrometheusTargetConfig {

0 commit comments

Comments
 (0)