Repository navigation
feat(bb)!: build wasm with exception handling; node 26, wasi-sdk 34 - #25669
charlielye wants to merge 8 commits into
Conversation
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
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
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.
|
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
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
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_abortin 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_abortthrows a real C++ exception in wasm and bbapi answers with anErrorResponse, as it does natively.Changes
-fwasm-exceptions -mllvm -wasm-use-legacy-eh=falseand link-lunwind. The threaded target iswasm32-wasip1-threads(wasi-sdk 34 dropped the old name). Thewasmpreset no longer setsBB_NO_EXCEPTIONS;clang20-no-exceptionsstill does.inline(-Wunused-template), a scoped-Wno-c2y-extensionsfor google-benchmark.-Wexceptions=y -Wshared-memory=yalongside the thread flags, now inwasmtime.shand the bench and profile scripts. 46 is the last release with wasi-threads (-Sthreads); 47 and later reject it (Remove wasi-threads andwasi-commonfrom Wasmtime. bytecodealliance/rfcs#47).--experimental-transform-types, which node 26 dropped; type stripping is enough for the codegen scripts./opt/wasi-sdk, wasmtime 46.0.3, Playwright 1.63.0. Tags stay at 3.1 until the image is deployed.Transitional upgrade in bootstrap.sh
Until CI runs the new image and AMI,
transitional_toolchain_upgradein the rootbootstrap.sh(called fromprepandcheck, 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 passesPATHandPLAYWRIGHT_BROWSERS_PATHto isolated test containers, which mount$HOME. Inaztecprotocol/devbox:3.1the firstchecktakes 36 s and later ones about 3 s. Delete it once the image is rolled out.Measured
barretenberg.wasmgrows 5% (17.17 MB to 18.03 MB), 3.4% gzipped (3.88 MB to 4.01 MB).ecc_testsunder wasmtime (1016), the bb.js wasm suites on node 26, nativebbapi_testsandcommitment_schemes_tests. A wasm module with exceptions also ran in Chromium 153 without a flag.Not verified locally
PATH.~/.wasmtimewill reject the new flags until upgraded.🤖 Generated with Claude Code
https://claude.ai/code/session_01G5s7nEWrYapDK2CWpEzcAf