@aztec/txe 5.0.0-private.20260319 → 5.0.0-rc.2

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 (160) hide show
  1. package/dest/AuthRegistry-URXCCPYF.js +3 -0
  2. package/dest/AuthRegistry-URXCCPYF.js.map +7 -0
  3. package/dest/ContractClassRegistry-5RDBM6TC.js +3 -0
  4. package/dest/ContractClassRegistry-5RDBM6TC.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-GCR4G4D7.js +3 -0
  6. package/dest/ContractInstanceRegistry-GCR4G4D7.js.map +7 -0
  7. package/dest/FeeJuice-O3KOSZO5.js +3 -0
  8. package/dest/FeeJuice-O3KOSZO5.js.map +7 -0
  9. package/dest/HandshakeRegistry-TXSMHMNY.js +3 -0
  10. package/dest/HandshakeRegistry-TXSMHMNY.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-P4FSRXAD.js +3 -0
  12. package/dest/MultiCallEntrypoint-P4FSRXAD.js.map +7 -0
  13. package/dest/SchnorrAccount-AQZX7ROU.js +3 -0
  14. package/dest/SchnorrAccount-AQZX7ROU.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-KMX2H3J6.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-KMX2H3J6.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  18. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  19. package/dest/bin/check_txe_oracle_version.js +61 -0
  20. package/dest/bin/index.js +3 -30
  21. package/dest/bin/index.js.map +7 -0
  22. package/dest/bin/oracle_test_server.d.ts +3 -0
  23. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  24. package/dest/bin/oracle_test_server.js +41 -0
  25. package/dest/chunk-BJVAAXNA.js +3 -0
  26. package/dest/chunk-BJVAAXNA.js.map +7 -0
  27. package/dest/chunk-I6DL4FT2.js +304 -0
  28. package/dest/chunk-I6DL4FT2.js.map +7 -0
  29. package/dest/chunk-IAO54JS2.js +266 -0
  30. package/dest/chunk-IAO54JS2.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 +70 -190
  40. package/dest/metafile.json +39364 -0
  41. package/dest/msgpackr_fr_extension.d.ts +2 -0
  42. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  43. package/dest/msgpackr_fr_extension.js +21 -0
  44. package/dest/oracle/interfaces.d.ts +38 -8
  45. package/dest/oracle/interfaces.d.ts.map +1 -1
  46. package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
  47. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  48. package/dest/oracle/test-resolver/default_fixtures.js +164 -0
  49. package/dest/oracle/test-resolver/index.d.ts +9 -0
  50. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  51. package/dest/oracle/test-resolver/index.js +32 -0
  52. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  53. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  54. package/dest/oracle/test-resolver/resolver.js +144 -0
  55. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  56. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_public_context.js +43 -1
  58. package/dest/oracle/txe_oracle_registry.d.ts +167 -0
  59. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  60. package/dest/oracle/txe_oracle_registry.js +715 -0
  61. package/dest/oracle/txe_oracle_top_level_context.d.ts +42 -17
  62. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  63. package/dest/oracle/txe_oracle_top_level_context.js +205 -70
  64. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  65. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  66. package/dest/oracle/txe_oracle_version.js +14 -0
  67. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  68. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  69. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  70. package/dest/rpc_server.d.ts +14 -0
  71. package/dest/rpc_server.d.ts.map +1 -0
  72. package/dest/rpc_server.js +78 -0
  73. package/dest/rpc_translator.d.ts +111 -233
  74. package/dest/rpc_translator.d.ts.map +1 -1
  75. package/dest/rpc_translator.js +759 -636
  76. package/dest/server.bundle.js +3 -0
  77. package/dest/server.bundle.js.map +7 -0
  78. package/dest/state_machine/archiver.d.ts +4 -3
  79. package/dest/state_machine/archiver.d.ts.map +1 -1
  80. package/dest/state_machine/archiver.js +24 -14
  81. package/dest/state_machine/dummy_p2p_client.d.ts +15 -7
  82. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  83. package/dest/state_machine/dummy_p2p_client.js +22 -4
  84. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  85. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  86. package/dest/state_machine/global_variable_builder.js +8 -5
  87. package/dest/state_machine/index.d.ts +9 -6
  88. package/dest/state_machine/index.d.ts.map +1 -1
  89. package/dest/state_machine/index.js +45 -12
  90. package/dest/state_machine/mock_epoch_cache.d.ts +1 -2
  91. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  92. package/dest/state_machine/mock_epoch_cache.js +0 -3
  93. package/dest/state_machine/synchronizer.d.ts +3 -2
  94. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  95. package/dest/state_machine/synchronizer.js +4 -3
  96. package/dest/txe_session.d.ts +89 -20
  97. package/dest/txe_session.d.ts.map +1 -1
  98. package/dest/txe_session.js +289 -64
  99. package/dest/utils/block_creation.d.ts +2 -2
  100. package/dest/utils/block_creation.d.ts.map +1 -1
  101. package/dest/utils/block_creation.js +2 -2
  102. package/dest/utils/encoding.d.ts +191 -0
  103. package/dest/utils/encoding.d.ts.map +1 -0
  104. package/dest/{util → utils}/encoding.js +7 -2
  105. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  106. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  107. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  108. package/dest/utils/txe_account_store.d.ts.map +1 -0
  109. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  110. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  111. package/dest/utils/txe_artifact_resolver.js +161 -0
  112. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  113. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  114. package/dest/{util → utils}/txe_public_contract_data_source.js +1 -3
  115. package/dest/worker.bundle.js +3 -0
  116. package/dest/worker.bundle.js.map +7 -0
  117. package/dest/worker.d.ts +2 -0
  118. package/dest/worker.d.ts.map +1 -0
  119. package/dest/worker.js +92 -0
  120. package/package.json +38 -21
  121. package/src/bin/check_txe_oracle_version.ts +70 -0
  122. package/src/bin/index.ts +11 -2
  123. package/src/bin/oracle_test_server.ts +51 -0
  124. package/src/constants.ts +11 -1
  125. package/src/dispatcher_pool.ts +317 -0
  126. package/src/index.ts +97 -227
  127. package/src/msgpackr_fr_extension.ts +23 -0
  128. package/src/oracle/interfaces.ts +35 -7
  129. package/src/oracle/test-resolver/default_fixtures.ts +226 -0
  130. package/src/oracle/test-resolver/index.ts +44 -0
  131. package/src/oracle/test-resolver/resolver.ts +198 -0
  132. package/src/oracle/txe_oracle_public_context.ts +60 -0
  133. package/src/oracle/txe_oracle_registry.ts +494 -0
  134. package/src/oracle/txe_oracle_top_level_context.ts +245 -81
  135. package/src/oracle/txe_oracle_version.ts +17 -0
  136. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  137. package/src/rpc_server.ts +87 -0
  138. package/src/rpc_translator.ts +845 -905
  139. package/src/state_machine/archiver.ts +37 -16
  140. package/src/state_machine/dummy_p2p_client.ts +40 -11
  141. package/src/state_machine/global_variable_builder.ts +12 -11
  142. package/src/state_machine/index.ts +44 -30
  143. package/src/state_machine/mock_epoch_cache.ts +0 -4
  144. package/src/state_machine/synchronizer.ts +4 -3
  145. package/src/txe_session.ts +496 -80
  146. package/src/utils/block_creation.ts +2 -1
  147. package/src/{util → utils}/encoding.ts +8 -2
  148. package/src/utils/txe_artifact_resolver.ts +217 -0
  149. package/src/{util → utils}/txe_public_contract_data_source.ts +0 -2
  150. package/src/worker.ts +98 -0
  151. package/dest/util/encoding.d.ts +0 -720
  152. package/dest/util/encoding.d.ts.map +0 -1
  153. package/dest/util/expected_failure_error.d.ts.map +0 -1
  154. package/dest/util/txe_account_store.d.ts.map +0 -1
  155. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  156. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  157. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  158. /package/dest/{util → utils}/txe_account_store.js +0 -0
  159. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  160. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,39 +1,44 @@
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
+ CapsuleService,
18
16
  CapsuleStore,
19
17
  type ContractStore,
20
- type ContractSyncService,
18
+ type ExecutionHooks,
19
+ FactService,
20
+ FactStore,
21
21
  NoteStore,
22
- ORACLE_VERSION,
22
+ ORACLE_VERSION_MAJOR,
23
23
  PrivateEventStore,
24
24
  RecipientTaggingStore,
25
- SenderAddressBookStore,
26
25
  SenderTaggingStore,
26
+ TaggingSecretSourcesStore,
27
+ type TaggingSecretStrategy,
28
+ composeHooks,
27
29
  enrichPublicSimulationError,
28
30
  } from '@aztec/pxe/server';
29
31
  import {
32
+ CONTRACT_INSTANCE,
30
33
  ExecutionNoteCache,
31
34
  ExecutionTaggingIndexCache,
32
35
  HashedValuesCache,
33
36
  type IMiscOracle,
34
- Oracle,
37
+ type Option,
35
38
  PrivateExecutionOracle,
39
+ TransientArrayService,
36
40
  UtilityExecutionOracle,
41
+ buildACIRCallback,
37
42
  executePrivateFunction,
38
43
  generateSimulatedProvingResult,
39
44
  } from '@aztec/pxe/simulator';
@@ -65,6 +70,8 @@ import {
65
70
  PrivateToPublicAccumulatedData,
66
71
  PublicCallRequest,
67
72
  } from '@aztec/stdlib/kernel';
73
+ import { hashPublicKey } from '@aztec/stdlib/keys';
74
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
68
75
  import { ChonkProof } from '@aztec/stdlib/proofs';
69
76
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
70
77
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -81,13 +88,14 @@ import {
81
88
  collectNested,
82
89
  } from '@aztec/stdlib/tx';
83
90
  import type { UInt64 } from '@aztec/stdlib/types';
84
- import { ForkCheckpoint } from '@aztec/world-state';
91
+ import { ForkCheckpoint } from '@aztec/world-state/native';
85
92
 
86
- import { DEFAULT_ADDRESS } from '../constants.js';
93
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
87
94
  import type { TXEStateMachine } from '../state_machine/index.js';
88
- import type { TXEAccountStore } from '../util/txe_account_store.js';
89
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
90
95
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
96
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
97
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
98
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
91
99
  import type { ITxeExecutionOracle } from './interfaces.js';
92
100
 
93
101
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -105,25 +113,41 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
105
113
  private accountStore: TXEAccountStore,
106
114
  private senderTaggingStore: SenderTaggingStore,
107
115
  private recipientTaggingStore: RecipientTaggingStore,
108
- private senderAddressBookStore: SenderAddressBookStore,
116
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
109
117
  private capsuleStore: CapsuleStore,
118
+ private factStore: FactStore,
110
119
  private privateEventStore: PrivateEventStore,
111
120
  private nextBlockTimestamp: bigint,
112
121
  private version: Fr,
113
122
  private chainId: Fr,
114
123
  private authwits: Map<string, AuthWitness>,
115
- private readonly contractSyncService: ContractSyncService,
124
+ private taggingSecretStrategy: TaggingSecretStrategy | undefined,
125
+ private readonly artifactResolver: TXEArtifactResolver,
126
+ private readonly rootPath: string,
127
+ private readonly packageName: string,
116
128
  ) {
117
129
  this.logger = createLogger('txe:top_level_context');
118
130
  this.logger.debug('Entering Top Level Context');
119
131
  }
120
132
 
121
- assertCompatibleOracleVersion(version: number): void {
122
- if (version !== ORACLE_VERSION) {
133
+ private contractOracleVersion: { major: number; minor: number } | undefined;
134
+
135
+ assertCompatibleOracleVersion(major: number, minor: number): void {
136
+ if (major !== ORACLE_VERSION_MAJOR) {
137
+ const hint =
138
+ major > ORACLE_VERSION_MAJOR
139
+ ? '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.'
140
+ : 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
123
141
  throw new Error(
124
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
142
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
125
143
  );
126
144
  }
145
+ this.contractOracleVersion = { major, minor };
146
+ }
147
+
148
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
149
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
150
+ return this.contractOracleVersion;
127
151
  }
128
152
 
129
153
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
@@ -133,7 +157,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
133
157
  }
134
158
 
135
159
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
136
- log(level: number, message: string, fields: Fr[]): Promise<void> {
160
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
137
161
  if (!LogLevels[level]) {
138
162
  throw new Error(`Invalid log level: ${level}`);
139
163
  }
@@ -156,12 +180,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
156
180
  }
157
181
 
158
182
  async getLastBlockTimestamp() {
159
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
183
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
160
184
  }
161
185
 
162
186
  async getLastTxEffects() {
163
187
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
164
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
188
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
165
189
 
166
190
  if (block!.body.txEffects.length != 1) {
167
191
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -170,7 +194,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
170
194
 
171
195
  const txEffects = block!.body.txEffects[0];
172
196
 
173
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
197
+ const privateLogs = txEffects.privateLogs;
198
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
199
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
200
+ }
201
+
202
+ return {
203
+ txHash: txEffects.txHash,
204
+ noteHashes: txEffects.noteHashes,
205
+ nullifiers: txEffects.nullifiers,
206
+ privateLogs,
207
+ };
174
208
  }
175
209
 
176
210
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
@@ -184,7 +218,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
184
218
  contractAddress,
185
219
  null,
186
220
  async (call, execScopes) => {
187
- await this.executeUtilityCall(call, execScopes, jobId);
221
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
188
222
  },
189
223
  blockHeader,
190
224
  jobId,
@@ -193,7 +227,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
193
227
  }
194
228
 
195
229
  async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
196
- return (
230
+ const events = (
197
231
  await this.privateEventStore.getPrivateEvents(selector, {
198
232
  contractAddress,
199
233
  scopes: [scope],
@@ -201,6 +235,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
201
235
  toBlock: (await this.getLastBlockNumber()) + 1,
202
236
  })
203
237
  ).map(e => e.packedEvent);
238
+
239
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
240
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
241
+ }
242
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
243
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
244
+ }
245
+
246
+ return events;
204
247
  }
205
248
 
206
249
  async advanceBlocksBy(blocks: number) {
@@ -216,27 +259,64 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
216
259
  this.nextBlockTimestamp += duration;
217
260
  }
218
261
 
219
- async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
262
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
263
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
264
+ }
265
+
266
+ async deploy(
267
+ contractPath: string,
268
+ initializer: string,
269
+ args: Fr[],
270
+ secret: Fr,
271
+ salt: Fr,
272
+ deployer: AztecAddress,
273
+ ): Promise<Fr[]> {
274
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
275
+ rootPath: this.rootPath,
276
+ packageName: this.packageName,
277
+ contractPath,
278
+ initializer,
279
+ args,
280
+ secret,
281
+ salt,
282
+ deployer,
283
+ });
284
+
220
285
  // Emit deployment nullifier
221
286
  await this.mineBlock({
222
- nullifiers: [
223
- await siloNullifier(
224
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
225
- instance.address.toField(),
226
- ),
227
- ],
287
+ nullifiers: [await this.deploymentNullifier(instance.address)],
228
288
  });
229
289
 
230
290
  if (!secret.equals(Fr.ZERO)) {
231
- await this.addAccount(artifact, instance, secret);
291
+ await this.registerContractAndAddAccount(artifact, instance, secret);
232
292
  } else {
233
293
  await this.contractStore.addContractInstance(instance);
234
294
  await this.contractStore.addContractArtifact(artifact);
235
295
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
236
296
  }
297
+
298
+ return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
299
+ }
300
+
301
+ /**
302
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
303
+ */
304
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
305
+ await this.mineBlock({
306
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
307
+ });
237
308
  }
238
309
 
239
- async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
310
+ async addAccount(secret: Fr) {
311
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
312
+ return this.registerContractAndAddAccount(artifact, instance, secret);
313
+ }
314
+
315
+ private async registerContractAndAddAccount(
316
+ artifact: ContractArtifact,
317
+ instance: ContractInstanceWithAddress,
318
+ secret: Fr,
319
+ ) {
240
320
  const partialAddress = await computePartialAddress(instance);
241
321
 
242
322
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
@@ -263,17 +343,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
263
343
 
264
344
  async addAuthWitness(address: AztecAddress, messageHash: Fr) {
265
345
  const account = await this.accountStore.getAccount(address);
266
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
346
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
347
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
267
348
 
268
349
  const schnorr = new Schnorr();
269
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
350
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
270
351
 
271
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
352
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
272
353
 
273
354
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
274
355
  }
275
356
 
276
- async mineBlock(options: { nullifiers?: Fr[] } = {}) {
357
+ setTaggingSecretStrategy(strategy: Option<TaggingSecretStrategy>): void {
358
+ this.taggingSecretStrategy = strategy.value;
359
+ }
360
+
361
+ async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
362
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
363
+ const { size } = await this.stateMachine.synchronizer
364
+ .getCommitted()
365
+ .getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
366
+ const leafIndex = new Fr(size);
367
+
368
+ const message = new L1ToL2Message(
369
+ new L1Actor(sender, this.chainId.toNumber()),
370
+ new L2Actor(recipient, this.version.toNumber()),
371
+ content,
372
+ secretHash,
373
+ leafIndex,
374
+ );
375
+
376
+ await this.mineBlock({ l1ToL2Messages: [message.hash()] });
377
+
378
+ return leafIndex;
379
+ }
380
+
381
+ async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
277
382
  const blockNumber = await this.getNextBlockNumber();
278
383
 
279
384
  const txEffect = TxEffect.empty();
@@ -281,7 +386,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
281
386
  txEffect.txHash = new TxHash(new Fr(blockNumber));
282
387
 
283
388
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
284
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
389
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
285
390
 
286
391
  const globals = makeGlobalVariables(undefined, {
287
392
  blockNumber,
@@ -295,17 +400,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
295
400
 
296
401
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
297
402
 
298
- await this.stateMachine.handleL2Block(block);
403
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
299
404
  }
300
405
 
301
406
  async privateCallNewFlow(
302
- from: AztecAddress,
407
+ from: AztecAddress | undefined,
303
408
  targetContractAddress: AztecAddress = AztecAddress.zero(),
304
409
  functionSelector: FunctionSelector = FunctionSelector.empty(),
305
410
  args: Fr[],
306
411
  argsHash: Fr = Fr.zero(),
307
412
  isStaticCall: boolean = false,
413
+ additionalScopes: AztecAddress[] = [],
308
414
  jobId: string,
415
+ authorizedUtilityCallTargets: AztecAddress[],
416
+ gasSettings: GasSettings,
309
417
  ) {
310
418
  this.logger.verbose(
311
419
  `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
@@ -319,13 +427,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
319
427
  throw new Error(message);
320
428
  }
321
429
 
322
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
323
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
324
- const effectiveScopes = from.isZero() ? [] : [from];
430
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
325
431
 
326
432
  // Sync notes before executing private function to discover notes from previous transactions
327
- const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
328
- await this.executeUtilityCall(call, execScopes, jobId);
433
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
434
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
329
435
  };
330
436
 
331
437
  const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
@@ -335,16 +441,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
335
441
  utilityExecutor,
336
442
  blockHeader,
337
443
  jobId,
338
- effectiveScopes,
444
+ scopes,
339
445
  );
340
446
 
341
447
  const blockNumber = await this.getNextBlockNumber();
342
448
 
343
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
344
-
345
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
346
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
347
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
449
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
450
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
348
451
 
349
452
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
350
453
 
@@ -359,6 +462,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
359
462
 
360
463
  const simulator = new WASMSimulator();
361
464
 
465
+ const transientArrayService = new TransientArrayService();
466
+ const taggingSecretStrategy = this.taggingSecretStrategy;
362
467
  const privateExecutionOracle = new PrivateExecutionOracle({
363
468
  argsHash,
364
469
  txContext,
@@ -377,19 +482,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
377
482
  aztecNode: this.stateMachine.node,
378
483
  senderTaggingStore: this.senderTaggingStore,
379
484
  recipientTaggingStore: this.recipientTaggingStore,
380
- senderAddressBookStore: this.senderAddressBookStore,
381
- capsuleStore: this.capsuleStore,
485
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
486
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
487
+ factService: new FactService(this.factStore, scopes),
382
488
  privateEventStore: this.privateEventStore,
383
489
  contractSyncService: this.stateMachine.contractSyncService,
384
490
  jobId,
385
491
  totalPublicCalldataCount: 0,
386
492
  sideEffectCounter: minRevertibleSideEffectCounter,
387
- scopes: effectiveScopes,
493
+ scopes,
388
494
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
389
495
  // contract would perform, including setting senderForTags.
390
496
  senderForTags: from,
391
497
  simulator,
392
- messageContextService: this.stateMachine.messageContextService,
498
+ txResolver: this.stateMachine.txResolver,
499
+ l2TipsStore: this.stateMachine.l2TipsProvider,
500
+ hooks: composeHooks({
501
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
502
+ isStaticCall ? 'private view' : 'private',
503
+ authorizedUtilityCallTargets,
504
+ ),
505
+ // Only configure the hook when a strategy was explicitly set, so that otherwise the default tagging secret
506
+ // strategy is exercised.
507
+ resolveTaggingSecretStrategy: taggingSecretStrategy ? () => Promise.resolve(taggingSecretStrategy) : undefined,
508
+ }),
509
+ transientArrayService,
393
510
  });
394
511
 
395
512
  // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
@@ -412,7 +529,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
412
529
  );
413
530
  const publicFunctionsCalldata = await Promise.all(
414
531
  publicCallRequests.map(async r => {
415
- const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
532
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
416
533
  return new HashedValues(calldata, r.calldataHash);
417
534
  }),
418
535
  );
@@ -497,11 +614,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
497
614
  }
498
615
  }
499
616
 
617
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
618
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
619
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
620
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
621
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
622
+
500
623
  if (isStaticCall) {
501
624
  await checkpoint!.revert();
502
625
 
503
626
  await forkedWorldTrees.close();
504
- return executionResult.returnValues ?? [];
627
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
505
628
  }
506
629
 
507
630
  const txEffect = TxEffect.empty();
@@ -523,14 +646,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
523
646
 
524
647
  await forkedWorldTrees.close();
525
648
 
526
- return executionResult.returnValues ?? [];
649
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
527
650
  }
528
651
 
529
652
  async publicCallNewFlow(
530
- from: AztecAddress,
653
+ from: AztecAddress | undefined,
531
654
  targetContractAddress: AztecAddress,
532
655
  calldata: Fr[],
533
656
  isStaticCall: boolean,
657
+ gasSettings: GasSettings,
534
658
  ) {
535
659
  this.logger.verbose(
536
660
  `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
@@ -538,12 +662,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
538
662
 
539
663
  const blockNumber = await this.getNextBlockNumber();
540
664
 
541
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
542
-
543
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
544
-
545
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
546
-
547
665
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
548
666
 
549
667
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
@@ -595,7 +713,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
595
713
  // may require producing reverts.
596
714
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
597
715
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
598
- from,
716
+ from ?? AztecAddress.NULL_MSG_SENDER,
599
717
  targetContractAddress,
600
718
  isStaticCall,
601
719
  calldataHash,
@@ -682,10 +800,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
682
800
  }
683
801
 
684
802
  async executeUtilityFunction(
803
+ from: AztecAddress | undefined,
685
804
  targetContractAddress: AztecAddress,
686
805
  functionSelector: FunctionSelector,
687
806
  args: Fr[],
688
807
  jobId: string,
808
+ authorizedUtilityCallTargets: AztecAddress[],
689
809
  ) {
690
810
  const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
691
811
  if (!artifact) {
@@ -698,11 +818,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
698
818
  targetContractAddress,
699
819
  functionSelector,
700
820
  async (call, execScopes) => {
701
- await this.executeUtilityCall(call, execScopes, jobId);
821
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
702
822
  },
703
823
  blockHeader,
704
824
  jobId,
705
- 'ALL_SCOPES',
825
+ await this.keyStore.getAccounts(),
706
826
  );
707
827
 
708
828
  const call = FunctionCall.from({
@@ -716,10 +836,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
716
836
  returnTypes: [],
717
837
  });
718
838
 
719
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
839
+ return this.executeUtilityCall(call, {
840
+ from,
841
+ scopes: await this.keyStore.getAccounts(),
842
+ jobId,
843
+ authorizedUtilityCallTargets,
844
+ });
720
845
  }
721
846
 
722
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
847
+ private async executeUtilityCall(
848
+ call: FunctionCall,
849
+ {
850
+ from = AztecAddress.NULL_MSG_SENDER,
851
+ scopes,
852
+ jobId,
853
+ authorizedUtilityCallTargets = [],
854
+ }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
855
+ ): Promise<Fr[]> {
723
856
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
724
857
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
725
858
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -732,8 +865,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
732
865
 
733
866
  try {
734
867
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
868
+ const simulator = new WASMSimulator();
869
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
870
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
871
+ };
735
872
  const oracle = new UtilityExecutionOracle({
736
- contractAddress: call.to,
873
+ callContext: CallContext.from({
874
+ msgSender: from,
875
+ contractAddress: call.to,
876
+ functionSelector: call.selector,
877
+ isStaticCall: true,
878
+ }),
737
879
  authWitnesses: [],
738
880
  capsules: [],
739
881
  anchorBlockHeader,
@@ -743,16 +885,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
743
885
  addressStore: this.addressStore,
744
886
  aztecNode: this.stateMachine.node,
745
887
  recipientTaggingStore: this.recipientTaggingStore,
746
- senderAddressBookStore: this.senderAddressBookStore,
747
- capsuleStore: this.capsuleStore,
888
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
889
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
890
+ factService: new FactService(this.factStore, scopes),
748
891
  privateEventStore: this.privateEventStore,
749
- messageContextService: this.stateMachine.messageContextService,
750
- contractSyncService: this.contractSyncService,
892
+ txResolver: this.stateMachine.txResolver,
893
+ contractSyncService: this.stateMachine.contractSyncService,
894
+ l2TipsStore: this.stateMachine.l2TipsProvider,
751
895
  jobId,
752
896
  scopes,
897
+ simulator,
898
+ hooks: composeHooks({
899
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
900
+ }),
901
+ utilityExecutor,
902
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
903
+ transientArrayService: new TransientArrayService(),
753
904
  });
754
- const acirExecutionResult = await new WASMSimulator()
755
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
905
+ const acirExecutionResult = await simulator
906
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
756
907
  .catch((err: Error) => {
757
908
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
758
909
  throw new ExecutionError(
@@ -773,13 +924,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
773
924
  }
774
925
  }
775
926
 
776
- close(): [bigint, Map<string, AuthWitness>] {
927
+ close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
777
928
  this.logger.debug('Exiting Top Level Context');
778
- return [this.nextBlockTimestamp, this.authwits];
929
+ return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
779
930
  }
780
931
 
781
932
  private async getLastBlockNumber(): Promise<BlockNumber> {
782
- const header = await this.stateMachine.node.getBlockHeader('latest');
783
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
933
+ const block = await this.stateMachine.node.getBlock('latest');
934
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
935
+ }
936
+
937
+ private buildAuthorizeUtilityCallHook(
938
+ callerContext: 'private' | 'private view' | 'utility',
939
+ authorizedTargets: AztecAddress[],
940
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
941
+ if (authorizedTargets.length === 0) {
942
+ return undefined;
943
+ }
944
+ return req =>
945
+ Promise.resolve({
946
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
947
+ });
784
948
  }
785
949
  }
@@ -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 = 2;
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 = '118698345ea9d368ca82ea574a051e72f4df0b85454539ade14838a934976b62';