feat: section indexes, so the routes can be found
Every route added lately was reachable only by already knowing an address — a block hash, a preimage, an SS58 string, a spec_version. Fine for a link somebody sent you, useless for discovering the pages exist. A kind with nothing after it is now the index of that kind, and a nav under the chain chips names them. Not the same page three times. Blocks is the record behind the live ticker, paged by height. Accounts ranks by tokens earned over the whole indexed record, which is a different question from the standings' blocks-per-window and here a different answer: difficulty rose 346-fold inside mainnet's first day, so an early block cost a three-hundredth of a current one. Runtimes is the only list with no other home — a block does not name its runtime and neither do the standings. No `/:chain/miner`: the standings already are the index of miners, and a second page of the same rows under another address would be two answers to one question. That path redirects there, along with anything else that resolves to the front page without being spelled like it, so the address bar and the section nav agree about where the reader is. Two things caught by looking at the rendered pages: The block index's gaps came from `observed_at` and read *three milliseconds* between blocks on a chain targeting twelve seconds — exactly the trap CLAUDE.md records, since a gap fill writes a whole batch within one second. They come from `authored_at` now, the chain's own clock. The first page of that index came from the live ticker, which is ordered oldest-first because that is the order it is pushed in, so page one climbed and every page after it descended. The index sends a cursor for its first page too. Accounts shows the address beside any node name: one node legitimately reports for several payout addresses, and the first cut had two rows reading `pearl-prover` with nothing to tell them apart. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jp6a8EDar9ueEhAxzep4V5
This commit is contained in:
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n select height, miner, observed_at, authored_at, difficulty\n from block\n where chain = $1 and height < $2\n order by height desc\n limit $3\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "height",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "miner",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "observed_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "authored_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "difficulty",
|
||||
"type_info": "Numeric"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "525f21399582e40b79567a370e5ef052670f46ac12a413c6636bc06c720f9935"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n select a.account as \"account!\",\n count(*) as \"blocks!\",\n sum((e.fields->>'reward')::numeric)::text as \"total!\",\n -- Any of them: the wormhole derivation runs one way from a\n -- preimage to an address, so every reward paid to one\n -- account came from the same preimage. `max` is how to say\n -- \"any non-null\" in a group by, not a choice between\n -- candidates. Null when no reward height has a block row —\n -- events are indexed from genesis, blocks only from when\n -- this observer started watching.\n max(b.miner) as miner\n from chain_event e\n cross join unnest(e.accounts) a(account)\n left join block b on b.chain = e.chain and b.height = e.height\n where e.chain = $1\n and e.pallet = 'MiningRewards' and e.variant = 'MinerRewarded'\n group by a.account\n order by sum((e.fields->>'reward')::numeric) desc\n limit $2\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "account!",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "blocks!",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "total!",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "miner",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "914725a46ee04bd2655fd22c329a981b848f944edec94a5c50624fddae910e68"
|
||||
}
|
||||
Reference in New Issue
Block a user