mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
the validators page counts every network, not just this one
Zoo and Hanzo run as L2s on the primary network, Pars and Osage as their own L1s, so "how many validators secure Lux" is a question about all of them. The Validators page answered with this chain's 6 while the landing page said 21 — same word, two quantities, one site, and no way for a reader to tell which question either was answering. Both numbers were right. The page now shows every network with its own count beside the total, and says how many answered so a partial sum is never read as the whole. A network that cannot be read is still listed: dropping it would make it look like a network with no validators. The stake beside the landing-page total names its network now. Stake stays primary-only — each network bonds its own currency and the sum of two currencies is not a quantity — so leaving it unlabelled next to an all-network validator count invited reading the two as one ratio.
This commit is contained in:
@@ -262,10 +262,12 @@ const NetworkOverview = () => {
|
||||
'py-4 px-4 gap-x-6 gap-y-3 border border-[var(--color-border-divider)]',
|
||||
'bg-[var(--color-stats-bg)]',
|
||||
) }>
|
||||
{ /* Every L1 in the registry, not just this chain. The breakdown is
|
||||
in the Validators card below. Stake stays primary-network only:
|
||||
each chain bonds its own currency and the sum of two currencies
|
||||
is not a quantity. */ }
|
||||
{ /* Every network's validators, which is the number a reader wants:
|
||||
the fleet securing Lux is not just the primary network's share
|
||||
of it. Stake stays primary-only beside it because each network
|
||||
bonds its own currency and the sum of two currencies is not a
|
||||
quantity \u2014 so the label says which network the stake is for
|
||||
rather than letting the two be read as one ratio. */ }
|
||||
<Metric
|
||||
label={ allValidators.answeredCount === allValidators.queriedCount ? 'Validators' : 'Validators (partial)' }
|
||||
value={ allValidators.isKnown ? String(allValidators.total) : '\u2014' }
|
||||
@@ -273,7 +275,7 @@ const NetworkOverview = () => {
|
||||
/>
|
||||
<div className="w-px h-7 hidden md:block bg-[var(--color-border-divider)]"/>
|
||||
<Metric
|
||||
label="Staked"
|
||||
label={ `Staked on ${ config.chain.name || 'primary' }` }
|
||||
value={ hasValidatorData ?
|
||||
`${ formatStake(stats.totalStake) } ${ config.chain.currency.symbol || 'LUX' }` :
|
||||
'\u2014' }
|
||||
|
||||
@@ -3,6 +3,8 @@ import React from 'react';
|
||||
|
||||
import config from 'configs/app';
|
||||
import type { PChainValidator, ValidatorStats } from 'lib/api/pchain';
|
||||
import { useNetworkValidators } from 'lib/api/pchain/useNetworkValidators';
|
||||
import { cn } from 'lib/utils/cn';
|
||||
|
||||
import { formatStake, truncateNodeId } from './utils';
|
||||
|
||||
@@ -20,6 +22,62 @@ const UNKNOWN = '\u2014';
|
||||
const TOP_VALIDATORS_COUNT = 20;
|
||||
const PERCENTAGE_SCALE = 100;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Every network's validators
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// The cards above count THIS chain. Zoo and Hanzo run as L2s on the primary
|
||||
// network and Pars and Osage as their own L1s, so a reader who wants to know
|
||||
// how much iron is behind Lux needs all of them — a page titled "Validators"
|
||||
// that shows one network's share is answering a narrower question than the one
|
||||
// being asked.
|
||||
//
|
||||
// Every network is listed, including ones that did not answer. A chain dropped
|
||||
// from the list would read as a chain with no validators, and the total says
|
||||
// how many answered so a partial sum is never mistaken for the whole.
|
||||
const NetworkValidators = () => {
|
||||
const { networks, total, isKnown, isLoading, answeredCount, queriedCount } = useNetworkValidators();
|
||||
|
||||
if (networks.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-[var(--color-border-divider)] p-4">
|
||||
<div className="flex items-baseline justify-between mb-3">
|
||||
<span className="text-sm font-medium">All networks</span>
|
||||
<Skeleton loading={ isLoading }>
|
||||
<span className="font-mono text-sm">
|
||||
{ isKnown ? total.toLocaleString() : UNKNOWN }
|
||||
{ answeredCount !== queriedCount && (
|
||||
<span className="ml-2 text-2xs text-[var(--color-text-secondary)]">
|
||||
{ answeredCount } of { queriedCount } answered
|
||||
</span>
|
||||
) }
|
||||
</span>
|
||||
</Skeleton>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
{ networks.map((network) => (
|
||||
<div key={ network.chainId } className="flex items-center justify-between text-xs">
|
||||
<span className="text-[var(--color-text-secondary)]">{ network.name }</span>
|
||||
<Skeleton loading={ network.isLoading }>
|
||||
<span className={ cn(
|
||||
'font-mono',
|
||||
network.status === 'live' ?
|
||||
'text-[var(--color-text-primary)]' :
|
||||
'text-[var(--color-text-secondary)]',
|
||||
) }>
|
||||
{ network.status === 'live' ? network.validatorCount : network.status }
|
||||
</span>
|
||||
</Skeleton>
|
||||
</div>
|
||||
)) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Stat card
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -201,6 +259,9 @@ const ValidatorsDashboard = ({ validators, stats, isLoading, isKnown }: Validato
|
||||
/>
|
||||
</div>
|
||||
|
||||
{ /* Every network, not just this one */ }
|
||||
<NetworkValidators/>
|
||||
|
||||
{ /* Stake breakdown */ }
|
||||
<StakeBreakdown stats={ stats } isLoading={ isLoading } isKnown={ isKnown }/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user