@aztec/bb.js 3.0.0-nightly.20251115 → 3.0.0-nightly.20251119
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/build/amd64-linux/bb +0 -0
- package/build/amd64-linux/nodejs_module.node +0 -0
- package/build/amd64-macos/bb +0 -0
- package/build/amd64-macos/nodejs_module.node +0 -0
- package/build/arm64-linux/bb +0 -0
- package/build/arm64-linux/nodejs_module.node +0 -0
- package/build/arm64-macos/bb +0 -0
- package/build/arm64-macos/nodejs_module.node +0 -0
- package/dest/browser/barretenberg/backend.d.ts +9 -23
- package/dest/browser/barretenberg/backend.d.ts.map +1 -1
- package/dest/browser/barretenberg/backend.js +24 -84
- package/dest/browser/barretenberg/index.d.ts +1 -3
- package/dest/browser/barretenberg/index.d.ts.map +1 -1
- package/dest/browser/barretenberg/index.js +15 -24
- package/dest/browser/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/browser/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/browser/barretenberg/testing/bigint-buffer.js +37 -0
- package/dest/browser/barretenberg/testing/fields.d.ts +16 -0
- package/dest/browser/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/browser/barretenberg/testing/fields.js +48 -0
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg-threads.js +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg.js +1 -1
- package/dest/browser/bb_backends/browser/platform.d.ts +4 -0
- package/dest/browser/bb_backends/browser/platform.d.ts.map +1 -0
- package/dest/browser/bb_backends/browser/platform.js +10 -0
- package/dest/browser/bb_backends/index.d.ts +8 -5
- package/dest/browser/bb_backends/index.d.ts.map +1 -1
- package/dest/browser/bb_backends/index.js +5 -5
- package/dest/browser/index.d.ts +1 -0
- package/dest/browser/index.d.ts.map +1 -1
- package/dest/browser/index.js +2 -1
- package/dest/node/barretenberg/backend.d.ts +9 -23
- package/dest/node/barretenberg/backend.d.ts.map +1 -1
- package/dest/node/barretenberg/backend.js +24 -84
- package/dest/node/barretenberg/blake2s.test.js +2 -2
- package/dest/node/barretenberg/index.d.ts +1 -3
- package/dest/node/barretenberg/index.d.ts.map +1 -1
- package/dest/node/barretenberg/index.js +15 -24
- package/dest/node/barretenberg/pedersen.test.js +2 -2
- package/dest/node/barretenberg/poseidon.bench.test.js +27 -68
- package/dest/node/barretenberg/poseidon.test.js +2 -2
- package/dest/node/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/node/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/node/barretenberg/testing/bigint-buffer.js +37 -0
- package/dest/node/barretenberg/testing/fields.d.ts +16 -0
- package/dest/node/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/node/barretenberg/testing/fields.js +48 -0
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node/bb_backends/browser/platform.d.ts +4 -0
- package/dest/node/bb_backends/browser/platform.d.ts.map +1 -0
- package/dest/node/bb_backends/browser/platform.js +10 -0
- package/dest/node/bb_backends/index.d.ts +8 -5
- package/dest/node/bb_backends/index.d.ts.map +1 -1
- package/dest/node/bb_backends/index.js +5 -5
- package/dest/node/bb_backends/node/index.d.ts.map +1 -1
- package/dest/node/bb_backends/node/index.js +12 -4
- package/dest/node/bb_backends/node/native_shm.d.ts +2 -1
- package/dest/node/bb_backends/node/native_shm.d.ts.map +1 -1
- package/dest/node/bb_backends/node/native_shm.js +50 -15
- package/dest/node/bb_backends/node/native_socket.d.ts +1 -1
- package/dest/node/bb_backends/node/native_socket.d.ts.map +1 -1
- package/dest/node/bb_backends/node/native_socket.js +28 -19
- package/dest/node/index.d.ts +1 -0
- package/dest/node/index.d.ts.map +1 -1
- package/dest/node/index.js +2 -1
- package/dest/node-cjs/barretenberg/backend.d.ts +9 -23
- package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/backend.js +30 -90
- package/dest/node-cjs/barretenberg/blake2s.test.js +6 -6
- package/dest/node-cjs/barretenberg/index.d.ts +1 -3
- package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/index.js +15 -24
- package/dest/node-cjs/barretenberg/pedersen.test.js +9 -9
- package/dest/node-cjs/barretenberg/poseidon.bench.test.js +36 -77
- package/dest/node-cjs/barretenberg/poseidon.test.js +4 -4
- package/dest/node-cjs/{bigint-array/index.d.ts → barretenberg/testing/bigint-buffer.d.ts} +1 -1
- package/dest/node-cjs/barretenberg/testing/bigint-buffer.d.ts.map +1 -0
- package/dest/node-cjs/barretenberg/testing/bigint-buffer.js +43 -0
- package/dest/node-cjs/barretenberg/testing/fields.d.ts +16 -0
- package/dest/node-cjs/barretenberg/testing/fields.d.ts.map +1 -0
- package/dest/node-cjs/barretenberg/testing/fields.js +52 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node-cjs/bb_backends/browser/platform.d.ts +4 -0
- package/dest/node-cjs/bb_backends/browser/platform.d.ts.map +1 -0
- package/dest/node-cjs/bb_backends/browser/platform.js +15 -0
- package/dest/node-cjs/bb_backends/index.d.ts +8 -5
- package/dest/node-cjs/bb_backends/index.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/index.js +5 -5
- package/dest/node-cjs/bb_backends/node/index.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/index.js +12 -4
- package/dest/node-cjs/bb_backends/node/native_shm.d.ts +2 -1
- package/dest/node-cjs/bb_backends/node/native_shm.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/native_shm.js +50 -15
- package/dest/node-cjs/bb_backends/node/native_socket.d.ts +1 -1
- package/dest/node-cjs/bb_backends/node/native_socket.d.ts.map +1 -1
- package/dest/node-cjs/bb_backends/node/native_socket.js +28 -19
- package/dest/node-cjs/index.d.ts +1 -0
- package/dest/node-cjs/index.d.ts.map +1 -1
- package/dest/node-cjs/index.js +4 -2
- package/package.json +1 -1
- package/src/barretenberg/backend.ts +19 -97
- package/src/barretenberg/blake2s.test.ts +1 -1
- package/src/barretenberg/index.ts +14 -24
- package/src/barretenberg/pedersen.test.ts +1 -1
- package/src/barretenberg/poseidon.bench.test.ts +109 -156
- package/src/barretenberg/poseidon.test.ts +1 -1
- package/src/{types → barretenberg/testing}/fields.ts +12 -26
- package/src/bb_backends/browser/platform.ts +11 -0
- package/src/bb_backends/index.ts +8 -5
- package/src/bb_backends/node/index.ts +23 -3
- package/src/bb_backends/node/native_shm.ts +51 -14
- package/src/bb_backends/node/native_socket.ts +31 -17
- package/src/index.ts +2 -0
- package/dest/browser/bigint-array/index.d.ts.map +0 -1
- package/dest/browser/bigint-array/index.js +0 -37
- package/dest/browser/serialize/index.d.ts +0 -2
- package/dest/browser/serialize/index.d.ts.map +0 -1
- package/dest/browser/serialize/index.js +0 -2
- package/dest/browser/serialize/serialize.d.ts +0 -18
- package/dest/browser/serialize/serialize.d.ts.map +0 -1
- package/dest/browser/serialize/serialize.js +0 -72
- package/dest/browser/types/fields.d.ts +0 -23
- package/dest/browser/types/fields.d.ts.map +0 -1
- package/dest/browser/types/fields.js +0 -61
- package/dest/browser/types/index.d.ts +0 -3
- package/dest/browser/types/index.d.ts.map +0 -1
- package/dest/browser/types/index.js +0 -3
- package/dest/browser/types/point.d.ts +0 -18
- package/dest/browser/types/point.d.ts.map +0 -1
- package/dest/browser/types/point.js +0 -28
- package/dest/node/bigint-array/index.d.ts.map +0 -1
- package/dest/node/bigint-array/index.js +0 -37
- package/dest/node/serialize/index.d.ts +0 -2
- package/dest/node/serialize/index.d.ts.map +0 -1
- package/dest/node/serialize/index.js +0 -2
- package/dest/node/serialize/serialize.d.ts +0 -18
- package/dest/node/serialize/serialize.d.ts.map +0 -1
- package/dest/node/serialize/serialize.js +0 -72
- package/dest/node/types/fields.d.ts +0 -23
- package/dest/node/types/fields.d.ts.map +0 -1
- package/dest/node/types/fields.js +0 -61
- package/dest/node/types/index.d.ts +0 -3
- package/dest/node/types/index.d.ts.map +0 -1
- package/dest/node/types/index.js +0 -3
- package/dest/node/types/point.d.ts +0 -18
- package/dest/node/types/point.d.ts.map +0 -1
- package/dest/node/types/point.js +0 -28
- package/dest/node-cjs/bigint-array/index.d.ts.map +0 -1
- package/dest/node-cjs/bigint-array/index.js +0 -43
- package/dest/node-cjs/serialize/index.d.ts +0 -2
- package/dest/node-cjs/serialize/index.d.ts.map +0 -1
- package/dest/node-cjs/serialize/index.js +0 -5
- package/dest/node-cjs/serialize/serialize.d.ts +0 -18
- package/dest/node-cjs/serialize/serialize.d.ts.map +0 -1
- package/dest/node-cjs/serialize/serialize.js +0 -82
- package/dest/node-cjs/types/fields.d.ts +0 -23
- package/dest/node-cjs/types/fields.d.ts.map +0 -1
- package/dest/node-cjs/types/fields.js +0 -65
- package/dest/node-cjs/types/index.d.ts +0 -3
- package/dest/node-cjs/types/index.d.ts.map +0 -1
- package/dest/node-cjs/types/index.js +0 -6
- package/dest/node-cjs/types/point.d.ts +0 -18
- package/dest/node-cjs/types/point.d.ts.map +0 -1
- package/dest/node-cjs/types/point.js +0 -32
- package/src/serialize/index.ts +0 -1
- package/src/serialize/serialize.ts +0 -75
- package/src/types/index.ts +0 -2
- package/src/types/point.ts +0 -32
- /package/src/{bigint-array/index.ts → barretenberg/testing/bigint-buffer.ts} +0 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Barretenberg, BarretenbergSync } from '../index.js';
|
|
2
|
-
import { Fr } from '../types/fields.js';
|
|
3
|
-
import { serializeBufferable } from '../serialize/index.js';
|
|
4
2
|
import { BarretenbergWasmMain } from '../barretenberg_wasm/barretenberg_wasm_main/index.js';
|
|
5
3
|
import { fetchModuleAndThreads } from '../barretenberg_wasm/index.js';
|
|
6
4
|
import { BackendType } from './index.js';
|
|
5
|
+
import { Fr } from './testing/fields.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Async API benchmark test: WASM vs Native backends with proper non-blocking I/O
|
|
@@ -67,170 +66,129 @@ describe('poseidon2Hash benchmark (Async API): WASM vs Native', () => {
|
|
|
67
66
|
}
|
|
68
67
|
}, 20000);
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
if (nativeShmApi) {
|
|
79
|
-
await nativeShmApi.destroy();
|
|
80
|
-
}
|
|
81
|
-
if (nativeShmSyncApi) {
|
|
82
|
-
nativeShmSyncApi.destroy();
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
async function directPoseidon2Hash(inputsBuffer: Fr[]): Promise<Fr> {
|
|
87
|
-
const inArgs = [inputsBuffer].map(serializeBufferable);
|
|
88
|
-
const outTypes = [Fr];
|
|
89
|
-
const result = wasm.callWasmExport(
|
|
90
|
-
'poseidon2_hash',
|
|
91
|
-
inArgs,
|
|
92
|
-
outTypes.map(t => t.SIZE_IN_BYTES),
|
|
93
|
-
);
|
|
94
|
-
const out = result.map((r, i) => outTypes[i].fromBuffer(r));
|
|
95
|
-
return Promise.resolve(out[0]);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
it.each(SIZES)('benchmark with %p field elements', async size => {
|
|
99
|
-
// Generate random inputs
|
|
100
|
-
const inputs = Array(size)
|
|
101
|
-
.fill(0)
|
|
102
|
-
.map(() => Fr.random());
|
|
103
|
-
|
|
104
|
-
// Benchmark 1: Direct WASM (baseline - always available)
|
|
105
|
-
const directStart = performance.now();
|
|
106
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
107
|
-
await directPoseidon2Hash(inputs);
|
|
108
|
-
}
|
|
109
|
-
const directTime = performance.now() - directStart;
|
|
69
|
+
it.each(SIZES)(
|
|
70
|
+
'benchmark with %p field elements',
|
|
71
|
+
async size => {
|
|
72
|
+
// Generate random inputs
|
|
73
|
+
const inputs = Array(size)
|
|
74
|
+
.fill(0)
|
|
75
|
+
.map(() => Fr.random().toBuffer());
|
|
110
76
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
77
|
+
// Benchmark 1: WASM (async)
|
|
78
|
+
let wasmTime = 0;
|
|
79
|
+
if (wasmApi) {
|
|
80
|
+
const wasmStart = performance.now();
|
|
81
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
82
|
+
await wasmApi.poseidon2Hash({ inputs });
|
|
83
|
+
}
|
|
84
|
+
wasmTime = performance.now() - wasmStart;
|
|
117
85
|
}
|
|
118
|
-
wasmTime = performance.now() - wasmStart;
|
|
119
|
-
}
|
|
120
86
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
87
|
+
// Benchmark 2: Native Socket (async with non-blocking I/O)
|
|
88
|
+
let nativeSocketTime = 0;
|
|
89
|
+
if (nativeSocketApi) {
|
|
90
|
+
const nativeSocketStart = performance.now();
|
|
91
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
92
|
+
await nativeSocketApi.poseidon2Hash({ inputs });
|
|
93
|
+
}
|
|
94
|
+
nativeSocketTime = performance.now() - nativeSocketStart;
|
|
127
95
|
}
|
|
128
|
-
nativeSocketTime = performance.now() - nativeSocketStart;
|
|
129
|
-
}
|
|
130
96
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
97
|
+
// Benchmark 3: Native Shared Memory (async)
|
|
98
|
+
let nativeShmTime = 0;
|
|
99
|
+
if (nativeShmApi) {
|
|
100
|
+
const nativeShmStart = performance.now();
|
|
101
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
102
|
+
await nativeShmApi.poseidon2Hash({ inputs });
|
|
103
|
+
}
|
|
104
|
+
nativeShmTime = performance.now() - nativeShmStart;
|
|
137
105
|
}
|
|
138
|
-
nativeShmTime = performance.now() - nativeShmStart;
|
|
139
|
-
}
|
|
140
106
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
107
|
+
// Benchmark 4: Native Shared Memory (sync)
|
|
108
|
+
let nativeShmSyncTime = 0;
|
|
109
|
+
if (nativeShmSyncApi) {
|
|
110
|
+
const nativeShmSyncStart = performance.now();
|
|
111
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
112
|
+
nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
113
|
+
}
|
|
114
|
+
nativeShmSyncTime = performance.now() - nativeShmSyncStart;
|
|
147
115
|
}
|
|
148
|
-
nativeShmSyncTime = performance.now() - nativeShmSyncStart;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Calculate metrics (all relative to WASM baseline)
|
|
152
|
-
const directOverhead = ((directTime - wasmTime) / wasmTime) * 100;
|
|
153
|
-
const nativeSocketOverhead = ((nativeSocketTime - wasmTime) / wasmTime) * 100;
|
|
154
|
-
const nativeShmOverhead = ((nativeShmTime - wasmTime) / wasmTime) * 100;
|
|
155
|
-
const nativeShmSyncOverhead = ((nativeShmSyncTime - wasmTime) / wasmTime) * 100;
|
|
156
116
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const avgNativeShmSyncTimeUs = (nativeShmSyncTime / ITERATIONS) * 1000;
|
|
117
|
+
// Calculate metrics (all relative to WASM baseline)
|
|
118
|
+
const nativeSocketOverhead = ((nativeSocketTime - wasmTime) / wasmTime) * 100;
|
|
119
|
+
const nativeShmOverhead = ((nativeShmTime - wasmTime) / wasmTime) * 100;
|
|
120
|
+
const nativeShmSyncOverhead = ((nativeShmSyncTime - wasmTime) / wasmTime) * 100;
|
|
162
121
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
return `${sign}${value}%`;
|
|
168
|
-
};
|
|
122
|
+
const avgWasmTimeUs = (wasmTime / ITERATIONS) * 1000;
|
|
123
|
+
const avgNativeSocketTimeUs = (nativeSocketTime / ITERATIONS) * 1000;
|
|
124
|
+
const avgNativeShmTimeUs = (nativeShmTime / ITERATIONS) * 1000;
|
|
125
|
+
const avgNativeShmSyncTimeUs = (nativeShmSyncTime / ITERATIONS) * 1000;
|
|
169
126
|
|
|
170
|
-
if (wasmApi) {
|
|
171
127
|
process.stdout.write(
|
|
172
|
-
|
|
128
|
+
`┌─ Size ${size.toString().padStart(3)} field elements ──────────────────────────────────┐\n`,
|
|
173
129
|
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
130
|
+
const formatOverhead = (overhead: number): string => {
|
|
131
|
+
const sign = overhead >= 0 ? '+' : '-';
|
|
132
|
+
const value = Math.abs(overhead).toFixed(1).padStart(6);
|
|
133
|
+
return `${sign}${value}%`;
|
|
134
|
+
};
|
|
177
135
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
} else {
|
|
187
|
-
process.stdout.write(`│ Native Socket: unavailable │\n`);
|
|
188
|
-
}
|
|
136
|
+
if (wasmApi) {
|
|
137
|
+
process.stdout.write(
|
|
138
|
+
`│ WASM: ${wasmTime.toFixed(2).padStart(8)}ms (${avgWasmTimeUs.toFixed(2).padStart(7)}µs/call) [baseline] │\n`,
|
|
139
|
+
);
|
|
140
|
+
} else {
|
|
141
|
+
process.stdout.write(`│ WASM: unavailable │\n`);
|
|
142
|
+
}
|
|
189
143
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
144
|
+
if (nativeSocketApi) {
|
|
145
|
+
process.stdout.write(
|
|
146
|
+
`│ Native Socket: ${nativeSocketTime.toFixed(2).padStart(8)}ms (${avgNativeSocketTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeSocketOverhead)} │\n`,
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
process.stdout.write(`│ Native Socket: unavailable │\n`);
|
|
150
|
+
}
|
|
197
151
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
152
|
+
if (nativeShmApi) {
|
|
153
|
+
process.stdout.write(
|
|
154
|
+
`│ Native Shared: ${nativeShmTime.toFixed(2).padStart(8)}ms (${avgNativeShmTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeShmOverhead)} │\n`,
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
process.stdout.write(`│ Native Shared: unavailable │\n`);
|
|
158
|
+
}
|
|
205
159
|
|
|
206
|
-
|
|
160
|
+
if (nativeShmSyncApi) {
|
|
161
|
+
process.stdout.write(
|
|
162
|
+
`│ Native Shared Sync: ${nativeShmSyncTime.toFixed(2).padStart(8)}ms (${avgNativeShmSyncTimeUs.toFixed(2).padStart(7)}µs/call) ${formatOverhead(nativeShmSyncOverhead)} │\n`,
|
|
163
|
+
);
|
|
164
|
+
} else {
|
|
165
|
+
process.stdout.write(`│ Native Shared Sync: unavailable │\n`);
|
|
166
|
+
}
|
|
207
167
|
|
|
208
|
-
|
|
209
|
-
const directResult = await directPoseidon2Hash(inputs);
|
|
168
|
+
process.stdout.write(`└────────────────────────────────────────────────────────────┘\n`);
|
|
210
169
|
|
|
211
|
-
|
|
212
|
-
const wasmResult = await wasmApi.poseidon2Hash({ inputs: inputs.map(fr => fr.toBuffer()) });
|
|
213
|
-
expect(Buffer.from(wasmResult.hash)).toEqual(directResult.toBuffer());
|
|
214
|
-
}
|
|
170
|
+
const wasmResult = await wasmApi!.poseidon2Hash({ inputs });
|
|
215
171
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
172
|
+
if (nativeSocketApi) {
|
|
173
|
+
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs });
|
|
174
|
+
expect(Buffer.from(nativeSocketResult.hash)).toEqual(wasmResult.hash);
|
|
175
|
+
}
|
|
220
176
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
177
|
+
if (nativeShmApi) {
|
|
178
|
+
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs });
|
|
179
|
+
expect(Buffer.from(nativeShmResult.hash)).toEqual(wasmResult.hash);
|
|
180
|
+
}
|
|
225
181
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
182
|
+
if (nativeShmSyncApi) {
|
|
183
|
+
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
184
|
+
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(wasmResult.hash);
|
|
185
|
+
}
|
|
230
186
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
187
|
+
// Test always passes, this is just for measuring performance
|
|
188
|
+
expect(true).toBe(true);
|
|
189
|
+
},
|
|
190
|
+
10000,
|
|
191
|
+
);
|
|
234
192
|
|
|
235
193
|
const TEST_VECTORS = [1, 2, 3, 5, 10, 50, 100];
|
|
236
194
|
const NUM_RANDOM_TESTS = 10;
|
|
@@ -240,28 +198,23 @@ describe('poseidon2Hash benchmark (Async API): WASM vs Native', () => {
|
|
|
240
198
|
for (let test = 0; test < NUM_RANDOM_TESTS; test++) {
|
|
241
199
|
const inputs = Array(size)
|
|
242
200
|
.fill(0)
|
|
243
|
-
.map(() => Fr.random());
|
|
201
|
+
.map(() => Fr.random().toBuffer());
|
|
244
202
|
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
if (wasmApi) {
|
|
248
|
-
const wasmResult = await wasmApi.poseidon2Hash({ inputs: inputs.map(fr => fr.toBuffer()) });
|
|
249
|
-
expect(Buffer.from(wasmResult.hash)).toEqual(directResult.toBuffer());
|
|
250
|
-
}
|
|
203
|
+
const wasmResult = await wasmApi!.poseidon2Hash({ inputs });
|
|
251
204
|
|
|
252
205
|
if (nativeSocketApi) {
|
|
253
|
-
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs
|
|
254
|
-
expect(Buffer.from(nativeSocketResult.hash)).toEqual(
|
|
206
|
+
const nativeSocketResult = await nativeSocketApi.poseidon2Hash({ inputs });
|
|
207
|
+
expect(Buffer.from(nativeSocketResult.hash)).toEqual(wasmResult.hash);
|
|
255
208
|
}
|
|
256
209
|
|
|
257
210
|
if (nativeShmApi) {
|
|
258
|
-
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs
|
|
259
|
-
expect(Buffer.from(nativeShmResult.hash)).toEqual(
|
|
211
|
+
const nativeShmResult = await nativeShmApi.poseidon2Hash({ inputs });
|
|
212
|
+
expect(Buffer.from(nativeShmResult.hash)).toEqual(wasmResult.hash);
|
|
260
213
|
}
|
|
261
214
|
|
|
262
215
|
if (nativeShmSyncApi) {
|
|
263
|
-
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs
|
|
264
|
-
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(
|
|
216
|
+
const nativeShmSyncResult = nativeShmSyncApi.poseidon2Hash({ inputs });
|
|
217
|
+
expect(Buffer.from(nativeShmSyncResult.hash)).toEqual(wasmResult.hash);
|
|
265
218
|
}
|
|
266
219
|
}
|
|
267
220
|
});
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { randomBytes } from '
|
|
1
|
+
import { randomBytes } from '../../random/index.js';
|
|
2
2
|
import {
|
|
3
3
|
buffer32BytesToBigIntBE,
|
|
4
4
|
uint8ArrayToBigIntBE,
|
|
5
5
|
bigIntToBufferBE,
|
|
6
6
|
bigIntToUint8ArrayBE,
|
|
7
|
-
} from '
|
|
7
|
+
} from './bigint-buffer.js';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Internal Fr field class for tests.
|
|
11
|
-
* @dev This minimal implementation is provided for testing barretenberg directly.
|
|
12
|
-
* Projects using bb.js should create their own field abstraction using the curve constants
|
|
13
|
-
* exported from the barretenberg binary (see CurveConstants generation).
|
|
14
|
-
*/
|
|
15
9
|
export class Fr {
|
|
16
10
|
static ZERO = new Fr(0n);
|
|
17
11
|
static MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
|
|
@@ -41,24 +35,6 @@ export class Fr {
|
|
|
41
35
|
return new this(r);
|
|
42
36
|
}
|
|
43
37
|
|
|
44
|
-
static fromBuffer(buffer: Uint8Array | Buffer) {
|
|
45
|
-
if (buffer.length !== this.SIZE_IN_BYTES) {
|
|
46
|
-
throw new Error(`Expected ${this.SIZE_IN_BYTES} bytes, got ${buffer.length}`);
|
|
47
|
-
}
|
|
48
|
-
return new this(buffer);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
static fromBufferReduce(buffer: Uint8Array | Buffer) {
|
|
52
|
-
if (buffer.length !== this.SIZE_IN_BYTES) {
|
|
53
|
-
throw new Error(`Expected ${this.SIZE_IN_BYTES} bytes, got ${buffer.length}`);
|
|
54
|
-
}
|
|
55
|
-
return new this(uint8ArrayToBigIntBE(buffer instanceof Buffer ? new Uint8Array(buffer) : buffer) % Fr.MODULUS);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static fromString(str: string) {
|
|
59
|
-
return this.fromBuffer(Buffer.from(str.replace(/^0x/i, ''), 'hex'));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
38
|
toBuffer() {
|
|
63
39
|
return this.value;
|
|
64
40
|
}
|
|
@@ -74,4 +50,14 @@ export class Fr {
|
|
|
74
50
|
isZero() {
|
|
75
51
|
return this.value.every(v => v === 0);
|
|
76
52
|
}
|
|
53
|
+
|
|
54
|
+
static fromBuffer(value: Uint8Array): Fr {
|
|
55
|
+
return Fr.fromBufferReduce(value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static fromBufferReduce(value: Uint8Array): Fr {
|
|
59
|
+
const valueBigInt = uint8ArrayToBigIntBE(value);
|
|
60
|
+
const reducedValue = valueBigInt % Fr.MODULUS;
|
|
61
|
+
return new Fr(reducedValue);
|
|
62
|
+
}
|
|
77
63
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function findPackageRoot(): string | null {
|
|
2
|
+
throw new Error('Not implemented in browser environment.');
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function findBbBinary(customPath?: string): string | null {
|
|
6
|
+
throw new Error('Not implemented in browser environment.');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function findNapiBinary(customPath?: string): string | null {
|
|
10
|
+
throw new Error('Not implemented in browser environment.');
|
|
11
|
+
}
|
package/src/bb_backends/index.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export enum BackendType {
|
|
5
5
|
/** WASM direct execution (no worker) */
|
|
6
|
-
Wasm = '
|
|
6
|
+
Wasm = 'Wasm',
|
|
7
7
|
/** WASM with worker threads */
|
|
8
|
-
WasmWorker = '
|
|
8
|
+
WasmWorker = 'WasmWorker',
|
|
9
9
|
/** Native via Unix domain socket (async only) */
|
|
10
|
-
NativeUnixSocket = '
|
|
10
|
+
NativeUnixSocket = 'NativeUnixSocket',
|
|
11
11
|
/** Native via shared memory (sync only currently) */
|
|
12
|
-
NativeSharedMemory = '
|
|
12
|
+
NativeSharedMemory = 'NativeSharedMemory',
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export type BackendOptions = {
|
|
@@ -28,7 +28,10 @@ export type BackendOptions = {
|
|
|
28
28
|
/** @description Custom path to bb binary for native backend (overrides automatic detection) */
|
|
29
29
|
bbPath?: string;
|
|
30
30
|
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* @description Logging function
|
|
33
|
+
* Warning: Attaching a logger can prevent nodejs from exiting without explicitly destroying the backend.
|
|
34
|
+
*/
|
|
32
35
|
logger?: (msg: string) => void;
|
|
33
36
|
|
|
34
37
|
/**
|
|
@@ -14,6 +14,11 @@ export async function createAsyncBackend(
|
|
|
14
14
|
options: BackendOptions,
|
|
15
15
|
logger: (msg: string) => void,
|
|
16
16
|
): Promise<Barretenberg> {
|
|
17
|
+
options = {
|
|
18
|
+
...options,
|
|
19
|
+
wasmPath: options.wasmPath ?? process.env.BB_WASM_PATH,
|
|
20
|
+
};
|
|
21
|
+
|
|
17
22
|
switch (type) {
|
|
18
23
|
case BackendType.NativeUnixSocket: {
|
|
19
24
|
const bbPath = findBbBinary(options.bbPath);
|
|
@@ -21,7 +26,7 @@ export async function createAsyncBackend(
|
|
|
21
26
|
throw new Error('Native backend requires bb binary.');
|
|
22
27
|
}
|
|
23
28
|
logger(`Using native Unix socket backend: ${bbPath}`);
|
|
24
|
-
const socket = new BarretenbergNativeSocketAsyncBackend(bbPath, options.threads);
|
|
29
|
+
const socket = new BarretenbergNativeSocketAsyncBackend(bbPath, options.threads, options.logger);
|
|
25
30
|
return new Barretenberg(socket, options);
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -36,7 +41,12 @@ export async function createAsyncBackend(
|
|
|
36
41
|
}
|
|
37
42
|
logger(`Using native shared memory backend (via sync adapter): ${bbPath}`);
|
|
38
43
|
// Use sync backend with adapter to provide async interface
|
|
39
|
-
const syncBackend = await BarretenbergNativeShmSyncBackend.new(
|
|
44
|
+
const syncBackend = await BarretenbergNativeShmSyncBackend.new(
|
|
45
|
+
bbPath,
|
|
46
|
+
options.threads,
|
|
47
|
+
options.maxClients,
|
|
48
|
+
options.logger,
|
|
49
|
+
);
|
|
40
50
|
const asyncBackend = new SyncToAsyncAdapter(syncBackend);
|
|
41
51
|
return new Barretenberg(asyncBackend, options);
|
|
42
52
|
}
|
|
@@ -68,6 +78,11 @@ export async function createSyncBackend(
|
|
|
68
78
|
options: BackendOptions,
|
|
69
79
|
logger: (msg: string) => void,
|
|
70
80
|
): Promise<BarretenbergSync> {
|
|
81
|
+
options = {
|
|
82
|
+
...options,
|
|
83
|
+
wasmPath: options.wasmPath ?? process.env.BB_WASM_PATH,
|
|
84
|
+
};
|
|
85
|
+
|
|
71
86
|
switch (type) {
|
|
72
87
|
case BackendType.NativeSharedMemory: {
|
|
73
88
|
const bbPath = findBbBinary(options.bbPath);
|
|
@@ -79,7 +94,12 @@ export async function createSyncBackend(
|
|
|
79
94
|
throw new Error('Native sync backend requires napi client stub.');
|
|
80
95
|
}
|
|
81
96
|
logger(`Using native shared memory backend: ${bbPath}`);
|
|
82
|
-
const shm = await BarretenbergNativeShmSyncBackend.new(
|
|
97
|
+
const shm = await BarretenbergNativeShmSyncBackend.new(
|
|
98
|
+
bbPath,
|
|
99
|
+
options.threads,
|
|
100
|
+
options.maxClients,
|
|
101
|
+
options.logger,
|
|
102
|
+
);
|
|
83
103
|
return new BarretenbergSync(shm);
|
|
84
104
|
}
|
|
85
105
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
2
|
import { spawn, ChildProcess } from 'child_process';
|
|
3
|
+
import { openSync, closeSync } from 'fs';
|
|
3
4
|
import { IMsgpackBackendSync } from '../interface.js';
|
|
4
5
|
import { findNapiBinary, findPackageRoot } from './platform.js';
|
|
6
|
+
import readline from 'readline';
|
|
5
7
|
|
|
6
8
|
// Import the NAPI module
|
|
7
9
|
// The addon is built to the nodejs_module directory
|
|
@@ -32,10 +34,12 @@ try {
|
|
|
32
34
|
export class BarretenbergNativeShmSyncBackend implements IMsgpackBackendSync {
|
|
33
35
|
private process: ChildProcess;
|
|
34
36
|
private client: any; // NAPI MsgpackClient instance
|
|
37
|
+
private logFd?: number; // File descriptor for logs
|
|
35
38
|
|
|
36
|
-
private constructor(process: ChildProcess, client: any) {
|
|
39
|
+
private constructor(process: ChildProcess, client: any, logFd?: number) {
|
|
37
40
|
this.process = process;
|
|
38
41
|
this.client = client;
|
|
42
|
+
this.logFd = logFd;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
/**
|
|
@@ -48,6 +52,7 @@ export class BarretenbergNativeShmSyncBackend implements IMsgpackBackendSync {
|
|
|
48
52
|
bbBinaryPath: string,
|
|
49
53
|
threads?: number,
|
|
50
54
|
maxClients?: number,
|
|
55
|
+
logger?: (msg: string) => void,
|
|
51
56
|
): Promise<BarretenbergNativeShmSyncBackend> {
|
|
52
57
|
if (!addon || !addon.MsgpackClient) {
|
|
53
58
|
throw new Error('Shared memory NAPI not available.');
|
|
@@ -59,22 +64,40 @@ export class BarretenbergNativeShmSyncBackend implements IMsgpackBackendSync {
|
|
|
59
64
|
// Default maxClients to 1 if not specified
|
|
60
65
|
const clientCount = maxClients ?? 1;
|
|
61
66
|
|
|
62
|
-
//
|
|
63
|
-
const
|
|
67
|
+
// If threads not set use 1 thread. We're not expected to do long lived work on sync backends.
|
|
68
|
+
const hwc = threads ? threads.toString() : '1';
|
|
69
|
+
const env = { ...process.env, HARDWARE_CONCURRENCY: '1' };
|
|
70
|
+
|
|
71
|
+
// Set up file logging if logger is provided.
|
|
72
|
+
// Direct file redirection bypasses Node event loop - logs are written even if process hangs.
|
|
73
|
+
let logFd: number | undefined;
|
|
74
|
+
let logPath: string | undefined;
|
|
75
|
+
if (logger) {
|
|
76
|
+
logPath = `/tmp/${shmName}.log`;
|
|
77
|
+
logFd = openSync(logPath, 'w');
|
|
78
|
+
logger(`BB process logs redirected to: ${logPath}`);
|
|
79
|
+
}
|
|
64
80
|
|
|
65
81
|
// Spawn bb process with shared memory mode
|
|
66
|
-
const args = [
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
const args = [
|
|
83
|
+
'msgpack',
|
|
84
|
+
'run',
|
|
85
|
+
'--input',
|
|
86
|
+
`${shmName}.shm`,
|
|
87
|
+
'--max-clients',
|
|
88
|
+
clientCount.toString(),
|
|
89
|
+
'--request-ring-size',
|
|
90
|
+
`${1024 * 1024 * 2}`,
|
|
91
|
+
];
|
|
92
|
+
const bbProcess = spawn(bbBinaryPath, args, {
|
|
93
|
+
stdio: ['ignore', logFd ?? 'ignore', logFd ?? 'ignore'],
|
|
69
94
|
env,
|
|
70
95
|
});
|
|
71
|
-
// Disconnect from event loop so process can exit. The kill wrapper will reap bb once parent (node) dies.
|
|
72
|
-
bbProcess.unref();
|
|
73
96
|
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
97
|
+
// Disconnect from event loop so process can exit without waiting for bb
|
|
98
|
+
// The bb process has parent death monitoring (prctl on Linux, kqueue on macOS)
|
|
99
|
+
// so it will automatically exit when Node.js exits
|
|
100
|
+
bbProcess.unref();
|
|
78
101
|
|
|
79
102
|
// Track if process has exited
|
|
80
103
|
let processExited = false;
|
|
@@ -133,12 +156,19 @@ export class BarretenbergNativeShmSyncBackend implements IMsgpackBackendSync {
|
|
|
133
156
|
throw new Error('Failed to create client connection');
|
|
134
157
|
}
|
|
135
158
|
|
|
136
|
-
return new BarretenbergNativeShmSyncBackend(bbProcess, client);
|
|
159
|
+
return new BarretenbergNativeShmSyncBackend(bbProcess, client, logFd);
|
|
137
160
|
} finally {
|
|
138
|
-
// If we failed to connect, ensure the process is killed
|
|
161
|
+
// If we failed to connect, ensure the process is killed and log file closed
|
|
139
162
|
// kill() returns false if process already exited, but doesn't throw
|
|
140
163
|
if (!client) {
|
|
141
164
|
bbProcess.kill('SIGKILL');
|
|
165
|
+
if (logFd !== undefined) {
|
|
166
|
+
try {
|
|
167
|
+
closeSync(logFd);
|
|
168
|
+
} catch (e) {
|
|
169
|
+
// Ignore errors during cleanup
|
|
170
|
+
}
|
|
171
|
+
}
|
|
142
172
|
}
|
|
143
173
|
}
|
|
144
174
|
}
|
|
@@ -160,6 +190,13 @@ export class BarretenbergNativeShmSyncBackend implements IMsgpackBackendSync {
|
|
|
160
190
|
// Ignore errors during cleanup
|
|
161
191
|
}
|
|
162
192
|
}
|
|
193
|
+
if (this.logFd !== undefined) {
|
|
194
|
+
try {
|
|
195
|
+
closeSync(this.logFd);
|
|
196
|
+
} catch (e) {
|
|
197
|
+
// Ignore errors during cleanup
|
|
198
|
+
}
|
|
199
|
+
}
|
|
163
200
|
}
|
|
164
201
|
|
|
165
202
|
destroy(): void {
|