@aztec/txe 0.0.1-commit.2f68f620 → 0.0.1-commit.321f6a9

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 (136) hide show
  1. package/dest/AuthRegistry-QVGDDH5X.js +3 -0
  2. package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
  3. package/dest/ContractClassRegistry-VWR3F42P.js +3 -0
  4. package/dest/ContractClassRegistry-VWR3F42P.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-FHIWE33X.js +3 -0
  6. package/dest/ContractInstanceRegistry-FHIWE33X.js.map +7 -0
  7. package/dest/FeeJuice-SAOWVGG7.js +3 -0
  8. package/dest/FeeJuice-SAOWVGG7.js.map +7 -0
  9. package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
  10. package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
  12. package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
  13. package/dest/SchnorrAccount-NME3E45O.js +3 -0
  14. package/dest/SchnorrAccount-NME3E45O.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.js +7 -15
  18. package/dest/bin/index.js +1 -1
  19. package/dest/bin/oracle_test_server.js +2 -2
  20. package/dest/chunk-32UHX7YY.js +3 -0
  21. package/dest/chunk-SZPMCTJK.js +260 -0
  22. package/dest/chunk-SZPMCTJK.js.map +7 -0
  23. package/dest/{chunk-W2NSX64C.js → chunk-YS3UIBVR.js} +2 -2
  24. package/dest/{chunk-W2NSX64C.js.map → chunk-YS3UIBVR.js.map} +3 -3
  25. package/dest/constants.d.ts +1 -1
  26. package/dest/constants.d.ts.map +1 -1
  27. package/dest/constants.js +1 -1
  28. package/dest/dispatcher_pool.d.ts +2 -2
  29. package/dest/dispatcher_pool.d.ts.map +1 -1
  30. package/dest/dispatcher_pool.js +5 -3
  31. package/dest/index.d.ts +2 -136
  32. package/dest/index.d.ts.map +1 -1
  33. package/dest/index.js +5 -3
  34. package/dest/metafile.json +9632 -7418
  35. package/dest/oracle/interfaces.d.ts +24 -11
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  38. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  39. package/dest/oracle/tagging_secret_strategy.js +12 -0
  40. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  41. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  42. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  43. package/dest/oracle/test-resolver/index.d.ts +1 -1
  44. package/dest/oracle/test-resolver/index.d.ts.map +1 -1
  45. package/dest/oracle/test-resolver/index.js +1 -2
  46. package/dest/oracle/test-resolver/resolver.d.ts +21 -7
  47. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -1
  48. package/dest/oracle/test-resolver/resolver.js +100 -33
  49. package/dest/oracle/txe_oracle_public_context.d.ts +9 -9
  50. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  51. package/dest/oracle/txe_oracle_public_context.js +15 -9
  52. package/dest/oracle/txe_oracle_registry.d.ts +51 -26
  53. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
  54. package/dest/oracle/txe_oracle_registry.js +258 -53
  55. package/dest/oracle/txe_oracle_top_level_context.d.ts +30 -9
  56. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_top_level_context.js +454 -288
  58. package/dest/oracle/txe_oracle_version.d.ts +4 -4
  59. package/dest/oracle/txe_oracle_version.js +4 -4
  60. package/dest/rpc_translator.d.ts +23 -4
  61. package/dest/rpc_translator.d.ts.map +1 -1
  62. package/dest/rpc_translator.js +167 -81
  63. package/dest/server.bundle.js +1 -1
  64. package/dest/state_machine/archiver.d.ts +1 -1
  65. package/dest/state_machine/archiver.d.ts.map +1 -1
  66. package/dest/state_machine/archiver.js +1 -2
  67. package/dest/state_machine/dummy_p2p_client.d.ts +5 -2
  68. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  69. package/dest/state_machine/dummy_p2p_client.js +9 -0
  70. package/dest/state_machine/global_variable_builder.d.ts +3 -4
  71. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  72. package/dest/state_machine/global_variable_builder.js +0 -3
  73. package/dest/state_machine/index.d.ts +8 -6
  74. package/dest/state_machine/index.d.ts.map +1 -1
  75. package/dest/state_machine/index.js +41 -19
  76. package/dest/state_machine/synchronizer.d.ts +10 -2
  77. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  78. package/dest/state_machine/synchronizer.js +18 -5
  79. package/dest/txe_session.d.ts +29 -20
  80. package/dest/txe_session.d.ts.map +1 -1
  81. package/dest/txe_session.js +165 -41
  82. package/dest/utils/block_creation.d.ts +2 -2
  83. package/dest/utils/block_creation.d.ts.map +1 -1
  84. package/dest/utils/block_creation.js +2 -2
  85. package/dest/utils/encoding.d.ts +4 -3
  86. package/dest/utils/encoding.d.ts.map +1 -1
  87. package/dest/utils/tx_effect_creation.d.ts +1 -1
  88. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  89. package/dest/utils/tx_effect_creation.js +0 -1
  90. package/dest/utils/txe_public_contract_data_source.d.ts +1 -1
  91. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -1
  92. package/dest/utils/txe_public_contract_data_source.js +7 -4
  93. package/dest/worker.bundle.js +1 -1
  94. package/package.json +17 -17
  95. package/src/bin/check_txe_oracle_version.ts +9 -12
  96. package/src/bin/oracle_test_server.ts +2 -2
  97. package/src/constants.ts +1 -1
  98. package/src/dispatcher_pool.ts +4 -3
  99. package/src/index.ts +6 -4
  100. package/src/oracle/interfaces.ts +26 -9
  101. package/src/oracle/tagging_secret_strategy.ts +25 -0
  102. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  103. package/src/oracle/test-resolver/index.ts +1 -2
  104. package/src/oracle/test-resolver/resolver.ts +121 -41
  105. package/src/oracle/txe_oracle_public_context.ts +16 -14
  106. package/src/oracle/txe_oracle_registry.ts +197 -42
  107. package/src/oracle/txe_oracle_top_level_context.ts +201 -66
  108. package/src/oracle/txe_oracle_version.ts +4 -4
  109. package/src/rpc_translator.ts +224 -108
  110. package/src/state_machine/archiver.ts +0 -1
  111. package/src/state_machine/dummy_p2p_client.ts +13 -0
  112. package/src/state_machine/global_variable_builder.ts +2 -16
  113. package/src/state_machine/index.ts +50 -34
  114. package/src/state_machine/synchronizer.ts +26 -5
  115. package/src/txe_session.ts +284 -45
  116. package/src/utils/block_creation.ts +2 -1
  117. package/src/utils/tx_effect_creation.ts +0 -2
  118. package/src/utils/txe_public_contract_data_source.ts +6 -4
  119. package/dest/ContractClassRegistry-PII7Q556.js +0 -3
  120. package/dest/ContractClassRegistry-PII7Q556.js.map +0 -7
  121. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +0 -3
  122. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +0 -7
  123. package/dest/FeeJuice-TQV5AQK7.js +0 -3
  124. package/dest/FeeJuice-TQV5AQK7.js.map +0 -7
  125. package/dest/MultiCallEntrypoint-SBJUIJY7.js +0 -3
  126. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +0 -7
  127. package/dest/SchnorrAccount-MQXPIZ44.js +0 -3
  128. package/dest/SchnorrAccount-MQXPIZ44.js.map +0 -7
  129. package/dest/chunk-BJVAAXNA.js +0 -3
  130. package/dest/chunk-CDITIZHX.js +0 -257
  131. package/dest/chunk-CDITIZHX.js.map +0 -7
  132. package/dest/oracle/test-resolver/fixtures.d.ts +0 -43
  133. package/dest/oracle/test-resolver/fixtures.d.ts.map +0 -1
  134. package/dest/oracle/test-resolver/fixtures.js +0 -39
  135. package/src/oracle/test-resolver/fixtures.ts +0 -84
  136. /package/dest/{chunk-BJVAAXNA.js.map → chunk-32UHX7YY.js.map} +0 -0
@@ -1,11 +1,76 @@
1
+ function _ts_add_disposable_resource(env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() {
16
+ try {
17
+ inner.call(this);
18
+ } catch (e) {
19
+ return Promise.reject(e);
20
+ }
21
+ };
22
+ env.stack.push({
23
+ value: value,
24
+ dispose: dispose,
25
+ async: async
26
+ });
27
+ } else if (async) {
28
+ env.stack.push({
29
+ async: true
30
+ });
31
+ }
32
+ return value;
33
+ }
34
+ function _ts_dispose_resources(env) {
35
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
36
+ var e = new Error(message);
37
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
38
+ };
39
+ return (_ts_dispose_resources = function _ts_dispose_resources(env) {
40
+ function fail(e) {
41
+ env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
42
+ env.hasError = true;
43
+ }
44
+ var r, s = 0;
45
+ function next() {
46
+ while(r = env.stack.pop()){
47
+ try {
48
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
49
+ if (r.dispose) {
50
+ var result = r.dispose.call(r.value);
51
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
52
+ fail(e);
53
+ return next();
54
+ });
55
+ } else s |= 1;
56
+ } catch (e) {
57
+ fail(e);
58
+ }
59
+ }
60
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
61
+ if (env.hasError) throw env.error;
62
+ }
63
+ return next();
64
+ })(env);
65
+ }
1
66
  import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
67
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
68
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
4
69
  import { Fr } from '@aztec/foundation/curves/bn254';
5
70
  import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
6
71
  import { TestDateProvider } from '@aztec/foundation/timer';
7
- import { CapsuleService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
8
- import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
72
+ import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
73
+ import { CONTRACT_INSTANCE, ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, TransientArrayService, UtilityExecutionOracle, buildACIRCallback, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
9
74
  import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
10
75
  import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, PublicTxSimulator } from '@aztec/simulator/server';
11
76
  import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
@@ -16,7 +81,9 @@ import { computePartialAddress } from '@aztec/stdlib/contract';
16
81
  import { Gas, GasFees } from '@aztec/stdlib/gas';
17
82
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
18
83
  import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
19
- import { hashPublicKey } from '@aztec/stdlib/keys';
84
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
85
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
86
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
20
87
  import { ChonkProof } from '@aztec/stdlib/proofs';
21
88
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
22
89
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -25,6 +92,7 @@ import { ForkCheckpoint } from '@aztec/world-state/native';
25
92
  import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
26
93
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
27
94
  import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
95
+ import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
28
96
  export class TXEOracleTopLevelContext {
29
97
  stateMachine;
30
98
  contractStore;
@@ -34,20 +102,23 @@ export class TXEOracleTopLevelContext {
34
102
  accountStore;
35
103
  senderTaggingStore;
36
104
  recipientTaggingStore;
37
- senderAddressBookStore;
105
+ taggingSecretSourcesStore;
38
106
  capsuleStore;
107
+ factStore;
39
108
  privateEventStore;
40
109
  nextBlockTimestamp;
41
110
  version;
42
111
  chainId;
43
112
  authwits;
113
+ taggingSecretStrategies;
114
+ authorizeAllUtilityCallTargets;
44
115
  artifactResolver;
45
116
  rootPath;
46
117
  packageName;
47
118
  isMisc;
48
119
  isTxe;
49
120
  logger;
50
- constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, artifactResolver, rootPath, packageName){
121
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
51
122
  this.stateMachine = stateMachine;
52
123
  this.contractStore = contractStore;
53
124
  this.noteStore = noteStore;
@@ -56,13 +127,16 @@ export class TXEOracleTopLevelContext {
56
127
  this.accountStore = accountStore;
57
128
  this.senderTaggingStore = senderTaggingStore;
58
129
  this.recipientTaggingStore = recipientTaggingStore;
59
- this.senderAddressBookStore = senderAddressBookStore;
130
+ this.taggingSecretSourcesStore = taggingSecretSourcesStore;
60
131
  this.capsuleStore = capsuleStore;
132
+ this.factStore = factStore;
61
133
  this.privateEventStore = privateEventStore;
62
134
  this.nextBlockTimestamp = nextBlockTimestamp;
63
135
  this.version = version;
64
136
  this.chainId = chainId;
65
137
  this.authwits = authwits;
138
+ this.taggingSecretStrategies = taggingSecretStrategies;
139
+ this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
66
140
  this.artifactResolver = artifactResolver;
67
141
  this.rootPath = rootPath;
68
142
  this.packageName = packageName;
@@ -142,7 +216,10 @@ export class TXEOracleTopLevelContext {
142
216
  }
143
217
  const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
144
218
  await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
145
- await this.executeUtilityCall(call, execScopes, jobId);
219
+ await this.executeUtilityCall(call, {
220
+ scopes: execScopes,
221
+ jobId
222
+ });
146
223
  }, blockHeader, jobId, [
147
224
  scope
148
225
  ]);
@@ -175,7 +252,7 @@ export class TXEOracleTopLevelContext {
175
252
  this.nextBlockTimestamp += duration;
176
253
  }
177
254
  deploymentNullifier(address) {
178
- return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
255
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
179
256
  }
180
257
  async deploy(contractPath, initializer, args, secret, salt, deployer) {
181
258
  const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
@@ -201,14 +278,7 @@ export class TXEOracleTopLevelContext {
201
278
  await this.contractStore.addContractArtifact(artifact);
202
279
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
203
280
  }
204
- return [
205
- instance.salt,
206
- instance.deployer.toField(),
207
- instance.currentContractClassId,
208
- instance.initializationHash,
209
- instance.immutablesHash,
210
- ...instance.publicKeys.toFields()
211
- ];
281
+ return CONTRACT_INSTANCE.serialization.fn(instance).flat();
212
282
  }
213
283
  /**
214
284
  * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
@@ -226,15 +296,14 @@ export class TXEOracleTopLevelContext {
226
296
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
227
297
  await this.contractStore.addContractInstance(instance);
228
298
  await this.contractStore.addContractArtifact(artifact);
229
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
299
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
230
300
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
231
301
  await this.addressStore.addCompleteAddress(completeAddress);
232
302
  this.logger.debug(`Created account ${completeAddress.address}`);
233
303
  return completeAddress;
234
304
  }
235
- async createAccount(secret) {
236
- // This is a foot gun !
237
- const completeAddress = await this.keyStore.addAccount(secret, secret);
305
+ async createAccount(secret, partialAddress) {
306
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
238
307
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
239
308
  await this.addressStore.addCompleteAddress(completeAddress);
240
309
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -249,6 +318,32 @@ export class TXEOracleTopLevelContext {
249
318
  const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
250
319
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
251
320
  }
321
+ setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
322
+ const apply = (mode, strategy)=>{
323
+ if (strategy.isSome()) {
324
+ this.taggingSecretStrategies.set(mode, strategy.value);
325
+ } else {
326
+ this.taggingSecretStrategies.delete(mode);
327
+ }
328
+ };
329
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
330
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
331
+ }
332
+ setAuthorizeAllUtilityCallTargets(authorizeAll) {
333
+ this.authorizeAllUtilityCallTargets = authorizeAll;
334
+ }
335
+ async sendL1ToL2Message(content, secretHash, sender, recipient) {
336
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
337
+ const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
338
+ const leafIndex = new Fr(size);
339
+ const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
340
+ await this.mineBlock({
341
+ l1ToL2Messages: [
342
+ message.hash()
343
+ ]
344
+ });
345
+ return leafIndex;
346
+ }
252
347
  async mineBlock(options = {}) {
253
348
  const blockNumber = await this.getNextBlockNumber();
254
349
  const txEffect = TxEffect.empty();
@@ -258,7 +353,7 @@ export class TXEOracleTopLevelContext {
258
353
  ];
259
354
  txEffect.txHash = new TxHash(new Fr(blockNumber));
260
355
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
261
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
356
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
262
357
  const globals = makeGlobalVariables(undefined, {
263
358
  blockNumber,
264
359
  timestamp: this.nextBlockTimestamp,
@@ -270,280 +365,319 @@ export class TXEOracleTopLevelContext {
270
365
  ]);
271
366
  await forkedWorldTrees.close();
272
367
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
273
- await this.stateMachine.handleL2Block(block);
368
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
274
369
  }
275
370
  async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
276
- this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
277
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
278
- if (!artifact) {
279
- const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
280
- throw new Error(message);
281
- }
282
- const scopes = from === undefined ? additionalScopes : [
283
- from,
284
- ...additionalScopes
285
- ];
286
- // Sync notes before executing private function to discover notes from previous transactions
287
- const utilityExecutor = async (call, execScopes)=>{
288
- await this.executeUtilityCall(call, execScopes, jobId);
371
+ const env = {
372
+ stack: [],
373
+ error: void 0,
374
+ hasError: false
289
375
  };
290
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
291
- await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
292
- const blockNumber = await this.getNextBlockNumber();
293
- const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
294
- const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
295
- const txContext = new TxContext(this.chainId, this.version, gasSettings);
296
- const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
297
- const noteCache = new ExecutionNoteCache(protocolNullifier);
298
- // In production, the account contract sets the min revertible counter before calling the app function.
299
- // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
300
- // marking all side effects as revertible.
301
- const minRevertibleSideEffectCounter = 1;
302
- await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
303
- const taggingIndexCache = new ExecutionTaggingIndexCache();
304
- const simulator = new WASMSimulator();
305
- const privateExecutionOracle = new PrivateExecutionOracle({
306
- argsHash,
307
- txContext,
308
- callContext,
309
- anchorBlockHeader: blockHeader,
310
- utilityExecutor,
311
- authWitnesses: Array.from(this.authwits.values()),
312
- capsules: [],
313
- executionCache: HashedValuesCache.create([
314
- new HashedValues(args, argsHash)
315
- ]),
316
- noteCache,
317
- taggingIndexCache,
318
- contractStore: this.contractStore,
319
- noteStore: this.noteStore,
320
- keyStore: this.keyStore,
321
- addressStore: this.addressStore,
322
- aztecNode: this.stateMachine.node,
323
- senderTaggingStore: this.senderTaggingStore,
324
- recipientTaggingStore: this.recipientTaggingStore,
325
- senderAddressBookStore: this.senderAddressBookStore,
326
- capsuleService: new CapsuleService(this.capsuleStore, scopes),
327
- privateEventStore: this.privateEventStore,
328
- contractSyncService: this.stateMachine.contractSyncService,
329
- jobId,
330
- totalPublicCalldataCount: 0,
331
- sideEffectCounter: minRevertibleSideEffectCounter,
332
- scopes,
333
- // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
334
- // contract would perform, including setting senderForTags.
335
- senderForTags: from,
336
- simulator,
337
- messageContextService: this.stateMachine.messageContextService,
338
- l2TipsStore: this.stateMachine.l2TipsProvider,
339
- hooks: composeHooks({
340
- authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets)
341
- })
342
- });
343
- // 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.
344
- let result;
345
- let executionResult;
346
376
  try {
347
- executionResult = await executePrivateFunction(simulator, privateExecutionOracle, artifact, targetContractAddress, functionSelector);
348
- const publicCallRequests = collectNested([
377
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
378
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
379
+ this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
380
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
381
+ if (!artifact) {
382
+ const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
383
+ throw new Error(message);
384
+ }
385
+ const scopes = from === undefined ? additionalScopes : [
386
+ from,
387
+ ...additionalScopes
388
+ ];
389
+ // Sync notes before executing private function to discover notes from previous transactions
390
+ const utilityExecutor = async (call, execScopes)=>{
391
+ await this.executeUtilityCall(call, {
392
+ scopes: execScopes,
393
+ jobId
394
+ });
395
+ };
396
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
397
+ const blockNumber = await this.getNextBlockNumber();
398
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
399
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
400
+ const txContext = new TxContext(this.chainId, this.version, gasSettings);
401
+ const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
402
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
403
+ // In production, the account contract sets the min revertible counter before calling the app function.
404
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
405
+ // marking all side effects as revertible.
406
+ const minRevertibleSideEffectCounter = 1;
407
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
408
+ const taggingIndexCache = new ExecutionTaggingIndexCache();
409
+ const simulator = new WASMSimulator();
410
+ const transientArrayService = new TransientArrayService();
411
+ const privateExecutionOracle = new PrivateExecutionOracle({
412
+ argsHash,
413
+ txContext,
414
+ txRequestSalt: Fr.ZERO,
415
+ callContext,
416
+ anchorBlockHeader: blockHeader,
417
+ utilityExecutor,
418
+ authWitnesses: Array.from(this.authwits.values()),
419
+ capsules: [],
420
+ executionCache: HashedValuesCache.create([
421
+ new HashedValues(args, argsHash)
422
+ ]),
423
+ noteCache,
424
+ taggingIndexCache,
425
+ anchoredContractData,
426
+ noteStore: this.noteStore,
427
+ keyStore: this.keyStore,
428
+ addressStore: this.addressStore,
429
+ aztecNode: this.stateMachine.node,
430
+ senderTaggingStore: this.senderTaggingStore,
431
+ recipientTaggingStore: this.recipientTaggingStore,
432
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
433
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
434
+ factService: new FactService(this.factStore, scopes),
435
+ privateEventStore: this.privateEventStore,
436
+ contractSyncService: this.stateMachine.contractSyncService,
437
+ jobId,
438
+ totalPublicCalldataCount: 0,
439
+ sideEffectCounter: minRevertibleSideEffectCounter,
440
+ scopes,
441
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
442
+ // contract would perform, including setting senderForTags.
443
+ senderForTags: from,
444
+ simulator,
445
+ txResolver: this.stateMachine.txResolver,
446
+ l2TipsStore: this.stateMachine.l2TipsProvider,
447
+ hooks: composeHooks({
448
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
449
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
450
+ }),
451
+ transientArrayService
452
+ });
453
+ // 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.
454
+ let result;
455
+ let executionResult;
456
+ try {
457
+ executionResult = await executePrivateFunction(simulator, privateExecutionOracle, artifact, targetContractAddress, functionSelector);
458
+ const publicCallRequests = collectNested([
459
+ executionResult
460
+ ], (r)=>r.publicInputs.publicCallRequests.getActiveItems().map((r)=>r.inner).concat(r.publicInputs.publicTeardownCallRequest.isEmpty() ? [] : [
461
+ r.publicInputs.publicTeardownCallRequest
462
+ ]));
463
+ const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
464
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
465
+ return new HashedValues(calldata, r.calldataHash);
466
+ }));
467
+ const nonceGenerator = noteCache.getNonceGenerator();
468
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
469
+ } catch (err) {
470
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
471
+ }
472
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
473
+ // the nonce generator for the note hashes.
474
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
475
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
476
+ const globals = makeGlobalVariables();
477
+ globals.blockNumber = blockNumber;
478
+ globals.timestamp = this.nextBlockTimestamp;
479
+ globals.chainId = this.chainId;
480
+ globals.version = this.version;
481
+ globals.gasFees = GasFees.empty();
482
+ const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
483
+ const bindings = this.logger.getBindings();
484
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
485
+ const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
486
+ const config = PublicSimulatorConfig.from({
487
+ skipFeeEnforcement: true,
488
+ collectDebugLogs: true,
489
+ collectHints: false,
490
+ collectStatistics: false,
491
+ collectCallMetadata: true
492
+ });
493
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
494
+ const forkId = forkedWorldTrees.getRevision().forkId;
495
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new PublicTxSimulator(this.stateMachine.synchronizer.avmSimulator, globals, contractsDB, forkId, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
496
+ const tx = await Tx.create({
497
+ data: publicInputs,
498
+ chonkProof: ChonkProof.empty(),
499
+ contractClassLogFields: [],
500
+ publicFunctionCalldata: result.publicFunctionCalldata
501
+ });
502
+ let checkpoint;
503
+ if (isStaticCall) {
504
+ checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
505
+ }
506
+ const results = await processor.process([
507
+ tx
508
+ ]);
509
+ const [processedTx] = results[0];
510
+ const failedTxs = results[1];
511
+ if (failedTxs.length !== 0) {
512
+ throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
513
+ } else if (!processedTx.revertCode.isOK()) {
514
+ if (processedTx.revertReason) {
515
+ try {
516
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
517
+ // eslint-disable-next-line no-empty
518
+ } catch {}
519
+ throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
520
+ } else {
521
+ throw new Error('Contract execution has reverted');
522
+ }
523
+ }
524
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
525
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
526
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
527
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
528
+ const offchainEffects = collectNested([
349
529
  executionResult
350
- ], (r)=>r.publicInputs.publicCallRequests.getActiveItems().map((r)=>r.inner).concat(r.publicInputs.publicTeardownCallRequest.isEmpty() ? [] : [
351
- r.publicInputs.publicTeardownCallRequest
352
- ]));
353
- const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
354
- const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
355
- return new HashedValues(calldata, r.calldataHash);
356
- }));
357
- noteCache.finish();
358
- const nonceGenerator = noteCache.getNonceGenerator();
359
- result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
360
- } catch (err) {
361
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
362
- }
363
- // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
364
- // the nonce generator for the note hashes.
365
- // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
366
- const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
367
- const globals = makeGlobalVariables();
368
- globals.blockNumber = blockNumber;
369
- globals.timestamp = this.nextBlockTimestamp;
370
- globals.chainId = this.chainId;
371
- globals.version = this.version;
372
- globals.gasFees = GasFees.empty();
373
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
374
- const bindings = this.logger.getBindings();
375
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
376
- const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
377
- const config = PublicSimulatorConfig.from({
378
- skipFeeEnforcement: true,
379
- collectDebugLogs: true,
380
- collectHints: false,
381
- collectStatistics: false,
382
- collectCallMetadata: true
383
- });
384
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
385
- const tx = await Tx.create({
386
- data: publicInputs,
387
- chonkProof: ChonkProof.empty(),
388
- contractClassLogFields: [],
389
- publicFunctionCalldata: result.publicFunctionCalldata
390
- });
391
- let checkpoint;
392
- if (isStaticCall) {
393
- checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
394
- }
395
- const results = await processor.process([
396
- tx
397
- ]);
398
- const [processedTx] = results[0];
399
- const failedTxs = results[1];
400
- if (failedTxs.length !== 0) {
401
- throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
402
- } else if (!processedTx.revertCode.isOK()) {
403
- if (processedTx.revertReason) {
404
- try {
405
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
406
- // eslint-disable-next-line no-empty
407
- } catch {}
408
- throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
409
- } else {
410
- throw new Error('Contract execution has reverted');
530
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
531
+ if (isStaticCall) {
532
+ await checkpoint.revert();
533
+ return {
534
+ returnValues: executionResult.returnValues ?? [],
535
+ offchainEffects
536
+ };
411
537
  }
412
- }
413
- // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
414
- // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
415
- // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
416
- // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
417
- const offchainEffects = collectNested([
418
- executionResult
419
- ], (r)=>r.offchainEffects.map((e)=>e.data));
420
- if (isStaticCall) {
421
- await checkpoint.revert();
422
- await forkedWorldTrees.close();
538
+ const txEffect = TxEffect.empty();
539
+ txEffect.noteHashes = processedTx.txEffect.noteHashes;
540
+ txEffect.nullifiers = processedTx.txEffect.nullifiers;
541
+ txEffect.privateLogs = processedTx.txEffect.privateLogs;
542
+ txEffect.publicLogs = processedTx.txEffect.publicLogs;
543
+ txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
544
+ txEffect.txHash = new TxHash(new Fr(blockNumber));
545
+ const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
546
+ await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
547
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
548
+ txEffect
549
+ ]);
550
+ await this.stateMachine.handleL2Block(l2Block);
423
551
  return {
424
552
  returnValues: executionResult.returnValues ?? [],
425
553
  offchainEffects
426
554
  };
555
+ } catch (e) {
556
+ env.error = e;
557
+ env.hasError = true;
558
+ } finally{
559
+ const result = _ts_dispose_resources(env);
560
+ if (result) await result;
427
561
  }
428
- const txEffect = TxEffect.empty();
429
- txEffect.noteHashes = processedTx.txEffect.noteHashes;
430
- txEffect.nullifiers = processedTx.txEffect.nullifiers;
431
- txEffect.privateLogs = processedTx.txEffect.privateLogs;
432
- txEffect.publicLogs = processedTx.txEffect.publicLogs;
433
- txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
434
- txEffect.txHash = new TxHash(new Fr(blockNumber));
435
- const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
436
- await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
437
- const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
438
- txEffect
439
- ]);
440
- await this.stateMachine.handleL2Block(l2Block);
441
- await forkedWorldTrees.close();
442
- return {
443
- returnValues: executionResult.returnValues ?? [],
444
- offchainEffects
445
- };
446
562
  }
447
563
  async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
448
- this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
449
- const blockNumber = await this.getNextBlockNumber();
450
- const txContext = new TxContext(this.chainId, this.version, gasSettings);
451
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
452
- const calldataHash = await computeCalldataHash(calldata);
453
- const calldataHashedValues = new HashedValues(calldata, calldataHash);
454
- const globals = makeGlobalVariables();
455
- globals.blockNumber = blockNumber;
456
- globals.timestamp = this.nextBlockTimestamp;
457
- globals.chainId = this.chainId;
458
- globals.version = this.version;
459
- globals.gasFees = GasFees.empty();
460
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
461
- const bindings2 = this.logger.getBindings();
462
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
463
- const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
464
- const config = PublicSimulatorConfig.from({
465
- skipFeeEnforcement: true,
466
- collectDebugLogs: true,
467
- collectHints: false,
468
- collectStatistics: false,
469
- collectCallMetadata: true
470
- });
471
- const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
472
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
473
- // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
474
- // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
475
- // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
476
- // unique.
477
- const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
478
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
479
- // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
480
- // may require producing reverts.
481
- const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
482
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
483
- const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
484
- const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
485
- const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
486
- const tx = await Tx.create({
487
- data: txData,
488
- chonkProof: ChonkProof.empty(),
489
- contractClassLogFields: [],
490
- publicFunctionCalldata: [
491
- calldataHashedValues
492
- ]
493
- });
494
- let checkpoint;
495
- if (isStaticCall) {
496
- checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
497
- }
498
- const results = await processor.process([
499
- tx
500
- ]);
501
- const [processedTx] = results[0];
502
- const failedTxs = results[1];
503
- if (failedTxs.length !== 0) {
504
- throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
505
- } else if (!processedTx.revertCode.isOK()) {
506
- if (processedTx.revertReason) {
507
- try {
508
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
509
- // eslint-disable-next-line no-empty
510
- } catch {}
511
- throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
512
- } else {
513
- throw new Error('Contract execution has reverted');
564
+ const env = {
565
+ stack: [],
566
+ error: void 0,
567
+ hasError: false
568
+ };
569
+ try {
570
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
571
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
572
+ this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
573
+ const blockNumber = await this.getNextBlockNumber();
574
+ const txContext = new TxContext(this.chainId, this.version, gasSettings);
575
+ const calldataHash = await computeCalldataHash(calldata);
576
+ const calldataHashedValues = new HashedValues(calldata, calldataHash);
577
+ const globals = makeGlobalVariables();
578
+ globals.blockNumber = blockNumber;
579
+ globals.timestamp = this.nextBlockTimestamp;
580
+ globals.chainId = this.chainId;
581
+ globals.version = this.version;
582
+ globals.gasFees = GasFees.empty();
583
+ const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
584
+ const bindings2 = this.logger.getBindings();
585
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
586
+ const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
587
+ const config = PublicSimulatorConfig.from({
588
+ skipFeeEnforcement: true,
589
+ collectDebugLogs: true,
590
+ collectHints: false,
591
+ collectStatistics: false,
592
+ collectCallMetadata: true
593
+ });
594
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
595
+ const forkId2 = forkedWorldTrees.getRevision().forkId;
596
+ const simulator = new PublicTxSimulator(this.stateMachine.synchronizer.avmSimulator, globals, contractsDB, forkId2, config, bindings2);
597
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
598
+ // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
599
+ // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
600
+ // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
601
+ // unique.
602
+ const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
603
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
604
+ // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
605
+ // may require producing reverts.
606
+ const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
607
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
608
+ const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
609
+ const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
610
+ const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
611
+ const tx = await Tx.create({
612
+ data: txData,
613
+ chonkProof: ChonkProof.empty(),
614
+ contractClassLogFields: [],
615
+ publicFunctionCalldata: [
616
+ calldataHashedValues
617
+ ]
618
+ });
619
+ let checkpoint;
620
+ if (isStaticCall) {
621
+ checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
514
622
  }
515
- }
516
- const returnValues = results[3][0].values;
517
- if (isStaticCall) {
518
- await checkpoint.revert();
519
- await forkedWorldTrees.close();
623
+ const results = await processor.process([
624
+ tx
625
+ ]);
626
+ const [processedTx] = results[0];
627
+ const failedTxs = results[1];
628
+ if (failedTxs.length !== 0) {
629
+ throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
630
+ } else if (!processedTx.revertCode.isOK()) {
631
+ if (processedTx.revertReason) {
632
+ try {
633
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
634
+ // eslint-disable-next-line no-empty
635
+ } catch {}
636
+ throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
637
+ } else {
638
+ throw new Error('Contract execution has reverted');
639
+ }
640
+ }
641
+ const returnValues = results[3][0].values;
642
+ if (isStaticCall) {
643
+ await checkpoint.revert();
644
+ return returnValues ?? [];
645
+ }
646
+ const txEffect = TxEffect.empty();
647
+ txEffect.noteHashes = processedTx.txEffect.noteHashes;
648
+ txEffect.nullifiers = processedTx.txEffect.nullifiers;
649
+ txEffect.privateLogs = processedTx.txEffect.privateLogs;
650
+ txEffect.publicLogs = processedTx.txEffect.publicLogs;
651
+ txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
652
+ txEffect.txHash = new TxHash(new Fr(blockNumber));
653
+ const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
654
+ await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
655
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
656
+ txEffect
657
+ ]);
658
+ await this.stateMachine.handleL2Block(l2Block);
520
659
  return returnValues ?? [];
660
+ } catch (e) {
661
+ env.error = e;
662
+ env.hasError = true;
663
+ } finally{
664
+ const result = _ts_dispose_resources(env);
665
+ if (result) await result;
521
666
  }
522
- const txEffect = TxEffect.empty();
523
- txEffect.noteHashes = processedTx.txEffect.noteHashes;
524
- txEffect.nullifiers = processedTx.txEffect.nullifiers;
525
- txEffect.privateLogs = processedTx.txEffect.privateLogs;
526
- txEffect.publicLogs = processedTx.txEffect.publicLogs;
527
- txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
528
- txEffect.txHash = new TxHash(new Fr(blockNumber));
529
- const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
530
- await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
531
- const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
532
- txEffect
533
- ]);
534
- await this.stateMachine.handleL2Block(l2Block);
535
- await forkedWorldTrees.close();
536
- return returnValues ?? [];
537
667
  }
538
- async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
539
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
668
+ async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
669
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
670
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
671
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
540
672
  if (!artifact) {
541
673
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
542
674
  }
543
675
  // Sync notes before executing utility function to discover notes from previous transactions
544
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
545
676
  await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
546
- await this.executeUtilityCall(call, execScopes, jobId);
677
+ await this.executeUtilityCall(call, {
678
+ scopes: execScopes,
679
+ jobId
680
+ });
547
681
  }, blockHeader, jobId, await this.keyStore.getAccounts());
548
682
  const call = FunctionCall.from({
549
683
  name: artifact.name,
@@ -555,10 +689,20 @@ export class TXEOracleTopLevelContext {
555
689
  args,
556
690
  returnTypes: []
557
691
  });
558
- return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
692
+ return this.executeUtilityCall(call, {
693
+ from,
694
+ scopes: await this.keyStore.getAccounts(),
695
+ jobId,
696
+ authorizedUtilityCallTargets
697
+ });
559
698
  }
560
- async executeUtilityCall(call, scopes, jobId, authorizedUtilityCallTargets = []) {
561
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
699
+ async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
700
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
701
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
702
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
703
+ if (!entryPointArtifact) {
704
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
705
+ }
562
706
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
563
707
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
564
708
  }
@@ -567,26 +711,34 @@ export class TXEOracleTopLevelContext {
567
711
  selector: call.selector
568
712
  });
569
713
  try {
570
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
571
714
  const simulator = new WASMSimulator();
572
715
  const utilityExecutor = async (syncCall, execScopes)=>{
573
- await this.executeUtilityCall(syncCall, execScopes, jobId);
716
+ await this.executeUtilityCall(syncCall, {
717
+ scopes: execScopes,
718
+ jobId
719
+ });
574
720
  };
575
721
  const oracle = new UtilityExecutionOracle({
576
- contractAddress: call.to,
722
+ callContext: CallContext.from({
723
+ msgSender: from,
724
+ contractAddress: call.to,
725
+ functionSelector: call.selector,
726
+ isStaticCall: true
727
+ }),
577
728
  authWitnesses: [],
578
729
  capsules: [],
579
730
  anchorBlockHeader,
580
- contractStore: this.contractStore,
731
+ anchoredContractData,
581
732
  noteStore: this.noteStore,
582
733
  keyStore: this.keyStore,
583
734
  addressStore: this.addressStore,
584
735
  aztecNode: this.stateMachine.node,
585
736
  recipientTaggingStore: this.recipientTaggingStore,
586
- senderAddressBookStore: this.senderAddressBookStore,
737
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
587
738
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
739
+ factService: new FactService(this.factStore, scopes),
588
740
  privateEventStore: this.privateEventStore,
589
- messageContextService: this.stateMachine.messageContextService,
741
+ txResolver: this.stateMachine.txResolver,
590
742
  contractSyncService: this.stateMachine.contractSyncService,
591
743
  l2TipsStore: this.stateMachine.l2TipsProvider,
592
744
  jobId,
@@ -595,9 +747,11 @@ export class TXEOracleTopLevelContext {
595
747
  hooks: composeHooks({
596
748
  authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
597
749
  }),
598
- utilityExecutor
750
+ utilityExecutor,
751
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
752
+ transientArrayService: new TransientArrayService()
599
753
  });
600
- const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
754
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
601
755
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
602
756
  throw new ExecutionError(err.message, {
603
757
  contractAddress: call.to,
@@ -614,16 +768,21 @@ export class TXEOracleTopLevelContext {
614
768
  }
615
769
  close() {
616
770
  this.logger.debug('Exiting Top Level Context');
617
- return [
618
- this.nextBlockTimestamp,
619
- this.authwits
620
- ];
771
+ return {
772
+ nextBlockTimestamp: this.nextBlockTimestamp,
773
+ authwits: this.authwits,
774
+ taggingSecretStrategies: this.taggingSecretStrategies,
775
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
776
+ };
621
777
  }
622
778
  async getLastBlockNumber() {
623
779
  const block = await this.stateMachine.node.getBlock('latest');
624
780
  return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
625
781
  }
626
782
  buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
783
+ if (this.authorizeAllUtilityCallTargets) {
784
+ return authorizeAllUtilityCallsHook;
785
+ }
627
786
  if (authorizedTargets.length === 0) {
628
787
  return undefined;
629
788
  }
@@ -632,3 +791,10 @@ export class TXEOracleTopLevelContext {
632
791
  });
633
792
  }
634
793
  }
794
+ /**
795
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
796
+ *
797
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
798
+ */ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
799
+ authorized: true
800
+ });