@aztec/pxe 0.0.1-commit.f2ce05ee → 0.0.1-commit.f5d02921e

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 (210) 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/block_synchronizer/block_synchronizer.d.ts +1 -1
  5. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  6. package/dest/block_synchronizer/block_synchronizer.js +6 -0
  7. package/dest/config/index.d.ts +2 -2
  8. package/dest/config/index.d.ts.map +1 -1
  9. package/dest/config/index.js +1 -1
  10. package/dest/config/package_info.js +1 -1
  11. package/dest/contract_function_simulator/contract_function_simulator.d.ts +60 -30
  12. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/contract_function_simulator.js +199 -72
  14. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +7 -7
  15. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  16. package/dest/contract_function_simulator/execution_tagging_index_cache.js +19 -11
  17. package/dest/contract_function_simulator/index.d.ts +2 -1
  18. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/index.js +1 -0
  20. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -5
  21. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +7 -9
  23. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  24. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  25. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -3
  26. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -6
  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 +5 -10
  29. package/dest/contract_function_simulator/oracle/interfaces.d.ts +50 -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 +38 -0
  34. package/dest/contract_function_simulator/oracle/oracle.d.ts +64 -44
  35. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/oracle/oracle.js +187 -97
  37. package/dest/contract_function_simulator/oracle/private_execution.js +5 -3
  38. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +54 -80
  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 +98 -85
  41. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +90 -52
  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 +213 -116
  44. package/dest/contract_logging.d.ts +27 -0
  45. package/dest/contract_logging.d.ts.map +1 -0
  46. package/dest/contract_logging.js +38 -0
  47. package/dest/contract_sync/contract_sync_service.d.ts +10 -5
  48. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
  49. package/dest/contract_sync/contract_sync_service.js +72 -30
  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 +9 -4
  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/bundle/utils.d.ts +1 -1
  60. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  61. package/dest/entrypoints/client/bundle/utils.js +9 -1
  62. package/dest/entrypoints/client/lazy/index.d.ts +4 -1
  63. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  64. package/dest/entrypoints/client/lazy/index.js +3 -0
  65. package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
  66. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  67. package/dest/entrypoints/client/lazy/utils.js +9 -1
  68. package/dest/entrypoints/server/index.d.ts +3 -1
  69. package/dest/entrypoints/server/index.d.ts.map +1 -1
  70. package/dest/entrypoints/server/index.js +2 -0
  71. package/dest/entrypoints/server/utils.js +9 -1
  72. package/dest/events/event_service.d.ts +3 -2
  73. package/dest/events/event_service.d.ts.map +1 -1
  74. package/dest/events/event_service.js +16 -4
  75. package/dest/logs/log_service.d.ts +6 -6
  76. package/dest/logs/log_service.d.ts.map +1 -1
  77. package/dest/logs/log_service.js +31 -40
  78. package/dest/messages/message_context_service.d.ts +17 -0
  79. package/dest/messages/message_context_service.d.ts.map +1 -0
  80. package/dest/messages/message_context_service.js +36 -0
  81. package/dest/notes/note_service.d.ts +5 -4
  82. package/dest/notes/note_service.d.ts.map +1 -1
  83. package/dest/notes/note_service.js +17 -7
  84. package/dest/notes_filter.d.ts +25 -0
  85. package/dest/notes_filter.d.ts.map +1 -0
  86. package/dest/notes_filter.js +4 -0
  87. package/dest/oracle_version.d.ts +2 -2
  88. package/dest/oracle_version.js +3 -3
  89. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
  90. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
  91. package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
  92. package/dest/private_kernel/hints/index.d.ts +1 -1
  93. package/dest/private_kernel/hints/index.js +1 -1
  94. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
  95. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  96. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +129 -68
  97. package/dest/private_kernel/hints/test_utils.d.ts +122 -0
  98. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
  99. package/dest/private_kernel/hints/test_utils.js +203 -0
  100. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  101. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  102. package/dest/private_kernel/private_kernel_execution_prover.js +19 -11
  103. package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
  104. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  105. package/dest/private_kernel/private_kernel_oracle.js +7 -3
  106. package/dest/pxe.d.ts +63 -24
  107. package/dest/pxe.d.ts.map +1 -1
  108. package/dest/pxe.js +105 -74
  109. package/dest/storage/capsule_store/capsule_service.d.ts +22 -0
  110. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -0
  111. package/dest/storage/capsule_store/capsule_service.js +50 -0
  112. package/dest/storage/capsule_store/capsule_store.d.ts +9 -9
  113. package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
  114. package/dest/storage/capsule_store/capsule_store.js +33 -28
  115. package/dest/storage/capsule_store/index.d.ts +2 -1
  116. package/dest/storage/capsule_store/index.d.ts.map +1 -1
  117. package/dest/storage/capsule_store/index.js +1 -0
  118. package/dest/storage/contract_store/contract_store.d.ts +42 -15
  119. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  120. package/dest/storage/contract_store/contract_store.js +140 -64
  121. package/dest/storage/metadata.d.ts +1 -1
  122. package/dest/storage/metadata.js +1 -1
  123. package/dest/storage/note_store/note_store.d.ts +3 -3
  124. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  125. package/dest/storage/note_store/note_store.js +3 -4
  126. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  127. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  128. package/dest/storage/tagging_store/sender_tagging_store.d.ts +29 -28
  129. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  130. package/dest/storage/tagging_store/sender_tagging_store.js +141 -115
  131. package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
  132. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
  133. package/dest/tagging/get_all_logs_by_tags.js +17 -3
  134. package/dest/tagging/index.d.ts +3 -3
  135. package/dest/tagging/index.d.ts.map +1 -1
  136. package/dest/tagging/index.js +1 -1
  137. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -5
  138. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  139. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +7 -7
  140. package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
  141. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +6 -7
  142. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  143. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +12 -11
  144. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -8
  145. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  146. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +13 -7
  147. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +4 -3
  148. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  149. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +20 -10
  150. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
  151. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  152. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +36 -24
  153. package/package.json +16 -16
  154. package/src/access_scopes.ts +9 -0
  155. package/src/block_synchronizer/block_synchronizer.ts +6 -0
  156. package/src/config/index.ts +1 -1
  157. package/src/config/package_info.ts +1 -1
  158. package/src/contract_function_simulator/contract_function_simulator.ts +358 -133
  159. package/src/contract_function_simulator/execution_tagging_index_cache.ts +19 -14
  160. package/src/contract_function_simulator/index.ts +1 -0
  161. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +8 -8
  162. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -4
  163. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +3 -9
  164. package/src/contract_function_simulator/oracle/interfaces.ts +63 -54
  165. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +98 -0
  166. package/src/contract_function_simulator/oracle/oracle.ts +223 -139
  167. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  168. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +122 -177
  169. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +375 -131
  170. package/src/contract_logging.ts +52 -0
  171. package/src/contract_sync/contract_sync_service.ts +108 -45
  172. package/src/contract_sync/helpers.ts +9 -3
  173. package/src/debug/pxe_debug_utils.ts +11 -9
  174. package/src/entrypoints/client/bundle/index.ts +3 -0
  175. package/src/entrypoints/client/bundle/utils.ts +9 -1
  176. package/src/entrypoints/client/lazy/index.ts +3 -0
  177. package/src/entrypoints/client/lazy/utils.ts +9 -1
  178. package/src/entrypoints/server/index.ts +2 -0
  179. package/src/entrypoints/server/utils.ts +7 -7
  180. package/src/events/event_service.ts +17 -4
  181. package/src/logs/log_service.ts +61 -63
  182. package/src/messages/message_context_service.ts +44 -0
  183. package/src/notes/note_service.ts +20 -8
  184. package/src/notes_filter.ts +26 -0
  185. package/src/oracle_version.ts +3 -3
  186. package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
  187. package/src/private_kernel/hints/index.ts +1 -1
  188. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +164 -117
  189. package/src/private_kernel/hints/test_utils.ts +325 -0
  190. package/src/private_kernel/private_kernel_execution_prover.ts +19 -12
  191. package/src/private_kernel/private_kernel_oracle.ts +7 -7
  192. package/src/pxe.ts +190 -117
  193. package/src/storage/capsule_store/capsule_service.ts +91 -0
  194. package/src/storage/capsule_store/capsule_store.ts +34 -26
  195. package/src/storage/capsule_store/index.ts +1 -0
  196. package/src/storage/contract_store/contract_store.ts +170 -71
  197. package/src/storage/metadata.ts +1 -1
  198. package/src/storage/note_store/note_store.ts +8 -5
  199. package/src/storage/tagging_store/recipient_tagging_store.ts +9 -5
  200. package/src/storage/tagging_store/sender_tagging_store.ts +185 -138
  201. package/src/tagging/get_all_logs_by_tags.ts +28 -4
  202. package/src/tagging/index.ts +2 -2
  203. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +7 -10
  204. package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
  205. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
  206. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +23 -10
  207. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +26 -11
  208. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +27 -26
  209. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
  210. 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,15 +80,20 @@ 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';
96
+ import { CapsuleService } from '../storage/capsule_store/capsule_service.js';
77
97
  import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
78
98
  import type { ContractStore } from '../storage/contract_store/contract_store.js';
79
99
  import type { NoteStore } from '../storage/note_store/note_store.js';
@@ -90,52 +110,92 @@ import { executePrivateFunction } from './oracle/private_execution.js';
90
110
  import { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
91
111
  import { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
92
112
 
113
+ /** Options for ContractFunctionSimulator.run. */
114
+ export type ContractSimulatorRunOpts = {
115
+ /** The address of the contract (should match request.origin). */
116
+ contractAddress: AztecAddress;
117
+ /** The function selector of the entry point. */
118
+ selector: FunctionSelector;
119
+ /** The address calling the function. Can be replaced to simulate a call from another contract or account. */
120
+ msgSender?: AztecAddress;
121
+ /** The block header to use as base state for this run. */
122
+ anchorBlockHeader: BlockHeader;
123
+ /** The address used as a tagging sender when emitting private logs. */
124
+ senderForTags?: AztecAddress;
125
+ /** The accounts whose notes we can access in this call. */
126
+ scopes: AccessScopes;
127
+ /** The job ID for staged writes. */
128
+ jobId: string;
129
+ };
130
+
131
+ /** Args for ContractFunctionSimulator constructor. */
132
+ export type ContractFunctionSimulatorArgs = {
133
+ contractStore: ContractStore;
134
+ noteStore: NoteStore;
135
+ keyStore: KeyStore;
136
+ addressStore: AddressStore;
137
+ aztecNode: AztecNode;
138
+ senderTaggingStore: SenderTaggingStore;
139
+ recipientTaggingStore: RecipientTaggingStore;
140
+ senderAddressBookStore: SenderAddressBookStore;
141
+ capsuleStore: CapsuleStore;
142
+ privateEventStore: PrivateEventStore;
143
+ simulator: CircuitSimulator;
144
+ contractSyncService: ContractSyncService;
145
+ messageContextService: MessageContextService;
146
+ };
147
+
93
148
  /**
94
149
  * The contract function simulator.
95
150
  */
96
151
  export class ContractFunctionSimulator {
97
- private log: Logger;
98
-
99
- constructor(
100
- private contractStore: ContractStore,
101
- private noteStore: NoteStore,
102
- private keyStore: KeyStore,
103
- private addressStore: AddressStore,
104
- private aztecNode: AztecNode,
105
- private senderTaggingStore: SenderTaggingStore,
106
- private recipientTaggingStore: RecipientTaggingStore,
107
- private senderAddressBookStore: SenderAddressBookStore,
108
- private capsuleStore: CapsuleStore,
109
- private privateEventStore: PrivateEventStore,
110
- private simulator: CircuitSimulator,
111
- private contractSyncService: ContractSyncService,
112
- ) {
152
+ private readonly log: Logger;
153
+ private readonly contractStore: ContractStore;
154
+ private readonly noteStore: NoteStore;
155
+ private readonly keyStore: KeyStore;
156
+ private readonly addressStore: AddressStore;
157
+ private readonly aztecNode: AztecNode;
158
+ private readonly senderTaggingStore: SenderTaggingStore;
159
+ private readonly recipientTaggingStore: RecipientTaggingStore;
160
+ private readonly senderAddressBookStore: SenderAddressBookStore;
161
+ private readonly capsuleStore: CapsuleStore;
162
+ private readonly privateEventStore: PrivateEventStore;
163
+ private readonly simulator: CircuitSimulator;
164
+ private readonly contractSyncService: ContractSyncService;
165
+ private readonly messageContextService: MessageContextService;
166
+
167
+ constructor(args: ContractFunctionSimulatorArgs) {
168
+ this.contractStore = args.contractStore;
169
+ this.noteStore = args.noteStore;
170
+ this.keyStore = args.keyStore;
171
+ this.addressStore = args.addressStore;
172
+ this.aztecNode = args.aztecNode;
173
+ this.senderTaggingStore = args.senderTaggingStore;
174
+ this.recipientTaggingStore = args.recipientTaggingStore;
175
+ this.senderAddressBookStore = args.senderAddressBookStore;
176
+ this.capsuleStore = args.capsuleStore;
177
+ this.privateEventStore = args.privateEventStore;
178
+ this.simulator = args.simulator;
179
+ this.contractSyncService = args.contractSyncService;
180
+ this.messageContextService = args.messageContextService;
113
181
  this.log = createLogger('simulator');
114
182
  }
115
183
 
116
184
  /**
117
185
  * Runs a private function.
118
186
  * @param request - The transaction request.
119
- * @param entryPointArtifact - The artifact of the entry point function.
120
- * @param contractAddress - The address of the contract (should match request.origin)
121
- * @param msgSender - The address calling the function. This can be replaced to simulate a call from another contract
122
- * or a specific account.
123
- * @param anchorBlockHeader - The block header to use as base state for this run.
124
- * @param senderForTags - The address that is used as a tagging sender when emitting private logs. Returned from
125
- * the `privateGetSenderForTags` oracle.
126
- * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
127
- * @param jobId - The job ID for staged writes.
128
- * @returns The result of the execution.
129
187
  */
130
188
  public async run(
131
189
  request: TxExecutionRequest,
132
- contractAddress: AztecAddress,
133
- selector: FunctionSelector,
134
- msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
135
- anchorBlockHeader: BlockHeader,
136
- senderForTags: AztecAddress | undefined,
137
- scopes: AztecAddress[] | undefined,
138
- jobId: string,
190
+ {
191
+ contractAddress,
192
+ selector,
193
+ msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
194
+ anchorBlockHeader,
195
+ senderForTags,
196
+ scopes,
197
+ jobId,
198
+ }: ContractSimulatorRunOpts,
139
199
  ): Promise<PrivateExecutionResult> {
140
200
  const simulatorSetupTimer = new Timer();
141
201
 
@@ -165,38 +225,38 @@ export class ContractFunctionSimulator {
165
225
  const noteCache = new ExecutionNoteCache(protocolNullifier);
166
226
  const taggingIndexCache = new ExecutionTaggingIndexCache();
167
227
 
168
- const privateExecutionOracle = new PrivateExecutionOracle(
169
- request.firstCallArgsHash,
170
- request.txContext,
228
+ const privateExecutionOracle = new PrivateExecutionOracle({
229
+ argsHash: request.firstCallArgsHash,
230
+ txContext: request.txContext,
171
231
  callContext,
172
232
  anchorBlockHeader,
173
- async call => {
174
- await this.runUtility(call, [], anchorBlockHeader, scopes, jobId);
233
+ utilityExecutor: async (call, execScopes) => {
234
+ await this.runUtility(call, [], anchorBlockHeader, execScopes, jobId);
175
235
  },
176
- request.authWitnesses,
177
- request.capsules,
178
- HashedValuesCache.create(request.argsOfCalls),
236
+ authWitnesses: request.authWitnesses,
237
+ capsules: request.capsules,
238
+ executionCache: HashedValuesCache.create(request.argsOfCalls),
179
239
  noteCache,
180
240
  taggingIndexCache,
181
- this.contractStore,
182
- this.noteStore,
183
- this.keyStore,
184
- this.addressStore,
185
- this.aztecNode,
186
- this.senderTaggingStore,
187
- this.recipientTaggingStore,
188
- this.senderAddressBookStore,
189
- this.capsuleStore,
190
- this.privateEventStore,
191
- this.contractSyncService,
241
+ contractStore: this.contractStore,
242
+ noteStore: this.noteStore,
243
+ keyStore: this.keyStore,
244
+ addressStore: this.addressStore,
245
+ aztecNode: this.aztecNode,
246
+ senderTaggingStore: this.senderTaggingStore,
247
+ recipientTaggingStore: this.recipientTaggingStore,
248
+ senderAddressBookStore: this.senderAddressBookStore,
249
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
250
+ privateEventStore: this.privateEventStore,
251
+ messageContextService: this.messageContextService,
252
+ contractSyncService: this.contractSyncService,
192
253
  jobId,
193
- 0, // totalPublicArgsCount
194
- startSideEffectCounter,
195
- undefined, // log
254
+ totalPublicCalldataCount: 0,
255
+ sideEffectCounter: startSideEffectCounter,
196
256
  scopes,
197
257
  senderForTags,
198
- this.simulator,
199
- );
258
+ simulator: this.simulator,
259
+ });
200
260
 
201
261
  const setupTime = simulatorSetupTimer.ms();
202
262
 
@@ -225,7 +285,7 @@ export class ContractFunctionSimulator {
225
285
  );
226
286
  const publicFunctionsCalldata = await Promise.all(
227
287
  publicCallRequests.map(async r => {
228
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
288
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
229
289
  return new HashedValues(calldata, r.calldataHash);
230
290
  }),
231
291
  );
@@ -260,33 +320,34 @@ export class ContractFunctionSimulator {
260
320
  call: FunctionCall,
261
321
  authwits: AuthWitness[],
262
322
  anchorBlockHeader: BlockHeader,
263
- scopes: AztecAddress[] | undefined,
323
+ scopes: AccessScopes,
264
324
  jobId: string,
265
- ): Promise<Fr[]> {
325
+ ): Promise<{ result: Fr[]; offchainEffects: OffchainEffect[] }> {
266
326
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
267
327
 
268
328
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
269
329
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
270
330
  }
271
331
 
272
- const oracle = new UtilityExecutionOracle(
273
- call.to,
274
- authwits,
275
- [],
332
+ const oracle = new UtilityExecutionOracle({
333
+ contractAddress: call.to,
334
+ authWitnesses: authwits,
335
+ capsules: [],
276
336
  anchorBlockHeader,
277
- this.contractStore,
278
- this.noteStore,
279
- this.keyStore,
280
- this.addressStore,
281
- this.aztecNode,
282
- this.recipientTaggingStore,
283
- this.senderAddressBookStore,
284
- this.capsuleStore,
285
- this.privateEventStore,
337
+ contractStore: this.contractStore,
338
+ noteStore: this.noteStore,
339
+ keyStore: this.keyStore,
340
+ addressStore: this.addressStore,
341
+ aztecNode: this.aztecNode,
342
+ recipientTaggingStore: this.recipientTaggingStore,
343
+ senderAddressBookStore: this.senderAddressBookStore,
344
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
345
+ privateEventStore: this.privateEventStore,
346
+ messageContextService: this.messageContextService,
347
+ contractSyncService: this.contractSyncService,
286
348
  jobId,
287
- undefined,
288
349
  scopes,
289
- );
350
+ });
290
351
 
291
352
  try {
292
353
  this.log.verbose(`Executing utility function ${entryPointArtifact.name}`, {
@@ -310,8 +371,11 @@ export class ContractFunctionSimulator {
310
371
  );
311
372
  });
312
373
 
313
- this.log.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
314
- return witnessMapToFields(acirExecutionResult.returnWitness);
374
+ this.log.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
375
+ return {
376
+ result: witnessMapToFields(acirExecutionResult.returnWitness),
377
+ offchainEffects: oracle.getOffchainEffects(),
378
+ };
315
379
  } catch (err) {
316
380
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
317
381
  }
@@ -352,7 +416,8 @@ class OrderedSideEffect<T> {
352
416
  * (allowing state overrides) and is much faster, while still generating a valid
353
417
  * output that can be sent to the node for public simulation
354
418
  * @param privateExecutionResult - The result of the private execution.
355
- * @param contractStore - A provider for contract data in order to get function names and debug info.
419
+ * @param debugFunctionNameGetter - A provider for contract data in order to get function names and debug info.
420
+ * @param node - AztecNode for verifying settled read requests against the note hash and nullifier trees.
356
421
  * @param minRevertibleSideEffectCounterOverride - Optional override for the min revertible side effect counter.
357
422
  * Used by TXE to simulate account contract behavior (setting the counter before app execution).
358
423
  * @returns The simulated proving result.
@@ -360,58 +425,73 @@ class OrderedSideEffect<T> {
360
425
  export async function generateSimulatedProvingResult(
361
426
  privateExecutionResult: PrivateExecutionResult,
362
427
  debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
428
+ node: AztecNode,
363
429
  minRevertibleSideEffectCounterOverride?: number,
364
430
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
365
- const siloedNoteHashes: OrderedSideEffect<Fr>[] = [];
366
- const nullifiers: OrderedSideEffect<Fr>[] = [];
367
- const taggedPrivateLogs: OrderedSideEffect<PrivateLog>[] = [];
431
+ const taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[] = [];
368
432
  const l2ToL1Messages: OrderedSideEffect<ScopedL2ToL1Message>[] = [];
369
433
  const contractClassLogsHashes: OrderedSideEffect<ScopedLogHash>[] = [];
370
434
  const publicCallRequests: OrderedSideEffect<PublicCallRequest>[] = [];
371
435
  const executionSteps: PrivateExecutionStep[] = [];
372
436
 
437
+ // Unsiloed scoped arrays — used for squashing, read request verification,
438
+ // and siloed at the end only for the surviving items
439
+ const scopedNoteHashes: ScopedNoteHash[] = [];
440
+ const scopedNullifiers: ScopedNullifier[] = [];
441
+
442
+ // Read requests for verification
443
+ const noteHashReadRequests: ScopedReadRequest[] = [];
444
+ const nullifierReadRequests: ScopedReadRequest[] = [];
445
+
373
446
  let publicTeardownCallRequest;
374
447
 
448
+ // We set expiration timestamp to anchor_block_timestamp + MAX_TX_LIFETIME (24h) just like kernels do
449
+ let expirationTimestamp =
450
+ privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader.globalVariables.timestamp +
451
+ BigInt(MAX_TX_LIFETIME);
452
+
453
+ let feePayer = AztecAddress.zero();
454
+
375
455
  const executions = [privateExecutionResult.entrypoint];
376
456
 
377
457
  while (executions.length !== 0) {
378
458
  const execution = executions.shift()!;
379
459
  executions.unshift(...execution!.nestedExecutionResults);
380
460
 
461
+ // Just like kernels we overwrite the default value if the call sets it.
462
+ const callExpirationTimestamp = execution.publicInputs.expirationTimestamp;
463
+ if (callExpirationTimestamp !== 0n && callExpirationTimestamp < expirationTimestamp) {
464
+ expirationTimestamp = callExpirationTimestamp;
465
+ }
466
+
381
467
  const { contractAddress } = execution.publicInputs.callContext;
382
468
 
383
- const noteHashesFromExecution = await Promise.all(
384
- execution.publicInputs.noteHashes
385
- .getActiveItems()
386
- .filter(noteHash => !noteHash.isEmpty())
387
- .map(
388
- async noteHash =>
389
- new OrderedSideEffect(await siloNoteHash(contractAddress, noteHash.value), noteHash.counter),
390
- ),
391
- );
469
+ if (execution.publicInputs.isFeePayer) {
470
+ if (!feePayer.isZero()) {
471
+ throw new Error('Multiple fee payers found in private execution result');
472
+ }
473
+ feePayer = contractAddress;
474
+ }
392
475
 
393
- const nullifiersFromExecution = await Promise.all(
394
- execution.publicInputs.nullifiers
476
+ scopedNoteHashes.push(
477
+ ...execution.publicInputs.noteHashes
395
478
  .getActiveItems()
396
- .map(
397
- async nullifier =>
398
- new OrderedSideEffect(await siloNullifier(contractAddress, nullifier.value), nullifier.counter),
399
- ),
479
+ .filter(nh => !nh.isEmpty())
480
+ .map(nh => nh.scope(contractAddress)),
400
481
  );
482
+ scopedNullifiers.push(...execution.publicInputs.nullifiers.getActiveItems().map(n => n.scope(contractAddress)));
401
483
 
402
- const privateLogsFromExecution = await Promise.all(
403
- execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
404
- metadata.log.fields[0] = await poseidon2HashWithSeparator(
405
- [contractAddress, metadata.log.fields[0]],
406
- GeneratorIndex.PRIVATE_LOG_FIRST_FIELD,
407
- );
408
- return new OrderedSideEffect(metadata.log, metadata.counter);
409
- }),
484
+ taggedPrivateLogs.push(
485
+ ...(await Promise.all(
486
+ execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
487
+ metadata.log.fields[0] = await computeSiloedPrivateLogFirstField(contractAddress, metadata.log.fields[0]);
488
+ return new OrderedSideEffect(metadata, metadata.counter);
489
+ }),
490
+ )),
410
491
  );
411
492
 
412
- siloedNoteHashes.push(...noteHashesFromExecution);
413
- taggedPrivateLogs.push(...privateLogsFromExecution);
414
- nullifiers.push(...nullifiersFromExecution);
493
+ noteHashReadRequests.push(...execution.publicInputs.noteHashReadRequests.getActiveItems());
494
+ nullifierReadRequests.push(...execution.publicInputs.nullifierReadRequests.getActiveItems());
415
495
  l2ToL1Messages.push(
416
496
  ...execution.publicInputs.l2ToL1Msgs
417
497
  .getActiveItems()
@@ -451,6 +531,47 @@ export async function generateSimulatedProvingResult(
451
531
  });
452
532
  }
453
533
 
534
+ const noteHashNullifierCounterMap = collectNoteHashNullifierCounterMap(privateExecutionResult);
535
+ const minRevertibleSideEffectCounter =
536
+ minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
537
+
538
+ const scopedNoteHashesCLA = new ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>(
539
+ padArrayEnd(scopedNoteHashes, ScopedNoteHash.empty(), MAX_NOTE_HASHES_PER_TX),
540
+ scopedNoteHashes.length,
541
+ );
542
+ const scopedNullifiersCLA = new ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>(
543
+ padArrayEnd(scopedNullifiers, ScopedNullifier.empty(), MAX_NULLIFIERS_PER_TX),
544
+ scopedNullifiers.length,
545
+ );
546
+
547
+ const { filteredNoteHashes, filteredNullifiers, filteredPrivateLogs } = squashTransientSideEffects(
548
+ taggedPrivateLogs,
549
+ scopedNoteHashesCLA,
550
+ scopedNullifiersCLA,
551
+ noteHashNullifierCounterMap,
552
+ minRevertibleSideEffectCounter,
553
+ );
554
+
555
+ await verifyReadRequests(
556
+ node,
557
+ await privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader.hash(),
558
+ noteHashReadRequests,
559
+ nullifierReadRequests,
560
+ scopedNoteHashesCLA,
561
+ scopedNullifiersCLA,
562
+ );
563
+
564
+ const siloedNoteHashes = await Promise.all(
565
+ filteredNoteHashes
566
+ .sort((a, b) => a.counter - b.counter)
567
+ .map(async nh => new OrderedSideEffect(await siloNoteHash(nh.contractAddress, nh.value), nh.counter)),
568
+ );
569
+ const siloedNullifiers = await Promise.all(
570
+ filteredNullifiers
571
+ .sort((a, b) => a.counter - b.counter)
572
+ .map(async n => new OrderedSideEffect(await siloNullifier(n.contractAddress, n.value), n.counter)),
573
+ );
574
+
454
575
  const constantData = new TxConstantData(
455
576
  privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader,
456
577
  privateExecutionResult.entrypoint.publicInputs.txContext,
@@ -467,11 +588,9 @@ export async function generateSimulatedProvingResult(
467
588
  const getEffect = <T>(orderedSideEffect: OrderedSideEffect<T>) => orderedSideEffect.sideEffect;
468
589
 
469
590
  const isPrivateOnlyTx = privateExecutionResult.publicFunctionCalldata.length === 0;
470
- const minRevertibleSideEffectCounter =
471
- minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
472
591
 
473
592
  const [nonRevertibleNullifiers, revertibleNullifiers] = splitOrderedSideEffects(
474
- nullifiers.sort(sortByCounter),
593
+ siloedNullifiers,
475
594
  minRevertibleSideEffectCounter,
476
595
  );
477
596
  const nonceGenerator = privateExecutionResult.firstNullifier;
@@ -485,7 +604,7 @@ export async function generateSimulatedProvingResult(
485
604
  // We must make the note hashes unique by using the
486
605
  // nonce generator and their index in the tx.
487
606
  const uniqueNoteHashes = await Promise.all(
488
- siloedNoteHashes.sort(sortByCounter).map(async (orderedSideEffect, i) => {
607
+ siloedNoteHashes.map(async (orderedSideEffect, i) => {
489
608
  const siloedNoteHash = orderedSideEffect.sideEffect;
490
609
  const nonce = await computeNoteHashNonce(nonceGenerator, i);
491
610
  const uniqueNoteHash = await computeUniqueNoteHash(nonce, siloedNoteHash);
@@ -500,18 +619,18 @@ export async function generateSimulatedProvingResult(
500
619
  ScopedL2ToL1Message.empty(),
501
620
  MAX_L2_TO_L1_MSGS_PER_TX,
502
621
  ),
503
- padArrayEnd(taggedPrivateLogs.sort(sortByCounter).map(getEffect), PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
622
+ padArrayEnd(filteredPrivateLogs.sort(sortByCounter).map(getEffect), PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
504
623
  padArrayEnd(
505
624
  contractClassLogsHashes.sort(sortByCounter).map(getEffect),
506
625
  ScopedLogHash.empty(),
507
626
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
508
627
  ),
509
628
  );
510
- gasUsed = meterGasUsed(accumulatedDataForRollup);
629
+ gasUsed = meterGasUsed(accumulatedDataForRollup, isPrivateOnlyTx);
511
630
  inputsForRollup = new PartialPrivateTailPublicInputsForRollup(accumulatedDataForRollup);
512
631
  } else {
513
632
  const [nonRevertibleNoteHashes, revertibleNoteHashes] = splitOrderedSideEffects(
514
- siloedNoteHashes.sort(sortByCounter),
633
+ siloedNoteHashes,
515
634
  minRevertibleSideEffectCounter,
516
635
  );
517
636
  const nonRevertibleUniqueNoteHashes = await Promise.all(
@@ -525,7 +644,7 @@ export async function generateSimulatedProvingResult(
525
644
  minRevertibleSideEffectCounter,
526
645
  );
527
646
  const [nonRevertibleTaggedPrivateLogs, revertibleTaggedPrivateLogs] = splitOrderedSideEffects(
528
- taggedPrivateLogs,
647
+ filteredPrivateLogs,
529
648
  minRevertibleSideEffectCounter,
530
649
  );
531
650
  const [nonRevertibleContractClassLogHashes, revertibleContractClassLogHashes] = splitOrderedSideEffects(
@@ -554,9 +673,9 @@ export async function generateSimulatedProvingResult(
554
673
  padArrayEnd(revertibleContractClassLogHashes, ScopedLogHash.empty(), MAX_CONTRACT_CLASS_LOGS_PER_TX),
555
674
  padArrayEnd(revertiblePublicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
556
675
  );
557
- gasUsed = meterGasUsed(revertibleData).add(meterGasUsed(nonRevertibleData));
676
+ gasUsed = meterGasUsed(revertibleData, isPrivateOnlyTx).add(meterGasUsed(nonRevertibleData, isPrivateOnlyTx));
558
677
  if (publicTeardownCallRequest) {
559
- gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
678
+ gasUsed = gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
560
679
  }
561
680
 
562
681
  inputsForPublic = new PartialPrivateTailPublicInputsForPublic(
@@ -568,9 +687,14 @@ export async function generateSimulatedProvingResult(
568
687
 
569
688
  const publicInputs = new PrivateKernelTailCircuitPublicInputs(
570
689
  constantData,
571
- /*gasUsed=*/ gasUsed.add(Gas.from({ l2Gas: FIXED_L2_GAS, daGas: FIXED_DA_GAS })),
572
- /*feePayer=*/ AztecAddress.zero(),
573
- /*includeByTimestamp=*/ 0n,
690
+ /*gasUsed=*/ gasUsed.add(
691
+ Gas.from({
692
+ l2Gas: isPrivateOnlyTx ? PRIVATE_TX_L2_GAS_OVERHEAD : PUBLIC_TX_L2_GAS_OVERHEAD,
693
+ daGas: TX_DA_GAS_OVERHEAD,
694
+ }),
695
+ ),
696
+ /*feePayer=*/ feePayer,
697
+ /*expirationTimestamp=*/ expirationTimestamp,
574
698
  hasPublicCalls ? inputsForPublic : undefined,
575
699
  !hasPublicCalls ? inputsForRollup : undefined,
576
700
  );
@@ -582,6 +706,104 @@ export async function generateSimulatedProvingResult(
582
706
  };
583
707
  }
584
708
 
709
+ /**
710
+ * Squashes transient note hashes and nullifiers, mimicking the behavior
711
+ * of the reset kernels. Returns the filtered (surviving) scoped items and private logs.
712
+ */
713
+ function squashTransientSideEffects(
714
+ taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[],
715
+ scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
716
+ scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
717
+ noteHashNullifierCounterMap: Map<number, number>,
718
+ minRevertibleSideEffectCounter: number,
719
+ ) {
720
+ const { numTransientData, hints: transientDataHints } = buildTransientDataHints(
721
+ scopedNoteHashesCLA,
722
+ scopedNullifiersCLA,
723
+ /*futureNoteHashReads=*/ [],
724
+ /*futureNullifierReads=*/ [],
725
+ /*futureLogs=*/ [],
726
+ noteHashNullifierCounterMap,
727
+ minRevertibleSideEffectCounter,
728
+ );
729
+
730
+ const squashedNoteHashCounters = new Set<number>();
731
+ const squashedNullifierCounters = new Set<number>();
732
+ for (let i = 0; i < numTransientData; i++) {
733
+ const hint = transientDataHints[i];
734
+ squashedNoteHashCounters.add(scopedNoteHashesCLA.array[hint.noteHashIndex].counter);
735
+ squashedNullifierCounters.add(scopedNullifiersCLA.array[hint.nullifierIndex].counter);
736
+ }
737
+
738
+ return {
739
+ filteredNoteHashes: scopedNoteHashesCLA.getActiveItems().filter(nh => !squashedNoteHashCounters.has(nh.counter)),
740
+ filteredNullifiers: scopedNullifiersCLA.getActiveItems().filter(n => !squashedNullifierCounters.has(n.counter)),
741
+ filteredPrivateLogs: taggedPrivateLogs
742
+ .filter(item => !squashedNoteHashCounters.has(item.sideEffect.noteHashCounter))
743
+ .map(item => new OrderedSideEffect(item.sideEffect.log, item.counter)),
744
+ };
745
+ }
746
+
747
+ /**
748
+ * Verifies settled read requests by checking membership in the note hash and nullifier trees
749
+ * at the tx's anchor block, mimicking the behavior of the kernels
750
+ */
751
+ async function verifyReadRequests(
752
+ node: Pick<AztecNode, 'getNoteHashMembershipWitness' | 'getNullifierMembershipWitness'>,
753
+ anchorBlockHash: BlockParameter,
754
+ noteHashReadRequests: ScopedReadRequest[],
755
+ nullifierReadRequests: ScopedReadRequest[],
756
+ scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
757
+ scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
758
+ ) {
759
+ const noteHashReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>(
760
+ padArrayEnd(noteHashReadRequests, ScopedReadRequest.empty(), MAX_NOTE_HASH_READ_REQUESTS_PER_TX),
761
+ noteHashReadRequests.length,
762
+ );
763
+ const nullifierReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>(
764
+ padArrayEnd(nullifierReadRequests, ScopedReadRequest.empty(), MAX_NULLIFIER_READ_REQUESTS_PER_TX),
765
+ nullifierReadRequests.length,
766
+ );
767
+
768
+ const noteHashResetActions = getNoteHashReadRequestResetActions(noteHashReadRequestsCLA, scopedNoteHashesCLA);
769
+ const nullifierResetActions = getNullifierReadRequestResetActions(nullifierReadRequestsCLA, scopedNullifiersCLA);
770
+
771
+ const settledNoteHashReads: { index: number; value: Fr }[] = [];
772
+ for (let i = 0; i < noteHashResetActions.actions.length; i++) {
773
+ if (noteHashResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
774
+ settledNoteHashReads.push({ index: i, value: noteHashReadRequests[i].value });
775
+ }
776
+ }
777
+
778
+ const settledNullifierReads: { index: number; value: Fr }[] = [];
779
+ for (let i = 0; i < nullifierResetActions.actions.length; i++) {
780
+ if (nullifierResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
781
+ settledNullifierReads.push({ index: i, value: nullifierReadRequests[i].value });
782
+ }
783
+ }
784
+
785
+ const [noteHashWitnesses, nullifierWitnesses] = await Promise.all([
786
+ Promise.all(settledNoteHashReads.map(({ value }) => node.getNoteHashMembershipWitness(anchorBlockHash, value))),
787
+ Promise.all(settledNullifierReads.map(({ value }) => node.getNullifierMembershipWitness(anchorBlockHash, value))),
788
+ ]);
789
+
790
+ for (let i = 0; i < settledNoteHashReads.length; i++) {
791
+ if (!noteHashWitnesses[i]) {
792
+ throw new Error(
793
+ `Note hash read request at index ${settledNoteHashReads[i].index} is reading an unknown note hash: ${settledNoteHashReads[i].value}`,
794
+ );
795
+ }
796
+ }
797
+
798
+ for (let i = 0; i < settledNullifierReads.length; i++) {
799
+ if (!nullifierWitnesses[i]) {
800
+ throw new Error(
801
+ `Nullifier read request at index ${settledNullifierReads[i].index} is reading an unknown nullifier: ${settledNullifierReads[i].value}`,
802
+ );
803
+ }
804
+ }
805
+ }
806
+
585
807
  function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertibleSideEffectCounter: number) {
586
808
  const revertibleSideEffects: T[] = [];
587
809
  const nonRevertibleSideEffects: T[] = [];
@@ -595,21 +817,24 @@ function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertib
595
817
  return [nonRevertibleSideEffects, revertibleSideEffects];
596
818
  }
597
819
 
598
- function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData) {
820
+ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData, isPrivateOnlyTx: boolean) {
599
821
  let meteredDAFields = 0;
600
822
  let meteredL2Gas = 0;
601
823
 
602
824
  const numNoteHashes = arrayNonEmptyLength(data.noteHashes, hash => hash.isEmpty());
603
825
  meteredDAFields += numNoteHashes;
604
- meteredL2Gas += numNoteHashes * AVM_EMITNOTEHASH_BASE_L2_GAS;
826
+ const noteHashBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NOTE_HASH : AVM_EMITNOTEHASH_BASE_L2_GAS;
827
+ meteredL2Gas += numNoteHashes * noteHashBaseGas;
605
828
 
606
829
  const numNullifiers = arrayNonEmptyLength(data.nullifiers, nullifier => nullifier.isEmpty());
607
830
  meteredDAFields += numNullifiers;
608
- meteredL2Gas += numNullifiers * AVM_EMITNULLIFIER_BASE_L2_GAS;
831
+ const nullifierBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NULLIFIER : AVM_EMITNULLIFIER_BASE_L2_GAS;
832
+ meteredL2Gas += numNullifiers * nullifierBaseGas;
609
833
 
610
834
  const numL2toL1Messages = arrayNonEmptyLength(data.l2ToL1Msgs, msg => msg.isEmpty());
611
835
  meteredDAFields += numL2toL1Messages;
612
- meteredL2Gas += numL2toL1Messages * AVM_SENDL2TOL1MSG_BASE_L2_GAS;
836
+ const l2ToL1MessageBaseGas = isPrivateOnlyTx ? L2_GAS_PER_L2_TO_L1_MSG : AVM_SENDL2TOL1MSG_BASE_L2_GAS;
837
+ meteredL2Gas += numL2toL1Messages * l2ToL1MessageBaseGas;
613
838
 
614
839
  const numPrivatelogs = arrayNonEmptyLength(data.privateLogs, log => log.isEmpty());
615
840
  // Every private log emits its length as an additional field
@@ -617,14 +842,14 @@ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccu
617
842
  meteredL2Gas += numPrivatelogs * L2_GAS_PER_PRIVATE_LOG;
618
843
 
619
844
  const numContractClassLogs = arrayNonEmptyLength(data.contractClassLogsHashes, log => log.isEmpty());
620
- // Every contract class log emits its length and contract address as additional fields
845
+ // Every contract class log emits its contract address as an additional field
621
846
  meteredDAFields += data.contractClassLogsHashes.reduce(
622
- (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 2 : acc),
847
+ (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 1 : acc),
623
848
  0,
624
849
  );
625
850
  meteredL2Gas += numContractClassLogs * L2_GAS_PER_CONTRACT_CLASS_LOG;
626
851
 
627
- const meteredDAGas = meteredDAFields * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE;
852
+ const meteredDAGas = meteredDAFields * DA_GAS_PER_FIELD;
628
853
 
629
854
  if ((data as PrivateToPublicAccumulatedData).publicCallRequests) {
630
855
  const dataForPublic = data as PrivateToPublicAccumulatedData;