Skip to content

feat(bb)!: build wasm with exception handling; node 26, wasi-sdk 34 - #25669

Open
charlielye wants to merge 8 commits into
nextfrom
cl/wasm-eh-vm2-sim
Open

charlielye wants to merge 8 commits into
nextfrom
cl/wasm-eh-vm2-sim

Conversation

@charlielye

@charlielye charlielye commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Builds every barretenberg wasm with wasm exception handling, and moves the toolchain to node 26.12.0 and wasi-sdk 34 (LLVM 23), so there is one version of each in play.

Why

  • throw_or_abort in wasm used to call a JS import that throws a JS error. That unwinds the module without running C++ catch blocks or destructors, so bbapi could not turn a failure into an error response and bb.js logged the call as aborted. With exceptions on, throw_or_abort throws a real C++ exception in wasm and bbapi answers with an ErrorResponse, as it does natively.
  • It unblocks the AVM simulator in wasm, which relies on catching exceptions. That build, and a bb-avm-sim package with a wasm backend, is a separate PR.

Changes

  • CMake: wasm builds always compile with -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false and link -lunwind. The threaded target is wasm32-wasip1-threads (wasi-sdk 34 dropped the old name). The wasm preset no longer sets BB_NO_EXCEPTIONS; clang20-no-exceptions still does.
  • LLVM 23 fixes: three header templates made inline (-Wunused-template), a scoped -Wno-c2y-extensions for google-benchmark.
  • wasmtime 46.0.3: needs -Wexceptions=y -Wshared-memory=y alongside the thread flags, now in wasmtime.sh and the bench and profile scripts. 46 is the last release with wasi-threads (-Sthreads); 47 and later reject it (Remove wasi-threads and wasi-common from Wasmtime. bytecodealliance/rfcs#47).
  • Node 26: removed --experimental-transform-types, which node 26 dropped; type stripping is enough for the codegen scripts.
  • Playwright 1.63.0 (Chromium 153), which runs exnref wasm without a flag. Unflagged support: Chrome 137, Firefox 131, Safari 18.4.
  • Build image: node 26, wasi-sdk 34 at /opt/wasi-sdk, wasmtime 46.0.3, Playwright 1.63.0. Tags stay at 3.1 until the image is deployed.
  • bb.js: new test that an error response arrives without the module aborting. It fails on the old wasm.

Transitional upgrade in bootstrap.sh

Until CI runs the new image and AMI, transitional_toolchain_upgrade in the root bootstrap.sh (called from prep and check, only in CI or the devbox) installs wasi-sdk 34 at /opt/wasi-sdk, and node, wasmtime and Playwright's Chromium under $HOME/.cache/aztec-transitional-toolchains. It passes PATH and PLAYWRIGHT_BROWSERS_PATH to isolated test containers, which mount $HOME. In aztecprotocol/devbox:3.1 the first check takes 36 s and later ones about 3 s. Delete it once the image is rolled out.

Measured

  • barretenberg.wasm grows 5% (17.17 MB to 18.03 MB), 3.4% gzipped (3.88 MB to 4.01 MB).
  • UltraHonk 2^20 proving under wasmtime at 16 threads: no difference beyond noise.
  • Passing: threaded ecc_tests under wasmtime (1016), the bb.js wasm suites on node 26, native bbapi_tests and commitment_schemes_tests. A wasm module with exceptions also ran in Chromium 153 without a flag.

Not verified locally

  • A full CI run, including isolated containers picking up the injected PATH.
  • The Dockerfile build and arm64 downloads.
  • yarn-project on node 26.
  • Remote bench machines, whose own ~/.wasmtime will reject the new flags until upgraded.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf

Every bb wasm build compiled with -fno-exceptions, so throw_or_abort called out to the JavaScript environment, whose
throw unwound the module without running catch blocks or destructors, and the AVM simulator (which signals
exceptional halts with C++ exceptions) could not build for wasm at all. wasi-sdk 33+ ships a sysroot with a C++
exception runtime, so the wasm and wasm-threads builds now use standard (exnref) wasm exception handling, and the
toolchains move to versions that run it unflagged.

bb wasm
- arch.cmake: -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false, linked with -lunwind, in place of
  -fno-exceptions. The wasm preset drops -DBB_NO_EXCEPTIONS and sets AVM off.
- throw_or_abort throws std::runtime_error inside the module in wasm builds with exceptions, so bbapi answers with an
  ErrorResponse, as it does natively. bb.js's exception test now also checks the module no longer aborts (it fails on
  the old wasm).
- The wasm build adds aztec, world_state_reference, vm2 (vm2_sim only) and crypto/merkle_tree, and the wasm build
  preset builds vm2_sim_smoke. That runs one hinted public transaction (vm2/testing/minimal_tx.testdata.bin) through
  AvmSimAPI::simulate_with_hinted_dbs after checking a TagMismatchException is caught;
  scripts/vm2_sim_smoke_test.sh runs it natively and in wasm under node and requires identical results. It runs in
  the default bb test_cmds.
- wasm32 fixes in the simulator and the in-memory trees, where size_t is 32-bit: contract_crypto shifted a size_t
  by 32, which is undefined on wasm32 and would corrupt the first bytecode field; index_t to size_t casts in the
  in-memory indexed trees and their callers; ptrdiff_t in to_radix.
- LLVM 23 (wasi-sdk 34) fixes: wasm32-wasip1-threads in place of the removed wasm32-wasi-threads target; missing
  <algorithm> and <cstdlib> includes; static function templates in headers made inline (-Wunused-template);
  -Wno-c2y-extensions for google-benchmark, which builds with -pedantic-errors and uses __COUNTER__.
- barretenberg.wasm grows 5% (17.17 MB to 18.03 MB), 3.4% gzipped (3.88 MB to 4.01 MB). UltraHonk 2^20 proving under
  wasmtime showed no difference beyond noise.

Toolchains (build image and scripts/setup-container.sh)
- node 24.15.0 to 26.12.0 (.nvmrc, bootstrap's expected minimum and install_node). Node 26 removed
  --experimental-transform-types; the ipc-codegen callers only need type stripping, so it is dropped.
- wasi-sdk 27 to 34 at /opt/wasi-sdk.
- wasmtime 20.0.2 to 46.0.3, the last release with wasi-threads (-Sthreads), which the threaded wasm tests and
  benchmarks use. Its invocations add -Wexceptions=y and -Wshared-memory=y.
- playwright 1.49 to 1.63.0 (Chromium 153; exnref is unflagged from Chrome 137), in the image and headless-test.

The CI image is not redeployed here. Until it is, the root bootstrap's transitional_toolchain_upgrade (run by prep and
check, in CI or the devbox) installs wasi-sdk 34 at /opt/wasi-sdk and node, wasmtime and playwright's chromium under
$HOME, passing PATH and PLAYWRIGHT_BROWSERS_PATH through to isolated test containers. In devbox:3.1 it takes about
36s the first time and 3s after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
@socket-security

socket-security Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​playwright@​1.49.0 ⏵ 1.63.0100 +1100 +1610099 +180 -19

View full report

@socket-security

socket-security Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Priority Alert  (click "▶" to expand/collapse) Action
Low priority
Potential security risk (AI signal): npm playwright-core is 70.0% likely risky

Notes: No evidence of obfuscated or overtly malicious logic (no persistence, exfiltration, or credential theft) appears in the provided snippet. However, it implements a high-risk supply-chain pattern: it downloads an MSI from a URL provided at runtime and installs it silently via msiexec without any integrity or origin verification. If an attacker can influence $args[0] or the referenced endpoint, this script can facilitate arbitrary MSI payload execution on the host.

Confidence: 0.70

Severity: 0.72

From: barretenberg/acir_tests/headless-test/package.json → npm/playwright@1.63.0 → npm/playwright-core@1.63.0

ℹ Read more on: This package | This alert | What are AI-detected potential security risks?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system identified potential security problems in this package. It is advised to review the package thoroughly and assess the potential risks before installation. You may also consider reporting the issue to the package maintainer or seeking alternative solutions with a stronger security posture.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/playwright-core@1.63.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Potential security risk (AI signal): npm playwright-core is 76.0% likely risky

Notes: This module is a straightforward installer wrapper, but it has a high supply-chain trust boundary risk: it downloads an MSI from a caller-provided URL and silently executes it via msiexec without any integrity/signature validation or URL allowlisting. There is no clear evidence of hidden malware in the visible code, but the execution pattern can enable malicious installer delivery if the URL/contents are compromised or attacker-controlled.

Confidence: 0.76

Severity: 0.74

From: barretenberg/acir_tests/headless-test/package.json → npm/playwright@1.63.0 → npm/playwright-core@1.63.0

ℹ Read more on: This package | This alert | What are AI-detected potential security risks?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system identified potential security problems in this package. It is advised to review the package thoroughly and assess the potential risks before installation. You may also consider reporting the issue to the package maintainer or seeking alternative solutions with a stronger security posture.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/playwright-core@1.63.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Potential security risk (AI signal): npm playwright-core is 78.0% likely risky

Notes: This module is a generic “download-and-silent-install MSI” bootstrapper where the critical control point (the download URL) is fully caller-controlled and the fragment lacks any integrity/signature verification of the downloaded MSI before executing it via msiexec. While there is no explicit backdoor/exfiltration code in the fragment, the combination of (a) arbitrary remote MSI acquisition and (b) silent installer execution makes it a high-risk supply-chain pattern if $args[0] can be influenced or if download provenance cannot be guaranteed externally.

Confidence: 0.78

Severity: 0.78

From: barretenberg/acir_tests/headless-test/package.json → npm/playwright@1.63.0 → npm/playwright-core@1.63.0

ℹ Read more on: This package | This alert | What are AI-detected potential security risks?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system identified potential security problems in this package. It is advised to review the package thoroughly and assess the potential risks before installation. You may also consider reporting the issue to the package maintainer or seeking alternative solutions with a stronger security posture.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/playwright-core@1.63.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

This PR keeps to the toolchain and exception handling. The vm2_sim_smoke
program, its test, the vm2-in-wasm CMake and the wasm32 fixes in the
simulator move to the PR that builds bb-avm-sim as a wasm module for its
generated package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
supertest 6 resets the second of two concurrent requests on Node 26,
which fails safe_json_rpc_client.test.ts. Carried until the aztec-node
PR with the same change lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
charlielye and others added 5 commits October 21, 2026 16:00
Chromium 131 from playwright 1.49 cannot compile bb's exnref wasm, which
fails chonk_browser.test.ts, and the 1.49 pins point at browsers the CI
image no longer installs. Carried until the aztec-node PR with the same
change lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
chonk_browser.test.ts launches puppeteer with playwright's
chromium.executablePath(), which is the full chromium build. The
transitional install only fetched the headless shell, so the path was
missing and puppeteer fell back to a Chrome nobody installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
The images built from this Dockerfile (node 26, wasi-sdk 34, wasmtime 46,
playwright 1.63.0) go out as 3.2 so 3.1 keeps serving next and every
other branch. CI, isolated tests, the AMI pre-pull and the devcontainer
all move to 3.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf
The 3.2 build images and AMIs ship node 26.12.0, wasi-sdk 34, wasmtime
46.0.3 and playwright 1.63.0's browsers, so CI no longer needs to
upgrade the 3.1 image in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf

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.

1 participant