@aztec/pxe 0.0.1-commit.3d8f95d → 0.0.1-commit.3e3d0c9cd

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 (184) hide show
  1. package/dest/access_scopes.d.ts +9 -0
  2. package/dest/access_scopes.d.ts.map +1 -0
  3. package/dest/access_scopes.js +6 -0
  4. package/dest/config/index.d.ts +2 -2
  5. package/dest/config/index.d.ts.map +1 -1
  6. package/dest/config/index.js +1 -1
  7. package/dest/config/package_info.js +1 -1
  8. package/dest/contract_function_simulator/contract_function_simulator.d.ts +15 -7
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  10. package/dest/contract_function_simulator/contract_function_simulator.js +129 -45
  11. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +7 -7
  12. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/execution_tagging_index_cache.js +19 -11
  14. package/dest/contract_function_simulator/index.d.ts +2 -1
  15. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  16. package/dest/contract_function_simulator/index.js +1 -0
  17. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +2 -3
  18. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +5 -4
  20. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  21. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -3
  23. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts +16 -0
  24. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts.map +1 -0
  25. package/dest/contract_function_simulator/noir-structs/message_tx_context.js +57 -0
  26. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -4
  27. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +3 -5
  29. package/dest/contract_function_simulator/oracle/interfaces.d.ts +49 -45
  30. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  31. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +9 -0
  32. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +1 -0
  33. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +43 -0
  34. package/dest/contract_function_simulator/oracle/oracle.d.ts +44 -44
  35. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/oracle/oracle.js +142 -93
  37. package/dest/contract_function_simulator/oracle/private_execution.js +5 -3
  38. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +24 -45
  39. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  40. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +39 -69
  41. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +48 -37
  42. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  43. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +104 -55
  44. package/dest/contract_logging.d.ts +22 -0
  45. package/dest/contract_logging.d.ts.map +1 -0
  46. package/dest/contract_logging.js +23 -0
  47. package/dest/contract_sync/contract_sync_service.d.ts +4 -2
  48. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
  49. package/dest/contract_sync/contract_sync_service.js +34 -19
  50. package/dest/contract_sync/helpers.d.ts +3 -2
  51. package/dest/contract_sync/helpers.d.ts.map +1 -1
  52. package/dest/contract_sync/helpers.js +3 -3
  53. package/dest/debug/pxe_debug_utils.d.ts +5 -4
  54. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  55. package/dest/debug/pxe_debug_utils.js +4 -4
  56. package/dest/entrypoints/client/bundle/index.d.ts +4 -1
  57. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  58. package/dest/entrypoints/client/bundle/index.js +3 -0
  59. package/dest/entrypoints/client/lazy/index.d.ts +4 -1
  60. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  61. package/dest/entrypoints/client/lazy/index.js +3 -0
  62. package/dest/entrypoints/server/index.d.ts +3 -1
  63. package/dest/entrypoints/server/index.d.ts.map +1 -1
  64. package/dest/entrypoints/server/index.js +2 -0
  65. package/dest/logs/log_service.d.ts +3 -2
  66. package/dest/logs/log_service.d.ts.map +1 -1
  67. package/dest/logs/log_service.js +9 -14
  68. package/dest/messages/message_context_service.d.ts +17 -0
  69. package/dest/messages/message_context_service.d.ts.map +1 -0
  70. package/dest/messages/message_context_service.js +36 -0
  71. package/dest/notes/note_service.d.ts +4 -3
  72. package/dest/notes/note_service.d.ts.map +1 -1
  73. package/dest/notes/note_service.js +3 -2
  74. package/dest/notes_filter.d.ts +25 -0
  75. package/dest/notes_filter.d.ts.map +1 -0
  76. package/dest/notes_filter.js +4 -0
  77. package/dest/oracle_version.d.ts +2 -2
  78. package/dest/oracle_version.js +3 -3
  79. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
  80. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
  81. package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
  82. package/dest/private_kernel/hints/index.d.ts +1 -1
  83. package/dest/private_kernel/hints/index.js +1 -1
  84. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
  85. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  86. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +129 -68
  87. package/dest/private_kernel/hints/test_utils.d.ts +122 -0
  88. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
  89. package/dest/private_kernel/hints/test_utils.js +203 -0
  90. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  91. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  92. package/dest/private_kernel/private_kernel_execution_prover.js +19 -11
  93. package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
  94. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  95. package/dest/private_kernel/private_kernel_oracle.js +7 -3
  96. package/dest/pxe.d.ts +23 -15
  97. package/dest/pxe.d.ts.map +1 -1
  98. package/dest/pxe.js +72 -51
  99. package/dest/storage/contract_store/contract_store.d.ts +42 -15
  100. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  101. package/dest/storage/contract_store/contract_store.js +140 -64
  102. package/dest/storage/metadata.d.ts +1 -1
  103. package/dest/storage/metadata.js +1 -1
  104. package/dest/storage/note_store/note_store.d.ts +3 -3
  105. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  106. package/dest/storage/note_store/note_store.js +3 -4
  107. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  108. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  109. package/dest/storage/tagging_store/sender_tagging_store.d.ts +29 -28
  110. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  111. package/dest/storage/tagging_store/sender_tagging_store.js +141 -115
  112. package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
  113. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
  114. package/dest/tagging/get_all_logs_by_tags.js +17 -3
  115. package/dest/tagging/index.d.ts +3 -3
  116. package/dest/tagging/index.d.ts.map +1 -1
  117. package/dest/tagging/index.js +1 -1
  118. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -5
  119. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  120. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +7 -7
  121. package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
  122. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +6 -7
  123. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  124. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +12 -11
  125. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -8
  126. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  127. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +13 -7
  128. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +4 -3
  129. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  130. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +20 -10
  131. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
  132. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  133. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +36 -24
  134. package/package.json +16 -16
  135. package/src/access_scopes.ts +9 -0
  136. package/src/config/index.ts +1 -1
  137. package/src/config/package_info.ts +1 -1
  138. package/src/contract_function_simulator/contract_function_simulator.ts +244 -65
  139. package/src/contract_function_simulator/execution_tagging_index_cache.ts +19 -14
  140. package/src/contract_function_simulator/index.ts +1 -0
  141. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +8 -5
  142. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -4
  143. package/src/contract_function_simulator/noir-structs/message_tx_context.ts +55 -0
  144. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +3 -6
  145. package/src/contract_function_simulator/oracle/interfaces.ts +53 -54
  146. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +142 -0
  147. package/src/contract_function_simulator/oracle/oracle.ts +155 -137
  148. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  149. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +47 -86
  150. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +142 -67
  151. package/src/contract_logging.ts +39 -0
  152. package/src/contract_sync/contract_sync_service.ts +49 -26
  153. package/src/contract_sync/helpers.ts +7 -2
  154. package/src/debug/pxe_debug_utils.ts +11 -9
  155. package/src/entrypoints/client/bundle/index.ts +3 -0
  156. package/src/entrypoints/client/lazy/index.ts +3 -0
  157. package/src/entrypoints/server/index.ts +2 -0
  158. package/src/logs/log_service.ts +17 -24
  159. package/src/messages/message_context_service.ts +45 -0
  160. package/src/notes/note_service.ts +4 -3
  161. package/src/notes_filter.ts +26 -0
  162. package/src/oracle_version.ts +3 -3
  163. package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
  164. package/src/private_kernel/hints/index.ts +1 -1
  165. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +164 -117
  166. package/src/private_kernel/hints/test_utils.ts +325 -0
  167. package/src/private_kernel/private_kernel_execution_prover.ts +19 -12
  168. package/src/private_kernel/private_kernel_oracle.ts +7 -7
  169. package/src/pxe.ts +111 -69
  170. package/src/storage/contract_store/contract_store.ts +170 -71
  171. package/src/storage/metadata.ts +1 -1
  172. package/src/storage/note_store/note_store.ts +8 -5
  173. package/src/storage/tagging_store/recipient_tagging_store.ts +9 -5
  174. package/src/storage/tagging_store/sender_tagging_store.ts +185 -138
  175. package/src/tagging/get_all_logs_by_tags.ts +28 -4
  176. package/src/tagging/index.ts +2 -2
  177. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +7 -10
  178. package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
  179. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
  180. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +23 -10
  181. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +26 -11
  182. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +27 -26
  183. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
  184. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +0 -1
@@ -2,23 +2,27 @@ import {
2
2
  AVM_EMITNOTEHASH_BASE_L2_GAS,
3
3
  AVM_EMITNULLIFIER_BASE_L2_GAS,
4
4
  AVM_SENDL2TOL1MSG_BASE_L2_GAS,
5
- DA_BYTES_PER_FIELD,
6
- DA_GAS_PER_BYTE,
5
+ DA_GAS_PER_FIELD,
7
6
  FIXED_AVM_STARTUP_L2_GAS,
8
- FIXED_DA_GAS,
9
- FIXED_L2_GAS,
10
- GeneratorIndex,
11
7
  L2_GAS_PER_CONTRACT_CLASS_LOG,
8
+ L2_GAS_PER_L2_TO_L1_MSG,
9
+ L2_GAS_PER_NOTE_HASH,
10
+ L2_GAS_PER_NULLIFIER,
12
11
  L2_GAS_PER_PRIVATE_LOG,
13
12
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
14
13
  MAX_ENQUEUED_CALLS_PER_TX,
15
14
  MAX_L2_TO_L1_MSGS_PER_TX,
16
15
  MAX_NOTE_HASHES_PER_TX,
16
+ MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
17
17
  MAX_NULLIFIERS_PER_TX,
18
+ MAX_NULLIFIER_READ_REQUESTS_PER_TX,
18
19
  MAX_PRIVATE_LOGS_PER_TX,
20
+ MAX_TX_LIFETIME,
21
+ PRIVATE_TX_L2_GAS_OVERHEAD,
22
+ PUBLIC_TX_L2_GAS_OVERHEAD,
23
+ TX_DA_GAS_OVERHEAD,
19
24
  } from '@aztec/constants';
20
25
  import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
21
- import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
22
26
  import { Fr } from '@aztec/foundation/curves/bn254';
23
27
  import { type Logger, createLogger } from '@aztec/foundation/log';
24
28
  import { Timer } from '@aztec/foundation/timer';
@@ -38,25 +42,36 @@ import type { FunctionCall } from '@aztec/stdlib/abi';
38
42
  import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
39
43
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
40
44
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
45
+ import type { BlockParameter } from '@aztec/stdlib/block';
41
46
  import { Gas } from '@aztec/stdlib/gas';
42
47
  import {
43
48
  computeNoteHashNonce,
44
49
  computeProtocolNullifier,
50
+ computeSiloedPrivateLogFirstField,
45
51
  computeUniqueNoteHash,
46
52
  siloNoteHash,
47
53
  siloNullifier,
48
54
  } from '@aztec/stdlib/hash';
49
55
  import type { AztecNode } from '@aztec/stdlib/interfaces/server';
50
56
  import {
57
+ ClaimedLengthArray,
51
58
  PartialPrivateTailPublicInputsForPublic,
52
59
  PartialPrivateTailPublicInputsForRollup,
53
60
  type PrivateExecutionStep,
54
61
  type PrivateKernelExecutionProofOutput,
55
62
  PrivateKernelTailCircuitPublicInputs,
63
+ PrivateLogData,
56
64
  PrivateToPublicAccumulatedData,
57
65
  PrivateToRollupAccumulatedData,
58
66
  PublicCallRequest,
67
+ ReadRequestActionEnum,
59
68
  ScopedLogHash,
69
+ ScopedNoteHash,
70
+ ScopedNullifier,
71
+ ScopedReadRequest,
72
+ buildTransientDataHints,
73
+ getNoteHashReadRequestResetActions,
74
+ getNullifierReadRequestResetActions,
60
75
  } from '@aztec/stdlib/kernel';
61
76
  import { PrivateLog } from '@aztec/stdlib/logs';
62
77
  import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
@@ -65,14 +80,18 @@ import {
65
80
  BlockHeader,
66
81
  CallContext,
67
82
  HashedValues,
83
+ type OffchainEffect,
68
84
  PrivateExecutionResult,
69
85
  TxConstantData,
70
86
  TxExecutionRequest,
71
87
  collectNested,
88
+ collectNoteHashNullifierCounterMap,
72
89
  getFinalMinRevertibleSideEffectCounter,
73
90
  } from '@aztec/stdlib/tx';
74
91
 
92
+ import type { AccessScopes } from '../access_scopes.js';
75
93
  import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
94
+ import type { MessageContextService } from '../messages/message_context_service.js';
76
95
  import type { AddressStore } from '../storage/address_store/address_store.js';
77
96
  import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
78
97
  import type { ContractStore } from '../storage/contract_store/contract_store.js';
@@ -102,8 +121,8 @@ export type ContractSimulatorRunOpts = {
102
121
  anchorBlockHeader: BlockHeader;
103
122
  /** The address used as a tagging sender when emitting private logs. */
104
123
  senderForTags?: AztecAddress;
105
- /** The accounts whose notes we can access in this call. Defaults to all. */
106
- scopes?: AztecAddress[];
124
+ /** The accounts whose notes we can access in this call. */
125
+ scopes: AccessScopes;
107
126
  /** The job ID for staged writes. */
108
127
  jobId: string;
109
128
  };
@@ -122,6 +141,7 @@ export type ContractFunctionSimulatorArgs = {
122
141
  privateEventStore: PrivateEventStore;
123
142
  simulator: CircuitSimulator;
124
143
  contractSyncService: ContractSyncService;
144
+ messageContextService: MessageContextService;
125
145
  };
126
146
 
127
147
  /**
@@ -141,6 +161,7 @@ export class ContractFunctionSimulator {
141
161
  private readonly privateEventStore: PrivateEventStore;
142
162
  private readonly simulator: CircuitSimulator;
143
163
  private readonly contractSyncService: ContractSyncService;
164
+ private readonly messageContextService: MessageContextService;
144
165
 
145
166
  constructor(args: ContractFunctionSimulatorArgs) {
146
167
  this.contractStore = args.contractStore;
@@ -155,6 +176,7 @@ export class ContractFunctionSimulator {
155
176
  this.privateEventStore = args.privateEventStore;
156
177
  this.simulator = args.simulator;
157
178
  this.contractSyncService = args.contractSyncService;
179
+ this.messageContextService = args.messageContextService;
158
180
  this.log = createLogger('simulator');
159
181
  }
160
182
 
@@ -207,8 +229,8 @@ export class ContractFunctionSimulator {
207
229
  txContext: request.txContext,
208
230
  callContext,
209
231
  anchorBlockHeader,
210
- utilityExecutor: async call => {
211
- await this.runUtility(call, [], anchorBlockHeader, scopes, jobId);
232
+ utilityExecutor: async (call, execScopes) => {
233
+ await this.runUtility(call, [], anchorBlockHeader, execScopes, jobId);
212
234
  },
213
235
  authWitnesses: request.authWitnesses,
214
236
  capsules: request.capsules,
@@ -225,6 +247,7 @@ export class ContractFunctionSimulator {
225
247
  senderAddressBookStore: this.senderAddressBookStore,
226
248
  capsuleStore: this.capsuleStore,
227
249
  privateEventStore: this.privateEventStore,
250
+ messageContextService: this.messageContextService,
228
251
  contractSyncService: this.contractSyncService,
229
252
  jobId,
230
253
  totalPublicCalldataCount: 0,
@@ -261,7 +284,7 @@ export class ContractFunctionSimulator {
261
284
  );
262
285
  const publicFunctionsCalldata = await Promise.all(
263
286
  publicCallRequests.map(async r => {
264
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
287
+ const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
265
288
  return new HashedValues(calldata, r.calldataHash);
266
289
  }),
267
290
  );
@@ -296,9 +319,9 @@ export class ContractFunctionSimulator {
296
319
  call: FunctionCall,
297
320
  authwits: AuthWitness[],
298
321
  anchorBlockHeader: BlockHeader,
299
- scopes: AztecAddress[] | undefined,
322
+ scopes: AccessScopes,
300
323
  jobId: string,
301
- ): Promise<Fr[]> {
324
+ ): Promise<{ result: Fr[]; offchainEffects: OffchainEffect[] }> {
302
325
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
303
326
 
304
327
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
@@ -319,6 +342,7 @@ export class ContractFunctionSimulator {
319
342
  senderAddressBookStore: this.senderAddressBookStore,
320
343
  capsuleStore: this.capsuleStore,
321
344
  privateEventStore: this.privateEventStore,
345
+ messageContextService: this.messageContextService,
322
346
  jobId,
323
347
  scopes,
324
348
  });
@@ -345,8 +369,11 @@ export class ContractFunctionSimulator {
345
369
  );
346
370
  });
347
371
 
348
- this.log.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
349
- return witnessMapToFields(acirExecutionResult.returnWitness);
372
+ this.log.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
373
+ return {
374
+ result: witnessMapToFields(acirExecutionResult.returnWitness),
375
+ offchainEffects: oracle.getOffchainEffects(),
376
+ };
350
377
  } catch (err) {
351
378
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
352
379
  }
@@ -387,7 +414,8 @@ class OrderedSideEffect<T> {
387
414
  * (allowing state overrides) and is much faster, while still generating a valid
388
415
  * output that can be sent to the node for public simulation
389
416
  * @param privateExecutionResult - The result of the private execution.
390
- * @param contractStore - A provider for contract data in order to get function names and debug info.
417
+ * @param debugFunctionNameGetter - A provider for contract data in order to get function names and debug info.
418
+ * @param node - AztecNode for verifying settled read requests against the note hash and nullifier trees.
391
419
  * @param minRevertibleSideEffectCounterOverride - Optional override for the min revertible side effect counter.
392
420
  * Used by TXE to simulate account contract behavior (setting the counter before app execution).
393
421
  * @returns The simulated proving result.
@@ -395,58 +423,64 @@ class OrderedSideEffect<T> {
395
423
  export async function generateSimulatedProvingResult(
396
424
  privateExecutionResult: PrivateExecutionResult,
397
425
  debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
426
+ node: AztecNode,
398
427
  minRevertibleSideEffectCounterOverride?: number,
399
428
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
400
- const siloedNoteHashes: OrderedSideEffect<Fr>[] = [];
401
- const nullifiers: OrderedSideEffect<Fr>[] = [];
402
- const taggedPrivateLogs: OrderedSideEffect<PrivateLog>[] = [];
429
+ const taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[] = [];
403
430
  const l2ToL1Messages: OrderedSideEffect<ScopedL2ToL1Message>[] = [];
404
431
  const contractClassLogsHashes: OrderedSideEffect<ScopedLogHash>[] = [];
405
432
  const publicCallRequests: OrderedSideEffect<PublicCallRequest>[] = [];
406
433
  const executionSteps: PrivateExecutionStep[] = [];
407
434
 
435
+ // Unsiloed scoped arrays — used for squashing, read request verification,
436
+ // and siloed at the end only for the surviving items
437
+ const scopedNoteHashes: ScopedNoteHash[] = [];
438
+ const scopedNullifiers: ScopedNullifier[] = [];
439
+
440
+ // Read requests for verification
441
+ const noteHashReadRequests: ScopedReadRequest[] = [];
442
+ const nullifierReadRequests: ScopedReadRequest[] = [];
443
+
408
444
  let publicTeardownCallRequest;
409
445
 
446
+ // We set expiration timestamp to anchor_block_timestamp + MAX_TX_LIFETIME (24h) just like kernels do
447
+ let expirationTimestamp =
448
+ privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader.globalVariables.timestamp +
449
+ BigInt(MAX_TX_LIFETIME);
450
+
410
451
  const executions = [privateExecutionResult.entrypoint];
411
452
 
412
453
  while (executions.length !== 0) {
413
454
  const execution = executions.shift()!;
414
455
  executions.unshift(...execution!.nestedExecutionResults);
415
456
 
416
- const { contractAddress } = execution.publicInputs.callContext;
457
+ // Just like kernels we overwrite the default value if the call sets it.
458
+ const callExpirationTimestamp = execution.publicInputs.expirationTimestamp;
459
+ if (callExpirationTimestamp !== 0n && callExpirationTimestamp < expirationTimestamp) {
460
+ expirationTimestamp = callExpirationTimestamp;
461
+ }
417
462
 
418
- const noteHashesFromExecution = await Promise.all(
419
- execution.publicInputs.noteHashes
420
- .getActiveItems()
421
- .filter(noteHash => !noteHash.isEmpty())
422
- .map(
423
- async noteHash =>
424
- new OrderedSideEffect(await siloNoteHash(contractAddress, noteHash.value), noteHash.counter),
425
- ),
426
- );
463
+ const { contractAddress } = execution.publicInputs.callContext;
427
464
 
428
- const nullifiersFromExecution = await Promise.all(
429
- execution.publicInputs.nullifiers
465
+ scopedNoteHashes.push(
466
+ ...execution.publicInputs.noteHashes
430
467
  .getActiveItems()
431
- .map(
432
- async nullifier =>
433
- new OrderedSideEffect(await siloNullifier(contractAddress, nullifier.value), nullifier.counter),
434
- ),
468
+ .filter(nh => !nh.isEmpty())
469
+ .map(nh => nh.scope(contractAddress)),
435
470
  );
471
+ scopedNullifiers.push(...execution.publicInputs.nullifiers.getActiveItems().map(n => n.scope(contractAddress)));
436
472
 
437
- const privateLogsFromExecution = await Promise.all(
438
- execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
439
- metadata.log.fields[0] = await poseidon2HashWithSeparator(
440
- [contractAddress, metadata.log.fields[0]],
441
- GeneratorIndex.PRIVATE_LOG_FIRST_FIELD,
442
- );
443
- return new OrderedSideEffect(metadata.log, metadata.counter);
444
- }),
473
+ taggedPrivateLogs.push(
474
+ ...(await Promise.all(
475
+ execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
476
+ metadata.log.fields[0] = await computeSiloedPrivateLogFirstField(contractAddress, metadata.log.fields[0]);
477
+ return new OrderedSideEffect(metadata, metadata.counter);
478
+ }),
479
+ )),
445
480
  );
446
481
 
447
- siloedNoteHashes.push(...noteHashesFromExecution);
448
- taggedPrivateLogs.push(...privateLogsFromExecution);
449
- nullifiers.push(...nullifiersFromExecution);
482
+ noteHashReadRequests.push(...execution.publicInputs.noteHashReadRequests.getActiveItems());
483
+ nullifierReadRequests.push(...execution.publicInputs.nullifierReadRequests.getActiveItems());
450
484
  l2ToL1Messages.push(
451
485
  ...execution.publicInputs.l2ToL1Msgs
452
486
  .getActiveItems()
@@ -486,6 +520,47 @@ export async function generateSimulatedProvingResult(
486
520
  });
487
521
  }
488
522
 
523
+ const noteHashNullifierCounterMap = collectNoteHashNullifierCounterMap(privateExecutionResult);
524
+ const minRevertibleSideEffectCounter =
525
+ minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
526
+
527
+ const scopedNoteHashesCLA = new ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>(
528
+ padArrayEnd(scopedNoteHashes, ScopedNoteHash.empty(), MAX_NOTE_HASHES_PER_TX),
529
+ scopedNoteHashes.length,
530
+ );
531
+ const scopedNullifiersCLA = new ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>(
532
+ padArrayEnd(scopedNullifiers, ScopedNullifier.empty(), MAX_NULLIFIERS_PER_TX),
533
+ scopedNullifiers.length,
534
+ );
535
+
536
+ const { filteredNoteHashes, filteredNullifiers, filteredPrivateLogs } = squashTransientSideEffects(
537
+ taggedPrivateLogs,
538
+ scopedNoteHashesCLA,
539
+ scopedNullifiersCLA,
540
+ noteHashNullifierCounterMap,
541
+ minRevertibleSideEffectCounter,
542
+ );
543
+
544
+ await verifyReadRequests(
545
+ node,
546
+ await privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader.hash(),
547
+ noteHashReadRequests,
548
+ nullifierReadRequests,
549
+ scopedNoteHashesCLA,
550
+ scopedNullifiersCLA,
551
+ );
552
+
553
+ const siloedNoteHashes = await Promise.all(
554
+ filteredNoteHashes
555
+ .sort((a, b) => a.counter - b.counter)
556
+ .map(async nh => new OrderedSideEffect(await siloNoteHash(nh.contractAddress, nh.value), nh.counter)),
557
+ );
558
+ const siloedNullifiers = await Promise.all(
559
+ filteredNullifiers
560
+ .sort((a, b) => a.counter - b.counter)
561
+ .map(async n => new OrderedSideEffect(await siloNullifier(n.contractAddress, n.value), n.counter)),
562
+ );
563
+
489
564
  const constantData = new TxConstantData(
490
565
  privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader,
491
566
  privateExecutionResult.entrypoint.publicInputs.txContext,
@@ -502,11 +577,9 @@ export async function generateSimulatedProvingResult(
502
577
  const getEffect = <T>(orderedSideEffect: OrderedSideEffect<T>) => orderedSideEffect.sideEffect;
503
578
 
504
579
  const isPrivateOnlyTx = privateExecutionResult.publicFunctionCalldata.length === 0;
505
- const minRevertibleSideEffectCounter =
506
- minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
507
580
 
508
581
  const [nonRevertibleNullifiers, revertibleNullifiers] = splitOrderedSideEffects(
509
- nullifiers.sort(sortByCounter),
582
+ siloedNullifiers,
510
583
  minRevertibleSideEffectCounter,
511
584
  );
512
585
  const nonceGenerator = privateExecutionResult.firstNullifier;
@@ -520,7 +593,7 @@ export async function generateSimulatedProvingResult(
520
593
  // We must make the note hashes unique by using the
521
594
  // nonce generator and their index in the tx.
522
595
  const uniqueNoteHashes = await Promise.all(
523
- siloedNoteHashes.sort(sortByCounter).map(async (orderedSideEffect, i) => {
596
+ siloedNoteHashes.map(async (orderedSideEffect, i) => {
524
597
  const siloedNoteHash = orderedSideEffect.sideEffect;
525
598
  const nonce = await computeNoteHashNonce(nonceGenerator, i);
526
599
  const uniqueNoteHash = await computeUniqueNoteHash(nonce, siloedNoteHash);
@@ -535,18 +608,18 @@ export async function generateSimulatedProvingResult(
535
608
  ScopedL2ToL1Message.empty(),
536
609
  MAX_L2_TO_L1_MSGS_PER_TX,
537
610
  ),
538
- padArrayEnd(taggedPrivateLogs.sort(sortByCounter).map(getEffect), PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
611
+ padArrayEnd(filteredPrivateLogs.sort(sortByCounter).map(getEffect), PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
539
612
  padArrayEnd(
540
613
  contractClassLogsHashes.sort(sortByCounter).map(getEffect),
541
614
  ScopedLogHash.empty(),
542
615
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
543
616
  ),
544
617
  );
545
- gasUsed = meterGasUsed(accumulatedDataForRollup);
618
+ gasUsed = meterGasUsed(accumulatedDataForRollup, isPrivateOnlyTx);
546
619
  inputsForRollup = new PartialPrivateTailPublicInputsForRollup(accumulatedDataForRollup);
547
620
  } else {
548
621
  const [nonRevertibleNoteHashes, revertibleNoteHashes] = splitOrderedSideEffects(
549
- siloedNoteHashes.sort(sortByCounter),
622
+ siloedNoteHashes,
550
623
  minRevertibleSideEffectCounter,
551
624
  );
552
625
  const nonRevertibleUniqueNoteHashes = await Promise.all(
@@ -560,7 +633,7 @@ export async function generateSimulatedProvingResult(
560
633
  minRevertibleSideEffectCounter,
561
634
  );
562
635
  const [nonRevertibleTaggedPrivateLogs, revertibleTaggedPrivateLogs] = splitOrderedSideEffects(
563
- taggedPrivateLogs,
636
+ filteredPrivateLogs,
564
637
  minRevertibleSideEffectCounter,
565
638
  );
566
639
  const [nonRevertibleContractClassLogHashes, revertibleContractClassLogHashes] = splitOrderedSideEffects(
@@ -589,9 +662,9 @@ export async function generateSimulatedProvingResult(
589
662
  padArrayEnd(revertibleContractClassLogHashes, ScopedLogHash.empty(), MAX_CONTRACT_CLASS_LOGS_PER_TX),
590
663
  padArrayEnd(revertiblePublicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
591
664
  );
592
- gasUsed = meterGasUsed(revertibleData).add(meterGasUsed(nonRevertibleData));
665
+ gasUsed = meterGasUsed(revertibleData, isPrivateOnlyTx).add(meterGasUsed(nonRevertibleData, isPrivateOnlyTx));
593
666
  if (publicTeardownCallRequest) {
594
- gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
667
+ gasUsed = gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
595
668
  }
596
669
 
597
670
  inputsForPublic = new PartialPrivateTailPublicInputsForPublic(
@@ -603,9 +676,14 @@ export async function generateSimulatedProvingResult(
603
676
 
604
677
  const publicInputs = new PrivateKernelTailCircuitPublicInputs(
605
678
  constantData,
606
- /*gasUsed=*/ gasUsed.add(Gas.from({ l2Gas: FIXED_L2_GAS, daGas: FIXED_DA_GAS })),
679
+ /*gasUsed=*/ gasUsed.add(
680
+ Gas.from({
681
+ l2Gas: isPrivateOnlyTx ? PRIVATE_TX_L2_GAS_OVERHEAD : PUBLIC_TX_L2_GAS_OVERHEAD,
682
+ daGas: TX_DA_GAS_OVERHEAD,
683
+ }),
684
+ ),
607
685
  /*feePayer=*/ AztecAddress.zero(),
608
- /*includeByTimestamp=*/ 0n,
686
+ /*expirationTimestamp=*/ expirationTimestamp,
609
687
  hasPublicCalls ? inputsForPublic : undefined,
610
688
  !hasPublicCalls ? inputsForRollup : undefined,
611
689
  );
@@ -617,6 +695,104 @@ export async function generateSimulatedProvingResult(
617
695
  };
618
696
  }
619
697
 
698
+ /**
699
+ * Squashes transient note hashes and nullifiers, mimicking the behavior
700
+ * of the reset kernels. Returns the filtered (surviving) scoped items and private logs.
701
+ */
702
+ function squashTransientSideEffects(
703
+ taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[],
704
+ scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
705
+ scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
706
+ noteHashNullifierCounterMap: Map<number, number>,
707
+ minRevertibleSideEffectCounter: number,
708
+ ) {
709
+ const { numTransientData, hints: transientDataHints } = buildTransientDataHints(
710
+ scopedNoteHashesCLA,
711
+ scopedNullifiersCLA,
712
+ /*futureNoteHashReads=*/ [],
713
+ /*futureNullifierReads=*/ [],
714
+ /*futureLogs=*/ [],
715
+ noteHashNullifierCounterMap,
716
+ minRevertibleSideEffectCounter,
717
+ );
718
+
719
+ const squashedNoteHashCounters = new Set<number>();
720
+ const squashedNullifierCounters = new Set<number>();
721
+ for (let i = 0; i < numTransientData; i++) {
722
+ const hint = transientDataHints[i];
723
+ squashedNoteHashCounters.add(scopedNoteHashesCLA.array[hint.noteHashIndex].counter);
724
+ squashedNullifierCounters.add(scopedNullifiersCLA.array[hint.nullifierIndex].counter);
725
+ }
726
+
727
+ return {
728
+ filteredNoteHashes: scopedNoteHashesCLA.getActiveItems().filter(nh => !squashedNoteHashCounters.has(nh.counter)),
729
+ filteredNullifiers: scopedNullifiersCLA.getActiveItems().filter(n => !squashedNullifierCounters.has(n.counter)),
730
+ filteredPrivateLogs: taggedPrivateLogs
731
+ .filter(item => !squashedNoteHashCounters.has(item.sideEffect.noteHashCounter))
732
+ .map(item => new OrderedSideEffect(item.sideEffect.log, item.counter)),
733
+ };
734
+ }
735
+
736
+ /**
737
+ * Verifies settled read requests by checking membership in the note hash and nullifier trees
738
+ * at the tx's anchor block, mimicking the behavior of the kernels
739
+ */
740
+ async function verifyReadRequests(
741
+ node: Pick<AztecNode, 'getNoteHashMembershipWitness' | 'getNullifierMembershipWitness'>,
742
+ anchorBlockHash: BlockParameter,
743
+ noteHashReadRequests: ScopedReadRequest[],
744
+ nullifierReadRequests: ScopedReadRequest[],
745
+ scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
746
+ scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
747
+ ) {
748
+ const noteHashReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>(
749
+ padArrayEnd(noteHashReadRequests, ScopedReadRequest.empty(), MAX_NOTE_HASH_READ_REQUESTS_PER_TX),
750
+ noteHashReadRequests.length,
751
+ );
752
+ const nullifierReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>(
753
+ padArrayEnd(nullifierReadRequests, ScopedReadRequest.empty(), MAX_NULLIFIER_READ_REQUESTS_PER_TX),
754
+ nullifierReadRequests.length,
755
+ );
756
+
757
+ const noteHashResetActions = getNoteHashReadRequestResetActions(noteHashReadRequestsCLA, scopedNoteHashesCLA);
758
+ const nullifierResetActions = getNullifierReadRequestResetActions(nullifierReadRequestsCLA, scopedNullifiersCLA);
759
+
760
+ const settledNoteHashReads: { index: number; value: Fr }[] = [];
761
+ for (let i = 0; i < noteHashResetActions.actions.length; i++) {
762
+ if (noteHashResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
763
+ settledNoteHashReads.push({ index: i, value: noteHashReadRequests[i].value });
764
+ }
765
+ }
766
+
767
+ const settledNullifierReads: { index: number; value: Fr }[] = [];
768
+ for (let i = 0; i < nullifierResetActions.actions.length; i++) {
769
+ if (nullifierResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
770
+ settledNullifierReads.push({ index: i, value: nullifierReadRequests[i].value });
771
+ }
772
+ }
773
+
774
+ const [noteHashWitnesses, nullifierWitnesses] = await Promise.all([
775
+ Promise.all(settledNoteHashReads.map(({ value }) => node.getNoteHashMembershipWitness(anchorBlockHash, value))),
776
+ Promise.all(settledNullifierReads.map(({ value }) => node.getNullifierMembershipWitness(anchorBlockHash, value))),
777
+ ]);
778
+
779
+ for (let i = 0; i < settledNoteHashReads.length; i++) {
780
+ if (!noteHashWitnesses[i]) {
781
+ throw new Error(
782
+ `Note hash read request at index ${settledNoteHashReads[i].index} is reading an unknown note hash: ${settledNoteHashReads[i].value}`,
783
+ );
784
+ }
785
+ }
786
+
787
+ for (let i = 0; i < settledNullifierReads.length; i++) {
788
+ if (!nullifierWitnesses[i]) {
789
+ throw new Error(
790
+ `Nullifier read request at index ${settledNullifierReads[i].index} is reading an unknown nullifier: ${settledNullifierReads[i].value}`,
791
+ );
792
+ }
793
+ }
794
+ }
795
+
620
796
  function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertibleSideEffectCounter: number) {
621
797
  const revertibleSideEffects: T[] = [];
622
798
  const nonRevertibleSideEffects: T[] = [];
@@ -630,21 +806,24 @@ function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertib
630
806
  return [nonRevertibleSideEffects, revertibleSideEffects];
631
807
  }
632
808
 
633
- function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData) {
809
+ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData, isPrivateOnlyTx: boolean) {
634
810
  let meteredDAFields = 0;
635
811
  let meteredL2Gas = 0;
636
812
 
637
813
  const numNoteHashes = arrayNonEmptyLength(data.noteHashes, hash => hash.isEmpty());
638
814
  meteredDAFields += numNoteHashes;
639
- meteredL2Gas += numNoteHashes * AVM_EMITNOTEHASH_BASE_L2_GAS;
815
+ const noteHashBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NOTE_HASH : AVM_EMITNOTEHASH_BASE_L2_GAS;
816
+ meteredL2Gas += numNoteHashes * noteHashBaseGas;
640
817
 
641
818
  const numNullifiers = arrayNonEmptyLength(data.nullifiers, nullifier => nullifier.isEmpty());
642
819
  meteredDAFields += numNullifiers;
643
- meteredL2Gas += numNullifiers * AVM_EMITNULLIFIER_BASE_L2_GAS;
820
+ const nullifierBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NULLIFIER : AVM_EMITNULLIFIER_BASE_L2_GAS;
821
+ meteredL2Gas += numNullifiers * nullifierBaseGas;
644
822
 
645
823
  const numL2toL1Messages = arrayNonEmptyLength(data.l2ToL1Msgs, msg => msg.isEmpty());
646
824
  meteredDAFields += numL2toL1Messages;
647
- meteredL2Gas += numL2toL1Messages * AVM_SENDL2TOL1MSG_BASE_L2_GAS;
825
+ const l2ToL1MessageBaseGas = isPrivateOnlyTx ? L2_GAS_PER_L2_TO_L1_MSG : AVM_SENDL2TOL1MSG_BASE_L2_GAS;
826
+ meteredL2Gas += numL2toL1Messages * l2ToL1MessageBaseGas;
648
827
 
649
828
  const numPrivatelogs = arrayNonEmptyLength(data.privateLogs, log => log.isEmpty());
650
829
  // Every private log emits its length as an additional field
@@ -652,14 +831,14 @@ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccu
652
831
  meteredL2Gas += numPrivatelogs * L2_GAS_PER_PRIVATE_LOG;
653
832
 
654
833
  const numContractClassLogs = arrayNonEmptyLength(data.contractClassLogsHashes, log => log.isEmpty());
655
- // Every contract class log emits its length and contract address as additional fields
834
+ // Every contract class log emits its contract address as an additional field
656
835
  meteredDAFields += data.contractClassLogsHashes.reduce(
657
- (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 2 : acc),
836
+ (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 1 : acc),
658
837
  0,
659
838
  );
660
839
  meteredL2Gas += numContractClassLogs * L2_GAS_PER_CONTRACT_CLASS_LOG;
661
840
 
662
- const meteredDAGas = meteredDAFields * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE;
841
+ const meteredDAGas = meteredDAFields * DA_GAS_PER_FIELD;
663
842
 
664
843
  if ((data as PrivateToPublicAccumulatedData).publicCallRequests) {
665
844
  const dataForPublic = data as PrivateToPublicAccumulatedData;
@@ -1,32 +1,37 @@
1
- import { DirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs';
1
+ import { ExtendedDirectionalAppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';
2
2
 
3
3
  /**
4
- * A map that stores the tagging index for a given directional app tagging secret.
4
+ * A map that stores the tagging index range for a given extended directional app tagging secret.
5
5
  * Note: The directional app tagging secret is unique for a (sender, recipient, contract) tuple while the direction
6
6
  * of sender -> recipient matters.
7
7
  */
8
8
  export class ExecutionTaggingIndexCache {
9
- private taggingIndexMap: Map<string, number> = new Map();
9
+ private taggingIndexMap: Map<string, { lowestIndex: number; highestIndex: number }> = new Map();
10
10
 
11
- public getLastUsedIndex(secret: DirectionalAppTaggingSecret): number | undefined {
12
- return this.taggingIndexMap.get(secret.toString());
11
+ public getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret): number | undefined {
12
+ return this.taggingIndexMap.get(secret.toString())?.highestIndex;
13
13
  }
14
14
 
15
- public setLastUsedIndex(secret: DirectionalAppTaggingSecret, index: number) {
15
+ public setLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) {
16
16
  const currentValue = this.taggingIndexMap.get(secret.toString());
17
- if (currentValue !== undefined && currentValue !== index - 1) {
18
- throw new Error(`Invalid tagging index update. Current value: ${currentValue}, new value: ${index}`);
17
+ if (currentValue !== undefined && currentValue.highestIndex !== index - 1) {
18
+ throw new Error(`Invalid tagging index update. Current value: ${currentValue.highestIndex}, new value: ${index}`);
19
+ }
20
+ if (currentValue !== undefined) {
21
+ currentValue.highestIndex = index;
22
+ } else {
23
+ this.taggingIndexMap.set(secret.toString(), { lowestIndex: index, highestIndex: index });
19
24
  }
20
- this.taggingIndexMap.set(secret.toString(), index);
21
25
  }
22
26
 
23
27
  /**
24
- * Returns the pre-tags that were used in this execution (and that need to be stored in the db).
28
+ * Returns the tagging index ranges that were used in this execution (and that need to be stored in the db).
25
29
  */
26
- public getUsedPreTags(): PreTag[] {
27
- return Array.from(this.taggingIndexMap.entries()).map(([secret, index]) => ({
28
- secret: DirectionalAppTaggingSecret.fromString(secret),
29
- index,
30
+ public getUsedTaggingIndexRanges(): TaggingIndexRange[] {
31
+ return Array.from(this.taggingIndexMap.entries()).map(([secret, { lowestIndex, highestIndex }]) => ({
32
+ extendedSecret: ExtendedDirectionalAppTaggingSecret.fromString(secret),
33
+ lowestIndex,
34
+ highestIndex,
30
35
  }));
31
36
  }
32
37
  }
@@ -4,6 +4,7 @@ export { HashedValuesCache } from './hashed_values_cache.js';
4
4
  export { pickNotes } from './pick_notes.js';
5
5
  export type { NoteData, IMiscOracle, IUtilityExecutionOracle, IPrivateExecutionOracle } from './oracle/interfaces.js';
6
6
  export { MessageLoadOracleInputs } from './oracle/message_load_oracle_inputs.js';
7
+ export { MessageContextService } from '../messages/message_context_service.js';
7
8
  export { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
8
9
  export { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
9
10
  export { Oracle } from './oracle/oracle.js';
@@ -4,9 +4,6 @@ import { EventSelector } from '@aztec/stdlib/abi';
4
4
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
5
5
  import { TxHash } from '@aztec/stdlib/tx';
6
6
 
7
- // TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
8
- const MAX_EVENT_SERIALIZED_LEN = 12;
9
-
10
7
  /**
11
8
  * Intermediate struct used to perform batch event validation by PXE. The `utilityValidateAndStoreEnqueuedNotesAndEvents` oracle
12
9
  * expects for values of this type to be stored in a `CapsuleArray`.
@@ -22,7 +19,7 @@ export class EventValidationRequest {
22
19
  public recipient: AztecAddress,
23
20
  ) {}
24
21
 
25
- static fromFields(fields: Fr[] | FieldReader): EventValidationRequest {
22
+ static fromFields(fields: Fr[], maxEventSerializedLen: number): EventValidationRequest {
26
23
  const reader = FieldReader.asReader(fields);
27
24
 
28
25
  const contractAddress = AztecAddress.fromField(reader.readField());
@@ -30,7 +27,7 @@ export class EventValidationRequest {
30
27
 
31
28
  const randomness = reader.readField();
32
29
 
33
- const eventStorage = reader.readFieldArray(MAX_EVENT_SERIALIZED_LEN);
30
+ const eventStorage = reader.readFieldArray(maxEventSerializedLen);
34
31
  const eventLen = reader.readField().toNumber();
35
32
  const serializedEvent = eventStorage.slice(0, eventLen);
36
33
 
@@ -38,6 +35,12 @@ export class EventValidationRequest {
38
35
  const txHash = TxHash.fromField(reader.readField());
39
36
  const recipient = AztecAddress.fromField(reader.readField());
40
37
 
38
+ if (reader.remainingFields() !== 0) {
39
+ throw new Error(
40
+ `Error converting array of fields to EventValidationRequest: expected ${reader.cursor} fields but received ${fields.length} (maxEventSerializedLen=${maxEventSerializedLen}).`,
41
+ );
42
+ }
43
+
41
44
  return new EventValidationRequest(
42
45
  contractAddress,
43
46
  eventTypeId,