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

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-6AVNR3XX.js +304 -0
  28. package/dest/chunk-6AVNR3XX.js.map +7 -0
  29. package/dest/chunk-CJEH2W44.js +260 -0
  30. package/dest/chunk-CJEH2W44.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 +529 -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 -647
  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 +12 -9
  88. package/dest/state_machine/index.d.ts.map +1 -1
  89. package/dest/state_machine/index.js +51 -15
  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 +7 -4
  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 +321 -113
  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 +864 -941
  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 -35
  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 +543 -90
  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 -4
  154. package/src/worker.ts +98 -0
  155. package/dest/util/encoding.d.ts +0 -788
  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,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';
@@ -48,10 +53,10 @@ import {
48
53
  witnessMapToFields,
49
54
  } from '@aztec/simulator/client';
50
55
  import {
51
- CppPublicTxSimulator,
52
56
  GuardedMerkleTreeOperations,
53
57
  PublicContractsDB,
54
58
  PublicProcessor,
59
+ PublicTxSimulator,
55
60
  } from '@aztec/simulator/server';
56
61
  import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
57
62
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
@@ -66,6 +71,9 @@ 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 { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
69
77
  import { ChonkProof } from '@aztec/stdlib/proofs';
70
78
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
71
79
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -82,13 +90,14 @@ import {
82
90
  collectNested,
83
91
  } from '@aztec/stdlib/tx';
84
92
  import type { UInt64 } from '@aztec/stdlib/types';
85
- import { ForkCheckpoint } from '@aztec/world-state';
93
+ import { ForkCheckpoint } from '@aztec/world-state/native';
86
94
 
87
- import { DEFAULT_ADDRESS } from '../constants.js';
95
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
88
96
  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
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';
92
101
  import type { ITxeExecutionOracle } from './interfaces.js';
93
102
 
94
103
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -106,29 +115,41 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
106
115
  private accountStore: TXEAccountStore,
107
116
  private senderTaggingStore: SenderTaggingStore,
108
117
  private recipientTaggingStore: RecipientTaggingStore,
109
- private senderAddressBookStore: SenderAddressBookStore,
118
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
110
119
  private capsuleStore: CapsuleStore,
120
+ private factStore: FactStore,
111
121
  private privateEventStore: PrivateEventStore,
112
122
  private nextBlockTimestamp: bigint,
113
123
  private version: Fr,
114
124
  private chainId: Fr,
115
125
  private authwits: Map<string, AuthWitness>,
116
- private readonly contractSyncService: ContractSyncService,
126
+ private taggingSecretStrategy: TaggingSecretStrategy | undefined,
127
+ private readonly artifactResolver: TXEArtifactResolver,
128
+ private readonly rootPath: string,
129
+ private readonly packageName: string,
117
130
  ) {
118
131
  this.logger = createLogger('txe:top_level_context');
119
132
  this.logger.debug('Entering Top Level Context');
120
133
  }
121
134
 
122
- assertCompatibleOracleVersion(version: number): void {
123
- 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) {
124
139
  const hint =
125
- version > ORACLE_VERSION
140
+ major > ORACLE_VERSION_MAJOR
126
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.'
127
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.';
128
143
  throw new Error(
129
- `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${ORACLE_VERSION}, got ${version})`,
144
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
130
145
  );
131
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;
132
153
  }
133
154
 
134
155
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
@@ -138,7 +159,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
138
159
  }
139
160
 
140
161
  // 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> {
162
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
142
163
  if (!LogLevels[level]) {
143
164
  throw new Error(`Invalid log level: ${level}`);
144
165
  }
@@ -161,12 +182,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
161
182
  }
162
183
 
163
184
  async getLastBlockTimestamp() {
164
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
185
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
165
186
  }
166
187
 
167
- async getLastTxEffects() {
188
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
168
189
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
169
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
190
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
170
191
 
171
192
  if (block!.body.txEffects.length != 1) {
172
193
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -175,7 +196,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
175
196
 
176
197
  const txEffects = block!.body.txEffects[0];
177
198
 
178
- 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
+ };
179
210
  }
180
211
 
181
212
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
@@ -189,7 +220,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
189
220
  contractAddress,
190
221
  null,
191
222
  async (call, execScopes) => {
192
- await this.executeUtilityCall(call, execScopes, jobId);
223
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
193
224
  },
194
225
  blockHeader,
195
226
  jobId,
@@ -198,7 +229,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
198
229
  }
199
230
 
200
231
  async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
201
- return (
232
+ const events = (
202
233
  await this.privateEventStore.getPrivateEvents(selector, {
203
234
  contractAddress,
204
235
  scopes: [scope],
@@ -206,6 +237,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
206
237
  toBlock: (await this.getLastBlockNumber()) + 1,
207
238
  })
208
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;
209
249
  }
210
250
 
211
251
  async advanceBlocksBy(blocks: number) {
@@ -221,34 +261,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
221
261
  this.nextBlockTimestamp += duration;
222
262
  }
223
263
 
224
- 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
+
225
287
  // Emit deployment nullifier
226
288
  await this.mineBlock({
227
- nullifiers: [
228
- await siloNullifier(
229
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
230
- instance.address.toField(),
231
- ),
232
- ],
289
+ nullifiers: [await this.deploymentNullifier(instance.address)],
233
290
  });
234
291
 
235
292
  if (!secret.equals(Fr.ZERO)) {
236
- await this.addAccount(artifact, instance, secret);
293
+ await this.registerContractAndAddAccount(artifact, instance, secret);
237
294
  } else {
238
295
  await this.contractStore.addContractInstance(instance);
239
296
  await this.contractStore.addContractArtifact(artifact);
240
297
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
241
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);
242
315
  }
243
316
 
244
- async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
317
+ private async registerContractAndAddAccount(
318
+ artifact: ContractArtifact,
319
+ instance: ContractInstanceWithAddress,
320
+ secret: Fr,
321
+ ) {
245
322
  const partialAddress = await computePartialAddress(instance);
246
323
 
247
324
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
248
325
  await this.contractStore.addContractInstance(instance);
249
326
  await this.contractStore.addContractArtifact(artifact);
250
327
 
251
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
328
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
252
329
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
253
330
  await this.addressStore.addCompleteAddress(completeAddress);
254
331
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -258,7 +335,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
258
335
 
259
336
  async createAccount(secret: Fr) {
260
337
  // This is a foot gun !
261
- const completeAddress = await this.keyStore.addAccount(secret, secret);
338
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
262
339
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
263
340
  await this.addressStore.addCompleteAddress(completeAddress);
264
341
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -268,17 +345,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
268
345
 
269
346
  async addAuthWitness(address: AztecAddress, messageHash: Fr) {
270
347
  const account = await this.accountStore.getAccount(address);
271
- 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);
272
350
 
273
351
  const schnorr = new Schnorr();
274
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
352
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
275
353
 
276
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
354
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
277
355
 
278
356
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
279
357
  }
280
358
 
281
- 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[] } = {}) {
282
384
  const blockNumber = await this.getNextBlockNumber();
283
385
 
284
386
  const txEffect = TxEffect.empty();
@@ -286,7 +388,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
286
388
  txEffect.txHash = new TxHash(new Fr(blockNumber));
287
389
 
288
390
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
289
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
391
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
290
392
 
291
393
  const globals = makeGlobalVariables(undefined, {
292
394
  blockNumber,
@@ -300,23 +402,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
300
402
 
301
403
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
302
404
 
303
- await this.stateMachine.handleL2Block(block);
405
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
304
406
  }
305
407
 
306
408
  async privateCallNewFlow(
307
- from: AztecAddress,
409
+ from: AztecAddress | undefined,
308
410
  targetContractAddress: AztecAddress = AztecAddress.zero(),
309
411
  functionSelector: FunctionSelector = FunctionSelector.empty(),
310
412
  args: Fr[],
311
413
  argsHash: Fr = Fr.zero(),
312
414
  isStaticCall: boolean = false,
415
+ additionalScopes: AztecAddress[] = [],
313
416
  jobId: string,
417
+ authorizedUtilityCallTargets: AztecAddress[],
418
+ gasSettings: GasSettings,
314
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
+
315
427
  this.logger.verbose(
316
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
428
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
317
429
  );
318
430
 
319
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
431
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
320
432
  if (!artifact) {
321
433
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
322
434
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -324,32 +436,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
324
436
  throw new Error(message);
325
437
  }
326
438
 
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];
439
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
330
440
 
331
441
  // 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);
442
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
443
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
334
444
  };
335
445
 
336
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
337
446
  await this.stateMachine.contractSyncService.ensureContractSynced(
338
447
  targetContractAddress,
339
448
  functionSelector,
340
449
  utilityExecutor,
341
450
  blockHeader,
342
451
  jobId,
343
- effectiveScopes,
452
+ scopes,
344
453
  );
345
454
 
346
455
  const blockNumber = await this.getNextBlockNumber();
347
456
 
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());
457
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
458
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
353
459
 
354
460
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
355
461
 
@@ -364,9 +470,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
364
470
 
365
471
  const simulator = new WASMSimulator();
366
472
 
473
+ const transientArrayService = new TransientArrayService();
474
+ const taggingSecretStrategy = this.taggingSecretStrategy;
367
475
  const privateExecutionOracle = new PrivateExecutionOracle({
368
476
  argsHash,
369
477
  txContext,
478
+ txRequestSalt: Fr.ZERO,
370
479
  callContext,
371
480
  anchorBlockHeader: blockHeader,
372
481
  utilityExecutor,
@@ -375,26 +484,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
375
484
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
376
485
  noteCache,
377
486
  taggingIndexCache,
378
- contractStore: this.contractStore,
487
+ anchoredContractData,
379
488
  noteStore: this.noteStore,
380
489
  keyStore: this.keyStore,
381
490
  addressStore: this.addressStore,
382
491
  aztecNode: this.stateMachine.node,
383
492
  senderTaggingStore: this.senderTaggingStore,
384
493
  recipientTaggingStore: this.recipientTaggingStore,
385
- senderAddressBookStore: this.senderAddressBookStore,
386
- capsuleService: new CapsuleService(this.capsuleStore, effectiveScopes),
494
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
495
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
496
+ factService: new FactService(this.factStore, scopes),
387
497
  privateEventStore: this.privateEventStore,
388
498
  contractSyncService: this.stateMachine.contractSyncService,
389
499
  jobId,
390
500
  totalPublicCalldataCount: 0,
391
501
  sideEffectCounter: minRevertibleSideEffectCounter,
392
- scopes: effectiveScopes,
502
+ scopes,
393
503
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
394
504
  // contract would perform, including setting senderForTags.
395
505
  senderForTags: from,
396
506
  simulator,
397
- 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,
398
519
  });
399
520
 
400
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.
@@ -422,7 +543,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
422
543
  }),
423
544
  );
424
545
 
425
- noteCache.finish();
426
546
  const nonceGenerator = noteCache.getNonceGenerator();
427
547
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
428
548
  } catch (err) {
@@ -434,7 +554,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
434
554
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
435
555
  const { publicInputs } = await generateSimulatedProvingResult(
436
556
  result,
437
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
557
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
438
558
  this.stateMachine.node,
439
559
  minRevertibleSideEffectCounter,
440
560
  );
@@ -446,7 +566,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
446
566
  globals.version = this.version;
447
567
  globals.gasFees = GasFees.empty();
448
568
 
449
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
569
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
450
570
 
451
571
  const bindings = this.logger.getBindings();
452
572
  const contractsDB = new PublicContractsDB(
@@ -461,11 +581,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
461
581
  collectStatistics: false,
462
582
  collectCallMetadata: true,
463
583
  });
584
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
585
+ const forkId = forkedWorldTrees.getRevision().forkId;
464
586
  const processor = new PublicProcessor(
465
587
  globals,
466
588
  guardedMerkleTrees,
467
589
  contractsDB,
468
- 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
+ ),
469
598
  new TestDateProvider(),
470
599
  undefined,
471
600
  createLogger('simulator:public-processor', bindings),
@@ -493,7 +622,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
493
622
  } else if (!processedTx.revertCode.isOK()) {
494
623
  if (processedTx.revertReason) {
495
624
  try {
496
- 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
+ );
497
632
  // eslint-disable-next-line no-empty
498
633
  } catch {}
499
634
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -502,11 +637,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
502
637
  }
503
638
  }
504
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
+
505
646
  if (isStaticCall) {
506
647
  await checkpoint!.revert();
507
-
508
- await forkedWorldTrees.close();
509
- return executionResult.returnValues ?? [];
648
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
510
649
  }
511
650
 
512
651
  const txEffect = TxEffect.empty();
@@ -526,33 +665,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
526
665
 
527
666
  await this.stateMachine.handleL2Block(l2Block);
528
667
 
529
- await forkedWorldTrees.close();
530
-
531
- return executionResult.returnValues ?? [];
668
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
532
669
  }
533
670
 
534
671
  async publicCallNewFlow(
535
- from: AztecAddress,
672
+ from: AztecAddress | undefined,
536
673
  targetContractAddress: AztecAddress,
537
674
  calldata: Fr[],
538
675
  isStaticCall: boolean,
676
+ gasSettings: GasSettings,
539
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
+
540
685
  this.logger.verbose(
541
- `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}`,
542
687
  );
543
688
 
544
689
  const blockNumber = await this.getNextBlockNumber();
545
690
 
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
691
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
553
692
 
554
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
555
-
556
693
  const calldataHash = await computeCalldataHash(calldata);
557
694
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
558
695
 
@@ -563,7 +700,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
563
700
  globals.version = this.version;
564
701
  globals.gasFees = GasFees.empty();
565
702
 
566
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
703
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
567
704
 
568
705
  const bindings2 = this.logger.getBindings();
569
706
  const contractsDB = new PublicContractsDB(
@@ -578,7 +715,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
578
715
  collectStatistics: false,
579
716
  collectCallMetadata: true,
580
717
  });
581
- 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
+ );
582
728
  const processor = new PublicProcessor(
583
729
  globals,
584
730
  guardedMerkleTrees,
@@ -600,7 +746,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
600
746
  // may require producing reverts.
601
747
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
602
748
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
603
- from,
749
+ from ?? AztecAddress.NULL_MSG_SENDER,
604
750
  targetContractAddress,
605
751
  isStaticCall,
606
752
  calldataHash,
@@ -645,7 +791,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
645
791
  } else if (!processedTx.revertCode.isOK()) {
646
792
  if (processedTx.revertReason) {
647
793
  try {
648
- 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
+ );
649
801
  // eslint-disable-next-line no-empty
650
802
  } catch {}
651
803
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -658,9 +810,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
658
810
 
659
811
  if (isStaticCall) {
660
812
  await checkpoint!.revert();
661
-
662
- await forkedWorldTrees.close();
663
-
664
813
  return returnValues ?? [];
665
814
  }
666
815
 
@@ -681,33 +830,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
681
830
 
682
831
  await this.stateMachine.handleL2Block(l2Block);
683
832
 
684
- await forkedWorldTrees.close();
685
-
686
833
  return returnValues ?? [];
687
834
  }
688
835
 
689
836
  async executeUtilityFunction(
837
+ from: AztecAddress | undefined,
690
838
  targetContractAddress: AztecAddress,
691
839
  functionSelector: FunctionSelector,
692
840
  args: Fr[],
693
841
  jobId: string,
842
+ authorizedUtilityCallTargets: AztecAddress[],
694
843
  ) {
695
- 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);
696
852
  if (!artifact) {
697
853
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
698
854
  }
699
855
 
700
856
  // Sync notes before executing utility function to discover notes from previous transactions
701
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
702
857
  await this.stateMachine.contractSyncService.ensureContractSynced(
703
858
  targetContractAddress,
704
859
  functionSelector,
705
860
  async (call, execScopes) => {
706
- await this.executeUtilityCall(call, execScopes, jobId);
861
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
707
862
  },
708
863
  blockHeader,
709
864
  jobId,
710
- 'ALL_SCOPES',
865
+ await this.keyStore.getAccounts(),
711
866
  );
712
867
 
713
868
  const call = FunctionCall.from({
@@ -721,11 +876,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
721
876
  returnTypes: [],
722
877
  });
723
878
 
724
- 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
+ });
725
885
  }
726
886
 
727
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
728
- 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
+ }
729
907
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
730
908
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
731
909
  }
@@ -736,28 +914,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
736
914
  });
737
915
 
738
916
  try {
739
- 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
+ };
740
921
  const oracle = new UtilityExecutionOracle({
741
- contractAddress: call.to,
922
+ callContext: CallContext.from({
923
+ msgSender: from,
924
+ contractAddress: call.to,
925
+ functionSelector: call.selector,
926
+ isStaticCall: true,
927
+ }),
742
928
  authWitnesses: [],
743
929
  capsules: [],
744
930
  anchorBlockHeader,
745
- contractStore: this.contractStore,
931
+ anchoredContractData,
746
932
  noteStore: this.noteStore,
747
933
  keyStore: this.keyStore,
748
934
  addressStore: this.addressStore,
749
935
  aztecNode: this.stateMachine.node,
750
936
  recipientTaggingStore: this.recipientTaggingStore,
751
- senderAddressBookStore: this.senderAddressBookStore,
937
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
752
938
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
939
+ factService: new FactService(this.factStore, scopes),
753
940
  privateEventStore: this.privateEventStore,
754
- messageContextService: this.stateMachine.messageContextService,
755
- contractSyncService: this.contractSyncService,
941
+ txResolver: this.stateMachine.txResolver,
942
+ contractSyncService: this.stateMachine.contractSyncService,
943
+ l2TipsStore: this.stateMachine.l2TipsProvider,
756
944
  jobId,
757
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(),
758
953
  });
759
- const acirExecutionResult = await new WASMSimulator()
760
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
954
+ const acirExecutionResult = await simulator
955
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
761
956
  .catch((err: Error) => {
762
957
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
763
958
  throw new ExecutionError(
@@ -778,13 +973,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
778
973
  }
779
974
  }
780
975
 
781
- close(): [bigint, Map<string, AuthWitness>] {
976
+ close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
782
977
  this.logger.debug('Exiting Top Level Context');
783
- return [this.nextBlockTimestamp, this.authwits];
978
+ return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
784
979
  }
785
980
 
786
981
  private async getLastBlockNumber(): Promise<BlockNumber> {
787
- const header = await this.stateMachine.node.getBlockHeader('latest');
788
- 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
+ });
789
997
  }
790
998
  }