Skip to content

Dev to main - #681

Merged
alibabaedge merged 15 commits into
mainfrom
dev
Aug 7, 2026
Merged

Dev to main#681
alibabaedge merged 15 commits into
mainfrom
dev

Conversation

@alibabaedge

Copy link
Copy Markdown
Member

No description provided.

m1amgn and others added 15 commits July 28, 2026 17:09
Normalize the persisted average interval into seconds for signing-window duration estimates and classify block- versus slot-based networks in one place.

Reuse one typed Prisma chain selection across validator queries, including synthetic Aztec rows, so avgTxInterval is always present without growing the legacy service. Register focused tests for Cosmos values, millisecond chains, slot precedence, missing intervals, and invalid windows.
Replace the misleading lifetime header copy in every table namespace and add the previously missing network-nodes hint in English, Russian, and Portuguese.

Render the canonical block or slot window and approximate hours in all uptime and missed-block cell tooltips. Preserve localized Aztec attestation and proposal details, use no-time variants when intervals are unavailable, and omit tooltips when the window itself is invalid.
Return a typed translation descriptor from the pure missed-window utility so block/slot and time/no-time key selection has one canonical implementation.

The three server row components now translate that descriptor directly instead of repeating the same branching. Focused tests pin key selection, value formatting, and the no-window result.
Both sides appended new entries to the single-line "test" script in
package.json, so git could not reconcile them automatically. dev added the
Ethereum total-supply and TVS suites, this branch added the missed-window
suite; the resolution keeps all three and preserves the alphabetical order
of the file list.

No other file conflicted: the Ethereum FDV work touched only the ethereum
chain tools, .env.example and CLAUDE.md, while this branch touches the
validator/node tables, locale files, chain-service and src/utils.
…p-window

Fix/506 missed blocks tooltip window
FDV is supply times price and has no dependency on the validator set, but
getTvs aborted the whole snapshot whenever the Beacon request came back
empty. The supply had already been fetched successfully from Etherscan and
CoinGecko at that point and was discarded along with the empty node list,
so update-chain-tvs never wrote total_supply and update-fdv kept skipping on
its supply <= 0 guard. Ethereum FDV stayed at 0 in the networks table.

The Beacon endpoint fails for mainnet because its active-validator response
exceeds the V8 string limit (Cannot create a string longer than 0x1fffffe8
characters), so this is the steady state rather than a transient blip.

Staking figures now degrade to zero when the validator set is unavailable
while supply is still published. Bonded stake exceeding total supply is
treated the same way, so a ratio above 1 can never reach the database. The
only remaining abort is a missing supply, where returning null correctly
preserves the previous snapshot.

Verified end to end against a local database: chain-tvls wrote
120682557074402769230357351 wei and update-fdv computed 231410010015.74 USD
at a price of 1917.51.
The mainnet validator endpoint returns ~1 GB in a single response, so
res.json() could never materialise it and threw "Cannot create a string
longer than 0x1fffffe8 characters" — the V8 string limit is 512 MB. Three
retries burned 313 seconds every hour and always ended with an empty list,
which is why Ethereum had no validators, no TVS and no APR.

Server-side filtering does not help: ?status=active and ?status=active_ongoing
both return the full set byte for byte (1059431887 vs 1059448434), so the node
ignores the parameter. Of the 2.32M entries returned, 1.43M are withdrawal_done
and only ~890k are active.

Fold the response incrementally with stream-json instead. Memory stays flat —
15 MB heap and 156 MB RSS over the full gigabyte — and a live run now completes
in 107 seconds where it previously spent 313 seconds failing.

Mainnet no longer indexes validators one by one. jobs/get-nodes.ts issues
database queries per node, so a successful parse would mean ~890k round trips
and rows for a single chain; aggregate stake is streamed instead. Testnets keep
the per-node path, their sets being small enough to index.

Live verification: 2322293 validators streamed, 892032 bonded, bonded stake
41452485.77 ETH against a supply of 120682557.07 ETH, TVS 34.35%.

Note for review: the bonded figure follows the pre-existing definition in this
code (active* plus withdrawal_possible, using current rather than effective
balances). It could not be cross-checked against a public source — beaconcha.in
and ultrasound.money both require an API key now — and 34.35% sits above the
commonly quoted staked share, so the definition is worth a second look.
The tab lists transfers in and out of the wallet, so "Tokens" read as a
holdings view and set the wrong expectation. Its page title said "Token
Portfolio and Assets Holdings", which described a portfolio the tab never
showed.

Renames the tab label and the page title across all three locales. The route
stays /address/<addr>/tokens and the AccountPage.Tokens message namespace is
unchanged, so existing links keep working and the diff stays confined to the
strings a user actually sees.

Verified in a local render for en, ru and pt: tab reads Movements / Движения /
Movimentos and the title reads Token Movements / Движения токенов /
Movimentos de Tokens, with no missing-message fallbacks.
…from-nodes

Fix Ethereum FDV and stop the Beacon fetch from failing
Introduce a locale-aware formatter that caps regular token values at two fraction digits while preserving two significant digits for small non-zero amounts. Apply it to rich-list delegations, staking results, Monero fee and pool values, and the mining calculator; keep USD output in the localized currency formatter with a two-digit maximum. Register focused boundary and locale tests without changing prices, rates, technical metrics, or exact ledger-string displays.
Honor the existing link prop for boolean node-detail statuses and give icon-only anchors the localized row label as their accessible name. Point known Voting states to the validator voting summary, and build supported Send TX destinations from the curated message-type resolver with encoded repeatable query parameters. Keep unknown or unsupported states inert and add a round-trip filter test proving the Send query remains active after parsing.
Capping USD output at two fraction digits made small amounts render as
$0.00. The mining calculator shows a pool fee of one to two percent of a
daily payout, so any miner earning less than roughly half a dollar a day
saw the fee line collapse to zero; the same happened to dust delegations
in the validator rich list. Losing the value entirely is worse than the
long decimal tail the rounding was meant to remove.

formatCurrencyDecimal keeps the two-digit currency format but renders
anything below a cent as a bound - <$0.01, or >-$0.01 when negative,
since the calculator's net profit goes negative on unprofitable rigs.
This mirrors what formatDecimal already does for token amounts: never
round a non-zero value down to nothing.

The helper caches one Intl.NumberFormat per locale and currency. The
rich list builds a formatter per table row, so it was allocating one
instance per delegation on every render.
formatXmrReward cut the fractional part with slice(0, 4), so anything
below 0.0001 XMR rendered as "0.0000 XMR". A typical Monero transaction
fee is around 0.00003 XMR, which meant the fee column on the network
transaction list, the fee on a transaction page, and the per-transaction
fees inside an expanded block were all showing zero. The cut also
truncated rather than rounded, reporting 0.00029 as 0.0002.

Reusing formatDecimal fixes both: values at or above 0.01 keep two
fraction digits, smaller ones fall back to significant digits, so fees
stay readable and block rewards stay short.

Block rewards now read 0.61 XMR instead of 0.6086. The average reward
card on the blocks page formatted the same quantity with four digits of
its own, so it moves to the shared helper too - otherwise the list and
the block page disagreed about the same number.
…ckable-node-details

Fix/673 674 decimals and clickable node details
Node 20's undici/webstreams implementation has a race where an
AbortSignal.timeout() firing mid-response-body-read corrupts the
internal TransformStream (TypeError: controller[kState].transformAlgorithm
is not a function). Under load from failing LCD endpoints this piled up
into an event-loop livelock that took down validatorinfo-main-frontend.
Fixed upstream in Node after 24.18; moving both build stages there to
see whether the crash pattern recurs.
@alibabaedge
alibabaedge merged commit 3335f07 into main Aug 7, 2026
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