Skip to content

feat: expose stratum mining stats via Owner API#3897

Open
iho wants to merge 2 commits into
mimblewimble:stagingfrom
iho:feat/mining-status-api
Open

feat: expose stratum mining stats via Owner API#3897
iho wants to merge 2 commits into
mimblewimble:stagingfrom
iho:feat/mining-status-api

Conversation

@iho

@iho iho commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Adds an Owner API endpoint for stratum mining statistics so operators running headless (no TUI) can inspect connected workers and share stats — the same data shown on the TUI mining tab.

Closes #3201

Changes

  • New get_mining_status method on Owner JSON-RPC (/v2/owner)
  • New types: MiningStatus / WorkerInfo in the API crate
  • Server wires live StratumStats into the Owner API via a provider callback
  • CLI: grin client miningstatus
  • Brief docs in doc/api/api.md

Example

{
  "jsonrpc": "2.0",
  "method": "get_mining_status",
  "params": [],
  "id": 1
}

Returns whether stratum is enabled/running, worker count, block height, network difficulty/hashrate, blocks found, and per-worker share stats. When stratum is disabled (or no provider is wired), returns a disabled default rather than an error.

Test plan

  • Unit tests: MiningStatus serde roundtrip, default disabled state
  • Unit tests: Owner::get_mining_status with/without provider
  • Unit tests: StratumStatsMiningStatus conversion
  • cargo check -p grin --bin grin
  • Manually: enable stratum, connect a miner, run grin client miningstatus

@wiesche89 wiesche89 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice and useful feature, and the endpoint is wired to the live StratumStats correctly. Before merging, I’d clarify whether the API should return only active workers, avoid masking a missing provider as disabled, and preserve the public node_apis signature.

Comment thread servers/src/common/stats.rs Outdated
Comment thread api/src/owner.rs Outdated
Comment thread api/src/handlers.rs
Comment thread api/src/types.rs
/// Whether the stratum server is enabled in config
pub is_enabled: bool,
/// Whether the stratum server is currently running
pub is_running: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source flag is set on startup but never cleared on listener failure or shutdown. Is “currently running” too strong for the API contract?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A port conflict still leaves this as true after the listener exits. Could we set it after a successful bind, clear it on exit, and test the bind-failure case?

Comment thread api/src/owner.rs
Add get_mining_status to the Owner JSON-RPC API so headless operators
can query the same stratum/worker stats shown on the TUI mining tab.
Wire live StratumStats into node_apis and add `grin client miningstatus`.

Closes mimblewimble#3201
@iho
iho force-pushed the feat/mining-status-api branch 2 times, most recently from f406b85 to 60178eb Compare July 17, 2026 00:56
- Filter mining status worker_stats to currently connected workers
  (StratumStats retains disconnected workers for the node lifetime),
  and drop the now always-true is_connected field from WorkerInfo
- Return an internal error from get_mining_status when no stats
  provider is wired, instead of masking it as disabled
- Restore the public node_apis signature; add
  node_apis_with_mining_stats for provider wiring
- Document is_running as set-once at startup
- Trim get_mining_status doc comment to match neighboring methods
@iho
iho force-pushed the feat/mining-status-api branch from 60178eb to 120e0cd Compare July 17, 2026 00:58
@iho
iho requested a review from wiesche89 July 17, 2026 01:01
blocks_found: stats.blocks_found,
network_hashrate: stats.network_hashrate,
minimum_share_difficulty: stats.minimum_share_difficulty,
// worker_stats retains every worker that ever connected; only expose

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The response is bounded now, but each request still scans the full worker history under the stats lock. Could we keep a bounded active-worker view and derive num_workers from it too?

Comment thread api/src/types.rs
/// Whether the stratum server is enabled in config
pub is_enabled: bool,
/// Whether the stratum server is currently running
pub is_running: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A port conflict still leaves this as true after the listener exits. Could we set it after a successful bind, clear it on exit, and test the bind-failure case?

Comment thread api/src/types.rs
pub worker_stats: Vec<WorkerInfo>,
}

impl Default for MiningStatus {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no caller besides its own test and duplicates StratumStats::default(). Could we remove the impl and test to avoid default drift?

Comment thread api/src/owner.rs
}

#[test]
fn get_mining_status_with_provider() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we test this once through the generated JSON RPC handler? The current tests only call Owner directly, so the wire response is not covered.

Comment thread api/src/owner.rs
pub fn get_mining_status(&self) -> Result<MiningStatus, Error> {
match &self.mining_stats {
Some(provider) => Ok(provider()),
None => Err(Error::Internal(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fixed now. Could you also update the PR description? It still says a missing provider returns a disabled default.

@wiesche89

Copy link
Copy Markdown
Contributor

I’ve written a prototype Grin miner in Rust https://github.com/wiesche89/rust-miner . It can be used to test the new Owner API method end to end.
With a synced testnet node running, Stratum enabled on port 13416, and the Owner API listening on 13413, start a lightweight worker with:

./target/release/grin-cuckatoo-miner mine \
  --backend cpu \
  --edge-bits 25 \
  --node-port 13416 \
  --login api-test-1

I tested four connected miners this way. The API reported num_workers: 4 with four worker entries, then returned num_workers: 0 and an empty worker list after disconnecting them. C25 is only intended as a lightweight connection test, valid testnet mining requires C32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants