@aztec/txe 0.0.1-commit.96dac018d → 0.0.1-commit.9a89641

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-PVNCKGG7.js +3 -0
  4. package/dest/ContractClassRegistry-PVNCKGG7.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-WLOZKTR6.js +3 -0
  6. package/dest/ContractInstanceRegistry-WLOZKTR6.js.map +7 -0
  7. package/dest/FeeJuice-MAQJU53K.js +3 -0
  8. package/dest/FeeJuice-MAQJU53K.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-ADD65DYA.js +3 -0
  14. package/dest/SchnorrAccount-ADD65DYA.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-TWGKRUSY.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 +22 -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-RVEPNDEP.js +304 -0
  28. package/dest/chunk-RVEPNDEP.js.map +7 -0
  29. package/dest/chunk-XWIMXLKD.js +258 -0
  30. package/dest/chunk-XWIMXLKD.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 -188
  40. package/dest/metafile.json +38833 -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 +68 -30
  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 +38 -14
  59. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  60. package/dest/oracle/txe_oracle_public_context.js +61 -13
  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 +68 -27
  65. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  66. package/dest/oracle/txe_oracle_top_level_context.js +571 -312
  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 +116 -228
  77. package/dest/rpc_translator.d.ts.map +1 -1
  78. package/dest/rpc_translator.js +909 -636
  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 +6 -5
  82. package/dest/state_machine/archiver.d.ts.map +1 -1
  83. package/dest/state_machine/archiver.js +28 -20
  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 -5
  91. package/dest/state_machine/index.d.ts.map +1 -1
  92. package/dest/state_machine/index.js +50 -10
  93. package/dest/state_machine/mock_epoch_cache.d.ts +17 -3
  94. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  95. package/dest/state_machine/mock_epoch_cache.js +32 -2
  96. package/dest/state_machine/synchronizer.d.ts +14 -6
  97. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  98. package/dest/state_machine/synchronizer.js +22 -9
  99. package/dest/txe_session.d.ts +92 -19
  100. package/dest/txe_session.d.ts.map +1 -1
  101. package/dest/txe_session.js +325 -61
  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 +194 -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 +31 -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 -224
  133. package/src/msgpackr_fr_extension.ts +23 -0
  134. package/src/oracle/interfaces.ts +70 -35
  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 +74 -12
  140. package/src/oracle/txe_oracle_registry.ts +556 -0
  141. package/src/oracle/txe_oracle_top_level_context.ts +380 -128
  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 +1126 -1021
  146. package/src/state_machine/archiver.ts +41 -20
  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 +63 -28
  150. package/src/state_machine/mock_epoch_cache.ts +42 -3
  151. package/src/state_machine/synchronizer.ts +31 -10
  152. package/src/txe_session.ts +564 -75
  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 -720
  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,38 +1,45 @@
1
1
  import {
2
2
  CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
3
- DEFAULT_DA_GAS_LIMIT,
4
- DEFAULT_L2_GAS_LIMIT,
5
- DEFAULT_TEARDOWN_DA_GAS_LIMIT,
6
- DEFAULT_TEARDOWN_L2_GAS_LIMIT,
3
+ MAX_PRIVATE_LOGS_PER_TX,
7
4
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
8
5
  } from '@aztec/constants';
9
6
  import { BlockNumber } from '@aztec/foundation/branded-types';
10
7
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
11
8
  import { Fr } from '@aztec/foundation/curves/bn254';
9
+ import type { EthAddress } from '@aztec/foundation/eth-address';
12
10
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
11
  import { TestDateProvider } from '@aztec/foundation/timer';
14
12
  import type { KeyStore } from '@aztec/key-store';
15
- import type { AccessScopes } from '@aztec/pxe/client/lazy';
16
13
  import {
17
14
  AddressStore,
15
+ AnchoredContractData,
16
+ CapsuleService,
18
17
  CapsuleStore,
19
18
  type ContractStore,
19
+ type ExecutionHooks,
20
+ FactService,
21
+ FactStore,
20
22
  NoteStore,
21
- ORACLE_VERSION,
23
+ ORACLE_VERSION_MAJOR,
22
24
  PrivateEventStore,
23
25
  RecipientTaggingStore,
24
- SenderAddressBookStore,
25
26
  SenderTaggingStore,
27
+ TaggingSecretSourcesStore,
28
+ type TaggingSecretStrategy,
29
+ composeHooks,
26
30
  enrichPublicSimulationError,
27
31
  } from '@aztec/pxe/server';
28
32
  import {
33
+ CONTRACT_INSTANCE,
29
34
  ExecutionNoteCache,
30
35
  ExecutionTaggingIndexCache,
31
36
  HashedValuesCache,
32
37
  type IMiscOracle,
33
- Oracle,
38
+ type Option,
34
39
  PrivateExecutionOracle,
40
+ TransientArrayService,
35
41
  UtilityExecutionOracle,
42
+ buildACIRCallback,
36
43
  executePrivateFunction,
37
44
  generateSimulatedProvingResult,
38
45
  } from '@aztec/pxe/simulator';
@@ -46,10 +53,10 @@ import {
46
53
  witnessMapToFields,
47
54
  } from '@aztec/simulator/client';
48
55
  import {
49
- CppPublicTxSimulator,
50
56
  GuardedMerkleTreeOperations,
51
57
  PublicContractsDB,
52
58
  PublicProcessor,
59
+ PublicTxSimulator,
53
60
  } from '@aztec/simulator/server';
54
61
  import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
55
62
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
@@ -64,6 +71,10 @@ import {
64
71
  PrivateToPublicAccumulatedData,
65
72
  PublicCallRequest,
66
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';
67
78
  import { ChonkProof } from '@aztec/stdlib/proofs';
68
79
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
69
80
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -80,14 +91,16 @@ import {
80
91
  collectNested,
81
92
  } from '@aztec/stdlib/tx';
82
93
  import type { UInt64 } from '@aztec/stdlib/types';
83
- import { ForkCheckpoint } from '@aztec/world-state';
94
+ import { ForkCheckpoint } from '@aztec/world-state/native';
84
95
 
85
- import { DEFAULT_ADDRESS } from '../constants.js';
96
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
86
97
  import type { TXEStateMachine } from '../state_machine/index.js';
87
- import type { TXEAccountStore } from '../util/txe_account_store.js';
88
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
89
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';
90
102
  import type { ITxeExecutionOracle } from './interfaces.js';
103
+ import { type TXETaggingSecretStrategies, makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
91
104
 
92
105
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
93
106
  isMisc = true as const;
@@ -104,34 +117,52 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
104
117
  private accountStore: TXEAccountStore,
105
118
  private senderTaggingStore: SenderTaggingStore,
106
119
  private recipientTaggingStore: RecipientTaggingStore,
107
- private senderAddressBookStore: SenderAddressBookStore,
120
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
108
121
  private capsuleStore: CapsuleStore,
122
+ private factStore: FactStore,
109
123
  private privateEventStore: PrivateEventStore,
110
124
  private nextBlockTimestamp: bigint,
111
125
  private version: Fr,
112
126
  private chainId: Fr,
113
127
  private authwits: Map<string, AuthWitness>,
128
+ private taggingSecretStrategies: TXETaggingSecretStrategies,
129
+ private authorizeAllUtilityCallTargets: boolean,
130
+ private readonly artifactResolver: TXEArtifactResolver,
131
+ private readonly rootPath: string,
132
+ private readonly packageName: string,
114
133
  ) {
115
134
  this.logger = createLogger('txe:top_level_context');
116
135
  this.logger.debug('Entering Top Level Context');
117
136
  }
118
137
 
119
- utilityAssertCompatibleOracleVersion(version: number): void {
120
- if (version !== ORACLE_VERSION) {
138
+ private contractOracleVersion: { major: number; minor: number } | undefined;
139
+
140
+ assertCompatibleOracleVersion(major: number, minor: number): void {
141
+ if (major !== ORACLE_VERSION_MAJOR) {
142
+ const hint =
143
+ major > ORACLE_VERSION_MAJOR
144
+ ? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.'
145
+ : 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
121
146
  throw new Error(
122
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
147
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
123
148
  );
124
149
  }
150
+ this.contractOracleVersion = { major, minor };
151
+ }
152
+
153
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
154
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
155
+ return this.contractOracleVersion;
125
156
  }
126
157
 
127
158
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
128
159
  // setup.
129
- utilityGetRandomField(): Fr {
160
+ getRandomField(): Fr {
130
161
  return Fr.random();
131
162
  }
132
163
 
133
164
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
134
- utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
165
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
135
166
  if (!LogLevels[level]) {
136
167
  throw new Error(`Invalid log level: ${level}`);
137
168
  }
@@ -141,25 +172,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
141
172
  return Promise.resolve();
142
173
  }
143
174
 
144
- txeGetDefaultAddress(): AztecAddress {
175
+ getDefaultAddress(): AztecAddress {
145
176
  return DEFAULT_ADDRESS;
146
177
  }
147
178
 
148
- async txeGetNextBlockNumber(): Promise<BlockNumber> {
179
+ async getNextBlockNumber(): Promise<BlockNumber> {
149
180
  return BlockNumber((await this.getLastBlockNumber()) + 1);
150
181
  }
151
182
 
152
- txeGetNextBlockTimestamp(): Promise<bigint> {
183
+ getNextBlockTimestamp(): Promise<bigint> {
153
184
  return Promise.resolve(this.nextBlockTimestamp);
154
185
  }
155
186
 
156
- async txeGetLastBlockTimestamp() {
157
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
187
+ async getLastBlockTimestamp() {
188
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
158
189
  }
159
190
 
160
- async txeGetLastTxEffects() {
191
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
161
192
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
162
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
193
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
163
194
 
164
195
  if (block!.body.txEffects.length != 1) {
165
196
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -168,12 +199,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
168
199
 
169
200
  const txEffects = block!.body.txEffects[0];
170
201
 
171
- 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
+ };
172
213
  }
173
214
 
174
215
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
175
216
  if (contractAddress.equals(DEFAULT_ADDRESS)) {
176
- this.logger.debug(`Skipping sync in txeGetPrivateEvents because the events correspond to the default address.`);
217
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
177
218
  return;
178
219
  }
179
220
 
@@ -182,7 +223,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
182
223
  contractAddress,
183
224
  null,
184
225
  async (call, execScopes) => {
185
- await this.executeUtilityCall(call, execScopes, jobId);
226
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
186
227
  },
187
228
  blockHeader,
188
229
  jobId,
@@ -190,8 +231,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
190
231
  );
191
232
  }
192
233
 
193
- async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
194
- return (
234
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
235
+ const events = (
195
236
  await this.privateEventStore.getPrivateEvents(selector, {
196
237
  contractAddress,
197
238
  scopes: [scope],
@@ -199,9 +240,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
199
240
  toBlock: (await this.getLastBlockNumber()) + 1,
200
241
  })
201
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;
202
252
  }
203
253
 
204
- async txeAdvanceBlocksBy(blocks: number) {
254
+ async advanceBlocksBy(blocks: number) {
205
255
  this.logger.debug(`time traveling ${blocks} blocks`);
206
256
 
207
257
  for (let i = 0; i < blocks; i++) {
@@ -209,39 +259,76 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
209
259
  }
210
260
  }
211
261
 
212
- txeAdvanceTimestampBy(duration: UInt64) {
262
+ advanceTimestampBy(duration: UInt64) {
213
263
  this.logger.debug(`time traveling ${duration} seconds`);
214
264
  this.nextBlockTimestamp += duration;
215
265
  }
216
266
 
217
- async txeDeploy(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
+
218
290
  // Emit deployment nullifier
219
291
  await this.mineBlock({
220
- nullifiers: [
221
- await siloNullifier(
222
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
223
- instance.address.toField(),
224
- ),
225
- ],
292
+ nullifiers: [await this.deploymentNullifier(instance.address)],
226
293
  });
227
294
 
228
295
  if (!secret.equals(Fr.ZERO)) {
229
- await this.txeAddAccount(artifact, instance, secret);
296
+ await this.registerContractAndAddAccount(artifact, instance, secret);
230
297
  } else {
231
298
  await this.contractStore.addContractInstance(instance);
232
299
  await this.contractStore.addContractArtifact(artifact);
233
300
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
234
301
  }
302
+
303
+ return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
304
+ }
305
+
306
+ /**
307
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
308
+ */
309
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
310
+ await this.mineBlock({
311
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
312
+ });
313
+ }
314
+
315
+ async addAccount(secret: Fr) {
316
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
317
+ return this.registerContractAndAddAccount(artifact, instance, secret);
235
318
  }
236
319
 
237
- async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
320
+ private async registerContractAndAddAccount(
321
+ artifact: ContractArtifact,
322
+ instance: ContractInstanceWithAddress,
323
+ secret: Fr,
324
+ ) {
238
325
  const partialAddress = await computePartialAddress(instance);
239
326
 
240
327
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
241
328
  await this.contractStore.addContractInstance(instance);
242
329
  await this.contractStore.addContractArtifact(artifact);
243
330
 
244
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
331
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
245
332
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
246
333
  await this.addressStore.addCompleteAddress(completeAddress);
247
334
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -249,9 +336,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
249
336
  return completeAddress;
250
337
  }
251
338
 
252
- async txeCreateAccount(secret: Fr) {
253
- // This is a foot gun !
254
- 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);
255
341
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
256
342
  await this.addressStore.addCompleteAddress(completeAddress);
257
343
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -259,27 +345,67 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
259
345
  return completeAddress;
260
346
  }
261
347
 
262
- async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
348
+ async addAuthWitness(address: AztecAddress, messageHash: Fr) {
263
349
  const account = await this.accountStore.getAccount(address);
264
- 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);
265
352
 
266
353
  const schnorr = new Schnorr();
267
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
354
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
268
355
 
269
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
356
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
270
357
 
271
358
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
272
359
  }
273
360
 
274
- async mineBlock(options: { nullifiers?: Fr[] } = {}) {
275
- const blockNumber = await this.txeGetNextBlockNumber();
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[] } = {}) {
401
+ const blockNumber = await this.getNextBlockNumber();
276
402
 
277
403
  const txEffect = TxEffect.empty();
278
404
  txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
279
405
  txEffect.txHash = new TxHash(new Fr(blockNumber));
280
406
 
281
407
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
282
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
408
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
283
409
 
284
410
  const globals = makeGlobalVariables(undefined, {
285
411
  blockNumber,
@@ -293,23 +419,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
293
419
 
294
420
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
295
421
 
296
- await this.stateMachine.handleL2Block(block);
422
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
297
423
  }
298
424
 
299
- async txePrivateCallNewFlow(
300
- from: AztecAddress,
425
+ async privateCallNewFlow(
426
+ from: AztecAddress | undefined,
301
427
  targetContractAddress: AztecAddress = AztecAddress.zero(),
302
428
  functionSelector: FunctionSelector = FunctionSelector.empty(),
303
429
  args: Fr[],
304
430
  argsHash: Fr = Fr.zero(),
305
431
  isStaticCall: boolean = false,
432
+ additionalScopes: AztecAddress[] = [],
306
433
  jobId: string,
434
+ authorizedUtilityCallTargets: AztecAddress[],
435
+ gasSettings: GasSettings,
307
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
+
308
444
  this.logger.verbose(
309
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
445
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
310
446
  );
311
447
 
312
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
448
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
313
449
  if (!artifact) {
314
450
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
315
451
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -317,32 +453,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
317
453
  throw new Error(message);
318
454
  }
319
455
 
320
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
321
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
322
- const effectiveScopes = from.isZero() ? [] : [from];
456
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
323
457
 
324
458
  // Sync notes before executing private function to discover notes from previous transactions
325
- const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
326
- await this.executeUtilityCall(call, execScopes, jobId);
459
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
460
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
327
461
  };
328
462
 
329
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
330
463
  await this.stateMachine.contractSyncService.ensureContractSynced(
331
464
  targetContractAddress,
332
465
  functionSelector,
333
466
  utilityExecutor,
334
467
  blockHeader,
335
468
  jobId,
336
- effectiveScopes,
469
+ scopes,
337
470
  );
338
471
 
339
- const blockNumber = await this.txeGetNextBlockNumber();
340
-
341
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
472
+ const blockNumber = await this.getNextBlockNumber();
342
473
 
343
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
344
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
345
- 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);
346
476
 
347
477
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
348
478
 
@@ -357,9 +487,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
357
487
 
358
488
  const simulator = new WASMSimulator();
359
489
 
490
+ const transientArrayService = new TransientArrayService();
360
491
  const privateExecutionOracle = new PrivateExecutionOracle({
361
492
  argsHash,
362
493
  txContext,
494
+ txRequestSalt: Fr.ZERO,
363
495
  callContext,
364
496
  anchorBlockHeader: blockHeader,
365
497
  utilityExecutor,
@@ -368,25 +500,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
368
500
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
369
501
  noteCache,
370
502
  taggingIndexCache,
371
- contractStore: this.contractStore,
503
+ anchoredContractData,
372
504
  noteStore: this.noteStore,
373
505
  keyStore: this.keyStore,
374
506
  addressStore: this.addressStore,
375
507
  aztecNode: this.stateMachine.node,
376
508
  senderTaggingStore: this.senderTaggingStore,
377
509
  recipientTaggingStore: this.recipientTaggingStore,
378
- senderAddressBookStore: this.senderAddressBookStore,
379
- capsuleStore: this.capsuleStore,
510
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
511
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
512
+ factService: new FactService(this.factStore, scopes),
380
513
  privateEventStore: this.privateEventStore,
381
514
  contractSyncService: this.stateMachine.contractSyncService,
382
515
  jobId,
383
516
  totalPublicCalldataCount: 0,
384
517
  sideEffectCounter: minRevertibleSideEffectCounter,
385
- scopes: effectiveScopes,
518
+ scopes,
386
519
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
387
520
  // contract would perform, including setting senderForTags.
388
521
  senderForTags: from,
389
522
  simulator,
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,
390
533
  });
391
534
 
392
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.
@@ -409,12 +552,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
409
552
  );
410
553
  const publicFunctionsCalldata = await Promise.all(
411
554
  publicCallRequests.map(async r => {
412
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
555
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
413
556
  return new HashedValues(calldata, r.calldataHash);
414
557
  }),
415
558
  );
416
559
 
417
- noteCache.finish();
418
560
  const nonceGenerator = noteCache.getNonceGenerator();
419
561
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
420
562
  } catch (err) {
@@ -426,7 +568,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
426
568
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
427
569
  const { publicInputs } = await generateSimulatedProvingResult(
428
570
  result,
429
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
571
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
430
572
  this.stateMachine.node,
431
573
  minRevertibleSideEffectCounter,
432
574
  );
@@ -438,7 +580,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
438
580
  globals.version = this.version;
439
581
  globals.gasFees = GasFees.empty();
440
582
 
441
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
583
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
442
584
 
443
585
  const bindings = this.logger.getBindings();
444
586
  const contractsDB = new PublicContractsDB(
@@ -453,11 +595,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
453
595
  collectStatistics: false,
454
596
  collectCallMetadata: true,
455
597
  });
598
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
599
+ const forkId = forkedWorldTrees.getRevision().forkId;
456
600
  const processor = new PublicProcessor(
457
601
  globals,
458
602
  guardedMerkleTrees,
459
603
  contractsDB,
460
- 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
+ ),
461
612
  new TestDateProvider(),
462
613
  undefined,
463
614
  createLogger('simulator:public-processor', bindings),
@@ -485,7 +636,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
485
636
  } else if (!processedTx.revertCode.isOK()) {
486
637
  if (processedTx.revertReason) {
487
638
  try {
488
- 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
+ );
489
646
  // eslint-disable-next-line no-empty
490
647
  } catch {}
491
648
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -494,11 +651,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
494
651
  }
495
652
  }
496
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
+
497
660
  if (isStaticCall) {
498
661
  await checkpoint!.revert();
499
-
500
- await forkedWorldTrees.close();
501
- return executionResult.returnValues ?? [];
662
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
502
663
  }
503
664
 
504
665
  const txEffect = TxEffect.empty();
@@ -518,33 +679,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
518
679
 
519
680
  await this.stateMachine.handleL2Block(l2Block);
520
681
 
521
- await forkedWorldTrees.close();
522
-
523
- return executionResult.returnValues ?? [];
682
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
524
683
  }
525
684
 
526
- async txePublicCallNewFlow(
527
- from: AztecAddress,
685
+ async publicCallNewFlow(
686
+ from: AztecAddress | undefined,
528
687
  targetContractAddress: AztecAddress,
529
688
  calldata: Fr[],
530
689
  isStaticCall: boolean,
690
+ gasSettings: GasSettings,
531
691
  ) {
532
- this.logger.verbose(
533
- `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
692
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
693
+ const anchoredContractData = new AnchoredContractData(
694
+ this.contractStore,
695
+ this.stateMachine.contractClassService,
696
+ anchorBlockHeader,
534
697
  );
535
698
 
536
- const blockNumber = await this.txeGetNextBlockNumber();
537
-
538
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
539
-
540
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
699
+ this.logger.verbose(
700
+ `Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
701
+ );
541
702
 
542
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
703
+ const blockNumber = await this.getNextBlockNumber();
543
704
 
544
705
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
545
706
 
546
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
547
-
548
707
  const calldataHash = await computeCalldataHash(calldata);
549
708
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
550
709
 
@@ -555,7 +714,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
555
714
  globals.version = this.version;
556
715
  globals.gasFees = GasFees.empty();
557
716
 
558
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
717
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
559
718
 
560
719
  const bindings2 = this.logger.getBindings();
561
720
  const contractsDB = new PublicContractsDB(
@@ -570,7 +729,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
570
729
  collectStatistics: false,
571
730
  collectCallMetadata: true,
572
731
  });
573
- 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
+ );
574
742
  const processor = new PublicProcessor(
575
743
  globals,
576
744
  guardedMerkleTrees,
@@ -592,7 +760,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
592
760
  // may require producing reverts.
593
761
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
594
762
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
595
- from,
763
+ from ?? AztecAddress.NULL_MSG_SENDER,
596
764
  targetContractAddress,
597
765
  isStaticCall,
598
766
  calldataHash,
@@ -637,7 +805,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
637
805
  } else if (!processedTx.revertCode.isOK()) {
638
806
  if (processedTx.revertReason) {
639
807
  try {
640
- 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
+ );
641
815
  // eslint-disable-next-line no-empty
642
816
  } catch {}
643
817
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -650,9 +824,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
650
824
 
651
825
  if (isStaticCall) {
652
826
  await checkpoint!.revert();
653
-
654
- await forkedWorldTrees.close();
655
-
656
827
  return returnValues ?? [];
657
828
  }
658
829
 
@@ -673,33 +844,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
673
844
 
674
845
  await this.stateMachine.handleL2Block(l2Block);
675
846
 
676
- await forkedWorldTrees.close();
677
-
678
847
  return returnValues ?? [];
679
848
  }
680
849
 
681
- async txeExecuteUtilityFunction(
850
+ async executeUtilityFunction(
851
+ from: AztecAddress | undefined,
682
852
  targetContractAddress: AztecAddress,
683
853
  functionSelector: FunctionSelector,
684
854
  args: Fr[],
685
855
  jobId: string,
856
+ authorizedUtilityCallTargets: AztecAddress[],
686
857
  ) {
687
- 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);
688
866
  if (!artifact) {
689
867
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
690
868
  }
691
869
 
692
870
  // Sync notes before executing utility function to discover notes from previous transactions
693
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
694
871
  await this.stateMachine.contractSyncService.ensureContractSynced(
695
872
  targetContractAddress,
696
873
  functionSelector,
697
874
  async (call, execScopes) => {
698
- await this.executeUtilityCall(call, execScopes, jobId);
875
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
699
876
  },
700
877
  blockHeader,
701
878
  jobId,
702
- 'ALL_SCOPES',
879
+ await this.keyStore.getAccounts(),
703
880
  );
704
881
 
705
882
  const call = FunctionCall.from({
@@ -710,14 +887,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
710
887
  hideMsgSender: false,
711
888
  isStatic: false,
712
889
  args,
713
- returnTypes: [],
714
890
  });
715
891
 
716
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
892
+ return this.executeUtilityCall(call, {
893
+ from,
894
+ scopes: await this.keyStore.getAccounts(),
895
+ jobId,
896
+ authorizedUtilityCallTargets,
897
+ });
717
898
  }
718
899
 
719
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
720
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
900
+ private async executeUtilityCall(
901
+ call: FunctionCall,
902
+ {
903
+ from = AztecAddress.NULL_MSG_SENDER,
904
+ scopes,
905
+ jobId,
906
+ authorizedUtilityCallTargets = [],
907
+ }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
908
+ ): Promise<Fr[]> {
909
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
910
+ const anchoredContractData = new AnchoredContractData(
911
+ this.contractStore,
912
+ this.stateMachine.contractClassService,
913
+ anchorBlockHeader,
914
+ );
915
+
916
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
917
+ if (!entryPointArtifact) {
918
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
919
+ }
721
920
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
722
921
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
723
922
  }
@@ -728,26 +927,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
728
927
  });
729
928
 
730
929
  try {
731
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
930
+ const simulator = new WASMSimulator();
931
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
932
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
933
+ };
732
934
  const oracle = new UtilityExecutionOracle({
733
- contractAddress: call.to,
935
+ callContext: CallContext.from({
936
+ msgSender: from,
937
+ contractAddress: call.to,
938
+ functionSelector: call.selector,
939
+ isStaticCall: true,
940
+ }),
734
941
  authWitnesses: [],
735
942
  capsules: [],
736
943
  anchorBlockHeader,
737
- contractStore: this.contractStore,
944
+ anchoredContractData,
738
945
  noteStore: this.noteStore,
739
946
  keyStore: this.keyStore,
740
947
  addressStore: this.addressStore,
741
948
  aztecNode: this.stateMachine.node,
742
949
  recipientTaggingStore: this.recipientTaggingStore,
743
- senderAddressBookStore: this.senderAddressBookStore,
744
- capsuleStore: this.capsuleStore,
950
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
951
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
952
+ factService: new FactService(this.factStore, scopes),
745
953
  privateEventStore: this.privateEventStore,
954
+ txResolver: this.stateMachine.txResolver,
955
+ contractSyncService: this.stateMachine.contractSyncService,
956
+ l2TipsStore: this.stateMachine.l2TipsProvider,
746
957
  jobId,
747
958
  scopes,
959
+ simulator,
960
+ hooks: composeHooks({
961
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
962
+ }),
963
+ utilityExecutor,
964
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
965
+ transientArrayService: new TransientArrayService(),
748
966
  });
749
- const acirExecutionResult = await new WASMSimulator()
750
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
967
+ const acirExecutionResult = await simulator
968
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
751
969
  .catch((err: Error) => {
752
970
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
753
971
  throw new ExecutionError(
@@ -768,13 +986,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
768
986
  }
769
987
  }
770
988
 
771
- close(): [bigint, Map<string, AuthWitness>] {
989
+ close(): {
990
+ nextBlockTimestamp: bigint;
991
+ authwits: Map<string, AuthWitness>;
992
+ taggingSecretStrategies: TXETaggingSecretStrategies;
993
+ authorizeAllUtilityCallTargets: boolean;
994
+ } {
772
995
  this.logger.debug('Exiting Top Level Context');
773
- return [this.nextBlockTimestamp, this.authwits];
996
+ return {
997
+ nextBlockTimestamp: this.nextBlockTimestamp,
998
+ authwits: this.authwits,
999
+ taggingSecretStrategies: this.taggingSecretStrategies,
1000
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
1001
+ };
774
1002
  }
775
1003
 
776
1004
  private async getLastBlockNumber(): Promise<BlockNumber> {
777
- const header = await this.stateMachine.node.getBlockHeader('latest');
778
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
1005
+ const block = await this.stateMachine.node.getBlock('latest');
1006
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
1007
+ }
1008
+
1009
+ private buildAuthorizeUtilityCallHook(
1010
+ callerContext: 'private' | 'private view' | 'utility',
1011
+ authorizedTargets: AztecAddress[],
1012
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
1013
+ if (this.authorizeAllUtilityCallTargets) {
1014
+ return authorizeAllUtilityCallsHook;
1015
+ }
1016
+ if (authorizedTargets.length === 0) {
1017
+ return undefined;
1018
+ }
1019
+ return req =>
1020
+ Promise.resolve({
1021
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
1022
+ });
779
1023
  }
780
1024
  }
1025
+
1026
+ /**
1027
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
1028
+ *
1029
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
1030
+ */
1031
+ export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
1032
+ Promise.resolve({ authorized: true });