@aztec/txe 0.0.1-commit.343b43af6 → 0.0.1-commit.350e0a4d

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 (164) hide show
  1. package/dest/AuthRegistry-2RDAZOGB.js +3 -0
  2. package/dest/AuthRegistry-2RDAZOGB.js.map +7 -0
  3. package/dest/ContractClassRegistry-L5F3G33N.js +3 -0
  4. package/dest/ContractClassRegistry-L5F3G33N.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-IJOBAWAC.js +3 -0
  6. package/dest/ContractInstanceRegistry-IJOBAWAC.js.map +7 -0
  7. package/dest/FeeJuice-J3XDQPFS.js +3 -0
  8. package/dest/FeeJuice-J3XDQPFS.js.map +7 -0
  9. package/dest/HandshakeRegistry-QGWZJYVS.js +3 -0
  10. package/dest/HandshakeRegistry-QGWZJYVS.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-WZHPRFJ6.js +3 -0
  12. package/dest/MultiCallEntrypoint-WZHPRFJ6.js.map +7 -0
  13. package/dest/SchnorrAccount-II4XD6MI.js +3 -0
  14. package/dest/SchnorrAccount-II4XD6MI.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-FXIOXUQQ.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-FXIOXUQQ.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  18. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  19. package/dest/bin/check_txe_oracle_version.js +61 -0
  20. package/dest/bin/index.js +3 -30
  21. package/dest/bin/index.js.map +7 -0
  22. package/dest/bin/oracle_test_server.d.ts +3 -0
  23. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  24. package/dest/bin/oracle_test_server.js +41 -0
  25. package/dest/chunk-BJVAAXNA.js +3 -0
  26. package/dest/chunk-BJVAAXNA.js.map +7 -0
  27. package/dest/chunk-OMH3BDML.js +304 -0
  28. package/dest/chunk-OMH3BDML.js.map +7 -0
  29. package/dest/chunk-R3ZWQEFL.js +260 -0
  30. package/dest/chunk-R3ZWQEFL.js.map +7 -0
  31. package/dest/constants.d.ts +5 -1
  32. package/dest/constants.d.ts.map +1 -1
  33. package/dest/constants.js +9 -1
  34. package/dest/dispatcher_pool.d.ts +67 -0
  35. package/dest/dispatcher_pool.d.ts.map +1 -0
  36. package/dest/dispatcher_pool.js +286 -0
  37. package/dest/index.d.ts +51 -7
  38. package/dest/index.d.ts.map +1 -1
  39. package/dest/index.js +72 -190
  40. package/dest/metafile.json +38140 -0
  41. package/dest/msgpackr_fr_extension.d.ts +2 -0
  42. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  43. package/dest/msgpackr_fr_extension.js +21 -0
  44. package/dest/oracle/interfaces.d.ts +38 -8
  45. package/dest/oracle/interfaces.d.ts.map +1 -1
  46. package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
  47. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  48. package/dest/oracle/test-resolver/default_fixtures.js +207 -0
  49. package/dest/oracle/test-resolver/index.d.ts +9 -0
  50. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  51. package/dest/oracle/test-resolver/index.js +32 -0
  52. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  53. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  54. package/dest/oracle/test-resolver/resolver.js +181 -0
  55. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  56. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_public_context.js +49 -1
  58. package/dest/oracle/txe_oracle_registry.d.ts +169 -0
  59. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  60. package/dest/oracle/txe_oracle_registry.js +745 -0
  61. package/dest/oracle/txe_oracle_top_level_context.d.ts +43 -16
  62. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  63. package/dest/oracle/txe_oracle_top_level_context.js +233 -86
  64. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  65. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  66. package/dest/oracle/txe_oracle_version.js +14 -0
  67. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  68. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  69. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  70. package/dest/rpc_server.d.ts +14 -0
  71. package/dest/rpc_server.d.ts.map +1 -0
  72. package/dest/rpc_server.js +78 -0
  73. package/dest/rpc_translator.d.ts +112 -227
  74. package/dest/rpc_translator.d.ts.map +1 -1
  75. package/dest/rpc_translator.js +769 -607
  76. package/dest/server.bundle.js +3 -0
  77. package/dest/server.bundle.js.map +7 -0
  78. package/dest/state_machine/archiver.d.ts +4 -3
  79. package/dest/state_machine/archiver.d.ts.map +1 -1
  80. package/dest/state_machine/archiver.js +24 -14
  81. package/dest/state_machine/dummy_p2p_client.d.ts +16 -7
  82. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  83. package/dest/state_machine/dummy_p2p_client.js +25 -4
  84. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  85. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  86. package/dest/state_machine/global_variable_builder.js +8 -5
  87. package/dest/state_machine/index.d.ts +11 -5
  88. package/dest/state_machine/index.d.ts.map +1 -1
  89. package/dest/state_machine/index.js +50 -10
  90. package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
  91. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  92. package/dest/state_machine/mock_epoch_cache.js +29 -2
  93. package/dest/state_machine/synchronizer.d.ts +9 -6
  94. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  95. package/dest/state_machine/synchronizer.js +10 -6
  96. package/dest/txe_session.d.ts +89 -19
  97. package/dest/txe_session.d.ts.map +1 -1
  98. package/dest/txe_session.js +308 -60
  99. package/dest/utils/block_creation.d.ts +2 -2
  100. package/dest/utils/block_creation.d.ts.map +1 -1
  101. package/dest/utils/block_creation.js +2 -2
  102. package/dest/utils/encoding.d.ts +192 -0
  103. package/dest/utils/encoding.d.ts.map +1 -0
  104. package/dest/{util → utils}/encoding.js +7 -2
  105. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  106. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  107. package/dest/utils/tx_effect_creation.d.ts +1 -1
  108. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  109. package/dest/utils/tx_effect_creation.js +0 -1
  110. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  111. package/dest/utils/txe_account_store.d.ts.map +1 -0
  112. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  113. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  114. package/dest/utils/txe_artifact_resolver.js +161 -0
  115. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  116. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  117. package/dest/{util → utils}/txe_public_contract_data_source.js +8 -7
  118. package/dest/worker.bundle.js +3 -0
  119. package/dest/worker.bundle.js.map +7 -0
  120. package/dest/worker.d.ts +2 -0
  121. package/dest/worker.d.ts.map +1 -0
  122. package/dest/worker.js +92 -0
  123. package/package.json +38 -21
  124. package/src/bin/check_txe_oracle_version.ts +70 -0
  125. package/src/bin/index.ts +11 -2
  126. package/src/bin/oracle_test_server.ts +51 -0
  127. package/src/constants.ts +11 -1
  128. package/src/dispatcher_pool.ts +317 -0
  129. package/src/index.ts +99 -227
  130. package/src/msgpackr_fr_extension.ts +23 -0
  131. package/src/oracle/interfaces.ts +35 -7
  132. package/src/oracle/test-resolver/default_fixtures.ts +282 -0
  133. package/src/oracle/test-resolver/index.ts +44 -0
  134. package/src/oracle/test-resolver/resolver.ts +245 -0
  135. package/src/oracle/txe_oracle_public_context.ts +62 -0
  136. package/src/oracle/txe_oracle_registry.ts +536 -0
  137. package/src/oracle/txe_oracle_top_level_context.ts +307 -98
  138. package/src/oracle/txe_oracle_version.ts +17 -0
  139. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  140. package/src/rpc_server.ts +87 -0
  141. package/src/rpc_translator.ts +858 -866
  142. package/src/state_machine/archiver.ts +37 -16
  143. package/src/state_machine/dummy_p2p_client.ts +44 -11
  144. package/src/state_machine/global_variable_builder.ts +12 -11
  145. package/src/state_machine/index.ts +63 -28
  146. package/src/state_machine/mock_epoch_cache.ts +38 -3
  147. package/src/state_machine/synchronizer.ts +13 -7
  148. package/src/txe_session.ts +539 -74
  149. package/src/utils/block_creation.ts +2 -1
  150. package/src/{util → utils}/encoding.ts +8 -2
  151. package/src/utils/tx_effect_creation.ts +0 -2
  152. package/src/utils/txe_artifact_resolver.ts +217 -0
  153. package/src/{util → utils}/txe_public_contract_data_source.ts +6 -6
  154. package/src/worker.ts +98 -0
  155. package/dest/util/encoding.d.ts +0 -720
  156. package/dest/util/encoding.d.ts.map +0 -1
  157. package/dest/util/expected_failure_error.d.ts.map +0 -1
  158. package/dest/util/txe_account_store.d.ts.map +0 -1
  159. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  160. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  161. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  162. /package/dest/{util → utils}/txe_account_store.js +0 -0
  163. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  164. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,38 +1,45 @@
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';
10
7
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
11
8
  import { Fr } from '@aztec/foundation/curves/bn254';
9
+ import type { EthAddress } from '@aztec/foundation/eth-address';
12
10
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
11
  import { TestDateProvider } from '@aztec/foundation/timer';
14
12
  import type { KeyStore } from '@aztec/key-store';
15
- import type { AccessScopes } from '@aztec/pxe/client/lazy';
16
13
  import {
17
14
  AddressStore,
15
+ AnchoredContractData,
16
+ CapsuleService,
18
17
  CapsuleStore,
19
18
  type ContractStore,
19
+ type ExecutionHooks,
20
+ FactService,
21
+ FactStore,
20
22
  NoteStore,
21
- ORACLE_VERSION,
23
+ ORACLE_VERSION_MAJOR,
22
24
  PrivateEventStore,
23
25
  RecipientTaggingStore,
24
- SenderAddressBookStore,
25
26
  SenderTaggingStore,
27
+ TaggingSecretSourcesStore,
28
+ type TaggingSecretStrategy,
29
+ composeHooks,
26
30
  enrichPublicSimulationError,
27
31
  } from '@aztec/pxe/server';
28
32
  import {
33
+ CONTRACT_INSTANCE,
29
34
  ExecutionNoteCache,
30
35
  ExecutionTaggingIndexCache,
31
36
  HashedValuesCache,
32
37
  type IMiscOracle,
33
- Oracle,
38
+ type Option,
34
39
  PrivateExecutionOracle,
40
+ TransientArrayService,
35
41
  UtilityExecutionOracle,
42
+ buildACIRCallback,
36
43
  executePrivateFunction,
37
44
  generateSimulatedProvingResult,
38
45
  } from '@aztec/pxe/simulator';
@@ -46,10 +53,10 @@ import {
46
53
  witnessMapToFields,
47
54
  } from '@aztec/simulator/client';
48
55
  import {
49
- CppPublicTxSimulator,
50
56
  GuardedMerkleTreeOperations,
51
57
  PublicContractsDB,
52
58
  PublicProcessor,
59
+ PublicTxSimulator,
53
60
  } from '@aztec/simulator/server';
54
61
  import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
55
62
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
@@ -64,6 +71,9 @@ import {
64
71
  PrivateToPublicAccumulatedData,
65
72
  PublicCallRequest,
66
73
  } from '@aztec/stdlib/kernel';
74
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
75
+ import type { PrivateLog } from '@aztec/stdlib/logs';
76
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
67
77
  import { ChonkProof } from '@aztec/stdlib/proofs';
68
78
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
69
79
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -80,13 +90,14 @@ import {
80
90
  collectNested,
81
91
  } from '@aztec/stdlib/tx';
82
92
  import type { UInt64 } from '@aztec/stdlib/types';
83
- import { ForkCheckpoint } from '@aztec/world-state';
93
+ import { ForkCheckpoint } from '@aztec/world-state/native';
84
94
 
85
- import { DEFAULT_ADDRESS } from '../constants.js';
95
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
86
96
  import type { TXEStateMachine } from '../state_machine/index.js';
87
- import type { TXEAccountStore } from '../util/txe_account_store.js';
88
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
89
97
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
98
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
99
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
100
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
90
101
  import type { ITxeExecutionOracle } from './interfaces.js';
91
102
 
92
103
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -104,24 +115,41 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
104
115
  private accountStore: TXEAccountStore,
105
116
  private senderTaggingStore: SenderTaggingStore,
106
117
  private recipientTaggingStore: RecipientTaggingStore,
107
- private senderAddressBookStore: SenderAddressBookStore,
118
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
108
119
  private capsuleStore: CapsuleStore,
120
+ private factStore: FactStore,
109
121
  private privateEventStore: PrivateEventStore,
110
122
  private nextBlockTimestamp: bigint,
111
123
  private version: Fr,
112
124
  private chainId: Fr,
113
125
  private authwits: Map<string, AuthWitness>,
126
+ private taggingSecretStrategy: TaggingSecretStrategy | undefined,
127
+ private readonly artifactResolver: TXEArtifactResolver,
128
+ private readonly rootPath: string,
129
+ private readonly packageName: string,
114
130
  ) {
115
131
  this.logger = createLogger('txe:top_level_context');
116
132
  this.logger.debug('Entering Top Level Context');
117
133
  }
118
134
 
119
- assertCompatibleOracleVersion(version: number): void {
120
- if (version !== ORACLE_VERSION) {
135
+ private contractOracleVersion: { major: number; minor: number } | undefined;
136
+
137
+ assertCompatibleOracleVersion(major: number, minor: number): void {
138
+ if (major !== ORACLE_VERSION_MAJOR) {
139
+ const hint =
140
+ major > ORACLE_VERSION_MAJOR
141
+ ? '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.'
142
+ : '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.';
121
143
  throw new Error(
122
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
144
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
123
145
  );
124
146
  }
147
+ this.contractOracleVersion = { major, minor };
148
+ }
149
+
150
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
151
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
152
+ return this.contractOracleVersion;
125
153
  }
126
154
 
127
155
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
@@ -131,7 +159,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
131
159
  }
132
160
 
133
161
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
134
- log(level: number, message: string, fields: Fr[]): Promise<void> {
162
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
135
163
  if (!LogLevels[level]) {
136
164
  throw new Error(`Invalid log level: ${level}`);
137
165
  }
@@ -154,12 +182,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
154
182
  }
155
183
 
156
184
  async getLastBlockTimestamp() {
157
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
185
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
158
186
  }
159
187
 
160
- async getLastTxEffects() {
188
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
161
189
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
162
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
190
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
163
191
 
164
192
  if (block!.body.txEffects.length != 1) {
165
193
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -168,7 +196,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
168
196
 
169
197
  const txEffects = block!.body.txEffects[0];
170
198
 
171
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
199
+ const privateLogs = txEffects.privateLogs;
200
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
201
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
202
+ }
203
+
204
+ return {
205
+ txHash: txEffects.txHash,
206
+ noteHashes: txEffects.noteHashes,
207
+ nullifiers: txEffects.nullifiers,
208
+ privateLogs,
209
+ };
172
210
  }
173
211
 
174
212
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
@@ -182,7 +220,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
182
220
  contractAddress,
183
221
  null,
184
222
  async (call, execScopes) => {
185
- await this.executeUtilityCall(call, execScopes, jobId);
223
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
186
224
  },
187
225
  blockHeader,
188
226
  jobId,
@@ -191,7 +229,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
191
229
  }
192
230
 
193
231
  async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
194
- return (
232
+ const events = (
195
233
  await this.privateEventStore.getPrivateEvents(selector, {
196
234
  contractAddress,
197
235
  scopes: [scope],
@@ -199,6 +237,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
199
237
  toBlock: (await this.getLastBlockNumber()) + 1,
200
238
  })
201
239
  ).map(e => e.packedEvent);
240
+
241
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
242
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
243
+ }
244
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
245
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
246
+ }
247
+
248
+ return events;
202
249
  }
203
250
 
204
251
  async advanceBlocksBy(blocks: number) {
@@ -214,34 +261,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
214
261
  this.nextBlockTimestamp += duration;
215
262
  }
216
263
 
217
- async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
264
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
265
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
266
+ }
267
+
268
+ async deploy(
269
+ contractPath: string,
270
+ initializer: string,
271
+ args: Fr[],
272
+ secret: Fr,
273
+ salt: Fr,
274
+ deployer: AztecAddress,
275
+ ): Promise<Fr[]> {
276
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
277
+ rootPath: this.rootPath,
278
+ packageName: this.packageName,
279
+ contractPath,
280
+ initializer,
281
+ args,
282
+ secret,
283
+ salt,
284
+ deployer,
285
+ });
286
+
218
287
  // Emit deployment nullifier
219
288
  await this.mineBlock({
220
- nullifiers: [
221
- await siloNullifier(
222
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
223
- instance.address.toField(),
224
- ),
225
- ],
289
+ nullifiers: [await this.deploymentNullifier(instance.address)],
226
290
  });
227
291
 
228
292
  if (!secret.equals(Fr.ZERO)) {
229
- await this.addAccount(artifact, instance, secret);
293
+ await this.registerContractAndAddAccount(artifact, instance, secret);
230
294
  } else {
231
295
  await this.contractStore.addContractInstance(instance);
232
296
  await this.contractStore.addContractArtifact(artifact);
233
297
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
234
298
  }
299
+
300
+ return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
235
301
  }
236
302
 
237
- async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
303
+ /**
304
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
305
+ */
306
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
307
+ await this.mineBlock({
308
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
309
+ });
310
+ }
311
+
312
+ async addAccount(secret: Fr) {
313
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
314
+ return this.registerContractAndAddAccount(artifact, instance, secret);
315
+ }
316
+
317
+ private async registerContractAndAddAccount(
318
+ artifact: ContractArtifact,
319
+ instance: ContractInstanceWithAddress,
320
+ secret: Fr,
321
+ ) {
238
322
  const partialAddress = await computePartialAddress(instance);
239
323
 
240
324
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
241
325
  await this.contractStore.addContractInstance(instance);
242
326
  await this.contractStore.addContractArtifact(artifact);
243
327
 
244
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
328
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
245
329
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
246
330
  await this.addressStore.addCompleteAddress(completeAddress);
247
331
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -251,7 +335,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
251
335
 
252
336
  async createAccount(secret: Fr) {
253
337
  // This is a foot gun !
254
- const completeAddress = await this.keyStore.addAccount(secret, secret);
338
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
255
339
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
256
340
  await this.addressStore.addCompleteAddress(completeAddress);
257
341
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -261,17 +345,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
261
345
 
262
346
  async addAuthWitness(address: AztecAddress, messageHash: Fr) {
263
347
  const account = await this.accountStore.getAccount(address);
264
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
348
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
349
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
265
350
 
266
351
  const schnorr = new Schnorr();
267
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
352
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
268
353
 
269
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
354
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
270
355
 
271
356
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
272
357
  }
273
358
 
274
- async mineBlock(options: { nullifiers?: Fr[] } = {}) {
359
+ setTaggingSecretStrategy(strategy: Option<TaggingSecretStrategy>): void {
360
+ this.taggingSecretStrategy = strategy.value;
361
+ }
362
+
363
+ async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
364
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
365
+ const { size } = await this.stateMachine.synchronizer
366
+ .getCommitted()
367
+ .getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
368
+ const leafIndex = new Fr(size);
369
+
370
+ const message = new L1ToL2Message(
371
+ new L1Actor(sender, this.chainId.toNumber()),
372
+ new L2Actor(recipient, this.version.toNumber()),
373
+ content,
374
+ secretHash,
375
+ leafIndex,
376
+ );
377
+
378
+ await this.mineBlock({ l1ToL2Messages: [message.hash()] });
379
+
380
+ return leafIndex;
381
+ }
382
+
383
+ async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
275
384
  const blockNumber = await this.getNextBlockNumber();
276
385
 
277
386
  const txEffect = TxEffect.empty();
@@ -279,7 +388,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
279
388
  txEffect.txHash = new TxHash(new Fr(blockNumber));
280
389
 
281
390
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
282
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
391
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
283
392
 
284
393
  const globals = makeGlobalVariables(undefined, {
285
394
  blockNumber,
@@ -293,23 +402,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
293
402
 
294
403
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
295
404
 
296
- await this.stateMachine.handleL2Block(block);
405
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
297
406
  }
298
407
 
299
408
  async privateCallNewFlow(
300
- from: AztecAddress,
409
+ from: AztecAddress | undefined,
301
410
  targetContractAddress: AztecAddress = AztecAddress.zero(),
302
411
  functionSelector: FunctionSelector = FunctionSelector.empty(),
303
412
  args: Fr[],
304
413
  argsHash: Fr = Fr.zero(),
305
414
  isStaticCall: boolean = false,
415
+ additionalScopes: AztecAddress[] = [],
306
416
  jobId: string,
417
+ authorizedUtilityCallTargets: AztecAddress[],
418
+ gasSettings: GasSettings,
307
419
  ) {
420
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
421
+ const anchoredContractData = new AnchoredContractData(
422
+ this.contractStore,
423
+ this.stateMachine.contractClassService,
424
+ blockHeader,
425
+ );
426
+
308
427
  this.logger.verbose(
309
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
428
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
310
429
  );
311
430
 
312
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
431
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
313
432
  if (!artifact) {
314
433
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
315
434
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -317,32 +436,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
317
436
  throw new Error(message);
318
437
  }
319
438
 
320
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
321
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
322
- const effectiveScopes = from.isZero() ? [] : [from];
439
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
323
440
 
324
441
  // Sync notes before executing private function to discover notes from previous transactions
325
- const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
326
- await this.executeUtilityCall(call, execScopes, jobId);
442
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
443
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
327
444
  };
328
445
 
329
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
330
446
  await this.stateMachine.contractSyncService.ensureContractSynced(
331
447
  targetContractAddress,
332
448
  functionSelector,
333
449
  utilityExecutor,
334
450
  blockHeader,
335
451
  jobId,
336
- effectiveScopes,
452
+ scopes,
337
453
  );
338
454
 
339
455
  const blockNumber = await this.getNextBlockNumber();
340
456
 
341
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
342
-
343
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
344
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
345
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
457
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
458
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
346
459
 
347
460
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
348
461
 
@@ -357,9 +470,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
357
470
 
358
471
  const simulator = new WASMSimulator();
359
472
 
473
+ const transientArrayService = new TransientArrayService();
474
+ const taggingSecretStrategy = this.taggingSecretStrategy;
360
475
  const privateExecutionOracle = new PrivateExecutionOracle({
361
476
  argsHash,
362
477
  txContext,
478
+ txRequestSalt: Fr.ZERO,
363
479
  callContext,
364
480
  anchorBlockHeader: blockHeader,
365
481
  utilityExecutor,
@@ -368,25 +484,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
368
484
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
369
485
  noteCache,
370
486
  taggingIndexCache,
371
- contractStore: this.contractStore,
487
+ anchoredContractData,
372
488
  noteStore: this.noteStore,
373
489
  keyStore: this.keyStore,
374
490
  addressStore: this.addressStore,
375
491
  aztecNode: this.stateMachine.node,
376
492
  senderTaggingStore: this.senderTaggingStore,
377
493
  recipientTaggingStore: this.recipientTaggingStore,
378
- senderAddressBookStore: this.senderAddressBookStore,
379
- capsuleStore: this.capsuleStore,
494
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
495
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
496
+ factService: new FactService(this.factStore, scopes),
380
497
  privateEventStore: this.privateEventStore,
381
498
  contractSyncService: this.stateMachine.contractSyncService,
382
499
  jobId,
383
500
  totalPublicCalldataCount: 0,
384
501
  sideEffectCounter: minRevertibleSideEffectCounter,
385
- scopes: effectiveScopes,
502
+ scopes,
386
503
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
387
504
  // contract would perform, including setting senderForTags.
388
505
  senderForTags: from,
389
506
  simulator,
507
+ txResolver: this.stateMachine.txResolver,
508
+ l2TipsStore: this.stateMachine.l2TipsProvider,
509
+ hooks: composeHooks({
510
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
511
+ isStaticCall ? 'private view' : 'private',
512
+ authorizedUtilityCallTargets,
513
+ ),
514
+ // Only configure the hook when a strategy was explicitly set, so that otherwise the default tagging secret
515
+ // strategy is exercised.
516
+ resolveTaggingSecretStrategy: taggingSecretStrategy ? () => Promise.resolve(taggingSecretStrategy) : undefined,
517
+ }),
518
+ transientArrayService,
390
519
  });
391
520
 
392
521
  // 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.
@@ -409,12 +538,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
409
538
  );
410
539
  const publicFunctionsCalldata = await Promise.all(
411
540
  publicCallRequests.map(async r => {
412
- const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
541
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
413
542
  return new HashedValues(calldata, r.calldataHash);
414
543
  }),
415
544
  );
416
545
 
417
- noteCache.finish();
418
546
  const nonceGenerator = noteCache.getNonceGenerator();
419
547
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
420
548
  } catch (err) {
@@ -426,7 +554,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
426
554
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
427
555
  const { publicInputs } = await generateSimulatedProvingResult(
428
556
  result,
429
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
557
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
430
558
  this.stateMachine.node,
431
559
  minRevertibleSideEffectCounter,
432
560
  );
@@ -457,7 +585,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
457
585
  globals,
458
586
  guardedMerkleTrees,
459
587
  contractsDB,
460
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
588
+ new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
461
589
  new TestDateProvider(),
462
590
  undefined,
463
591
  createLogger('simulator:public-processor', bindings),
@@ -485,7 +613,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
485
613
  } else if (!processedTx.revertCode.isOK()) {
486
614
  if (processedTx.revertReason) {
487
615
  try {
488
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
616
+ await enrichPublicSimulationError(
617
+ processedTx.revertReason,
618
+ this.contractStore,
619
+ this.stateMachine.contractClassService,
620
+ await this.stateMachine.anchorBlockStore.getBlockHeader(),
621
+ this.logger,
622
+ );
489
623
  // eslint-disable-next-line no-empty
490
624
  } catch {}
491
625
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -494,11 +628,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
494
628
  }
495
629
  }
496
630
 
631
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
632
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
633
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
634
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
635
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
636
+
497
637
  if (isStaticCall) {
498
638
  await checkpoint!.revert();
499
639
 
500
640
  await forkedWorldTrees.close();
501
- return executionResult.returnValues ?? [];
641
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
502
642
  }
503
643
 
504
644
  const txEffect = TxEffect.empty();
@@ -520,31 +660,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
520
660
 
521
661
  await forkedWorldTrees.close();
522
662
 
523
- return executionResult.returnValues ?? [];
663
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
524
664
  }
525
665
 
526
666
  async publicCallNewFlow(
527
- from: AztecAddress,
667
+ from: AztecAddress | undefined,
528
668
  targetContractAddress: AztecAddress,
529
669
  calldata: Fr[],
530
670
  isStaticCall: boolean,
671
+ gasSettings: GasSettings,
531
672
  ) {
673
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
674
+ const anchoredContractData = new AnchoredContractData(
675
+ this.contractStore,
676
+ this.stateMachine.contractClassService,
677
+ anchorBlockHeader,
678
+ );
679
+
532
680
  this.logger.verbose(
533
- `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
681
+ `Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
534
682
  );
535
683
 
536
684
  const blockNumber = await this.getNextBlockNumber();
537
685
 
538
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
539
-
540
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
541
-
542
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
543
-
544
686
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
545
687
 
546
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
547
-
548
688
  const calldataHash = await computeCalldataHash(calldata);
549
689
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
550
690
 
@@ -570,7 +710,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
570
710
  collectStatistics: false,
571
711
  collectCallMetadata: true,
572
712
  });
573
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
713
+ const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
574
714
  const processor = new PublicProcessor(
575
715
  globals,
576
716
  guardedMerkleTrees,
@@ -592,7 +732,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
592
732
  // may require producing reverts.
593
733
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
594
734
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
595
- from,
735
+ from ?? AztecAddress.NULL_MSG_SENDER,
596
736
  targetContractAddress,
597
737
  isStaticCall,
598
738
  calldataHash,
@@ -637,7 +777,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
637
777
  } else if (!processedTx.revertCode.isOK()) {
638
778
  if (processedTx.revertReason) {
639
779
  try {
640
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
780
+ await enrichPublicSimulationError(
781
+ processedTx.revertReason,
782
+ this.contractStore,
783
+ this.stateMachine.contractClassService,
784
+ anchorBlockHeader,
785
+ this.logger,
786
+ );
641
787
  // eslint-disable-next-line no-empty
642
788
  } catch {}
643
789
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -679,27 +825,35 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
679
825
  }
680
826
 
681
827
  async executeUtilityFunction(
828
+ from: AztecAddress | undefined,
682
829
  targetContractAddress: AztecAddress,
683
830
  functionSelector: FunctionSelector,
684
831
  args: Fr[],
685
832
  jobId: string,
833
+ authorizedUtilityCallTargets: AztecAddress[],
686
834
  ) {
687
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
835
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
836
+ const anchoredContractData = new AnchoredContractData(
837
+ this.contractStore,
838
+ this.stateMachine.contractClassService,
839
+ blockHeader,
840
+ );
841
+
842
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
688
843
  if (!artifact) {
689
844
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
690
845
  }
691
846
 
692
847
  // Sync notes before executing utility function to discover notes from previous transactions
693
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
694
848
  await this.stateMachine.contractSyncService.ensureContractSynced(
695
849
  targetContractAddress,
696
850
  functionSelector,
697
851
  async (call, execScopes) => {
698
- await this.executeUtilityCall(call, execScopes, jobId);
852
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
699
853
  },
700
854
  blockHeader,
701
855
  jobId,
702
- 'ALL_SCOPES',
856
+ await this.keyStore.getAccounts(),
703
857
  );
704
858
 
705
859
  const call = FunctionCall.from({
@@ -713,11 +867,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
713
867
  returnTypes: [],
714
868
  });
715
869
 
716
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
870
+ return this.executeUtilityCall(call, {
871
+ from,
872
+ scopes: await this.keyStore.getAccounts(),
873
+ jobId,
874
+ authorizedUtilityCallTargets,
875
+ });
717
876
  }
718
877
 
719
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
720
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
878
+ private async executeUtilityCall(
879
+ call: FunctionCall,
880
+ {
881
+ from = AztecAddress.NULL_MSG_SENDER,
882
+ scopes,
883
+ jobId,
884
+ authorizedUtilityCallTargets = [],
885
+ }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
886
+ ): Promise<Fr[]> {
887
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
888
+ const anchoredContractData = new AnchoredContractData(
889
+ this.contractStore,
890
+ this.stateMachine.contractClassService,
891
+ anchorBlockHeader,
892
+ );
893
+
894
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
895
+ if (!entryPointArtifact) {
896
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
897
+ }
721
898
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
722
899
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
723
900
  }
@@ -728,26 +905,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
728
905
  });
729
906
 
730
907
  try {
731
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
908
+ const simulator = new WASMSimulator();
909
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
910
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
911
+ };
732
912
  const oracle = new UtilityExecutionOracle({
733
- contractAddress: call.to,
913
+ callContext: CallContext.from({
914
+ msgSender: from,
915
+ contractAddress: call.to,
916
+ functionSelector: call.selector,
917
+ isStaticCall: true,
918
+ }),
734
919
  authWitnesses: [],
735
920
  capsules: [],
736
921
  anchorBlockHeader,
737
- contractStore: this.contractStore,
922
+ anchoredContractData,
738
923
  noteStore: this.noteStore,
739
924
  keyStore: this.keyStore,
740
925
  addressStore: this.addressStore,
741
926
  aztecNode: this.stateMachine.node,
742
927
  recipientTaggingStore: this.recipientTaggingStore,
743
- senderAddressBookStore: this.senderAddressBookStore,
744
- capsuleStore: this.capsuleStore,
928
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
929
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
930
+ factService: new FactService(this.factStore, scopes),
745
931
  privateEventStore: this.privateEventStore,
932
+ txResolver: this.stateMachine.txResolver,
933
+ contractSyncService: this.stateMachine.contractSyncService,
934
+ l2TipsStore: this.stateMachine.l2TipsProvider,
746
935
  jobId,
747
936
  scopes,
937
+ simulator,
938
+ hooks: composeHooks({
939
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
940
+ }),
941
+ utilityExecutor,
942
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
943
+ transientArrayService: new TransientArrayService(),
748
944
  });
749
- const acirExecutionResult = await new WASMSimulator()
750
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
945
+ const acirExecutionResult = await simulator
946
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
751
947
  .catch((err: Error) => {
752
948
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
753
949
  throw new ExecutionError(
@@ -768,13 +964,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
768
964
  }
769
965
  }
770
966
 
771
- close(): [bigint, Map<string, AuthWitness>] {
967
+ close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
772
968
  this.logger.debug('Exiting Top Level Context');
773
- return [this.nextBlockTimestamp, this.authwits];
969
+ return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
774
970
  }
775
971
 
776
972
  private async getLastBlockNumber(): Promise<BlockNumber> {
777
- const header = await this.stateMachine.node.getBlockHeader('latest');
778
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
973
+ const block = await this.stateMachine.node.getBlock('latest');
974
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
975
+ }
976
+
977
+ private buildAuthorizeUtilityCallHook(
978
+ callerContext: 'private' | 'private view' | 'utility',
979
+ authorizedTargets: AztecAddress[],
980
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
981
+ if (authorizedTargets.length === 0) {
982
+ return undefined;
983
+ }
984
+ return req =>
985
+ Promise.resolve({
986
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
987
+ });
779
988
  }
780
989
  }