Skip to content

Commit 4b89f14

Browse files
authored
Merge pull request #2460 from o1-labs/florian/properly-fix-cache
Store all cache artefacts
2 parents 1a9bbe7 + 00dd71e commit 4b89f14

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ This project adheres to
3232
- Fixed a verification key regression that was caused by incorrectly enabling a
3333
proof system feature that wasn't needed.
3434
https://github.com/o1-labs/o1js/pull/2449
35+
- Fixed an edge case where not all the artefacts needed for the cache were
36+
stored properly, resulting in them being re-computed after loading the cache.
37+
https://github.com/o1-labs/o1js/pull/2460
3538

3639
### Deprecated
3740

src/bindings/crypto/bindings/srs.ts

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Wasm, RustConversion } from '../bindings.js';
2-
import type { WasmFpSrs, WasmFqSrs } from '../../compiled/node_bindings/plonk_wasm.cjs';
2+
import { type WasmFpSrs, type WasmFqSrs } from '../../compiled/node_bindings/plonk_wasm.cjs';
33
import { PolyComm } from './kimchi-types.js';
44
import {
55
type CacheHeader,
@@ -24,6 +24,8 @@ function empty(): SrsStore {
2424

2525
const srsStore = { fp: empty(), fq: empty() };
2626

27+
const CacheReadRegister = new Map<string, boolean>();
28+
2729
let cache: Cache | undefined;
2830

2931
function setSrsCache(c: Cache) {
@@ -143,16 +145,15 @@ function srsPerField(f: 'fp' | 'fq', wasm: Wasm, conversion: RustConversion) {
143145
} else {
144146
// try to read lagrange basis from cache / recompute and write if not found
145147
let header = cacheHeaderLagrange(f, domainSize);
146-
147-
let didRead = readCache(cache, header, (bytes) => {
148-
let comms: PolyCommJson[] = JSON.parse(new TextDecoder().decode(bytes));
149-
let mlComms = polyCommsFromJSON(comms);
150-
let wasmComms = conversion[f].polyCommsToRust(mlComms);
151-
152-
setLagrangeBasis(srs, domainSize, wasmComms);
153-
return true;
154-
});
155-
148+
let didRead = readCacheLazy(
149+
cache,
150+
header,
151+
conversion,
152+
f,
153+
srs,
154+
domainSize,
155+
setLagrangeBasis
156+
);
156157
if (didRead !== true) {
157158
// not in cache
158159
if (cache.canWrite) {
@@ -167,13 +168,39 @@ function srsPerField(f: 'fp' | 'fq', wasm: Wasm, conversion: RustConversion) {
167168
lagrangeCommitment(srs, domainSize, i);
168169
}
169170
}
170-
171171
// here, basis is definitely stored on the srs
172172
let c = maybeLagrangeCommitment(srs, domainSize, i);
173173
assert(c !== undefined, 'commitment exists after setting');
174174
commitment = c;
175175
}
176176
}
177+
178+
// edge case for when we have a writeable cache and the basis was already stored on the srs
179+
// but we didn't store it in the cache seperately yet
180+
if (commitment && cache && cache.canWrite) {
181+
let header = cacheHeaderLagrange(f, domainSize);
182+
let didRead = readCacheLazy(
183+
cache,
184+
header,
185+
conversion,
186+
f,
187+
srs,
188+
domainSize,
189+
setLagrangeBasis
190+
);
191+
// only proceed for entries we haven't written to the cache yet
192+
if (didRead !== true) {
193+
// same code as above - write the lagrange basis to the cache if it wasn't there already
194+
// currently we re-generate the basis via `getLagrangeBasis` - we could derive this from the
195+
// already existing `commitment` instead, but this is simpler and the performance impact is negligible
196+
let wasmComms = getLagrangeBasis(srs, domainSize);
197+
let mlComms = conversion[f].polyCommsFromRust(wasmComms);
198+
let comms = polyCommsToJSON(mlComms);
199+
let bytes = new TextEncoder().encode(JSON.stringify(comms));
200+
201+
writeCache(cache, header, bytes);
202+
}
203+
}
177204
return conversion[f].polyCommFromRust(commitment);
178205
},
179206

@@ -222,3 +249,24 @@ function polyCommsFromJSON(json: PolyCommJson[]): MlArray<PolyComm> {
222249
return [0, MlArray.mapTo(shifted, OrInfinity.fromJSON)];
223250
});
224251
}
252+
253+
function readCacheLazy(
254+
cache: Cache,
255+
header: CacheHeader,
256+
conversion: RustConversion,
257+
f: 'fp' | 'fq',
258+
srs: WasmSrs,
259+
domainSize: number,
260+
setLagrangeBasis: (srs: WasmSrs, domainSize: number, comms: Uint32Array) => void
261+
) {
262+
if (CacheReadRegister.get(header.uniqueId) === true) return true;
263+
return readCache(cache, header, (bytes) => {
264+
let comms: PolyCommJson[] = JSON.parse(new TextDecoder().decode(bytes));
265+
let mlComms = polyCommsFromJSON(comms);
266+
let wasmComms = conversion[f].polyCommsToRust(mlComms);
267+
268+
setLagrangeBasis(srs, domainSize, wasmComms);
269+
CacheReadRegister.set(header.uniqueId, true);
270+
return true;
271+
});
272+
}

0 commit comments

Comments
 (0)