@aztec/txe 0.0.1-commit.42ee6df9b → 0.0.1-commit.431c48d

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 (170) hide show
  1. package/dest/AuthRegistry-56AMRLSQ.js +3 -0
  2. package/dest/AuthRegistry-56AMRLSQ.js.map +7 -0
  3. package/dest/ContractClassRegistry-CRN27URB.js +3 -0
  4. package/dest/ContractClassRegistry-CRN27URB.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-GRGL26IC.js +3 -0
  6. package/dest/ContractInstanceRegistry-GRGL26IC.js.map +7 -0
  7. package/dest/FeeJuice-J23RVHLW.js +3 -0
  8. package/dest/FeeJuice-J23RVHLW.js.map +7 -0
  9. package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js +3 -0
  10. package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js.map +7 -0
  11. package/dest/HandshakeRegistry-GNFACTEE.js +3 -0
  12. package/dest/HandshakeRegistry-GNFACTEE.js.map +7 -0
  13. package/dest/MultiCallEntrypoint-MIDICLQB.js +3 -0
  14. package/dest/MultiCallEntrypoint-MIDICLQB.js.map +7 -0
  15. package/dest/SchnorrAccount-ZRENHSMV.js +3 -0
  16. package/dest/SchnorrAccount-ZRENHSMV.js.map +7 -0
  17. package/dest/SchnorrInitializerlessAccount-L56LOFSV.js +3 -0
  18. package/dest/SchnorrInitializerlessAccount-L56LOFSV.js.map +7 -0
  19. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  20. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  21. package/dest/bin/check_txe_oracle_version.js +53 -0
  22. package/dest/bin/index.js +3 -30
  23. package/dest/bin/index.js.map +7 -0
  24. package/dest/bin/oracle_test_server.d.ts +3 -0
  25. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  26. package/dest/bin/oracle_test_server.js +41 -0
  27. package/dest/chunk-BJVAAXNA.js +3 -0
  28. package/dest/chunk-BJVAAXNA.js.map +7 -0
  29. package/dest/chunk-LVLJKGGH.js +266 -0
  30. package/dest/chunk-LVLJKGGH.js.map +7 -0
  31. package/dest/chunk-OVMCQ5A6.js +304 -0
  32. package/dest/chunk-OVMCQ5A6.js.map +7 -0
  33. package/dest/constants.d.ts +5 -1
  34. package/dest/constants.d.ts.map +1 -1
  35. package/dest/constants.js +9 -1
  36. package/dest/dispatcher_pool.d.ts +67 -0
  37. package/dest/dispatcher_pool.d.ts.map +1 -0
  38. package/dest/dispatcher_pool.js +286 -0
  39. package/dest/index.d.ts +51 -7
  40. package/dest/index.d.ts.map +1 -1
  41. package/dest/index.js +72 -190
  42. package/dest/metafile.json +40494 -0
  43. package/dest/msgpackr_fr_extension.d.ts +2 -0
  44. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  45. package/dest/msgpackr_fr_extension.js +21 -0
  46. package/dest/oracle/interfaces.d.ts +47 -9
  47. package/dest/oracle/interfaces.d.ts.map +1 -1
  48. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  49. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  50. package/dest/oracle/tagging_secret_strategy.js +12 -0
  51. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  52. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  53. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  54. package/dest/oracle/test-resolver/index.d.ts +9 -0
  55. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  56. package/dest/oracle/test-resolver/index.js +32 -0
  57. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  58. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  59. package/dest/oracle/test-resolver/resolver.js +181 -0
  60. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  61. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  62. package/dest/oracle/txe_oracle_public_context.js +49 -1
  63. package/dest/oracle/txe_oracle_registry.d.ts +172 -0
  64. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  65. package/dest/oracle/txe_oracle_registry.js +767 -0
  66. package/dest/oracle/txe_oracle_top_level_context.d.ts +58 -18
  67. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  68. package/dest/oracle/txe_oracle_top_level_context.js +286 -97
  69. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  70. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  71. package/dest/oracle/txe_oracle_version.js +14 -0
  72. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  73. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  74. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  75. package/dest/rpc_server.d.ts +14 -0
  76. package/dest/rpc_server.d.ts.map +1 -0
  77. package/dest/rpc_server.js +78 -0
  78. package/dest/rpc_translator.d.ts +115 -233
  79. package/dest/rpc_translator.d.ts.map +1 -1
  80. package/dest/rpc_translator.js +791 -647
  81. package/dest/server.bundle.js +3 -0
  82. package/dest/server.bundle.js.map +7 -0
  83. package/dest/state_machine/archiver.d.ts +4 -3
  84. package/dest/state_machine/archiver.d.ts.map +1 -1
  85. package/dest/state_machine/archiver.js +25 -16
  86. package/dest/state_machine/dummy_p2p_client.d.ts +16 -7
  87. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  88. package/dest/state_machine/dummy_p2p_client.js +26 -2
  89. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  90. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  91. package/dest/state_machine/global_variable_builder.js +8 -5
  92. package/dest/state_machine/index.d.ts +11 -7
  93. package/dest/state_machine/index.d.ts.map +1 -1
  94. package/dest/state_machine/index.js +52 -14
  95. package/dest/state_machine/mock_epoch_cache.d.ts +1 -2
  96. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  97. package/dest/state_machine/mock_epoch_cache.js +0 -3
  98. package/dest/state_machine/synchronizer.d.ts +5 -2
  99. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  100. package/dest/state_machine/synchronizer.js +7 -3
  101. package/dest/txe_session.d.ts +90 -20
  102. package/dest/txe_session.d.ts.map +1 -1
  103. package/dest/txe_session.js +313 -67
  104. package/dest/utils/block_creation.d.ts +2 -2
  105. package/dest/utils/block_creation.d.ts.map +1 -1
  106. package/dest/utils/block_creation.js +2 -2
  107. package/dest/utils/encoding.d.ts +192 -0
  108. package/dest/utils/encoding.d.ts.map +1 -0
  109. package/dest/{util → utils}/encoding.js +7 -2
  110. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  111. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  112. package/dest/utils/tx_effect_creation.d.ts +1 -1
  113. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  114. package/dest/utils/tx_effect_creation.js +0 -1
  115. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  116. package/dest/utils/txe_account_store.d.ts.map +1 -0
  117. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  118. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  119. package/dest/utils/txe_artifact_resolver.js +161 -0
  120. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  121. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  122. package/dest/{util → utils}/txe_public_contract_data_source.js +7 -4
  123. package/dest/worker.bundle.js +3 -0
  124. package/dest/worker.bundle.js.map +7 -0
  125. package/dest/worker.d.ts +2 -0
  126. package/dest/worker.d.ts.map +1 -0
  127. package/dest/worker.js +92 -0
  128. package/package.json +38 -21
  129. package/src/bin/check_txe_oracle_version.ts +67 -0
  130. package/src/bin/index.ts +11 -2
  131. package/src/bin/oracle_test_server.ts +51 -0
  132. package/src/constants.ts +11 -1
  133. package/src/dispatcher_pool.ts +317 -0
  134. package/src/index.ts +99 -227
  135. package/src/msgpackr_fr_extension.ts +23 -0
  136. package/src/oracle/interfaces.ts +47 -8
  137. package/src/oracle/tagging_secret_strategy.ts +25 -0
  138. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  139. package/src/oracle/test-resolver/index.ts +44 -0
  140. package/src/oracle/test-resolver/resolver.ts +245 -0
  141. package/src/oracle/txe_oracle_public_context.ts +62 -0
  142. package/src/oracle/txe_oracle_registry.ts +556 -0
  143. package/src/oracle/txe_oracle_top_level_context.ts +357 -118
  144. package/src/oracle/txe_oracle_version.ts +17 -0
  145. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  146. package/src/rpc_server.ts +87 -0
  147. package/src/rpc_translator.ts +890 -938
  148. package/src/state_machine/archiver.ts +37 -17
  149. package/src/state_machine/dummy_p2p_client.ts +43 -10
  150. package/src/state_machine/global_variable_builder.ts +12 -17
  151. package/src/state_machine/index.ts +63 -32
  152. package/src/state_machine/mock_epoch_cache.ts +0 -4
  153. package/src/state_machine/synchronizer.ts +9 -3
  154. package/src/txe_session.ts +545 -80
  155. package/src/utils/block_creation.ts +2 -1
  156. package/src/{util → utils}/encoding.ts +8 -2
  157. package/src/utils/tx_effect_creation.ts +0 -2
  158. package/src/utils/txe_artifact_resolver.ts +217 -0
  159. package/src/{util → utils}/txe_public_contract_data_source.ts +6 -4
  160. package/src/worker.ts +98 -0
  161. package/dest/util/encoding.d.ts +0 -788
  162. package/dest/util/encoding.d.ts.map +0 -1
  163. package/dest/util/expected_failure_error.d.ts.map +0 -1
  164. package/dest/util/txe_account_store.d.ts.map +0 -1
  165. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  166. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  167. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  168. /package/dest/{util → utils}/txe_account_store.js +0 -0
  169. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  170. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,39 +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
13
  import {
16
14
  AddressStore,
15
+ AnchoredContractData,
17
16
  CapsuleService,
18
17
  CapsuleStore,
19
18
  type ContractStore,
20
- type ContractSyncService,
19
+ type ExecutionHooks,
20
+ FactService,
21
+ FactStore,
21
22
  NoteStore,
22
- ORACLE_VERSION,
23
+ ORACLE_VERSION_MAJOR,
23
24
  PrivateEventStore,
24
25
  RecipientTaggingStore,
25
- SenderAddressBookStore,
26
26
  SenderTaggingStore,
27
+ TaggingSecretSourcesStore,
28
+ type TaggingSecretStrategy,
29
+ composeHooks,
27
30
  enrichPublicSimulationError,
28
31
  } from '@aztec/pxe/server';
29
32
  import {
33
+ CONTRACT_INSTANCE,
30
34
  ExecutionNoteCache,
31
35
  ExecutionTaggingIndexCache,
32
36
  HashedValuesCache,
33
37
  type IMiscOracle,
34
- Oracle,
38
+ type Option,
35
39
  PrivateExecutionOracle,
40
+ TransientArrayService,
36
41
  UtilityExecutionOracle,
42
+ buildACIRCallback,
37
43
  executePrivateFunction,
38
44
  generateSimulatedProvingResult,
39
45
  } from '@aztec/pxe/simulator';
@@ -65,6 +71,10 @@ import {
65
71
  PrivateToPublicAccumulatedData,
66
72
  PublicCallRequest,
67
73
  } from '@aztec/stdlib/kernel';
74
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
75
+ import type { PrivateLog } from '@aztec/stdlib/logs';
76
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
77
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
68
78
  import { ChonkProof } from '@aztec/stdlib/proofs';
69
79
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
70
80
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -81,14 +91,16 @@ import {
81
91
  collectNested,
82
92
  } from '@aztec/stdlib/tx';
83
93
  import type { UInt64 } from '@aztec/stdlib/types';
84
- import { ForkCheckpoint } from '@aztec/world-state';
94
+ import { ForkCheckpoint } from '@aztec/world-state/native';
85
95
 
86
- import { DEFAULT_ADDRESS } from '../constants.js';
96
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
87
97
  import type { TXEStateMachine } from '../state_machine/index.js';
88
- import type { TXEAccountStore } from '../util/txe_account_store.js';
89
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
90
98
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
99
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
100
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
101
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
91
102
  import type { ITxeExecutionOracle } from './interfaces.js';
103
+ import { type TXETaggingSecretStrategies, makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
92
104
 
93
105
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
94
106
  isMisc = true as const;
@@ -105,29 +117,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
105
117
  private accountStore: TXEAccountStore,
106
118
  private senderTaggingStore: SenderTaggingStore,
107
119
  private recipientTaggingStore: RecipientTaggingStore,
108
- private senderAddressBookStore: SenderAddressBookStore,
120
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
109
121
  private capsuleStore: CapsuleStore,
122
+ private factStore: FactStore,
110
123
  private privateEventStore: PrivateEventStore,
111
124
  private nextBlockTimestamp: bigint,
112
125
  private version: Fr,
113
126
  private chainId: Fr,
114
127
  private authwits: Map<string, AuthWitness>,
115
- private readonly contractSyncService: ContractSyncService,
128
+ private taggingSecretStrategies: TXETaggingSecretStrategies,
129
+ private authorizeAllUtilityCallTargets: boolean,
130
+ private readonly artifactResolver: TXEArtifactResolver,
131
+ private readonly rootPath: string,
132
+ private readonly packageName: string,
116
133
  ) {
117
134
  this.logger = createLogger('txe:top_level_context');
118
135
  this.logger.debug('Entering Top Level Context');
119
136
  }
120
137
 
121
- assertCompatibleOracleVersion(version: number): void {
122
- if (version !== ORACLE_VERSION) {
138
+ private contractOracleVersion: { major: number; minor: number } | undefined;
139
+
140
+ assertCompatibleOracleVersion(major: number, minor: number): void {
141
+ if (major !== ORACLE_VERSION_MAJOR) {
123
142
  const hint =
124
- version > ORACLE_VERSION
143
+ major > ORACLE_VERSION_MAJOR
125
144
  ? '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.'
126
145
  : '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.';
127
146
  throw new Error(
128
- `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${ORACLE_VERSION}, got ${version})`,
147
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
129
148
  );
130
149
  }
150
+ this.contractOracleVersion = { major, minor };
151
+ }
152
+
153
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
154
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
155
+ return this.contractOracleVersion;
131
156
  }
132
157
 
133
158
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
@@ -137,7 +162,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
137
162
  }
138
163
 
139
164
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
140
- log(level: number, message: string, fields: Fr[]): Promise<void> {
165
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
141
166
  if (!LogLevels[level]) {
142
167
  throw new Error(`Invalid log level: ${level}`);
143
168
  }
@@ -160,12 +185,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
160
185
  }
161
186
 
162
187
  async getLastBlockTimestamp() {
163
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
188
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
164
189
  }
165
190
 
166
- async getLastTxEffects() {
191
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
167
192
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
168
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
193
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
169
194
 
170
195
  if (block!.body.txEffects.length != 1) {
171
196
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -174,7 +199,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
174
199
 
175
200
  const txEffects = block!.body.txEffects[0];
176
201
 
177
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
202
+ const privateLogs = txEffects.privateLogs;
203
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
204
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
205
+ }
206
+
207
+ return {
208
+ txHash: txEffects.txHash,
209
+ noteHashes: txEffects.noteHashes,
210
+ nullifiers: txEffects.nullifiers,
211
+ privateLogs,
212
+ };
178
213
  }
179
214
 
180
215
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
@@ -183,21 +218,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
183
218
  return;
184
219
  }
185
220
 
186
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
187
- await this.stateMachine.contractSyncService.ensureContractSynced(
188
- contractAddress,
189
- null,
190
- async (call, execScopes) => {
191
- await this.executeUtilityCall(call, execScopes, jobId);
221
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
222
+ await this.stateMachine.contractSyncService.ensureContractSynced({
223
+ contract: contractAddress,
224
+ functionToInvokeAfterSync: null,
225
+ utilityExecutor: async (call, execScopes) => {
226
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
192
227
  },
193
- blockHeader,
228
+ anchorBlockHeader,
194
229
  jobId,
195
- [scope],
196
- );
230
+ scopes: [scope],
231
+ triggeredBy: undefined,
232
+ });
197
233
  }
198
234
 
199
235
  async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
200
- return (
236
+ const events = (
201
237
  await this.privateEventStore.getPrivateEvents(selector, {
202
238
  contractAddress,
203
239
  scopes: [scope],
@@ -205,6 +241,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
205
241
  toBlock: (await this.getLastBlockNumber()) + 1,
206
242
  })
207
243
  ).map(e => e.packedEvent);
244
+
245
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
246
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
247
+ }
248
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
249
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
250
+ }
251
+
252
+ return events;
208
253
  }
209
254
 
210
255
  async advanceBlocksBy(blocks: number) {
@@ -220,34 +265,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
220
265
  this.nextBlockTimestamp += duration;
221
266
  }
222
267
 
223
- async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
268
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
269
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
270
+ }
271
+
272
+ async deploy(
273
+ contractPath: string,
274
+ initializer: string,
275
+ args: Fr[],
276
+ secret: Fr,
277
+ salt: Fr,
278
+ deployer: AztecAddress,
279
+ ): Promise<Fr[]> {
280
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
281
+ rootPath: this.rootPath,
282
+ packageName: this.packageName,
283
+ contractPath,
284
+ initializer,
285
+ args,
286
+ secret,
287
+ salt,
288
+ deployer,
289
+ });
290
+
224
291
  // Emit deployment nullifier
225
292
  await this.mineBlock({
226
- nullifiers: [
227
- await siloNullifier(
228
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
229
- instance.address.toField(),
230
- ),
231
- ],
293
+ nullifiers: [await this.deploymentNullifier(instance.address)],
232
294
  });
233
295
 
234
296
  if (!secret.equals(Fr.ZERO)) {
235
- await this.addAccount(artifact, instance, secret);
297
+ await this.registerContractAndAddAccount(artifact, instance, secret);
236
298
  } else {
237
299
  await this.contractStore.addContractInstance(instance);
238
300
  await this.contractStore.addContractArtifact(artifact);
239
301
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
240
302
  }
303
+
304
+ return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
241
305
  }
242
306
 
243
- async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
307
+ /**
308
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
309
+ */
310
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
311
+ await this.mineBlock({
312
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
313
+ });
314
+ }
315
+
316
+ async addAccount(secret: Fr) {
317
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
318
+ return this.registerContractAndAddAccount(artifact, instance, secret);
319
+ }
320
+
321
+ private async registerContractAndAddAccount(
322
+ artifact: ContractArtifact,
323
+ instance: ContractInstanceWithAddress,
324
+ secret: Fr,
325
+ ) {
244
326
  const partialAddress = await computePartialAddress(instance);
245
327
 
246
328
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
247
329
  await this.contractStore.addContractInstance(instance);
248
330
  await this.contractStore.addContractArtifact(artifact);
249
331
 
250
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
332
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
251
333
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
252
334
  await this.addressStore.addCompleteAddress(completeAddress);
253
335
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -255,9 +337,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
255
337
  return completeAddress;
256
338
  }
257
339
 
258
- async createAccount(secret: Fr) {
259
- // This is a foot gun !
260
- const completeAddress = await this.keyStore.addAccount(secret, secret);
340
+ async createAccount(secret: Fr, partialAddress: Fr) {
341
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
261
342
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
262
343
  await this.addressStore.addCompleteAddress(completeAddress);
263
344
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -267,17 +348,57 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
267
348
 
268
349
  async addAuthWitness(address: AztecAddress, messageHash: Fr) {
269
350
  const account = await this.accountStore.getAccount(address);
270
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
351
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
352
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
271
353
 
272
354
  const schnorr = new Schnorr();
273
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
355
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
274
356
 
275
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
357
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
276
358
 
277
359
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
278
360
  }
279
361
 
280
- async mineBlock(options: { nullifiers?: Fr[] } = {}) {
362
+ setTaggingSecretStrategies(
363
+ unconstrainedStrategy: Option<TaggingSecretStrategy>,
364
+ constrainedStrategy: Option<TaggingSecretStrategy>,
365
+ ): void {
366
+ const apply = (mode: AppTaggingSecretKind, strategy: Option<TaggingSecretStrategy>) => {
367
+ if (strategy.isSome()) {
368
+ this.taggingSecretStrategies.set(mode, strategy.value);
369
+ } else {
370
+ this.taggingSecretStrategies.delete(mode);
371
+ }
372
+ };
373
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
374
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
375
+ }
376
+
377
+ setAuthorizeAllUtilityCallTargets(authorizeAll: boolean): void {
378
+ this.authorizeAllUtilityCallTargets = authorizeAll;
379
+ }
380
+
381
+ async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
382
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
383
+ const { size } = await this.stateMachine.synchronizer
384
+ .getCommitted()
385
+ .getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
386
+ const leafIndex = new Fr(size);
387
+
388
+ const message = new L1ToL2Message(
389
+ new L1Actor(sender, this.chainId.toNumber()),
390
+ new L2Actor(recipient, this.version.toNumber()),
391
+ content,
392
+ secretHash,
393
+ leafIndex,
394
+ );
395
+
396
+ await this.mineBlock({ l1ToL2Messages: [message.hash()] });
397
+
398
+ return leafIndex;
399
+ }
400
+
401
+ async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
281
402
  const blockNumber = await this.getNextBlockNumber();
282
403
 
283
404
  const txEffect = TxEffect.empty();
@@ -285,7 +406,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
285
406
  txEffect.txHash = new TxHash(new Fr(blockNumber));
286
407
 
287
408
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
288
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
409
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
289
410
 
290
411
  const globals = makeGlobalVariables(undefined, {
291
412
  blockNumber,
@@ -299,23 +420,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
299
420
 
300
421
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
301
422
 
302
- await this.stateMachine.handleL2Block(block);
423
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
303
424
  }
304
425
 
305
426
  async privateCallNewFlow(
306
- from: AztecAddress,
427
+ from: AztecAddress | undefined,
307
428
  targetContractAddress: AztecAddress = AztecAddress.zero(),
308
429
  functionSelector: FunctionSelector = FunctionSelector.empty(),
309
430
  args: Fr[],
310
431
  argsHash: Fr = Fr.zero(),
311
432
  isStaticCall: boolean = false,
433
+ additionalScopes: AztecAddress[] = [],
312
434
  jobId: string,
435
+ authorizedUtilityCallTargets: AztecAddress[],
436
+ gasSettings: GasSettings,
313
437
  ) {
438
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
439
+ const anchoredContractData = new AnchoredContractData(
440
+ this.contractStore,
441
+ this.stateMachine.contractClassService,
442
+ blockHeader,
443
+ );
444
+
314
445
  this.logger.verbose(
315
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
446
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
316
447
  );
317
448
 
318
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
449
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
319
450
  if (!artifact) {
320
451
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
321
452
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -323,32 +454,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
323
454
  throw new Error(message);
324
455
  }
325
456
 
326
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
327
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
328
- const effectiveScopes = from.isZero() ? [] : [from];
457
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
329
458
 
330
459
  // Sync notes before executing private function to discover notes from previous transactions
331
460
  const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
332
- await this.executeUtilityCall(call, execScopes, jobId);
461
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
333
462
  };
334
463
 
335
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
336
- await this.stateMachine.contractSyncService.ensureContractSynced(
337
- targetContractAddress,
338
- functionSelector,
464
+ await this.stateMachine.contractSyncService.ensureContractSynced({
465
+ contract: targetContractAddress,
466
+ functionToInvokeAfterSync: functionSelector,
339
467
  utilityExecutor,
340
- blockHeader,
468
+ anchorBlockHeader: blockHeader,
341
469
  jobId,
342
- effectiveScopes,
343
- );
470
+ scopes,
471
+ triggeredBy: undefined,
472
+ });
344
473
 
345
474
  const blockNumber = await this.getNextBlockNumber();
346
475
 
347
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
348
-
349
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
350
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
351
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
476
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
477
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
352
478
 
353
479
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
354
480
 
@@ -363,9 +489,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
363
489
 
364
490
  const simulator = new WASMSimulator();
365
491
 
492
+ const transientArrayService = new TransientArrayService();
366
493
  const privateExecutionOracle = new PrivateExecutionOracle({
367
494
  argsHash,
368
495
  txContext,
496
+ // The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
497
+ txRequestSalt: Fr.ZERO,
369
498
  callContext,
370
499
  anchorBlockHeader: blockHeader,
371
500
  utilityExecutor,
@@ -374,26 +503,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
374
503
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
375
504
  noteCache,
376
505
  taggingIndexCache,
377
- contractStore: this.contractStore,
506
+ anchoredContractData,
378
507
  noteStore: this.noteStore,
379
508
  keyStore: this.keyStore,
380
509
  addressStore: this.addressStore,
381
510
  aztecNode: this.stateMachine.node,
382
511
  senderTaggingStore: this.senderTaggingStore,
383
512
  recipientTaggingStore: this.recipientTaggingStore,
384
- senderAddressBookStore: this.senderAddressBookStore,
385
- capsuleService: new CapsuleService(this.capsuleStore, effectiveScopes),
513
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
514
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
515
+ factService: new FactService(this.factStore, scopes),
386
516
  privateEventStore: this.privateEventStore,
387
517
  contractSyncService: this.stateMachine.contractSyncService,
388
518
  jobId,
389
519
  totalPublicCalldataCount: 0,
390
520
  sideEffectCounter: minRevertibleSideEffectCounter,
391
- scopes: effectiveScopes,
521
+ scopes,
392
522
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
393
523
  // contract would perform, including setting senderForTags.
394
524
  senderForTags: from,
395
525
  simulator,
396
- messageContextService: this.stateMachine.messageContextService,
526
+ txResolver: this.stateMachine.txResolver,
527
+ l2TipsStore: this.stateMachine.l2TipsProvider,
528
+ hooks: composeHooks({
529
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
530
+ isStaticCall ? 'private view' : 'private',
531
+ authorizedUtilityCallTargets,
532
+ ),
533
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
534
+ }),
535
+ transientArrayService,
397
536
  });
398
537
 
399
538
  // 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.
@@ -421,7 +560,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
421
560
  }),
422
561
  );
423
562
 
424
- noteCache.finish();
425
563
  const nonceGenerator = noteCache.getNonceGenerator();
426
564
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
427
565
  } catch (err) {
@@ -433,7 +571,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
433
571
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
434
572
  const { publicInputs } = await generateSimulatedProvingResult(
435
573
  result,
436
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
574
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
437
575
  this.stateMachine.node,
438
576
  minRevertibleSideEffectCounter,
439
577
  );
@@ -492,7 +630,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
492
630
  } else if (!processedTx.revertCode.isOK()) {
493
631
  if (processedTx.revertReason) {
494
632
  try {
495
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
633
+ await enrichPublicSimulationError(
634
+ processedTx.revertReason,
635
+ this.contractStore,
636
+ this.stateMachine.contractClassService,
637
+ await this.stateMachine.anchorBlockStore.getBlockHeader(),
638
+ this.logger,
639
+ );
496
640
  // eslint-disable-next-line no-empty
497
641
  } catch {}
498
642
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -501,11 +645,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
501
645
  }
502
646
  }
503
647
 
648
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
649
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
650
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
651
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
652
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
653
+
504
654
  if (isStaticCall) {
505
655
  await checkpoint!.revert();
506
656
 
507
657
  await forkedWorldTrees.close();
508
- return executionResult.returnValues ?? [];
658
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
509
659
  }
510
660
 
511
661
  const txEffect = TxEffect.empty();
@@ -527,31 +677,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
527
677
 
528
678
  await forkedWorldTrees.close();
529
679
 
530
- return executionResult.returnValues ?? [];
680
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
531
681
  }
532
682
 
533
683
  async publicCallNewFlow(
534
- from: AztecAddress,
684
+ from: AztecAddress | undefined,
535
685
  targetContractAddress: AztecAddress,
536
686
  calldata: Fr[],
537
687
  isStaticCall: boolean,
688
+ gasSettings: GasSettings,
538
689
  ) {
690
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
691
+ const anchoredContractData = new AnchoredContractData(
692
+ this.contractStore,
693
+ this.stateMachine.contractClassService,
694
+ anchorBlockHeader,
695
+ );
696
+
539
697
  this.logger.verbose(
540
- `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
698
+ `Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
541
699
  );
542
700
 
543
701
  const blockNumber = await this.getNextBlockNumber();
544
702
 
545
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
546
-
547
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
548
-
549
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
550
-
551
703
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
552
704
 
553
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
554
-
555
705
  const calldataHash = await computeCalldataHash(calldata);
556
706
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
557
707
 
@@ -599,7 +749,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
599
749
  // may require producing reverts.
600
750
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
601
751
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
602
- from,
752
+ from ?? AztecAddress.NULL_MSG_SENDER,
603
753
  targetContractAddress,
604
754
  isStaticCall,
605
755
  calldataHash,
@@ -644,7 +794,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
644
794
  } else if (!processedTx.revertCode.isOK()) {
645
795
  if (processedTx.revertReason) {
646
796
  try {
647
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
797
+ await enrichPublicSimulationError(
798
+ processedTx.revertReason,
799
+ this.contractStore,
800
+ this.stateMachine.contractClassService,
801
+ anchorBlockHeader,
802
+ this.logger,
803
+ );
648
804
  // eslint-disable-next-line no-empty
649
805
  } catch {}
650
806
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -686,28 +842,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
686
842
  }
687
843
 
688
844
  async executeUtilityFunction(
845
+ from: AztecAddress | undefined,
689
846
  targetContractAddress: AztecAddress,
690
847
  functionSelector: FunctionSelector,
691
848
  args: Fr[],
692
849
  jobId: string,
850
+ authorizedUtilityCallTargets: AztecAddress[],
693
851
  ) {
694
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
852
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
853
+ const anchoredContractData = new AnchoredContractData(
854
+ this.contractStore,
855
+ this.stateMachine.contractClassService,
856
+ blockHeader,
857
+ );
858
+
859
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
695
860
  if (!artifact) {
696
861
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
697
862
  }
698
863
 
699
864
  // Sync notes before executing utility function to discover notes from previous transactions
700
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
701
- await this.stateMachine.contractSyncService.ensureContractSynced(
702
- targetContractAddress,
703
- functionSelector,
704
- async (call, execScopes) => {
705
- await this.executeUtilityCall(call, execScopes, jobId);
865
+ await this.stateMachine.contractSyncService.ensureContractSynced({
866
+ contract: targetContractAddress,
867
+ functionToInvokeAfterSync: functionSelector,
868
+ utilityExecutor: async (call, execScopes) => {
869
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
706
870
  },
707
- blockHeader,
871
+ anchorBlockHeader: blockHeader,
708
872
  jobId,
709
- await this.keyStore.getAccounts(),
710
- );
873
+ scopes: await this.keyStore.getAccounts(),
874
+ triggeredBy: undefined,
875
+ });
711
876
 
712
877
  const call = FunctionCall.from({
713
878
  name: artifact.name,
@@ -720,11 +885,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
720
885
  returnTypes: [],
721
886
  });
722
887
 
723
- return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId);
888
+ return this.executeUtilityCall(call, {
889
+ from,
890
+ scopes: await this.keyStore.getAccounts(),
891
+ jobId,
892
+ authorizedUtilityCallTargets,
893
+ });
724
894
  }
725
895
 
726
- private async executeUtilityCall(call: FunctionCall, scopes: AztecAddress[], jobId: string): Promise<Fr[]> {
727
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
896
+ private async executeUtilityCall(
897
+ call: FunctionCall,
898
+ {
899
+ from = AztecAddress.NULL_MSG_SENDER,
900
+ scopes,
901
+ jobId,
902
+ authorizedUtilityCallTargets = [],
903
+ }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
904
+ ): Promise<Fr[]> {
905
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
906
+ const anchoredContractData = new AnchoredContractData(
907
+ this.contractStore,
908
+ this.stateMachine.contractClassService,
909
+ anchorBlockHeader,
910
+ );
911
+
912
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
913
+ if (!entryPointArtifact) {
914
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
915
+ }
728
916
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
729
917
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
730
918
  }
@@ -735,28 +923,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
735
923
  });
736
924
 
737
925
  try {
738
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
926
+ const simulator = new WASMSimulator();
927
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
928
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId, authorizedUtilityCallTargets });
929
+ };
739
930
  const oracle = new UtilityExecutionOracle({
740
- contractAddress: call.to,
931
+ callContext: CallContext.from({
932
+ msgSender: from,
933
+ contractAddress: call.to,
934
+ functionSelector: call.selector,
935
+ isStaticCall: true,
936
+ }),
741
937
  authWitnesses: [],
742
938
  capsules: [],
743
939
  anchorBlockHeader,
744
- contractStore: this.contractStore,
940
+ anchoredContractData,
745
941
  noteStore: this.noteStore,
746
942
  keyStore: this.keyStore,
747
943
  addressStore: this.addressStore,
748
944
  aztecNode: this.stateMachine.node,
749
945
  recipientTaggingStore: this.recipientTaggingStore,
750
- senderAddressBookStore: this.senderAddressBookStore,
946
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
751
947
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
948
+ factService: new FactService(this.factStore, scopes),
752
949
  privateEventStore: this.privateEventStore,
753
- messageContextService: this.stateMachine.messageContextService,
754
- contractSyncService: this.contractSyncService,
950
+ txResolver: this.stateMachine.txResolver,
951
+ contractSyncService: this.stateMachine.contractSyncService,
952
+ l2TipsStore: this.stateMachine.l2TipsProvider,
755
953
  jobId,
756
954
  scopes,
955
+ simulator,
956
+ utilityExecutor,
957
+ hooks: composeHooks({
958
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
959
+ }),
960
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
961
+ transientArrayService: new TransientArrayService(),
757
962
  });
758
- const acirExecutionResult = await new WASMSimulator()
759
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
963
+ const acirExecutionResult = await simulator
964
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
760
965
  .catch((err: Error) => {
761
966
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
762
967
  throw new ExecutionError(
@@ -777,13 +982,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
777
982
  }
778
983
  }
779
984
 
780
- close(): [bigint, Map<string, AuthWitness>] {
985
+ close(): {
986
+ nextBlockTimestamp: bigint;
987
+ authwits: Map<string, AuthWitness>;
988
+ taggingSecretStrategies: TXETaggingSecretStrategies;
989
+ authorizeAllUtilityCallTargets: boolean;
990
+ } {
781
991
  this.logger.debug('Exiting Top Level Context');
782
- return [this.nextBlockTimestamp, this.authwits];
992
+ return {
993
+ nextBlockTimestamp: this.nextBlockTimestamp,
994
+ authwits: this.authwits,
995
+ taggingSecretStrategies: this.taggingSecretStrategies,
996
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
997
+ };
783
998
  }
784
999
 
785
1000
  private async getLastBlockNumber(): Promise<BlockNumber> {
786
- const header = await this.stateMachine.node.getBlockHeader('latest');
787
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
1001
+ const block = await this.stateMachine.node.getBlock('latest');
1002
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
1003
+ }
1004
+
1005
+ private buildAuthorizeUtilityCallHook(
1006
+ callerContext: 'private' | 'private view' | 'utility',
1007
+ authorizedTargets: AztecAddress[],
1008
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
1009
+ if (this.authorizeAllUtilityCallTargets) {
1010
+ return authorizeAllUtilityCallsHook;
1011
+ }
1012
+ if (authorizedTargets.length === 0) {
1013
+ return undefined;
1014
+ }
1015
+ return req =>
1016
+ Promise.resolve({
1017
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
1018
+ });
788
1019
  }
789
1020
  }
1021
+
1022
+ /**
1023
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
1024
+ *
1025
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
1026
+ */
1027
+ export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
1028
+ Promise.resolve({ authorized: true });