Skip to content

perf: stop wallets and contracts refetching UTxOs they already have - #853

Merged
twwu123 merged 5 commits into
feat/tx-builder-fetch-efficiencyfrom
feat/contract-wallet-fetch-efficiency
Oct 16, 2026
Merged

twwu123 merged 5 commits into
feat/tx-builder-fetch-efficiencyfrom
feat/contract-wallet-fetch-efficiency

Conversation

@lisicky

@lisicky lisicky commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

What

Stops wallets and contracts from fetching UTxOs they already have.

Stacked on #849, which adds CachedFetcher. Merge #849 first; this PR can then be retargeted to main.

Contents

mesh-transaction:

  • utxoToTxIn(utxo) now also returns the UTxO's reference script size: [txHash, outputIndex, amount, address, scriptSize]. txIn(...utxoToTxIn(utxo)) gives the builder everything it needs, so it no longer fetches a UTxO the caller passed in full.
  • Deprecated Transaction: setNativeScriptInput and the reference-script branch of redeemValue pass the script size. redeemValue also passes the reference script's hash, derived from scriptRef when the UTxO lacks scriptHash. Neither spend refetches its UTxOs any more.

mesh-contract:

  • All 27 txIn calls passed a full UTxO without its script size, so every script spend in every contract triggered a fetchUTxOs. They now use txIn(...utxoToTxIn(utxo)).
  • MeshTxInitiator wraps its fetcher in CachedFetcher.wrap. Looking up a UTxO with getUtxoByTxHash and then spending it costs one request, shared with the builder and wallet using the same provider.
  • Removed destructured variables in content-ownership that the rewrite left unused.

mesh-wallet:

  • MeshWallet and AppWallet wrap their fetcher in CachedFetcher.wrap. getUtxos() followed by getCollateral() used to fetch the same address twice; now it is one request. Address lookups are cached for 10 s.
  • submitTx clears that short-lived cache, so UTxOs read after a submit are fetched fresh.

Provider calls, before → after

Measured on ScalusEmulator behind a call-recording proxy: unlocking MeshHelloWorldContract, from getUtxoByTxHash through submit (mesh-contract/test/provider-calls.test.ts):

Call Before After
fetchUTxOs 2 1
fetchAddressUTxOs 2 1

The before column is measured on #849. Measured from main, there is also one fetchCostModels per transaction, which #849 removes.

Validation

npm run build:mesh
cd packages/mesh-contract && NODE_OPTIONS=--experimental-vm-modules npx jest
cd packages/mesh-wallet && npx jest
cd packages/mesh-transaction && NODE_OPTIONS=--experimental-vm-modules npx jest
  • mesh-contract: the new provider-calls.test.ts passes. It is the package's first test and needs @meshsdk/scalus-emulator as a devDependency, as mesh-transaction has. The lockfile change is that one line.
  • mesh-wallet: 34 tests pass, including the new fetcher-cache.test.ts.
  • mesh-transaction: 160 tests pass. script-tx-fetcher and script-tx-fail fail to load under --experimental-vm-modules on main too. Both pass without the flag, as do the test/transaction suites.

@twwu123
twwu123 merged commit f1a8cf4 into feat/tx-builder-fetch-efficiency Oct 16, 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