@aztec/txe 0.0.1-commit.2ed92850 → 0.0.1-commit.2f68f620

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 (158) hide show
  1. package/dest/ContractClassRegistry-PII7Q556.js +3 -0
  2. package/dest/ContractClassRegistry-PII7Q556.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +3 -0
  4. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +7 -0
  5. package/dest/FeeJuice-TQV5AQK7.js +3 -0
  6. package/dest/FeeJuice-TQV5AQK7.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-SBJUIJY7.js +3 -0
  8. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +7 -0
  9. package/dest/SchnorrAccount-MQXPIZ44.js +3 -0
  10. package/dest/SchnorrAccount-MQXPIZ44.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +61 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/bin/oracle_test_server.d.ts +3 -0
  17. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  18. package/dest/bin/oracle_test_server.js +41 -0
  19. package/dest/chunk-BJVAAXNA.js +3 -0
  20. package/dest/chunk-BJVAAXNA.js.map +7 -0
  21. package/dest/chunk-CDITIZHX.js +257 -0
  22. package/dest/chunk-CDITIZHX.js.map +7 -0
  23. package/dest/chunk-W2NSX64C.js +304 -0
  24. package/dest/chunk-W2NSX64C.js.map +7 -0
  25. package/dest/constants.d.ts +5 -1
  26. package/dest/constants.d.ts.map +1 -1
  27. package/dest/constants.js +8 -0
  28. package/dest/dispatcher_pool.d.ts +67 -0
  29. package/dest/dispatcher_pool.d.ts.map +1 -0
  30. package/dest/dispatcher_pool.js +284 -0
  31. package/dest/index.d.ts +185 -7
  32. package/dest/index.d.ts.map +1 -1
  33. package/dest/index.js +71 -157
  34. package/dest/metafile.json +36545 -0
  35. package/dest/msgpackr_fr_extension.d.ts +2 -0
  36. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  37. package/dest/msgpackr_fr_extension.js +21 -0
  38. package/dest/oracle/interfaces.d.ts +56 -30
  39. package/dest/oracle/interfaces.d.ts.map +1 -1
  40. package/dest/oracle/test-resolver/fixtures.d.ts +43 -0
  41. package/dest/oracle/test-resolver/fixtures.d.ts.map +1 -0
  42. package/dest/oracle/test-resolver/fixtures.js +39 -0
  43. package/dest/oracle/test-resolver/index.d.ts +9 -0
  44. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  45. package/dest/oracle/test-resolver/index.js +33 -0
  46. package/dest/oracle/test-resolver/resolver.d.ts +34 -0
  47. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  48. package/dest/oracle/test-resolver/resolver.js +114 -0
  49. package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
  50. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  51. package/dest/oracle/txe_oracle_public_context.js +57 -16
  52. package/dest/oracle/txe_oracle_registry.d.ts +147 -0
  53. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  54. package/dest/oracle/txe_oracle_registry.js +562 -0
  55. package/dest/oracle/txe_oracle_top_level_context.d.ts +45 -26
  56. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_top_level_context.js +251 -86
  58. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  59. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  60. package/dest/oracle/txe_oracle_version.js +14 -0
  61. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  62. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  63. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  64. package/dest/rpc_server.d.ts +14 -0
  65. package/dest/rpc_server.d.ts.map +1 -0
  66. package/dest/rpc_server.js +78 -0
  67. package/dest/rpc_translator.d.ts +96 -228
  68. package/dest/rpc_translator.d.ts.map +1 -1
  69. package/dest/rpc_translator.js +815 -613
  70. package/dest/server.bundle.js +3 -0
  71. package/dest/server.bundle.js.map +7 -0
  72. package/dest/state_machine/archiver.d.ts +6 -5
  73. package/dest/state_machine/archiver.d.ts.map +1 -1
  74. package/dest/state_machine/archiver.js +32 -21
  75. package/dest/state_machine/dummy_p2p_client.d.ts +26 -16
  76. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  77. package/dest/state_machine/dummy_p2p_client.js +44 -20
  78. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  79. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  80. package/dest/state_machine/global_variable_builder.js +9 -3
  81. package/dest/state_machine/index.d.ts +10 -6
  82. package/dest/state_machine/index.d.ts.map +1 -1
  83. package/dest/state_machine/index.js +35 -12
  84. package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
  85. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  86. package/dest/state_machine/mock_epoch_cache.js +33 -2
  87. package/dest/state_machine/synchronizer.d.ts +5 -5
  88. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  89. package/dest/state_machine/synchronizer.js +4 -4
  90. package/dest/txe_session.d.ts +80 -15
  91. package/dest/txe_session.d.ts.map +1 -1
  92. package/dest/txe_session.js +241 -44
  93. package/dest/utils/block_creation.d.ts +1 -1
  94. package/dest/utils/block_creation.d.ts.map +1 -1
  95. package/dest/utils/block_creation.js +3 -1
  96. package/dest/utils/encoding.d.ts +191 -0
  97. package/dest/utils/encoding.d.ts.map +1 -0
  98. package/dest/{util → utils}/encoding.js +7 -2
  99. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  100. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  101. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  102. package/dest/utils/txe_account_store.d.ts.map +1 -0
  103. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  104. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  105. package/dest/utils/txe_artifact_resolver.js +161 -0
  106. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  107. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  108. package/dest/{util → utils}/txe_public_contract_data_source.js +6 -25
  109. package/dest/worker.bundle.js +3 -0
  110. package/dest/worker.bundle.js.map +7 -0
  111. package/dest/worker.d.ts +2 -0
  112. package/dest/worker.d.ts.map +1 -0
  113. package/dest/worker.js +92 -0
  114. package/package.json +38 -21
  115. package/src/bin/check_txe_oracle_version.ts +70 -0
  116. package/src/bin/index.ts +11 -2
  117. package/src/bin/oracle_test_server.ts +51 -0
  118. package/src/constants.ts +10 -0
  119. package/src/dispatcher_pool.ts +316 -0
  120. package/src/index.ts +97 -190
  121. package/src/msgpackr_fr_extension.ts +23 -0
  122. package/src/oracle/interfaces.ts +58 -35
  123. package/src/oracle/test-resolver/fixtures.ts +84 -0
  124. package/src/oracle/test-resolver/index.ts +45 -0
  125. package/src/oracle/test-resolver/resolver.ts +165 -0
  126. package/src/oracle/txe_oracle_public_context.ts +74 -16
  127. package/src/oracle/txe_oracle_registry.ts +401 -0
  128. package/src/oracle/txe_oracle_top_level_context.ts +317 -147
  129. package/src/oracle/txe_oracle_version.ts +17 -0
  130. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  131. package/src/rpc_server.ts +87 -0
  132. package/src/rpc_translator.ts +1000 -988
  133. package/src/state_machine/archiver.ts +44 -20
  134. package/src/state_machine/dummy_p2p_client.ts +70 -32
  135. package/src/state_machine/global_variable_builder.ts +18 -3
  136. package/src/state_machine/index.ts +48 -13
  137. package/src/state_machine/mock_epoch_cache.ts +43 -3
  138. package/src/state_machine/synchronizer.ts +5 -5
  139. package/src/txe_session.ts +363 -109
  140. package/src/utils/block_creation.ts +3 -1
  141. package/src/{util → utils}/encoding.ts +8 -2
  142. package/src/utils/txe_artifact_resolver.ts +217 -0
  143. package/src/{util → utils}/txe_public_contract_data_source.ts +10 -38
  144. package/src/worker.ts +98 -0
  145. package/dest/util/encoding.d.ts +0 -720
  146. package/dest/util/encoding.d.ts.map +0 -1
  147. package/dest/util/expected_failure_error.d.ts.map +0 -1
  148. package/dest/util/txe_account_store.d.ts.map +0 -1
  149. package/dest/util/txe_contract_store.d.ts +0 -12
  150. package/dest/util/txe_contract_store.d.ts.map +0 -1
  151. package/dest/util/txe_contract_store.js +0 -22
  152. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  153. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  154. package/src/util/txe_contract_store.ts +0 -36
  155. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  156. /package/dest/{util → utils}/txe_account_store.js +0 -0
  157. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  158. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,9 +1,6 @@
1
1
  import {
2
2
  CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
3
- DEFAULT_DA_GAS_LIMIT,
4
- DEFAULT_L2_GAS_LIMIT,
5
- DEFAULT_TEARDOWN_DA_GAS_LIMIT,
6
- DEFAULT_TEARDOWN_L2_GAS_LIMIT,
3
+ MAX_PRIVATE_LOGS_PER_TX,
7
4
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
8
5
  } from '@aztec/constants';
9
6
  import { BlockNumber } from '@aztec/foundation/branded-types';
@@ -14,15 +11,18 @@ import { TestDateProvider } from '@aztec/foundation/timer';
14
11
  import type { KeyStore } from '@aztec/key-store';
15
12
  import {
16
13
  AddressStore,
14
+ CapsuleService,
17
15
  CapsuleStore,
16
+ type ContractStore,
17
+ type ExecutionHooks,
18
18
  NoteStore,
19
- ORACLE_VERSION,
19
+ ORACLE_VERSION_MAJOR,
20
20
  PrivateEventStore,
21
21
  RecipientTaggingStore,
22
22
  SenderAddressBookStore,
23
23
  SenderTaggingStore,
24
+ composeHooks,
24
25
  enrichPublicSimulationError,
25
- syncState,
26
26
  } from '@aztec/pxe/server';
27
27
  import {
28
28
  ExecutionNoteCache,
@@ -45,10 +45,10 @@ import {
45
45
  witnessMapToFields,
46
46
  } from '@aztec/simulator/client';
47
47
  import {
48
- CppPublicTxSimulator,
49
48
  GuardedMerkleTreeOperations,
50
49
  PublicContractsDB,
51
50
  PublicProcessor,
51
+ PublicTxSimulator,
52
52
  } from '@aztec/simulator/server';
53
53
  import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
54
54
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
@@ -63,6 +63,7 @@ import {
63
63
  PrivateToPublicAccumulatedData,
64
64
  PublicCallRequest,
65
65
  } from '@aztec/stdlib/kernel';
66
+ import { hashPublicKey } from '@aztec/stdlib/keys';
66
67
  import { ChonkProof } from '@aztec/stdlib/proofs';
67
68
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
68
69
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -79,14 +80,14 @@ import {
79
80
  collectNested,
80
81
  } from '@aztec/stdlib/tx';
81
82
  import type { UInt64 } from '@aztec/stdlib/types';
82
- import { ForkCheckpoint } from '@aztec/world-state';
83
+ import { ForkCheckpoint } from '@aztec/world-state/native';
83
84
 
84
- import { DEFAULT_ADDRESS } from '../constants.js';
85
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
85
86
  import type { TXEStateMachine } from '../state_machine/index.js';
86
- import type { TXEAccountStore } from '../util/txe_account_store.js';
87
- import type { TXEContractStore } from '../util/txe_contract_store.js';
88
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
89
87
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
88
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
89
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
90
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
90
91
  import type { ITxeExecutionOracle } from './interfaces.js';
91
92
 
92
93
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -97,7 +98,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
97
98
 
98
99
  constructor(
99
100
  private stateMachine: TXEStateMachine,
100
- private contractStore: TXEContractStore,
101
+ private contractStore: ContractStore,
101
102
  private noteStore: NoteStore,
102
103
  private keyStore: KeyStore,
103
104
  private addressStore: AddressStore,
@@ -107,59 +108,74 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
107
108
  private senderAddressBookStore: SenderAddressBookStore,
108
109
  private capsuleStore: CapsuleStore,
109
110
  private privateEventStore: PrivateEventStore,
110
- private jobId: string,
111
111
  private nextBlockTimestamp: bigint,
112
112
  private version: Fr,
113
113
  private chainId: Fr,
114
114
  private authwits: Map<string, AuthWitness>,
115
+ private readonly artifactResolver: TXEArtifactResolver,
116
+ private readonly rootPath: string,
117
+ private readonly packageName: string,
115
118
  ) {
116
119
  this.logger = createLogger('txe:top_level_context');
117
120
  this.logger.debug('Entering Top Level Context');
118
121
  }
119
122
 
120
- utilityAssertCompatibleOracleVersion(version: number): void {
121
- if (version !== ORACLE_VERSION) {
123
+ private contractOracleVersion: { major: number; minor: number } | undefined;
124
+
125
+ assertCompatibleOracleVersion(major: number, minor: number): void {
126
+ if (major !== ORACLE_VERSION_MAJOR) {
127
+ const hint =
128
+ major > ORACLE_VERSION_MAJOR
129
+ ? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.'
130
+ : 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
122
131
  throw new Error(
123
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
132
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
124
133
  );
125
134
  }
135
+ this.contractOracleVersion = { major, minor };
136
+ }
137
+
138
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
139
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
140
+ return this.contractOracleVersion;
126
141
  }
127
142
 
128
143
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
129
144
  // setup.
130
- utilityGetRandomField(): Fr {
145
+ getRandomField(): Fr {
131
146
  return Fr.random();
132
147
  }
133
148
 
134
149
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
135
- utilityDebugLog(level: number, message: string, fields: Fr[]): void {
150
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
136
151
  if (!LogLevels[level]) {
137
- throw new Error(`Invalid debug log level: ${level}`);
152
+ throw new Error(`Invalid log level: ${level}`);
138
153
  }
139
154
  const levelName = LogLevels[level];
140
155
 
141
156
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
157
+ return Promise.resolve();
142
158
  }
143
159
 
144
- txeGetDefaultAddress(): AztecAddress {
160
+ getDefaultAddress(): AztecAddress {
145
161
  return DEFAULT_ADDRESS;
146
162
  }
147
163
 
148
- async txeGetNextBlockNumber(): Promise<BlockNumber> {
164
+ async getNextBlockNumber(): Promise<BlockNumber> {
149
165
  return BlockNumber((await this.getLastBlockNumber()) + 1);
150
166
  }
151
167
 
152
- txeGetNextBlockTimestamp(): Promise<bigint> {
168
+ getNextBlockTimestamp(): Promise<bigint> {
153
169
  return Promise.resolve(this.nextBlockTimestamp);
154
170
  }
155
171
 
156
- async txeGetLastBlockTimestamp() {
157
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
172
+ async getLastBlockTimestamp() {
173
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
158
174
  }
159
175
 
160
- async txeGetLastTxEffects() {
176
+ async getLastTxEffects() {
161
177
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
162
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
178
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
163
179
 
164
180
  if (block!.body.txEffects.length != 1) {
165
181
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -168,11 +184,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
168
184
 
169
185
  const txEffects = block!.body.txEffects[0];
170
186
 
171
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
187
+ const privateLogs = txEffects.privateLogs;
188
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
189
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
190
+ }
191
+
192
+ return {
193
+ txHash: txEffects.txHash,
194
+ noteHashes: txEffects.noteHashes,
195
+ nullifiers: txEffects.nullifiers,
196
+ privateLogs,
197
+ };
198
+ }
199
+
200
+ async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
201
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
202
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
203
+ return;
204
+ }
205
+
206
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
207
+ await this.stateMachine.contractSyncService.ensureContractSynced(
208
+ contractAddress,
209
+ null,
210
+ async (call, execScopes) => {
211
+ await this.executeUtilityCall(call, execScopes, jobId);
212
+ },
213
+ blockHeader,
214
+ jobId,
215
+ [scope],
216
+ );
172
217
  }
173
218
 
174
- async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
175
- return (
219
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
220
+ const events = (
176
221
  await this.privateEventStore.getPrivateEvents(selector, {
177
222
  contractAddress,
178
223
  scopes: [scope],
@@ -180,9 +225,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
180
225
  toBlock: (await this.getLastBlockNumber()) + 1,
181
226
  })
182
227
  ).map(e => e.packedEvent);
228
+
229
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
230
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
231
+ }
232
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
233
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
234
+ }
235
+
236
+ return events;
183
237
  }
184
238
 
185
- async txeAdvanceBlocksBy(blocks: number) {
239
+ async advanceBlocksBy(blocks: number) {
186
240
  this.logger.debug(`time traveling ${blocks} blocks`);
187
241
 
188
242
  for (let i = 0; i < blocks; i++) {
@@ -190,37 +244,81 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
190
244
  }
191
245
  }
192
246
 
193
- txeAdvanceTimestampBy(duration: UInt64) {
247
+ advanceTimestampBy(duration: UInt64) {
194
248
  this.logger.debug(`time traveling ${duration} seconds`);
195
249
  this.nextBlockTimestamp += duration;
196
250
  }
197
251
 
198
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
252
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
253
+ return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
254
+ }
255
+
256
+ async deploy(
257
+ contractPath: string,
258
+ initializer: string,
259
+ args: Fr[],
260
+ secret: Fr,
261
+ salt: Fr,
262
+ deployer: AztecAddress,
263
+ ): Promise<Fr[]> {
264
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
265
+ rootPath: this.rootPath,
266
+ packageName: this.packageName,
267
+ contractPath,
268
+ initializer,
269
+ args,
270
+ secret,
271
+ salt,
272
+ deployer,
273
+ });
274
+
199
275
  // Emit deployment nullifier
200
276
  await this.mineBlock({
201
- nullifiers: [
202
- await siloNullifier(
203
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
204
- instance.address.toField(),
205
- ),
206
- ],
277
+ nullifiers: [await this.deploymentNullifier(instance.address)],
207
278
  });
208
279
 
209
280
  if (!secret.equals(Fr.ZERO)) {
210
- await this.txeAddAccount(artifact, instance, secret);
281
+ await this.registerContractAndAddAccount(artifact, instance, secret);
211
282
  } else {
212
283
  await this.contractStore.addContractInstance(instance);
213
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
284
+ await this.contractStore.addContractArtifact(artifact);
214
285
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
215
286
  }
287
+
288
+ return [
289
+ instance.salt,
290
+ instance.deployer.toField(),
291
+ instance.currentContractClassId,
292
+ instance.initializationHash,
293
+ instance.immutablesHash,
294
+ ...instance.publicKeys.toFields(),
295
+ ];
216
296
  }
217
297
 
218
- async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
298
+ /**
299
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
300
+ */
301
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
302
+ await this.mineBlock({
303
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
304
+ });
305
+ }
306
+
307
+ async addAccount(secret: Fr) {
308
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
309
+ return this.registerContractAndAddAccount(artifact, instance, secret);
310
+ }
311
+
312
+ private async registerContractAndAddAccount(
313
+ artifact: ContractArtifact,
314
+ instance: ContractInstanceWithAddress,
315
+ secret: Fr,
316
+ ) {
219
317
  const partialAddress = await computePartialAddress(instance);
220
318
 
221
319
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
222
320
  await this.contractStore.addContractInstance(instance);
223
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
321
+ await this.contractStore.addContractArtifact(artifact);
224
322
 
225
323
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
226
324
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -230,7 +328,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
230
328
  return completeAddress;
231
329
  }
232
330
 
233
- async txeCreateAccount(secret: Fr) {
331
+ async createAccount(secret: Fr) {
234
332
  // This is a foot gun !
235
333
  const completeAddress = await this.keyStore.addAccount(secret, secret);
236
334
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -240,20 +338,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
240
338
  return completeAddress;
241
339
  }
242
340
 
243
- async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
341
+ async addAuthWitness(address: AztecAddress, messageHash: Fr) {
244
342
  const account = await this.accountStore.getAccount(address);
245
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
343
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
344
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
246
345
 
247
346
  const schnorr = new Schnorr();
248
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
347
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
249
348
 
250
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
349
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
251
350
 
252
351
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
253
352
  }
254
353
 
255
354
  async mineBlock(options: { nullifiers?: Fr[] } = {}) {
256
- const blockNumber = await this.txeGetNextBlockNumber();
355
+ const blockNumber = await this.getNextBlockNumber();
257
356
 
258
357
  const txEffect = TxEffect.empty();
259
358
  txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
@@ -277,13 +376,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
277
376
  await this.stateMachine.handleL2Block(block);
278
377
  }
279
378
 
280
- async txePrivateCallNewFlow(
281
- from: AztecAddress,
379
+ async privateCallNewFlow(
380
+ from: AztecAddress | undefined,
282
381
  targetContractAddress: AztecAddress = AztecAddress.zero(),
283
382
  functionSelector: FunctionSelector = FunctionSelector.empty(),
284
383
  args: Fr[],
285
384
  argsHash: Fr = Fr.zero(),
286
385
  isStaticCall: boolean = false,
386
+ additionalScopes: AztecAddress[] = [],
387
+ jobId: string,
388
+ authorizedUtilityCallTargets: AztecAddress[],
389
+ gasSettings: GasSettings,
287
390
  ) {
288
391
  this.logger.verbose(
289
392
  `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
@@ -297,25 +400,30 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
297
400
  throw new Error(message);
298
401
  }
299
402
 
403
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
404
+
300
405
  // Sync notes before executing private function to discover notes from previous transactions
301
- const utilityExecutor = async (call: FunctionCall) => {
302
- await this.executeUtilityCall(call);
406
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
407
+ await this.executeUtilityCall(call, execScopes, jobId);
303
408
  };
304
409
 
305
- await syncState(targetContractAddress, this.contractStore, functionSelector, utilityExecutor);
306
-
307
- const blockNumber = await this.txeGetNextBlockNumber();
410
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
411
+ await this.stateMachine.contractSyncService.ensureContractSynced(
412
+ targetContractAddress,
413
+ functionSelector,
414
+ utilityExecutor,
415
+ blockHeader,
416
+ jobId,
417
+ scopes,
418
+ );
308
419
 
309
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
420
+ const blockNumber = await this.getNextBlockNumber();
310
421
 
311
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
312
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
313
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
422
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
423
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
314
424
 
315
425
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
316
426
 
317
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
318
-
319
427
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
320
428
  const noteCache = new ExecutionNoteCache(protocolNullifier);
321
429
  // In production, the account contract sets the min revertible counter before calling the app function.
@@ -327,43 +435,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
327
435
 
328
436
  const simulator = new WASMSimulator();
329
437
 
330
- const privateExecutionOracle = new PrivateExecutionOracle(
438
+ const privateExecutionOracle = new PrivateExecutionOracle({
331
439
  argsHash,
332
440
  txContext,
333
441
  callContext,
334
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
335
- blockHeader,
442
+ anchorBlockHeader: blockHeader,
336
443
  utilityExecutor,
337
- /** List of transient auth witnesses to be used during this simulation */
338
- Array.from(this.authwits.values()),
339
- /** List of transient auth witnesses to be used during this simulation */
340
- [],
341
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
444
+ authWitnesses: Array.from(this.authwits.values()),
445
+ capsules: [],
446
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
342
447
  noteCache,
343
448
  taggingIndexCache,
344
- this.contractStore,
345
- this.noteStore,
346
- this.keyStore,
347
- this.addressStore,
348
- this.stateMachine.node,
349
- this.stateMachine.anchorBlockStore,
350
- this.senderTaggingStore,
351
- this.recipientTaggingStore,
352
- this.senderAddressBookStore,
353
- this.capsuleStore,
354
- this.privateEventStore,
355
- this.jobId,
356
- 0, // totalPublicArgsCount
357
- minRevertibleSideEffectCounter, // (start) sideEffectCounter
358
- undefined, // log
359
- undefined, // scopes
360
- /**
361
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
362
- * contract would perform, including setting senderForTags.
363
- */
364
- from,
449
+ contractStore: this.contractStore,
450
+ noteStore: this.noteStore,
451
+ keyStore: this.keyStore,
452
+ addressStore: this.addressStore,
453
+ aztecNode: this.stateMachine.node,
454
+ senderTaggingStore: this.senderTaggingStore,
455
+ recipientTaggingStore: this.recipientTaggingStore,
456
+ senderAddressBookStore: this.senderAddressBookStore,
457
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
458
+ privateEventStore: this.privateEventStore,
459
+ contractSyncService: this.stateMachine.contractSyncService,
460
+ jobId,
461
+ totalPublicCalldataCount: 0,
462
+ sideEffectCounter: minRevertibleSideEffectCounter,
463
+ scopes,
464
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
465
+ // contract would perform, including setting senderForTags.
466
+ senderForTags: from,
365
467
  simulator,
366
- );
468
+ messageContextService: this.stateMachine.messageContextService,
469
+ l2TipsStore: this.stateMachine.l2TipsProvider,
470
+ hooks: composeHooks({
471
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
472
+ isStaticCall ? 'private view' : 'private',
473
+ authorizedUtilityCallTargets,
474
+ ),
475
+ }),
476
+ });
367
477
 
368
478
  // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
369
479
  let result: PrivateExecutionResult;
@@ -385,7 +495,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
385
495
  );
386
496
  const publicFunctionsCalldata = await Promise.all(
387
497
  publicCallRequests.map(async r => {
388
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
498
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
389
499
  return new HashedValues(calldata, r.calldataHash);
390
500
  }),
391
501
  );
@@ -402,7 +512,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
402
512
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
403
513
  const { publicInputs } = await generateSimulatedProvingResult(
404
514
  result,
405
- this.contractStore,
515
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
516
+ this.stateMachine.node,
406
517
  minRevertibleSideEffectCounter,
407
518
  );
408
519
 
@@ -415,7 +526,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
415
526
 
416
527
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
417
528
 
418
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
529
+ const bindings = this.logger.getBindings();
530
+ const contractsDB = new PublicContractsDB(
531
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
532
+ bindings,
533
+ );
419
534
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
420
535
  const config = PublicSimulatorConfig.from({
421
536
  skipFeeEnforcement: true,
@@ -428,8 +543,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
428
543
  globals,
429
544
  guardedMerkleTrees,
430
545
  contractsDB,
431
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
546
+ new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
432
547
  new TestDateProvider(),
548
+ undefined,
549
+ createLogger('simulator:public-processor', bindings),
433
550
  );
434
551
 
435
552
  const tx = await Tx.create({
@@ -463,11 +580,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
463
580
  }
464
581
  }
465
582
 
583
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
584
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
585
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
586
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
587
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
588
+
466
589
  if (isStaticCall) {
467
590
  await checkpoint!.revert();
468
591
 
469
592
  await forkedWorldTrees.close();
470
- return executionResult.returnValues ?? [];
593
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
471
594
  }
472
595
 
473
596
  const txEffect = TxEffect.empty();
@@ -489,26 +612,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
489
612
 
490
613
  await forkedWorldTrees.close();
491
614
 
492
- return executionResult.returnValues ?? [];
615
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
493
616
  }
494
617
 
495
- async txePublicCallNewFlow(
496
- from: AztecAddress,
618
+ async publicCallNewFlow(
619
+ from: AztecAddress | undefined,
497
620
  targetContractAddress: AztecAddress,
498
621
  calldata: Fr[],
499
622
  isStaticCall: boolean,
623
+ gasSettings: GasSettings,
500
624
  ) {
501
625
  this.logger.verbose(
502
626
  `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
503
627
  );
504
628
 
505
- const blockNumber = await this.txeGetNextBlockNumber();
506
-
507
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
508
-
509
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
510
-
511
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
629
+ const blockNumber = await this.getNextBlockNumber();
512
630
 
513
631
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
514
632
 
@@ -526,7 +644,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
526
644
 
527
645
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
528
646
 
529
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
647
+ const bindings2 = this.logger.getBindings();
648
+ const contractsDB = new PublicContractsDB(
649
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
650
+ bindings2,
651
+ );
530
652
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
531
653
  const config = PublicSimulatorConfig.from({
532
654
  skipFeeEnforcement: true,
@@ -535,8 +657,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
535
657
  collectStatistics: false,
536
658
  collectCallMetadata: true,
537
659
  });
538
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
539
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
660
+ const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
661
+ const processor = new PublicProcessor(
662
+ globals,
663
+ guardedMerkleTrees,
664
+ contractsDB,
665
+ simulator,
666
+ new TestDateProvider(),
667
+ undefined,
668
+ createLogger('simulator:public-processor', bindings2),
669
+ );
540
670
 
541
671
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
542
672
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
@@ -549,7 +679,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
549
679
  // may require producing reverts.
550
680
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
551
681
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
552
- from,
682
+ from ?? AztecAddress.NULL_MSG_SENDER,
553
683
  targetContractAddress,
554
684
  isStaticCall,
555
685
  calldataHash,
@@ -567,7 +697,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
567
697
  constantData,
568
698
  /*gasUsed=*/ new Gas(0, 0),
569
699
  /*feePayer=*/ AztecAddress.zero(),
570
- /*includeByTimestamp=*/ 0n,
700
+ /*expirationTimestamp=*/ 0n,
571
701
  inputsForPublic,
572
702
  undefined,
573
703
  );
@@ -635,10 +765,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
635
765
  return returnValues ?? [];
636
766
  }
637
767
 
638
- async txeSimulateUtilityFunction(
768
+ async executeUtilityFunction(
639
769
  targetContractAddress: AztecAddress,
640
770
  functionSelector: FunctionSelector,
641
771
  args: Fr[],
772
+ jobId: string,
773
+ authorizedUtilityCallTargets: AztecAddress[],
642
774
  ) {
643
775
  const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
644
776
  if (!artifact) {
@@ -646,25 +778,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
646
778
  }
647
779
 
648
780
  // Sync notes before executing utility function to discover notes from previous transactions
649
- await syncState(targetContractAddress, this.contractStore, functionSelector, async call => {
650
- await this.executeUtilityCall(call);
651
- });
652
-
653
- const call = new FunctionCall(
654
- artifact.name,
781
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
782
+ await this.stateMachine.contractSyncService.ensureContractSynced(
655
783
  targetContractAddress,
656
784
  functionSelector,
657
- FunctionType.UTILITY,
658
- false,
659
- false,
660
- args,
661
- [],
785
+ async (call, execScopes) => {
786
+ await this.executeUtilityCall(call, execScopes, jobId);
787
+ },
788
+ blockHeader,
789
+ jobId,
790
+ await this.keyStore.getAccounts(),
662
791
  );
663
792
 
664
- return this.executeUtilityCall(call);
793
+ const call = FunctionCall.from({
794
+ name: artifact.name,
795
+ to: targetContractAddress,
796
+ selector: functionSelector,
797
+ type: FunctionType.UTILITY,
798
+ hideMsgSender: false,
799
+ isStatic: false,
800
+ args,
801
+ returnTypes: [],
802
+ });
803
+
804
+ return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
665
805
  }
666
806
 
667
- private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
807
+ private async executeUtilityCall(
808
+ call: FunctionCall,
809
+ scopes: AztecAddress[],
810
+ jobId: string,
811
+ authorizedUtilityCallTargets: AztecAddress[] = [],
812
+ ): Promise<Fr[]> {
668
813
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
669
814
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
670
815
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -677,24 +822,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
677
822
 
678
823
  try {
679
824
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
680
- const oracle = new UtilityExecutionOracle(
681
- call.to,
682
- [],
683
- [],
825
+ const simulator = new WASMSimulator();
826
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
827
+ await this.executeUtilityCall(syncCall, execScopes, jobId);
828
+ };
829
+ const oracle = new UtilityExecutionOracle({
830
+ contractAddress: call.to,
831
+ authWitnesses: [],
832
+ capsules: [],
684
833
  anchorBlockHeader,
685
- this.contractStore,
686
- this.noteStore,
687
- this.keyStore,
688
- this.addressStore,
689
- this.stateMachine.node,
690
- this.stateMachine.anchorBlockStore,
691
- this.recipientTaggingStore,
692
- this.senderAddressBookStore,
693
- this.capsuleStore,
694
- this.privateEventStore,
695
- this.jobId,
696
- );
697
- const acirExecutionResult = await new WASMSimulator()
834
+ contractStore: this.contractStore,
835
+ noteStore: this.noteStore,
836
+ keyStore: this.keyStore,
837
+ addressStore: this.addressStore,
838
+ aztecNode: this.stateMachine.node,
839
+ recipientTaggingStore: this.recipientTaggingStore,
840
+ senderAddressBookStore: this.senderAddressBookStore,
841
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
842
+ privateEventStore: this.privateEventStore,
843
+ messageContextService: this.stateMachine.messageContextService,
844
+ contractSyncService: this.stateMachine.contractSyncService,
845
+ l2TipsStore: this.stateMachine.l2TipsProvider,
846
+ jobId,
847
+ scopes,
848
+ simulator,
849
+ hooks: composeHooks({
850
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
851
+ }),
852
+ utilityExecutor,
853
+ });
854
+ const acirExecutionResult = await simulator
698
855
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
699
856
  .catch((err: Error) => {
700
857
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
@@ -709,10 +866,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
709
866
  );
710
867
  });
711
868
 
712
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
869
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
713
870
  return witnessMapToFields(acirExecutionResult.returnWitness);
714
871
  } catch (err) {
715
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
872
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
716
873
  }
717
874
  }
718
875
 
@@ -722,7 +879,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
722
879
  }
723
880
 
724
881
  private async getLastBlockNumber(): Promise<BlockNumber> {
725
- const header = await this.stateMachine.node.getBlockHeader('latest');
726
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
882
+ const block = await this.stateMachine.node.getBlock('latest');
883
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
884
+ }
885
+
886
+ private buildAuthorizeUtilityCallHook(
887
+ callerContext: 'private' | 'private view' | 'utility',
888
+ authorizedTargets: AztecAddress[],
889
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
890
+ if (authorizedTargets.length === 0) {
891
+ return undefined;
892
+ }
893
+ return req =>
894
+ Promise.resolve({
895
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
896
+ });
727
897
  }
728
898
  }