Reported from the demo page:
Access to fetch at 'https://explorer.runonflux.io/api/txs?address=t1ebxupkNYVQiswfwi7xBTwwKtioJqwLmUG&pageNum=17'
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
GET .../api/txs?address=t1ebxupk...&pageNum=17 net::ERR_FAILED 429 (Too Many Requests)
Two things to say about it.
The CORS message is a lie, and we already know that
Per the comment block at the top of client/src/explorer.js: a rate-limited explorer response omits the CORS headers, so the browser refuses to surface the 429 to JS and reports a CORS violation instead. Every one of those errors is a rate limit wearing a CORS costume. Nothing is misconfigured. The 429 on the next line is the real error.
The real bug: the donation scan is unbounded
client/src/api/globalStats.js:245 — scanDonationAddress():
const { pagesTotal } = firstPage;
const pageNums = pagesTotal <= 1 ? [] : new Array(pagesTotal - 1).fill(0).map((_v, i) => i + 1);
for (const page of pageNums) {
const json = await explorerFetchJson(`${basePath}&pageNum=${page}`);
...
}
There is no page cap and no date window. It walks the complete lifetime transaction history of the address, and scanBothDonationAddresses() then does it for both the current and old donation addresses on every page load. pageNum=17 in the report is it climbing, and the old address t1ebxupk...LmUG has years of history.
Compare client/src/donor/donorStatus.js, which scans the same endpoint and is careful about exactly this:
while (!hitWindowEdge && pageNum < pagesTotal && pageNum < DONOR_MAX_PAGES_FETCHED)
with DONOR_MAX_PAGES_FETCHED = 20 and DONOR_WINDOW_DAYS = 365 — it stops as soon as it reaches a transaction older than the window. The donation-total scan was never given the same treatment.
Consequences
- Home's donation total is one of the first things fetched, so it burns the explorer budget that donor verification, chain activity and the wallet lookup then need — self-inflicted rate limiting.
- It gets slower every month, forever, as the addresses accumulate history.
- The console noise makes every genuine CORS/explorer problem harder to spot.
Suggested fix
Give scanDonationAddress the same two bounds donorStatus.js already has — a page cap and an early exit once transactions pass the window of interest. Worth checking against #258 first for what window the Home total is actually supposed to cover: if it is meant to be all-time, the answer is probably to cache the total rather than to recompute it from page 1 on every load.
Relates to #270. Split from the web-vitals console error reported alongside it (#313), which is a separate and probably-not-ours problem.
Reported from the demo page:
Two things to say about it.
The CORS message is a lie, and we already know that
Per the comment block at the top of
client/src/explorer.js: a rate-limited explorer response omits the CORS headers, so the browser refuses to surface the 429 to JS and reports a CORS violation instead. Every one of those errors is a rate limit wearing a CORS costume. Nothing is misconfigured. The429on the next line is the real error.The real bug: the donation scan is unbounded
client/src/api/globalStats.js:245—scanDonationAddress():There is no page cap and no date window. It walks the complete lifetime transaction history of the address, and
scanBothDonationAddresses()then does it for both the current and old donation addresses on every page load.pageNum=17in the report is it climbing, and the old addresst1ebxupk...LmUGhas years of history.Compare
client/src/donor/donorStatus.js, which scans the same endpoint and is careful about exactly this:with
DONOR_MAX_PAGES_FETCHED = 20andDONOR_WINDOW_DAYS = 365— it stops as soon as it reaches a transaction older than the window. The donation-total scan was never given the same treatment.Consequences
Suggested fix
Give
scanDonationAddressthe same two boundsdonorStatus.jsalready has — a page cap and an early exit once transactions pass the window of interest. Worth checking against #258 first for what window the Home total is actually supposed to cover: if it is meant to be all-time, the answer is probably to cache the total rather than to recompute it from page 1 on every load.Relates to #270. Split from the web-vitals console error reported alongside it (#313), which is a separate and probably-not-ours problem.