fix(app): cap holder counts - #1609
Merged
Merged
Conversation
SELECT COUNT(*) FROM ft_holders WHERE contract=... AND amount>0 was the single heaviest statement on the read replica: 15.9 million buffer accesses per call, 2.3s mean, and 289 billion buffer hits in total for one popular contract alone. That is 213x the next statement, and the replica is 99.6% cached, so it is CPU rather than disk. Count inside a LIMIT and run the result through cappedCount, matching what the transaction counts already do. Beyond maxQueryCount the response reads "10000+" instead of an exact figure; the schemas already type these as strings, so no schema change is needed. Applies to the FT, NFT and MT holder counts, which share the shape. Note mts/holderCount.sql is registered but currently unreferenced; it is capped for consistency, so any future caller must pass a limit.
Capping the API response meant the token overview cards and the FT FAQ received "10000+", and both passed it straight to numberFormat, which returns the literal string "NaN". The overview sits in the token layout, so that would have appeared on every tab of every FT, NFT and MT page whose holder set exceeds the cap: exactly the popular tokens the capping was aimed at. The holders tables were already correct, switching between holders.total and holders.totalExact via isApproxCount. approxCountFormat formats the number and re-appends the "+", so a capped count never reads as an exact figure. Using countFormat alone would have rendered "10,000" and stated a total we do not know to be true. Keeping the suffix in the value rather than the sentence avoids adding an approx variant to three namespaces across fourteen locales, and reads correctly in all of them.
The previous commit added an approxCountFormat helper that baked a "+"
into the value. Every other capped count in the app instead switches
translation keys on isApproxCount and formats with countFormat, so the
wording carries the approximation and the number stays a number:
t(isApproxCount(count) ? 'x.total' : 'x.totalExact',
{ count: countFormat(count) })
Used in eleven places including txns, receipts, keys, staking and the
holders tables themselves. Follow it rather than introduce a twelfth
style.
Adds holdersApprox ('More than {{count}}') to the FT, NFT and MT
overview namespaces and supplySplitApprox to the FT FAQ, across all
fourteen locales, matching how the existing total/totalExact pairs are
populated.
/v3/mts/{contract}/tokens/count has been capped since before this
branch (services/v3/mts/index.ts:220), but the contract overview passed
the value straight to numberFormat, which returns the literal string
"NaN" for "10000+". The row sits in the contract layout, so any MT
contract with more than 10000 tokens showed "Tokens: NaN" on both the
main page and the inventory tab.
Pre-existing on main and unrelated to the holder-count capping; found
while reviewing it. Same treatment as the holder counts, with a
tokensApprox key across all fourteen locales.
Swept the rest of the frontend for the same shape: the only other
numberFormat calls on a count field read block aggregates, which are
never capped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.