@aztec/bb.js 0.76.4-devnet-test-rc3 → 0.77.0-testnet-ignition.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dest/browser/barretenberg/backend.d.ts +5 -1
- package/dest/browser/barretenberg/backend.d.ts.map +1 -1
- package/dest/browser/barretenberg/index.d.ts +3 -1
- package/dest/browser/barretenberg/index.d.ts.map +1 -1
- package/dest/browser/barretenberg-threads.js +1 -1
- package/dest/browser/barretenberg.js +1 -1
- package/dest/browser/barretenberg_api/index.d.ts +1 -0
- package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/index.d.ts +2 -2
- package/dest/browser/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/browser/crs/net_crs.d.ts.map +1 -1
- package/dest/browser/crs/node/index.d.ts +6 -4
- package/dest/browser/crs/node/index.d.ts.map +1 -1
- package/dest/browser/index.js +98 -38
- package/dest/browser/retry/index.d.ts +26 -0
- package/dest/browser/retry/index.d.ts.map +1 -0
- package/dest/node/barretenberg/__snapshots__/pedersen.test.js.snap +156 -0
- package/dest/node/barretenberg/__snapshots__/poseidon.test.js.snap +40 -0
- package/dest/node/barretenberg/backend.d.ts +5 -1
- package/dest/node/barretenberg/backend.d.ts.map +1 -1
- package/dest/node/barretenberg/backend.js +21 -4
- package/dest/node/barretenberg/index.d.ts +3 -1
- package/dest/node/barretenberg/index.d.ts.map +1 -1
- package/dest/node/barretenberg/index.js +11 -12
- package/dest/node/barretenberg_api/index.d.ts +1 -0
- package/dest/node/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node/barretenberg_api/index.js +25 -1
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -6
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.js +6 -7
- package/dest/node/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/fetch_code/browser/index.js +5 -2
- package/dest/node/barretenberg_wasm/fetch_code/node/index.js +2 -2
- package/dest/node/barretenberg_wasm/index.d.ts +2 -2
- package/dest/node/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/index.js +11 -9
- package/dest/node/barretenberg_wasm/index.test.js +3 -3
- package/dest/node/crs/net_crs.d.ts.map +1 -1
- package/dest/node/crs/net_crs.js +6 -5
- package/dest/node/crs/node/index.d.ts +6 -4
- package/dest/node/crs/node/index.d.ts.map +1 -1
- package/dest/node/crs/node/index.js +16 -13
- package/dest/node/examples/simple.test.js +2 -2
- package/dest/node/main.d.ts.map +1 -1
- package/dest/node/main.js +55 -65
- package/dest/node/retry/index.d.ts +26 -0
- package/dest/node/retry/index.d.ts.map +1 -0
- package/dest/node/retry/index.js +50 -0
- package/dest/node-cjs/barretenberg/backend.d.ts +5 -1
- package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/backend.js +23 -5
- package/dest/node-cjs/barretenberg/index.d.ts +3 -1
- package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/index.js +11 -12
- package/dest/node-cjs/barretenberg_api/index.d.ts +1 -0
- package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_api/index.js +25 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -6
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.js +6 -7
- package/dest/node-cjs/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/fetch_code/browser/index.js +5 -2
- package/dest/node-cjs/barretenberg_wasm/fetch_code/node/index.js +2 -2
- package/dest/node-cjs/barretenberg_wasm/index.d.ts +2 -2
- package/dest/node-cjs/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/index.js +11 -9
- package/dest/node-cjs/barretenberg_wasm/index.test.js +3 -3
- package/dest/node-cjs/crs/net_crs.d.ts.map +1 -1
- package/dest/node-cjs/crs/net_crs.js +6 -5
- package/dest/node-cjs/crs/node/index.d.ts +6 -4
- package/dest/node-cjs/crs/node/index.d.ts.map +1 -1
- package/dest/node-cjs/crs/node/index.js +16 -13
- package/dest/node-cjs/examples/simple.test.js +2 -2
- package/dest/node-cjs/main.d.ts.map +1 -1
- package/dest/node-cjs/main.js +55 -65
- package/dest/node-cjs/retry/index.d.ts +26 -0
- package/dest/node-cjs/retry/index.d.ts.map +1 -0
- package/dest/node-cjs/retry/index.js +56 -0
- package/package.json +3 -3
- package/src/barretenberg/backend.ts +22 -3
- package/src/barretenberg/index.ts +19 -12
- package/src/barretenberg_api/index.ts +35 -0
- package/src/barretenberg_wasm/barretenberg_wasm_base/index.ts +4 -6
- package/src/barretenberg_wasm/barretenberg_wasm_main/index.ts +5 -7
- package/src/barretenberg_wasm/fetch_code/browser/index.ts +4 -1
- package/src/barretenberg_wasm/fetch_code/node/index.ts +1 -1
- package/src/barretenberg_wasm/index.test.ts +2 -2
- package/src/barretenberg_wasm/index.ts +21 -10
- package/src/crs/net_crs.ts +18 -9
- package/src/crs/node/index.ts +31 -15
- package/src/examples/simple.test.ts +1 -1
- package/src/main.ts +59 -70
- package/src/retry/index.ts +50 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.retry = exports.makeBackoff = exports.backoffGenerator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Generates a backoff sequence for retrying operations with an increasing delay.
|
|
6
|
+
* The backoff sequence follows this pattern: 1, 1, 1, 2, 4, 8, 16, 32, 64, ...
|
|
7
|
+
* This generator can be used in combination with the `retry` function to perform
|
|
8
|
+
* retries with exponential backoff and capped at 64 seconds between attempts.
|
|
9
|
+
*
|
|
10
|
+
* @returns A generator that yields the next backoff value in seconds as an integer.
|
|
11
|
+
*/
|
|
12
|
+
function* backoffGenerator() {
|
|
13
|
+
const v = [1, 1, 1, 2, 4, 8, 16, 32, 64];
|
|
14
|
+
let i = 0;
|
|
15
|
+
while (true) {
|
|
16
|
+
yield v[Math.min(i++, v.length - 1)];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.backoffGenerator = backoffGenerator;
|
|
20
|
+
/**
|
|
21
|
+
* Generates a backoff sequence based on the array of retry intervals to use with the `retry` function.
|
|
22
|
+
* @param retries - Intervals to retry (in seconds).
|
|
23
|
+
* @returns A generator sequence.
|
|
24
|
+
*/
|
|
25
|
+
function* makeBackoff(retries) {
|
|
26
|
+
for (const retry of retries) {
|
|
27
|
+
yield retry;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.makeBackoff = makeBackoff;
|
|
31
|
+
/**
|
|
32
|
+
* Retry a given asynchronous function with a specific backoff strategy, until it succeeds or backoff generator ends.
|
|
33
|
+
* It logs the error and retry interval in case an error is caught. The function can be named for better log output.
|
|
34
|
+
*
|
|
35
|
+
* @param fn - The asynchronous function to be retried.
|
|
36
|
+
* @param backoff - The optional backoff generator providing the intervals in seconds between retries. Defaults to a predefined series.
|
|
37
|
+
* @returns A Promise that resolves with the successful result of the provided function, or rejects if backoff generator ends.
|
|
38
|
+
* @throws If `NoRetryError` is thrown by the `fn`, it is rethrown.
|
|
39
|
+
*/
|
|
40
|
+
async function retry(fn, backoff = backoffGenerator()) {
|
|
41
|
+
while (true) {
|
|
42
|
+
try {
|
|
43
|
+
return await fn();
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const s = backoff.next().value;
|
|
47
|
+
if (s === undefined) {
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
await new Promise(resolve => setTimeout(resolve, s * 1000));
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.retry = retry;
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcmV0cnkvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7Ozs7Ozs7R0FPRztBQUNILFFBQWUsQ0FBQyxDQUFDLGdCQUFnQjtJQUMvQixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNaLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7QUFDSCxDQUFDO0FBTkQsNENBTUM7QUFFRDs7OztHQUlHO0FBQ0gsUUFBZSxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQWlCO0lBQzVDLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFLENBQUM7UUFDNUIsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUpELGtDQUlDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSSxLQUFLLFVBQVUsS0FBSyxDQUFTLEVBQXlCLEVBQUUsT0FBTyxHQUFHLGdCQUFnQixFQUFFO0lBQ3pGLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDWixJQUFJLENBQUM7WUFDSCxPQUFPLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFDcEIsQ0FBQztRQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7WUFDbEIsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQztZQUMvQixJQUFJLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxHQUFHLENBQUM7WUFDWixDQUFDO1lBQ0QsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDNUQsU0FBUztRQUNYLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQWJELHNCQWFDIn0=
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/bb.js",
|
|
3
3
|
"packageManager": "yarn@4.5.2",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.77.0-testnet-ignition.4",
|
|
5
5
|
"homepage": "https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/ts",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"default": "./dest/node/index.js"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"bin": "
|
|
16
|
+
"bin": "dest/node/main.js",
|
|
17
17
|
"files": [
|
|
18
18
|
"src/",
|
|
19
19
|
"dest/",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"ts-jest": "^29.1.0",
|
|
97
97
|
"ts-loader": "^9.4.2",
|
|
98
98
|
"ts-node": "^10.9.1",
|
|
99
|
-
"typescript": "
|
|
99
|
+
"typescript": "5.4.5",
|
|
100
100
|
"webpack": "^5.82.1",
|
|
101
101
|
"webpack-cli": "^5.1.1",
|
|
102
102
|
"webpack-dev-server": "^5.2.0",
|
|
@@ -10,6 +10,12 @@ import {
|
|
|
10
10
|
reconstructUltraPlonkProof,
|
|
11
11
|
} from '../proof/index.js';
|
|
12
12
|
|
|
13
|
+
export class AztecClientBackendError extends Error {
|
|
14
|
+
constructor(message: string) {
|
|
15
|
+
super(message);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
export class UltraPlonkBackend {
|
|
14
20
|
// These type assertions are used so that we don't
|
|
15
21
|
// have to initialize `api` and `acirComposer` in the constructor.
|
|
@@ -302,9 +308,11 @@ export class UltraHonkBackend {
|
|
|
302
308
|
return await verifyUltraHonk(proof, new RawBuffer(vkBuf));
|
|
303
309
|
}
|
|
304
310
|
|
|
305
|
-
async getVerificationKey(): Promise<Uint8Array> {
|
|
311
|
+
async getVerificationKey(options?: UltraHonkBackendOptions): Promise<Uint8Array> {
|
|
306
312
|
await this.instantiate();
|
|
307
|
-
return
|
|
313
|
+
return options?.keccak
|
|
314
|
+
? await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive)
|
|
315
|
+
: await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive);
|
|
308
316
|
}
|
|
309
317
|
|
|
310
318
|
/** @description Returns a solidity verifier */
|
|
@@ -376,7 +384,12 @@ export class AztecClientBackend {
|
|
|
376
384
|
|
|
377
385
|
async prove(witnessMsgpack: Uint8Array[]): Promise<[Uint8Array, Uint8Array]> {
|
|
378
386
|
await this.instantiate();
|
|
379
|
-
|
|
387
|
+
const proofAndVk = await this.api.acirProveAztecClient(this.acirMsgpack, witnessMsgpack);
|
|
388
|
+
const [proof, vk] = proofAndVk;
|
|
389
|
+
if (!await this.verify(proof, vk)) {
|
|
390
|
+
throw new AztecClientBackendError("Failed to verify the private (ClientIVC) transaction proof!");
|
|
391
|
+
}
|
|
392
|
+
return proofAndVk;
|
|
380
393
|
}
|
|
381
394
|
|
|
382
395
|
async verify(proof: Uint8Array, vk: Uint8Array): Promise<boolean> {
|
|
@@ -389,6 +402,12 @@ export class AztecClientBackend {
|
|
|
389
402
|
return this.api.acirProveAndVerifyAztecClient(this.acirMsgpack, witnessMsgpack);
|
|
390
403
|
}
|
|
391
404
|
|
|
405
|
+
async gates(): Promise<number[]> {
|
|
406
|
+
// call function on API
|
|
407
|
+
await this.instantiate();
|
|
408
|
+
return this.api.acirGatesAztecClient(this.acirMsgpack);
|
|
409
|
+
}
|
|
410
|
+
|
|
392
411
|
async destroy(): Promise<void> {
|
|
393
412
|
if (!this.api) {
|
|
394
413
|
return;
|
|
@@ -11,8 +11,6 @@ import { RawBuffer } from '../types/raw_buffer.js';
|
|
|
11
11
|
export { BarretenbergVerifier } from './verifier.js';
|
|
12
12
|
export { UltraPlonkBackend, UltraHonkBackend, AztecClientBackend } from './backend.js';
|
|
13
13
|
|
|
14
|
-
const debug = createDebug('bb.js:wasm');
|
|
15
|
-
|
|
16
14
|
export type BackendOptions = {
|
|
17
15
|
/** @description Number of threads to run the backend worker on */
|
|
18
16
|
threads?: number;
|
|
@@ -25,6 +23,9 @@ export type BackendOptions = {
|
|
|
25
23
|
|
|
26
24
|
/** @description Path to download WASM files */
|
|
27
25
|
wasmPath?: string;
|
|
26
|
+
|
|
27
|
+
/** @description Logging function */
|
|
28
|
+
logger?: (msg: string) => void;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
export type CircuitOptions = {
|
|
@@ -53,8 +54,14 @@ export class Barretenberg extends BarretenbergApi {
|
|
|
53
54
|
static async new(options: BackendOptions = {}) {
|
|
54
55
|
const worker = createMainWorker();
|
|
55
56
|
const wasm = getRemoteBarretenbergWasm<BarretenbergWasmMainWorker>(worker);
|
|
56
|
-
const { module, threads } = await fetchModuleAndThreads(options.threads, options.wasmPath);
|
|
57
|
-
await wasm.init(
|
|
57
|
+
const { module, threads } = await fetchModuleAndThreads(options.threads, options.wasmPath, options.logger);
|
|
58
|
+
await wasm.init(
|
|
59
|
+
module,
|
|
60
|
+
threads,
|
|
61
|
+
proxy(options.logger ?? createDebug('bb.js:bb_wasm_async')),
|
|
62
|
+
options.memory?.initial,
|
|
63
|
+
options.memory?.maximum,
|
|
64
|
+
);
|
|
58
65
|
return new Barretenberg(worker, wasm, options);
|
|
59
66
|
}
|
|
60
67
|
|
|
@@ -63,7 +70,7 @@ export class Barretenberg extends BarretenbergApi {
|
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
async initSRSForCircuitSize(circuitSize: number): Promise<void> {
|
|
66
|
-
const crs = await Crs.new(circuitSize + 1, this.options.crsPath);
|
|
73
|
+
const crs = await Crs.new(circuitSize + 1, this.options.crsPath, this.options.logger);
|
|
67
74
|
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1129): Do slab allocator initialization?
|
|
68
75
|
// await this.commonInitSlabAllocator(circuitSize);
|
|
69
76
|
await this.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data()));
|
|
@@ -71,8 +78,8 @@ export class Barretenberg extends BarretenbergApi {
|
|
|
71
78
|
|
|
72
79
|
async initSRSClientIVC(): Promise<void> {
|
|
73
80
|
// crsPath can be undefined
|
|
74
|
-
const crs = await Crs.new(2 ** 20 + 1, this.options.crsPath);
|
|
75
|
-
const grumpkinCrs = await GrumpkinCrs.new(2 ** 16 + 1, this.options.crsPath);
|
|
81
|
+
const crs = await Crs.new(2 ** 20 + 1, this.options.crsPath, this.options.logger);
|
|
82
|
+
const grumpkinCrs = await GrumpkinCrs.new(2 ** 16 + 1, this.options.crsPath, this.options.logger);
|
|
76
83
|
|
|
77
84
|
// Load CRS into wasm global CRS state.
|
|
78
85
|
// TODO: Make RawBuffer be default behavior, and have a specific Vector type for when wanting length prefixed.
|
|
@@ -100,16 +107,16 @@ export class BarretenbergSync extends BarretenbergApiSync {
|
|
|
100
107
|
super(wasm);
|
|
101
108
|
}
|
|
102
109
|
|
|
103
|
-
private static async new(wasmPath?: string) {
|
|
110
|
+
private static async new(wasmPath?: string, logger: (msg: string) => void = createDebug('bb.js:bb_wasm_sync')) {
|
|
104
111
|
const wasm = new BarretenbergWasmMain();
|
|
105
|
-
const { module, threads } = await fetchModuleAndThreads(1, wasmPath);
|
|
106
|
-
await wasm.init(module, threads);
|
|
112
|
+
const { module, threads } = await fetchModuleAndThreads(1, wasmPath, logger);
|
|
113
|
+
await wasm.init(module, threads, logger);
|
|
107
114
|
return new BarretenbergSync(wasm);
|
|
108
115
|
}
|
|
109
116
|
|
|
110
|
-
static async initSingleton(wasmPath?: string) {
|
|
117
|
+
static async initSingleton(wasmPath?: string, logger: (msg: string) => void = createDebug('bb.js:bb_wasm_sync')) {
|
|
111
118
|
if (!barrentenbergSyncSingletonPromise) {
|
|
112
|
-
barrentenbergSyncSingletonPromise = BarretenbergSync.new(wasmPath);
|
|
119
|
+
barrentenbergSyncSingletonPromise = BarretenbergSync.new(wasmPath, logger);
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
barretenbergSyncSingleton = await barrentenbergSyncSingletonPromise;
|
|
@@ -12,6 +12,26 @@ import {
|
|
|
12
12
|
OutputType,
|
|
13
13
|
} from '../serialize/index.js';
|
|
14
14
|
import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js';
|
|
15
|
+
function parseBigEndianU32Array(buffer: Uint8Array, hasSizePrefix = false): number[] {
|
|
16
|
+
const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
17
|
+
|
|
18
|
+
let offset = 0;
|
|
19
|
+
let count = buffer.byteLength >>> 2; // default is entire buffer length / 4
|
|
20
|
+
|
|
21
|
+
if (hasSizePrefix) {
|
|
22
|
+
// Read the first 4 bytes as the size (big-endian).
|
|
23
|
+
count = dv.getUint32(0, /* littleEndian= */ false);
|
|
24
|
+
offset = 4;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const out: number[] = new Array(count);
|
|
28
|
+
for (let i = 0; i < count; i++) {
|
|
29
|
+
out[i] = dv.getUint32(offset, false);
|
|
30
|
+
offset += 4;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
15
35
|
|
|
16
36
|
export class BarretenbergApi {
|
|
17
37
|
constructor(protected wasm: BarretenbergWasmWorker | BarretenbergWasmMain) {}
|
|
@@ -357,6 +377,21 @@ export class BarretenbergApi {
|
|
|
357
377
|
return out as [number, number];
|
|
358
378
|
}
|
|
359
379
|
|
|
380
|
+
async acirGatesAztecClient(
|
|
381
|
+
// cf acirProveAztecClient
|
|
382
|
+
acirVec: Uint8Array[],
|
|
383
|
+
): Promise<number[]> {
|
|
384
|
+
const inArgs = [acirVec].map(serializeBufferable);
|
|
385
|
+
const outTypes: OutputType[] = [BufferDeserializer()];
|
|
386
|
+
const resultBuffer = await this.wasm.callWasmExport(
|
|
387
|
+
'acir_gates_aztec_client',
|
|
388
|
+
inArgs,
|
|
389
|
+
outTypes.map(t => t.SIZE_IN_BYTES),
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
return parseBigEndianU32Array(resultBuffer[0], /*hasSizePrefix=*/ true);
|
|
393
|
+
}
|
|
394
|
+
|
|
360
395
|
async acirNewAcirComposer(sizeHint: number): Promise<Ptr> {
|
|
361
396
|
const inArgs = [sizeHint].map(serializeBufferable);
|
|
362
397
|
const outTypes: OutputType[] = [Ptr];
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import createDebug from 'debug';
|
|
2
2
|
import { randomBytes } from '../../random/index.js';
|
|
3
3
|
|
|
4
|
-
const debug = createDebug('bb.js:wasm');
|
|
5
|
-
|
|
6
4
|
/**
|
|
7
5
|
* Base implementation of BarretenbergWasm.
|
|
8
6
|
* Contains code that is common to the "main thread" implementation and the "child thread" implementation.
|
|
@@ -11,7 +9,7 @@ export class BarretenbergWasmBase {
|
|
|
11
9
|
protected memStore: { [key: string]: Uint8Array } = {};
|
|
12
10
|
protected memory!: WebAssembly.Memory;
|
|
13
11
|
protected instance!: WebAssembly.Instance;
|
|
14
|
-
protected logger: (msg: string) => void =
|
|
12
|
+
protected logger: (msg: string) => void = createDebug('bb.js:bb_wasm_base');
|
|
15
13
|
|
|
16
14
|
protected getImportObj(memory: WebAssembly.Memory) {
|
|
17
15
|
/* eslint-disable camelcase */
|
|
@@ -51,9 +49,9 @@ export class BarretenbergWasmBase {
|
|
|
51
49
|
const m = this.getMemory();
|
|
52
50
|
const str2 = `${str} (mem: ${(m.length / (1024 * 1024)).toFixed(2)}MiB)`;
|
|
53
51
|
this.logger(str2);
|
|
54
|
-
if (str2.startsWith('WARNING:')) {
|
|
55
|
-
|
|
56
|
-
}
|
|
52
|
+
// if (str2.startsWith('WARNING:')) {
|
|
53
|
+
// this.logger(new Error().stack!);
|
|
54
|
+
// }
|
|
57
55
|
},
|
|
58
56
|
|
|
59
57
|
get_data: (keyAddr: number, outBufAddr: number) => {
|
|
@@ -7,8 +7,6 @@ import { type BarretenbergWasmThreadWorker } from '../barretenberg_wasm_thread/i
|
|
|
7
7
|
import { BarretenbergWasmBase } from '../barretenberg_wasm_base/index.js';
|
|
8
8
|
import { HeapAllocator } from './heap_allocator.js';
|
|
9
9
|
|
|
10
|
-
const debug = createDebug('bb.js:wasm');
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* This is the "main thread" implementation of BarretenbergWasm.
|
|
14
12
|
* It spawns a bunch of "child thread" implementations.
|
|
@@ -31,7 +29,7 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
|
|
|
31
29
|
public async init(
|
|
32
30
|
module: WebAssembly.Module,
|
|
33
31
|
threads = Math.min(getNumCpu(), BarretenbergWasmMain.MAX_THREADS),
|
|
34
|
-
logger: (msg: string) => void =
|
|
32
|
+
logger: (msg: string) => void = createDebug('bb.js:bb_wasm'),
|
|
35
33
|
initial = 32,
|
|
36
34
|
maximum = 2 ** 16,
|
|
37
35
|
) {
|
|
@@ -42,9 +40,9 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
|
|
|
42
40
|
const shared = getSharedMemoryAvailable();
|
|
43
41
|
|
|
44
42
|
this.logger(
|
|
45
|
-
`
|
|
46
|
-
`max
|
|
47
|
-
`threads: ${threads}
|
|
43
|
+
`Initializing bb wasm: initial memory ${initial} pages ${initialMb}MiB; ` +
|
|
44
|
+
`max memory: ${maximum} pages, ${maxMb}MiB; ` +
|
|
45
|
+
`threads: ${threads}; shared memory: ${shared}`,
|
|
48
46
|
);
|
|
49
47
|
|
|
50
48
|
this.memory = new WebAssembly.Memory({ initial, maximum, shared });
|
|
@@ -58,7 +56,7 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
|
|
|
58
56
|
|
|
59
57
|
// Create worker threads. Create 1 less than requested, as main thread counts as a thread.
|
|
60
58
|
if (threads > 1) {
|
|
61
|
-
this.logger(`
|
|
59
|
+
this.logger(`Creating ${threads} worker threads`);
|
|
62
60
|
this.workers = await Promise.all(Array.from({ length: threads - 1 }).map(createThreadWorker));
|
|
63
61
|
this.remoteWasms = await Promise.all(this.workers.map(getRemoteBarretenbergWasm<BarretenbergWasmThreadWorker>));
|
|
64
62
|
await Promise.all(this.remoteWasms.map(w => w.initThread(module, this.memory)));
|
|
@@ -6,7 +6,10 @@ export async function fetchCode(multithreaded: boolean, wasmPath?: string) {
|
|
|
6
6
|
let url: string;
|
|
7
7
|
if (wasmPath) {
|
|
8
8
|
const suffix = multithreaded ? '-threads' : '';
|
|
9
|
-
|
|
9
|
+
const filePath = wasmPath.split('/').slice(0, -1).join('/');
|
|
10
|
+
const fileNameWithExtensions = wasmPath.split('/').pop();
|
|
11
|
+
const [fileName, ...extensions] = fileNameWithExtensions!.split('.');
|
|
12
|
+
url = `${filePath}/${fileName}${suffix}.${extensions.join('.')}`;
|
|
10
13
|
} else {
|
|
11
14
|
url = multithreaded
|
|
12
15
|
? (await import(/* webpackIgnore: true */ './barretenberg-threads.js')).default
|
|
@@ -15,7 +15,7 @@ function getCurrentDir() {
|
|
|
15
15
|
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
17
|
export async function fetchCode(multithreaded: boolean, wasmPath?: string) {
|
|
18
|
-
const path = getCurrentDir() + '/../../barretenberg-threads.wasm.gz';
|
|
18
|
+
const path = wasmPath ?? getCurrentDir() + '/../../barretenberg-threads.wasm.gz';
|
|
19
19
|
const compressedData = await readFile(path);
|
|
20
20
|
const decompressedData = pako.ungzip(new Uint8Array(compressedData));
|
|
21
21
|
return decompressedData.buffer;
|
|
@@ -18,7 +18,7 @@ describe('barretenberg wasm', () => {
|
|
|
18
18
|
const length = 1024;
|
|
19
19
|
const ptr = await wasm.call('bbmalloc', length);
|
|
20
20
|
const buf = Buffer.alloc(length, 128);
|
|
21
|
-
await wasm.writeMemory(ptr, buf);
|
|
21
|
+
await wasm.writeMemory(ptr, Uint8Array.from(buf));
|
|
22
22
|
const result = Buffer.from(await wasm.getMemorySlice(ptr, ptr + length));
|
|
23
23
|
await wasm.call('bbfree', ptr);
|
|
24
24
|
expect(result).toStrictEqual(buf);
|
|
@@ -37,7 +37,7 @@ describe('barretenberg wasm', () => {
|
|
|
37
37
|
const length = 1024;
|
|
38
38
|
const ptr = await wasm.call('bbmalloc', length);
|
|
39
39
|
const buf = Buffer.alloc(length, 128);
|
|
40
|
-
await wasm.writeMemory(ptr, buf);
|
|
40
|
+
await wasm.writeMemory(ptr, Uint8Array.from(buf));
|
|
41
41
|
const result = Buffer.from(await wasm.getMemorySlice(ptr, ptr + length));
|
|
42
42
|
await wasm.call('bbfree', ptr);
|
|
43
43
|
expect(result).toStrictEqual(buf);
|
|
@@ -5,29 +5,36 @@ import { getRemoteBarretenbergWasm, getSharedMemoryAvailable } from './helpers/n
|
|
|
5
5
|
import { BarretenbergWasmMain, BarretenbergWasmMainWorker } from './barretenberg_wasm_main/index.js';
|
|
6
6
|
import { fetchCode } from './fetch_code/index.js';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export async function fetchModuleAndThreads(
|
|
9
|
+
desiredThreads = 32,
|
|
10
|
+
wasmPath?: string,
|
|
11
|
+
logger: (msg: string) => void = createDebug('bb.js:fetch_mat'),
|
|
12
|
+
) {
|
|
11
13
|
const shared = getSharedMemoryAvailable();
|
|
12
14
|
|
|
13
|
-
const availableThreads = shared ? await getAvailableThreads() : 1;
|
|
15
|
+
const availableThreads = shared ? await getAvailableThreads(logger) : 1;
|
|
14
16
|
// We limit the number of threads to 32 as we do not benefit from greater numbers.
|
|
15
17
|
const limitedThreads = Math.min(desiredThreads, availableThreads, 32);
|
|
16
18
|
|
|
19
|
+
logger(`Fetching bb wasm from ${wasmPath ?? 'default location'}`);
|
|
17
20
|
const code = await fetchCode(shared, wasmPath);
|
|
21
|
+
logger(`Compiling bb wasm of ${code.byteLength} bytes`);
|
|
18
22
|
const module = await WebAssembly.compile(code);
|
|
23
|
+
logger('Compilation of bb wasm complete');
|
|
19
24
|
return { module, threads: limitedThreads };
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
async function getAvailableThreads(): Promise<number> {
|
|
27
|
+
async function getAvailableThreads(logger: (msg: string) => void): Promise<number> {
|
|
23
28
|
if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {
|
|
24
29
|
return navigator.hardwareConcurrency;
|
|
25
30
|
} else {
|
|
26
31
|
try {
|
|
27
32
|
const os = await import('os');
|
|
28
33
|
return os.cpus().length;
|
|
29
|
-
} catch (e) {
|
|
30
|
-
|
|
34
|
+
} catch (e: any) {
|
|
35
|
+
logger(
|
|
36
|
+
`Could not detect environment to query number of threads. Falling back to one thread. Error: ${e.message ?? e}`,
|
|
37
|
+
);
|
|
31
38
|
return 1;
|
|
32
39
|
}
|
|
33
40
|
}
|
|
@@ -38,11 +45,15 @@ export class BarretenbergWasm extends BarretenbergWasmMain {
|
|
|
38
45
|
* Construct and initialize BarretenbergWasm within a Worker. Return both the worker and the wasm proxy.
|
|
39
46
|
* Used when running in the browser, because we can't block the main thread.
|
|
40
47
|
*/
|
|
41
|
-
public static async new(
|
|
48
|
+
public static async new(
|
|
49
|
+
desiredThreads?: number,
|
|
50
|
+
wasmPath?: string,
|
|
51
|
+
logger: (msg: string) => void = createDebug('bb.js:bb_wasm_main'),
|
|
52
|
+
) {
|
|
42
53
|
const worker = createMainWorker();
|
|
43
54
|
const wasm = getRemoteBarretenbergWasm<BarretenbergWasmMainWorker>(worker);
|
|
44
|
-
const { module, threads } = await fetchModuleAndThreads(desiredThreads, wasmPath);
|
|
45
|
-
await wasm.init(module, threads, proxy(
|
|
55
|
+
const { module, threads } = await fetchModuleAndThreads(desiredThreads, wasmPath, logger);
|
|
56
|
+
await wasm.init(module, threads, proxy(logger));
|
|
46
57
|
return { worker, wasm };
|
|
47
58
|
}
|
|
48
59
|
}
|
package/src/crs/net_crs.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { retry, makeBackoff } from '../retry/index.js';
|
|
1
2
|
/**
|
|
2
3
|
* Downloader for CRS from the web or local.
|
|
3
4
|
*/
|
|
@@ -28,12 +29,16 @@ export class NetCrs {
|
|
|
28
29
|
|
|
29
30
|
const g1End = this.numPoints * 64 - 1;
|
|
30
31
|
|
|
31
|
-
const response = await
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const response = await retry(
|
|
33
|
+
() =>
|
|
34
|
+
fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g1.dat', {
|
|
35
|
+
headers: {
|
|
36
|
+
Range: `bytes=0-${g1End}`,
|
|
37
|
+
},
|
|
38
|
+
cache: 'force-cache',
|
|
39
|
+
}),
|
|
40
|
+
makeBackoff([5, 5, 5]),
|
|
41
|
+
);
|
|
37
42
|
|
|
38
43
|
return (this.data = new Uint8Array(await response.arrayBuffer()));
|
|
39
44
|
}
|
|
@@ -42,9 +47,13 @@ export class NetCrs {
|
|
|
42
47
|
* Download the G2 points data.
|
|
43
48
|
*/
|
|
44
49
|
async downloadG2Data() {
|
|
45
|
-
const response2 = await
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
const response2 = await retry(
|
|
51
|
+
() =>
|
|
52
|
+
fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g2.dat', {
|
|
53
|
+
cache: 'force-cache',
|
|
54
|
+
}),
|
|
55
|
+
makeBackoff([5, 5, 5]),
|
|
56
|
+
);
|
|
48
57
|
|
|
49
58
|
return (this.g2Data = new Uint8Array(await response2.arrayBuffer()));
|
|
50
59
|
}
|
package/src/crs/node/index.ts
CHANGED
|
@@ -4,16 +4,22 @@ import { stat } from 'fs/promises';
|
|
|
4
4
|
import createDebug from 'debug';
|
|
5
5
|
import { homedir } from 'os';
|
|
6
6
|
|
|
7
|
-
const debug = createDebug('bb.js:crs');
|
|
8
|
-
|
|
9
7
|
/**
|
|
10
8
|
* Generic CRS finder utility class.
|
|
11
9
|
*/
|
|
12
10
|
export class Crs {
|
|
13
|
-
constructor(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
constructor(
|
|
12
|
+
public readonly numPoints: number,
|
|
13
|
+
public readonly path: string,
|
|
14
|
+
private readonly logger: (msg: string) => void = createDebug('bb.js:crs'),
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
static async new(
|
|
18
|
+
numPoints: number,
|
|
19
|
+
crsPath = homedir() + '/.bb-crs',
|
|
20
|
+
logger: (msg: string) => void = createDebug('bb.js:crs'),
|
|
21
|
+
) {
|
|
22
|
+
const crs = new Crs(numPoints, crsPath, logger);
|
|
17
23
|
await crs.init();
|
|
18
24
|
return crs;
|
|
19
25
|
}
|
|
@@ -29,11 +35,11 @@ export class Crs {
|
|
|
29
35
|
.catch(() => 0);
|
|
30
36
|
|
|
31
37
|
if (g1FileSize >= this.numPoints * 64 && g1FileSize % 64 == 0 && g2FileSize == 128) {
|
|
32
|
-
|
|
38
|
+
this.logger(`Using cached CRS of size ${g1FileSize / 64}`);
|
|
33
39
|
return;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
this.logger(`Downloading CRS of size ${this.numPoints} into ${this.path}`);
|
|
37
43
|
const crs = new NetCrs(this.numPoints);
|
|
38
44
|
await crs.init();
|
|
39
45
|
writeFileSync(this.path + '/bn254_g1.dat', crs.getG1Data());
|
|
@@ -45,7 +51,9 @@ export class Crs {
|
|
|
45
51
|
* @returns The points data.
|
|
46
52
|
*/
|
|
47
53
|
getG1Data(): Uint8Array {
|
|
48
|
-
|
|
54
|
+
// Ensure length > 0, otherwise we might read a huge file.
|
|
55
|
+
// This is a backup.
|
|
56
|
+
const length = Math.max(this.numPoints, 1) * 64;
|
|
49
57
|
const fd = openSync(this.path + '/bn254_g1.dat', 'r');
|
|
50
58
|
const buffer = new Uint8Array(length);
|
|
51
59
|
readSync(fd, buffer, 0, length, 0);
|
|
@@ -66,10 +74,18 @@ export class Crs {
|
|
|
66
74
|
* Generic Grumpkin CRS finder utility class.
|
|
67
75
|
*/
|
|
68
76
|
export class GrumpkinCrs {
|
|
69
|
-
constructor(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
constructor(
|
|
78
|
+
public readonly numPoints: number,
|
|
79
|
+
public readonly path: string,
|
|
80
|
+
private readonly logger: (msg: string) => void = createDebug('bb.js:crs'),
|
|
81
|
+
) {}
|
|
82
|
+
|
|
83
|
+
static async new(
|
|
84
|
+
numPoints: number,
|
|
85
|
+
crsPath = homedir() + '/.bb-crs',
|
|
86
|
+
logger: (msg: string) => void = createDebug('bb.js:crs'),
|
|
87
|
+
) {
|
|
88
|
+
const crs = new GrumpkinCrs(numPoints, crsPath, logger);
|
|
73
89
|
await crs.init();
|
|
74
90
|
return crs;
|
|
75
91
|
}
|
|
@@ -82,11 +98,11 @@ export class GrumpkinCrs {
|
|
|
82
98
|
.catch(() => 0);
|
|
83
99
|
|
|
84
100
|
if (g1FileSize >= this.numPoints * 64 && g1FileSize % 64 == 0) {
|
|
85
|
-
|
|
101
|
+
this.logger(`Using cached Grumpkin CRS of size ${g1FileSize / 64}`);
|
|
86
102
|
return;
|
|
87
103
|
}
|
|
88
104
|
|
|
89
|
-
|
|
105
|
+
this.logger(`Downloading Grumpkin CRS of size ${this.numPoints} into ${this.path}`);
|
|
90
106
|
const crs = new NetGrumpkinCrs(this.numPoints);
|
|
91
107
|
await crs.init();
|
|
92
108
|
writeFileSync(this.path + '/grumpkin_g1.dat', crs.getG1Data());
|