@aztec/txe 0.0.1-commit.a89ec08 → 0.0.1-commit.aa0c64f

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