Problem
TPROXY_MODE and VARDIFF_ENABLED are declared as process-wide static OnceLock<_> in miner-apps/translator/src/lib/mod.rs:
static TPROXY_MODE: OnceLock<TproxyMode> = OnceLock::new();
static VARDIFF_ENABLED: OnceLock<bool> = OnceLock::new();
TranslatorSv2::start() initializes them unconditionally on every call:
TPROXY_MODE
.set(self.config.aggregate_channels.into())
.expect("TPROXY_MODE initialized more than once");
VARDIFF_ENABLED
.set(self.config.downstream_difficulty_config.enable_vardiff)
.expect("VARDIFF_ENABLED initialized more than once");
nextest.toml sets test-threads = 1, so all integration tests run sequentially in the same process. The first test that calls start() on a TranslatorSv2 sets the OnceLocks successfully. Every subsequent test that creates a new TranslatorSv2 and calls start() causes OnceLock::set() to return Err — the .expect() panics. Since start() is invoked inside tokio::spawn, the panic is silently swallowed, the translator exits immediately, and the test framework only sees a downstream symptom (e.g. "Connection refused" on the monitoring or SV1 port).
Observed symptom
When running the monitoring integration tests with --test-threads=1, the first tProxy test passes and the remaining 9 fail with "Connection refused" on the monitoring endpoint. There are 10 tProxy tests total, producing a consistent 10/9 pass/fail split. Confirmed reproducible on 3773dd5 (upstream main before PR #373).
Fix
TPROXY_MODE and VARDIFF_ENABLED should not be process-wide singletons. Options:
- Make them instance fields on
TranslatorSv2 (preferred) — remove the statics, store the values in the struct, and pass them through to callers.
- Use
get_or_init everywhere instead of set + expect — this silently ignores the second initialization, which is safe if all instances are configured identically, but masks misconfiguration.
Option 1 is the correct fix as it allows multiple TranslatorSv2 instances with different configs to coexist in the same process (required for integration tests and any future multi-instance deployment).
Problem
TPROXY_MODEandVARDIFF_ENABLEDare declared as process-widestatic OnceLock<_>inminer-apps/translator/src/lib/mod.rs:TranslatorSv2::start()initializes them unconditionally on every call:nextest.tomlsetstest-threads = 1, so all integration tests run sequentially in the same process. The first test that callsstart()on aTranslatorSv2sets theOnceLocks successfully. Every subsequent test that creates a newTranslatorSv2and callsstart()causesOnceLock::set()to returnErr— the.expect()panics. Sincestart()is invoked insidetokio::spawn, the panic is silently swallowed, the translator exits immediately, and the test framework only sees a downstream symptom (e.g. "Connection refused" on the monitoring or SV1 port).Observed symptom
When running the monitoring integration tests with
--test-threads=1, the first tProxy test passes and the remaining 9 fail with "Connection refused" on the monitoring endpoint. There are 10 tProxy tests total, producing a consistent 10/9 pass/fail split. Confirmed reproducible on3773dd5(upstream main before PR #373).Fix
TPROXY_MODEandVARDIFF_ENABLEDshould not be process-wide singletons. Options:TranslatorSv2(preferred) — remove the statics, store the values in the struct, and pass them through to callers.get_or_initeverywhere instead ofset+expect— this silently ignores the second initialization, which is safe if all instances are configured identically, but masks misconfiguration.Option 1 is the correct fix as it allows multiple
TranslatorSv2instances with different configs to coexist in the same process (required for integration tests and any future multi-instance deployment).