@aztec/txe 0.0.1-commit.9ef841308 → 0.0.1-commit.a5db02d

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