@aztec/txe 0.0.1-commit.b6e433891 → 0.0.1-commit.b8a057fa

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