@aztec/simulator 0.0.1-commit.d3ec352c → 0.0.1-commit.fcb71a6

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 (213) hide show
  1. package/dest/common/errors.d.ts +2 -2
  2. package/dest/common/errors.d.ts.map +1 -1
  3. package/dest/private/acvm/deserialize.d.ts +2 -2
  4. package/dest/private/acvm/deserialize.d.ts.map +1 -1
  5. package/dest/private/acvm/deserialize.js +1 -1
  6. package/dest/private/acvm/serialize.d.ts +2 -2
  7. package/dest/private/acvm/serialize.d.ts.map +1 -1
  8. package/dest/private/acvm/serialize.js +1 -1
  9. package/dest/private/circuit_recording/circuit_recorder.d.ts +1 -1
  10. package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
  11. package/dest/private/circuit_recording/circuit_recorder.js +16 -15
  12. package/dest/public/avm/avm_context.d.ts +2 -2
  13. package/dest/public/avm/avm_context.d.ts.map +1 -1
  14. package/dest/public/avm/avm_contract_call_result.d.ts +2 -2
  15. package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
  16. package/dest/public/avm/avm_execution_environment.d.ts +2 -2
  17. package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
  18. package/dest/public/avm/avm_execution_environment.js +1 -1
  19. package/dest/public/avm/avm_gas.d.ts +1 -1
  20. package/dest/public/avm/avm_gas.d.ts.map +1 -1
  21. package/dest/public/avm/avm_machine_state.d.ts +2 -2
  22. package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
  23. package/dest/public/avm/avm_memory_types.d.ts +2 -2
  24. package/dest/public/avm/avm_memory_types.d.ts.map +1 -1
  25. package/dest/public/avm/avm_memory_types.js +1 -1
  26. package/dest/public/avm/avm_simulator.d.ts +2 -2
  27. package/dest/public/avm/avm_simulator.d.ts.map +1 -1
  28. package/dest/public/avm/avm_simulator.js +1 -1
  29. package/dest/public/avm/errors.d.ts +2 -2
  30. package/dest/public/avm/errors.d.ts.map +1 -1
  31. package/dest/public/avm/fixtures/avm_simulation_tester.js +1 -1
  32. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +2 -2
  33. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
  34. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +1 -1
  35. package/dest/public/avm/fixtures/initializers.d.ts +2 -2
  36. package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
  37. package/dest/public/avm/fixtures/initializers.js +1 -1
  38. package/dest/public/avm/fixtures/utils.d.ts +2 -2
  39. package/dest/public/avm/fixtures/utils.d.ts.map +1 -1
  40. package/dest/public/avm/fixtures/utils.js +1 -1
  41. package/dest/public/avm/opcodes/arithmetic.d.ts +3 -1
  42. package/dest/public/avm/opcodes/arithmetic.d.ts.map +1 -1
  43. package/dest/public/avm/opcodes/arithmetic.js +11 -1
  44. package/dest/public/avm/opcodes/ec_add.js +2 -2
  45. package/dest/public/avm/opcodes/hashing.d.ts +1 -1
  46. package/dest/public/avm/opcodes/hashing.d.ts.map +1 -1
  47. package/dest/public/avm/opcodes/hashing.js +9 -4
  48. package/dest/public/avm/opcodes/memory.js +1 -1
  49. package/dest/public/avm/revert_reason.d.ts +2 -2
  50. package/dest/public/avm/revert_reason.d.ts.map +1 -1
  51. package/dest/public/avm/serialization/instruction_serialization.js +1 -1
  52. package/dest/public/avm/test_utils.d.ts +2 -2
  53. package/dest/public/avm/test_utils.d.ts.map +1 -1
  54. package/dest/public/avm/test_utils.js +1 -1
  55. package/dest/public/contracts_db_checkpoint.d.ts +2 -2
  56. package/dest/public/contracts_db_checkpoint.d.ts.map +1 -1
  57. package/dest/public/db_interfaces.d.ts +2 -2
  58. package/dest/public/db_interfaces.d.ts.map +1 -1
  59. package/dest/public/debug_fn_name.d.ts +2 -2
  60. package/dest/public/debug_fn_name.d.ts.map +1 -1
  61. package/dest/public/debug_fn_name.js +10 -3
  62. package/dest/public/fixtures/amm_test.js +2 -2
  63. package/dest/public/fixtures/bulk_test.js +4 -52
  64. package/dest/public/fixtures/custom_bytecode_tester.d.ts +28 -6
  65. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -1
  66. package/dest/public/fixtures/custom_bytecode_tester.js +36 -12
  67. package/dest/public/fixtures/custom_bytecode_tests.d.ts +4 -1
  68. package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -1
  69. package/dest/public/fixtures/custom_bytecode_tests.js +74 -9
  70. package/dest/public/fixtures/index.d.ts +4 -2
  71. package/dest/public/fixtures/index.d.ts.map +1 -1
  72. package/dest/public/fixtures/index.js +3 -1
  73. package/dest/public/fixtures/minimal_public_tx.d.ts +2 -7
  74. package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -1
  75. package/dest/public/fixtures/minimal_public_tx.js +2 -12
  76. package/dest/public/fixtures/opcode_spammer.d.ts +123 -0
  77. package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -0
  78. package/dest/public/fixtures/opcode_spammer.js +1681 -0
  79. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +15 -2
  80. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  81. package/dest/public/fixtures/public_tx_simulation_tester.js +36 -8
  82. package/dest/public/fixtures/simple_contract_data_source.d.ts +2 -2
  83. package/dest/public/fixtures/simple_contract_data_source.d.ts.map +1 -1
  84. package/dest/public/fixtures/token_test.js +1 -1
  85. package/dest/public/fixtures/utils.d.ts +2 -2
  86. package/dest/public/fixtures/utils.d.ts.map +1 -1
  87. package/dest/public/fixtures/utils.js +4 -3
  88. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts +46 -0
  89. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts.map +1 -0
  90. package/dest/public/fuzzing/avm_fuzzer_simulator.js +139 -0
  91. package/dest/public/fuzzing/avm_simulator_bin.d.ts +2 -0
  92. package/dest/public/fuzzing/avm_simulator_bin.d.ts.map +1 -0
  93. package/dest/public/fuzzing/avm_simulator_bin.js +100 -0
  94. package/dest/public/hinting_db_sources.d.ts +3 -2
  95. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  96. package/dest/public/hinting_db_sources.js +5 -2
  97. package/dest/public/index.d.ts +2 -2
  98. package/dest/public/index.d.ts.map +1 -1
  99. package/dest/public/index.js +1 -1
  100. package/dest/public/public_db_sources.d.ts +2 -2
  101. package/dest/public/public_db_sources.d.ts.map +1 -1
  102. package/dest/public/public_db_sources.js +1 -1
  103. package/dest/public/public_processor/guarded_merkle_tree.d.ts +2 -1
  104. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
  105. package/dest/public/public_processor/guarded_merkle_tree.js +3 -0
  106. package/dest/public/public_processor/public_processor.d.ts +2 -2
  107. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  108. package/dest/public/public_processor/public_processor.js +23 -11
  109. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +1 -13
  110. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
  111. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +18 -53
  112. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +16 -1
  113. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
  114. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +41 -3
  115. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +1 -1
  116. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -1
  117. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +7 -6
  118. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts +22 -0
  119. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts.map +1 -0
  120. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.js +52 -0
  121. package/dest/public/public_tx_simulator/factories.d.ts +13 -0
  122. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -0
  123. package/dest/public/public_tx_simulator/factories.js +28 -0
  124. package/dest/public/public_tx_simulator/index.d.ts +3 -1
  125. package/dest/public/public_tx_simulator/index.d.ts.map +1 -1
  126. package/dest/public/public_tx_simulator/index.js +2 -0
  127. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +2 -2
  128. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
  129. package/dest/public/public_tx_simulator/public_tx_context.d.ts +2 -2
  130. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  131. package/dest/public/public_tx_simulator/public_tx_context.js +1 -1
  132. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +2 -2
  133. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  134. package/dest/public/public_tx_simulator/public_tx_simulator.js +5 -3
  135. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +24 -1
  136. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts.map +1 -1
  137. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +2 -2
  138. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
  139. package/dest/public/side_effect_trace.d.ts +2 -2
  140. package/dest/public/side_effect_trace.d.ts.map +1 -1
  141. package/dest/public/side_effect_trace.js +1 -1
  142. package/dest/public/side_effect_trace_interface.d.ts +2 -2
  143. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  144. package/dest/public/state_manager/nullifiers.d.ts +2 -2
  145. package/dest/public/state_manager/nullifiers.d.ts.map +1 -1
  146. package/dest/public/state_manager/public_storage.d.ts +2 -2
  147. package/dest/public/state_manager/public_storage.d.ts.map +1 -1
  148. package/dest/public/state_manager/public_storage.js +1 -1
  149. package/dest/public/state_manager/state_manager.d.ts +2 -2
  150. package/dest/public/state_manager/state_manager.d.ts.map +1 -1
  151. package/dest/public/state_manager/state_manager.js +1 -1
  152. package/package.json +17 -17
  153. package/src/common/errors.ts +1 -1
  154. package/src/private/acvm/deserialize.ts +1 -1
  155. package/src/private/acvm/serialize.ts +1 -1
  156. package/src/private/circuit_recording/circuit_recorder.ts +17 -16
  157. package/src/public/avm/avm_context.ts +1 -1
  158. package/src/public/avm/avm_contract_call_result.ts +1 -1
  159. package/src/public/avm/avm_execution_environment.ts +1 -1
  160. package/src/public/avm/avm_gas.ts +3 -3
  161. package/src/public/avm/avm_machine_state.ts +1 -1
  162. package/src/public/avm/avm_memory_types.ts +1 -1
  163. package/src/public/avm/avm_simulator.ts +1 -1
  164. package/src/public/avm/errors.ts +1 -1
  165. package/src/public/avm/fixtures/avm_simulation_tester.ts +1 -1
  166. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -1
  167. package/src/public/avm/fixtures/initializers.ts +1 -1
  168. package/src/public/avm/fixtures/utils.ts +1 -1
  169. package/src/public/avm/opcodes/arithmetic.ts +13 -1
  170. package/src/public/avm/opcodes/ec_add.ts +2 -2
  171. package/src/public/avm/opcodes/hashing.ts +10 -4
  172. package/src/public/avm/opcodes/memory.ts +1 -1
  173. package/src/public/avm/revert_reason.ts +1 -1
  174. package/src/public/avm/serialization/instruction_serialization.ts +1 -1
  175. package/src/public/avm/test_utils.ts +1 -1
  176. package/src/public/contracts_db_checkpoint.ts +1 -1
  177. package/src/public/db_interfaces.ts +1 -1
  178. package/src/public/debug_fn_name.ts +11 -4
  179. package/src/public/fixtures/amm_test.ts +2 -2
  180. package/src/public/fixtures/bulk_test.ts +7 -7
  181. package/src/public/fixtures/custom_bytecode_tester.ts +53 -19
  182. package/src/public/fixtures/custom_bytecode_tests.ts +93 -9
  183. package/src/public/fixtures/index.ts +7 -1
  184. package/src/public/fixtures/minimal_public_tx.ts +4 -13
  185. package/src/public/fixtures/opcode_spammer.ts +1638 -0
  186. package/src/public/fixtures/public_tx_simulation_tester.ts +40 -6
  187. package/src/public/fixtures/simple_contract_data_source.ts +1 -1
  188. package/src/public/fixtures/token_test.ts +1 -1
  189. package/src/public/fixtures/utils.ts +2 -3
  190. package/src/public/fuzzing/avm_fuzzer_simulator.ts +240 -0
  191. package/src/public/fuzzing/avm_simulator_bin.ts +140 -0
  192. package/src/public/hinting_db_sources.ts +6 -2
  193. package/src/public/index.ts +2 -0
  194. package/src/public/public_db_sources.ts +1 -1
  195. package/src/public/public_processor/guarded_merkle_tree.ts +4 -0
  196. package/src/public/public_processor/public_processor.ts +28 -12
  197. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +19 -60
  198. package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +48 -3
  199. package/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +1 -1
  200. package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +7 -10
  201. package/src/public/public_tx_simulator/dumping_cpp_public_tx_simulator.ts +81 -0
  202. package/src/public/public_tx_simulator/factories.ts +41 -0
  203. package/src/public/public_tx_simulator/index.ts +2 -0
  204. package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +1 -1
  205. package/src/public/public_tx_simulator/public_tx_context.ts +1 -1
  206. package/src/public/public_tx_simulator/public_tx_simulator.ts +14 -3
  207. package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +23 -0
  208. package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +1 -1
  209. package/src/public/side_effect_trace.ts +1 -1
  210. package/src/public/side_effect_trace_interface.ts +1 -1
  211. package/src/public/state_manager/nullifiers.ts +1 -1
  212. package/src/public/state_manager/public_storage.ts +1 -1
  213. package/src/public/state_manager/state_manager.ts +2 -2
@@ -1,7 +1,7 @@
1
1
  import { DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT } from '@aztec/constants';
2
2
  import { asyncMap } from '@aztec/foundation/async-map';
3
3
  import { BlockNumber } from '@aztec/foundation/branded-types';
4
- import { Fr } from '@aztec/foundation/fields';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { type ContractArtifact, encodeArguments } from '@aztec/stdlib/abi';
6
6
  import { PublicSimulatorConfig, type PublicTxResult } from '@aztec/stdlib/avm';
7
7
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -31,7 +31,7 @@ const DEFAULT_GAS_FEES = new GasFees(2, 3);
31
31
  export type TestEnqueuedCall = {
32
32
  sender?: AztecAddress;
33
33
  address: AztecAddress;
34
- fnName: string;
34
+ fnName?: string;
35
35
  args: any[];
36
36
  isStaticCall?: boolean;
37
37
  contractArtifact?: ContractArtifact;
@@ -42,6 +42,7 @@ const defaultConfig: PublicSimulatorConfig = PublicSimulatorConfig.from({
42
42
  collectCallMetadata: true,
43
43
  collectDebugLogs: true,
44
44
  collectHints: false,
45
+ collectPublicInputs: false,
45
46
  collectStatistics: false,
46
47
  });
47
48
 
@@ -224,6 +225,25 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
224
225
  this.metrics.prettyPrint();
225
226
  }
226
227
 
228
+ /**
229
+ * Cancel the current simulation if one is in progress.
230
+ * This signals the underlying simulator (e.g., C++) to stop at the next safe point.
231
+ * Safe to call even if no simulation is in progress.
232
+ *
233
+ * @param waitTimeoutMs - If provided, wait up to this many ms for the simulation to actually stop.
234
+ */
235
+ public async cancel(waitTimeoutMs?: number): Promise<void> {
236
+ await this.simulator.cancel?.(waitTimeoutMs);
237
+ }
238
+
239
+ /**
240
+ * Get the underlying simulator for advanced test scenarios.
241
+ * Use this when you need direct control over simulation (e.g., for testing cancellation).
242
+ */
243
+ public getSimulator(): MeasuredPublicTxSimulatorInterface {
244
+ return this.simulator;
245
+ }
246
+
227
247
  async #createPubicCallRequestForCall(
228
248
  call: TestEnqueuedCall,
229
249
  sender: AztecAddress,
@@ -234,10 +254,24 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
234
254
  throw new Error(`Contract artifact not found for address: ${address}`);
235
255
  }
236
256
 
237
- const fnSelector = await getFunctionSelector(call.fnName, contractArtifact);
238
- const fnAbi = getContractFunctionAbi(call.fnName, contractArtifact)!;
239
- const encodedArgs = encodeArguments(fnAbi, call.args);
240
- const calldata = [fnSelector.toField(), ...encodedArgs];
257
+ let calldata: Fr[] = [];
258
+ if (!call.fnName) {
259
+ this.logger.debug(
260
+ `No function name specified for call to contract ${call.address.toString()}. Assuming this is a custom bytecode with no public_dispatch function.`,
261
+ );
262
+ this.logger.debug(`Not using ABI to encode arguments. Not prepending fn selector to calldata.`);
263
+ try {
264
+ calldata = call.args.map(arg => new Fr(arg));
265
+ } catch (error) {
266
+ this.logger.warn(`Tried assuming that all arguments are Field-like. Failed. Error: ${error}`);
267
+ throw error;
268
+ }
269
+ } else {
270
+ const fnSelector = await getFunctionSelector(call.fnName, contractArtifact);
271
+ const fnAbi = getContractFunctionAbi(call.fnName, contractArtifact)!;
272
+ const encodedArgs = encodeArguments(fnAbi, call.args);
273
+ calldata = [fnSelector.toField(), ...encodedArgs];
274
+ }
241
275
  const isStaticCall = call.isStaticCall ?? false;
242
276
  const request = await PublicCallRequest.fromCalldata(sender, address, isStaticCall, calldata);
243
277
 
@@ -1,5 +1,5 @@
1
1
  import type { BlockNumber } from '@aztec/foundation/branded-types';
2
- import type { Fr } from '@aztec/foundation/fields';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import type { ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
5
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -1,4 +1,4 @@
1
- import { Fr } from '@aztec/foundation/fields';
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { Logger } from '@aztec/foundation/log';
3
3
  import { Timer } from '@aztec/foundation/timer';
4
4
  import type { ContractArtifact } from '@aztec/stdlib/abi';
@@ -9,7 +9,7 @@ import {
9
9
  PRIVATE_LOG_SIZE_IN_FIELDS,
10
10
  } from '@aztec/constants';
11
11
  import { padArrayEnd } from '@aztec/foundation/collection';
12
- import { Fr } from '@aztec/foundation/fields';
12
+ import { Fr } from '@aztec/foundation/curves/bn254';
13
13
  import { CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG } from '@aztec/protocol-contracts';
14
14
  import { bufferAsFields } from '@aztec/stdlib/abi';
15
15
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -132,8 +132,7 @@ export async function createTxForPublicCalls(
132
132
  : Gas.empty();
133
133
  const gasSettings = new GasSettings(gasLimits, teardownGasLimits, maxFeesPerGas, GasFees.empty());
134
134
  const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings);
135
- const header = BlockHeader.empty();
136
- header.globalVariables = globals;
135
+ const header = BlockHeader.empty({ globalVariables: globals });
137
136
  const constantData = new TxConstantData(header, txContext, Fr.zero(), Fr.zero());
138
137
  const includeByTimestamp = 0n; // Not used in the simulator.
139
138
 
@@ -0,0 +1,240 @@
1
+ import {
2
+ MAX_ENQUEUED_CALLS_PER_TX,
3
+ MAX_L2_TO_L1_MSGS_PER_TX,
4
+ MAX_NOTE_HASHES_PER_TX,
5
+ MAX_NULLIFIERS_PER_TX,
6
+ MAX_PRIVATE_LOGS_PER_TX,
7
+ } from '@aztec/constants';
8
+ import { padArrayEnd } from '@aztec/foundation/collection';
9
+ import { Fr } from '@aztec/foundation/curves/bn254';
10
+ import { AvmTxHint, type PublicTxResult } from '@aztec/stdlib/avm';
11
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
12
+ import { contractClassPublicFromPlainObject, contractInstanceWithAddressFromPlainObject } from '@aztec/stdlib/contract';
13
+ import {
14
+ PartialPrivateTailPublicInputsForPublic,
15
+ PrivateKernelTailCircuitPublicInputs,
16
+ PrivateToPublicAccumulatedData,
17
+ PublicCallRequest,
18
+ } from '@aztec/stdlib/kernel';
19
+ import { PrivateLog } from '@aztec/stdlib/logs';
20
+ import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
21
+ import { ChonkProof } from '@aztec/stdlib/proofs';
22
+ import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
23
+ import { BlockHeader, GlobalVariables, HashedValues, Tx, TxConstantData, TxContext, TxHash } from '@aztec/stdlib/tx';
24
+ import type { NativeWorldStateService } from '@aztec/world-state';
25
+
26
+ import { BaseAvmSimulationTester } from '../avm/fixtures/base_avm_simulation_tester.js';
27
+ import { SimpleContractDataSource } from '../fixtures/simple_contract_data_source.js';
28
+ import { PublicContractsDB } from '../public_db_sources.js';
29
+ import { PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js';
30
+
31
+ /**
32
+ * Request structure for fuzzer simulation communication from C++.
33
+ * Matches the C++ FuzzerSimulationRequest struct
34
+ */
35
+ export class FuzzerSimulationRequest {
36
+ constructor(
37
+ public readonly wsDataDir: string,
38
+ public readonly wsMapSizeKb: number,
39
+ public readonly tx: AvmTxHint,
40
+ public readonly globals: GlobalVariables,
41
+ public readonly contractClasses: any[], // Raw, processed by addContractClassFromCpp
42
+ public readonly contractInstances: [any, any][], // Raw pairs [address, instance]
43
+ ) {}
44
+
45
+ static fromPlainObject(obj: any): FuzzerSimulationRequest {
46
+ if (obj instanceof FuzzerSimulationRequest) {
47
+ return obj;
48
+ }
49
+ return new FuzzerSimulationRequest(
50
+ obj.wsDataDir,
51
+ obj.wsMapSizeKb,
52
+ AvmTxHint.fromPlainObject(obj.tx),
53
+ GlobalVariables.fromPlainObject(obj.globals),
54
+ obj.contractClasses,
55
+ obj.contractInstances,
56
+ );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Creates a TypeScript Tx object from a deserialized C++ Tx (AvmTxHint-like structure).
62
+ * This allows using PublicTxSimulator.simulate() with fuzzer-generated transactions.
63
+ */
64
+ async function createTxFromHint(cppTx: AvmTxHint): Promise<Tx> {
65
+ // Create TxHash from the C++ tx hash string
66
+ if (!cppTx.hash) {
67
+ throw new Error(`cppTx.hash is undefined. Keys: ${Object.keys(cppTx || {}).join(', ')}`);
68
+ }
69
+ const txHash = TxHash.fromString(cppTx.hash);
70
+
71
+ // Extract PublicCallRequest instances from enqueued calls
72
+ const setupCallRequests = cppTx.setupEnqueuedCalls.map(call => call.request);
73
+ const paddedSetupCalls = padArrayEnd(setupCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX);
74
+
75
+ const appLogicCallRequests = cppTx.appLogicEnqueuedCalls.map(call => call.request);
76
+ const paddedAppLogicCalls = padArrayEnd(appLogicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX);
77
+
78
+ // Build non-revertible accumulated data from C++ tx
79
+ const emptyNonRevertible = PrivateToPublicAccumulatedData.empty();
80
+ const nonRevertibleAccumulatedData = new PrivateToPublicAccumulatedData(
81
+ padArrayEnd(cppTx.nonRevertibleAccumulatedData.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
82
+ padArrayEnd(cppTx.nonRevertibleAccumulatedData.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX),
83
+ padArrayEnd(
84
+ cppTx.nonRevertibleAccumulatedData.l2ToL1Messages,
85
+ ScopedL2ToL1Message.empty(),
86
+ MAX_L2_TO_L1_MSGS_PER_TX,
87
+ ),
88
+ padArrayEnd(cppTx.nonRevertibleContractDeploymentData.privateLogs, PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
89
+ emptyNonRevertible.contractClassLogsHashes,
90
+ paddedSetupCalls,
91
+ );
92
+
93
+ // Build revertible accumulated data from C++ tx
94
+ const emptyRevertible = PrivateToPublicAccumulatedData.empty();
95
+ const revertibleAccumulatedData = new PrivateToPublicAccumulatedData(
96
+ padArrayEnd(cppTx.revertibleAccumulatedData.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
97
+ padArrayEnd(cppTx.revertibleAccumulatedData.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX),
98
+ padArrayEnd(cppTx.revertibleAccumulatedData.l2ToL1Messages, ScopedL2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_TX),
99
+ padArrayEnd(cppTx.revertibleContractDeploymentData.privateLogs, PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
100
+ emptyRevertible.contractClassLogsHashes,
101
+ paddedAppLogicCalls,
102
+ );
103
+
104
+ // Build teardown call request (if exists)
105
+ const teardownCallRequest = cppTx.teardownEnqueuedCall?.request ?? PublicCallRequest.empty();
106
+
107
+ // Create forPublic structure
108
+ const forPublic = new PartialPrivateTailPublicInputsForPublic(
109
+ nonRevertibleAccumulatedData,
110
+ revertibleAccumulatedData,
111
+ teardownCallRequest,
112
+ );
113
+
114
+ // Build TxContext - gasSettings is already a proper GasSettings after AvmTxHint.fromPlainObject
115
+ const txContext = new TxContext(
116
+ Fr.ZERO, // chainId - this is fine because simulation actually reads from globalVariables not here
117
+ Fr.ZERO, // version - this is fine because simulation actually reads from globalVariables not here
118
+ cppTx.gasSettings,
119
+ );
120
+
121
+ // Build TxConstantData
122
+ const constants = new TxConstantData(
123
+ BlockHeader.empty(), // anchorBlockHeader (unused in simulation)
124
+ txContext,
125
+ Fr.ZERO, // vkTreeRoot - not needed for public simulation
126
+ Fr.ZERO, // protocolContractsHash - not needed for public simulation
127
+ );
128
+
129
+ const data = new PrivateKernelTailCircuitPublicInputs(
130
+ constants,
131
+ cppTx.gasUsedByPrivate,
132
+ cppTx.feePayer,
133
+ 0n, // includeByTimestamp
134
+ forPublic,
135
+ undefined, // forRollup - not needed for public simulation
136
+ );
137
+
138
+ // Build publicFunctionCalldata from all enqueued calls
139
+ // Calldata is already Fr[] after AvmTxHint.fromPlainObject
140
+ const publicFunctionCalldata: HashedValues[] = [];
141
+
142
+ // Add setup calls
143
+ for (const call of cppTx.setupEnqueuedCalls || []) {
144
+ publicFunctionCalldata.push(await HashedValues.fromCalldata(call.calldata));
145
+ }
146
+
147
+ // Add app logic calls
148
+ for (const call of cppTx.appLogicEnqueuedCalls || []) {
149
+ publicFunctionCalldata.push(await HashedValues.fromCalldata(call.calldata));
150
+ }
151
+
152
+ // Add teardown call if present
153
+ if (cppTx.teardownEnqueuedCall) {
154
+ publicFunctionCalldata.push(await HashedValues.fromCalldata(cppTx.teardownEnqueuedCall.calldata));
155
+ }
156
+
157
+ // Extract contract class log fields from ContractDeploymentData
158
+ const contractClassLogFields = [
159
+ ...cppTx.nonRevertibleContractDeploymentData.contractClassLogs.map(log => log.fields),
160
+ ...cppTx.revertibleContractDeploymentData.contractClassLogs.map(log => log.fields),
161
+ ];
162
+
163
+ // Create the Tx
164
+ return new Tx(
165
+ txHash,
166
+ data,
167
+ ChonkProof.empty(), // No real proof needed for simulation
168
+ contractClassLogFields,
169
+ publicFunctionCalldata,
170
+ );
171
+ }
172
+
173
+ /**
174
+ * A simulator class for the AVM fuzzer that extends BaseAvmSimulationTester.
175
+ * It provides methods for registering contracts from C++ msgpack data and simulating transactions.
176
+ */
177
+ export class AvmFuzzerSimulator extends BaseAvmSimulationTester {
178
+ private simulator: PublicTxSimulator;
179
+
180
+ constructor(
181
+ merkleTrees: MerkleTreeWriteOperations,
182
+ contractDataSource: SimpleContractDataSource,
183
+ globals: GlobalVariables,
184
+ ) {
185
+ super(contractDataSource, merkleTrees);
186
+ const contractsDb = new PublicContractsDB(contractDataSource);
187
+ this.simulator = new PublicTxSimulator(merkleTrees, contractsDb, globals, {
188
+ skipFeeEnforcement: false,
189
+ collectDebugLogs: false,
190
+ collectHints: false,
191
+ collectStatistics: false,
192
+ collectCallMetadata: false,
193
+ });
194
+ }
195
+
196
+ /**
197
+ * Static factory method to create an AvmFuzzerSimulator.
198
+ */
199
+ public static async create(
200
+ worldStateService: NativeWorldStateService,
201
+ globals: GlobalVariables,
202
+ ): Promise<AvmFuzzerSimulator> {
203
+ const contractDataSource = new SimpleContractDataSource();
204
+ const merkleTrees = await worldStateService.fork();
205
+ return new AvmFuzzerSimulator(merkleTrees, contractDataSource, globals);
206
+ }
207
+
208
+ /**
209
+ * Simulate a transaction from a C++ AvmTxHint.
210
+ */
211
+ public async simulate(txHint: AvmTxHint): Promise<PublicTxResult> {
212
+ // Compute fee from gas limits and max fees per gas (upper bound on fee)
213
+ const totalFee =
214
+ BigInt(txHint.gasSettings.gasLimits.daGas) * txHint.gasSettings.maxFeesPerGas.feePerDaGas +
215
+ BigInt(txHint.gasSettings.gasLimits.l2Gas) * txHint.gasSettings.maxFeesPerGas.feePerL2Gas;
216
+
217
+ await this.setFeePayerBalance(txHint.feePayer, new Fr(totalFee));
218
+
219
+ const tx = await createTxFromHint(txHint);
220
+ return await this.simulator.simulate(tx);
221
+ }
222
+
223
+ /**
224
+ * Add a contract class from C++ raw msgpack data.
225
+ */
226
+ public async addContractClassFromCpp(rawClass: any): Promise<void> {
227
+ const contractClass = contractClassPublicFromPlainObject(rawClass);
228
+ await this.contractDataSource.addContractClass(contractClass);
229
+ }
230
+
231
+ /**
232
+ * Add a contract instance from C++ raw msgpack data.
233
+ * This also inserts the contract address nullifier into the nullifier tree.
234
+ */
235
+ public async addContractInstanceFromCpp(rawAddress: any, rawInstance: any): Promise<void> {
236
+ const address = AztecAddress.fromPlainObject(rawAddress);
237
+ const instance = contractInstanceWithAddressFromPlainObject(address, rawInstance);
238
+ await this.addContractInstance(instance);
239
+ }
240
+ }
@@ -0,0 +1,140 @@
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import {
4
+ AvmCircuitPublicInputs,
5
+ type AvmTxHint,
6
+ deserializeFromMessagePack,
7
+ serializeWithMessagePack,
8
+ } from '@aztec/stdlib/avm';
9
+ import { GlobalVariables, TreeSnapshots } from '@aztec/stdlib/tx';
10
+ import { NativeWorldStateService } from '@aztec/world-state';
11
+
12
+ import { writeSync } from 'fs';
13
+ import { createInterface } from 'readline';
14
+
15
+ import { AvmFuzzerSimulator, FuzzerSimulationRequest } from './avm_fuzzer_simulator.js';
16
+
17
+ // This cache holds opened world states to avoid reopening them for each invocation.
18
+ // It's a map so that in the future we could support multiple world states (if we had multiple fuzzers).
19
+ const worldStateCache = new Map<string, NativeWorldStateService>();
20
+
21
+ async function openExistingWorldState(dataDir: string, mapSizeKb: number): Promise<NativeWorldStateService> {
22
+ const cached = worldStateCache.get(dataDir);
23
+ if (cached) {
24
+ return cached;
25
+ }
26
+
27
+ const ws = await NativeWorldStateService.new(EthAddress.ZERO, dataDir, {
28
+ archiveTreeMapSizeKb: mapSizeKb,
29
+ nullifierTreeMapSizeKb: mapSizeKb,
30
+ noteHashTreeMapSizeKb: mapSizeKb,
31
+ messageTreeMapSizeKb: mapSizeKb,
32
+ publicDataTreeMapSizeKb: mapSizeKb,
33
+ });
34
+
35
+ worldStateCache.set(dataDir, ws);
36
+ return ws;
37
+ }
38
+
39
+ async function simulateWithFuzzer(
40
+ dataDir: string,
41
+ mapSizeKb: number,
42
+ txHint: AvmTxHint,
43
+ globals: GlobalVariables,
44
+ rawContractClasses: any[], // Replace these when we are moving contract classes to TS
45
+ rawContractInstances: [any, any][], // Replace these when we are moving contract instances to TS
46
+ ): Promise<{ reverted: boolean; output: Fr[]; revertReason?: string; publicInputs: AvmCircuitPublicInputs }> {
47
+ const worldStateService = await openExistingWorldState(dataDir, mapSizeKb);
48
+
49
+ const simulator = await AvmFuzzerSimulator.create(worldStateService, globals);
50
+
51
+ // Register contract classes from C++
52
+ for (const rawClass of rawContractClasses) {
53
+ await simulator.addContractClassFromCpp(rawClass);
54
+ }
55
+
56
+ // Register contract instances from C++
57
+ for (const [rawAddress, rawInstance] of rawContractInstances) {
58
+ await simulator.addContractInstanceFromCpp(rawAddress, rawInstance);
59
+ }
60
+
61
+ const result = await simulator.simulate(txHint);
62
+
63
+ const output = result
64
+ .getAppLogicReturnValues()
65
+ .flatMap((rv: { values?: Fr[] } | undefined) => rv?.values?.filter((v: Fr | null | undefined) => v != null) ?? []);
66
+
67
+ return {
68
+ reverted: !result.revertCode.isOK(),
69
+ output,
70
+ revertReason: result.findRevertReason()?.message,
71
+ publicInputs: result.publicInputs!,
72
+ };
73
+ }
74
+
75
+ async function execute(base64Line: string): Promise<void> {
76
+ try {
77
+ // Decode base64 and deserialize the entire request from msgpack
78
+ const buffer = Buffer.from(base64Line.trim(), 'base64');
79
+ const rawRequest = deserializeFromMessagePack(buffer);
80
+ const request = FuzzerSimulationRequest.fromPlainObject(rawRequest);
81
+
82
+ // Run the TS simulation
83
+ const result = await simulateWithFuzzer(
84
+ request.wsDataDir,
85
+ request.wsMapSizeKb,
86
+ request.tx,
87
+ request.globals,
88
+ request.contractClasses,
89
+ request.contractInstances,
90
+ );
91
+
92
+ // Serialize the result to msgpack and encode it in base64 for output
93
+ const resultBuffer = serializeWithMessagePack({
94
+ reverted: result.reverted,
95
+ output: result.output,
96
+ revertReason: result.revertReason ?? '',
97
+ endTreeSnapshots: result.publicInputs.endTreeSnapshots,
98
+ });
99
+ writeSync(process.stdout.fd, resultBuffer.toString('base64') + '\n');
100
+ } catch (error: any) {
101
+ // If we error, treat as reverted
102
+ const errorResult = serializeWithMessagePack({
103
+ reverted: true,
104
+ output: [] as string[],
105
+ revertReason: `Unexpected Error ${error.message}`,
106
+ endTreeSnapshots: TreeSnapshots.empty(),
107
+ });
108
+ writeSync(process.stdout.fd, errorResult.toString('base64') + '\n');
109
+ }
110
+ }
111
+
112
+ function mainLoop() {
113
+ const rl = createInterface({ input: process.stdin, terminal: false });
114
+
115
+ // Process lines sequentially to avoid race conditions in responses
116
+ const lineQueue: string[] = [];
117
+ let processing = false;
118
+
119
+ async function processQueue() {
120
+ if (processing || lineQueue.length === 0) {
121
+ return;
122
+ }
123
+ processing = true;
124
+ while (lineQueue.length > 0) {
125
+ const line = lineQueue.shift()!;
126
+ await execute(line);
127
+ }
128
+ processing = false;
129
+ }
130
+
131
+ rl.on('line', (line: string) => {
132
+ if (line.trim()) {
133
+ lineQueue.push(line);
134
+ void processQueue();
135
+ }
136
+ });
137
+ rl.on('close', () => process.exit(0));
138
+ }
139
+
140
+ void mainLoop();
@@ -1,6 +1,6 @@
1
1
  import type { BlockNumber } from '@aztec/foundation/branded-types';
2
- import { sha256Trunc } from '@aztec/foundation/crypto';
3
- import { Fr } from '@aztec/foundation/fields';
2
+ import { sha256Trunc } from '@aztec/foundation/crypto/sha256';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
5
  import type { IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
6
6
  import type { FunctionSelector } from '@aztec/stdlib/abi';
@@ -572,6 +572,10 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
572
572
  return await this.db.close();
573
573
  }
574
574
 
575
+ async [Symbol.dispose](): Promise<void> {
576
+ await this.close();
577
+ }
578
+
575
579
  public async findLeafIndices<ID extends MerkleTreeId>(
576
580
  treeId: ID,
577
581
  values: MerkleTreeLeafType<ID>[],
@@ -3,6 +3,8 @@ export { GuardedMerkleTreeOperations } from './public_processor/guarded_merkle_t
3
3
  export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js';
4
4
  export {
5
5
  CppPublicTxSimulator,
6
+ createPublicTxSimulatorForBlockBuilding,
7
+ DumpingCppPublicTxSimulator,
6
8
  type PublicTxSimulatorInterface,
7
9
  TelemetryCppPublicTxSimulator,
8
10
  } from './public_tx_simulator/index.js';
@@ -4,7 +4,7 @@ import {
4
4
  NULLIFIER_SUBTREE_HEIGHT,
5
5
  PUBLIC_DATA_SUBTREE_HEIGHT,
6
6
  } from '@aztec/constants';
7
- import { Fr } from '@aztec/foundation/fields';
7
+ import { Fr } from '@aztec/foundation/curves/bn254';
8
8
  import { createLogger } from '@aztec/foundation/log';
9
9
  import { Timer } from '@aztec/foundation/timer';
10
10
  import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
@@ -81,6 +81,10 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
81
81
  close(): Promise<void> {
82
82
  return this.guardAndPush(() => this.target.close());
83
83
  }
84
+
85
+ async [Symbol.dispose](): Promise<void> {
86
+ await this.close();
87
+ }
84
88
  getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
85
89
  return this.guardAndPush(() => this.target.getTreeInfo(treeId));
86
90
  }
@@ -1,6 +1,6 @@
1
1
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT } from '@aztec/constants';
2
2
  import { padArrayEnd } from '@aztec/foundation/collection';
3
- import { Fr } from '@aztec/foundation/fields';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer';
@@ -126,7 +126,7 @@ export class PublicProcessor implements Traceable {
126
126
  private dateProvider: DateProvider,
127
127
  telemetryClient: TelemetryClient = getTelemetryClient(),
128
128
  private log = createLogger('simulator:public-processor'),
129
- private opts: Pick<SequencerConfig, 'fakeProcessingDelayPerTxMs'> = {},
129
+ private opts: Pick<SequencerConfig, 'fakeProcessingDelayPerTxMs' | 'fakeThrowAfterProcessingTxCount'> = {},
130
130
  ) {
131
131
  this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');
132
132
  }
@@ -160,7 +160,7 @@ export class PublicProcessor implements Traceable {
160
160
  let totalBlockGas = new Gas(0, 0);
161
161
  let totalBlobFields = 0;
162
162
 
163
- for await (const origTx of txs) {
163
+ for await (const tx of txs) {
164
164
  // Only process up to the max tx limit
165
165
  if (maxTransactions !== undefined && result.length >= maxTransactions) {
166
166
  this.log.debug(`Stopping tx processing due to reaching the max tx limit.`);
@@ -174,8 +174,8 @@ export class PublicProcessor implements Traceable {
174
174
  }
175
175
 
176
176
  // Skip this tx if it'd exceed max block size
177
- const txHash = origTx.getTxHash().toString();
178
- const preTxSizeInBytes = origTx.getEstimatedPrivateTxEffectsSize();
177
+ const txHash = tx.getTxHash().toString();
178
+ const preTxSizeInBytes = tx.getEstimatedPrivateTxEffectsSize();
179
179
  if (maxBlockSize !== undefined && totalSizeInBytes + preTxSizeInBytes > maxBlockSize) {
180
180
  this.log.warn(`Skipping processing of tx ${txHash} sized ${preTxSizeInBytes} bytes due to block size limit`, {
181
181
  txHash,
@@ -187,7 +187,7 @@ export class PublicProcessor implements Traceable {
187
187
  }
188
188
 
189
189
  // Skip this tx if its gas limit would exceed the block gas limit
190
- const txGasLimit = origTx.data.constants.txContext.gasSettings.gasLimits;
190
+ const txGasLimit = tx.data.constants.txContext.gasSettings.gasLimits;
191
191
  if (maxBlockGas !== undefined && totalBlockGas.add(txGasLimit).gtAny(maxBlockGas)) {
192
192
  this.log.warn(`Skipping processing of tx ${txHash} due to block gas limit`, {
193
193
  txHash,
@@ -198,9 +198,6 @@ export class PublicProcessor implements Traceable {
198
198
  continue;
199
199
  }
200
200
 
201
- // The processor modifies the tx objects in place, so we need to clone them.
202
- const tx = Tx.clone(origTx);
203
-
204
201
  // We validate the tx before processing it, to avoid unnecessary work.
205
202
  if (preprocessValidator) {
206
203
  const result = await preprocessValidator.validateTx(tx);
@@ -233,6 +230,12 @@ export class PublicProcessor implements Traceable {
233
230
  try {
234
231
  const [processedTx, returnValues] = await this.processTx(tx, deadline);
235
232
 
233
+ // Inject a fake processing failure after N txs if requested
234
+ const fakeThrowAfter = this.opts.fakeThrowAfterProcessingTxCount;
235
+ if (fakeThrowAfter !== undefined && result.length + failed.length + 1 >= fakeThrowAfter) {
236
+ throw new Error(`Fake error after processing ${fakeThrowAfter} txs`);
237
+ }
238
+
236
239
  const txBlobFields = processedTx.txEffect.getNumBlobFields();
237
240
 
238
241
  // If the actual size of this tx would exceed block size, skip it
@@ -282,7 +285,15 @@ export class PublicProcessor implements Traceable {
282
285
  if (err?.name === 'PublicProcessorTimeoutError') {
283
286
  this.log.warn(`Stopping tx processing due to timeout.`);
284
287
  // We hit the transaction execution deadline.
285
- // There may still be a transaction executing. We stop the guarded fork to prevent any further access to the world state.
288
+ // There may still be a transaction executing on a worker thread (C++ via NAPI).
289
+ // Signal cancellation AND WAIT for the simulation to actually stop.
290
+ // This is critical because C++ might be in the middle of a slow operation (e.g., pad_trees)
291
+ // and won't check the cancellation flag until that operation completes.
292
+ // Without waiting, we'd proceed to revert checkpoints while C++ is still writing to state.
293
+ // Wait for C++ to stop gracefully.
294
+ await this.publicTxSimulator.cancel?.();
295
+
296
+ // Now stop the guarded fork to prevent any further TS-side access to the world state.
286
297
  await this.guardedMerkleTree.stop();
287
298
 
288
299
  // We now know there can't be any further access to world state. The fork is in a state where there is:
@@ -523,7 +534,7 @@ export class PublicProcessor implements Traceable {
523
534
 
524
535
  const result = await this.publicTxSimulator.simulate(tx);
525
536
  // TODO: use the callStackMetadata here to extract more data about public execution
526
- const { hints, publicInputs, gasUsed, revertCode /*callStackMetadata*/ } = result;
537
+ const { hints, publicInputs, publicTxEffect, gasUsed, revertCode /*callStackMetadata*/ } = result;
527
538
 
528
539
  const contractClassLogs = revertCode.isOK()
529
540
  ? tx.getContractClassLogs()
@@ -542,10 +553,15 @@ export class PublicProcessor implements Traceable {
542
553
  const appLogicReturnValues: NestedProcessReturnValues[] = result.getAppLogicReturnValues();
543
554
  // Extract the revert reason from the call stack metadata.
544
555
  const revertReason = result.findRevertReason();
556
+ // Create proving request if we have hints and public inputs.
557
+ const avmProvingRequest =
558
+ hints && publicInputs ? PublicProcessor.generateProvingRequest(publicInputs, hints) : undefined;
545
559
 
546
560
  const processedTx = makeProcessedTxFromTxWithPublicCalls(
547
561
  tx,
548
- PublicProcessor.generateProvingRequest(publicInputs, hints),
562
+ this.globalVariables,
563
+ avmProvingRequest,
564
+ publicTxEffect,
549
565
  gasUsed,
550
566
  revertCode,
551
567
  revertReason,