@aztec/pxe 0.0.1-commit.f146247c → 0.0.1-commit.f1b29a41e

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 (212) 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 +4 -2
  5. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  6. package/dest/block_synchronizer/block_synchronizer.js +13 -1
  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 +61 -29
  12. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/contract_function_simulator.js +201 -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 +206 -104
  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 -78
  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 +99 -86
  41. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +93 -53
  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 +233 -119
  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 +46 -0
  48. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -0
  49. package/dest/contract_sync/contract_sync_service.js +124 -0
  50. package/dest/contract_sync/helpers.d.ts +29 -0
  51. package/dest/contract_sync/helpers.d.ts.map +1 -0
  52. package/dest/contract_sync/{index.js → helpers.js} +19 -13
  53. package/dest/debug/pxe_debug_utils.d.ts +14 -10
  54. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  55. package/dest/debug/pxe_debug_utils.js +16 -15
  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 +4 -2
  69. package/dest/entrypoints/server/index.d.ts.map +1 -1
  70. package/dest/entrypoints/server/index.js +3 -1
  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 +32 -43
  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 +74 -24
  107. package/dest/pxe.d.ts.map +1 -1
  108. package/dest/pxe.js +126 -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 +145 -69
  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 +6 -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 +25 -16
  154. package/src/access_scopes.ts +9 -0
  155. package/src/block_synchronizer/block_synchronizer.ts +12 -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 +361 -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 +233 -142
  167. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  168. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +125 -179
  169. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +399 -136
  170. package/src/contract_logging.ts +52 -0
  171. package/src/contract_sync/contract_sync_service.ts +192 -0
  172. package/src/contract_sync/{index.ts → helpers.ts} +23 -22
  173. package/src/debug/pxe_debug_utils.ts +48 -18
  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 +3 -1
  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 +63 -65
  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 +231 -124
  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 +174 -75
  197. package/src/storage/metadata.ts +1 -1
  198. package/src/storage/note_store/note_store.ts +12 -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/contract_sync/index.d.ts +0 -23
  210. package/dest/contract_sync/index.d.ts.map +0 -1
  211. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
  212. 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,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';
93
+ import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
94
+ import type { MessageContextService } from '../messages/message_context_service.js';
75
95
  import type { AddressStore } from '../storage/address_store/address_store.js';
96
+ import { CapsuleService } from '../storage/capsule_store/capsule_service.js';
76
97
  import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
77
98
  import type { ContractStore } from '../storage/contract_store/contract_store.js';
78
99
  import type { NoteStore } from '../storage/note_store/note_store.js';
@@ -89,51 +110,92 @@ import { executePrivateFunction } from './oracle/private_execution.js';
89
110
  import { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
90
111
  import { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
91
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
+
92
148
  /**
93
149
  * The contract function simulator.
94
150
  */
95
151
  export class ContractFunctionSimulator {
96
- private log: Logger;
97
-
98
- constructor(
99
- private contractStore: ContractStore,
100
- private noteStore: NoteStore,
101
- private keyStore: KeyStore,
102
- private addressStore: AddressStore,
103
- private aztecNode: AztecNode,
104
- private senderTaggingStore: SenderTaggingStore,
105
- private recipientTaggingStore: RecipientTaggingStore,
106
- private senderAddressBookStore: SenderAddressBookStore,
107
- private capsuleStore: CapsuleStore,
108
- private privateEventStore: PrivateEventStore,
109
- private simulator: CircuitSimulator,
110
- ) {
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;
111
181
  this.log = createLogger('simulator');
112
182
  }
113
183
 
114
184
  /**
115
185
  * Runs a private function.
116
186
  * @param request - The transaction request.
117
- * @param entryPointArtifact - The artifact of the entry point function.
118
- * @param contractAddress - The address of the contract (should match request.origin)
119
- * @param msgSender - The address calling the function. This can be replaced to simulate a call from another contract
120
- * or a specific account.
121
- * @param anchorBlockHeader - The block header to use as base state for this run.
122
- * @param senderForTags - The address that is used as a tagging sender when emitting private logs. Returned from
123
- * the `privateGetSenderForTags` oracle.
124
- * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
125
- * @param jobId - The job ID for staged writes.
126
- * @returns The result of the execution.
127
187
  */
128
188
  public async run(
129
189
  request: TxExecutionRequest,
130
- contractAddress: AztecAddress,
131
- selector: FunctionSelector,
132
- msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
133
- anchorBlockHeader: BlockHeader,
134
- senderForTags: AztecAddress | undefined,
135
- scopes: AztecAddress[] | undefined,
136
- 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,
137
199
  ): Promise<PrivateExecutionResult> {
138
200
  const simulatorSetupTimer = new Timer();
139
201
 
@@ -163,37 +225,38 @@ export class ContractFunctionSimulator {
163
225
  const noteCache = new ExecutionNoteCache(protocolNullifier);
164
226
  const taggingIndexCache = new ExecutionTaggingIndexCache();
165
227
 
166
- const privateExecutionOracle = new PrivateExecutionOracle(
167
- request.firstCallArgsHash,
168
- request.txContext,
228
+ const privateExecutionOracle = new PrivateExecutionOracle({
229
+ argsHash: request.firstCallArgsHash,
230
+ txContext: request.txContext,
169
231
  callContext,
170
232
  anchorBlockHeader,
171
- async call => {
172
- await this.runUtility(call, [], anchorBlockHeader, scopes, jobId);
233
+ utilityExecutor: async (call, execScopes) => {
234
+ await this.runUtility(call, [], anchorBlockHeader, execScopes, jobId);
173
235
  },
174
- request.authWitnesses,
175
- request.capsules,
176
- HashedValuesCache.create(request.argsOfCalls),
236
+ authWitnesses: request.authWitnesses,
237
+ capsules: request.capsules,
238
+ executionCache: HashedValuesCache.create(request.argsOfCalls),
177
239
  noteCache,
178
240
  taggingIndexCache,
179
- this.contractStore,
180
- this.noteStore,
181
- this.keyStore,
182
- this.addressStore,
183
- this.aztecNode,
184
- this.senderTaggingStore,
185
- this.recipientTaggingStore,
186
- this.senderAddressBookStore,
187
- this.capsuleStore,
188
- this.privateEventStore,
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,
189
253
  jobId,
190
- 0, // totalPublicArgsCount
191
- startSideEffectCounter,
192
- undefined, // log
254
+ totalPublicCalldataCount: 0,
255
+ sideEffectCounter: startSideEffectCounter,
193
256
  scopes,
194
257
  senderForTags,
195
- this.simulator,
196
- );
258
+ simulator: this.simulator,
259
+ });
197
260
 
198
261
  const setupTime = simulatorSetupTimer.ms();
199
262
 
@@ -222,7 +285,7 @@ export class ContractFunctionSimulator {
222
285
  );
223
286
  const publicFunctionsCalldata = await Promise.all(
224
287
  publicCallRequests.map(async r => {
225
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
288
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
226
289
  return new HashedValues(calldata, r.calldataHash);
227
290
  }),
228
291
  );
@@ -257,33 +320,34 @@ export class ContractFunctionSimulator {
257
320
  call: FunctionCall,
258
321
  authwits: AuthWitness[],
259
322
  anchorBlockHeader: BlockHeader,
260
- scopes: AztecAddress[] | undefined,
323
+ scopes: AccessScopes,
261
324
  jobId: string,
262
- ): Promise<Fr[]> {
325
+ ): Promise<{ result: Fr[]; offchainEffects: OffchainEffect[] }> {
263
326
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
264
327
 
265
328
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
266
329
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
267
330
  }
268
331
 
269
- const oracle = new UtilityExecutionOracle(
270
- call.to,
271
- authwits,
272
- [],
332
+ const oracle = new UtilityExecutionOracle({
333
+ contractAddress: call.to,
334
+ authWitnesses: authwits,
335
+ capsules: [],
273
336
  anchorBlockHeader,
274
- this.contractStore,
275
- this.noteStore,
276
- this.keyStore,
277
- this.addressStore,
278
- this.aztecNode,
279
- this.recipientTaggingStore,
280
- this.senderAddressBookStore,
281
- this.capsuleStore,
282
- 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,
283
348
  jobId,
284
- undefined,
285
349
  scopes,
286
- );
350
+ });
287
351
 
288
352
  try {
289
353
  this.log.verbose(`Executing utility function ${entryPointArtifact.name}`, {
@@ -307,8 +371,11 @@ export class ContractFunctionSimulator {
307
371
  );
308
372
  });
309
373
 
310
- this.log.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
311
- 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
+ };
312
379
  } catch (err) {
313
380
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
314
381
  }
@@ -349,66 +416,82 @@ class OrderedSideEffect<T> {
349
416
  * (allowing state overrides) and is much faster, while still generating a valid
350
417
  * output that can be sent to the node for public simulation
351
418
  * @param privateExecutionResult - The result of the private execution.
352
- * @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.
353
421
  * @param minRevertibleSideEffectCounterOverride - Optional override for the min revertible side effect counter.
354
422
  * Used by TXE to simulate account contract behavior (setting the counter before app execution).
355
423
  * @returns The simulated proving result.
356
424
  */
357
425
  export async function generateSimulatedProvingResult(
358
426
  privateExecutionResult: PrivateExecutionResult,
359
- contractStore: ContractStore,
427
+ debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
428
+ node: AztecNode,
360
429
  minRevertibleSideEffectCounterOverride?: number,
361
430
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
362
- const siloedNoteHashes: OrderedSideEffect<Fr>[] = [];
363
- const nullifiers: OrderedSideEffect<Fr>[] = [];
364
- const taggedPrivateLogs: OrderedSideEffect<PrivateLog>[] = [];
431
+ const taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[] = [];
365
432
  const l2ToL1Messages: OrderedSideEffect<ScopedL2ToL1Message>[] = [];
366
433
  const contractClassLogsHashes: OrderedSideEffect<ScopedLogHash>[] = [];
367
434
  const publicCallRequests: OrderedSideEffect<PublicCallRequest>[] = [];
368
435
  const executionSteps: PrivateExecutionStep[] = [];
369
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
+
370
446
  let publicTeardownCallRequest;
371
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
+
372
455
  const executions = [privateExecutionResult.entrypoint];
373
456
 
374
457
  while (executions.length !== 0) {
375
458
  const execution = executions.shift()!;
376
459
  executions.unshift(...execution!.nestedExecutionResults);
377
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
+
378
467
  const { contractAddress } = execution.publicInputs.callContext;
379
468
 
380
- const noteHashesFromExecution = await Promise.all(
381
- execution.publicInputs.noteHashes
382
- .getActiveItems()
383
- .filter(noteHash => !noteHash.isEmpty())
384
- .map(
385
- async noteHash =>
386
- new OrderedSideEffect(await siloNoteHash(contractAddress, noteHash.value), noteHash.counter),
387
- ),
388
- );
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
+ }
389
475
 
390
- const nullifiersFromExecution = await Promise.all(
391
- execution.publicInputs.nullifiers
476
+ scopedNoteHashes.push(
477
+ ...execution.publicInputs.noteHashes
392
478
  .getActiveItems()
393
- .map(
394
- async nullifier =>
395
- new OrderedSideEffect(await siloNullifier(contractAddress, nullifier.value), nullifier.counter),
396
- ),
479
+ .filter(nh => !nh.isEmpty())
480
+ .map(nh => nh.scope(contractAddress)),
397
481
  );
482
+ scopedNullifiers.push(...execution.publicInputs.nullifiers.getActiveItems().map(n => n.scope(contractAddress)));
398
483
 
399
- const privateLogsFromExecution = await Promise.all(
400
- execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
401
- metadata.log.fields[0] = await poseidon2HashWithSeparator(
402
- [contractAddress, metadata.log.fields[0]],
403
- GeneratorIndex.PRIVATE_LOG_FIRST_FIELD,
404
- );
405
- return new OrderedSideEffect(metadata.log, metadata.counter);
406
- }),
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
+ )),
407
491
  );
408
492
 
409
- siloedNoteHashes.push(...noteHashesFromExecution);
410
- taggedPrivateLogs.push(...privateLogsFromExecution);
411
- nullifiers.push(...nullifiersFromExecution);
493
+ noteHashReadRequests.push(...execution.publicInputs.noteHashReadRequests.getActiveItems());
494
+ nullifierReadRequests.push(...execution.publicInputs.nullifierReadRequests.getActiveItems());
412
495
  l2ToL1Messages.push(
413
496
  ...execution.publicInputs.l2ToL1Msgs
414
497
  .getActiveItems()
@@ -437,7 +520,7 @@ export async function generateSimulatedProvingResult(
437
520
  : execution.publicInputs.publicTeardownCallRequest;
438
521
 
439
522
  executionSteps.push({
440
- functionName: await contractStore.getDebugFunctionName(
523
+ functionName: await debugFunctionNameGetter(
441
524
  execution.publicInputs.callContext.contractAddress,
442
525
  execution.publicInputs.callContext.functionSelector,
443
526
  ),
@@ -448,6 +531,47 @@ export async function generateSimulatedProvingResult(
448
531
  });
449
532
  }
450
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
+
451
575
  const constantData = new TxConstantData(
452
576
  privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader,
453
577
  privateExecutionResult.entrypoint.publicInputs.txContext,
@@ -464,11 +588,9 @@ export async function generateSimulatedProvingResult(
464
588
  const getEffect = <T>(orderedSideEffect: OrderedSideEffect<T>) => orderedSideEffect.sideEffect;
465
589
 
466
590
  const isPrivateOnlyTx = privateExecutionResult.publicFunctionCalldata.length === 0;
467
- const minRevertibleSideEffectCounter =
468
- minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
469
591
 
470
592
  const [nonRevertibleNullifiers, revertibleNullifiers] = splitOrderedSideEffects(
471
- nullifiers.sort(sortByCounter),
593
+ siloedNullifiers,
472
594
  minRevertibleSideEffectCounter,
473
595
  );
474
596
  const nonceGenerator = privateExecutionResult.firstNullifier;
@@ -482,7 +604,7 @@ export async function generateSimulatedProvingResult(
482
604
  // We must make the note hashes unique by using the
483
605
  // nonce generator and their index in the tx.
484
606
  const uniqueNoteHashes = await Promise.all(
485
- siloedNoteHashes.sort(sortByCounter).map(async (orderedSideEffect, i) => {
607
+ siloedNoteHashes.map(async (orderedSideEffect, i) => {
486
608
  const siloedNoteHash = orderedSideEffect.sideEffect;
487
609
  const nonce = await computeNoteHashNonce(nonceGenerator, i);
488
610
  const uniqueNoteHash = await computeUniqueNoteHash(nonce, siloedNoteHash);
@@ -497,18 +619,18 @@ export async function generateSimulatedProvingResult(
497
619
  ScopedL2ToL1Message.empty(),
498
620
  MAX_L2_TO_L1_MSGS_PER_TX,
499
621
  ),
500
- 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),
501
623
  padArrayEnd(
502
624
  contractClassLogsHashes.sort(sortByCounter).map(getEffect),
503
625
  ScopedLogHash.empty(),
504
626
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
505
627
  ),
506
628
  );
507
- gasUsed = meterGasUsed(accumulatedDataForRollup);
629
+ gasUsed = meterGasUsed(accumulatedDataForRollup, isPrivateOnlyTx);
508
630
  inputsForRollup = new PartialPrivateTailPublicInputsForRollup(accumulatedDataForRollup);
509
631
  } else {
510
632
  const [nonRevertibleNoteHashes, revertibleNoteHashes] = splitOrderedSideEffects(
511
- siloedNoteHashes.sort(sortByCounter),
633
+ siloedNoteHashes,
512
634
  minRevertibleSideEffectCounter,
513
635
  );
514
636
  const nonRevertibleUniqueNoteHashes = await Promise.all(
@@ -522,7 +644,7 @@ export async function generateSimulatedProvingResult(
522
644
  minRevertibleSideEffectCounter,
523
645
  );
524
646
  const [nonRevertibleTaggedPrivateLogs, revertibleTaggedPrivateLogs] = splitOrderedSideEffects(
525
- taggedPrivateLogs,
647
+ filteredPrivateLogs,
526
648
  minRevertibleSideEffectCounter,
527
649
  );
528
650
  const [nonRevertibleContractClassLogHashes, revertibleContractClassLogHashes] = splitOrderedSideEffects(
@@ -551,9 +673,9 @@ export async function generateSimulatedProvingResult(
551
673
  padArrayEnd(revertibleContractClassLogHashes, ScopedLogHash.empty(), MAX_CONTRACT_CLASS_LOGS_PER_TX),
552
674
  padArrayEnd(revertiblePublicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
553
675
  );
554
- gasUsed = meterGasUsed(revertibleData).add(meterGasUsed(nonRevertibleData));
676
+ gasUsed = meterGasUsed(revertibleData, isPrivateOnlyTx).add(meterGasUsed(nonRevertibleData, isPrivateOnlyTx));
555
677
  if (publicTeardownCallRequest) {
556
- gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
678
+ gasUsed = gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
557
679
  }
558
680
 
559
681
  inputsForPublic = new PartialPrivateTailPublicInputsForPublic(
@@ -565,9 +687,14 @@ export async function generateSimulatedProvingResult(
565
687
 
566
688
  const publicInputs = new PrivateKernelTailCircuitPublicInputs(
567
689
  constantData,
568
- /*gasUsed=*/ gasUsed.add(Gas.from({ l2Gas: FIXED_L2_GAS, daGas: FIXED_DA_GAS })),
569
- /*feePayer=*/ AztecAddress.zero(),
570
- /*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,
571
698
  hasPublicCalls ? inputsForPublic : undefined,
572
699
  !hasPublicCalls ? inputsForRollup : undefined,
573
700
  );
@@ -579,6 +706,104 @@ export async function generateSimulatedProvingResult(
579
706
  };
580
707
  }
581
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
+
582
807
  function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertibleSideEffectCounter: number) {
583
808
  const revertibleSideEffects: T[] = [];
584
809
  const nonRevertibleSideEffects: T[] = [];
@@ -592,21 +817,24 @@ function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertib
592
817
  return [nonRevertibleSideEffects, revertibleSideEffects];
593
818
  }
594
819
 
595
- function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData) {
820
+ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData, isPrivateOnlyTx: boolean) {
596
821
  let meteredDAFields = 0;
597
822
  let meteredL2Gas = 0;
598
823
 
599
824
  const numNoteHashes = arrayNonEmptyLength(data.noteHashes, hash => hash.isEmpty());
600
825
  meteredDAFields += numNoteHashes;
601
- 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;
602
828
 
603
829
  const numNullifiers = arrayNonEmptyLength(data.nullifiers, nullifier => nullifier.isEmpty());
604
830
  meteredDAFields += numNullifiers;
605
- meteredL2Gas += numNullifiers * AVM_EMITNULLIFIER_BASE_L2_GAS;
831
+ const nullifierBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NULLIFIER : AVM_EMITNULLIFIER_BASE_L2_GAS;
832
+ meteredL2Gas += numNullifiers * nullifierBaseGas;
606
833
 
607
834
  const numL2toL1Messages = arrayNonEmptyLength(data.l2ToL1Msgs, msg => msg.isEmpty());
608
835
  meteredDAFields += numL2toL1Messages;
609
- 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;
610
838
 
611
839
  const numPrivatelogs = arrayNonEmptyLength(data.privateLogs, log => log.isEmpty());
612
840
  // Every private log emits its length as an additional field
@@ -614,14 +842,14 @@ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccu
614
842
  meteredL2Gas += numPrivatelogs * L2_GAS_PER_PRIVATE_LOG;
615
843
 
616
844
  const numContractClassLogs = arrayNonEmptyLength(data.contractClassLogsHashes, log => log.isEmpty());
617
- // 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
618
846
  meteredDAFields += data.contractClassLogsHashes.reduce(
619
- (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 2 : acc),
847
+ (acc, log) => (!log.isEmpty() ? acc + log.logHash.length + 1 : acc),
620
848
  0,
621
849
  );
622
850
  meteredL2Gas += numContractClassLogs * L2_GAS_PER_CONTRACT_CLASS_LOG;
623
851
 
624
- const meteredDAGas = meteredDAFields * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE;
852
+ const meteredDAGas = meteredDAFields * DA_GAS_PER_FIELD;
625
853
 
626
854
  if ((data as PrivateToPublicAccumulatedData).publicCallRequests) {
627
855
  const dataForPublic = data as PrivateToPublicAccumulatedData;