Skip to content

fix: page the ACS snapshot for holdings reads - #8

Merged
gabitoesmiapodo merged 3 commits into
mainfrom
fix/holdings-single-acs-query
Sep 2, 2026
Merged

fix: page the ACS snapshot for holdings reads#8
gabitoesmiapodo merged 3 commits into
mainfrom
fix/holdings-single-acs-query

Conversation

@gabitoesmiapodo

Copy link
Copy Markdown
Collaborator

Summary

No related issue.

Every balance read replayed the whole ledger update stream, thousands of requests each time. That tripped the validator's rate limit, which answered with an nginx 503 page the wallet then showed to the user.

Changes

  • Holdings reads page the participant's active contract snapshot instead of replaying ledger updates
  • A holding whose interface view is missing now fails the read instead of being dropped from the total
  • Listing holdings and summarizing them share one read

Deviations

  • Grouping inside the holding summary no longer rebuilds an array per holding, since this is now the only balance path when Scan is unavailable

Acceptance criteria

  • A balance read costs a handful of requests, not thousands
  • A party holding more contracts than the participant returns in one response is still read in full
  • Holding summaries, pending transfers and the rest of the RPC surface answer as before

Test plan

Automated tests

  1. Run pnpm install
  2. Run pnpm test
  3. Expect 91 passing tests, no failures

Manual verification

  1. On the devnet droplet, check out this branch and run docker compose up --build -d
  2. On the validator host, run grep -c "POST /v2/updates" /var/log/nginx/access.log and note the number
  3. Open the wallet and load a party's balance
  4. Run the same count again on the validator host
  5. Expect the balance to show, the count to be unchanged, and no 503

Breaking changes

None.

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

Screenshots

None.

sdk.token.utxos.list was called with continueUntilCompletion, which makes
core-acs-reader replay the whole update stream in 100-record pages instead of
querying the active contract set once. Every balance read fired thousands of
POST /v2/updates and tripped the validator ingress rate limit, which answered
503 and surfaced an nginx error page in the wallet.

The client-side limit goes with it: it truncates the snapshot silently, while
the participant's own http-list-max-elements-limit answers 413 instead.
sdk.token.utxos.list offers two shapes and neither answers "every holding":
with continueUntilCompletion it replays the whole update stream in 100-record
pages, and without it the read is a single response bounded by the
participant's http-list-max-elements-limit.

Read /v2/state/active-contracts-page directly instead, following nextPageToken
against an offset pinned by the first request, which is complete regardless of
that cap and costs one request per page rather than thousands per read.
Hoists the event format out of the read, drops a conditional spread that
JSON.stringify already handles, and ends the loop on an empty page token as
well as a missing one, which the participant documents as possible.

A holding whose interface view is absent now fails the read rather than being
skipped, since skipping it understates a balance. Grouping in
summarizeHoldingUtxos pushes instead of rebuilding each group array, which
matters now that this is the only balance path when Scan is unavailable.
@gabitoesmiapodo gabitoesmiapodo self-assigned this Sep 2, 2026
@gabitoesmiapodo
gabitoesmiapodo merged commit 8830ac4 into main Sep 2, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Canton - dAppBooster (#390) Sep 2, 2026
@gabitoesmiapodo
gabitoesmiapodo deleted the fix/holdings-single-acs-query branch September 3, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant