Skip to content

Commit b75ca28

Browse files
committed
explaining changes to abi
1 parent 88bc381 commit b75ca28

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

  • yarn-project/stdlib/src/abi

yarn-project/stdlib/src/abi/abi.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ export const FunctionDebugMetadataSchema = z.object({
224224
acir_locations: z.record(z.number()),
225225
brillig_locations: z.record(z.record(z.number())),
226226
}),
227+
// `function_locations` is required in the static `DebugFileMap` type (noir-types compat), but legacy v4-next
228+
// artifacts were compiled before this field existed — see {@link fillMissingFunctionLocations} for the full
229+
// rationale. The preprocessor injects `[]` for missing entries so parsing succeeds; the cast restores the
230+
// output type since `z.preprocess` widens the schema's input type to `unknown`.
227231
files: z.preprocess(
228232
fillMissingFunctionLocations,
229233
z.record(
@@ -336,8 +340,28 @@ export type DebugFileMap = Record<
336340
>;
337341

338342
/**
339-
* Fills missing `function_locations` on each entry of a file map with an empty array.
340-
* Kept for backwards compatibility with artifacts compiled before `function_locations` was introduced.
343+
* Preprocessor for {@link FunctionDebugMetadataSchema} / {@link ContractArtifactSchema} that injects an empty
344+
* `function_locations` array on any file map entry missing it. Invoked via `z.preprocess(...)` before the strict
345+
* object schema runs, so legacy inputs do not fail validation.
346+
*
347+
* Why this exists on v4-next (and not on `next` / v5):
348+
*
349+
* - The Noir submodule on `next` was bumped past nightly-2026-03-19, which added `function_locations` to the
350+
* debug file map in the Noir `@aztec/noir-types` package and to every freshly-compiled artifact's `file_map`
351+
* entries. The matching stdlib change (making `DebugFileMap.function_locations` required) was done in one
352+
* go on `next`, so there `function_locations` is always present both at compile time and at runtime.
353+
*
354+
* - On v4-next we had to cherry-pick the Noir bump (chore: Update Noir to nightly-2026-04-10 (#22393)) without
355+
* re-running the full noir-projects compilation pipeline, so the on-disk contract and protocol-circuit
356+
* artifacts (e.g. `yarn-project/protocol-contracts/artifacts/AuthRegistry.json`) still carry the pre-update
357+
* `file_map` shape with only `source` + `path`. Separately, `ivc-integration` compares our `DebugFileMap`
358+
* against the Noir-types `DebugFileMap`, which *does* require `function_locations`, so we cannot simply make
359+
* our own field optional — that would break the structural compatibility check.
360+
*
361+
* - To satisfy both constraints at once we keep `function_locations` required in the static TypeScript type
362+
* (so `ivc-integration` keeps compiling) but relax the runtime input shape via this preprocessor (so legacy
363+
* artifacts keep parsing). Once all v4-next artifacts get regenerated with the new Noir compiler, this
364+
* helper — and both `z.preprocess(...)` wrappers — can be removed.
341365
*/
342366
function fillMissingFunctionLocations(val: unknown): unknown {
343367
if (val && typeof val === 'object') {
@@ -405,6 +429,10 @@ export const ContractArtifactSchema = zodFor<ContractArtifact>()(
405429
globals: z.record(z.array(AbiValueSchema)),
406430
}),
407431
storageLayout: z.record(z.object({ slot: schemas.Fr })),
432+
// Legacy v4-next contract artifacts (e.g. `protocol-contracts/artifacts/AuthRegistry.json`) were emitted
433+
// before Noir started including `function_locations` in their `file_map` entries — see
434+
// {@link fillMissingFunctionLocations} for the full rationale. The preprocessor injects `[]` for missing
435+
// entries so parsing succeeds without weakening the static `DebugFileMap` type.
408436
fileMap: z.preprocess(
409437
fillMissingFunctionLocations,
410438
z.record(

0 commit comments

Comments
 (0)