Files
observer/web/src/api/generated/LeaderboardRow.ts
T
grenadeandClaude Opus 5 f9ea292a70
deploy / build (push) Successful in 7m25s
deploy / deploy-web (push) Successful in 4s
deploy / deploy-api (push) Successful in 15s
fix: a hashrate estimate now carries its error bar
The leaderboard credited a miner with "1.55 GH/s" on the strength of one block,
last seen four hours earlier, to three significant figures. Block finding is
Poisson: k blocks carries a relative standard error of 1/√k, so one block is
±100% and it takes twenty-five to reach ±20%. The estimator was unbiased and the
presentation was not honest, which is the half that matters to a reader.

`miner_hashrate` now returns the count's uncertainty with the figure, and the
leaderboard and miner page render it — dimmed below four blocks, where the error
bar is wider than half the value.

Checked first that the arithmetic itself is sound, because the obvious
suspicion was the formula. It is the chain's own: `qpow-math::is_valid_nonce`
accepts when `hash < U512::MAX / difficulty`, `verify_nonce_internal` passes it
what `get_difficulty()` returns, and the hash is uniform — 200,000 samples of
`hash_squeeze_twice` gave 0.4995 of 2^512 against a uniform 0.5, and 12.48%
below 2^509 against 12.5%. Acceptance is 1/difficulty, so expected trials is
difficulty, exactly. The two network estimators — difficulty over tip interval,
and summed work over window span — also agree within 5% on live data.

What that leaves is recorded in CLAUDE.md and is not an observer bug: our three
miners measure 1.66 GH/s (1.39 instantaneous), while the chain credited the same
preimage 5.3 GH/s over 29 blocks. Sampling does not explain 14 sigma.
`miner_cpu_hash_rate` is 0 on all three — every hash is on GPU — and the miner's
CPU path calls `qpow_math::get_nonce_hash` directly while the CUDA kernel is a
separate implementation with its own counter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jp6a8EDar9ueEhAxzep4V5
2026-09-09 19:48:51 +03:00

84 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AttributionSource } from "./AttributionSource";
import type { MinerId } from "./MinerId";
/**
* One row of the leaderboard.
*/
export type LeaderboardRow = {
/**
* 1-based position within the window. Ties break by most recent block.
*/
rank: number,
/**
* The miner's reward preimage — the stable key for this row.
*/
miner: MinerId,
/**
* The address this miner is paid at, derived from the preimage by the same
* function the chain uses to decide who to pay. Shown in place of the
* preimage wherever a miner has no name: both identify it exactly, and
* only this one is a string its owner recognises.
*/
address: string | null,
/**
* What to render: a telemetry node name when one is attributed, else the
* abbreviated preimage.
*/
display: string,
/**
* Where `display` came from.
*/
attribution: AttributionSource,
/**
* Fraction of attributed blocks pointing at the named node, 0.0–1.0. Zero
* when `attribution` is `Preimage`.
*/
confidence: number,
/**
* How many blocks that fraction is out of. A name is offered as soon as one
* node leads, so a row can carry 100% agreement on a single observation —
* the UI needs the count to tell that apart from a settled mapping, and to
* avoid presenting a best-effort guess as an established fact.
*/
attribution_votes: number,
/**
* Blocks authored inside the window.
*/
blocks: number,
/**
* Share of the window's blocks, 0.0–1.0.
*/
share: number,
/**
* Implied hashrate in hashes per second: the miner's share of blocks times
* the estimated network hashrate. A statistical estimate over a finite
* window, not a measurement of the miner's hardware — a lucky small miner
* will over-read and an unlucky large one will under-read.
*/
hashrate_estimate: number | null,
/**
* Relative standard error on that figure, as a fraction — `0.71` means
* ±71%. Block finding is Poisson, so this is `1/√blocks`: one block is
* ±100% and it takes twenty-five to reach ±20%.
*
* Carried beside the estimate rather than folded into it because they are
* different claims. Rendering the number without it is how a row came to
* say "7.64 GH/s" off two blocks, for a miner measuring 1.5 GH/s at its
* own hardware.
*/
hashrate_relative_error: number | null,
/**
* Height of this miner's most recent block in the window.
*/
last_block_height: number,
/**
* When the observer saw that block.
*/
last_seen: string,
/**
* Longest run of consecutive blocks by this miner within the window. A run
* far above what its share predicts is the signature of withheld blocks.
*/
best_streak: number, };