Skip to content

plutus-wasm 1.65.0.0 — 32-bit-correct Plutus evaluator

Choose a tag to compare

@paolino paolino released this 10 Jun 20:14
· 19 commits to master since this release
d6b0a19

plutus 1.65.0.0, made correct and tested on wasm32 (WORD_SIZE_IN_BITS == 32).

Upstream Plutus assumes a 64-bit machine word; on wasm32 several default builtins silently diverge from
the on-chain (64-bit) evaluator. This release tracks upstream 1.65.0.0 with a small, CPP-gated stack
that makes wasm32 evaluation byte-identical to the chain — and proves it by running upstream's own
test suite under wasmtime.

What's verified

  • Full upstream suite green on wasm32 under wasmtime: plutus-core-test 2294, untyped-plutus-core-test
    870, plutus-ir-test 332, index-envs-test 36, satint-test 17, flat-test 1491. (flat-big-test
    is a multi-GB memory stress test, gated — incompatible with wasm32's address space.)
  • 64-bit neutrality: all changes are gated behind #if WORD_SIZE_IN_BITS == 64, so the source the
    node compiles is byte-identical to upstream. Verified: the affected suites pass on x86_64 unchanged.
  • UPLC deserialization is platform-independent (flat Word64 codec), so a script decodes identically on
    wasm32 and on-chain.

How to use it

1. As a source dependency (wallets, verifiers, anyone embedding the evaluator in their own wasm).
Pin this rev and cross-compile your own wasm with the corrected plutus linked in:

source-repository-package
  type: git
  location: https://github.com/lambdasistemi/plutus.git
  tag: d6b0a1988    # or: 1.65.0.0-wasm32
  subdir: plutus-core plutus-ledger-api plutus-tx

Builds are cached in the paolino cachix cache, so you pull the prebuilt wasm dep closure instead of
recompiling. This is how cardano-ledger-wasi and cardano-mpfs-offchain consume it.

Verified end-to-end: repinning cardano-ledger-wasi to this rev builds wasm-tx-inspector.wasm with
no API changes, and its tx.evaluate.scripts smoke evaluates real Plutus scripts on wasm32 →
ExUnits memory=376813, steps=369294715 (within budget).

2. As a standalone evaluator (no Haskell toolchain) — verified.
Download uplc.wasm from the assets and run the real CEK + cost model on a UPLC program:

printf '(program 1.0.0 [ [ (builtin addInteger) (con integer 40) ] (con integer 2) ])' > add.uplc
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc       # -> (con integer 42)
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc -c    # adds CPU budget: 181308 / Memory budget: 602

Runs the same under a browser WASI shim — the "real CEK in the browser" use case.

3. Reproduce the proof (verified end-to-end). Needs a checkout — the goldens / test/data live in
the source, not the .wasm:

git clone -b 1.65.0.0-wasm32 https://github.com/lambdasistemi/plutus && cd plutus
nix build .#wasm-plutus-core-test
WASMTIME=$(nix build --no-link --print-out-paths .#wasm-toolchain)/bin/wasmtime
( cd plutus-core && "$WASMTIME" run --dir . --dir /tmp \
    ../result/plutus-core-test.wasm --hedgehog-tests 1000 --no-create )
# -> All 2294 tests passed

To just build the artifact without cloning: nix build github:lambdasistemi/plutus/1.65.0.0-wasm32#wasm-plutus-core-test
— the ref is required (bare github:lambdasistemi/plutus resolves to the default branch, which has
no wasm targets). The 🕸️ Wasm32 Testsuite workflow (runs-on: nixos, cachix-cached) runs the full
matrix on every push.

Assets

  • uplc.wasm (24.6 MB) — the UPLC evaluator (real CEK + cost model) compiled to wasm32-wasi. Verified under wasmtime: evaluate -i <prog> → result; -c → result + ExBudget.
  • SHA256SUMS.