qt: Overview "chain vitals" panel — height, difficulty + 7-day avg, net/pool hashrate, Great Ritual countdown + finale claimant link #62

Closed
opened 2026-08-04 21:41:27 +00:00 by dobbscoin · 1 comment
dobbscoin commented 2026-08-04 21:41:27 +00:00

Motivation

The Overview page's right column is the Transgressions (recent transactions) list with nothing but dead spacer below it (verticalSpacer_2). The wallet already knows almost everything a worshipper glances at the explorer for — height, difficulty, hashrate, and (since v2.0.0) the entire Great Ritual schedule. Put it on the Altar's doorstep instead.

Cosmetic / wallet-only change. No consensus impact, no forced upgrade — targets the v2.1.x line.

Placement

src/qt/forms/overviewpage.ui, right column (verticalLayout_3): replace verticalSpacer_2 below listTransactions with a styled QFrame matching the existing Altar / Transgressions panels. Labels should keep the established register (Altar, Transgressions, Incantations, Tithing) — flavored label + plain-English tooltip, same pattern as today.

Proposed rows

Row Data source Cost
Block Height ClientModel::getNumBlocks() — already wired to numBlocksChanged trivial
Network Difficulty GetDifficulty(chainActive.Tip()) via a new ClientModel getter trivial
Avg Difficulty (7 days) walk the in-memory block index back 10,080 headers (7 d × 1,440 blocks/day), mean of GetDifficulty(pindex); recompute on new-block signal cheap, local
Network Hashrate reuse the getnetworkhashps estimator from rpcmining.cpp (last ~120 blocks), exposed via ClientModel cheap, local
Pool Hashrate external HTTP — see decision below needs decision
Great Ritual countdown pure height math from the RitualBonus() schedule — see below trivial, local
Last finale claimed by… local coinbase read + explorer hyperlink — see below cheap, local

Pool hashrate — the one external dependency (decision needed)

The only row that can't come from the local chain state. Source would be the public Miningcore API: GET https://pool.23skidoo.info/api/pools/offerings → pool.poolStats.poolHashrate, polled via QNetworkAccessManager every ~60 s.

Considerations:

  • Every GUI wallet phoning one pool on a timer is a privacy and centralization smell the rest of the wallet doesn't have.
  • The pool being down must not blank or hang the panel.

Proposal: off by default, enabled via a Display option ("Show pool hashrate"), URL kept as a single constant, row shows — when disabled or on any fetch failure/timeout. Alternative: drop this row entirely and keep the panel 100 % local. Decide before implementation.

Great Ritual countdown (fully local)

The schedule is completely determined by height — RitualBonus() (src/main.cpp:1219): FIRST_FINALE = 1,141,666, PERIOD = 263,000, 29-day rite of once-per-day special blocks before each finale. Expose a small helper (next finale height, blocks remaining, current rite phase + that day's bounty when inside the window); no behavior change to consensus code.

Display states:

  • Outside the rite: Next finale: block 1,141,666 — 69,591 blocks (~48 days)
  • Inside the 29-day rite: show the phase (sacrifice / acceptance / greed / fervor / Tharanak shagg) and the day's special-block bounty
  • Finale height reached: a 10,000 OFF flourish, then roll to the next cycle

For reference at time of filing: tip ≈ 1,072,075, so the first post-fork finale is ~48 days out and the rite window opens at block 1,101,346 (~20 days out).

"Claimed by" — the address that solves the BIG block (fully local)

Once a finale height is buried in the chain, show:

Last finale (block 1,141,666) claimed by Qxxxx…xxxx → hyperlink to https://explorer.23skidoo.info/address/<Q-address>

Mechanics: chainActive[F] → ReadBlockFromDisk → coinbase vout[0] → ExtractDestination. vout[0] is the miner output (7/8 base + full ritual bonus) and vout[1] the Treasury split (src/miner.cpp:351-357), so no txindex is needed — one disk read per finale, cache the result.

Caveats to bake in:

  1. Pool-found finales resolve to the pool's payout address, not the lucky worshipper's own wallet — the real winner is settled by the pool's PPLNS accounting afterward. The link is still the correct on-chain claimant; the tooltip should say so honestly.
  2. Hide the row until the first finale has actually passed (nothing to show before block 1,141,666).
  3. Explorer base URL is a constant; blank/disable the hyperlink on testnet/regtest builds rather than linking the mainnet explorer.

Non-goals

  • No consensus or RPC changes (everything flows through ClientModel).
  • No mining controls — that's #8's territory.
  • No price/market data.

Sketch of files touched

  • src/qt/forms/overviewpage.ui — new frame in the right column
  • src/qt/overviewpage.{h,cpp} — wiring, refresh timer, formatting
  • src/qt/clientmodel.{h,cpp} — getters: difficulty, 7-day avg, net hashrate, ritual status, finale claimant
  • src/main.{h,cpp} — tiny read-only helpers exposing the RitualBonus() schedule
  • src/qt/optionsmodel / optionsdialog — pool-hashrate opt-in (only if that row survives)

Related: #8 (Mining tab), #18 (per-peer sync-height backport).

## Motivation The Overview page's right column is the **Transgressions** (recent transactions) list with nothing but dead spacer below it (`verticalSpacer_2`). The wallet already knows almost everything a worshipper glances at the explorer for — height, difficulty, hashrate, and (since v2.0.0) the entire Great Ritual schedule. Put it on the Altar's doorstep instead. Cosmetic / wallet-only change. **No consensus impact, no forced upgrade** — targets the v2.1.x line. ## Placement `src/qt/forms/overviewpage.ui`, right column (`verticalLayout_3`): replace `verticalSpacer_2` below `listTransactions` with a styled `QFrame` matching the existing Altar / Transgressions panels. Labels should keep the established register (Altar, Transgressions, Incantations, Tithing) — flavored label + plain-English tooltip, same pattern as today. ## Proposed rows | Row | Data source | Cost | |---|---|---| | Block Height | `ClientModel::getNumBlocks()` — already wired to `numBlocksChanged` | trivial | | Network Difficulty | `GetDifficulty(chainActive.Tip())` via a new `ClientModel` getter | trivial | | Avg Difficulty (7 days) | walk the in-memory block index back 10,080 headers (7 d × 1,440 blocks/day), mean of `GetDifficulty(pindex)`; recompute on new-block signal | cheap, local | | Network Hashrate | reuse the `getnetworkhashps` estimator from `rpcmining.cpp` (last ~120 blocks), exposed via `ClientModel` | cheap, local | | Pool Hashrate | **external HTTP — see decision below** | needs decision | | Great Ritual countdown | pure height math from the `RitualBonus()` schedule — see below | trivial, local | | Last finale claimed by… | local coinbase read + explorer hyperlink — see below | cheap, local | ## Pool hashrate — the one external dependency (decision needed) The only row that can't come from the local chain state. Source would be the public Miningcore API: `GET https://pool.23skidoo.info/api/pools/offerings` → `pool.poolStats.poolHashrate`, polled via `QNetworkAccessManager` every ~60 s. Considerations: - Every GUI wallet phoning one pool on a timer is a privacy and centralization smell the rest of the wallet doesn't have. - The pool being down must not blank or hang the panel. Proposal: **off by default**, enabled via a Display option ("Show pool hashrate"), URL kept as a single constant, row shows `—` when disabled or on any fetch failure/timeout. Alternative: drop this row entirely and keep the panel 100 % local. Decide before implementation. ## Great Ritual countdown (fully local) The schedule is completely determined by height — `RitualBonus()` (`src/main.cpp:1219`): `FIRST_FINALE = 1,141,666`, `PERIOD = 263,000`, 29-day rite of once-per-day special blocks before each finale. Expose a small helper (next finale height, blocks remaining, current rite phase + that day's bounty when inside the window); no behavior change to consensus code. Display states: - **Outside the rite:** `Next finale: block 1,141,666 — 69,591 blocks (~48 days)` - **Inside the 29-day rite:** show the phase (sacrifice / acceptance / greed / fervor / Tharanak shagg) and the day's special-block bounty - **Finale height reached:** a 10,000 OFF flourish, then roll to the next cycle For reference at time of filing: tip ≈ 1,072,075, so the first post-fork finale is ~48 days out and the rite window opens at block 1,101,346 (~20 days out). ## "Claimed by" — the address that solves the BIG block (fully local) Once a finale height is buried in the chain, show: > `Last finale (block 1,141,666) claimed by Qxxxx…xxxx` → hyperlink to `https://explorer.23skidoo.info/address/<Q-address>` Mechanics: `chainActive[F]` → `ReadBlockFromDisk` → coinbase `vout[0]` → `ExtractDestination`. `vout[0]` is the miner output (7/8 base + full ritual bonus) and `vout[1]` the Treasury split (`src/miner.cpp:351-357`), so no txindex is needed — one disk read per finale, cache the result. Caveats to bake in: 1. **Pool-found finales resolve to the pool's payout address**, not the lucky worshipper's own wallet — the real winner is settled by the pool's PPLNS accounting afterward. The link is still the correct on-chain claimant; the tooltip should say so honestly. 2. Hide the row until the first finale has actually passed (nothing to show before block 1,141,666). 3. Explorer base URL is a constant; blank/disable the hyperlink on testnet/regtest builds rather than linking the mainnet explorer. ## Non-goals - No consensus or RPC changes (everything flows through `ClientModel`). - No mining controls — that's #8's territory. - No price/market data. ## Sketch of files touched - `src/qt/forms/overviewpage.ui` — new frame in the right column - `src/qt/overviewpage.{h,cpp}` — wiring, refresh timer, formatting - `src/qt/clientmodel.{h,cpp}` — getters: difficulty, 7-day avg, net hashrate, ritual status, finale claimant - `src/main.{h,cpp}` — tiny read-only helpers exposing the `RitualBonus()` schedule - `src/qt/optionsmodel` / `optionsdialog` — pool-hashrate opt-in (only if that row survives) Related: #8 (Mining tab), #18 (per-peer sync-height backport).
dobbscoin commented 2026-08-04 21:58:03 +00:00

Scope update: the pool-hashrate row is dropped — the panel is now 100% local, no network I/O, which resolves the one open decision above.

Implementation is up on branch feat/62-overview-chain-vitals (commit 9a037588): "The Deep" panel in the Overview page's lower right — Depth (height), Vigilance (difficulty, current / 7-day mean), The Thrum (network hashrate), the Great Ritual finale countdown with rite-phase display, and the finale claimant's address linked to the explorer once the first finale has passed. Core side adds only read-only helpers (GetRitualStatus(), GetCoinbasePayoutAddress()); no consensus or RPC changes.

Scope update: the **pool-hashrate row is dropped** — the panel is now 100% local, no network I/O, which resolves the one open decision above. Implementation is up on branch [`feat/62-overview-chain-vitals`](https://github.com/SubGeniusFinance/Offerings-to-Cthulhu/tree/feat/62-overview-chain-vitals) (commit 9a037588): "The Deep" panel in the Overview page's lower right — Depth (height), Vigilance (difficulty, current / 7-day mean), The Thrum (network hashrate), the Great Ritual finale countdown with rite-phase display, and the finale claimant's address linked to the explorer once the first finale has passed. Core side adds only read-only helpers (`GetRitualStatus()`, `GetCoinbasePayoutAddress()`); no consensus or RPC changes.
dobbscoin closed this issue 2026-08-04 23:05:33 +00:00
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SubGeniusFinance/Offerings-to-Cthulhu#62
No description provided.