Skip to content

Conversation

ymekuria
Copy link
Contributor

@ymekuria ymekuria commented Sep 2, 2025

Summary

Enables ZkProgram.compile({ cache }) to work in browsers. Previously, using a cache in web environments with a ZkProgram was disabled because the underlying lagrange basis functions were not compatible with the web worker API and would cause compilation to hang indefinitely.

Background

The ZkProgram.compile({ cache }) functionality was broken in browsers because:

  1. Lagrange basis functions returned WasmVector types incompatible with web worker transfer
  2. These functions were disabled in worker-spec.js to prevent hanging
  3. Cache writing would fail silently or hang when attempting to compute lagrange basis

Changes

  • Added 2 new pointer-based function registrations to worker-spec.js
  • Updated srs.ts with environment-aware getLagrangeBasis function
  • Automatically detects Node.js vs Web environments
  • Uses pointer functions in browsers, direct functions in Node.js

Related PRs

This is part 3 of 3 for the complete fix:

  1. proof-systems#3325 (Rust pointer functions)
  2. mina#17707 (submodule reference update)
  3. This PR: o1js (worker spec + TypeScript integration)

Testing

Manually tested in browser environment:

  • Created test project with zkProgram.compile() using a cache in the browser
  • Verified compilation completes successfully without hanging
  • Confirmed cache files are written (lagrange-basis-fp-*, etc.)
  • Pointer functions return valid memory addresses

- Register caml_fp_srs_get_lagrange_basis_ptr and _read_from_ptr functions
- Register caml_fq_srs_get_lagrange_basis_ptr and _read_from_ptr functions
- These enable zkProgram.compile() with cache writing in web environments
- Follows existing pointer pattern used by lagrange_commitments_whole_domain
- Phase 2 of 4: Worker spec registration complete
- Implement platform detection (Node.js vs Web) in getLagrangeBasis
- Web environments use new pointer-based functions (_ptr + _read_from_ptr)
- Node.js continues using original direct function call
- Update TODO comment to reflect fixed functionality
- Phase 3 of 4: TypeScript integration complete
CHANGELOG.md Outdated

- Internal o1js and protocol constants, hashes and prefixes are now exported via
the `Core´ namespace. https://github.com/o1-labs/o1js/pull/2421
- Added `caml_fp_srs_get_lagrange_basis_ptr` and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an implementation detail, I don't think it belongs in a changelog

CHANGELOG.md Outdated
https://github.com/o1-labs/o1js/pull/2388

- Fixed issue where `zkProgram.compile()` was not able to use a browser cache.
Previously, the `get_lagrange_basis` functions were disabled on the web
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, this is an implementation detail. Maybe replace get_lagrange_basis with a generic reading from cache..

@@ -1,1621 +1,4 @@
// @generated this file is auto-generated - don't edit it directly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these files shouldn't be part of this PR

args: [wasm.WasmFqSrs, undefined /* number */],
res: undefined /* number, ptr */,
},
// New get_lagrange_basis pointer functions for web compatibility
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this workaround, we should clean up caml_fp_srs_get_lagrange_basis a bit (see line 111 in this file)

if (cache.canWrite) {
// TODO: this code path will throw on the web since `caml_${f}_srs_get_lagrange_basis` is not properly implemented
// using a writable cache in the browser seems to be fairly uncommon though, so it's at least an 80/20 solution
// getLagrangeBasis now works on web via environment-aware pointer functions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: just removing the initial TODO comment here would have been enough to clarify this is now working on the web


if (isWeb) {
// Web: Use new pointer-based functions for worker compatibility
const ptr = wasm[`caml_${f}_srs_get_lagrange_basis_ptr`](srs, n);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it's cleaner to keep using the patter above for wasm functions
let getLagrangeBasisPtr = ..

@Trivo25
Copy link
Member

Trivo25 commented Sep 18, 2025

continuing the discussion on slack

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