@aztec-labs/txe 6.0.0-nightly.20260829

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