Skip to content

fix: show all MPT transactions, including Batches, past the issuer's recent history - #1385

Open
kuan121 wants to merge 9 commits into
mainfrom
fix/mpt-transactions-scan-to-creation
Open

kuan121 wants to merge 9 commits into
mainfrom
fix/mpt-transactions-scan-to-creation

Conversation

@kuan121

@kuan121 kuan121 commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

High Level Overview of Change

Fixes the MPT page's "All" tab missing transactions. It gave up about 550 transactions back in the issuer's history, and dropped Batch, Vault and LoanBroker transactions.

  • On a Clio host, account_tx is sent with mpt_issuance_id (Clio 2.8.0+, feat: Support filtering txns by mpt_issuance_id XRPLF/clio#3153), so the server returns only rows linked to the MPT, including rows linked only through metadata (Vault, LoanBroker). The browser doesn't filter them again.
  • Clio omits the outer Batch, so each parent Batch (from the inner rows' ParentBatchID) is fetched from the same Clio host and added after its inner transactions, as on the account page. This includes Batches sent by holders. The main host isn't used for this, since on testnet and devnet it's rippled with short history.
  • Without a Clio host (custom networks), the existing browser filter runs, and now also keeps a Batch whose inner transactions mention the MPT.
  • The page keeps reading until it has 20 matches, reaches the MPT's creation transaction, or has read 50 pages this round. "Load more" continues from there.
  • TablePicker is keyed by MPT, so going back to an MPT reuses its cache instead of refetching every page at once.
  • Hook fixes: stop auto-fetching after a failed page (after 2 retries), and don't stall between pages.

The IOU page is unchanged. This is a stopgap until Clio's mptoken_issuance_history is usable.

Context of Change

Reported on testnet: MPT 014BAF7C… shows "No transactions found." while its issuer's account page lists them. The page filtered the issuer's account_tx in the browser and stopped after 11 pages (550 transactions); this MPT's 6 transactions are about 1,540 back. The cap dates from #1264.

Why this approach:

  • The browser filter only searches each transaction's summary, so it misses metadata-only links and Batches. Clio's filter uses the same rule as its indexer, and the Clio hosts of all three deployed explorers run 2.8.0+.
  • mptoken_issuance_history stays disabled until the backfill in unmerged XRPLF/clio#3211 runs.
  • 250 issuer transactions per request, and at most 50 requests per round. Clio's limit caps transactions scanned, not rows returned, so a response grows with the number of matches. At 250, the densest mainnet MPT found (0627B685…, 182 of its issuer's newest 200 transactions match) peaks at 623 KB per response, under s2.ripple.com's 1 MB per 0.5 s limit; at 400 it reached 953 KB. The reported MPT needs 7 requests.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)

Codebase Modernization

  • Updated files to React Hooks
  • Updated files to TypeScript

The changed files were already hooks and TypeScript.

Before / After

MPT page "All" tab Before After
Reported MPT No transactions All 6, including its Batch
014BB4E5… (15 Batches) No Batch rows All 15 Batches
Vault and LoanBroker transactions Missing Shown
Page load At most 550 issuer transactions Until 20 matches, the creation transaction, or 50 pages
"No transactions found." Also shown when it stopped early Only at the creation transaction; otherwise "Try loading more transactions"

Test Plan

  • lint:ci, build-ts and test:ci pass after npm ci with CI's environment variables (313 suites, 1,910 tests).
  • New unit tests cover the server filter, Batch handling (including a real testnet Batch run through the real summarizer), the scan budget and the stop at creation.
  • Live checks with the real code: testnet Clio (both MPTs above), devnet Clio (8 Vault and LoanBroker types, and a holder's Batch older than the main host's history), and mainnet s2.ripple.com (20 pages, no rate limiting).
  • Browser (headless Chrome): a testnet build shows the Batch rows. A mainnet build on 0627B685… shows 231 rows on load and 514 after two "Load more" clicks, peaking at 641 KB per 0.5 s with no rate limiting. With 2 or 3 tabs on one IP (23 runs), account_tx was never rate limited and every tab showed all rows; the only slowDown replies were for the page's existing feature and server_info requests.

Known limits:

  • A holder's failed transactions aren't in the issuer's history; only mptoken_issuance_history would list them.
  • Loan transactions on a vault-share MPT aren't shown, since they don't change share holdings. main doesn't show them either.
  • A busy issuer with sparse matches can end a round with "Try loading more transactions".
  • A request the server never answers leaves the spinner running, as on main (no xrpl-client timeout).

Future Tasks

🤖 Generated with Claude Code

kuan121 and others added 3 commits November 5, 2026 11:26
The MPT page reads the issuer's account history and filters it for the
MPT, but stopped after 10 empty pages (550 transactions). MPTs whose
issuer kept transacting afterwards showed "No transactions found."

The MPT page now keeps reading until it reaches the issuance's
creation transaction, reads from the Clio server (full history on
testnet and devnet), and retries a failed page twice. The hook also
stops auto-fetching after a failure, which the old attempt cap hid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… set

The auto-fetch effect only re-ran when shouldAutoFetch changed. When a
page's fetching state and data land in the same render, shouldAutoFetch
stays true, the effect doesn't re-run, and the scan stalls. It showed up
under @testing-library/react 16 (the locked version), where the scan
stopped after two pages. Re-running the effect per loaded page fixes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fetchUntilEnd read every page back to the issuance's creation on page
load, so a busy MPT downloaded its whole history on every visit. Replace
it with minResults: auto-fetch, uncapped, until 20 matches are loaded or
the creation is reached, and have "Load more" fetch the next 20, skipping
empty pages.

Reset the target when the token changes, since the hook stays mounted
across MPT pages. Make the fake-timer tests let waitFor drive the clock,
and add a real-timer test for the per-page effect re-run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kuan121
kuan121 marked this pull request as ready for review November 5, 2026 19:53
kuan121 and others added 2 commits November 5, 2026 15:54
minResults kept auto-fetching until 20 matches loaded, with no limit on
non-matching pages. An issuer with a long run of unrelated transactions
(or anyone sending it many tiny payments) made every visit to an older
MPT read thousands of pages. Each round, the initial load or one "Load
more", now reads at most 50 pages; the budget resets on "Load more" and
when the token changes.

When the budget runs out before any match, the MPT page shows "Try
loading more transactions" instead of "No transactions found.", since
more history is left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Going back to an MPT already viewed refetched every cached page at once:
TablePicker stayed mounted, so react-query refetched the stale infinite
query on the key change, bypassing the 200 ms pacing. Key TablePicker by
MPT so it remounts and the cache is reused (refetchOnMount is off). Count
pages already cached as a finished round, so a remount onto a round left
unfinished waits for "Load more" instead of fetching.

Choose the P2P (Clio) socket in lib/rippled.ts via a useP2P flag, like
the other P2P commands, instead of in the hook with a cast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ripple-code-reviewer ripple-code-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found.

The IOU page read 20 issuer transactions per page and stopped after 10
empty pages (~220 transactions), so older IOU transactions were missed.
Use the same hook options as the MPT page: 50 per page, scan until 20
matches with a 50-page budget per round, read from the Clio host, retry
twice, and show "Try loading more transactions" when the budget runs
out. There is no stop at creation, since an IOU has no creation tx.

Key TablePicker by token, as on the MPT page. Without it, switching to
another currency got 1 request instead of a full round (the attempt
counter wasn't reset), and going back refetched every cached page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ripple-code-reviewer ripple-code-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found.

@kuan121 kuan121 changed the title fix: show MPT transactions beyond the issuer's 550 most recent fix: show MPT and IOU transactions beyond the issuer's recent history Nov 6, 2026
…ches

Ask the Clio (P2P) host to filter account_tx by the MPT. Only matching
rows are sent, and Clio matches through metadata too, so Vault and
LoanBroker transactions that change the MPT's balances now show. Rows
the server filtered aren't filtered again in the browser, which dropped
them. Hosts without a configured Clio connection (custom networks) get
no filter and keep the browser-side filter.

Clio returns a Batch's inner transactions but not the Batch, so add each
parent Batch (via ParentBatchID) after its last inner transaction, as the
account page lists them. Without the server filter, keep a Batch whose
inner transactions mention the token; its summary drops them.

Revert the IOU page to main: the filter is MPT-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ripple-code-reviewer ripple-code-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found.

@kuan121 kuan121 changed the title fix: show MPT and IOU transactions beyond the issuer's recent history fix: show all MPT transactions, including Batches, past the issuer's recent history Nov 6, 2026
The parent Batch was looked up on the main host. On testnet and devnet
that is rippled with short history, so a Batch older than it was
silently dropped while its inner rows, from Clio, still showed. Give
getTransaction the same useP2P flag as getAccountTxs and look the
Batch up on the Clio host the rows came from.

Drop three tests that duplicate stronger ones: two mocked Batch filter
tests (covered by the real-Batch test) and a main-socket default test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ripple-code-reviewer ripple-code-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found.

With Clio filtering by MPT, a response holds only matching rows, so a
larger page mostly saves requests. Measured: the reported testnet MPT
needs 7 requests instead of 33, and the densest mainnet MPT found
(0627B685…, 182 of 200 issuer transactions match) peaks at 623 KB per
response, under s2.ripple.com's 1 MB per 0.5 s limit. 400 reached
953 KB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ripple-code-reviewer ripple-code-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found.

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.

1 participant