Add network field to GlobalInfo (GET /api/v1/global)#367
Add network field to GlobalInfo (GET /api/v1/global)#367vnprc wants to merge 4 commits intostratum-mining:mainfrom
network field to GlobalInfo (GET /api/v1/global)#367Conversation
fd8c1a3 to
fc7e0ce
Compare
Add `network: Option<String>` to `GlobalInfo` so the Bitcoin network is machine-readable from `GET /api/v1/global` without consulting Prometheus or config files. - `GlobalInfo` gets `pub network: Option<String>` - `ServerState.network`: `Option<String>` → `Arc<RwLock<Option<String>>>` - `MonitoringServer::with_network(self, Option<String>)` writes into the existing Arc so any handle obtained via `network_handle()` remains valid after the call - `MonitoringServer::network_handle()` returns a clone of the Arc for background tasks that need to update network after `run()` consumes self - `handle_global` reads via `.read().unwrap().clone()` - Tests: `global_endpoint_with_no_sources` asserts network is null; new `global_endpoint_network_field` asserts null and populated cases
Pool infers the Bitcoin network from the sv2-tp port in tp_address using well-known default ports (8442=mainnet, 18442=testnet3, 48442=testnet4, 38442=signet, 18447=regtest). An explicit `network` config field remains as an optional override for non-standard port setups. Translator fetches network from pool's /api/v1/global once per upstream connection instead of polling every 60 seconds. Retries are handled by the existing reconnect logic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove reqwest from translator entirely; replace with a plain hyper
HTTP/1.1 client inside stratum-apps/monitoring. hyper is already
compiled transitively via axum, so no new Cargo.lock entries are
introduced.
- MonitoringServer gains with_upstream_monitoring_url() which validates
the http:// scheme, stores the URL, and spawns a one-shot fetch in
run(). The old network_handle() method (which leaked internal Arc state
into application code) is removed.
- Translator chains .with_upstream_monitoring_url() onto the
MonitoringServer builder; fetch_network_from_pool() private function
removed from translator/mod.rs.
- Fix network_from_tp_port to use bitcoin-cli / getblockchaininfo names:
"main" (was "mainnet"), "test" (was "testnet3"). Add VALID_NETWORKS
constant; effective_network() validates explicit overrides against it.
Add valid_networks_covers_known_port_outputs unit test.
- Change all RwLock .unwrap() to .expect("network lock poisoned").
- Rename integration test to global_info_network_from_config_override;
bump polling deadline 10s -> 30s; add
global_info_network_unreachable_upstream test.
…tum-apps Move network_from_tp_port() and VALID_NETWORKS from pool-apps (private) into stratum-apps/src/tp_type.rs as public API. Add BitcoinNetwork::as_network_str() and TemplateProviderType::infer_network() so any application using TemplateProviderType can derive the Bitcoin network without duplicating the port-mapping logic. Pool config is updated to delegate to infer_network() instead of carrying its own copy of the helper function. JobDeclaratorClientConfig gains the same effective_network() / with_network() pattern as PoolConfig. For Sv2Tp the network is inferred from the sv2-tp port; for BitcoinCoreIpc it is taken directly from the BitcoinNetwork enum value. An explicit network override field (serde default) is provided for non-standard port setups. Both the initial startup and reconnect MonitoringServer paths are updated to call .with_network(config.effective_network()). Integration test lib adds start_jdc_with_network_override(); new test global_info_network_jdc_from_config_override verifies JDC GlobalInfo exposes the network field. Unit tests added to stratum-apps/tp_type, pool config, and JDC config.
dfa8ab3 to
5e3bb6f
Compare
|
Thanks for the detailed review @Alkamal01! I pushed three commits today and rebased onto current upstream main (95 commits, no conflicts). I believe this PR is ready for another look. feat: wire network field through pool, translator, and integration test
fix(monitoring): address PR review feedback
feat: extend network inference to JDC; move
|
|
Can you please clarify the need for these changes? Could you give a concrete example of when this is needed? |
|
Sv2 today does not provide a way to determine what blockchain you are mining on. This is the most basic piece of information I can think of, so that's where I started contributing to My mining dashboard displays this field and is running this code now (in my vendored sv2-apps repo, as you can see in this commit).
For the first iteration I just displayed a config file setting, but this is just a lie; it can and will be misconfigured eventually. I'm trying to build the plumbing to get this information from the source of truth: the template provider. This iteration uses standard ports (thanks for the tip @Sjors!) and falls back to displaying a config setting. This is better because it pulls info from the source of truth (the tp) as long as you stick to standard ports. It's still a lie if you deviate from the standard ports, but at least this PR adds the plumbing that routes this information to the monitoring API. The complete solution is to include this information in the template distribution protocol handshake message. I have opened an issue in the protocol repo here: stratum-mining/sv2-spec#190 Frankly, I am amazed that no one has considered this a problem before. It's not even in the protocol! We have so much work to do... |
|
@GitGab19 should i just write the spec and then open a new PR implementing it? |
|
I'm not sure this is a problem tbh, but I have to think more about this. When do you switch networks in production? Which is the specific use case? |
|
I switch networks between dev and prod environments. Dev runs My goal is to build pool software that runs on autopilot. We will never decentralize block producers if running a pool remains a specialized skillset only available to a select few. If a pleb miner is running hashpool I want to prevent them from missing out on a block because they didn't read the manual. When the SRI install base reaches the scale we need it to reach to decentralize bitcoin block production, the probability of a misconfiguration causing an invalid block approaches 1. Remember when Marathon mined an invalid block? I do. The objective of this protocol change is to prevent this footgun in an automated fashion.
|
|
I'm not getting your point yet. If you're running a Pool server (or a JDC) which gets block templates directly from Bitcoin Core (through IPC) or from a Template Provider, it will get templates related to the network where the node is running. How can this flow ever lead to the error Mara experienced in your example? |
|
How does the node network value get displayed to the end user? edit: How does your grandma know what network she is mining on? She's only computer literate enough to install a "pool-in-a-box" solution and click thru the install wizard. Is she supposed to grep the bitcoind logs? I think we can do better than that. I guess a more specific answer is this: grandma clicks testnet on the bitcoin node install option and then she clicks mainnet on the pool software option. What happens? It sounds like today the pool software just blindly trusts the node. Why? It's just not that hard to make sure that this information flows through the system to the end user UI display. Why would we not build this capability? Don't trust verify. |
|
How about a different example. The user is playing with the software and switches the node to It's just a basic software engineering principle to have a single source of truth. Violating this principle leads to bugs. We violate this principle for the most fundamental piece of data in the whole mining stack: what blockchain are we mining on? The fix is simple. So let's fix it. |


Summary
network: Option<String>toGlobalInfoso the Bitcoin network is machine-readable from the monitoring REST API without inspecting config files or Prometheus metrics[pool]TOML config (network = "regtest")GET <upstream_monitoring_url>/api/v1/globalevery 60 seconds in a background taskMotivation
Downstream consumers of the monitoring API (dashboards, alerting tools, and same for translator proxy) need to know which Bitcoin network the pool is operating on. Today this requires reading config files out-of-band. Exposing it in
GlobalInfomakes it a first-class, machine-readable API field.Changes
stratum-appsGlobalInfo.network: Option<String>(serializes tonullwhen not configured)ServerState.network: Arc<RwLock<Option<String>>>for runtime updatesMonitoringServer::with_network()— builder method for static configurationMonitoringServer::network_handle()— returns anArcclone for background tasks that need to update the field afterrun()consumesselfpool-apps/poolPoolConfig.network: Option<String>with#[serde(default)](backward-compatible).with_network(config.network())on startupminer-apps/translatorTranslatorConfig.upstream_monitoring_url: Option<String>with#[serde(default)]monitoring_server.network_handle()then spawnspoll_network_from_pool(): fetches pool's/api/v1/globalimmediately, then every 60 seconds; exits cleanly on cancellationreqwestadded as a dependency (default-features = false, features = ["json"])integration-testsstart_pool_with_networkandstart_sv2_translator_with_upstream_monitoringhelpers added (existing helpers unchanged, delegate to new ones)global_info_exposes_networktest: starts pool withnetwork = "regtest", starts translator pointing at pool's monitoring server, asserts pool exposes"regtest"immediately and translator propagates it within 10 secondsNetwork value convention
Values follow
bitcoin-cli -getinfo/bitcoin-cli getblockchaininfoconvention:"main","test","testnet4","regtest","signet". The field isnullif not configured.Test plan
cargo clippy --manifest-path stratum-apps/Cargo.toml -- -D warnings -A dead-code— cleancargo test --manifest-path stratum-apps/Cargo.toml— 29/29 passcargo fmt --manifest-path stratum-apps/Cargo.toml -- --check— cleanreqwestaddedglobal_info_exposes_networkintegration test passes end-to-end