Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
12670f6
feat(pbs): ePBS builder API + strict Eth-Consensus-Version enforcement
JasonVranek Aug 11, 2026
a07bcac
fix(pbs): order BuilderPreferencesRequest SSZ fields as (preferences,…
JasonVranek Aug 18, 2026
27f8dea
fix(pbs): reject empty auth.message.data with 400
JasonVranek Aug 18, 2026
9dfa5a4
chore(deps): bump lighthouse v8.1.3 -> v8.2.2 for spec-correct gloas
JasonVranek Aug 19, 2026
4a80e20
fix cargo audit
JasonVranek Aug 19, 2026
fff2bb4
test(pbs): pin auth_data demux contract vectors for external projectors
JasonVranek Aug 21, 2026
ada0b9c
feat(pbs): drop ePBS min_bid/payment-cap rejects, keep the cap as a r…
JasonVranek Aug 21, 2026
906009e
feat(km-tool): new cb-km-tool crate with KM wire types and overlay co…
JasonVranek Aug 21, 2026
b427ef0
feat(common): advertised_urls + projection-only mux fields + warn-on-…
JasonVranek Aug 21, 2026
3adeb9b
feat(km-tool): projection library
JasonVranek Aug 21, 2026
5f30622
feat(km-tool): KM client, apply/check flows, cb-km CLI
JasonVranek Aug 21, 2026
831c9c3
test(pbs): carry new MuxConfig fields through mux test literals
JasonVranek Aug 21, 2026
cac2fa9
test(km-tool): mock-KM integration suite
JasonVranek Aug 21, 2026
d419bbc
feat(pbs): transient pipe relay resolver with fail-closed self-URL guard
JasonVranek Aug 21, 2026
e6ec516
feat(pbs): pipe unmatched ePBS bid requests to the auth_data builder URL
JasonVranek Aug 21, 2026
13bd8b3
feat(pbs): pipe unmatched builder preferences to the auth_data builde…
JasonVranek Aug 21, 2026
a49d7dd
docs: document how advertised_urls gates the ePBS pipe
JasonVranek Aug 21, 2026
783b69a
fix(km-tool): fail projection when byte-distinct auth_data classes ar…
JasonVranek Aug 21, 2026
aa7b025
fix(km-tool): check errors on missing builder_config route for enumer…
JasonVranek Aug 21, 2026
244fa35
fix(km-tool): downgrade unroutable-auth-data to WARN
JasonVranek Aug 21, 2026
d997e6b
fix: dedupe unknown-mux-field warnings and skip None KM fields in TOM…
JasonVranek Aug 21, 2026
3553527
fix(km-tool): apply preflight separates probe failure from missing #8…
JasonVranek Aug 21, 2026
df996a3
fix(km-tool): preserve base URL path prefix when building endpoints
JasonVranek Aug 21, 2026
54f5d56
fix(km-tool): warn on group-readable token files too
JasonVranek Aug 21, 2026
b9df5c8
docs(km-tool): warn in --help that check-green does not make apply a …
JasonVranek Aug 21, 2026
7a30371
style(km-tool): rustfmt with the pinned toolchain
JasonVranek Aug 21, 2026
f6f4e4d
Merge branch 'feat/km-builder-config-tool' into feat/km-builder-config
JasonVranek Aug 21, 2026
0ccd34f
feat(km-tool): read projection fields from MuxConfig post-merge
JasonVranek Aug 21, 2026
d6c6801
feat(pbs): configurable bid signing-domain params
JasonVranek Aug 21, 2026
b7c3fbc
feat(km-tool): key-level p2p projection fields
JasonVranek Aug 21, 2026
ade56d4
chore(deps): bump lighthouse to unstable for progressive gloas SSZ
JasonVranek Aug 21, 2026
5e5123e
test(common): pin gloas ExecutionPayloadBid progressive tree-hash root
JasonVranek Aug 21, 2026
42e724b
feat(common): per-mux p2p projection override fields
JasonVranek Aug 21, 2026
491fbf0
feat(km-tool): per-mux p2p override in key-level projection
JasonVranek Aug 21, 2026
f94bd87
perf(pbs): reuse a process-lifetime pipe-relay placeholder pubkey
JasonVranek Aug 21, 2026
b08dce9
feat(km-tool): apply --preserve-entries merges third-party builder en…
JasonVranek Aug 21, 2026
d559ae4
docs(config): per-mux p2p overrides + advertised_urls form guidance
JasonVranek Aug 21, 2026
29bd848
test(km-tool): cover apply --preserve-entries merge
JasonVranek Aug 21, 2026
f6d4bcc
test(km-tool): assert per-mux min_bid_p2p and boost_p2p are independent
JasonVranek Aug 21, 2026
135a42a
docs(km-tool): clarify --preserve-entries semantics and concurrency c…
JasonVranek Aug 21, 2026
755a218
Merge branch 'feat/km-preserve-entries' into epbs
JasonVranek Aug 21, 2026
33eda8f
test(pbs): carry the per-mux p2p fields through the remaining mux tes…
JasonVranek Aug 21, 2026
ed884b0
sec(deps): pin blstrs_plus git patch to an explicit rev
JasonVranek Aug 21, 2026
f623f15
sec(km-tool): stop the KM client from following redirects
JasonVranek Aug 21, 2026
a0f3d48
sec(km-tool): restrict emit perms and redact secret auth_data in dry-run
JasonVranek Aug 21, 2026
f5c3373
refactor(km-tool): drop vestigial mux projection seams
JasonVranek Aug 21, 2026
cba0853
docs(km-tool): trim triplicated preserve_entries field doc
JasonVranek Aug 21, 2026
1017b54
docs(pbs): reattach transient_pipe_relay doc and dedup skip-sigverify…
JasonVranek Aug 21, 2026
71e46de
docs(common): use plain hyphens and cite ticket id in pbs config docs
JasonVranek Aug 21, 2026
2e1338d
docs(pbs): fix mislabeled metric in relay-invalid-response test doc
JasonVranek Aug 21, 2026
ce8176c
refactor(pbs): make the ePBS bid path a blind pipe
JasonVranek Aug 24, 2026
54d29c6
refactor(pbs): rename request-auth symbols to builder-request-auth
JasonVranek Aug 24, 2026
3b02575
docs(pbs): strip restate comments and dedup rationale in the ePBS sur…
JasonVranek Aug 24, 2026
ffe0587
refactor(pbs): extract shared ePBS route helpers and decompose long fns
JasonVranek Aug 24, 2026
1c83ebb
fix(pbs): correct gwei/eth units in ePBS metrics and logs
JasonVranek Aug 24, 2026
cd1d15c
fix(pbs): logging levels and metric coverage on ePBS paths
JasonVranek Aug 24, 2026
17805ab
fix(pbs): ePBS hardening across the bid, block and km-tool paths
JasonVranek Aug 24, 2026
7798fec
fix(km-tool): stop populating builder_config builder_pubkeys
JasonVranek Aug 24, 2026
97de482
fix(pbs): blind-pipe builder preferences, drop the slot_has_passed gate
JasonVranek Aug 25, 2026
33ea7d7
fix(km-tool): drop the lax-URL-ambiguity projection gate
JasonVranek Aug 25, 2026
3a83b07
fix(pbs): drop the fee_recipient equality check from the ePBS bid path
JasonVranek Aug 25, 2026
fea1e49
fix(pbs): make /beacon_blocks a blind pipe, decode only under strict …
JasonVranek Aug 25, 2026
ade046f
fix(pbs): derive the ePBS bid timeout from the proposer deadline + a …
JasonVranek Aug 25, 2026
376506e
Merge branch 'fix/pbs-drop-fee-recipient-gloas' into integration/epbs…
JasonVranek Aug 25, 2026
db3dda0
Merge branch 'fix/pbs-beacon-blocks-strict-opt-in' into integration/e…
JasonVranek Aug 25, 2026
e1f0cad
Merge branch 'fix/pbs-bid-timeout' into integration/epbs-bottleneck-f…
JasonVranek Aug 25, 2026
bfb6055
fix(pbs): make the fail-closed ePBS transient pipe loud, not silent
JasonVranek Aug 26, 2026
dddfab2
fix(pbs): restore Address import in the bid-path test module
JasonVranek Aug 26, 2026
5fa66d4
test(pbs): add the new PbsConfig fields to test-only literals
JasonVranek Aug 26, 2026
701953b
fix(pbs): return 204 on an expired proposer deadline; align fee_recip…
JasonVranek Aug 26, 2026
74fb476
test(pbs): align beacon-block and preferences tests with the new defa…
JasonVranek Aug 26, 2026
ab8b190
chore(fmt): rustfmt under the pinned nightly-2026-01-01
JasonVranek Aug 26, 2026
c442b36
Merge remote-tracking branch 'origin/main' into epbs
JasonVranek Aug 27, 2026
3a4ddb5
refactor(pbs): harden ePBS config surface and drop the unused fee_rec…
JasonVranek Sep 1, 2026
9c669e3
feat(pbs): reject a non-SSZ block reveal with 415 in the blind pipe
JasonVranek Sep 1, 2026
c92e0d8
refactor(pbs): accept Gloas only in the consensus-version header
JasonVranek Sep 1, 2026
7711068
chore(pbs): drop redundant comments and the dead content_type_encodin…
JasonVranek Sep 1, 2026
f4711c0
feat(pbs): harden the ePBS transient pipe (SSRF deny-list, sentinel r…
JasonVranek Sep 2, 2026
7dbd60e
feat(pbs): clamp the ePBS bid X-Timeout-Ms budget to one slot
JasonVranek Sep 2, 2026
327a7b9
feat(km-tool): error when an advertised_url is not covered by [pbs] a…
JasonVranek Sep 2, 2026
0940558
style(pbs): rustfmt reflow of a block-submission test doc comment
JasonVranek Sep 2, 2026
6d4d88f
refactor(pbs): share the ePBS handler failure arm and detached fan-out
JasonVranek Sep 8, 2026
ae9817d
refactor(pbs): parse the bid Accept once and forward it as a static h…
JasonVranek Sep 8, 2026
7f41677
refactor(pbs): carry the builder's status in BuilderRejected
JasonVranek Sep 8, 2026
9303c64
refactor(common): one startup warning for the disabled transient pipe
JasonVranek Sep 8, 2026
6a0b37d
test(pbs): boot the ePBS suites through spawn_mock_relay and setup_pbs
JasonVranek Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
693 changes: 394 additions & 299 deletions Cargo.lock

Large diffs are not rendered by default.

22 changes: 15 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ alloy = { version = "^1.0.35", features = [
"rpc-types-beacon",
"serde",
"signer-local",
"ssz",
] }
alloy-primitives = "^1.3.1"
assert_cmd = "2.1.2"
Expand All @@ -42,6 +41,7 @@ const_format = "0.2.34"
ctr = "0.9.2"
derive_more = { version = "2.0.1", features = ["deref", "display", "from", "into"] }
docker-compose-types = "0.16.0"
arbitrary = "1.4"
docker-image = "0.2.1"
ethereum_serde_utils = "0.7.0"
ethereum_ssz = "0.10"
Expand All @@ -54,10 +54,10 @@ indexmap = "2.2.6"
jsonwebtoken = { version = "9.3.1", default-features = false }
lazy_static = "1.5.0"
mediatype = "0.20.0"
lh_eth2 = { package = "eth2", git = "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/sigp/lighthouse", tag = "v8.1.3", features = ["events"] }
lh_eth2_keystore = { package = "eth2_keystore", git = "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/sigp/lighthouse", tag = "v8.1.3" }
lh_bls = { package = "bls", git = "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/sigp/lighthouse", tag = "v8.1.3" }
lh_types = { package = "types", git = "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/sigp/lighthouse", tag = "v8.1.3" }
lh_eth2 = { package = "eth2", git = "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/sigp/lighthouse", rev = "31d8cfd40d228c2dd902a67b5142ff6abf00c058", features = ["events"] }
lh_eth2_keystore = { package = "eth2_keystore", git = "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/sigp/lighthouse", rev = "31d8cfd40d228c2dd902a67b5142ff6abf00c058" }
lh_bls = { package = "bls", git = "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/sigp/lighthouse", rev = "31d8cfd40d228c2dd902a67b5142ff6abf00c058", features = ["arbitrary"] }
lh_types = { package = "types", git = "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/sigp/lighthouse", rev = "31d8cfd40d228c2dd902a67b5142ff6abf00c058", features = ["arbitrary"] }
notify = "8.2.0"
parking_lot = "0.12.3"
pbkdf2 = "0.12.2"
Expand All @@ -74,7 +74,7 @@ serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0.117"
serde_yaml = "0.9.33"
sha2 = "0.10.8"
ssz_types = "0.11"
ssz_types = "0.14.1"
subtle = "2.5"
tempfile = "3.20.0"
thiserror = "2.0.12"
Expand All @@ -97,4 +97,12 @@ uuid = { version = "1.8.0", features = ["fast-rng", "serde", "v4"] }
webpki-roots = "1.0"

[patch.crates-io]
blstrs_plus = { git = "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/Commit-Boost/blstrs" }
blstrs_plus = { git = "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/Commit-Boost/blstrs", rev = "c4ea6b21193886ee9849867397a62e9c243c1fbb" }
# Progressive-container ssz stack required by lighthouse-unstable (EIP-7495/7916).
# A consumer does NOT inherit a dependency's [patch]; mirror lighthouse's here.
ssz_types = { git = "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/sigp/ssz_types", rev = "9203d56ad2d7bc5f12133d043e085843f81edcd6" }
milhouse = { git = "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/sigp/milhouse", rev = "c70f128976ac0d60ea65a978dabd117a921c36ee" }
ethereum_ssz = { git = "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/sigp/ethereum_ssz", rev = "2059c21ba52cd3a7e39a8ad537012b761812a393" }
ethereum_ssz_derive = { git = "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/sigp/ethereum_ssz", rev = "2059c21ba52cd3a7e39a8ad537012b761812a393" }
tree_hash = { git = "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/sigp/tree_hash", rev = "03d9fa474586c125f306dd7a00cf46284575a01f" }
tree_hash_derive = { git = "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/sigp/tree_hash", rev = "03d9fa474586c125f306dd7a00cf46284575a01f" }
3 changes: 3 additions & 0 deletions benches/pbs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ fn get_mock_validator(bench: BenchConfig) -> RelayClient {
enable_timing_games: false,
target_first_request_ms: None,
frequency_get_header_ms: None,
bid_poll_timeout_ms: None,
validator_registration_batch_size: None,
max_execution_payment_gwei: None,
expected_auth_data: None,
};

RelayClient::new(config).unwrap()
Expand Down
79 changes: 78 additions & 1 deletion config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,17 @@ relay_check = true
# OPTIONAL, DEFAULT: true
wait_all_registrations = true
# Timeout in milliseconds for the `get_header` call to relays. Note that the CL has also a timeout (e.g. 1 second) so
# this should be lower than that, leaving some margin for overhead
# this should be lower than that, leaving some margin for overhead.
# LEGACY get_header path only: the ePBS bid path derives its timeout from the beacon node's own
# X-Timeout-Ms header instead (see proposer_deadline_buffer_ms below).
# OPTIONAL, DEFAULT: 950
timeout_get_header_ms = 950
# ePBS bid path only. The beacon node sends CB its own deadline (X-Timeout-Ms) on every bid request,
# so CB no longer needs a static timeout: it asks the builder for `deadline - proposer_deadline_buffer_ms`,
# reserving this many ms for the winning bid's return trip to the beacon node and the node's own
# bid-selection/assembly. Configure the margin directly instead of a deadline-minus-margin absolute.
# OPTIONAL, DEFAULT: 50
proposer_deadline_buffer_ms = 50
# Timeout in milliseconds for the `submit_blinded_block` call to relays.
# OPTIONAL, DEFAULT: 4000
timeout_get_payload_ms = 4000
Expand All @@ -44,6 +52,34 @@ skip_sigverify = false
# Can be specified as a float or a string for extra precision (e.g. "0.01")
# OPTIONAL, DEFAULT: 0.0
min_bid_eth = 0.0
# Projection-only: consumed by KM tooling, not read by the PBS runtime.
# The ePBS KEY-LEVEL minimum total payment in ETH: it governs p2p bids and builder entries that
# omit their own min_bid (projected entries always carry explicit per-entry values sourced from
# the mux/global min_bid). Float or string
# OPTIONAL, DEFAULT: unset (key level = mux/global min_bid)
# min_bid_p2p_eth = "0.2"
# Projection-only: consumed by KM tooling, not read by the PBS runtime.
# The ePBS KEY-LEVEL builder_boost_factor: it governs p2p bids and builder entries that omit
# their own (entry values stay mux-sourced)
# OPTIONAL, DEFAULT: unset
# builder_boost_factor_p2p = 100
# Execution-payment cap in Gwei used when ranking ePBS bids: a bid ranks at
# `value + min(execution_payment, cap)`, matching how the beacon node values it (the BN clamps the
# trusted payment at the cap instead of rejecting the bid). This does not accept or reject bids.
# Can be overridden per relay with `max_execution_payment_gwei` on the relay entry
# OPTIONAL, DEFAULT: unset (unclamped)
# max_execution_payment_gwei = 1000000000
# Whether to verify the BLS signature of the `SignedBuilderRequestAuth` on an ePBS request against the
# proposer pubkey in the request path, rejecting a bad signature with 401. CB forwards by default
# because the downstream builder must re-verify anyway; operators terminating trust at CB set it true
# OPTIONAL, DEFAULT: false
verify_builder_request_auth = false
# Strict decoding of the reveal at POST /eth/v1/builder/beacon_blocks. Default (false): CB is a blind
# pipe, forwarding the reveal bytes to the builder without parsing them, so the reveal MUST be SSZ in
# blind mode (the builder validates and rejects a bad block per builder-specs). When true: CB decodes
# the gloas SignedBeaconBlock itself and rejects a non-gloas or otherwise undecodable body with a 400
# OPTIONAL, DEFAULT: false
# strict_block_decode = false
# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to
# 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
# to force local building and miniminzing the risk of missed slots. See also the timing games section below
Expand Down Expand Up @@ -78,6 +114,18 @@ validator_registration_batch_size = ""
# enabled, this value will not be used.
# OPTIONAL, DEFAULT: 384
mux_registry_refresh_interval_seconds = 384
# Commit-Boost's externally-reachable URLs, i.e. the ones a validator client's builder config points
# at. Gates the ePBS pipe: when a request's auth data names a builder URL no configured relay serves,
# CB dials that URL directly through a transient client (trust is the validator client's job via its
# keymanager builder_pubkeys). Since an unconfigured key's auth data defaults to CB's own URL, the
# pipe first checks the decoded URL against this list and rejects a match instead of dialing itself.
# The guard fails closed: while this list is empty, unmatched auth data is always rejected and the
# pipe never dials, so set it to enable piping to builders outside the [[relays]] below.
# List EVERY scheme/host/IP form CB is reachable by: the self-URL guard matches on scheme+host+port
# exactly, so an equivalent form you omit (e.g. an IP instead of a hostname, or http vs https) is not
# recognized as CB's own and the pipe could self-dial.
# OPTIONAL, DEFAULT: []
# advertised_urls = ["http://cb.example.com:18550"]

# The PBS module needs one or more [[relays]] as defined below.
[[relays]]
Expand Down Expand Up @@ -130,6 +178,21 @@ target_first_request_ms = 200
# Frequency in ms to send get_header requests
# OPTIONAL
frequency_get_header_ms = 300
# How long each ePBS bid poll may take, in ms. Every poll shares the proposer's deadline, so bounding
# the early ones lands a floor of progressively better bids instead of leaving everything to the last
# instant; the final poll always holds for the remaining budget. Set this above your round trip to
# the builder, or every early poll times out
# OPTIONAL, DEFAULT: 500
# bid_poll_timeout_ms = 500
# Per-relay override of the ePBS bid-ranking execution-payment cap in Gwei (see the PBS-level
# `max_execution_payment_gwei`)
# OPTIONAL, DEFAULT: the PBS-level `max_execution_payment_gwei` (unset = unclamped)
# max_execution_payment_gwei = 1000000000
# The ePBS auth data this relay serves: a bid request routes here only when its `auth.message.data`
# equals this value. When unset, the relay is matched only by auth data carrying its URL; auth data
# matching no configured relay is rejected with 400
# OPTIONAL, DEFAULT: unset
# expected_auth_data = "0x68747470733a2f2f6275696c6465722e6578616d706c652e636f6d"

# Configuration for the PBS multiplexers, which enable different configs to be used for get header requests, depending on validator pubkey
# Note that:
Expand All @@ -145,6 +208,20 @@ validator_pubkeys = [
"0x80c7f782b2467c5898c5516a8b6595d75623960b4afc4f71ee07d40985d20e117ba35e7cd352a3e75fb85a8668a3b745",
"0xa119589bb33ef52acbb8116832bec2b58fca590fe5c85eac5d3230b44d5bc09fe73ccd21f88eab31d6de16194d17782e",
]
# Projection-only: consumed by KM tooling (builder_config projection for this mux's keys), not read
# by the PBS runtime
# OPTIONAL, DEFAULT: unset
# builder_boost_factor = 100
# Projection-only: the per-key-group minimum total payment for this mux's keys, in ETH (same format
# as the PBS-level `min_bid_eth`). Consumed by KM tooling, not read by the PBS runtime
# OPTIONAL, DEFAULT: unset
# min_bid_eth = 0.0
# Projection-only: the KEY-LEVEL p2p overrides for this mux's keys. Consumed by KM tooling, not read
# by the PBS runtime. When set they take precedence over the PBS-level `builder_boost_factor_p2p` /
# `min_bid_p2p_eth`; unset inherits the PBS-level value
# OPTIONAL, DEFAULT: unset (inherit the PBS-level p2p value)
# builder_boost_factor_p2p = 100
# min_bid_p2p_eth = "0.2"
# Loader for validator pubkeys. Three types of loaders are supported:
# - File: path to a file containing a list of validator pubkeys in JSON format
# - URL: URL to an HTTP endpoint returning a list of validator pubkeys in JSON format
Expand Down
5 changes: 3 additions & 2 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ testing-flags = []
[dependencies]
aes.workspace = true
alloy.workspace = true
arbitrary.workspace = true
async-trait.workspace = true
axum.workspace = true
base64.workspace = true
Expand Down Expand Up @@ -53,10 +54,10 @@ tracing-appender.workspace = true
tracing-subscriber.workspace = true
tree_hash.workspace = true
tree_hash_derive.workspace = true
typenum.workspace = true
unicode-normalization.workspace = true
url.workspace = true
uuid.workspace = true
reqwest-eventsource.workspace = true

[dev-dependencies]
tempfile.workspace = true
tempfile.workspace = true
4 changes: 3 additions & 1 deletion crates/common/src/config/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ pub struct LogsSettings {

impl LogsSettings {
pub fn from_env_config() -> Result<Self> {
let (mut config, _) = CommitBoostConfig::from_env_path()?;
// Silent load: the service's primary config load already warns about
// unknown mux fields; warning here too would log each key twice
let (mut config, _) = CommitBoostConfig::from_env_path_silent()?;

// Override log dir path if env var is set
if let Some(log_dir) = load_optional_env_var(LOGS_DIR_ENV) {
Expand Down
16 changes: 16 additions & 0 deletions crates/common/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,33 @@ impl CommitBoostConfig {
)
}

for relay in self.relays.iter() {
relay.validate()?;
}

Ok(())
}

pub fn from_file(path: &PathBuf) -> Result<Self> {
let (config, _): (Self, _) = load_from_file(path)?;
warn_unknown_mux_fields(path);
warn_unknown_pbs_fields(path);
Ok(config)
}

// When loading the config from the environment, it's important that every path
// is replaced with the correct value if the config is loaded inside a container
pub fn from_env_path() -> Result<(Self, PathBuf)> {
let (config, config_path) = Self::from_env_path_silent()?;
warn_unknown_mux_fields(&config_path);
warn_unknown_pbs_fields(&config_path);
Ok((config, config_path))
}

/// [`Self::from_env_path`] without the unknown-mux-field warnings. For
/// secondary loads (e.g. log settings) in processes whose primary config
/// load already warns, so each unknown key is logged once per process.
pub(crate) fn from_env_path_silent() -> Result<(Self, PathBuf)> {
let (helper_config, config_path): (HelperConfig, PathBuf) = load_file_from_env(CONFIG_ENV)?;

let chain = match helper_config.chain {
Expand Down
Loading
Loading