Skip to content

Viewer: what-if lab to fork a transaction (Script Lab) - #210

Open
satran004 wants to merge 1 commit into
viewer/debuggerfrom
viewer/fork
Open

satran004 wants to merge 1 commit into
viewer/debuggerfrom
viewer/fork

Conversation

@satran004

Copy link
Copy Markdown
Member

Stacked on #209. Part of #207: PR 4 of the Script Lab series, the what-if lab.

What users get

/transactions/{hash}/fork ("Fork this transaction" on the Scripts tab) rebuilds a transaction from Yaci Store and lets you change it. Every script runs again about a quarter of a second after each edit, next to the on-chain result.

What you can edit:

  • Redeemers of every script, and the datums of inputs being spent by scripts:
    • as JSON in the detailed schema ({constructor, fields}, {int}, {bytes}, {list}, {map}), with readable integers, or as raw CBOR
    • validated as you type, with per-field reset
  • Required signers: remove or add key hashes.
  • Validity range: from and until slots, with the UTC time shown; clear a field for no bound.
  • Outputs: address, lovelace and each token amount, or remove an output.
  • Mint (including new assets), withdrawals, fee.
  • Rules: another epoch's cost model, or protocol 10 or 11.

What you see:

  • Per script: on chain against fork, with status and CPU/memory, the % change, and Now passes / Now fails when an outcome flips.
  • Error and last trace of failing forks.
  • A summary: "2 changes · 1 outcome changed", with Reset.

What you can do with a run:

  • Debug the fork: opens the PR 3 debugger inline, on the forked run, and reopens it after each edit.
  • Export fixture: a JSON file with everything needed to run it again elsewhere:
    • script, target, cost model, limits
    • the VM arguments, ScriptContext CBOR
    • the expected result and the declared budget
    • the fork's edits

Nothing is submitted; the fork exists only in the browser.

How

  • replay/fork.ts: edits are applied to the store-shaped transaction before it is rebuilt. Ledger ordering, purposes, the julc#244 context corrections and the complete redeemer map therefore stay consistent for every script without special cases. Unit-tested on a recorded Mainnet transaction.
  • The debugger accepts a prepared run (prepared, syncUrl) for forks, and hides "Link to this step", since a fork isn't addressable by URL.
  • Older epochs have shorter cost models (Plutus V2: 175 parameters at epoch 500, against 332 now). julc runs protocol 10/11 rules, so it fills the newer builtins' costs with the maximum, and the lab explains this when you pick such an epoch.

Example (Mainnet withdraw-zero transaction 1da5cd…)

  • Setting the reward validator's redeemer to Constr 0 [] makes it Now fail (HeadList: empty list, −99% CPU); the two spend scripts are unaffected.
  • Epoch 500's cost model makes the reward validator 0.02% cheaper in CPU.
  • Protocol 10 gives the same budget as 11 for this transaction.

Not included

A julc-testkit Java snippet in the export. Loading a script from CBOR spans julc modules (one is in the decompiler), so a generated snippet would be fragile. The JSON fixture is language-neutral.

Tests

  • npm run check: 0 errors, 0 warnings.
  • vitest: 56 passing. New: fork edits for redeemers, an inline datum, signers, validity, fee, outputs, mint, withdrawals, protocol, another epoch's parameters.
  • Playwright script-lab.spec.ts: all 4 tests pass against a production build in Chrome. The new one covers an edit, the summary, invalid JSON, Reset and a fixture download.
  • 19 devnet smoke tests pass.

🤖 Generated with Claude Code

…ipt Lab)

/transactions/{hash}/fork rebuilds a transaction and lets you change it: redeemers and spent
datums (JSON in the detailed schema, or CBOR), required signers, the validity range, outputs
(address, ADA, tokens, removal), mint, withdrawals, fee, and the rules (another epoch's cost
model, protocol 10 or 11). Every script runs again shortly after each edit, next to the on-chain
result, with CPU/memory changes and "now passes" / "now fails" when an outcome flips.

- replay/fork.ts applies edits to the store-shaped transaction before it is rebuilt, so ledger
  order, purposes, the julc#244 context fixes and the redeemer map stay consistent.
- Forked runs open in the debugger inline (it now accepts a prepared run).
- Any run, on chain or forked, exports as a JSON fixture: script, target, cost model, limits,
  VM arguments, ScriptContext CBOR, expected result and the fork's edits.
- Older epochs' cost models are shorter; the lab says when julc fills the missing builtin costs.
- "Fork this transaction" link on the Scripts tab.

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

Copy link
Copy Markdown

Initial automated review · Aster

Hi @satran004, thanks for the PR! 🙏 This is an automatic first check by an AI reviewer. It does not replace maintainer review and may be wrong.

Reviewed commit: 087d5ab87e06966e423116707c3e983d8f2e9ba3

Issues found:

  • applications/viewer/src/lib/julc/fork/DataEditor.svelte:35 — Large JSON integers are silently changed before encoding: entering {"int":9007199254740993} runs the script with 9007199254740992, because JSON.parse has already rounded the number. Please reject unsafe numeric values and require quoted decimal strings, or use a lossless parser.
  • applications/viewer/src/lib/julc/fork/ForkLab.svelte:207 — Export remains enabled while a new edit is waiting for its rerun, so it combines the current edits/epoch with the previous run's arguments, cost model and expected result. Please export the snapshot associated with the completed run, or disable export throughout the debounce and evaluation.

Not tested: Static review only; type checks, Vitest, Playwright and live julc/Yaci Store execution were not run. GitHub reported no checks for this commit.

This branch has not been deployed

No deployments
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