Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2933e08
feat(bb.js): generated bb.js-api package with an in-process wasm tran…
charlielye Sep 9, 2026
6cafd81
refactor(ipc-codegen): imply --out from --package
charlielye Sep 9, 2026
1434011
feat(ipc-codegen): prefix FFI symbols with the service name
charlielye Sep 9, 2026
428e22c
feat(ipc-codegen): backend policy in the generated package; bb.js dro…
charlielye Sep 9, 2026
4496785
fix(ipc-codegen): package README describes only the backends the pack…
charlielye Sep 9, 2026
dbe22bc
fix(barretenberg): order the cross-copy targets that share node_modules
charlielye Sep 9, 2026
5cd1880
refactor(ipc-runtime): create wasm threads on demand
charlielye Sep 9, 2026
f1d496b
perf(ipc-runtime): reuse one request buffer and the memory views per …
charlielye Sep 9, 2026
d4256b9
refactor(ipc-runtime): share the platform entries, drop the allocator…
charlielye Sep 9, 2026
2811f17
refactor(ipc-runtime): split the wasm host code into node/ and browser/
charlielye Sep 9, 2026
8055180
docs(ipc-codegen): state which thread a wasm call runs on
charlielye Sep 9, 2026
2c3b7e9
fix(ipc-runtime): use the module's own memory when it exports one
charlielye Sep 9, 2026
6ff9b7a
fix(ipc-codegen): apply the engine's thread cap when resolving a default
charlielye Sep 9, 2026
d6eb4fc
feat(bb.js): ship the wasm modules uncompressed
charlielye Sep 10, 2026
5b98d91
refactor(ipc-codegen): move the generated package's logic into ipc-ru…
charlielye Sep 10, 2026
7a7dd0c
refactor(ipc-codegen): move the backend registry and arch-package sta…
charlielye Sep 10, 2026
7930421
refactor: move the curve constants out of ipc-codegen into bb.js
charlielye Sep 10, 2026
3aedd54
fix(ipc-codegen): remove generated files the generator no longer emits
charlielye Sep 10, 2026
c3b0491
refactor(bb.js): drop code the move to bb.js-api left behind
charlielye Sep 10, 2026
4ea4e89
docs(bb.js): credit the parent-death watch to ipc-runtime, not bb
charlielye Sep 10, 2026
cbe3580
fix(ipc-runtime): make unref mean what it says, and be one option
charlielye Sep 10, 2026
ef3a240
refactor(bb.js): lay the package out so it reads
charlielye Sep 10, 2026
880a941
chore(bb.js): drop the dead half of the CJS post-process
charlielye Sep 10, 2026
036f49d
refactor(bb.js): trim BBApiException to what it does
charlielye Sep 10, 2026
c395e73
refactor(ipc-codegen): generate the error class, drop the error factory
charlielye Sep 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ bb-cpp-full: bb-cpp bb-cpp-gcc bb-cpp-fuzzing bb-cpp-windows bb-cpp-asan bb-cpp-
bb-ts: bb-cpp-wasm bb-cpp-wasm-threads bb-cpp-native ipc-runtime
$(call build,$@,barretenberg/ts,build_bb_js)

# Copies the cross-compiles into bb.js.
# Copies the cross-compiles into bb.js (its NAPI module) and bb.js-api (the bb binaries).
bb-ts-cross-copy: bb-ts bb-cpp-cross
$(call build,$@,barretenberg/ts,cross_copy_bb_js)

Expand All @@ -270,10 +270,10 @@ bb-ts-cross-copy: bb-ts bb-cpp-cross
bb-avm-sim: ipc-codegen ipc-runtime bb-cpp-native bb-ts
$(call build,$@,barretenberg/ts,build_bb_avm_sim)

# Ordered after bb-cdb for the same reason bb-cdb is ordered after bb-avm-sim:
# all three regenerate the same barretenberg/ts workspaces and install into the
# same node_modules.
bb-avm-sim-cross-copy: bb-avm-sim bb-cdb bb-cpp-cross
# Ordered after bb-cdb (and after bb-ts-cross-copy, which builds bb.js-api's cross copies)
# for the same reason bb-cdb is ordered after bb-avm-sim: they all regenerate the same
# barretenberg/ts workspaces and install into the same node_modules.
bb-avm-sim-cross-copy: bb-avm-sim bb-cdb bb-ts-cross-copy bb-cpp-cross
$(call build,$@,barretenberg/ts,cross_copy_bb_avm_sim)

# Generated @aztec-foundation/cdb server bindings. Ordered after bb-avm-sim rather than run
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ add_library(
)

# bb-external: static library for external consumers (e.g. barretenberg-rs).
# Uses the core object list without lmdb/world_state — FFI consumers only need ipc_ffi_entry().
# Uses the core object list without lmdb/world_state — FFI consumers only need bb_ipc_ffi_entry().
# Built with -fvisibility=hidden; only WASM_EXPORT symbols remain visible.
if(NOT WASM)
add_library(
Expand Down
1 change: 0 additions & 1 deletion barretenberg/cpp/src/barretenberg/bb/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "barretenberg/bbapi/bbapi.hpp"
#include "barretenberg/bbapi/bbapi_schema.hpp"
#include "barretenberg/bbapi/bbapi_ultra_honk.hpp"
#include "barretenberg/bbapi/c_bind.hpp"
#include "barretenberg/common/bb_bench.hpp"
#include "barretenberg/common/get_bytecode.hpp"
#include "barretenberg/common/memory_profile.hpp"
Expand Down
12 changes: 11 additions & 1 deletion barretenberg/cpp/src/barretenberg/bbapi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ set(BB_GEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/generated)
if(NOT FUZZING)
set(BB_GEN_OUTPUTS
${BB_GEN_DIR}/bb_dispatch.hpp
${BB_GEN_DIR}/bb_ffi.cpp
${BB_GEN_DIR}/bb_ffi.hpp
${BB_GEN_DIR}/bb_ipc_server.hpp
${BB_GEN_DIR}/bb_types.hpp
${BB_GEN_DIR}/ipc_codegen/msgpack_adaptor.hpp
Expand All @@ -20,6 +22,7 @@ if(NOT FUZZING)
${IPC_CODEGEN_DIR}/src/*.ts
${IPC_CODEGEN_DIR}/templates/cpp/*.hpp
)
# --ffi emits the in-process entry (bb_ipc_ffi_entry) bb.js's wasm backend and barretenberg-rs call.
add_custom_command(
OUTPUT ${BB_GEN_OUTPUTS}
COMMAND node --experimental-strip-types --experimental-transform-types --no-warnings
Expand All @@ -28,11 +31,12 @@ if(NOT FUZZING)
--lang cpp
--out ${BB_GEN_DIR}
--server
--ffi
--cpp-namespace bb::bbapi
--cpp-include-dir barretenberg/bbapi/generated
--strip-method-prefix
DEPENDS ${BB_SCHEMA} ${IPC_CODEGEN_SRC}
COMMENT "Generating BB IPC wire types + server dispatch from bb_schema.json"
COMMENT "Generating BB IPC wire types + server dispatch + FFI entry from bb_schema.json"
VERBATIM
)
add_custom_target(bb_ipc_generated DEPENDS ${BB_GEN_OUTPUTS})
Expand All @@ -48,6 +52,12 @@ barretenberg_module(bbapi common chonk dsl crypto_poseidon2 crypto_pedersen_comm

if(NOT FUZZING)
add_dependencies(bbapi_objects bb_ipc_generated)
# The FFI entry is generated at build time, so the module's configure-time source glob misses it
# on a clean tree; list it explicitly (skipping the duplicate once the glob does see it).
get_target_property(BBAPI_SOURCES bbapi_objects SOURCES)
if(NOT "${BB_GEN_DIR}/bb_ffi.cpp" IN_LIST BBAPI_SOURCES)
target_sources(bbapi_objects PRIVATE ${BB_GEN_DIR}/bb_ffi.cpp)
endif()
endif()

# bbapi_tests needs vm2_stub to resolve dsl's AVM recursion constraint references
Expand Down
36 changes: 0 additions & 36 deletions barretenberg/cpp/src/barretenberg/bbapi/bb_curve_constants.json

This file was deleted.

4 changes: 4 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bb_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,10 @@
"response": {
"dummy": "u8"
}
},
"Warmup": {
"request": {},
"response": {}
}
}
}
41 changes: 41 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "barretenberg/crypto/poseidon2/poseidon2_permutation.hpp"
#include "barretenberg/crypto/schnorr/schnorr.hpp"
#include "barretenberg/crypto/sha256/sha256.hpp"
#include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp"
#include "barretenberg/polynomials/polynomial.hpp"
#include "barretenberg/srs/factories/bn254_crs_data.hpp"
#include "barretenberg/srs/factories/bn254_g1_chunk_hashes.hpp"
#include "barretenberg/srs/global_crs.hpp"
Expand Down Expand Up @@ -567,4 +569,43 @@ void handle_srs_init_grumpkin_srs(BBApiRequest& /*ctx*/,
respond.ok({});
}

void handle_warmup(BBApiRequest& /*ctx*/, wire::BbWarmup&& /*cmd*/, Responder<wire::BbWarmupResponse> respond)
{
// Run the prover's hot loops once — field arithmetic, batch inversion, Poseidon2 and a Pippenger
// MSM — so a tiering JIT (wasm) has optimized them before real work runs through them.
constexpr size_t NUM_POINTS = 1 << 14;
constexpr size_t NUM_HASHES = 1 << 10;

// Successive doublings of the generator: sums of distinct subsets of {2^i G} are distinct, so the
// MSM's addition tree never meets two equal points, which the unsafe (SRS-shaped) path cannot
// handle. Small multiples of G would (G + 4G = 2G + 3G).
std::vector<g1::element> points(NUM_POINTS);
points[0] = g1::one;
for (size_t i = 1; i < NUM_POINTS; ++i) {
points[i] = points[i - 1].dbl();
}
g1::element::batch_normalize(points.data(), NUM_POINTS);
std::vector<g1::affine_element> affine_points(NUM_POINTS);
for (size_t i = 0; i < NUM_POINTS; ++i) {
affine_points[i] = g1::affine_element(points[i]);
}
Polynomial<fr> scalars = Polynomial<fr>::random(NUM_POINTS);
g1::element commitment = scalar_multiplication::pippenger_unsafe<curve::BN254>(scalars, affine_points);

std::vector<fr> elements(NUM_POINTS);
for (size_t i = 0; i < NUM_POINTS; ++i) {
elements[i] = scalars[i].sqr() + fr(static_cast<uint64_t>(i + 1));
}
fr::batch_invert(elements.data(), NUM_POINTS);

fr acc = elements[0];
for (size_t i = 0; i < NUM_HASHES; ++i) {
acc = crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash({ acc, elements[i] });
}
if (commitment.is_point_at_infinity() || acc.is_zero()) {
throw_or_abort("Warmup: degenerate result");
}
respond.ok({});
}

} // namespace bb::bbapi
1 change: 1 addition & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_handlers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,5 @@ void handle_chonk_batch_verifier_stop(BBApiRequest& ctx,
void handle_srs_init_grumpkin_srs(BBApiRequest& ctx,
wire::BbSrsInitGrumpkinSrs&& cmd,
Responder<wire::BbSrsInitGrumpkinSrsResponse> respond);
void handle_warmup(BBApiRequest& ctx, wire::BbWarmup&& cmd, Responder<wire::BbWarmupResponse> respond);
} // namespace bb::bbapi
42 changes: 12 additions & 30 deletions barretenberg/cpp/src/barretenberg/bbapi/c_bind.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
#include "c_bind.hpp"
#include "barretenberg/bbapi/bbapi_handlers.hpp"
#include "barretenberg/bbapi/bbapi_shared.hpp"
#include "barretenberg/bbapi/generated/bb_dispatch.hpp"
#include <cstdlib>
#include <cstring>
#include <span>
#include <utility>
#include <vector>
#include "barretenberg/bbapi/generated/bb_ffi.hpp"

namespace {
// One request context for the process so stateful command sequences
// (ChonkStart/Load/Accumulate/Prove) share IVC state, mirroring a serve loop's
// single connection context.
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
bb::bbapi::BBApiRequest global_request;
} // namespace
namespace bb::bbapi {

/**
* @brief In-process FFI/wasm entrypoint: the ipc-codegen FFI backend contract.
* @brief The dispatcher behind the generated in-process FFI entry (bb_ipc_ffi_entry, see bb_ffi.hpp).
*
* Takes exactly the msgpack command payload a transport client would put inside
* a frame (no length/id envelope — framing is transport-level and an in-process
* call has none) and answers through the same generated dispatch the pipe /
* socket / shared-memory servers use. The output buffer is aligned_alloc'd and
* owned by the caller (free()-compatible), matching the cbind buffer contract.
* One request context for the process so stateful command sequences (ChonkStart/Load/Accumulate/
* Prove) share IVC state, mirroring a serve loop's single connection context.
*/
WASM_EXPORT void ipc_ffi_entry(const uint8_t* input, size_t input_len, uint8_t** output, size_t* output_len)
AsyncDispatchHandler& ipc_ffi_dispatcher()
{
static auto handler = bb::bbapi::make_bb_handler(global_request);
std::vector<uint8_t> response;
handler(std::span<const uint8_t>(input, input_len),
[&response](std::vector<uint8_t> r) { response = std::move(r); });
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
auto* out = static_cast<uint8_t*>(aligned_alloc(64, response.size()));
std::memcpy(out, response.data(), response.size());
*output = out;
*output_len = response.size();
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static BBApiRequest request;
static AsyncDispatchHandler handler = make_bb_handler(request);
return handler;
}

} // namespace bb::bbapi
13 changes: 0 additions & 13 deletions barretenberg/cpp/src/barretenberg/bbapi/c_bind.hpp

This file was deleted.

14 changes: 10 additions & 4 deletions barretenberg/cpp/src/barretenberg/bbapi/c_bind_exception.test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "barretenberg/bbapi/c_bind.hpp"
#include "barretenberg/bbapi/generated/bb_ffi.hpp"
#include "barretenberg/bbapi/generated/bb_types.hpp"
#include "barretenberg/bbapi/generated/ipc_codegen/msgpack_adaptor.hpp"
#include "barretenberg/bbapi/generated/ipc_codegen/msgpack_include.hpp"
Expand Down Expand Up @@ -26,11 +26,10 @@ template <typename Cmd> std::string ffi_response_type(const char* name, const Cm

uint8_t* out = nullptr;
size_t out_len = 0;
ipc_ffi_entry(reinterpret_cast<const uint8_t*>(buf.data()), buf.size(), &out, &out_len);
bb_ipc_ffi_entry(reinterpret_cast<const uint8_t*>(buf.data()), buf.size(), &out, &out_len);

auto oh = msgpack::unpack(reinterpret_cast<const char*>(out), out_len);
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
free(out);
bb_ipc_ffi_free(out);
auto arr = oh.get().via.array;
EXPECT_EQ(arr.size, 2U);
auto type = arr.ptr[0].as<std::string>();
Expand Down Expand Up @@ -74,6 +73,13 @@ TEST(CBind, UnknownCommandReturnsErrorResponse)
EXPECT_EQ(ffi_response_type("NoSuchCommand", cmd), "BbErrorResponse");
}

// Warmup runs the prover's hot loops on self-made inputs; they must be shaped so that
// the unsafe MSM path never meets two equal points.
TEST(CBind, WarmupSucceeds)
{
EXPECT_EQ(ffi_response_type("BbWarmup", wire::BbWarmup{}), "BbWarmupResponse");
}

#else
TEST(CBind, ExceptionsDisabled)
{
Expand Down
4 changes: 1 addition & 3 deletions barretenberg/ts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ bb.js/build
bb.js/.tsbuildinfo*
bb.js/*.tsbuildinfo
bb-avm-sim/
bb.js-api/
cdb/
.tsbuildinfo*
*.tsbuildinfo
Expand All @@ -16,6 +17,3 @@ cdb/
package.tgz
package
packages/

# Generated files
bb.js/src/generated/
4 changes: 0 additions & 4 deletions barretenberg/ts/bb.js/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +0,0 @@
# Codegen output: regenerated by `yarn generate`, never hand-edited, and not
# emitted in prettier's style. It is gitignored, but CI runners reuse working
# directories, so it can be present when `yarn formatting` runs.
src/generated/
33 changes: 30 additions & 3 deletions barretenberg/ts/bb.js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ If `1` is specified, fallback to non multi-threaded wasm that doesn't need share

See `src/main.ts` for larger example of how to use.

### How bb is reached

The typed API (`Barretenberg` extends it) and every way of reaching bb come from the
`@aztec-foundation/bb.js-api` package, generated from bb's schema by ipc-codegen; bb.js adds the facades,
its `BackendType` options and CRS handling. That package ships the bb binary as per-platform optional
dependencies (override with `bbPath` or `BB_BINARY_PATH`) and bb's wasm modules (single-thread and threads
builds), run in-process through `@aztec-foundation/ipc-runtime/wasm`: the module in a worker, wasi threads
on further workers. Pass `warmup: true` to run bb's `Warmup` command after initialization, which takes the
prover's hot loops through the engine's optimizing tier before the first real request. bb.js itself only
bundles bb's LMDB NAPI module (`findNapiBinary`).

The wasm modules ship uncompressed and are fetched as ordinary assets, so the browser streams them
straight into `WebAssembly.compileStreaming` and can cache the compiled code between visits. That means
serving them with your host's own compression: most CDNs compress `application/wasm` by default, but nginx
does not unless `application/wasm` is added to `gzip_types`. Where you cannot compress on the wire, pass
`wasmPath` (or set `BB_WASM_PATH` in node) pointing at a gzipped copy — the loader recognises gzip, at the
cost of the compiled-code cache. `wasmPath` also takes any other build of the module, and is used verbatim:
unlike earlier versions, bb.js no longer rewrites the filename to pick a `-threads` variant.

### Browser Context

It's recommended to use a dynamic import. This allows the developer to pick the time at which the package (several MB
Expand All @@ -53,6 +72,11 @@ in size) is loaded and keeps page load times responsive.
const { Barretenberg, RawBuffer, Crs } = await import('@aztec-foundation/bb.js');
```

The worker scripts and the wasm modules are referenced with `new URL('...', import.meta.url)` (the workers as
`new Worker(new URL(...), { type: 'module' })`), which webpack 5, Vite and similar bundlers turn into chunks and
assets of your application. Vite users should exclude `@aztec-foundation/bb.js` and `@aztec-foundation/bb.js-api`
from `optimizeDeps`, so those references are resolved from the packages rather than from a pre-bundled copy.

### Multithreading in browser

Multithreading in bb.js requires [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer) to be enabled. It is only enabled in browsers if COOP and COEP headers are set by the server. Read more [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements).
Expand Down Expand Up @@ -82,10 +106,13 @@ You can enable these headers for specific pages that perform proof generation, b

## Debugging

Got an unhelpful stack trace in wasm? Run:
Got an unhelpful stack trace in wasm? Point bb.js at the unstripped module the wasm build leaves next to the
stripped one:

```
BUILD_CPP=1 NO_STRIP=1 ./script/copy_wasm.sh
BB_WASM_PATH=$(git rev-parse --show-toplevel)/barretenberg/cpp/build-wasm-threads/bin/barretenberg-debug.wasm
```

This will drop unstripped wasms into the dest folder. Run your test again to get a trace.
(the loader takes a `.wasm` or a `.wasm.gz` either way)

Run your test again to get a trace.
Loading
Loading