@aztec/txe 5.0.0-nightly.20260707 → 5.0.0-nightly.20260708

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.
Files changed (44) hide show
  1. package/dest/AuthRegistry-D774QM2G.js +3 -0
  2. package/dest/AuthRegistry-D774QM2G.js.map +7 -0
  3. package/dest/HandshakeRegistry-4AIT55KH.js +3 -0
  4. package/dest/HandshakeRegistry-4AIT55KH.js.map +7 -0
  5. package/dest/{MultiCallEntrypoint-DSXOIHSY.js → MultiCallEntrypoint-WICVQACI.js} +1 -1
  6. package/dest/{MultiCallEntrypoint-DSXOIHSY.js.map → MultiCallEntrypoint-WICVQACI.js.map} +2 -2
  7. package/dest/SchnorrAccount-Y2WZTBJF.js +3 -0
  8. package/dest/SchnorrAccount-Y2WZTBJF.js.map +7 -0
  9. package/dest/bin/index.js +1 -1
  10. package/dest/{chunk-NRS7MF3Z.js → chunk-2LYGEVHI.js} +2 -2
  11. package/dest/{chunk-SHQZNKOL.js → chunk-HLH2NBQI.js} +9 -9
  12. package/dest/{chunk-SHQZNKOL.js.map → chunk-HLH2NBQI.js.map} +4 -4
  13. package/dest/index.d.ts +1 -1
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +5 -3
  16. package/dest/metafile.json +137 -104
  17. package/dest/oracle/test-resolver/default_fixtures.d.ts +3 -3
  18. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -1
  19. package/dest/oracle/test-resolver/default_fixtures.js +51 -18
  20. package/dest/oracle/test-resolver/resolver.js +38 -1
  21. package/dest/oracle/txe_oracle_registry.d.ts +2 -6
  22. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
  23. package/dest/oracle/txe_oracle_registry.js +12 -1
  24. package/dest/oracle/txe_oracle_version.d.ts +1 -1
  25. package/dest/oracle/txe_oracle_version.js +1 -1
  26. package/dest/server.bundle.js +1 -1
  27. package/dest/state_machine/synchronizer.d.ts +3 -1
  28. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  29. package/dest/state_machine/synchronizer.js +3 -0
  30. package/dest/worker.bundle.js +1 -1
  31. package/package.json +17 -17
  32. package/src/index.ts +5 -3
  33. package/src/oracle/test-resolver/default_fixtures.ts +67 -19
  34. package/src/oracle/test-resolver/resolver.ts +48 -1
  35. package/src/oracle/txe_oracle_registry.ts +6 -1
  36. package/src/oracle/txe_oracle_version.ts +1 -1
  37. package/src/state_machine/synchronizer.ts +5 -0
  38. package/dest/AuthRegistry-H7GBK47L.js +0 -3
  39. package/dest/AuthRegistry-H7GBK47L.js.map +0 -7
  40. package/dest/HandshakeRegistry-YKOC67AA.js +0 -3
  41. package/dest/HandshakeRegistry-YKOC67AA.js.map +0 -7
  42. package/dest/SchnorrAccount-3PXRHDBW.js +0 -3
  43. package/dest/SchnorrAccount-3PXRHDBW.js.map +0 -7
  44. /package/dest/{chunk-NRS7MF3Z.js.map → chunk-2LYGEVHI.js.map} +0 -0
@@ -2,8 +2,8 @@ import { type OracleRegistryEntry } from '@aztec/pxe/simulator';
2
2
  import type { OracleTestScenario } from './resolver.js';
3
3
  /**
4
4
  * Synthesizes fixture scenarios for every oracle in the registry whose parameters and return are built from scalars,
5
- * arrays/bounded vecs of them, or `Option`s of them. The matching Noir serialization tests are auto-generated by
6
- * `#[generate_oracle_tests]` from the same seed/scenario convention.
5
+ * arrays/bounded vecs of them, `Option`s of them, or `STRUCT`s over them. The matching Noir serialization tests are
6
+ * auto-generated by `#[generate_oracle_tests]` from the same seed/scenario convention.
7
7
  */
8
8
  export declare function synthesizeDefaultFixtures(registry: Record<string, OracleRegistryEntry>): Record<string, OracleTestScenario[]>;
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9maXh0dXJlcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29yYWNsZS90ZXN0LXJlc29sdmVyL2RlZmF1bHRfZml4dHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQWNMLEtBQUssbUJBQW1CLEVBR3pCLE1BQU0sc0JBQXNCLENBQUM7QUFNOUIsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEQ7Ozs7R0FJRztBQUNILHdCQUFnQix5QkFBeUIsQ0FDdkMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUMsR0FDNUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBV3RDIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9maXh0dXJlcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29yYWNsZS90ZXN0LXJlc29sdmVyL2RlZmF1bHRfZml4dHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQWNMLEtBQUssbUJBQW1CLEVBTXpCLE1BQU0sc0JBQXNCLENBQUM7QUFLOUIsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEQ7Ozs7R0FJRztBQUNILHdCQUFnQix5QkFBeUIsQ0FDdkMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUMsR0FDNUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBV3RDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"default_fixtures.d.ts","sourceRoot":"","sources":["../../../src/oracle/test-resolver/default_fixtures.ts"],"names":[],"mappings":"AAIA,OAAO,EAcL,KAAK,mBAAmB,EAGzB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAWtC"}
1
+ {"version":3,"file":"default_fixtures.d.ts","sourceRoot":"","sources":["../../../src/oracle/test-resolver/default_fixtures.ts"],"names":[],"mappings":"AAIA,OAAO,EAcL,KAAK,mBAAmB,EAMzB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAWtC"}
@@ -1,16 +1,15 @@
1
1
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
- import { AZTEC_ADDRESS, BIGINT, BLOCK_HASH, BLOCK_NUMBER, BOOL, BYTE, BoundedVec, DELIVERY_MODE, ETH_ADDRESS, FIELD, FUNCTION_SELECTOR, NOTE_SELECTOR, Option, U32 } from '@aztec/pxe/simulator';
5
+ import { AZTEC_ADDRESS, BIGINT, BLOCK_HASH, BLOCK_NUMBER, BOOL, BYTE, BoundedVec, DELIVERY_MODE, ETH_ADDRESS, FIELD, FUNCTION_SELECTOR, NOTE_SELECTOR, Option, SLOT_NUMBER, U32, tryFieldWidth } from '@aztec/pxe/simulator';
6
6
  import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
7
7
  import { BlockHash } from '@aztec/stdlib/block';
8
8
  import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
9
- import { CONTRACT_INSTANCE_MEMBER } from '../txe_oracle_registry.js';
10
9
  /**
11
10
  * Synthesizes fixture scenarios for every oracle in the registry whose parameters and return are built from scalars,
12
- * arrays/bounded vecs of them, or `Option`s of them. The matching Noir serialization tests are auto-generated by
13
- * `#[generate_oracle_tests]` from the same seed/scenario convention.
11
+ * arrays/bounded vecs of them, `Option`s of them, or `STRUCT`s over them. The matching Noir serialization tests are
12
+ * auto-generated by `#[generate_oracle_tests]` from the same seed/scenario convention.
14
13
  */ export function synthesizeDefaultFixtures(registry) {
15
14
  const synthesized = {};
16
15
  for (const [name, entry] of Object.entries(registry)){
@@ -22,8 +21,8 @@ import { CONTRACT_INSTANCE_MEMBER } from '../txe_oracle_registry.js';
22
21
  return synthesized;
23
22
  }
24
23
  /**
25
- * The test-value implementations, one per oracle type, mirroring the Noir `OracleTestValue` trait exactly
26
- * (`noir-projects/aztec-nr/.../macros/oracle_testing.nr`).
24
+ * The test-value implementations, one per oracle type, mirroring the Noir synthesizer tables (`scalars` and
25
+ * `synthesizers` in `noir-projects/aztec-nr/.../macros/oracle_testing.nr`) exactly.
27
26
  */ const TEST_VALUE_IMPLS = [
28
27
  scalar(FIELD, (seed)=>new Fr(seed)),
29
28
  scalar(U32, (seed)=>seed),
@@ -36,14 +35,9 @@ import { CONTRACT_INSTANCE_MEMBER } from '../txe_oracle_registry.js';
36
35
  scalar(FUNCTION_SELECTOR, (seed)=>FunctionSelector.fromField(new Fr(seed))),
37
36
  scalar(NOTE_SELECTOR, (seed)=>NoteSelector.fromField(new Fr(seed))),
38
37
  scalar(BLOCK_HASH, (seed)=>new BlockHash(new Fr(seed))),
38
+ scalar(SLOT_NUMBER, (seed)=>SlotNumber(seed)),
39
39
  // Only two delivery modes are valid for tagging, so the seed alternates between them, matching the Noir impl.
40
40
  scalar(DELIVERY_MODE, (seed)=>seed % 2 === 0 ? AppTaggingSecretKind.UNCONSTRAINED : AppTaggingSecretKind.CONSTRAINED),
41
- scalar(CONTRACT_INSTANCE_MEMBER, (seed)=>[
42
- {
43
- exists: seed % 2 !== 0,
44
- member: new Fr(seed + 1)
45
- }
46
- ]),
47
41
  composite(isOption, (type, seed)=>[
48
42
  named(Option.some(firstValue(type.inner, seed)), 'some'),
49
43
  named(Option.none(firstValue(type.inner, seed)), 'none')
@@ -56,6 +50,19 @@ import { CONTRACT_INSTANCE_MEMBER } from '../txe_oracle_registry.js';
56
50
  data: collectionData(type.inner, seed, DEFAULT_ARRAY_LENGTH),
57
51
  maxLength: BOUNDED_VEC_MAX_LENGTH
58
52
  }))
53
+ ]),
54
+ composite(isStruct, (type, seed)=>[
55
+ unnamed(structValue(type, seed))
56
+ ]),
57
+ // A fixed-length array uses its real (signature) length, unlike the generic-length ARRAY which is pinned to
58
+ // DEFAULT_ARRAY_LENGTH.
59
+ composite(isFixedArray, (type, seed)=>[
60
+ unnamed(collectionData(type.inner, seed, type.length))
61
+ ]),
62
+ // Same for a fixed-capacity bounded vec: real capacity, DEFAULT_ARRAY_LENGTH elements (its value type is a plain
63
+ // element array, unlike the two-slot BOUNDED_VEC), clamped to the capacity so small vecs stay valid.
64
+ composite(isFixedBoundedVec, (type, seed)=>[
65
+ unnamed(collectionData(type.inner, seed, Math.min(DEFAULT_ARRAY_LENGTH, type.maxLength)))
59
66
  ])
60
67
  ];
61
68
  /**
@@ -98,8 +105,25 @@ function named(value, name) {
98
105
  }, (_, i)=>firstValue(element, seed + i));
99
106
  }
100
107
  /**
101
- * The [`Scenario`]s for `type` at `seed`, one per serialization *shape*, mirroring the Noir
102
- * `OracleTestValue::oracle_test_value(seed) -> [Scenario<Self>; N]`. Throws if the type has no matching impl.
108
+ * The synthesized prop bag for a struct: each field's first scenario, seeded at the field's flat wire offset so the
109
+ * values depend on the wire layout rather than on how each side groups its fields. Mirrors the Noir reflected impls.
110
+ */ function structValue(type, seed) {
111
+ const value = {};
112
+ let offset = 0;
113
+ for (const field of type.fields){
114
+ value[field.name] = firstValue(field.type, seed + offset);
115
+ const width = tryFieldWidth(field.type.shape);
116
+ if (width === undefined) {
117
+ // A variable-width field has no flat offset to seed the next field at, so only this oracle is unsynthesizable.
118
+ throw new UnsynthesizableTypeError(field.type, `struct field '${field.name}' has a variable-width shape`);
119
+ }
120
+ offset += width;
121
+ }
122
+ return value;
123
+ }
124
+ /**
125
+ * The [`Scenario`]s for `type` at `seed`, one per serialization *shape*, mirroring the Noir `scenarios_for`
126
+ * dispatcher. Throws if the type has no matching impl.
103
127
  */ function scenariosForType(type, seed) {
104
128
  const impl = TEST_VALUE_IMPLS.find((i)=>i.match(type));
105
129
  if (!impl) {
@@ -111,15 +135,15 @@ function named(value, name) {
111
135
  return scenariosForType(type, seed)[0].value;
112
136
  }
113
137
  class UnsynthesizableTypeError extends Error {
114
- constructor(type){
115
- super(`No test-value impl for type: ${JSON.stringify(Object.keys(type))}`);
138
+ constructor(type, detail){
139
+ super(detail ?? `No test-value impl for type: ${JSON.stringify(Object.keys(type))}`);
116
140
  this.name = 'UnsynthesizableTypeError';
117
141
  }
118
142
  }
119
143
  /**
120
144
  * Synthesizes the scenarios for one oracle by zipping every position's [`Scenario`] list to one case per test (a
121
145
  * shorter list wraps around via mod), mirroring the Noir macro. Returns `undefined` if any param or return type is
122
- * unsynthesizable (structs, ephemeral arrays).
146
+ * unsynthesizable (ephemeral arrays, structs with a variable-width field).
123
147
  */ function synthesizeScenarios(entry) {
124
148
  try {
125
149
  return synthesizeScenariosOrThrow(entry);
@@ -172,3 +196,12 @@ function isBoundedVec(type) {
172
196
  function isOption(type) {
173
197
  return 'kind' in type && type.kind === 'option';
174
198
  }
199
+ function isStruct(type) {
200
+ return 'kind' in type && type.kind === 'struct';
201
+ }
202
+ function isFixedArray(type) {
203
+ return 'kind' in type && type.kind === 'fixed-array';
204
+ }
205
+ function isFixedBoundedVec(type) {
206
+ return 'kind' in type && type.kind === 'fixed-bounded-vec';
207
+ }
@@ -128,6 +128,11 @@ export const SET_SCENARIO_ENTRY = makeEntry({
128
128
  return String.fromCharCode(...value.data);
129
129
  }
130
130
  function valuesEqual(actual, expected) {
131
+ if (!isNonNullObject(actual) || !isNonNullObject(expected)) {
132
+ // Primitive scalars; String() bridges bigint vs number representations of the same seed. A primitive compared
133
+ // against an object is never equal.
134
+ return isNonNullObject(actual) === isNonNullObject(expected) && String(actual) === String(expected);
135
+ }
131
136
  if (actual instanceof Option && expected instanceof Option) {
132
137
  return actual.equals(expected, valuesEqual);
133
138
  }
@@ -137,7 +142,39 @@ function valuesEqual(actual, expected) {
137
142
  if (Array.isArray(actual) && Array.isArray(expected)) {
138
143
  return actual.length === expected.length && actual.every((v, i)=>valuesEqual(v, expected[i]));
139
144
  }
140
- return String(actual) === String(expected);
145
+ if (isPlainObject(actual) && isPlainObject(expected)) {
146
+ const expectedKeys = Object.keys(expected);
147
+ return Object.keys(actual).length === expectedKeys.length && expectedKeys.every((key)=>valuesEqual(actual[key], expected[key]));
148
+ }
149
+ if (actual.constructor !== expected.constructor) {
150
+ return false;
151
+ }
152
+ if (hasEquals(actual)) {
153
+ return actual.equals(expected);
154
+ }
155
+ const actualStr = customStringForm(actual);
156
+ const expectedStr = customStringForm(expected);
157
+ if (actualStr !== undefined && expectedStr !== undefined) {
158
+ return actualStr === expectedStr;
159
+ }
160
+ // Comparing blindly here could pass vacuously (e.g. two '[object Object]' strings), so refuse instead.
161
+ throw new Error(`valuesEqual cannot compare a '${actual.constructor?.name}' against a '${expected.constructor?.name}'. Add a branch for the type.`);
162
+ }
163
+ function isNonNullObject(value) {
164
+ return typeof value === 'object' && value !== null;
165
+ }
166
+ function isPlainObject(value) {
167
+ return isNonNullObject(value) && value.constructor === Object;
168
+ }
169
+ function hasEquals(value) {
170
+ return typeof value.equals === 'function';
171
+ }
172
+ /** The value's string form when its class overrides `toString` (a meaningful representation), undefined otherwise. */ function customStringForm(value) {
173
+ const { toString } = value;
174
+ if (typeof toString !== 'function' || toString === Object.prototype.toString) {
175
+ return undefined;
176
+ }
177
+ return toString.call(value);
141
178
  }
142
179
  function versionBumpHint(oracle) {
143
180
  return oracle.startsWith('aztec_txe_') || oracle.startsWith('aztec_avm_') ? 'If you changed this oracle, consider bumping the TXE oracle version in yarn-project/txe/src/oracle/txe_oracle_version.ts.' : 'If you changed this oracle, consider bumping the PXE oracle version in yarn-project/pxe/src/oracle_version.ts.';
@@ -1,6 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { TaggingSecretStrategy } from '@aztec/pxe/server';
3
- import { type InputSlot, type MaybePromise, type OracleRegistryEntry, type ParamTypes, type TypeMapping, buildACIRCallback } from '@aztec/pxe/simulator';
3
+ import { type InputSlot, type MaybePromise, type OracleRegistryEntry, type ParamTypes, buildACIRCallback } from '@aztec/pxe/simulator';
4
4
  import { EventSelector } from '@aztec/stdlib/abi';
5
5
  import { CompleteAddress } from '@aztec/stdlib/contract';
6
6
  import { GasSettings } from '@aztec/stdlib/gas';
@@ -12,10 +12,6 @@ export type { ContractClassLogData, EmbeddedCurvePoint, TxEffectData } from '@az
12
12
  export type { BlockHash } from '@aztec/stdlib/block';
13
13
  export type { MembershipWitness } from '@aztec/foundation/trees';
14
14
  export type { NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
15
- export declare const CONTRACT_INSTANCE_MEMBER: TypeMapping<{
16
- exists: boolean;
17
- member: Fr;
18
- }[]>;
19
15
  export declare const TXE_ORACLE_REGISTRY: {
20
16
  aztec_misc_assertCompatibleOracleVersion: OracleRegistryEntry<[import("@aztec/pxe/simulator").NamedValue<"major", number>, import("@aztec/pxe/simulator").NamedValue<"minor", number>], any>;
21
17
  aztec_misc_getRandomField: OracleRegistryEntry<import("@aztec/pxe/simulator").NamedValue<string, any>[], Fr>;
@@ -170,4 +166,4 @@ export declare function callTxeHandler<K extends keyof typeof TXE_ORACLE_REGISTR
170
166
  handler: (params: ParamTypes<ReturnType<(typeof TXE_ORACLE_REGISTRY)[K]['deserializeParams']>>) => MaybePromise<Parameters<(typeof TXE_ORACLE_REGISTRY)[K]['serializeReturn']>[0]>;
171
167
  }): Promise<ForeignCallResult>;
172
168
  export declare function callTxeLegacyHandler(oracle: string, inputs: ForeignCallArgs, oracleHandler: Parameters<typeof buildACIRCallback>[0]): Promise<ForeignCallResult>;
173
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX29yYWNsZV9yZWdpc3RyeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29yYWNsZS90eGVfb3JhY2xlX3JlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdwRCxPQUFPLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQy9ELE9BQU8sRUFVTCxLQUFLLFNBQVMsRUFDZCxLQUFLLFlBQVksRUFHakIsS0FBSyxtQkFBbUIsRUFFeEIsS0FBSyxVQUFVLEVBSWYsS0FBSyxXQUFXLEVBRWhCLGlCQUFpQixFQUVsQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUS9DLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBSy9FLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRyxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsWUFBWSxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsWUFBWSxFQUFFLDBCQUEwQixFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUEwSXpGLGVBQU8sTUFBTSx3QkFBd0IsRUFBRSxXQUFXLENBQUM7SUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDO0lBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQUUsQ0FNbkYsQ0FBQztBQStCRixlQUFPLE1BQU0sbUJBQW1COzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0EyT2UsQ0FBQztBQUVoRCx3QkFBZ0IsWUFBWSxDQUFDLE1BQU0sRUFBRSxlQUFlLEdBQUcsU0FBUyxFQUFFLENBR2pFO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFzQixjQUFjLENBQUMsQ0FBQyxTQUFTLE1BQU0sT0FBTyxtQkFBbUIsRUFBRSxFQUMvRSxNQUFNLEVBQ04sTUFBTSxFQUNOLE9BQU8sRUFDUixFQUFFO0lBQ0QsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNWLE1BQU0sRUFBRSxlQUFlLENBQUM7SUFDeEIsT0FBTyxFQUFFLENBQ1AsTUFBTSxFQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEtBQ2pGLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Q0FDdEYsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FNN0I7QUFTRCx3QkFBc0Isb0JBQW9CLENBQ3hDLE1BQU0sRUFBRSxNQUFNLEVBQ2QsTUFBTSxFQUFFLGVBQWUsRUFDdkIsYUFBYSxFQUFFLFVBQVUsQ0FBQyxPQUFPLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQ3JELE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQVU1QiJ9
169
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX29yYWNsZV9yZWdpc3RyeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29yYWNsZS90eGVfb3JhY2xlX3JlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdwRCxPQUFPLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQy9ELE9BQU8sRUFVTCxLQUFLLFNBQVMsRUFDZCxLQUFLLFlBQVksRUFHakIsS0FBSyxtQkFBbUIsRUFFeEIsS0FBSyxVQUFVLEVBTWYsaUJBQWlCLEVBRWxCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFRL0MsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFLL0UsWUFBWSxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25HLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRSxZQUFZLEVBQUUsMEJBQTBCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQW9MekYsZUFBTyxNQUFNLG1CQUFtQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBMk9lLENBQUM7QUFFaEQsd0JBQWdCLFlBQVksQ0FBQyxNQUFNLEVBQUUsZUFBZSxHQUFHLFNBQVMsRUFBRSxDQUdqRTtBQUVEOzs7O0dBSUc7QUFDSCx3QkFBc0IsY0FBYyxDQUFDLENBQUMsU0FBUyxNQUFNLE9BQU8sbUJBQW1CLEVBQUUsRUFDL0UsTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1IsRUFBRTtJQUNELE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDVixNQUFNLEVBQUUsZUFBZSxDQUFDO0lBQ3hCLE9BQU8sRUFBRSxDQUNQLE1BQU0sRUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxLQUNqRixZQUFZLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQ3RGLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBTTdCO0FBU0Qsd0JBQXNCLG9CQUFvQixDQUN4QyxNQUFNLEVBQUUsTUFBTSxFQUNkLE1BQU0sRUFBRSxlQUFlLEVBQ3ZCLGFBQWEsRUFBRSxVQUFVLENBQUMsT0FBTyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUNyRCxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FVNUIifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"txe_oracle_registry.d.ts","sourceRoot":"","sources":["../../src/oracle/txe_oracle_registry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAUL,KAAK,SAAS,EACd,KAAK,YAAY,EAGjB,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAIf,KAAK,WAAW,EAEhB,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAQ/C,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK/E,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACnG,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,YAAY,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AA0IzF,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,EAAE,CAAA;CAAE,EAAE,CAMnF,CAAC;AA+BF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Oe,CAAC;AAEhD,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,EAAE,CAGjE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,MAAM,OAAO,mBAAmB,EAAE,EAC/E,MAAM,EACN,MAAM,EACN,OAAO,EACR,EAAE;IACD,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CACP,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,KACjF,YAAY,CAAC,UAAU,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACtF,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAM7B;AASD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,aAAa,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACrD,OAAO,CAAC,iBAAiB,CAAC,CAU5B"}
1
+ {"version":3,"file":"txe_oracle_registry.d.ts","sourceRoot":"","sources":["../../src/oracle/txe_oracle_registry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAUL,KAAK,SAAS,EACd,KAAK,YAAY,EAGjB,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAMf,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAQ/C,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK/E,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACnG,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,YAAY,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAoLzF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Oe,CAAC;AAEhD,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,EAAE,CAGjE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,MAAM,OAAO,mBAAmB,EAAE,EAC/E,MAAM,EACN,MAAM,EACN,OAAO,EACR,EAAE;IACD,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CACP,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,KACjF,YAAY,CAAC,UAAU,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACtF,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAM7B;AASD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,aAAa,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACrD,OAAO,CAAC,iBAAiB,CAAC,CAU5B"}
@@ -22,6 +22,7 @@ const GAS_SETTINGS = {
22
22
  const STRATEGY_NON_INTERACTIVE_HANDSHAKE = 1;
23
23
  const STRATEGY_ARBITRARY_SECRET = 2;
24
24
  const STRATEGY_ADDRESS_DERIVED = 3;
25
+ const STRATEGY_INTERACTIVE_HANDSHAKE = 4;
25
26
  const TAGGING_SECRET_STRATEGY = {
26
27
  serialization: {
27
28
  fn: (strategy)=>{
@@ -32,6 +33,12 @@ const TAGGING_SECRET_STRATEGY = {
32
33
  Fr.ZERO,
33
34
  Fr.ZERO
34
35
  ];
36
+ case 'interactive-handshake':
37
+ return [
38
+ new Fr(STRATEGY_INTERACTIVE_HANDSHAKE),
39
+ Fr.ZERO,
40
+ Fr.ZERO
41
+ ];
35
42
  case 'address-derived':
36
43
  return [
37
44
  new Fr(STRATEGY_ADDRESS_DERIVED),
@@ -59,6 +66,10 @@ const TAGGING_SECRET_STRATEGY = {
59
66
  return {
60
67
  type: 'non-interactive-handshake'
61
68
  };
69
+ case STRATEGY_INTERACTIVE_HANDSHAKE:
70
+ return {
71
+ type: 'interactive-handshake'
72
+ };
62
73
  case STRATEGY_ADDRESS_DERIVED:
63
74
  return {
64
75
  type: 'address-derived'
@@ -177,7 +188,7 @@ const TXE_CALL_CONTEXT = {
177
188
  'scalar'
178
189
  ]
179
190
  };
180
- export const CONTRACT_INSTANCE_MEMBER = FIXED_ARRAY(STRUCT([
191
+ const CONTRACT_INSTANCE_MEMBER = FIXED_ARRAY(STRUCT([
181
192
  {
182
193
  name: 'exists',
183
194
  type: BOOL
@@ -6,7 +6,7 @@
6
6
  * The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`.
7
7
  */
8
8
  export declare const TXE_ORACLE_VERSION_MAJOR = 2;
9
- export declare const TXE_ORACLE_VERSION_MINOR = 2;
9
+ export declare const TXE_ORACLE_VERSION_MINOR = 3;
10
10
  /**
11
11
  * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to
12
12
  * detect when those interfaces change. When it does, bump:
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`.
7
7
  */ export const TXE_ORACLE_VERSION_MAJOR = 2;
8
- export const TXE_ORACLE_VERSION_MINOR = 2;
8
+ export const TXE_ORACLE_VERSION_MINOR = 3;
9
9
  /**
10
10
  * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to
11
11
  * detect when those interfaces change. When it does, bump:
@@ -1,3 +1,3 @@
1
1
  import { createRequire as __txeCreateRequire } from 'node:module';
2
2
  const require = __txeCreateRequire(import.meta.url);
3
- import{createTXERpcServer}from"./chunk-NRS7MF3Z.js";import"./chunk-SHQZNKOL.js";import"./chunk-BJVAAXNA.js";export{createTXERpcServer};
3
+ import{createTXERpcServer}from"./chunk-2LYGEVHI.js";import"./chunk-HLH2NBQI.js";import"./chunk-BJVAAXNA.js";export{createTXERpcServer};
@@ -22,6 +22,8 @@ export declare class TXESynchronizer implements WorldStateSynchronizer {
22
22
  fork(block?: number): Promise<MerkleTreeWriteOperations>;
23
23
  /** Gets a handle that allows reading the state as it was at the given block number. */
24
24
  getSnapshot(blockNumber: number): MerkleTreeReadOperations;
25
+ /** Gets a snapshot at the given block number. The TXE has no reorgs, so the fork hash is not verified. */
26
+ getVerifiedSnapshot(blockNumber: number, _blockHash: BlockHash): Promise<MerkleTreeReadOperations>;
25
27
  /** Backups the db to the target path. */
26
28
  backupTo(dstPath: string, compact?: boolean): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>>;
27
29
  start(): Promise<void>;
@@ -31,4 +33,4 @@ export declare class TXESynchronizer implements WorldStateSynchronizer {
31
33
  resumeSync(): void;
32
34
  clear(): Promise<void>;
33
35
  }
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGVfbWFjaGluZS9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTlELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQ1Ysd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixnQkFBZ0IsRUFDaEIsc0JBQXNCLEVBQ3RCLDRCQUE0QixFQUM3QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXBFLHFCQUFhLGVBQWdCLFlBQVcsc0JBQXNCO0lBSXpDLHVCQUF1QixFQUFFLHVCQUF1QjtJQUZuRSxPQUFPLENBQUMsV0FBVyxDQUFvQjtJQUV2QyxZQUFtQix1QkFBdUIsRUFBRSx1QkFBdUIsRUFBSTtJQUV2RSxPQUFhLE1BQU0sNkJBSWxCO0lBRVksYUFBYSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsY0FBYyxHQUFFLEVBQUUsRUFBTyxpQkFPbkU7SUFFRDs7Ozs7T0FLRztJQUNJLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FFaEc7SUFFRCwrRkFBK0Y7SUFDeEYsWUFBWSxJQUFJLHdCQUF3QixDQUU5QztJQUVELHFGQUFxRjtJQUM5RSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxDQUU5RDtJQUVELHVGQUF1RjtJQUNoRixXQUFXLENBQUMsV0FBVyxFQUFFLE1BQU0sR0FBRyx3QkFBd0IsQ0FFaEU7SUFFRCx5Q0FBeUM7SUFDbEMsUUFBUSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLEVBQUUsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBRWxIO0lBRU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFNUI7SUFFTSxNQUFNLElBQUksT0FBTyxDQUFDLDRCQUE0QixDQUFDLENBRXJEO0lBRU0sSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFM0I7SUFFTSxRQUFRLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUvQjtJQUVNLFVBQVUsSUFBSSxJQUFJLENBRXhCO0lBRU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFNUI7Q0FDRiJ9
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGVfbWFjaGluZS9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTlELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQ1Ysd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixnQkFBZ0IsRUFDaEIsc0JBQXNCLEVBQ3RCLDRCQUE0QixFQUM3QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXBFLHFCQUFhLGVBQWdCLFlBQVcsc0JBQXNCO0lBSXpDLHVCQUF1QixFQUFFLHVCQUF1QjtJQUZuRSxPQUFPLENBQUMsV0FBVyxDQUFvQjtJQUV2QyxZQUFtQix1QkFBdUIsRUFBRSx1QkFBdUIsRUFBSTtJQUV2RSxPQUFhLE1BQU0sNkJBSWxCO0lBRVksYUFBYSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsY0FBYyxHQUFFLEVBQUUsRUFBTyxpQkFPbkU7SUFFRDs7Ozs7T0FLRztJQUNJLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FFaEc7SUFFRCwrRkFBK0Y7SUFDeEYsWUFBWSxJQUFJLHdCQUF3QixDQUU5QztJQUVELHFGQUFxRjtJQUM5RSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxDQUU5RDtJQUVELHVGQUF1RjtJQUNoRixXQUFXLENBQUMsV0FBVyxFQUFFLE1BQU0sR0FBRyx3QkFBd0IsQ0FFaEU7SUFFRCwwR0FBMEc7SUFDbkcsbUJBQW1CLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUV4RztJQUVELHlDQUF5QztJQUNsQyxRQUFRLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FFbEg7SUFFTSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUU1QjtJQUVNLE1BQU0sSUFBSSxPQUFPLENBQUMsNEJBQTRCLENBQUMsQ0FFckQ7SUFFTSxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUzQjtJQUVNLFFBQVEsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBRS9CO0lBRU0sVUFBVSxJQUFJLElBQUksQ0FFeEI7SUFFTSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUU1QjtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/state_machine/synchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,qBAAa,eAAgB,YAAW,sBAAsB;IAIzC,uBAAuB,EAAE,uBAAuB;IAFnE,OAAO,CAAC,WAAW,CAAoB;IAEvC,YAAmB,uBAAuB,EAAE,uBAAuB,EAAI;IAEvE,OAAa,MAAM,6BAIlB;IAEY,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,GAAE,EAAE,EAAO,iBAOnE;IAED;;;;;OAKG;IACI,aAAa,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAEhG;IAED,+FAA+F;IACxF,YAAY,IAAI,wBAAwB,CAE9C;IAED,qFAAqF;IAC9E,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAE9D;IAED,uFAAuF;IAChF,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,wBAAwB,CAEhE;IAED,yCAAyC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAElH;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;IAEM,MAAM,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAErD;IAEM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEM,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/B;IAEM,UAAU,IAAI,IAAI,CAExB;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;CACF"}
1
+ {"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/state_machine/synchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,qBAAa,eAAgB,YAAW,sBAAsB;IAIzC,uBAAuB,EAAE,uBAAuB;IAFnE,OAAO,CAAC,WAAW,CAAoB;IAEvC,YAAmB,uBAAuB,EAAE,uBAAuB,EAAI;IAEvE,OAAa,MAAM,6BAIlB;IAEY,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,GAAE,EAAE,EAAO,iBAOnE;IAED;;;;;OAKG;IACI,aAAa,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAEhG;IAED,+FAA+F;IACxF,YAAY,IAAI,wBAAwB,CAE9C;IAED,qFAAqF;IAC9E,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAE9D;IAED,uFAAuF;IAChF,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,wBAAwB,CAEhE;IAED,0GAA0G;IACnG,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAExG;IAED,yCAAyC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAElH;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;IAEM,MAAM,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAErD;IAEM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEM,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/B;IAEM,UAAU,IAAI,IAAI,CAExB;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;CACF"}
@@ -36,6 +36,9 @@ export class TXESynchronizer {
36
36
  /** Gets a handle that allows reading the state as it was at the given block number. */ getSnapshot(blockNumber) {
37
37
  return this.nativeWorldStateService.getSnapshot(BlockNumber(blockNumber));
38
38
  }
39
+ /** Gets a snapshot at the given block number. The TXE has no reorgs, so the fork hash is not verified. */ getVerifiedSnapshot(blockNumber, _blockHash) {
40
+ return Promise.resolve(this.getSnapshot(blockNumber));
41
+ }
39
42
  /** Backups the db to the target path. */ backupTo(dstPath, compact) {
40
43
  return this.nativeWorldStateService.backupTo(dstPath, compact);
41
44
  }
@@ -1,3 +1,3 @@
1
1
  import { createRequire as __txeCreateRequire } from 'node:module';
2
2
  const require = __txeCreateRequire(import.meta.url);
3
- import{TXEDispatcher,activeSessionCount,createLogger}from"./chunk-SHQZNKOL.js";import{__name}from"./chunk-BJVAAXNA.js";import{BackendType,Barretenberg,BarretenbergSync}from"@aztec/bb.js";import{parentPort,workerData}from"node:worker_threads";Barretenberg.initSingleton({backend:BackendType.Wasm,skipSrsInit:!0,threads:1});BarretenbergSync.initSingleton({backend:BackendType.Wasm});if(!parentPort)throw new Error("worker.ts must be loaded as a worker_thread");var port=parentPort,logger=createLogger("txe:worker"),dispatcherOpts={contractStoreSourceDir:workerData.contractStoreSourceDir,schnorrClassId:workerData.schnorrClassId},dispatcher=new TXEDispatcher(logger,dispatcherOpts);function serializeError(err){return err instanceof Error?{message:err.message,name:err.name,stack:err.stack}:{message:String(err)}}__name(serializeError,"serializeError");process.env.TXE_WORKER_MEMSTAT==="1"&&setInterval(()=>{let m=process.memoryUsage();port.postMessage({type:"memstat",sessions:activeSessionCount(),rss:m.rss,heapTotal:m.heapTotal,heapUsed:m.heapUsed,external:m.external,arrayBuffers:m.arrayBuffers})},2e3).unref();port.on("message",msg=>{switch(msg.type){case"foreign-call":(async()=>{try{let value=await dispatcher.resolve_foreign_call(msg.callData);port.postMessage({type:"result",requestId:msg.requestId,ok:!0,value})}catch(err){port.postMessage({type:"result",requestId:msg.requestId,ok:!1,error:serializeError(err)})}})();return;case"dispose-session":dispatcher.disposeSession(msg.sessionId).catch(err=>logger.warn("disposeSession failed",err));return}});
3
+ import{TXEDispatcher,activeSessionCount,createLogger}from"./chunk-HLH2NBQI.js";import{__name}from"./chunk-BJVAAXNA.js";import{BackendType,Barretenberg,BarretenbergSync}from"@aztec/bb.js";import{parentPort,workerData}from"node:worker_threads";Barretenberg.initSingleton({backend:BackendType.Wasm,skipSrsInit:!0,threads:1});BarretenbergSync.initSingleton({backend:BackendType.Wasm});if(!parentPort)throw new Error("worker.ts must be loaded as a worker_thread");var port=parentPort,logger=createLogger("txe:worker"),dispatcherOpts={contractStoreSourceDir:workerData.contractStoreSourceDir,schnorrClassId:workerData.schnorrClassId},dispatcher=new TXEDispatcher(logger,dispatcherOpts);function serializeError(err){return err instanceof Error?{message:err.message,name:err.name,stack:err.stack}:{message:String(err)}}__name(serializeError,"serializeError");process.env.TXE_WORKER_MEMSTAT==="1"&&setInterval(()=>{let m=process.memoryUsage();port.postMessage({type:"memstat",sessions:activeSessionCount(),rss:m.rss,heapTotal:m.heapTotal,heapUsed:m.heapUsed,external:m.external,arrayBuffers:m.arrayBuffers})},2e3).unref();port.on("message",msg=>{switch(msg.type){case"foreign-call":(async()=>{try{let value=await dispatcher.resolve_foreign_call(msg.callData);port.postMessage({type:"result",requestId:msg.requestId,ok:!0,value})}catch(err){port.postMessage({type:"result",requestId:msg.requestId,ok:!1,error:serializeError(err)})}})();return;case"dispose-session":dispatcher.disposeSession(msg.sessionId).catch(err=>logger.warn("disposeSession failed",err));return}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "5.0.0-nightly.20260707",
3
+ "version": "5.0.0-nightly.20260708",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": {
@@ -69,22 +69,22 @@
69
69
  ]
70
70
  },
71
71
  "dependencies": {
72
- "@aztec/accounts": "5.0.0-nightly.20260707",
73
- "@aztec/archiver": "5.0.0-nightly.20260707",
74
- "@aztec/aztec-node": "5.0.0-nightly.20260707",
75
- "@aztec/aztec.js": "5.0.0-nightly.20260707",
76
- "@aztec/bb-prover": "5.0.0-nightly.20260707",
77
- "@aztec/bb.js": "5.0.0-nightly.20260707",
78
- "@aztec/constants": "5.0.0-nightly.20260707",
79
- "@aztec/foundation": "5.0.0-nightly.20260707",
80
- "@aztec/key-store": "5.0.0-nightly.20260707",
81
- "@aztec/kv-store": "5.0.0-nightly.20260707",
82
- "@aztec/protocol-contracts": "5.0.0-nightly.20260707",
83
- "@aztec/pxe": "5.0.0-nightly.20260707",
84
- "@aztec/simulator": "5.0.0-nightly.20260707",
85
- "@aztec/standard-contracts": "5.0.0-nightly.20260707",
86
- "@aztec/stdlib": "5.0.0-nightly.20260707",
87
- "@aztec/world-state": "5.0.0-nightly.20260707",
72
+ "@aztec/accounts": "5.0.0-nightly.20260708",
73
+ "@aztec/archiver": "5.0.0-nightly.20260708",
74
+ "@aztec/aztec-node": "5.0.0-nightly.20260708",
75
+ "@aztec/aztec.js": "5.0.0-nightly.20260708",
76
+ "@aztec/bb-prover": "5.0.0-nightly.20260708",
77
+ "@aztec/bb.js": "5.0.0-nightly.20260708",
78
+ "@aztec/constants": "5.0.0-nightly.20260708",
79
+ "@aztec/foundation": "5.0.0-nightly.20260708",
80
+ "@aztec/key-store": "5.0.0-nightly.20260708",
81
+ "@aztec/kv-store": "5.0.0-nightly.20260708",
82
+ "@aztec/protocol-contracts": "5.0.0-nightly.20260708",
83
+ "@aztec/pxe": "5.0.0-nightly.20260708",
84
+ "@aztec/simulator": "5.0.0-nightly.20260708",
85
+ "@aztec/standard-contracts": "5.0.0-nightly.20260708",
86
+ "@aztec/stdlib": "5.0.0-nightly.20260708",
87
+ "@aztec/world-state": "5.0.0-nightly.20260708",
88
88
  "msgpackr": "^1.11.2",
89
89
  "zod": "^4"
90
90
  },
package/src/index.ts CHANGED
@@ -21,9 +21,11 @@ import {
21
21
  } from './utils/encoding.js';
22
22
  import { TXEArtifactResolver } from './utils/txe_artifact_resolver.js';
23
23
 
24
- // Protocol contracts TXE registers in its contract store. Only AuthRegistry is needed for the
25
- // current test suites; add a contract here if a lookup against a `0x000…00X` address fails.
26
- export const TXE_REQUIRED_PROTOCOL_CONTRACTS: ProtocolContractName[] = [];
24
+ export const TXE_REQUIRED_PROTOCOL_CONTRACTS: ProtocolContractName[] = [
25
+ 'ContractClassRegistry',
26
+ 'ContractInstanceRegistry',
27
+ 'FeeJuice',
28
+ ];
27
29
 
28
30
  const sessions = new Map<number, TXESession>();
29
31
 
@@ -1,5 +1,5 @@
1
1
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import {
@@ -17,20 +17,22 @@ import {
17
17
  NOTE_SELECTOR,
18
18
  Option,
19
19
  type OracleRegistryEntry,
20
+ SLOT_NUMBER,
21
+ type StructField,
20
22
  type TypeMapping,
21
23
  U32,
24
+ tryFieldWidth,
22
25
  } from '@aztec/pxe/simulator';
23
26
  import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
24
27
  import { BlockHash } from '@aztec/stdlib/block';
25
28
  import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
26
29
 
27
- import { CONTRACT_INSTANCE_MEMBER } from '../txe_oracle_registry.js';
28
30
  import type { OracleTestScenario } from './resolver.js';
29
31
 
30
32
  /**
31
33
  * Synthesizes fixture scenarios for every oracle in the registry whose parameters and return are built from scalars,
32
- * arrays/bounded vecs of them, or `Option`s of them. The matching Noir serialization tests are auto-generated by
33
- * `#[generate_oracle_tests]` from the same seed/scenario convention.
34
+ * arrays/bounded vecs of them, `Option`s of them, or `STRUCT`s over them. The matching Noir serialization tests are
35
+ * auto-generated by `#[generate_oracle_tests]` from the same seed/scenario convention.
34
36
  */
35
37
  export function synthesizeDefaultFixtures(
36
38
  registry: Record<string, OracleRegistryEntry>,
@@ -48,8 +50,8 @@ export function synthesizeDefaultFixtures(
48
50
  }
49
51
 
50
52
  /**
51
- * The test-value implementations, one per oracle type, mirroring the Noir `OracleTestValue` trait exactly
52
- * (`noir-projects/aztec-nr/.../macros/oracle_testing.nr`).
53
+ * The test-value implementations, one per oracle type, mirroring the Noir synthesizer tables (`scalars` and
54
+ * `synthesizers` in `noir-projects/aztec-nr/.../macros/oracle_testing.nr`) exactly.
53
55
  */
54
56
  const TEST_VALUE_IMPLS: TestValueImpl[] = [
55
57
  scalar(FIELD, seed => new Fr(seed)),
@@ -63,11 +65,11 @@ const TEST_VALUE_IMPLS: TestValueImpl[] = [
63
65
  scalar(FUNCTION_SELECTOR, seed => FunctionSelector.fromField(new Fr(seed))),
64
66
  scalar(NOTE_SELECTOR, seed => NoteSelector.fromField(new Fr(seed))),
65
67
  scalar(BLOCK_HASH, seed => new BlockHash(new Fr(seed))),
68
+ scalar(SLOT_NUMBER, seed => SlotNumber(seed)),
66
69
  // Only two delivery modes are valid for tagging, so the seed alternates between them, matching the Noir impl.
67
70
  scalar(DELIVERY_MODE, seed =>
68
71
  seed % 2 === 0 ? AppTaggingSecretKind.UNCONSTRAINED : AppTaggingSecretKind.CONSTRAINED,
69
72
  ),
70
- scalar(CONTRACT_INSTANCE_MEMBER, seed => [{ exists: seed % 2 !== 0, member: new Fr(seed + 1) }]),
71
73
  composite(isOption, (type, seed) => [
72
74
  named(Option.some(firstValue(type.inner, seed)), 'some'),
73
75
  named(Option.none(firstValue(type.inner, seed)), 'none'),
@@ -81,6 +83,15 @@ const TEST_VALUE_IMPLS: TestValueImpl[] = [
81
83
  }),
82
84
  ),
83
85
  ]),
86
+ composite(isStruct, (type, seed) => [unnamed(structValue(type, seed))]),
87
+ // A fixed-length array uses its real (signature) length, unlike the generic-length ARRAY which is pinned to
88
+ // DEFAULT_ARRAY_LENGTH.
89
+ composite(isFixedArray, (type, seed) => [unnamed(collectionData(type.inner, seed, type.length))]),
90
+ // Same for a fixed-capacity bounded vec: real capacity, DEFAULT_ARRAY_LENGTH elements (its value type is a plain
91
+ // element array, unlike the two-slot BOUNDED_VEC), clamped to the capacity so small vecs stay valid.
92
+ composite(isFixedBoundedVec, (type, seed) => [
93
+ unnamed(collectionData(type.inner, seed, Math.min(DEFAULT_ARRAY_LENGTH, type.maxLength))),
94
+ ]),
84
95
  ];
85
96
 
86
97
  /**
@@ -115,9 +126,9 @@ function named(value: unknown, name: string): Scenario {
115
126
  }
116
127
 
117
128
  /**
118
- * One type's test-value implementation, mirroring a Noir `impl OracleTestValue<N> for T`: `match` selects the type and
119
- * `scenarios` yields its [`Scenario`]s for `seed`, one per serialization shape, like Noir's
120
- * `oracle_test_value(seed) -> [Scenario<Self>; N]`.
129
+ * One type's test-value implementation, mirroring a Noir `TestValueSynthesizer` entry: `match` selects the type and
130
+ * `scenarios` yields its [`Scenario`]s for `seed`, one per serialization shape, like the Noir entry's `scenarios`
131
+ * function.
121
132
  */
122
133
  interface TestValueImpl {
123
134
  match: (type: TypeMapping<any>) => boolean;
@@ -143,8 +154,27 @@ function collectionData(element: TypeMapping<any>, seed: number, length: number)
143
154
  }
144
155
 
145
156
  /**
146
- * The [`Scenario`]s for `type` at `seed`, one per serialization *shape*, mirroring the Noir
147
- * `OracleTestValue::oracle_test_value(seed) -> [Scenario<Self>; N]`. Throws if the type has no matching impl.
157
+ * The synthesized prop bag for a struct: each field's first scenario, seeded at the field's flat wire offset so the
158
+ * values depend on the wire layout rather than on how each side groups its fields. Mirrors the Noir reflected impls.
159
+ */
160
+ function structValue(type: StructMapping, seed: number): Record<string, unknown> {
161
+ const value: Record<string, unknown> = {};
162
+ let offset = 0;
163
+ for (const field of type.fields) {
164
+ value[field.name] = firstValue(field.type, seed + offset);
165
+ const width = tryFieldWidth(field.type.shape);
166
+ if (width === undefined) {
167
+ // A variable-width field has no flat offset to seed the next field at, so only this oracle is unsynthesizable.
168
+ throw new UnsynthesizableTypeError(field.type, `struct field '${field.name}' has a variable-width shape`);
169
+ }
170
+ offset += width;
171
+ }
172
+ return value;
173
+ }
174
+
175
+ /**
176
+ * The [`Scenario`]s for `type` at `seed`, one per serialization *shape*, mirroring the Noir `scenarios_for`
177
+ * dispatcher. Throws if the type has no matching impl.
148
178
  */
149
179
  function scenariosForType(type: TypeMapping<any>, seed: number): Scenario[] {
150
180
  const impl = TEST_VALUE_IMPLS.find(i => i.match(type));
@@ -160,8 +190,8 @@ function firstValue(type: TypeMapping<any>, seed: number): unknown {
160
190
  }
161
191
 
162
192
  class UnsynthesizableTypeError extends Error {
163
- constructor(type: TypeMapping<any>) {
164
- super(`No test-value impl for type: ${JSON.stringify(Object.keys(type))}`);
193
+ constructor(type: TypeMapping<any>, detail?: string) {
194
+ super(detail ?? `No test-value impl for type: ${JSON.stringify(Object.keys(type))}`);
165
195
  this.name = 'UnsynthesizableTypeError';
166
196
  }
167
197
  }
@@ -169,7 +199,7 @@ class UnsynthesizableTypeError extends Error {
169
199
  /**
170
200
  * Synthesizes the scenarios for one oracle by zipping every position's [`Scenario`] list to one case per test (a
171
201
  * shorter list wraps around via mod), mirroring the Noir macro. Returns `undefined` if any param or return type is
172
- * unsynthesizable (structs, ephemeral arrays).
202
+ * unsynthesizable (ephemeral arrays, structs with a variable-width field).
173
203
  */
174
204
  function synthesizeScenarios(entry: OracleRegistryEntry): OracleTestScenario[] | undefined {
175
205
  try {
@@ -214,14 +244,23 @@ function synthesizeScenariosOrThrow(entry: OracleRegistryEntry): OracleTestScena
214
244
  }
215
245
 
216
246
  /**
217
- * The composite `TypeMapping`s (`ARRAY`/`BOUNDED_VEC`/`OPTION`), discriminated by `kind`. The combinators attach `kind`
218
- * plus the inner mapping at construction; the registry erases params to the base `TypeMapping`, so the guards below
219
- * recover the structure for recursion.
247
+ * The composite `TypeMapping`s (`ARRAY`/`BOUNDED_VEC`/`OPTION`/`STRUCT`/`FIXED_ARRAY`/`FIXED_BOUNDED_VEC`),
248
+ * discriminated by `kind`. The combinators attach `kind` plus the inner mapping(s) at construction; the registry
249
+ * erases params to the base `TypeMapping`, so the guards below recover the structure for recursion.
220
250
  */
221
251
  type ArrayMapping = TypeMapping & { kind: 'array'; inner: TypeMapping };
222
252
  type BoundedVecMapping = TypeMapping & { kind: 'bounded-vec'; inner: TypeMapping };
223
253
  type OptionMapping = TypeMapping & { kind: 'option'; inner: TypeMapping };
224
- type CompositeMapping = ArrayMapping | BoundedVecMapping | OptionMapping;
254
+ type StructMapping = TypeMapping & { kind: 'struct'; fields: readonly StructField[] };
255
+ type FixedArrayMapping = TypeMapping & { kind: 'fixed-array'; inner: TypeMapping; length: number };
256
+ type FixedBoundedVecMapping = TypeMapping & { kind: 'fixed-bounded-vec'; inner: TypeMapping; maxLength: number };
257
+ type CompositeMapping =
258
+ | ArrayMapping
259
+ | BoundedVecMapping
260
+ | OptionMapping
261
+ | StructMapping
262
+ | FixedArrayMapping
263
+ | FixedBoundedVecMapping;
225
264
 
226
265
  function isArray(type: TypeMapping<any>): type is ArrayMapping {
227
266
  return 'kind' in type && type.kind === 'array';
@@ -232,3 +271,12 @@ function isBoundedVec(type: TypeMapping<any>): type is BoundedVecMapping {
232
271
  function isOption(type: TypeMapping<any>): type is OptionMapping {
233
272
  return 'kind' in type && type.kind === 'option';
234
273
  }
274
+ function isStruct(type: TypeMapping<any>): type is StructMapping {
275
+ return 'kind' in type && type.kind === 'struct';
276
+ }
277
+ function isFixedArray(type: TypeMapping<any>): type is FixedArrayMapping {
278
+ return 'kind' in type && type.kind === 'fixed-array';
279
+ }
280
+ function isFixedBoundedVec(type: TypeMapping<any>): type is FixedBoundedVecMapping {
281
+ return 'kind' in type && type.kind === 'fixed-bounded-vec';
282
+ }