dd8086df0db4d3401073745dfae67dafce704eef
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2cb8f1cf21
|
config: the node on bob is mainnet now, not Planck
Mainnet launched today and the node was switched to it. The observer reads whatever the node is on, so the `[[chains]]` entry pointing at 127.0.0.1:9944 had to follow it — until now the daemon was filing mainnet's blocks under the id `planck`, with Planck's genesis and PLK still attached to them. Read from the node, not assumed: `system_chain` "Quantus", genesis `0xfb5487c0…626fba`, token QTC. `mainnet = true` is asserted here rather than inferred, which is the field's whole purpose — telemetry also carries a chain calling itself "Quantus Staging Mainnet", and it is not this one. The target block time is **12 s, not the 6 s Planck used**. `TARGET_BLOCK_TIME_MS` is 12_000 in the runtime the node actually runs — checked at commit b017e642, the `0.11.1-b017e6420aa` its `system_version` reports, rather than at the tip of the chain repo. It is the denominator for every hashrate published before twenty tip samples exist, which on a chain hours old is all of them, so carrying 6.0 across would have put out a mainnet hashrate at exactly twice its true value — labelled "nominal", not broken. Planck keeps its 268 telemetry nodes and stays in the site's navigation as `no_endpoint`: still listed, no longer navigable, because authorship comes from block headers and we no longer run a node that serves Planck's. That is an ordinary state here, not an outage. Nothing about the node itself is touched by this; every command run against it was a read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jp6a8EDar9ueEhAxzep4V5 |
||
|
|
5f3aac2a13
|
feat(chains): discover every Quantus chain from telemetry; track the ones we can reach
The chain list is no longer config. substrate-telemetry announces every chain it knows — with live node counts — before and independent of any subscription, so one feed connection that never subscribes is a complete, self-maintaining index. A chain that launches tomorrow appears in the nav on its own. Config now contributes only RPC endpoints. Authorship lives in the `pow_` digest of a block *header*, and telemetry publishes hashes and heights but never headers — so a chain with no endpoint is listed with its node count and is not navigable, and the nav says why rather than offering an empty board. The two sets join on genesis hash, never on name. Two chains are tracked in full: Planck (our own node on bob) and Heisenberg (a1-heisenberg.quantus.cat, found via Quantus-Network/quantus-apps). Both decode identically — same digest shape, same QPoW runtime API — which is the proof that adding a chain is one [[chains]] entry and no new code. Quantus Staging Mainnet and Quantus Dirac Testnet are listed and disabled: no endpoint exists under the a1-/a2- pattern and none resolves under any plausible name. Nav is ordered by node count descending, ties broken on id so it cannot reshuffle between refreshes. Telemetry now also yields chain-wide best height, best finalized height, average block time and the client-version histogram (feed codes 1, 2, 12 and 22). Infra moves to a single site: oolon fronts blackbeard.observer, reverse-proxying cross-site over the mesh to the API beside the node on bob. That hop is the one the loopback health probe cannot see, so the deploy now checks it explicitly — a firewalld service scoped to bob's own /16 would leave a live site with a dead /v1 and nothing would fail. infra-setup gains `dns` and `cert` roles that run on oolon with the credential already there: the Cloudflare token is never copied off the proxy, and it refuses to repoint an apex record that already exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSDYiibCtELsrjQq6KXnoi |
||
|
|
110fbc3631
|
feat: blackbeard.observer — live Quantus mining leaderboard
Cargo workspace plus a Vite frontend, following ~/git/architecture/generic.md. Every block header carries its author's wormhole reward preimage in a `pow_` PreRuntime digest, so authorship for the whole network is derivable from headers alone — no indexer, no registration, no way for a miner to be left out. That decoding, the hashrate maths and the telemetry name attribution live in blackbeard-core with no I/O at all, so the parts that are easy to get subtly wrong are exercised by unit tests rather than only against a live chain. The browser holds one WebSocket: snapshot on subscribe, deltas thereafter. The head stream is itself a push (chain_subscribeNewHeads), so a block reaches the page the moment the node imports it. Messages are serialised once per broadcast, and leaderboards are recomputed only for windows a socket is actually watching. No RxJS — useSyncExternalStore is React's own contract for this. Verified against the live Planck testnet: 12/12 headers decoded, telemetry names attributed (quanpool-planck, baba-gorchitsa, …), warm start restoring 84 blocks and 5 held names across a restart. Three findings worth recording, all in CLAUDE.md: - substrate-telemetry sends its JSON in *binary* frames. A text-only client connects, subscribes, reports healthy and receives nothing at all — and a Python probe hides it, because json.loads accepts bytes. - Difficulty is a little-endian U512; decoding it big-endian gives a number wrong by ~10^150 that still renders fine. - Planck's real block interval is ~13-15s against a 6s target with enormous variance, so a measured interval needs 20 tip samples before it is publishable. Deploy assets, the Gitea Actions workflow and script/infra-setup.sh are included; port 25864 is registered in architecture/port-allocations.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSDYiibCtELsrjQq6KXnoi |