-
Notifications
You must be signed in to change notification settings - Fork 130
feat: Modify bb.js to be compatible with next.js #544
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
Changes from all commits
ab016eb
e35ae60
38ab0ea
c51086f
2ec7f60
5cda723
d5b9d56
914b96d
068aea5
0aa28fc
dd0cddb
fcb81f9
3bf4cfc
45c2fac
a8fbafb
9a2131a
e174be9
218e7c0
0697d6b
a91d6f4
80d6a0b
226f016
557ce64
74de092
6a503c5
dc767bc
cb839eb
d41d42d
480c3ea
10fbdf4
d5bfde0
7a3271d
9024a6c
2fdf85f
6f694a3
16aef23
60697f5
bf36f42
b95b162
732f269
921a579
0725a19
1997a3a
68157a9
18afd8a
89ab4f3
23cc31e
e8aff77
67981e2
365e575
752cfcb
8f28b8a
b0b9648
8856636
01ae15d
184d2f5
bf0e9e7
170d127
eeb3024
15e86ea
272cb35
15f6e69
4b3f7da
bf11890
018f821
f2b4e84
d618b4a
70117c2
465622f
38edbde
d981161
ff4b441
4609184
7d1fed7
b4f20ca
4f5f5f9
6c658a7
ff68b79
68d5cb5
6251826
30a1e15
1a93b95
472ca76
2834f86
7002874
4645fe4
fc632ae
a6c4484
d3ed0e0
465cfa1
5ca0d26
d4dfaef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| # Used to call this script from a stable path | ||
| DIR=$(dirname "$0") | ||
| exec node "$DIR/../ts/dest/node/main.js" $@ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,5 +3,7 @@ | |
| node_modules | ||
| dest | ||
| .tsbuildinfo | ||
| .tsbuildinfo.browser | ||
| .tsbuildinfo.node | ||
| *.log | ||
| crs | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,52 +8,41 @@ | |
| "displayName": "bb.js", | ||
| "tsconfig": "./tsconfig.json" | ||
| }, | ||
| "main": "./dest/index.js", | ||
| "bin": "./dest/main.js", | ||
| "files": [ | ||
| "src/", | ||
| "dest/", | ||
| "!dest/browser/*.wasm", | ||
| "README.md" | ||
| ], | ||
| "scripts": { | ||
| "clean": "rm -rf ./dest .tsbuildinfo", | ||
| "build": "yarn clean && yarn build:wasm && yarn build:ts", | ||
| "clean": "rm -rf ./dest .tsbuildinfo.browser .tsbuildinfo.node", | ||
| "build": "yarn clean && yarn build:wasm && yarn build:ts:browser && yarn build:ts:node", | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two individual tsconfigs (node/web) |
||
| "build:dev": "tsc -b --watch", | ||
| "build:wasm": "cd ../cpp && cmake --preset wasm-threads && cmake --build --preset wasm-threads && cmake --preset wasm && cmake --build --preset wasm", | ||
| "build:ts": "tsc -b && webpack && chmod +x ./dest/main.js", | ||
| "build:ts:browser": "tsc -b tsconfig.browser.json && BUILD_TARGET=browser webpack && chmod +x ./dest/browser/main.js && BUILD_TARGET=browser node replace_imports.cjs", | ||
| "build:ts:node": "tsc -b tsconfig.node.json && chmod +x ./dest/node/main.js && BUILD_TARGET=node node replace_imports.cjs", | ||
| "build:bindings": "cd .. && ./scripts/bindgen.sh", | ||
| "serve": "webpack serve", | ||
| "formatting": "prettier --check ./src && eslint --max-warnings 0 ./src", | ||
| "formatting:fix": "prettier -w ./src", | ||
| "test": "yarn test:jest && yarn test:bin", | ||
| "test:jest": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests", | ||
| "test": "yarn build:ts:browser && yarn build:ts:node && yarn test:jest && yarn test:bin", | ||
| "test:jest": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests", | ||
| "test:bin": "cd ./bin-test && ./bin-test.sh", | ||
| "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", | ||
| "test-debug": "NODE_NO_WARNINGS=1 node --inspect-brk=0.0.0.0 --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests --runInBand", | ||
| "prepack": "yarn build", | ||
| "deploy": "npm publish --access public" | ||
| }, | ||
| "jest": { | ||
| "preset": "ts-jest/presets/default-esm", | ||
| "transform": { | ||
| "./src/.*\\.ts": [ | ||
| "ts-jest", | ||
| { | ||
| "useESM": true | ||
| } | ||
| ] | ||
| }, | ||
| "moduleNameMapper": { | ||
| "^(\\.{1,2}/.*)\\.js$": "$1" | ||
| }, | ||
| "testRegex": "./src/.*\\.test\\.ts$", | ||
| "rootDir": "./src" | ||
| "testRegex": "./dest/node/.*\\.test\\.js$", | ||
| "rootDir": "./dest" | ||
| }, | ||
| "dependencies": { | ||
| "comlink": "^4.4.1", | ||
| "commander": "^10.0.1", | ||
| "debug": "^4.3.4", | ||
| "ts-node": "^10.9.1", | ||
| "tslib": "^2.4.0" | ||
| "idb-keyval": "^6.2.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@jest/globals": "^29.4.3", | ||
|
|
@@ -69,12 +58,13 @@ | |
| "eslint": "^8.35.0", | ||
| "eslint-config-prettier": "^8.8.0", | ||
| "html-webpack-plugin": "^5.5.1", | ||
| "idb-keyval": "^6.2.1", | ||
| "jest": "^29.5.0", | ||
| "prettier": "^2.8.4", | ||
| "replace-in-file": "^7.0.1", | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used in replace_imports |
||
| "resolve-typescript-plugin": "^2.0.1", | ||
| "ts-jest": "^29.1.0", | ||
| "ts-loader": "^9.4.2", | ||
| "tsconfig-paths-webpack-plugin": "^4.0.1", | ||
| "typescript": "^5.0.4", | ||
| "webpack": "^5.82.1", | ||
| "webpack-cli": "^5.1.1", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| const replaceInFile = require('replace-in-file'); | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
|
|
||
| const buildTarget = process.env.BUILD_TARGET; | ||
| const dynamic_imports = ['barretenberg_wasm', 'crs', 'random', 'types']; | ||
|
|
||
| async function replaceImports() { | ||
| try { | ||
| dynamic_imports.forEach(async item => { | ||
| await replaceInFile({ | ||
| files: path.resolve(__dirname, `dest/${buildTarget}/${item}/*`), | ||
| from: new RegExp(`'dynamic\\/${item}';`, 'g'), | ||
| to: `'./${buildTarget}/index.js';`, | ||
| }); | ||
| }); | ||
| const filePath = path.resolve(__dirname, `dest/${buildTarget}/barretenberg_wasm/${buildTarget}/index.js`); | ||
| // Grab the contents for a hacky check if this has ran twice | ||
| const contents = fs.readFileSync(filePath, 'utf8'); | ||
| // hack to allow for shared .wasm files between build targets | ||
| if (contents.includes('../../') && !contents.includes('../../../')) { | ||
| await replaceInFile({ | ||
| files: filePath, | ||
| from: /\.\.\/\.\.\//g, | ||
| to: `../../../`, | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| console.error('Error occurred:', error); | ||
| } | ||
| } | ||
|
|
||
| replaceImports(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,10 +3,14 @@ import { EventEmitter } from 'events'; | |
| import createDebug from 'debug'; | ||
| import { Remote, proxy } from 'comlink'; | ||
| import { randomBytes } from '../random/index.js'; | ||
| // Webpack config swaps this import with ./browser/index.js | ||
| // You can toggle between these two imports to sanity check the type-safety. | ||
| import { fetchCode, getNumCpu, createWorker, getRemoteBarretenbergWasm, threadLogger, killSelf } from './node/index.js'; | ||
| // import { fetchCode, getNumCpu, createWorker, randomBytes } from './browser/index.js'; | ||
| import { | ||
| fetchCode, | ||
| getNumCpu, | ||
| createWorker, | ||
| getRemoteBarretenbergWasm, | ||
| threadLogger, | ||
| killSelf, | ||
| } from 'dynamic/barretenberg_wasm'; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoids having to have two different (identical) entry points for the application. Ideally, we would want two entrypoints, but since the only change node's barretenberg_wasm and browser's barretenberg_wasm have between them is the imports, we would end up having two identical BarretenbergWasm classes (same for every file that has the Webpack aliases were not bundling the result with the correct path either. Also I do believe it's a cleaner approach to be more explicit about the dynamic nature of these imports. |
||
|
|
||
| const debug = createDebug('bb.js:wasm'); | ||
|
|
||
|
|
@@ -68,7 +72,7 @@ export class BarretenbergWasm { | |
|
|
||
| // Annoyingly the wasm declares if it's memory is shared or not. So now we need two wasms if we want to be | ||
| // able to fallback on "non shared memory" situations. | ||
| const code = await fetchCode(threads > 1 ? 'barretenberg-threads.wasm' : 'barretenberg.wasm'); | ||
| const code = await fetchCode(threads > 1); | ||
| const { instance, module } = await WebAssembly.instantiate(code, this.getImportObj(this.memory)); | ||
|
|
||
| this.instance = instance; | ||
|
|
@@ -78,8 +82,8 @@ export class BarretenbergWasm { | |
|
|
||
| // Create worker threads. Create 1 less than requested, as main thread counts as a thread. | ||
| this.logger('creating worker threads...'); | ||
| this.workers = await Promise.all(Array.from({ length: threads - 1 }).map(createWorker)); | ||
| this.remoteWasms = await Promise.all(this.workers.map(getRemoteBarretenbergWasm)); | ||
| this.workers = (await Promise.all(Array.from({ length: threads - 1 }).map(createWorker))) as any; | ||
| this.remoteWasms = await Promise.all(this.workers.map(getRemoteBarretenbergWasm as any)); | ||
| await Promise.all(this.remoteWasms.map(w => w.initThread(module, this.memory))); | ||
| this.logger('init complete.'); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| export { Crs } from './node/index.js'; | ||
| export { Crs } from 'dynamic/crs'; |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| export * from './node/index.js'; | ||
| export * from 'dynamic/random'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from './point.js'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { Fr } from '../index.js'; | ||
| import { BufferReader } from '../../serialize/buffer_reader.js'; | ||
|
|
||
| export class Point { | ||
| static SIZE_IN_BYTES = 64; | ||
| static EMPTY = new Point(Fr.ZERO, Fr.ZERO); | ||
|
|
||
| constructor(public readonly x: Fr, public readonly y: Fr) {} | ||
|
|
||
| static random() { | ||
| // TODO: This is not a point on the curve! | ||
| return new Point(Fr.random(), Fr.random()); | ||
| } | ||
|
|
||
| static fromBuffer(buffer: Uint8Array | BufferReader) { | ||
| const reader = BufferReader.asReader(buffer); | ||
| return new this(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); | ||
| } | ||
|
|
||
| static fromString(address: string) { | ||
| address = address.replace(/^0x/i, ''); | ||
| const byteValues = new Uint8Array(Math.ceil(address.length / 2)); | ||
| for (let i = 0; i < byteValues.length; i++) { | ||
| byteValues[i] = Number.parseInt(address.substr(i * 2, 2), 16); | ||
| } | ||
| return Point.fromBuffer(byteValues); | ||
| } | ||
|
|
||
| toBuffer() { | ||
| const xBuffer = this.x.toBuffer(); | ||
| const yBuffer = this.y.toBuffer(); | ||
| const combined = new Uint8Array(xBuffer.length + yBuffer.length); | ||
| combined.set(xBuffer, 0); | ||
| combined.set(yBuffer, xBuffer.length); | ||
| return combined; | ||
| } | ||
|
|
||
| toString() { | ||
| const buffer = this.toBuffer(); | ||
| let hexString = '0x'; | ||
| for (let i = 0; i < buffer.length; i++) { | ||
| hexString += buffer[i].toString(16).padStart(2, '0'); | ||
| } | ||
| return hexString; | ||
| } | ||
|
|
||
| equals(rhs: Point) { | ||
| return this.x.equals(rhs.x) && this.y.equals(rhs.y); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| export * from './ptr.js'; | ||
| export * from './fields.js'; | ||
| export * from './point.js'; | ||
| export * from 'dynamic/types'; | ||
| export * from './fixed_size_buffer.js'; | ||
| export * from './raw_buffer.js'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from './point.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaces with nodemon to allow for the tsconfig paths to work