@aztec/txe 0.0.1-commit.181e2d196 → 0.0.1-commit.189eedb3

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 (150) hide show
  1. package/dest/ContractClassRegistry-PII7Q556.js +3 -0
  2. package/dest/ContractClassRegistry-PII7Q556.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +3 -0
  4. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +7 -0
  5. package/dest/FeeJuice-TQV5AQK7.js +3 -0
  6. package/dest/FeeJuice-TQV5AQK7.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-SBJUIJY7.js +3 -0
  8. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +7 -0
  9. package/dest/SchnorrAccount-MQXPIZ44.js +3 -0
  10. package/dest/SchnorrAccount-MQXPIZ44.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +61 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/bin/oracle_test_server.d.ts +3 -0
  17. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  18. package/dest/bin/oracle_test_server.js +41 -0
  19. package/dest/chunk-6DNQGQKE.js +265 -0
  20. package/dest/chunk-6DNQGQKE.js.map +7 -0
  21. package/dest/chunk-BJVAAXNA.js +3 -0
  22. package/dest/chunk-BJVAAXNA.js.map +7 -0
  23. package/dest/chunk-IGFYWSUP.js +304 -0
  24. package/dest/chunk-IGFYWSUP.js.map +7 -0
  25. package/dest/constants.d.ts +5 -1
  26. package/dest/constants.d.ts.map +1 -1
  27. package/dest/constants.js +8 -0
  28. package/dest/dispatcher_pool.d.ts +67 -0
  29. package/dest/dispatcher_pool.d.ts.map +1 -0
  30. package/dest/dispatcher_pool.js +284 -0
  31. package/dest/index.d.ts +185 -7
  32. package/dest/index.d.ts.map +1 -1
  33. package/dest/index.js +70 -188
  34. package/dest/metafile.json +38642 -0
  35. package/dest/msgpackr_fr_extension.d.ts +2 -0
  36. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  37. package/dest/msgpackr_fr_extension.js +21 -0
  38. package/dest/oracle/interfaces.d.ts +55 -30
  39. package/dest/oracle/interfaces.d.ts.map +1 -1
  40. package/dest/oracle/test-resolver/fixtures.d.ts +43 -0
  41. package/dest/oracle/test-resolver/fixtures.d.ts.map +1 -0
  42. package/dest/oracle/test-resolver/fixtures.js +39 -0
  43. package/dest/oracle/test-resolver/index.d.ts +9 -0
  44. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  45. package/dest/oracle/test-resolver/index.js +33 -0
  46. package/dest/oracle/test-resolver/resolver.d.ts +34 -0
  47. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  48. package/dest/oracle/test-resolver/resolver.js +114 -0
  49. package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
  50. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  51. package/dest/oracle/txe_oracle_public_context.js +55 -13
  52. package/dest/oracle/txe_oracle_registry.d.ts +147 -0
  53. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  54. package/dest/oracle/txe_oracle_registry.js +562 -0
  55. package/dest/oracle/txe_oracle_top_level_context.d.ts +43 -23
  56. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_top_level_context.js +163 -69
  58. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  59. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  60. package/dest/oracle/txe_oracle_version.js +14 -0
  61. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  62. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  63. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  64. package/dest/rpc_server.d.ts +14 -0
  65. package/dest/rpc_server.d.ts.map +1 -0
  66. package/dest/rpc_server.js +78 -0
  67. package/dest/rpc_translator.d.ts +96 -228
  68. package/dest/rpc_translator.d.ts.map +1 -1
  69. package/dest/rpc_translator.js +815 -636
  70. package/dest/server.bundle.js +3 -0
  71. package/dest/server.bundle.js.map +7 -0
  72. package/dest/state_machine/archiver.d.ts +6 -5
  73. package/dest/state_machine/archiver.d.ts.map +1 -1
  74. package/dest/state_machine/archiver.js +30 -21
  75. package/dest/state_machine/dummy_p2p_client.d.ts +13 -7
  76. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  77. package/dest/state_machine/dummy_p2p_client.js +16 -4
  78. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  79. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  80. package/dest/state_machine/global_variable_builder.js +9 -3
  81. package/dest/state_machine/index.d.ts +7 -3
  82. package/dest/state_machine/index.d.ts.map +1 -1
  83. package/dest/state_machine/index.js +23 -5
  84. package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
  85. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  86. package/dest/state_machine/mock_epoch_cache.js +29 -2
  87. package/dest/state_machine/synchronizer.d.ts +5 -5
  88. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  89. package/dest/state_machine/synchronizer.js +4 -4
  90. package/dest/txe_session.d.ts +74 -12
  91. package/dest/txe_session.d.ts.map +1 -1
  92. package/dest/txe_session.js +175 -37
  93. package/dest/utils/encoding.d.ts +191 -0
  94. package/dest/utils/encoding.d.ts.map +1 -0
  95. package/dest/{util → utils}/encoding.js +7 -2
  96. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  97. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  98. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  99. package/dest/utils/txe_account_store.d.ts.map +1 -0
  100. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  101. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  102. package/dest/utils/txe_artifact_resolver.js +161 -0
  103. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  104. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  105. package/dest/{util → utils}/txe_public_contract_data_source.js +1 -3
  106. package/dest/worker.bundle.js +3 -0
  107. package/dest/worker.bundle.js.map +7 -0
  108. package/dest/worker.d.ts +2 -0
  109. package/dest/worker.d.ts.map +1 -0
  110. package/dest/worker.js +92 -0
  111. package/package.json +38 -21
  112. package/src/bin/check_txe_oracle_version.ts +70 -0
  113. package/src/bin/index.ts +11 -2
  114. package/src/bin/oracle_test_server.ts +51 -0
  115. package/src/constants.ts +10 -0
  116. package/src/dispatcher_pool.ts +316 -0
  117. package/src/index.ts +97 -224
  118. package/src/msgpackr_fr_extension.ts +23 -0
  119. package/src/oracle/interfaces.ts +53 -35
  120. package/src/oracle/test-resolver/fixtures.ts +84 -0
  121. package/src/oracle/test-resolver/index.ts +45 -0
  122. package/src/oracle/test-resolver/resolver.ts +165 -0
  123. package/src/oracle/txe_oracle_public_context.ts +72 -12
  124. package/src/oracle/txe_oracle_registry.ts +401 -0
  125. package/src/oracle/txe_oracle_top_level_context.ts +197 -79
  126. package/src/oracle/txe_oracle_version.ts +17 -0
  127. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  128. package/src/rpc_server.ts +87 -0
  129. package/src/rpc_translator.ts +1000 -1021
  130. package/src/state_machine/archiver.ts +42 -20
  131. package/src/state_machine/dummy_p2p_client.ts +31 -11
  132. package/src/state_machine/global_variable_builder.ts +18 -3
  133. package/src/state_machine/index.ts +25 -6
  134. package/src/state_machine/mock_epoch_cache.ts +38 -3
  135. package/src/state_machine/synchronizer.ts +5 -5
  136. package/src/txe_session.ts +286 -40
  137. package/src/{util → utils}/encoding.ts +8 -2
  138. package/src/utils/txe_artifact_resolver.ts +217 -0
  139. package/src/{util → utils}/txe_public_contract_data_source.ts +0 -2
  140. package/src/worker.ts +98 -0
  141. package/dest/util/encoding.d.ts +0 -720
  142. package/dest/util/encoding.d.ts.map +0 -1
  143. package/dest/util/expected_failure_error.d.ts.map +0 -1
  144. package/dest/util/txe_account_store.d.ts.map +0 -1
  145. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  146. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  147. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  148. /package/dest/{util → utils}/txe_account_store.js +0 -0
  149. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  150. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,9 +1,6 @@
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';
@@ -12,17 +9,19 @@ import { Fr } from '@aztec/foundation/curves/bn254';
12
9
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
10
  import { TestDateProvider } from '@aztec/foundation/timer';
14
11
  import type { KeyStore } from '@aztec/key-store';
15
- import type { AccessScopes } from '@aztec/pxe/client/lazy';
16
12
  import {
17
13
  AddressStore,
14
+ CapsuleService,
18
15
  CapsuleStore,
19
16
  type ContractStore,
17
+ type ExecutionHooks,
20
18
  NoteStore,
21
- ORACLE_VERSION,
19
+ ORACLE_VERSION_MAJOR,
22
20
  PrivateEventStore,
23
21
  RecipientTaggingStore,
24
22
  SenderAddressBookStore,
25
23
  SenderTaggingStore,
24
+ composeHooks,
26
25
  enrichPublicSimulationError,
27
26
  } from '@aztec/pxe/server';
28
27
  import {
@@ -64,6 +63,7 @@ import {
64
63
  PrivateToPublicAccumulatedData,
65
64
  PublicCallRequest,
66
65
  } from '@aztec/stdlib/kernel';
66
+ import { hashPublicKey } from '@aztec/stdlib/keys';
67
67
  import { ChonkProof } from '@aztec/stdlib/proofs';
68
68
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
69
69
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -80,13 +80,14 @@ import {
80
80
  collectNested,
81
81
  } from '@aztec/stdlib/tx';
82
82
  import type { UInt64 } from '@aztec/stdlib/types';
83
- import { ForkCheckpoint } from '@aztec/world-state';
83
+ import { ForkCheckpoint } from '@aztec/world-state/native';
84
84
 
85
- import { DEFAULT_ADDRESS } from '../constants.js';
85
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
86
86
  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
87
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
88
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
89
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
90
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
90
91
  import type { ITxeExecutionOracle } from './interfaces.js';
91
92
 
92
93
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -111,27 +112,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
111
112
  private version: Fr,
112
113
  private chainId: Fr,
113
114
  private authwits: Map<string, AuthWitness>,
115
+ private readonly artifactResolver: TXEArtifactResolver,
116
+ private readonly rootPath: string,
117
+ private readonly packageName: string,
114
118
  ) {
115
119
  this.logger = createLogger('txe:top_level_context');
116
120
  this.logger.debug('Entering Top Level Context');
117
121
  }
118
122
 
119
- utilityAssertCompatibleOracleVersion(version: number): void {
120
- if (version !== ORACLE_VERSION) {
123
+ private contractOracleVersion: { major: number; minor: number } | undefined;
124
+
125
+ assertCompatibleOracleVersion(major: number, minor: number): void {
126
+ if (major !== ORACLE_VERSION_MAJOR) {
127
+ const hint =
128
+ major > ORACLE_VERSION_MAJOR
129
+ ? '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.'
130
+ : '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
131
  throw new Error(
122
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
132
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
123
133
  );
124
134
  }
135
+ this.contractOracleVersion = { major, minor };
136
+ }
137
+
138
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
139
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
140
+ return this.contractOracleVersion;
125
141
  }
126
142
 
127
143
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
128
144
  // setup.
129
- utilityGetRandomField(): Fr {
145
+ getRandomField(): Fr {
130
146
  return Fr.random();
131
147
  }
132
148
 
133
149
  // 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> {
150
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
135
151
  if (!LogLevels[level]) {
136
152
  throw new Error(`Invalid log level: ${level}`);
137
153
  }
@@ -141,25 +157,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
141
157
  return Promise.resolve();
142
158
  }
143
159
 
144
- txeGetDefaultAddress(): AztecAddress {
160
+ getDefaultAddress(): AztecAddress {
145
161
  return DEFAULT_ADDRESS;
146
162
  }
147
163
 
148
- async txeGetNextBlockNumber(): Promise<BlockNumber> {
164
+ async getNextBlockNumber(): Promise<BlockNumber> {
149
165
  return BlockNumber((await this.getLastBlockNumber()) + 1);
150
166
  }
151
167
 
152
- txeGetNextBlockTimestamp(): Promise<bigint> {
168
+ getNextBlockTimestamp(): Promise<bigint> {
153
169
  return Promise.resolve(this.nextBlockTimestamp);
154
170
  }
155
171
 
156
- async txeGetLastBlockTimestamp() {
157
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
172
+ async getLastBlockTimestamp() {
173
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
158
174
  }
159
175
 
160
- async txeGetLastTxEffects() {
176
+ async getLastTxEffects() {
161
177
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
162
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
178
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
163
179
 
164
180
  if (block!.body.txEffects.length != 1) {
165
181
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -168,12 +184,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
168
184
 
169
185
  const txEffects = block!.body.txEffects[0];
170
186
 
171
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
187
+ const privateLogs = txEffects.privateLogs;
188
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
189
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
190
+ }
191
+
192
+ return {
193
+ txHash: txEffects.txHash,
194
+ noteHashes: txEffects.noteHashes,
195
+ nullifiers: txEffects.nullifiers,
196
+ privateLogs,
197
+ };
172
198
  }
173
199
 
174
200
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
175
201
  if (contractAddress.equals(DEFAULT_ADDRESS)) {
176
- this.logger.debug(`Skipping sync in txeGetPrivateEvents because the events correspond to the default address.`);
202
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
177
203
  return;
178
204
  }
179
205
 
@@ -190,8 +216,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
190
216
  );
191
217
  }
192
218
 
193
- async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
194
- return (
219
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
220
+ const events = (
195
221
  await this.privateEventStore.getPrivateEvents(selector, {
196
222
  contractAddress,
197
223
  scopes: [scope],
@@ -199,9 +225,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
199
225
  toBlock: (await this.getLastBlockNumber()) + 1,
200
226
  })
201
227
  ).map(e => e.packedEvent);
228
+
229
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
230
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
231
+ }
232
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
233
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
234
+ }
235
+
236
+ return events;
202
237
  }
203
238
 
204
- async txeAdvanceBlocksBy(blocks: number) {
239
+ async advanceBlocksBy(blocks: number) {
205
240
  this.logger.debug(`time traveling ${blocks} blocks`);
206
241
 
207
242
  for (let i = 0; i < blocks; i++) {
@@ -209,32 +244,76 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
209
244
  }
210
245
  }
211
246
 
212
- txeAdvanceTimestampBy(duration: UInt64) {
247
+ advanceTimestampBy(duration: UInt64) {
213
248
  this.logger.debug(`time traveling ${duration} seconds`);
214
249
  this.nextBlockTimestamp += duration;
215
250
  }
216
251
 
217
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
252
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
253
+ return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
254
+ }
255
+
256
+ async deploy(
257
+ contractPath: string,
258
+ initializer: string,
259
+ args: Fr[],
260
+ secret: Fr,
261
+ salt: Fr,
262
+ deployer: AztecAddress,
263
+ ): Promise<Fr[]> {
264
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
265
+ rootPath: this.rootPath,
266
+ packageName: this.packageName,
267
+ contractPath,
268
+ initializer,
269
+ args,
270
+ secret,
271
+ salt,
272
+ deployer,
273
+ });
274
+
218
275
  // Emit deployment nullifier
219
276
  await this.mineBlock({
220
- nullifiers: [
221
- await siloNullifier(
222
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
223
- instance.address.toField(),
224
- ),
225
- ],
277
+ nullifiers: [await this.deploymentNullifier(instance.address)],
226
278
  });
227
279
 
228
280
  if (!secret.equals(Fr.ZERO)) {
229
- await this.txeAddAccount(artifact, instance, secret);
281
+ await this.registerContractAndAddAccount(artifact, instance, secret);
230
282
  } else {
231
283
  await this.contractStore.addContractInstance(instance);
232
284
  await this.contractStore.addContractArtifact(artifact);
233
285
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
234
286
  }
287
+
288
+ return [
289
+ instance.salt,
290
+ instance.deployer.toField(),
291
+ instance.currentContractClassId,
292
+ instance.initializationHash,
293
+ instance.immutablesHash,
294
+ ...instance.publicKeys.toFields(),
295
+ ];
296
+ }
297
+
298
+ /**
299
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
300
+ */
301
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
302
+ await this.mineBlock({
303
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
304
+ });
305
+ }
306
+
307
+ async addAccount(secret: Fr) {
308
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
309
+ return this.registerContractAndAddAccount(artifact, instance, secret);
235
310
  }
236
311
 
237
- async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
312
+ private async registerContractAndAddAccount(
313
+ artifact: ContractArtifact,
314
+ instance: ContractInstanceWithAddress,
315
+ secret: Fr,
316
+ ) {
238
317
  const partialAddress = await computePartialAddress(instance);
239
318
 
240
319
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
@@ -249,7 +328,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
249
328
  return completeAddress;
250
329
  }
251
330
 
252
- async txeCreateAccount(secret: Fr) {
331
+ async createAccount(secret: Fr) {
253
332
  // This is a foot gun !
254
333
  const completeAddress = await this.keyStore.addAccount(secret, secret);
255
334
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
@@ -259,20 +338,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
259
338
  return completeAddress;
260
339
  }
261
340
 
262
- async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
341
+ async addAuthWitness(address: AztecAddress, messageHash: Fr) {
263
342
  const account = await this.accountStore.getAccount(address);
264
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
343
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
344
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
265
345
 
266
346
  const schnorr = new Schnorr();
267
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
347
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
268
348
 
269
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
349
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
270
350
 
271
351
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
272
352
  }
273
353
 
274
354
  async mineBlock(options: { nullifiers?: Fr[] } = {}) {
275
- const blockNumber = await this.txeGetNextBlockNumber();
355
+ const blockNumber = await this.getNextBlockNumber();
276
356
 
277
357
  const txEffect = TxEffect.empty();
278
358
  txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
@@ -296,14 +376,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
296
376
  await this.stateMachine.handleL2Block(block);
297
377
  }
298
378
 
299
- async txePrivateCallNewFlow(
300
- from: AztecAddress,
379
+ async privateCallNewFlow(
380
+ from: AztecAddress | undefined,
301
381
  targetContractAddress: AztecAddress = AztecAddress.zero(),
302
382
  functionSelector: FunctionSelector = FunctionSelector.empty(),
303
383
  args: Fr[],
304
384
  argsHash: Fr = Fr.zero(),
305
385
  isStaticCall: boolean = false,
386
+ additionalScopes: AztecAddress[] = [],
306
387
  jobId: string,
388
+ authorizedUtilityCallTargets: AztecAddress[],
389
+ gasSettings: GasSettings,
307
390
  ) {
308
391
  this.logger.verbose(
309
392
  `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
@@ -317,12 +400,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
317
400
  throw new Error(message);
318
401
  }
319
402
 
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];
403
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
323
404
 
324
405
  // Sync notes before executing private function to discover notes from previous transactions
325
- const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
406
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
326
407
  await this.executeUtilityCall(call, execScopes, jobId);
327
408
  };
328
409
 
@@ -333,16 +414,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
333
414
  utilityExecutor,
334
415
  blockHeader,
335
416
  jobId,
336
- effectiveScopes,
417
+ scopes,
337
418
  );
338
419
 
339
- const blockNumber = await this.txeGetNextBlockNumber();
340
-
341
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
420
+ const blockNumber = await this.getNextBlockNumber();
342
421
 
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());
422
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
423
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
346
424
 
347
425
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
348
426
 
@@ -376,17 +454,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
376
454
  senderTaggingStore: this.senderTaggingStore,
377
455
  recipientTaggingStore: this.recipientTaggingStore,
378
456
  senderAddressBookStore: this.senderAddressBookStore,
379
- capsuleStore: this.capsuleStore,
457
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
380
458
  privateEventStore: this.privateEventStore,
381
459
  contractSyncService: this.stateMachine.contractSyncService,
382
460
  jobId,
383
461
  totalPublicCalldataCount: 0,
384
462
  sideEffectCounter: minRevertibleSideEffectCounter,
385
- scopes: effectiveScopes,
463
+ scopes,
386
464
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
387
465
  // contract would perform, including setting senderForTags.
388
466
  senderForTags: from,
389
467
  simulator,
468
+ messageContextService: this.stateMachine.messageContextService,
469
+ l2TipsStore: this.stateMachine.l2TipsProvider,
470
+ hooks: composeHooks({
471
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
472
+ isStaticCall ? 'private view' : 'private',
473
+ authorizedUtilityCallTargets,
474
+ ),
475
+ }),
390
476
  });
391
477
 
392
478
  // 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,7 +495,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
409
495
  );
410
496
  const publicFunctionsCalldata = await Promise.all(
411
497
  publicCallRequests.map(async r => {
412
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
498
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
413
499
  return new HashedValues(calldata, r.calldataHash);
414
500
  }),
415
501
  );
@@ -494,11 +580,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
494
580
  }
495
581
  }
496
582
 
583
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
584
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
585
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
586
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
587
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
588
+
497
589
  if (isStaticCall) {
498
590
  await checkpoint!.revert();
499
591
 
500
592
  await forkedWorldTrees.close();
501
- return executionResult.returnValues ?? [];
593
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
502
594
  }
503
595
 
504
596
  const txEffect = TxEffect.empty();
@@ -520,26 +612,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
520
612
 
521
613
  await forkedWorldTrees.close();
522
614
 
523
- return executionResult.returnValues ?? [];
615
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
524
616
  }
525
617
 
526
- async txePublicCallNewFlow(
527
- from: AztecAddress,
618
+ async publicCallNewFlow(
619
+ from: AztecAddress | undefined,
528
620
  targetContractAddress: AztecAddress,
529
621
  calldata: Fr[],
530
622
  isStaticCall: boolean,
623
+ gasSettings: GasSettings,
531
624
  ) {
532
625
  this.logger.verbose(
533
626
  `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
534
627
  );
535
628
 
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);
541
-
542
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
629
+ const blockNumber = await this.getNextBlockNumber();
543
630
 
544
631
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
545
632
 
@@ -592,7 +679,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
592
679
  // may require producing reverts.
593
680
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
594
681
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
595
- from,
682
+ from ?? AztecAddress.NULL_MSG_SENDER,
596
683
  targetContractAddress,
597
684
  isStaticCall,
598
685
  calldataHash,
@@ -678,11 +765,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
678
765
  return returnValues ?? [];
679
766
  }
680
767
 
681
- async txeExecuteUtilityFunction(
768
+ async executeUtilityFunction(
682
769
  targetContractAddress: AztecAddress,
683
770
  functionSelector: FunctionSelector,
684
771
  args: Fr[],
685
772
  jobId: string,
773
+ authorizedUtilityCallTargets: AztecAddress[],
686
774
  ) {
687
775
  const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
688
776
  if (!artifact) {
@@ -699,7 +787,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
699
787
  },
700
788
  blockHeader,
701
789
  jobId,
702
- 'ALL_SCOPES',
790
+ await this.keyStore.getAccounts(),
703
791
  );
704
792
 
705
793
  const call = FunctionCall.from({
@@ -713,10 +801,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
713
801
  returnTypes: [],
714
802
  });
715
803
 
716
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
804
+ return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
717
805
  }
718
806
 
719
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
807
+ private async executeUtilityCall(
808
+ call: FunctionCall,
809
+ scopes: AztecAddress[],
810
+ jobId: string,
811
+ authorizedUtilityCallTargets: AztecAddress[] = [],
812
+ ): Promise<Fr[]> {
720
813
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
721
814
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
722
815
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -729,6 +822,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
729
822
 
730
823
  try {
731
824
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
825
+ const simulator = new WASMSimulator();
826
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
827
+ await this.executeUtilityCall(syncCall, execScopes, jobId);
828
+ };
732
829
  const oracle = new UtilityExecutionOracle({
733
830
  contractAddress: call.to,
734
831
  authWitnesses: [],
@@ -741,12 +838,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
741
838
  aztecNode: this.stateMachine.node,
742
839
  recipientTaggingStore: this.recipientTaggingStore,
743
840
  senderAddressBookStore: this.senderAddressBookStore,
744
- capsuleStore: this.capsuleStore,
841
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
745
842
  privateEventStore: this.privateEventStore,
843
+ messageContextService: this.stateMachine.messageContextService,
844
+ contractSyncService: this.stateMachine.contractSyncService,
845
+ l2TipsStore: this.stateMachine.l2TipsProvider,
746
846
  jobId,
747
847
  scopes,
848
+ simulator,
849
+ hooks: composeHooks({
850
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
851
+ }),
852
+ utilityExecutor,
748
853
  });
749
- const acirExecutionResult = await new WASMSimulator()
854
+ const acirExecutionResult = await simulator
750
855
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
751
856
  .catch((err: Error) => {
752
857
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
@@ -774,7 +879,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
774
879
  }
775
880
 
776
881
  private async getLastBlockNumber(): Promise<BlockNumber> {
777
- const header = await this.stateMachine.node.getBlockHeader('latest');
778
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
882
+ const block = await this.stateMachine.node.getBlock('latest');
883
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
884
+ }
885
+
886
+ private buildAuthorizeUtilityCallHook(
887
+ callerContext: 'private' | 'private view' | 'utility',
888
+ authorizedTargets: AztecAddress[],
889
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
890
+ if (authorizedTargets.length === 0) {
891
+ return undefined;
892
+ }
893
+ return req =>
894
+ Promise.resolve({
895
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
896
+ });
779
897
  }
780
898
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The TXE oracle version constants are used to check that the oracle interface used for tests is in sync between
3
+ * TXE and Aztec.nr. This is separate from the contract oracle version in `pxe/src/oracle_version.ts`, which covers
4
+ * oracles used during contract execution by PXE.
5
+ *
6
+ * The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`.
7
+ */
8
+ export const TXE_ORACLE_VERSION_MAJOR = 1;
9
+ export const TXE_ORACLE_VERSION_MINOR = 2;
10
+
11
+ /**
12
+ * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to
13
+ * detect when those interfaces change. When it does, bump:
14
+ * - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or
15
+ * - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added).
16
+ */
17
+ export const TXE_ORACLE_INTERFACE_HASH = '9e5f6ad5fd170d1de5ddd417f19cce47b17382567e08360dc6a783154828e218';
@@ -0,0 +1,30 @@
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
2
+ import { PrivateExecutionOracle } from '@aztec/pxe/simulator';
3
+ import type { FunctionSelector } from '@aztec/stdlib/abi';
4
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
5
+
6
+ /**
7
+ * TXE-specific subclass of PrivateExecutionOracle that forbids operations not supported in
8
+ * TestEnvironment::private_context. TXE uses dedicated oracle flows (e.g. private_call) instead.
9
+ */
10
+ export class TXEPrivateExecutionOracle extends PrivateExecutionOracle {
11
+ override callPrivateFunction(
12
+ _targetContractAddress: AztecAddress,
13
+ _functionSelector: FunctionSelector,
14
+ _argsHash: Fr,
15
+ _sideEffectCounter: number,
16
+ _isStaticCall: boolean,
17
+ ): Promise<{ endSideEffectCounter: Fr; returnsHash: Fr }> {
18
+ throw new Error(
19
+ 'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead',
20
+ );
21
+ }
22
+
23
+ override assertValidPublicCalldata(_calldataHash: Fr): Promise<void> {
24
+ throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
25
+ }
26
+
27
+ override notifyRevertiblePhaseStart(_minRevertibleSideEffectCounter: number): Promise<void> {
28
+ throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
29
+ }
30
+ }