Skip to content

fix(network): name the group each per-client and per-network-type share is of - #571

Merged
samcm merged 1 commit into
masterfrom
fix/network-share-chart-titles
Nov 12, 2026
Merged

samcm merged 1 commit into
masterfrom
fix/network-share-chart-titles

Conversation

@samcm

@samcm samcm commented Nov 12, 2026

Copy link
Copy Markdown
Member

"Seen all 30 days, by network type" on /ethereum/network drew Hosting and Other lines that add up to well over 100%. The data is right: each line is the share of that network type's own peers seen all 30 days (from fct_peer_churn_daily on 10 Nov 2026: hosting 4693 / 6741 = 69.6%, other 4230 / 7275 = 58.1%). The title and the "Share of peers" axis made the lines read as parts of one whole.

The per-client rate cards (clientShareLines) have the same problem: "New peers, by client" (Caplin reaches 80%), "Within a slot of the head, by client", "Dialled, by client" and "On all 64 subnets, by client".

Each of these cards' titles and value axes now names the denominator:

Before After Axis
New peers, by client Share of each client's peers that were new Share of the client's peers
Seen all 30 days, by network type Share of each network type's peers seen all 30 days Share of the type's peers
Within a slot of the head, by client Share of each client's peers within a slot of the head Share of the client's peers
Dialled, by client Share of each client's peers that were dialled Share of the client's peers
On all 64 subnets, by client Share of each client's peers on all 64 subnets Share of the client's peers

The xatu-cbt table is consistent: for every network type and day checked, new + 2–7 + 8–29 + 30-day buckets equal peer_count.

Checked with pnpm lint, pnpm build and the network unit tests, and by rendering the page against production data at 1440 and 1280 px.

…re is of

Seen all 30 days, by network type drew the share of hosting peers seen all
30 days and the share of other peers seen all 30 days, each of its own
group, so the two lines add up to well over 100% (69.6% and 58.1% on
10 Nov). The per-client lines on the churn, sync, reachability and subnet
cards are built the same way. Titled as "X, by client" they read as a
breakdown of one whole.

Each title and value axis now names its denominator: "Share of each
client's peers ..." and "Share of each network type's peers ...".

Amp-Thread-ID: https://ampcode.com/threads/T-01a1cd46-600c-7706-947f-ce26c936fe39
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
@samcm
samcm requested a review from Savid as a code owner November 12, 2026 01:10

@redpandabot redpandabot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

A copy-only change renaming five per-client and per-network-type share cards and their value axes so each names its denominator. Two of the new labels claim the share is of all of a client's peers while the code divides by a narrower population (peers that answered status, peers that answered metadata), so those cards still misstate the denominator; the network-type card also claims every type while drawing only two. The churn and reachability per-client cards are correct.

Issues

  • 🟡 src/pages/ethereum/network/components/SyncCharts/SyncCharts.tsx:66 — title and axis name the wrong denominator for head lag — see the thread on that line
  • 🟡 src/pages/ethereum/network/components/SubnetCharts/SubnetCharts.tsx:55 — subnet share is of metadata responders, not all the client's peers — see the thread on that line
  • 🟢 src/pages/ethereum/network/components/ChurnCharts/ChurnCharts.tsx:106 — "each network type" omits the unknown type the table carries — see the thread on that line

Reviewed @ f36c6f5a
"Pets vs. cattle." — Bill Baker

/>
<SeriesCard
title="Within a slot of the head, by client"
title="Share of each client's peers within a slot of the head"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 title and axis name the wrong denominator for head lag

clientShareLines divides by status_peer_count (peers that exchanged status), not peer_count (peers seen), so the card does not show "share of each client's peers" as titled, and the axis at 68 repeats the same claim. On 2026-11-10 caplin reads 414/490 = 84.5% although only 414 of its 727 peers are within a slot (56.9%): the 237 peers that never answered status are silently absent from the denominator. Name the population ("...peers that answered a status request within a slot of the head", axis "Share of the client's status peers") or divide by peer_count if the all-peers share is what is wanted.

<div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
<SeriesCard
title="On all 64 subnets, by client"
title="Share of each client's peers on all 64 subnets"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 subnet share is of metadata responders, not all the client's peers

FctPeerAttnetCountByClClientDaily.peer_count is documented as the peers that answered a metadata request, which is the denominator here, so the value is a share among responders rather than "each client's peers" as titled and on the axis at 57. On 2026-11-10 caplin shows 9/407 = 2.2% while it is 9 of caplin's 727 seen peers (1.2%). Name the population (e.g. "...peers that answered metadata on all 64 subnets") so the card does not overstate the share of a client's peers.

/>
<SeriesCard
title="Seen all 30 days, by network type"
title="Share of each network type's peers seen all 30 days"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 "each network type" omits the unknown type the table carries

The card only plots the hosting and other rows, but fct_peer_churn_daily also has network_type = 'unknown' (2026-11-10: hosting 6741, other 7275, unknown 5), so "share of each network type's peers" describes more coverage than is drawn. Either add the unknown series or drop "each network type"; the axis wording at 108 ("Share of the type's peers") also reads vaguely without a type named on the card.

@redpandabot

redpandabot Bot commented Nov 12, 2026

Copy link
Copy Markdown

CI failed @ f36c6f5a

One failed job: Vet / Storybook Test (2/2). It failed because Vite dep-optimized zod/v4/core mid-run and reloaded, tearing down two in-flight suites; the PR's diff only changes title/yName strings in four network chart components and does not reach it.

  • Vet / Storybook Test 2/2 — flaky — Nondeterministic Vite dependency-optimizer reload during the sharded Storybook run. At 1:13:39 the log shows 'new dependencies optimized: zod/v4/core' (line 249), then '[vitest] Vite unexpectedly reloaded a test' (line 251) and 'optimized dependencies changed. reloading' (line 255). The two suites in flight are then reported with '(0 test)' and their setup files fail to import with 'Error: Vitest failed to find the runner' — @storybook/addon-vitest/dist/vitest-plugin/setup-file.js (line 356) for src/components/Charts/StackedBar/StackedBar.stories.tsx and .storybook/vitest-setup.ts (line 368) for src/components/Layout/ScrollArea/ScrollArea.stories.tsx. The summary still reports 'Tests 460 passed (460)' and shard 1/2 passed. The only zod/v4/core import in the repo is 'import { $ZodError } from 'zod/v4/core';' in src/pages/ethereum/clients/hooks/useDailyByClient.ts:3, and it is not pre-bundled because vitest.config.ts:60 lists only include: ['react-dom/client', 'zod/mini'] (same at vitest.config.unit.ts:38), so the first story that transitively loads that hook triggers a mid-run optimize and reload. This PR's diff (git diff origin/master...HEAD) touches only title/yName string literals in ChurnCharts.tsx, ReachabilityCharts.tsx, SubnetCharts.tsx and SyncCharts.tsx under src/pages/ethereum/network/components/ — no import or dependency change — and the two failing stories import only ./StackedBar / ./ScrollArea and their types. The later Vet run on chore/web-toolchain-hardening head 6c97ae8 (33 commits ahead of, and containing, this PR's base f776ef9, so including the same zod/v4/core import) passed both Storybook shards. (vitest.config.ts:60) — Add the missing dependency to the pre-bundling list in vitest.config.ts:60 (and mirror it in vitest.config.unit.ts:38): optimizeDeps: { include: ['react-dom/client', 'zod/mini', 'zod/v4/core'] }. Re-running the job alone will probably go green, but without this line it can recur whenever a client/network story lands in the shard.

Diagnosed Vet @ f36c6f5a
"Pets vs. cattle." — Bill Baker

@samcm
samcm merged commit 123ca50 into master Nov 12, 2026
8 of 10 checks passed
@samcm
samcm deleted the fix/network-share-chart-titles branch November 12, 2026 01:20
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