Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Optimise bb.js package size and sandox/cli dockerfiles to unbloat final containers. #3462

Merged
merged 11 commits into from
Nov 29, 2023
1 change: 1 addition & 0 deletions barretenberg/cpp/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

# Needed scripts.
!scripts/install-wasi-sdk.sh
!scripts/strip-wasm.sh
!./.clang-format
!./format.sh
7 changes: 1 addition & 6 deletions barretenberg/cpp/dockerfiles/Dockerfile.wasm-linux-clang
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,10 @@ RUN ./scripts/install-wasi-sdk.sh
COPY . .
RUN cmake --preset wasm && cmake --build --preset wasm
RUN cmake --preset wasm-threads && cmake --build --preset wasm-threads
RUN ./scripts/strip-wasm.sh

FROM scratch
WORKDIR /usr/src/barretenberg/cpp
COPY . .
COPY --from=builder /usr/src/barretenberg/cpp/build-wasm/bin/barretenberg.wasm /usr/src/barretenberg/cpp/build-wasm/bin/barretenberg.wasm
COPY --from=builder /usr/src/barretenberg/cpp/build-wasm-threads/bin/barretenberg.wasm /usr/src/barretenberg/cpp/build-wasm-threads/bin/barretenberg.wasm
# Copy libs for consuming projects.
COPY --from=builder /usr/src/barretenberg/cpp/build-wasm/lib/libbarretenberg.a /usr/src/barretenberg/cpp/build-wasm/lib/libbarretenberg.a
COPY --from=builder /usr/src/barretenberg/cpp/build-wasm/lib/libwasi.a /usr/src/barretenberg/cpp/build-wasm/lib/libwasi.a
COPY --from=builder /usr/src/barretenberg/cpp/build-wasm/lib/libenv.a /usr/src/barretenberg/cpp/build-wasm/lib/libenv.a
# Copy wasi-sdk so that consuming projects have the toolchain available.
COPY --from=builder /usr/src/barretenberg/cpp/src/wasi-sdk-20.0 /usr/src/barretenberg/cpp/src/wasi-sdk-20.0
2 changes: 2 additions & 0 deletions barretenberg/ts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ dest
.tsbuildinfo*
*.log
/crs
package.tgz
package
6 changes: 6 additions & 0 deletions barretenberg/ts/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/barretenberg-wasm-linux-clang

FROM node:18-alpine
COPY --from=0 /usr/src/barretenberg /usr/src/barretenberg

# Create a standalone container that can run bb.js (and tests).
# We'll perform the build in a new, different directory, so the original directory can become the "published" package.
WORKDIR /usr/src/barretenberg/ts
# Leverage layer caching. Only re-install packages if these files change.
COPY .yarn .yarn
Expand All @@ -12,3 +15,6 @@ RUN yarn --immutable
COPY . .
RUN yarn formatting && SKIP_CPP_BUILD=1 yarn build
CMD ["yarn", "test"]

# We want to create a pure package, as would be published to npm, for consuming projects.
RUN yarn pack && tar zxf package.tgz && rm package.tgz
6 changes: 3 additions & 3 deletions barretenberg/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
"README.md"
],
"scripts": {
"clean": "rm -rf ./dest .tsbuildinfo .tsbuildinfo.cjs",
"build": "yarn clean && yarn build:wasm && yarn build:esm && yarn build:cjs && yarn build:browser",
"clean": "rm -rf ./dest .tsbuildinfo .tsbuildinfo.cjs package.tgz package",
"build": "yarn clean && yarn build:wasm && yarn build:esm && yarn build:cjs && yarn build:browser && yarn build:package",
"build:wasm": "./scripts/build_wasm.sh",
"build:esm": "tsc -b && chmod +x ./dest/node/main.js",
"build:cjs": "tsc -b tsconfig.cjs.json && ./scripts/cjs_postprocess.sh",
"build:browser": "webpack",
"build:bindings": "cd .. && ./scripts/bindgen.sh",
"build:package": "yarn pack && tar zxf package.tgz && rm -f package.tgz",
"formatting": "prettier --check ./src && eslint --max-warnings 0 ./src",
"formatting:fix": "prettier -w ./src",
"test": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests",
"test:debug": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 node --inspect-brk=0.0.0.0 --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests --runInBand",
"simple_test": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 node ./src/examples/simple.rawtest.ts",
"prepack": "yarn build",
"deploy": "npm publish --access public"
},
"jest": {
Expand Down
12 changes: 7 additions & 5 deletions barretenberg/ts/src/barretenberg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BarretenbergApi, BarretenbergApiSync } from '../barretenberg_api/index.
import { createMainWorker } from '../barretenberg_wasm/barretenberg_wasm_main/factory/node/index.js';
import { BarretenbergWasmMain, BarretenbergWasmMainWorker } from '../barretenberg_wasm/barretenberg_wasm_main/index.js';
import { getRemoteBarretenbergWasm } from '../barretenberg_wasm/helpers/index.js';
import { BarretenbergWasmWorker } from '../barretenberg_wasm/index.js';
import { BarretenbergWasmWorker, fetchModuleAndThreads } from '../barretenberg_wasm/index.js';
import createDebug from 'debug';

const debug = createDebug('bb.js:wasm');
Expand All @@ -19,14 +19,15 @@ export class Barretenberg extends BarretenbergApi {

/**
* Constructs an instance of Barretenberg.
* Launches it within a worker. This is necessary as it block waiting on child threads to complete,
* Launches it within a worker. This is necessary as it blocks waiting on child threads to complete,
* and blocking the main thread in the browser is not allowed.
* It threads > 1 (defaults to hardware availability), child threads will be created on their own workers.
*/
static async new(threads?: number) {
static async new(desiredThreads?: number) {
const worker = createMainWorker();
const wasm = getRemoteBarretenbergWasm<BarretenbergWasmMainWorker>(worker);
await wasm.init(threads, proxy(debug));
const { module, threads } = await fetchModuleAndThreads(desiredThreads);
await wasm.init(module, threads, proxy(debug));
return new Barretenberg(worker, wasm);
}

Expand All @@ -49,7 +50,8 @@ export class BarretenbergSync extends BarretenbergApiSync {

static async new() {
const wasm = new BarretenbergWasmMain();
await wasm.init(1);
const { module, threads } = await fetchModuleAndThreads(1);
await wasm.init(module, threads);
return new BarretenbergSync(wasm);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { type Worker } from 'worker_threads';
import createDebug from 'debug';
import { Remote } from 'comlink';
import { getNumCpu, getRemoteBarretenbergWasm, getSharedMemoryAvailable } from '../helpers/index.js';
import { fetchCode } from '../fetch_code/index.js';
import { createThreadWorker } from '../barretenberg_wasm_thread/factory/node/index.js';
import { type BarretenbergWasmThreadWorker } from '../barretenberg_wasm_thread/index.js';
import { BarretenbergWasmBase } from '../barretenberg_wasm_base/index.js';
Expand Down Expand Up @@ -30,6 +29,7 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
* Init as main thread. Spawn child threads.
*/
public async init(
module: WebAssembly.Module,
threads = Math.min(getNumCpu(), BarretenbergWasmMain.MAX_THREADS),
logger: (msg: string) => void = debug,
initial = 25,
Expand All @@ -41,10 +41,6 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
const maxMb = (maximum * 2 ** 16) / (1024 * 1024);
const shared = getSharedMemoryAvailable();

if (!shared) {
threads = 1;
}

this.logger(
`initial mem: ${initial} pages, ${initialMb}MiB. ` +
`max mem: ${maximum} pages, ${maxMb}MiB. ` +
Expand All @@ -53,8 +49,7 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {

this.memory = new WebAssembly.Memory({ initial, maximum, shared });

const code = await fetchCode(shared);
const { instance, module } = await WebAssembly.instantiate(code, this.getImportObj(this.memory));
const instance = await WebAssembly.instantiate(module, this.getImportObj(this.memory));

this.instance = instance;

Expand Down
5 changes: 4 additions & 1 deletion barretenberg/ts/src/barretenberg_wasm/helpers/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ export function getRemoteBarretenbergWasm<T>(worker: Worker): T {
return wrap(nodeEndpoint(worker)) as T;
}

/**
* Returns number of cpus as reported by the system, unless overriden by HARDWARE_CONCURRENCY env var.
*/
export function getNumCpu() {
return os.cpus().length;
return +process.env.HARDWARE_CONCURRENCY! || os.cpus().length;
}

/**
Expand Down
16 changes: 13 additions & 3 deletions barretenberg/ts/src/barretenberg_wasm/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { proxy } from 'comlink';
import createDebug from 'debug';
import { createMainWorker } from './barretenberg_wasm_main/factory/node/index.js';
import { getRemoteBarretenbergWasm } from './helpers/node/index.js';
import { getRemoteBarretenbergWasm, getSharedMemoryAvailable } from './helpers/node/index.js';
import { BarretenbergWasmMain, BarretenbergWasmMainWorker } from './barretenberg_wasm_main/index.js';
import { fetchCode } from './fetch_code/index.js';

const debug = createDebug('bb.js:wasm');

export async function fetchModuleAndThreads(desiredThreads?: number) {
const shared = getSharedMemoryAvailable();
const threads = shared ? desiredThreads : 1;
const code = await fetchCode(shared);
const module = await WebAssembly.compile(code);
return { module, threads };
}

export class BarretenbergWasm extends BarretenbergWasmMain {
/**
* Construct and initialize BarretenbergWasm within a Worker. Return both the worker and the wasm proxy.
* Used when running in the browser, because we can't block the main thread.
*/
public static async new(threads?: number) {
public static async new(desiredThreads?: number) {
const worker = createMainWorker();
const wasm = getRemoteBarretenbergWasm<BarretenbergWasmMainWorker>(worker);
await wasm.init(threads, proxy(debug));
const { module, threads } = await fetchModuleAndThreads(desiredThreads);
await wasm.init(module, threads, proxy(debug));
return { worker, wasm };
}
}
Expand Down
Loading