@aztec/simulator 0.0.1-commit.9593d84 → 0.0.1-commit.96bb3f7

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 (248) 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 +6 -5
  29. package/dest/public/avm/errors.d.ts +8 -2
  30. package/dest/public/avm/errors.d.ts.map +1 -1
  31. package/dest/public/avm/errors.js +14 -2
  32. package/dest/public/avm/fixtures/avm_simulation_tester.js +1 -1
  33. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +2 -2
  34. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
  35. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +1 -1
  36. package/dest/public/avm/fixtures/initializers.d.ts +2 -2
  37. package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
  38. package/dest/public/avm/fixtures/initializers.js +3 -3
  39. package/dest/public/avm/fixtures/utils.d.ts +4 -3
  40. package/dest/public/avm/fixtures/utils.d.ts.map +1 -1
  41. package/dest/public/avm/fixtures/utils.js +3 -2
  42. package/dest/public/avm/opcodes/accrued_substate.js +1 -1
  43. package/dest/public/avm/opcodes/addressing_mode.js +2 -2
  44. package/dest/public/avm/opcodes/arithmetic.d.ts +3 -1
  45. package/dest/public/avm/opcodes/arithmetic.d.ts.map +1 -1
  46. package/dest/public/avm/opcodes/arithmetic.js +11 -1
  47. package/dest/public/avm/opcodes/ec_add.js +2 -2
  48. package/dest/public/avm/opcodes/environment_getters.d.ts +3 -3
  49. package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
  50. package/dest/public/avm/opcodes/environment_getters.js +2 -2
  51. package/dest/public/avm/opcodes/external_calls.d.ts +1 -1
  52. package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
  53. package/dest/public/avm/opcodes/external_calls.js +1 -0
  54. package/dest/public/avm/opcodes/hashing.d.ts +1 -1
  55. package/dest/public/avm/opcodes/hashing.d.ts.map +1 -1
  56. package/dest/public/avm/opcodes/hashing.js +9 -4
  57. package/dest/public/avm/opcodes/memory.js +1 -1
  58. package/dest/public/avm/opcodes/misc.js +2 -2
  59. package/dest/public/avm/revert_reason.d.ts +2 -2
  60. package/dest/public/avm/revert_reason.d.ts.map +1 -1
  61. package/dest/public/avm/revert_reason.js +3 -2
  62. package/dest/public/avm/serialization/bytecode_serialization.d.ts +1 -1
  63. package/dest/public/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  64. package/dest/public/avm/serialization/bytecode_serialization.js +9 -6
  65. package/dest/public/avm/serialization/instruction_serialization.js +1 -1
  66. package/dest/public/avm/test_utils.d.ts +2 -2
  67. package/dest/public/avm/test_utils.d.ts.map +1 -1
  68. package/dest/public/avm/test_utils.js +1 -1
  69. package/dest/public/contracts_db_checkpoint.d.ts +2 -2
  70. package/dest/public/contracts_db_checkpoint.d.ts.map +1 -1
  71. package/dest/public/db_interfaces.d.ts +2 -2
  72. package/dest/public/db_interfaces.d.ts.map +1 -1
  73. package/dest/public/debug_fn_name.d.ts +15 -2
  74. package/dest/public/debug_fn_name.d.ts.map +1 -1
  75. package/dest/public/debug_fn_name.js +28 -2
  76. package/dest/public/executor_metrics.d.ts +1 -1
  77. package/dest/public/executor_metrics.d.ts.map +1 -1
  78. package/dest/public/executor_metrics.js +8 -34
  79. package/dest/public/fixtures/amm_test.js +2 -2
  80. package/dest/public/fixtures/bulk_test.js +5 -69
  81. package/dest/public/fixtures/custom_bytecode_tester.d.ts +28 -6
  82. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -1
  83. package/dest/public/fixtures/custom_bytecode_tester.js +36 -12
  84. package/dest/public/fixtures/custom_bytecode_tests.d.ts +4 -1
  85. package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -1
  86. package/dest/public/fixtures/custom_bytecode_tests.js +74 -9
  87. package/dest/public/fixtures/index.d.ts +4 -2
  88. package/dest/public/fixtures/index.d.ts.map +1 -1
  89. package/dest/public/fixtures/index.js +3 -1
  90. package/dest/public/fixtures/minimal_public_tx.d.ts +2 -7
  91. package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -1
  92. package/dest/public/fixtures/minimal_public_tx.js +2 -12
  93. package/dest/public/fixtures/opcode_spammer.d.ts +123 -0
  94. package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -0
  95. package/dest/public/fixtures/opcode_spammer.js +1681 -0
  96. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +22 -3
  97. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  98. package/dest/public/fixtures/public_tx_simulation_tester.js +50 -13
  99. package/dest/public/fixtures/simple_contract_data_source.d.ts +5 -4
  100. package/dest/public/fixtures/simple_contract_data_source.d.ts.map +1 -1
  101. package/dest/public/fixtures/simple_contract_data_source.js +4 -4
  102. package/dest/public/fixtures/token_test.d.ts +6 -2
  103. package/dest/public/fixtures/token_test.d.ts.map +1 -1
  104. package/dest/public/fixtures/token_test.js +13 -11
  105. package/dest/public/fixtures/utils.d.ts +2 -2
  106. package/dest/public/fixtures/utils.d.ts.map +1 -1
  107. package/dest/public/fixtures/utils.js +4 -3
  108. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts +46 -0
  109. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts.map +1 -0
  110. package/dest/public/fuzzing/avm_fuzzer_simulator.js +139 -0
  111. package/dest/public/fuzzing/avm_simulator_bin.d.ts +2 -0
  112. package/dest/public/fuzzing/avm_simulator_bin.d.ts.map +1 -0
  113. package/dest/public/fuzzing/avm_simulator_bin.js +111 -0
  114. package/dest/public/hinting_db_sources.d.ts +5 -3
  115. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  116. package/dest/public/hinting_db_sources.js +7 -2
  117. package/dest/public/index.d.ts +2 -2
  118. package/dest/public/index.d.ts.map +1 -1
  119. package/dest/public/index.js +1 -1
  120. package/dest/public/public_db_sources.d.ts +2 -2
  121. package/dest/public/public_db_sources.d.ts.map +1 -1
  122. package/dest/public/public_db_sources.js +1 -1
  123. package/dest/public/public_processor/guarded_merkle_tree.d.ts +4 -2
  124. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
  125. package/dest/public/public_processor/guarded_merkle_tree.js +5 -0
  126. package/dest/public/public_processor/public_processor.d.ts +5 -5
  127. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  128. package/dest/public/public_processor/public_processor.js +434 -42
  129. package/dest/public/public_processor/public_processor_metrics.d.ts +1 -1
  130. package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
  131. package/dest/public/public_processor/public_processor_metrics.js +12 -45
  132. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +1 -13
  133. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
  134. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +18 -53
  135. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +21 -34
  136. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
  137. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +60 -139
  138. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts +42 -0
  139. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts.map +1 -0
  140. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.js +86 -0
  141. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +30 -0
  142. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -0
  143. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +171 -0
  144. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts +22 -0
  145. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts.map +1 -0
  146. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.js +52 -0
  147. package/dest/public/public_tx_simulator/factories.d.ts +13 -0
  148. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -0
  149. package/dest/public/public_tx_simulator/factories.js +28 -0
  150. package/dest/public/public_tx_simulator/index.d.ts +4 -1
  151. package/dest/public/public_tx_simulator/index.d.ts.map +1 -1
  152. package/dest/public/public_tx_simulator/index.js +3 -0
  153. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +2 -2
  154. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
  155. package/dest/public/public_tx_simulator/public_tx_context.d.ts +2 -2
  156. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  157. package/dest/public/public_tx_simulator/public_tx_context.js +1 -1
  158. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +3 -3
  159. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  160. package/dest/public/public_tx_simulator/public_tx_simulator.js +11 -5
  161. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +24 -1
  162. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts.map +1 -1
  163. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +2 -2
  164. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
  165. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +395 -19
  166. package/dest/public/side_effect_trace.d.ts +2 -2
  167. package/dest/public/side_effect_trace.d.ts.map +1 -1
  168. package/dest/public/side_effect_trace.js +1 -1
  169. package/dest/public/side_effect_trace_interface.d.ts +2 -2
  170. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  171. package/dest/public/state_manager/nullifiers.d.ts +2 -2
  172. package/dest/public/state_manager/nullifiers.d.ts.map +1 -1
  173. package/dest/public/state_manager/public_storage.d.ts +2 -2
  174. package/dest/public/state_manager/public_storage.d.ts.map +1 -1
  175. package/dest/public/state_manager/public_storage.js +1 -1
  176. package/dest/public/state_manager/state_manager.d.ts +7 -2
  177. package/dest/public/state_manager/state_manager.d.ts.map +1 -1
  178. package/dest/public/state_manager/state_manager.js +5 -2
  179. package/package.json +19 -19
  180. package/src/common/errors.ts +1 -1
  181. package/src/private/acvm/deserialize.ts +1 -1
  182. package/src/private/acvm/serialize.ts +1 -1
  183. package/src/private/circuit_recording/circuit_recorder.ts +17 -16
  184. package/src/public/avm/avm_context.ts +1 -1
  185. package/src/public/avm/avm_contract_call_result.ts +1 -1
  186. package/src/public/avm/avm_execution_environment.ts +1 -1
  187. package/src/public/avm/avm_gas.ts +3 -3
  188. package/src/public/avm/avm_machine_state.ts +1 -1
  189. package/src/public/avm/avm_memory_types.ts +1 -1
  190. package/src/public/avm/avm_simulator.ts +8 -5
  191. package/src/public/avm/errors.ts +17 -3
  192. package/src/public/avm/fixtures/avm_simulation_tester.ts +1 -1
  193. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -1
  194. package/src/public/avm/fixtures/initializers.ts +3 -3
  195. package/src/public/avm/fixtures/utils.ts +3 -2
  196. package/src/public/avm/opcodes/accrued_substate.ts +1 -1
  197. package/src/public/avm/opcodes/addressing_mode.ts +2 -2
  198. package/src/public/avm/opcodes/arithmetic.ts +13 -1
  199. package/src/public/avm/opcodes/ec_add.ts +2 -2
  200. package/src/public/avm/opcodes/environment_getters.ts +4 -4
  201. package/src/public/avm/opcodes/external_calls.ts +1 -0
  202. package/src/public/avm/opcodes/hashing.ts +10 -4
  203. package/src/public/avm/opcodes/memory.ts +1 -1
  204. package/src/public/avm/opcodes/misc.ts +2 -2
  205. package/src/public/avm/revert_reason.ts +6 -3
  206. package/src/public/avm/serialization/bytecode_serialization.ts +17 -6
  207. package/src/public/avm/serialization/instruction_serialization.ts +1 -1
  208. package/src/public/avm/test_utils.ts +1 -1
  209. package/src/public/contracts_db_checkpoint.ts +1 -1
  210. package/src/public/db_interfaces.ts +1 -1
  211. package/src/public/debug_fn_name.ts +35 -3
  212. package/src/public/executor_metrics.ts +7 -34
  213. package/src/public/fixtures/amm_test.ts +2 -2
  214. package/src/public/fixtures/bulk_test.ts +9 -9
  215. package/src/public/fixtures/custom_bytecode_tester.ts +53 -19
  216. package/src/public/fixtures/custom_bytecode_tests.ts +93 -9
  217. package/src/public/fixtures/index.ts +7 -1
  218. package/src/public/fixtures/minimal_public_tx.ts +4 -13
  219. package/src/public/fixtures/opcode_spammer.ts +1638 -0
  220. package/src/public/fixtures/public_tx_simulation_tester.ts +69 -13
  221. package/src/public/fixtures/simple_contract_data_source.ts +8 -9
  222. package/src/public/fixtures/token_test.ts +18 -9
  223. package/src/public/fixtures/utils.ts +2 -3
  224. package/src/public/fuzzing/avm_fuzzer_simulator.ts +240 -0
  225. package/src/public/fuzzing/avm_simulator_bin.ts +153 -0
  226. package/src/public/hinting_db_sources.ts +8 -3
  227. package/src/public/index.ts +7 -1
  228. package/src/public/public_db_sources.ts +1 -1
  229. package/src/public/public_processor/guarded_merkle_tree.ts +6 -1
  230. package/src/public/public_processor/public_processor.ts +43 -27
  231. package/src/public/public_processor/public_processor_metrics.ts +11 -45
  232. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +19 -60
  233. package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +75 -174
  234. package/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +132 -0
  235. package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +237 -0
  236. package/src/public/public_tx_simulator/dumping_cpp_public_tx_simulator.ts +81 -0
  237. package/src/public/public_tx_simulator/factories.ts +41 -0
  238. package/src/public/public_tx_simulator/index.ts +3 -0
  239. package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +1 -1
  240. package/src/public/public_tx_simulator/public_tx_context.ts +1 -1
  241. package/src/public/public_tx_simulator/public_tx_simulator.ts +24 -9
  242. package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +23 -0
  243. package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +1 -1
  244. package/src/public/side_effect_trace.ts +1 -1
  245. package/src/public/side_effect_trace_interface.ts +1 -1
  246. package/src/public/state_manager/nullifiers.ts +1 -1
  247. package/src/public/state_manager/public_storage.ts +1 -1
  248. package/src/public/state_manager/state_manager.ts +10 -3
@@ -1,6 +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
- import { Fr } from '@aztec/foundation/fields';
3
+ import { BlockNumber } from '@aztec/foundation/branded-types';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { type ContractArtifact, encodeArguments } from '@aztec/stdlib/abi';
5
6
  import { PublicSimulatorConfig, type PublicTxResult } from '@aztec/stdlib/avm';
6
7
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -19,7 +20,7 @@ import {
19
20
  } from '../avm/fixtures/utils.js';
20
21
  import { PublicContractsDB } from '../public_db_sources.js';
21
22
  import { MeasuredCppPublicTxSimulator } from '../public_tx_simulator/cpp_public_tx_simulator.js';
22
- import { MeasuredPublicTxSimulator } from '../public_tx_simulator/measured_public_tx_simulator.js';
23
+ import { MeasuredCppVsTsPublicTxSimulator } from '../public_tx_simulator/cpp_vs_ts_public_tx_simulator.js';
23
24
  import type { MeasuredPublicTxSimulatorInterface } from '../public_tx_simulator/public_tx_simulator_interface.js';
24
25
  import { TestExecutorMetrics } from '../test_executor_metrics.js';
25
26
  import { SimpleContractDataSource } from './simple_contract_data_source.js';
@@ -30,7 +31,7 @@ const DEFAULT_GAS_FEES = new GasFees(2, 3);
30
31
  export type TestEnqueuedCall = {
31
32
  sender?: AztecAddress;
32
33
  address: AztecAddress;
33
- fnName: string;
34
+ fnName?: string;
34
35
  args: any[];
35
36
  isStaticCall?: boolean;
36
37
  contractArtifact?: ContractArtifact;
@@ -41,9 +42,21 @@ const defaultConfig: PublicSimulatorConfig = PublicSimulatorConfig.from({
41
42
  collectCallMetadata: true,
42
43
  collectDebugLogs: true,
43
44
  collectHints: false,
45
+ collectPublicInputs: false,
44
46
  collectStatistics: false,
45
47
  });
46
48
 
49
+ /**
50
+ * Factory type for creating a MeasuredPublicTxSimulatorInterface.
51
+ */
52
+ export type MeasuredSimulatorFactory = (
53
+ merkleTree: MerkleTreeWriteOperations,
54
+ contractsDB: PublicContractsDB,
55
+ globals: GlobalVariables,
56
+ metrics: TestExecutorMetrics,
57
+ config: PublicSimulatorConfig,
58
+ ) => MeasuredPublicTxSimulatorInterface;
59
+
47
60
  /**
48
61
  * A test class that extends the BaseAvmSimulationTester to enable real-app testing of the PublicTxSimulator.
49
62
  * It provides an interface for simulating one transaction at a time and maintains state between subsequent
@@ -59,15 +72,17 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
59
72
  contractDataSource: SimpleContractDataSource,
60
73
  globals: GlobalVariables = defaultGlobals(),
61
74
  private metrics: TestExecutorMetrics = new TestExecutorMetrics(),
62
- useCppSimulator: boolean = false,
75
+ simulatorFactory?: MeasuredSimulatorFactory,
63
76
  config: PublicSimulatorConfig = defaultConfig,
64
77
  ) {
65
78
  super(contractDataSource, merkleTree);
66
79
 
67
80
  const contractsDB = new PublicContractsDB(contractDataSource);
68
- this.simulator = useCppSimulator
69
- ? new MeasuredCppPublicTxSimulator(merkleTree, contractsDB, globals, this.metrics, config)
70
- : new MeasuredPublicTxSimulator(merkleTree, contractsDB, globals, this.metrics, config);
81
+ if (simulatorFactory) {
82
+ this.simulator = simulatorFactory(merkleTree, contractsDB, globals, this.metrics, config);
83
+ } else {
84
+ this.simulator = new MeasuredCppPublicTxSimulator(merkleTree, contractsDB, globals, this.metrics, config);
85
+ }
71
86
  }
72
87
 
73
88
  public static async create(
@@ -79,7 +94,10 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
79
94
  ): Promise<PublicTxSimulationTester> {
80
95
  const contractDataSource = new SimpleContractDataSource();
81
96
  const merkleTree = await worldStateService.fork();
82
- return new PublicTxSimulationTester(merkleTree, contractDataSource, globals, metrics, useCppSimulator, config);
97
+ const simulatorFactory: MeasuredSimulatorFactory = useCppSimulator
98
+ ? (mt, cdb, g, m, c) => new MeasuredCppPublicTxSimulator(mt, cdb, g, m, c)
99
+ : (mt, cdb, g, m, c) => new MeasuredCppVsTsPublicTxSimulator(mt, cdb, g, m, c);
100
+ return new PublicTxSimulationTester(merkleTree, contractDataSource, globals, metrics, simulatorFactory, config);
83
101
  }
84
102
 
85
103
  public setMetricsPrefix(prefix: string) {
@@ -136,6 +154,11 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
136
154
  const txLabelWithCount = `${txLabel}/${this.txCount - 1}`;
137
155
  const fullTxLabel = this.metricsPrefix ? `${this.metricsPrefix}/${txLabelWithCount}` : txLabelWithCount;
138
156
 
157
+ if (!this.simulator) {
158
+ throw new Error(
159
+ 'No simulator configured. Pass a simulatorFactory to the constructor or use PublicTxSimulationTester.create()',
160
+ );
161
+ }
139
162
  const avmResult = await this.simulator.simulate(tx, fullTxLabel);
140
163
 
141
164
  // Something like this is often useful for debugging:
@@ -202,6 +225,25 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
202
225
  this.metrics.prettyPrint();
203
226
  }
204
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
+
205
247
  async #createPubicCallRequestForCall(
206
248
  call: TestEnqueuedCall,
207
249
  sender: AztecAddress,
@@ -212,10 +254,24 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
212
254
  throw new Error(`Contract artifact not found for address: ${address}`);
213
255
  }
214
256
 
215
- const fnSelector = await getFunctionSelector(call.fnName, contractArtifact);
216
- const fnAbi = getContractFunctionAbi(call.fnName, contractArtifact)!;
217
- const encodedArgs = encodeArguments(fnAbi, call.args);
218
- 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
+ }
219
275
  const isStaticCall = call.isStaticCall ?? false;
220
276
  const request = await PublicCallRequest.fromCalldata(sender, address, isStaticCall, calldata);
221
277
 
@@ -227,6 +283,6 @@ export function defaultGlobals() {
227
283
  const globals = GlobalVariables.empty();
228
284
  globals.timestamp = DEFAULT_TIMESTAMP;
229
285
  globals.gasFees = DEFAULT_GAS_FEES; // apply some nonzero default gas fees
230
- globals.blockNumber = DEFAULT_BLOCK_NUMBER;
286
+ globals.blockNumber = BlockNumber(DEFAULT_BLOCK_NUMBER);
231
287
  return globals;
232
288
  }
@@ -1,4 +1,5 @@
1
- import type { Fr } from '@aztec/foundation/fields';
1
+ import type { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
3
  import { createLogger } from '@aztec/foundation/log';
3
4
  import type { ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
4
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -59,7 +60,7 @@ export class SimpleContractDataSource implements ContractDataSource {
59
60
 
60
61
  /////////////////////////////////////////////////////////////
61
62
  // ContractDataSource function implementations
62
- getBlockNumber(): Promise<number> {
63
+ getBlockNumber(): Promise<BlockNumber> {
63
64
  throw new Error('Method not implemented.');
64
65
  }
65
66
 
@@ -90,19 +91,17 @@ export class SimpleContractDataSource implements ContractDataSource {
90
91
  return this.contractArtifacts.get(contractInstance!.currentContractClassId.toString());
91
92
  }
92
93
 
93
- async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string> {
94
+ async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
94
95
  const contractInstance = await this.getContract(address);
95
96
  if (!contractInstance) {
96
- this.logger.warn(
97
- `Couldn't get fn name for debugging. Contract not in tester's ContractDataSource. Using selector:${selector} instead...`,
98
- );
99
- return `selector:${selector.toString()}`;
97
+ this.logger.warn(`Couldn't get fn name for debugging. Contract not in tester's ContractDataSource.`);
98
+ return undefined;
100
99
  }
101
100
  const key = `${contractInstance.currentContractClassId.toString()}:${selector.toString()}`;
102
101
  const fnName = this.debugFunctionName.get(key);
103
102
  if (!fnName) {
104
- this.logger.warn(`Couldn't get fn name for debugging. Using selector:${selector} instead...`);
105
- return selector.toString();
103
+ this.logger.warn(`Couldn't get fn name for debugging...`);
104
+ return undefined;
106
105
  }
107
106
  return fnName;
108
107
  }
@@ -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';
@@ -7,11 +7,17 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
7
7
 
8
8
  import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
9
9
 
10
+ export type TokenTestOptions = {
11
+ /** Skip return value assertions in balance checks (useful for benchmarking with collectCallMetadata=false) */
12
+ skipReturnValueAssertions?: boolean;
13
+ };
14
+
10
15
  export async function tokenTest(
11
16
  tester: PublicTxSimulationTester,
12
17
  logger: Logger,
13
18
  tokenArtifact: ContractArtifact,
14
19
  expectToBeTrue: (x: boolean) => void,
20
+ options: TokenTestOptions = {},
15
21
  ) {
16
22
  const timer = new Timer();
17
23
 
@@ -36,7 +42,7 @@ export async function tokenTest(
36
42
  ],
37
43
  );
38
44
  expectToBeTrue(mintResult.revertCode.isOK());
39
- await checkBalance(tester, token, sender, sender, mintAmount, expectToBeTrue);
45
+ await checkBalance(tester, token, sender, sender, mintAmount, expectToBeTrue, options);
40
46
 
41
47
  const authwitNonce = new Fr(0);
42
48
  const transferAmount = 50n;
@@ -54,8 +60,8 @@ export async function tokenTest(
54
60
  ],
55
61
  );
56
62
  expectToBeTrue(transferResult.revertCode.isOK());
57
- await checkBalance(tester, token, sender, receiver, mintAmount - transferAmount, expectToBeTrue);
58
- await checkBalance(tester, token, sender, receiver, transferAmount, expectToBeTrue);
63
+ await checkBalance(tester, token, sender, sender, mintAmount - transferAmount, expectToBeTrue, options);
64
+ await checkBalance(tester, token, sender, receiver, transferAmount, expectToBeTrue, options);
59
65
 
60
66
  // EXECUTE! This means that if using AvmProvingTester subclass, it will PROVE the transaction!
61
67
  const burnResult = await tester.executeTxWithLabel(
@@ -71,7 +77,7 @@ export async function tokenTest(
71
77
  ],
72
78
  );
73
79
  expectToBeTrue(burnResult.revertCode.isOK());
74
- await checkBalance(tester, token, sender, receiver, 0n, expectToBeTrue);
80
+ await checkBalance(tester, token, sender, receiver, 0n, expectToBeTrue, options);
75
81
 
76
82
  logger.info(`TokenContract test took ${timer.ms()}ms\n`);
77
83
  }
@@ -116,6 +122,7 @@ async function checkBalance(
116
122
  account: AztecAddress,
117
123
  expectedBalance: bigint,
118
124
  expectToBeTrue: (x: boolean) => void,
125
+ options: TokenTestOptions = {},
119
126
  ) {
120
127
  // Strictly simulate this! No need to "execute" (aka prove if using AvmProvingTester subclass).
121
128
  const balResult = await tester.simulateTxWithLabel(
@@ -132,8 +139,10 @@ async function checkBalance(
132
139
  ],
133
140
  );
134
141
  expectToBeTrue(balResult.revertCode.isOK());
135
- // should be 1 call with 1 return value that is expectedBalance
136
- expectToBeTrue(balResult.appLogicReturnValues.length == 1);
137
- expectToBeTrue(balResult.appLogicReturnValues[0].values!.length == 1);
138
- expectToBeTrue(balResult.appLogicReturnValues[0].values![0].toBigInt() == expectedBalance);
142
+ if (!options.skipReturnValueAssertions) {
143
+ // should be 1 call with 1 return value that is expectedBalance
144
+ const appLogicReturnValues = balResult.getAppLogicReturnValues();
145
+ expectToBeTrue(appLogicReturnValues.length === 1);
146
+ expectToBeTrue(appLogicReturnValues[0].values?.[0]?.toBigInt() === expectedBalance);
147
+ }
139
148
  }
@@ -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,153 @@
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 { createInterface } from 'readline';
13
+
14
+ import { AvmFuzzerSimulator, FuzzerSimulationRequest } from './avm_fuzzer_simulator.js';
15
+
16
+ /** Write data to stdout, letting Node handle buffering. */
17
+ function writeOutput(data: string): Promise<void> {
18
+ return new Promise<void>((resolve, reject) => {
19
+ process.stdout.write(data, err => {
20
+ if (err) {
21
+ reject(err);
22
+ } else {
23
+ resolve();
24
+ }
25
+ });
26
+ });
27
+ }
28
+
29
+ // This cache holds opened world states to avoid reopening them for each invocation.
30
+ // It's a map so that in the future we could support multiple world states (if we had multiple fuzzers).
31
+ const worldStateCache = new Map<string, NativeWorldStateService>();
32
+
33
+ async function openExistingWorldState(dataDir: string, mapSizeKb: number): Promise<NativeWorldStateService> {
34
+ const cached = worldStateCache.get(dataDir);
35
+ if (cached) {
36
+ return cached;
37
+ }
38
+
39
+ const ws = await NativeWorldStateService.new(EthAddress.ZERO, dataDir, {
40
+ archiveTreeMapSizeKb: mapSizeKb,
41
+ nullifierTreeMapSizeKb: mapSizeKb,
42
+ noteHashTreeMapSizeKb: mapSizeKb,
43
+ messageTreeMapSizeKb: mapSizeKb,
44
+ publicDataTreeMapSizeKb: mapSizeKb,
45
+ });
46
+
47
+ worldStateCache.set(dataDir, ws);
48
+ return ws;
49
+ }
50
+
51
+ async function simulateWithFuzzer(
52
+ dataDir: string,
53
+ mapSizeKb: number,
54
+ txHint: AvmTxHint,
55
+ globals: GlobalVariables,
56
+ rawContractClasses: any[], // Replace these when we are moving contract classes to TS
57
+ rawContractInstances: [any, any][], // Replace these when we are moving contract instances to TS
58
+ ): Promise<{ reverted: boolean; output: Fr[]; revertReason?: string; publicInputs: AvmCircuitPublicInputs }> {
59
+ const worldStateService = await openExistingWorldState(dataDir, mapSizeKb);
60
+
61
+ const simulator = await AvmFuzzerSimulator.create(worldStateService, globals);
62
+
63
+ // Register contract classes from C++
64
+ for (const rawClass of rawContractClasses) {
65
+ await simulator.addContractClassFromCpp(rawClass);
66
+ }
67
+
68
+ // Register contract instances from C++
69
+ for (const [rawAddress, rawInstance] of rawContractInstances) {
70
+ await simulator.addContractInstanceFromCpp(rawAddress, rawInstance);
71
+ }
72
+
73
+ const result = await simulator.simulate(txHint);
74
+
75
+ const output = result
76
+ .getAppLogicReturnValues()
77
+ .flatMap((rv: { values?: Fr[] } | undefined) => rv?.values?.filter((v: Fr | null | undefined) => v != null) ?? []);
78
+
79
+ return {
80
+ reverted: !result.revertCode.isOK(),
81
+ output,
82
+ revertReason: result.findRevertReason()?.message,
83
+ publicInputs: result.publicInputs!,
84
+ };
85
+ }
86
+
87
+ async function execute(base64Line: string): Promise<void> {
88
+ try {
89
+ // Decode base64 and deserialize the entire request from msgpack
90
+ const buffer = Buffer.from(base64Line.trim(), 'base64');
91
+ const rawRequest = deserializeFromMessagePack(buffer);
92
+ const request = FuzzerSimulationRequest.fromPlainObject(rawRequest);
93
+
94
+ // Run the TS simulation
95
+ const result = await simulateWithFuzzer(
96
+ request.wsDataDir,
97
+ request.wsMapSizeKb,
98
+ request.tx,
99
+ request.globals,
100
+ request.contractClasses,
101
+ request.contractInstances,
102
+ );
103
+
104
+ // Serialize the result to msgpack and encode it in base64 for output
105
+ const resultBuffer = serializeWithMessagePack({
106
+ reverted: result.reverted,
107
+ output: result.output,
108
+ revertReason: result.revertReason ?? '',
109
+ endTreeSnapshots: result.publicInputs.endTreeSnapshots,
110
+ });
111
+ const base64Response = resultBuffer.toString('base64') + '\n';
112
+ await writeOutput(base64Response);
113
+ } catch (error: any) {
114
+ // If we error, treat as reverted
115
+ const errorResult = serializeWithMessagePack({
116
+ reverted: true,
117
+ output: [] as Fr[],
118
+ revertReason: `Unexpected Error ${error.message}`,
119
+ endTreeSnapshots: TreeSnapshots.empty(),
120
+ });
121
+ await writeOutput(errorResult.toString('base64') + '\n');
122
+ }
123
+ }
124
+
125
+ function mainLoop() {
126
+ const rl = createInterface({ input: process.stdin, terminal: false });
127
+
128
+ // Process lines sequentially to avoid race conditions in responses
129
+ const lineQueue: string[] = [];
130
+ let processing = false;
131
+
132
+ async function processQueue() {
133
+ if (processing || lineQueue.length === 0) {
134
+ return;
135
+ }
136
+ processing = true;
137
+ while (lineQueue.length > 0) {
138
+ const line = lineQueue.shift()!;
139
+ await execute(line);
140
+ }
141
+ processing = false;
142
+ }
143
+
144
+ rl.on('line', (line: string) => {
145
+ if (line.trim()) {
146
+ lineQueue.push(line);
147
+ void processQueue();
148
+ }
149
+ });
150
+ rl.on('close', () => process.exit(0));
151
+ }
152
+
153
+ void mainLoop();