@aztec/pxe 1.2.1 → 2.0.0-nightly.20250813

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 (88) hide show
  1. package/dest/config/package_info.js +1 -1
  2. package/dest/contract_function_simulator/contract_function_simulator.d.ts +5 -2
  3. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  4. package/dest/contract_function_simulator/contract_function_simulator.js +48 -29
  5. package/dest/contract_function_simulator/index.d.ts +1 -0
  6. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  7. package/dest/contract_function_simulator/index.js +1 -0
  8. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
  9. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
  10. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +1 -1
  11. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +1 -1
  12. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  13. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -1
  14. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
  15. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
  16. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +22 -0
  17. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -0
  18. package/dest/contract_function_simulator/oracle/note_packing_utils.js +49 -0
  19. package/dest/contract_function_simulator/oracle/oracle.d.ts +44 -43
  20. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  21. package/dest/contract_function_simulator/oracle/oracle.js +127 -106
  22. package/dest/contract_function_simulator/oracle/private_execution.d.ts +7 -2
  23. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  24. package/dest/contract_function_simulator/oracle/private_execution.js +16 -11
  25. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +41 -17
  26. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  27. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +51 -23
  28. package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +48 -47
  29. package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +1 -1
  30. package/dest/contract_function_simulator/oracle/typed_oracle.js +89 -87
  31. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +31 -30
  32. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  33. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +33 -30
  34. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
  35. package/dest/contract_function_simulator/pxe_oracle_interface.js +6 -7
  36. package/dest/entrypoints/server/utils.d.ts +4 -2
  37. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  38. package/dest/entrypoints/server/utils.js +4 -2
  39. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +4 -4
  40. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
  41. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +58 -59
  42. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +4 -0
  43. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +1 -0
  44. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.js +41 -0
  45. package/dest/private_kernel/hints/index.d.ts +1 -0
  46. package/dest/private_kernel/hints/index.d.ts.map +1 -1
  47. package/dest/private_kernel/hints/index.js +1 -0
  48. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  49. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  50. package/dest/private_kernel/private_kernel_execution_prover.js +13 -4
  51. package/dest/private_kernel/private_kernel_oracle.d.ts +1 -1
  52. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  53. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
  54. package/dest/private_kernel/private_kernel_oracle_impl.js +6 -6
  55. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  56. package/dest/pxe_service/error_enriching.js +1 -0
  57. package/dest/pxe_service/pxe_service.d.ts +3 -2
  58. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  59. package/dest/pxe_service/pxe_service.js +28 -19
  60. package/dest/storage/capsule_data_provider/capsule_data_provider.js +1 -1
  61. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  62. package/dest/storage/note_data_provider/note_data_provider.js +16 -4
  63. package/package.json +16 -16
  64. package/src/config/package_info.ts +1 -1
  65. package/src/contract_function_simulator/contract_function_simulator.ts +67 -37
  66. package/src/contract_function_simulator/index.ts +1 -0
  67. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  68. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
  69. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -1
  70. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
  71. package/src/contract_function_simulator/oracle/note_packing_utils.ts +52 -0
  72. package/src/contract_function_simulator/oracle/oracle.ts +149 -111
  73. package/src/contract_function_simulator/oracle/private_execution.ts +17 -12
  74. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +60 -24
  75. package/src/contract_function_simulator/oracle/typed_oracle.ts +108 -92
  76. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +34 -30
  77. package/src/contract_function_simulator/pxe_oracle_interface.ts +6 -8
  78. package/src/entrypoints/server/utils.ts +17 -6
  79. package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +106 -104
  80. package/src/private_kernel/hints/compute_tx_include_by_timestamp.ts +58 -0
  81. package/src/private_kernel/hints/index.ts +1 -0
  82. package/src/private_kernel/private_kernel_execution_prover.ts +21 -4
  83. package/src/private_kernel/private_kernel_oracle.ts +1 -1
  84. package/src/private_kernel/private_kernel_oracle_impl.ts +12 -9
  85. package/src/pxe_service/error_enriching.ts +1 -0
  86. package/src/pxe_service/pxe_service.ts +30 -32
  87. package/src/storage/capsule_data_provider/capsule_data_provider.ts +1 -1
  88. package/src/storage/note_data_provider/note_data_provider.ts +27 -16
@@ -14,6 +14,7 @@ import { type Tuple, assertLength } from '@aztec/foundation/serialize';
14
14
  import { MembershipWitness } from '@aztec/foundation/trees';
15
15
  import { privateKernelResetDimensionsConfig } from '@aztec/noir-protocol-circuits-types/client';
16
16
  import {
17
+ ClaimedLengthArray,
17
18
  KeyValidationHint,
18
19
  PaddedSideEffects,
19
20
  type PrivateCircuitPublicInputs,
@@ -24,21 +25,19 @@ import {
24
25
  PrivateKernelResetHints,
25
26
  type PrivateKernelSimulateOutput,
26
27
  type ReadRequest,
27
- ReadRequestResetStates,
28
- ReadRequestState,
28
+ ReadRequestActionEnum,
29
+ ReadRequestResetActions,
29
30
  type ScopedKeyValidationRequestAndGenerator,
30
31
  ScopedNoteHash,
31
32
  ScopedNullifier,
32
33
  ScopedReadRequest,
33
- TransientDataIndexHint,
34
- buildNoteHashReadRequestHintsFromResetStates,
35
- buildNullifierReadRequestHintsFromResetStates,
34
+ TransientDataSquashingHint,
35
+ buildNoteHashReadRequestHintsFromResetActions,
36
+ buildNullifierReadRequestHintsFromResetActions,
36
37
  buildTransientDataHints,
37
- countAccumulatedItems,
38
38
  findPrivateKernelResetDimensions,
39
- getNonEmptyItems,
40
- getNoteHashReadRequestResetStates,
41
- getNullifierReadRequestResetStates,
39
+ getNoteHashReadRequestResetActions,
40
+ getNullifierReadRequestResetActions,
42
41
  privateKernelResetDimensionNames,
43
42
  } from '@aztec/stdlib/kernel';
44
43
  import { type PrivateCallExecutionResult, collectNested } from '@aztec/stdlib/tx';
@@ -46,15 +45,14 @@ import { VkData } from '@aztec/stdlib/vks';
46
45
 
47
46
  import type { PrivateKernelOracle } from '../private_kernel_oracle.js';
48
47
 
49
- function collectNestedReadRequests(
48
+ function collectNestedReadRequests<N extends number>(
50
49
  executionStack: PrivateCallExecutionResult[],
51
- extractReadRequests: (execution: PrivateCallExecutionResult) => ReadRequest[],
50
+ extractReadRequests: (execution: PrivateCallExecutionResult) => ClaimedLengthArray<ReadRequest, N>,
52
51
  ): ScopedReadRequest[] {
53
52
  return collectNested(executionStack, executionResult => {
54
- const nonEmptyReadRequests = getNonEmptyItems(extractReadRequests(executionResult));
55
- return nonEmptyReadRequests.map(
56
- readRequest => new ScopedReadRequest(readRequest, executionResult.publicInputs.callContext.contractAddress),
57
- );
53
+ return extractReadRequests(executionResult)
54
+ .getActiveItems()
55
+ .map(readRequest => new ScopedReadRequest(readRequest, executionResult.publicInputs.callContext.contractAddress));
58
56
  });
59
57
  }
60
58
 
@@ -74,13 +72,16 @@ function getNullifierMembershipWitnessResolver(oracle: PrivateKernelOracle) {
74
72
  }
75
73
 
76
74
  async function getMasterSecretKeysAndAppKeyGenerators(
77
- keyValidationRequests: Tuple<ScopedKeyValidationRequestAndGenerator, typeof MAX_KEY_VALIDATION_REQUESTS_PER_TX>,
75
+ keyValidationRequests: ClaimedLengthArray<
76
+ ScopedKeyValidationRequestAndGenerator,
77
+ typeof MAX_KEY_VALIDATION_REQUESTS_PER_TX
78
+ >,
78
79
  numRequestsToVerify: number,
79
80
  oracle: PrivateKernelOracle,
80
81
  ) {
81
- const numRequests = countAccumulatedItems(keyValidationRequests);
82
+ const numRequestsToProcess = Math.min(keyValidationRequests.claimedLength, numRequestsToVerify);
82
83
  const keysHints = await Promise.all(
83
- keyValidationRequests.slice(0, Math.min(numRequests, numRequestsToVerify)).map(async ({ request }) => {
84
+ keyValidationRequests.array.slice(0, numRequestsToProcess).map(async ({ request }) => {
84
85
  const secretKeys = await oracle.getMasterSecretKey(request.request.pkM);
85
86
  return new KeyValidationHint(secretKeys);
86
87
  }),
@@ -93,10 +94,10 @@ export class PrivateKernelResetPrivateInputsBuilder {
93
94
  // If there's no next iteration, it's the final reset.
94
95
  private nextIteration?: PrivateCircuitPublicInputs;
95
96
 
96
- private noteHashResetStates: ReadRequestResetStates<typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>;
97
- private nullifierResetStates: ReadRequestResetStates<typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>;
97
+ private noteHashResetActions: ReadRequestResetActions<typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>;
98
+ private nullifierResetActions: ReadRequestResetActions<typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>;
98
99
  private numTransientData?: number;
99
- private transientDataIndexHints: Tuple<TransientDataIndexHint, typeof MAX_NULLIFIERS_PER_TX>;
100
+ private transientDataSquashingHints: Tuple<TransientDataSquashingHint, typeof MAX_NULLIFIERS_PER_TX>;
100
101
  private requestedDimensions: PrivateKernelResetDimensions;
101
102
 
102
103
  constructor(
@@ -107,11 +108,11 @@ export class PrivateKernelResetPrivateInputsBuilder {
107
108
  ) {
108
109
  this.previousKernel = previousKernelOutput.publicInputs;
109
110
  this.requestedDimensions = PrivateKernelResetDimensions.empty();
110
- this.noteHashResetStates = ReadRequestResetStates.empty(MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
111
- this.nullifierResetStates = ReadRequestResetStates.empty(MAX_NULLIFIER_READ_REQUESTS_PER_TX);
112
- this.transientDataIndexHints = makeTuple(
111
+ this.noteHashResetActions = ReadRequestResetActions.empty(MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
112
+ this.nullifierResetActions = ReadRequestResetActions.empty(MAX_NULLIFIER_READ_REQUESTS_PER_TX);
113
+ this.transientDataSquashingHints = makeTuple(
113
114
  MAX_NULLIFIERS_PER_TX,
114
- () => new TransientDataIndexHint(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX),
115
+ () => new TransientDataSquashingHint(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX),
115
116
  );
116
117
  this.nextIteration = executionStack[this.executionStack.length - 1]?.publicInputs;
117
118
  }
@@ -169,13 +170,13 @@ export class PrivateKernelResetPrivateInputsBuilder {
169
170
  );
170
171
  const previousKernelData = new PrivateKernelData(this.previousKernelOutput.publicInputs, vkData);
171
172
 
172
- this.reduceReadRequestStates(
173
- this.noteHashResetStates,
173
+ this.reduceReadRequestActions(
174
+ this.noteHashResetActions,
174
175
  dimensions.NOTE_HASH_PENDING_READ,
175
176
  dimensions.NOTE_HASH_SETTLED_READ,
176
177
  );
177
- this.reduceReadRequestStates(
178
- this.nullifierResetStates,
178
+ this.reduceReadRequestActions(
179
+ this.nullifierResetActions,
179
180
  dimensions.NULLIFIER_PENDING_READ,
180
181
  dimensions.NULLIFIER_SETTLED_READ,
181
182
  );
@@ -187,101 +188,104 @@ export class PrivateKernelResetPrivateInputsBuilder {
187
188
  previousKernelData,
188
189
  paddedSideEffects,
189
190
  new PrivateKernelResetHints(
190
- await buildNoteHashReadRequestHintsFromResetStates(
191
+ await buildNoteHashReadRequestHintsFromResetActions(
191
192
  oracle,
192
193
  this.previousKernel.validationRequests.noteHashReadRequests,
193
194
  this.previousKernel.end.noteHashes,
194
- this.noteHashResetStates,
195
+ this.noteHashResetActions,
195
196
  noteHashLeafIndexMap,
196
197
  ),
197
- await buildNullifierReadRequestHintsFromResetStates(
198
+ await buildNullifierReadRequestHintsFromResetActions(
198
199
  { getNullifierMembershipWitness: getNullifierMembershipWitnessResolver(oracle) },
199
200
  this.previousKernel.validationRequests.nullifierReadRequests,
200
- this.nullifierResetStates,
201
+ this.nullifierResetActions,
201
202
  ),
202
203
  await getMasterSecretKeysAndAppKeyGenerators(
203
204
  this.previousKernel.validationRequests.scopedKeyValidationRequestsAndGenerators,
204
205
  dimensions.KEY_VALIDATION,
205
206
  oracle,
206
207
  ),
207
- this.transientDataIndexHints,
208
+ this.transientDataSquashingHints,
208
209
  this.validationRequestsSplitCounter,
209
210
  ),
210
211
  dimensions,
211
212
  );
212
213
  }
213
214
 
214
- private reduceReadRequestStates<NUM_READS extends number>(
215
- resetStates: ReadRequestResetStates<NUM_READS>,
215
+ private reduceReadRequestActions<NUM_READS extends number>(
216
+ resetActions: ReadRequestResetActions<NUM_READS>,
216
217
  maxPending: number,
217
218
  maxSettled: number,
218
219
  ) {
219
220
  let numPending = 0;
220
221
  let numSettled = 0;
221
- for (let i = 0; i < resetStates.states.length; i++) {
222
- const state = resetStates.states[i];
223
- if (state === ReadRequestState.PENDING) {
222
+ for (let i = 0; i < resetActions.actions.length; i++) {
223
+ const action = resetActions.actions[i];
224
+ if (action === ReadRequestActionEnum.READ_AS_PENDING) {
224
225
  if (numPending < maxPending) {
225
226
  numPending++;
226
227
  } else {
227
- resetStates.states[i] = ReadRequestState.NADA;
228
+ resetActions.actions[i] = ReadRequestActionEnum.SKIP;
228
229
  }
229
- } else if (state === ReadRequestState.SETTLED) {
230
+ } else if (action === ReadRequestActionEnum.READ_AS_SETTLED) {
230
231
  if (numSettled < maxSettled) {
231
232
  numSettled++;
232
233
  } else {
233
- resetStates.states[i] = ReadRequestState.NADA;
234
+ resetActions.actions[i] = ReadRequestActionEnum.SKIP;
234
235
  }
235
236
  }
236
237
  }
237
238
 
238
- resetStates.pendingReadHints = resetStates.pendingReadHints.slice(0, maxPending);
239
+ resetActions.pendingReadHints = resetActions.pendingReadHints.slice(0, maxPending);
239
240
  }
240
241
 
241
242
  private needsResetNoteHashReadRequests(forceResetAll = false) {
242
- const numCurr = countAccumulatedItems(this.previousKernel.validationRequests.noteHashReadRequests);
243
- const numNext = this.nextIteration ? countAccumulatedItems(this.nextIteration.noteHashReadRequests) : 0;
243
+ const numCurr = this.previousKernel.validationRequests.noteHashReadRequests.claimedLength;
244
+ const numNext = this.nextIteration ? this.nextIteration.noteHashReadRequests.claimedLength : 0;
244
245
  const maxAmountToKeep = !this.nextIteration || forceResetAll ? 0 : MAX_NOTE_HASH_READ_REQUESTS_PER_TX;
245
246
  if (numCurr + numNext <= maxAmountToKeep) {
246
247
  return false;
247
248
  }
248
249
 
249
250
  const futureNoteHashes = collectNested(this.executionStack, executionResult => {
250
- const nonEmptyNoteHashes = getNonEmptyItems(executionResult.publicInputs.noteHashes);
251
- return nonEmptyNoteHashes.map(
252
- noteHash => new ScopedNoteHash(noteHash, executionResult.publicInputs.callContext.contractAddress),
253
- );
251
+ return executionResult.publicInputs.noteHashes
252
+ .getActiveItems()
253
+ .map(noteHash => new ScopedNoteHash(noteHash, executionResult.publicInputs.callContext.contractAddress));
254
254
  });
255
255
 
256
- const resetStates = getNoteHashReadRequestResetStates(
256
+ const resetActions = getNoteHashReadRequestResetActions(
257
257
  this.previousKernel.validationRequests.noteHashReadRequests,
258
258
  this.previousKernel.end.noteHashes,
259
259
  futureNoteHashes,
260
260
  );
261
261
 
262
- const numPendingReads = resetStates.pendingReadHints.length;
263
- const numSettledReads = resetStates.states.reduce(
264
- (accum, state) => accum + (state === ReadRequestState.SETTLED ? 1 : 0),
262
+ const numPendingReads = resetActions.pendingReadHints.length;
263
+ const numSettledReads = resetActions.actions.reduce(
264
+ (accum, action) => accum + (action === ReadRequestActionEnum.READ_AS_SETTLED ? 1 : 0),
265
265
  0,
266
266
  );
267
267
 
268
268
  if (!this.nextIteration) {
269
- this.noteHashResetStates = resetStates;
269
+ this.noteHashResetActions = resetActions;
270
270
  this.requestedDimensions.NOTE_HASH_PENDING_READ = numPendingReads;
271
271
  this.requestedDimensions.NOTE_HASH_SETTLED_READ = numSettledReads;
272
272
  } else {
273
273
  // Pick only one dimension to reset if next iteration is not empty.
274
274
  if (numPendingReads > numSettledReads) {
275
275
  this.requestedDimensions.NOTE_HASH_PENDING_READ = numPendingReads;
276
- this.noteHashResetStates.states = assertLength(
277
- resetStates.states.map(state => (state === ReadRequestState.PENDING ? state : ReadRequestState.NADA)),
276
+ this.noteHashResetActions.actions = assertLength(
277
+ resetActions.actions.map(action =>
278
+ action === ReadRequestActionEnum.READ_AS_PENDING ? action : ReadRequestActionEnum.SKIP,
279
+ ),
278
280
  MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
279
281
  );
280
- this.noteHashResetStates.pendingReadHints = resetStates.pendingReadHints;
282
+ this.noteHashResetActions.pendingReadHints = resetActions.pendingReadHints;
281
283
  } else {
282
284
  this.requestedDimensions.NOTE_HASH_SETTLED_READ = numSettledReads;
283
- this.noteHashResetStates.states = assertLength(
284
- resetStates.states.map(state => (state === ReadRequestState.SETTLED ? state : ReadRequestState.NADA)),
285
+ this.noteHashResetActions.actions = assertLength(
286
+ resetActions.actions.map(action =>
287
+ action === ReadRequestActionEnum.READ_AS_SETTLED ? action : ReadRequestActionEnum.SKIP,
288
+ ),
285
289
  MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
286
290
  );
287
291
  }
@@ -291,49 +295,52 @@ export class PrivateKernelResetPrivateInputsBuilder {
291
295
  }
292
296
 
293
297
  private needsResetNullifierReadRequests(forceResetAll = false) {
294
- const numCurr = countAccumulatedItems(this.previousKernel.validationRequests.nullifierReadRequests);
295
- const numNext = this.nextIteration ? countAccumulatedItems(this.nextIteration.nullifierReadRequests) : 0;
298
+ const numCurr = this.previousKernel.validationRequests.nullifierReadRequests.claimedLength;
299
+ const numNext = this.nextIteration ? this.nextIteration.nullifierReadRequests.claimedLength : 0;
296
300
  const maxAmountToKeep = !this.nextIteration || forceResetAll ? 0 : MAX_NULLIFIER_READ_REQUESTS_PER_TX;
297
301
  if (numCurr + numNext <= maxAmountToKeep) {
298
302
  return false;
299
303
  }
300
304
 
301
305
  const futureNullifiers = collectNested(this.executionStack, executionResult => {
302
- const nonEmptyNullifiers = getNonEmptyItems(executionResult.publicInputs.nullifiers);
303
- return nonEmptyNullifiers.map(
304
- nullifier => new ScopedNullifier(nullifier, executionResult.publicInputs.callContext.contractAddress),
305
- );
306
+ return executionResult.publicInputs.nullifiers
307
+ .getActiveItems()
308
+ .map(nullifier => new ScopedNullifier(nullifier, executionResult.publicInputs.callContext.contractAddress));
306
309
  });
307
310
 
308
- const resetStates = getNullifierReadRequestResetStates(
311
+ const resetActions = getNullifierReadRequestResetActions(
309
312
  this.previousKernel.validationRequests.nullifierReadRequests,
310
313
  this.previousKernel.end.nullifiers,
311
314
  futureNullifiers,
312
315
  );
313
316
 
314
- const numPendingReads = resetStates.pendingReadHints.length;
315
- const numSettledReads = resetStates.states.reduce(
316
- (accum, state) => accum + (state === ReadRequestState.SETTLED ? 1 : 0),
317
+ const numPendingReads = resetActions.pendingReadHints.length;
318
+ const numSettledReads = resetActions.actions.reduce(
319
+ (accum, action) => accum + (action === ReadRequestActionEnum.READ_AS_SETTLED ? 1 : 0),
317
320
  0,
318
321
  );
319
322
 
320
323
  if (!this.nextIteration) {
321
- this.nullifierResetStates = resetStates;
324
+ this.nullifierResetActions = resetActions;
322
325
  this.requestedDimensions.NULLIFIER_PENDING_READ = numPendingReads;
323
326
  this.requestedDimensions.NULLIFIER_SETTLED_READ = numSettledReads;
324
327
  } else {
325
328
  // Pick only one dimension to reset if next iteration is not empty.
326
329
  if (numPendingReads > numSettledReads) {
327
330
  this.requestedDimensions.NULLIFIER_PENDING_READ = numPendingReads;
328
- this.nullifierResetStates.states = assertLength(
329
- resetStates.states.map(state => (state === ReadRequestState.PENDING ? state : ReadRequestState.NADA)),
331
+ this.nullifierResetActions.actions = assertLength(
332
+ resetActions.actions.map(action =>
333
+ action === ReadRequestActionEnum.READ_AS_PENDING ? action : ReadRequestActionEnum.SKIP,
334
+ ),
330
335
  MAX_NULLIFIER_READ_REQUESTS_PER_TX,
331
336
  );
332
- this.nullifierResetStates.pendingReadHints = resetStates.pendingReadHints;
337
+ this.nullifierResetActions.pendingReadHints = resetActions.pendingReadHints;
333
338
  } else {
334
339
  this.requestedDimensions.NULLIFIER_SETTLED_READ = numSettledReads;
335
- this.nullifierResetStates.states = assertLength(
336
- resetStates.states.map(state => (state === ReadRequestState.SETTLED ? state : ReadRequestState.NADA)),
340
+ this.nullifierResetActions.actions = assertLength(
341
+ resetActions.actions.map(action =>
342
+ action === ReadRequestActionEnum.READ_AS_SETTLED ? action : ReadRequestActionEnum.SKIP,
343
+ ),
337
344
  MAX_NULLIFIER_READ_REQUESTS_PER_TX,
338
345
  );
339
346
  }
@@ -343,12 +350,8 @@ export class PrivateKernelResetPrivateInputsBuilder {
343
350
  }
344
351
 
345
352
  private needsResetNullifierKeys() {
346
- const numCurr = countAccumulatedItems(
347
- this.previousKernel.validationRequests.scopedKeyValidationRequestsAndGenerators,
348
- );
349
- const numNext = this.nextIteration
350
- ? countAccumulatedItems(this.nextIteration.keyValidationRequestsAndGenerators)
351
- : 0;
353
+ const numCurr = this.previousKernel.validationRequests.scopedKeyValidationRequestsAndGenerators.claimedLength;
354
+ const numNext = this.nextIteration ? this.nextIteration.keyValidationRequestsAndGenerators.claimedLength : 0;
352
355
  const maxAmountToKeep = !this.nextIteration ? 0 : MAX_KEY_VALIDATION_REQUESTS_PER_TX;
353
356
  if (numCurr + numNext <= maxAmountToKeep) {
354
357
  return false;
@@ -364,16 +367,13 @@ export class PrivateKernelResetPrivateInputsBuilder {
364
367
  this.numTransientData = 0;
365
368
 
366
369
  const nextAccumNoteHashes =
367
- countAccumulatedItems(this.previousKernel.end.noteHashes) +
368
- countAccumulatedItems(this.nextIteration?.noteHashes ?? []);
370
+ this.previousKernel.end.noteHashes.claimedLength + (this.nextIteration?.noteHashes.claimedLength ?? 0);
369
371
  const noteHashWillOverflow = nextAccumNoteHashes > MAX_NOTE_HASHES_PER_TX;
370
372
  const nextAccumNullifiers =
371
- countAccumulatedItems(this.previousKernel.end.nullifiers) +
372
- countAccumulatedItems(this.nextIteration?.nullifiers ?? []);
373
+ this.previousKernel.end.nullifiers.claimedLength + (this.nextIteration?.nullifiers.claimedLength ?? 0);
373
374
  const nullifierWillOverflow = nextAccumNullifiers > MAX_NULLIFIERS_PER_TX;
374
375
  const nextAccumLogs =
375
- countAccumulatedItems(this.previousKernel.end.privateLogs) +
376
- countAccumulatedItems(this.nextIteration?.privateLogs ?? []);
376
+ this.previousKernel.end.privateLogs.claimedLength + (this.nextIteration?.privateLogs.claimedLength ?? 0);
377
377
  const logsWillOverflow = nextAccumLogs > MAX_PRIVATE_LOGS_PER_TX;
378
378
 
379
379
  if (this.nextIteration && !noteHashWillOverflow && !nullifierWillOverflow && !logsWillOverflow) {
@@ -388,26 +388,22 @@ export class PrivateKernelResetPrivateInputsBuilder {
388
388
  this.executionStack,
389
389
  executionResult => executionResult.publicInputs.nullifierReadRequests,
390
390
  );
391
+ // TODO(#15902): Collect future logs and only allow squashing a note hash when all its logs have been emitted
392
+ // (i.e. none of the future logs are linked to the to-be-squashed note hashes).
391
393
  if (this.nextIteration) {
392
394
  // If it's not the final reset, only one dimension will be reset at a time.
393
395
  // The note hashes and nullifiers for the remaining read requests can't be squashed.
394
- futureNoteHashReads.push(
395
- ...this.previousKernel.validationRequests.noteHashReadRequests.filter(r => !r.isEmpty()),
396
- );
397
- futureNullifierReads.push(
398
- ...this.previousKernel.validationRequests.nullifierReadRequests.filter(r => !r.isEmpty()),
399
- );
396
+ futureNoteHashReads.push(...this.previousKernel.validationRequests.noteHashReadRequests.getActiveItems());
397
+ futureNullifierReads.push(...this.previousKernel.validationRequests.nullifierReadRequests.getActiveItems());
400
398
  }
401
399
 
402
- const { numTransientData, hints: transientDataIndexHints } = buildTransientDataHints(
400
+ const { numTransientData, hints: transientDataSquashingHints } = buildTransientDataHints(
403
401
  this.previousKernel.end.noteHashes,
404
402
  this.previousKernel.end.nullifiers,
405
403
  futureNoteHashReads,
406
404
  futureNullifierReads,
407
405
  this.noteHashNullifierCounterMap,
408
406
  this.validationRequestsSplitCounter,
409
- MAX_NOTE_HASHES_PER_TX,
410
- MAX_NULLIFIERS_PER_TX,
411
407
  );
412
408
 
413
409
  if (this.nextIteration && !numTransientData) {
@@ -430,7 +426,7 @@ export class PrivateKernelResetPrivateInputsBuilder {
430
426
  }
431
427
 
432
428
  this.numTransientData = numTransientData;
433
- this.transientDataIndexHints = transientDataIndexHints;
429
+ this.transientDataSquashingHints = transientDataSquashingHints;
434
430
  this.requestedDimensions.TRANSIENT_DATA_SQUASHING = numTransientData;
435
431
 
436
432
  return numTransientData > 0;
@@ -441,7 +437,9 @@ export class PrivateKernelResetPrivateInputsBuilder {
441
437
  throw new Error('`needsResetTransientData` must be run before `needsSiloNoteHashes`.');
442
438
  }
443
439
 
444
- const numNoteHashes = this.previousKernel.end.noteHashes.filter(n => !n.contractAddress.isZero()).length;
440
+ const numNoteHashes = this.previousKernel.end.noteHashes
441
+ .getActiveItems()
442
+ .filter(n => !n.contractAddress.isZero()).length;
445
443
  const numToSilo = Math.max(0, numNoteHashes - this.numTransientData);
446
444
  this.requestedDimensions.NOTE_HASH_SILOING = numToSilo;
447
445
 
@@ -453,7 +451,9 @@ export class PrivateKernelResetPrivateInputsBuilder {
453
451
  throw new Error('`needsResetTransientData` must be run before `needsSiloNullifiers`.');
454
452
  }
455
453
 
456
- const numNullifiers = this.previousKernel.end.nullifiers.filter(n => !n.contractAddress.isZero()).length;
454
+ const numNullifiers = this.previousKernel.end.nullifiers
455
+ .getActiveItems()
456
+ .filter(n => !n.contractAddress.isZero()).length;
457
457
  const numToSilo = Math.max(0, numNullifiers - this.numTransientData);
458
458
  // Include the first nullifier if there's something to silo.
459
459
  // The reset circuit checks that capped_size must be greater than or equal to all non-empty nullifiers.
@@ -470,13 +470,15 @@ export class PrivateKernelResetPrivateInputsBuilder {
470
470
  }
471
471
 
472
472
  const privateLogs = this.previousKernel.end.privateLogs;
473
- const numLogs = privateLogs.filter(l => !l.contractAddress.isZero()).length;
473
+ const numLogs = privateLogs.getActiveItems().filter(l => !l.contractAddress.isZero()).length;
474
474
 
475
475
  const noteHashes = this.previousKernel.end.noteHashes;
476
- const squashedNoteHashCounters = this.transientDataIndexHints
477
- .filter(h => h.noteHashIndex < noteHashes.length)
478
- .map(h => noteHashes[h.noteHashIndex].counter);
479
- const numSquashedLogs = privateLogs.filter(l => squashedNoteHashCounters.includes(l.inner.noteHashCounter)).length;
476
+ const squashedNoteHashCounters = this.transientDataSquashingHints
477
+ .filter(h => h.noteHashIndex < noteHashes.claimedLength)
478
+ .map(h => noteHashes.array[h.noteHashIndex].counter);
479
+ const numSquashedLogs = privateLogs
480
+ .getActiveItems()
481
+ .filter(l => squashedNoteHashCounters.includes(l.inner.noteHashCounter)).length;
480
482
 
481
483
  const numToSilo = numLogs - numSquashedLogs;
482
484
  this.requestedDimensions.PRIVATE_LOG_SILOING = numToSilo;
@@ -0,0 +1,58 @@
1
+ import { MAX_INCLUDE_BY_TIMESTAMP_DURATION } from '@aztec/constants';
2
+ import type { PrivateKernelCircuitPublicInputs } from '@aztec/stdlib/kernel';
3
+ import type { UInt64 } from '@aztec/stdlib/types';
4
+
5
+ const ROUNDED_DURATIONS = [
6
+ 3600, // 1 hour
7
+ 1800, // 30 mins
8
+ 1, // 1 second
9
+ ];
10
+
11
+ function roundTimestamp(blockTimestamp: bigint, includeByTimestamp: bigint): UInt64 {
12
+ return ROUNDED_DURATIONS.reduce((timestamp, duration) => {
13
+ if (timestamp <= blockTimestamp) {
14
+ // The timestamp must be greater than the block timestamp.
15
+ // If it is too small, round it down again using a smaller duration.
16
+ const totalDuration = includeByTimestamp - blockTimestamp;
17
+ const roundedDuration = totalDuration - (totalDuration % BigInt(duration));
18
+ return blockTimestamp + roundedDuration;
19
+ }
20
+ return timestamp;
21
+ }, 0n);
22
+ }
23
+
24
+ export function computeTxIncludeByTimestamp(
25
+ previousKernel: PrivateKernelCircuitPublicInputs,
26
+ maxDuration = MAX_INCLUDE_BY_TIMESTAMP_DURATION,
27
+ ): UInt64 {
28
+ if (maxDuration > MAX_INCLUDE_BY_TIMESTAMP_DURATION) {
29
+ throw new Error(
30
+ `Custom max duration cannot be greater than the max allowed. Max allowed: ${MAX_INCLUDE_BY_TIMESTAMP_DURATION}. Custom value: ${maxDuration}.`,
31
+ );
32
+ }
33
+
34
+ const blockTimestamp = previousKernel.constants.historicalHeader.globalVariables.timestamp;
35
+ const maxTimestamp = blockTimestamp + BigInt(maxDuration);
36
+ const includeByTimestamp = previousKernel.includeByTimestamp;
37
+
38
+ // If the includeByTimestamp set during the tx execution is greater than or equal to the max allowed duration,
39
+ // use the maximum allowed timestamp.
40
+ // Note: It shouldn't be larger than the max allowed duration, but we check for it anyway.
41
+ if (includeByTimestamp >= maxTimestamp) {
42
+ return maxTimestamp;
43
+ }
44
+
45
+ // Round it down to the nearest hour/min/second to reduce precision and avoid revealing the exact value.
46
+ // This makes it harder for others to infer what function calls may have been used to produce a specific timestamp.
47
+ const roundedTimestamp = roundTimestamp(blockTimestamp, includeByTimestamp);
48
+
49
+ // The tx can't be published if the timestamp is the same or less than the historical block's timestamp.
50
+ // Future blocks will have a greater timestamp, so the tx would never be included.
51
+ if (roundedTimestamp <= blockTimestamp) {
52
+ throw new Error(
53
+ `Include-by timestamp must be greater than the historical block timestamp. Block timestamp: ${blockTimestamp}. Include-by timestamp: ${includeByTimestamp}.`,
54
+ );
55
+ }
56
+
57
+ return roundedTimestamp;
58
+ }
@@ -1 +1,2 @@
1
1
  export * from './build_private_kernel_reset_private_inputs.js';
2
+ export * from './compute_tx_include_by_timestamp.js';
@@ -50,7 +50,7 @@ export interface PrivateKernelExecutionProverConfig {
50
50
  }
51
51
 
52
52
  /**
53
- * The PrivateKernelSequencer class is responsible for taking a transaction request and sequencing the
53
+ * The PrivateKernelExecutionProver class is responsible for taking a transaction request and sequencing the
54
54
  * the execution of the private functions within, sequenced with private kernel "glue" to check protocol rules.
55
55
  * The result can be a client IVC proof of the private transaction portion, or just a simulation that can e.g.
56
56
  * inform state tree updates.
@@ -91,6 +91,8 @@ export class PrivateKernelExecutionProver {
91
91
 
92
92
  const isPrivateOnlyTx = executionResult.publicFunctionCalldata.length === 0;
93
93
 
94
+ // Initialise an executionStack, beginning with the PrivateCallExecutionResult
95
+ // of the entrypoint function of the tx.
94
96
  const executionStack = [executionResult.entrypoint];
95
97
  let firstIteration = true;
96
98
 
@@ -138,7 +140,7 @@ export class PrivateKernelExecutionProver {
138
140
 
139
141
  const currentExecution = executionStack.pop()!;
140
142
 
141
- executionStack.push(...[...currentExecution.nestedExecutions].reverse());
143
+ executionStack.push(...[...currentExecution.nestedExecutionResults].reverse());
142
144
 
143
145
  const functionName = await this.oracle.getDebugFunctionName(
144
146
  currentExecution.publicInputs.callContext.contractAddress,
@@ -270,9 +272,24 @@ export class PrivateKernelExecutionProver {
270
272
  `Calling private kernel tail with hwm ${previousKernelData.publicInputs.minRevertibleSideEffectCounter}`,
271
273
  );
272
274
 
273
- // TODO: Enable padding when we have a better what are the final amounts we should pad to.
275
+ // TODO: Enable padding once we better understand the final amounts to pad to.
274
276
  const paddedSideEffectAmounts = PaddedSideEffectAmounts.empty();
275
- const privateInputs = new PrivateKernelTailCircuitPrivateInputs(previousKernelData, paddedSideEffectAmounts);
277
+
278
+ // Use the aggregated includeByTimestamp set throughout the tx execution.
279
+ // TODO: Call `computeTxIncludeByTimestamp` to round the value down and reduce precision, improving privacy.
280
+ const includeByTimestampUpperBound = previousKernelData.publicInputs.includeByTimestamp;
281
+ const blockTimestamp = previousKernelData.publicInputs.constants.historicalHeader.globalVariables.timestamp;
282
+ if (includeByTimestampUpperBound <= blockTimestamp) {
283
+ throw new Error(
284
+ `Include-by timestamp must be greater than the historical block timestamp. Block timestamp: ${blockTimestamp}. Include-by timestamp: ${includeByTimestampUpperBound}.`,
285
+ );
286
+ }
287
+
288
+ const privateInputs = new PrivateKernelTailCircuitPrivateInputs(
289
+ previousKernelData,
290
+ paddedSideEffectAmounts,
291
+ includeByTimestampUpperBound,
292
+ );
276
293
 
277
294
  pushTestData('private-kernel-inputs-ordering', privateInputs);
278
295
 
@@ -66,6 +66,6 @@ export interface PrivateKernelOracle {
66
66
  getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
67
67
 
68
68
  /** Returns a membership witness and leaf index to our public data indexed merkle tree,
69
- * along with an associated SharedMutable containing the class ID to update. */
69
+ * along with an associated DelayedPublicMutable containing the class ID to update. */
70
70
  getUpdatedClassIdHints(contractAddress: AztecAddress): Promise<UpdatedClassIdHints>;
71
71
  }
@@ -10,10 +10,10 @@ import type { FunctionSelector } from '@aztec/stdlib/abi';
10
10
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
11
11
  import type { L2BlockNumber } from '@aztec/stdlib/block';
12
12
  import { computeContractClassIdPreimage, computeSaltedInitializationHash } from '@aztec/stdlib/contract';
13
+ import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '@aztec/stdlib/delayed-public-mutable';
13
14
  import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
14
15
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
15
16
  import { UpdatedClassIdHints } from '@aztec/stdlib/kernel';
16
- import { SharedMutableValues, SharedMutableValuesWithHash } from '@aztec/stdlib/shared-mutable';
17
17
  import type { NullifierMembershipWitness } from '@aztec/stdlib/trees';
18
18
  import type { VerificationKeyAsFields } from '@aztec/stdlib/vks';
19
19
 
@@ -22,10 +22,10 @@ import type { PrivateKernelOracle } from './private_kernel_oracle.js';
22
22
 
23
23
  // TODO: Block number should not be "latest".
24
24
  // It should be fixed at the time the proof is being simulated. I.e., it should be the same as the value defined in the constant data.
25
+
25
26
  /**
26
27
  * A data oracle that provides information needed for simulating a transaction.
27
28
  */
28
-
29
29
  export class PrivateKernelOracleImpl implements PrivateKernelOracle {
30
30
  constructor(
31
31
  private contractDataProvider: ContractDataProvider,
@@ -99,12 +99,12 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
99
99
  }
100
100
 
101
101
  public async getUpdatedClassIdHints(contractAddress: AztecAddress): Promise<UpdatedClassIdHints> {
102
- const { sharedMutableSlot, sharedMutableHashSlot } =
103
- await SharedMutableValuesWithHash.getContractUpdateSlots(contractAddress);
102
+ const { delayedPublicMutableSlot, delayedPublicMutableHashSlot } =
103
+ await DelayedPublicMutableValuesWithHash.getContractUpdateSlots(contractAddress);
104
104
 
105
105
  const hashLeafSlot = await computePublicDataTreeLeafSlot(
106
- ProtocolContractAddress.ContractInstanceDeployer,
107
- sharedMutableHashSlot,
106
+ ProtocolContractAddress.ContractInstanceRegistry,
107
+ delayedPublicMutableHashSlot,
108
108
  );
109
109
  const updatedClassIdWitness = await this.node.getPublicDataWitness(this.blockNumber, hashLeafSlot);
110
110
 
@@ -113,8 +113,11 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
113
113
  }
114
114
 
115
115
  const readStorage = (storageSlot: Fr) =>
116
- this.node.getPublicStorageAt(this.blockNumber, ProtocolContractAddress.ContractInstanceDeployer, storageSlot);
117
- const sharedMutableValues = await SharedMutableValues.readFromTree(sharedMutableSlot, readStorage);
116
+ this.node.getPublicStorageAt(this.blockNumber, ProtocolContractAddress.ContractInstanceRegistry, storageSlot);
117
+ const delayedPublicMutableValues = await DelayedPublicMutableValues.readFromTree(
118
+ delayedPublicMutableSlot,
119
+ readStorage,
120
+ );
118
121
 
119
122
  return new UpdatedClassIdHints(
120
123
  new MembershipWitness(
@@ -123,7 +126,7 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
123
126
  updatedClassIdWitness.siblingPath.toTuple(),
124
127
  ),
125
128
  updatedClassIdWitness.leafPreimage,
126
- sharedMutableValues,
129
+ delayedPublicMutableValues,
127
130
  );
128
131
  }
129
132
  }
@@ -19,6 +19,7 @@ export async function enrichSimulationError(
19
19
  // Maps contract addresses to the set of function selectors that were in error.
20
20
  // Map and Set do reference equality for their keys instead of value equality, so we store the string
21
21
  // representation to get e.g. different contract address objects with the same address value to match.
22
+ // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
22
23
  const mentionedFunctions: Map<string, Set<FunctionSelector>> = new Map();
23
24
 
24
25
  err.getCallStack().forEach(({ contractAddress, functionSelector }) => {