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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dest/client.d.ts +1 -3
  2. package/dest/client.d.ts.map +1 -1
  3. package/dest/client.js +0 -2
  4. package/dest/private/circuit_recording/circuit_recorder.d.ts +36 -23
  5. package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
  6. package/dest/private/circuit_recording/circuit_recorder.js +65 -69
  7. package/dest/private/circuit_recording/file_circuit_recorder.d.ts +7 -19
  8. package/dest/private/circuit_recording/file_circuit_recorder.d.ts.map +1 -1
  9. package/dest/private/circuit_recording/file_circuit_recorder.js +38 -42
  10. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts +1 -1
  11. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts.map +1 -1
  12. package/dest/private/circuit_recording/simulator_recorder_wrapper.js +11 -14
  13. package/dest/public/avm/testing/base_avm_simulation_tester.js +1 -1
  14. package/dest/public/avm/testing/utils.js +1 -1
  15. package/dest/public/avm_simulator.d.ts +28 -0
  16. package/dest/public/avm_simulator.d.ts.map +1 -0
  17. package/dest/public/avm_simulator.js +4 -0
  18. package/dest/public/avm_simulator_pool.d.ts +45 -0
  19. package/dest/public/avm_simulator_pool.d.ts.map +1 -0
  20. package/dest/public/avm_simulator_pool.js +197 -0
  21. package/dest/public/cdb/generated/api_types.d.ts +171 -0
  22. package/dest/public/cdb/generated/api_types.d.ts.map +1 -0
  23. package/dest/public/cdb/generated/api_types.js +314 -0
  24. package/dest/public/cdb/generated/server.d.ts +26 -0
  25. package/dest/public/cdb/generated/server.d.ts.map +1 -0
  26. package/dest/public/cdb/generated/server.js +135 -0
  27. package/dest/public/cdb_ipc_server.d.ts +33 -0
  28. package/dest/public/cdb_ipc_server.d.ts.map +1 -0
  29. package/dest/public/cdb_ipc_server.js +153 -0
  30. package/dest/public/fixtures/amm_test.js +2 -2
  31. package/dest/public/fixtures/bulk_test.js +2 -2
  32. package/dest/public/fixtures/custom_bytecode_tester.d.ts +1 -1
  33. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -1
  34. package/dest/public/fixtures/custom_bytecode_tester.js +2 -2
  35. package/dest/public/fixtures/index.d.ts +2 -1
  36. package/dest/public/fixtures/index.d.ts.map +1 -1
  37. package/dest/public/fixtures/index.js +1 -0
  38. package/dest/public/fixtures/public_processor_test_env.d.ts +30 -0
  39. package/dest/public/fixtures/public_processor_test_env.d.ts.map +1 -0
  40. package/dest/public/fixtures/public_processor_test_env.js +73 -0
  41. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +9 -5
  42. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  43. package/dest/public/fixtures/public_tx_simulation_tester.js +29 -11
  44. package/dest/public/fixtures/token_test.js +3 -3
  45. package/dest/public/fixtures/utils.d.ts +1 -1
  46. package/dest/public/fixtures/utils.d.ts.map +1 -1
  47. package/dest/public/fixtures/utils.js +5 -3
  48. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts +7 -2
  49. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts.map +1 -1
  50. package/dest/public/fuzzing/avm_fuzzer_simulator.js +15 -6
  51. package/dest/public/index.d.ts +5 -2
  52. package/dest/public/index.d.ts.map +1 -1
  53. package/dest/public/index.js +2 -1
  54. package/dest/public/public_db_sources.d.ts +2 -2
  55. package/dest/public/public_db_sources.d.ts.map +1 -1
  56. package/dest/public/public_db_sources.js +1 -1
  57. package/dest/public/public_processor/public_processor.d.ts +8 -4
  58. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  59. package/dest/public/public_processor/public_processor.js +17 -13
  60. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.d.ts +6 -12
  61. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.d.ts.map +1 -1
  62. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.js +8 -21
  63. package/dest/public/public_tx_simulator/factories.d.ts +5 -5
  64. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -1
  65. package/dest/public/public_tx_simulator/factories.js +5 -5
  66. package/dest/public/public_tx_simulator/index.d.ts +3 -3
  67. package/dest/public/public_tx_simulator/index.d.ts.map +1 -1
  68. package/dest/public/public_tx_simulator/index.js +1 -1
  69. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +16 -16
  70. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  71. package/dest/public/public_tx_simulator/public_tx_simulator.js +59 -58
  72. package/dest/public/public_tx_simulator/public_tx_simulator_base.d.ts +10 -8
  73. package/dest/public/public_tx_simulator/public_tx_simulator_base.d.ts.map +1 -1
  74. package/dest/public/public_tx_simulator/public_tx_simulator_base.js +11 -8
  75. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +5 -5
  76. package/package.json +21 -17
  77. package/src/client.ts +0 -2
  78. package/src/private/circuit_recording/circuit_recorder.ts +84 -78
  79. package/src/private/circuit_recording/file_circuit_recorder.ts +38 -48
  80. package/src/private/circuit_recording/simulator_recorder_wrapper.ts +9 -15
  81. package/src/public/avm/testing/base_avm_simulation_tester.ts +1 -1
  82. package/src/public/avm/testing/utils.ts +1 -1
  83. package/src/public/avm_simulator.ts +29 -0
  84. package/src/public/avm_simulator_pool.ts +226 -0
  85. package/src/public/cdb/generated/api_types.ts +457 -0
  86. package/src/public/cdb/generated/server.ts +109 -0
  87. package/src/public/cdb_ipc_server.ts +197 -0
  88. package/src/public/fixtures/amm_test.ts +2 -2
  89. package/src/public/fixtures/bulk_test.ts +2 -2
  90. package/src/public/fixtures/custom_bytecode_tester.ts +2 -2
  91. package/src/public/fixtures/index.ts +1 -0
  92. package/src/public/fixtures/public_processor_test_env.ts +88 -0
  93. package/src/public/fixtures/public_tx_simulation_tester.ts +37 -25
  94. package/src/public/fixtures/token_test.ts +3 -3
  95. package/src/public/fixtures/utils.ts +6 -11
  96. package/src/public/fuzzing/avm_fuzzer_simulator.ts +28 -10
  97. package/src/public/index.ts +4 -0
  98. package/src/public/public_db_sources.ts +1 -1
  99. package/src/public/public_processor/public_processor.ts +22 -15
  100. package/src/public/public_tx_simulator/dumping_public_tx_simulator.ts +13 -29
  101. package/src/public/public_tx_simulator/factories.ts +24 -7
  102. package/src/public/public_tx_simulator/index.ts +5 -2
  103. package/src/public/public_tx_simulator/public_tx_simulator.ts +70 -81
  104. package/src/public/public_tx_simulator/public_tx_simulator_base.ts +8 -6
  105. package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +5 -5
  106. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +0 -19
  107. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +0 -1
  108. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +0 -99
  109. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +0 -125
@@ -50,6 +50,7 @@ import { ForkCheckpoint } from '@aztec/world-state/native';
50
50
 
51
51
  import { AssertionError } from 'assert';
52
52
 
53
+ import type { AvmSimulator } from '../avm_simulator.js';
53
54
  import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
54
55
  import {
55
56
  type PublicTxSimulatorConfig,
@@ -66,6 +67,7 @@ export class PublicProcessorFactory {
66
67
  private log: Logger;
67
68
  constructor(
68
69
  private contractDataSource: ContractDataSource,
70
+ private avmSimulator: AvmSimulator,
69
71
  private dateProvider: DateProvider = new DateProvider(),
70
72
  protected telemetryClient: TelemetryClient = getTelemetryClient(),
71
73
  bindings?: LoggerBindings,
@@ -74,7 +76,9 @@ export class PublicProcessorFactory {
74
76
  }
75
77
 
76
78
  /**
77
- * Creates a new instance of a PublicProcessor.
79
+ * Creates a new instance of a PublicProcessor. The simulator it drives reads contract data from the fork's
80
+ * contracts DB, scoped by the fork id so AVM requests route to the right state.
81
+ *
78
82
  * @param globalVariables - The global variables for the block being processed.
79
83
  * @param contractsDB - Optional pre-populated contracts DB; a fresh one is constructed if omitted.
80
84
  * @returns A new instance of a PublicProcessor.
@@ -85,8 +89,10 @@ export class PublicProcessorFactory {
85
89
  config: PublicSimulatorConfig,
86
90
  contractsDB: PublicContractsDB = new PublicContractsDB(this.contractDataSource, this.log.getBindings()),
87
91
  ): PublicProcessor {
92
+ const forkId = merkleTree.getRevision().forkId;
93
+
88
94
  const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
89
- const publicTxSimulator = this.createPublicTxSimulator(guardedFork, contractsDB, globalVariables, config);
95
+ const publicTxSimulator = this.createPublicTxSimulator(forkId, globalVariables, contractsDB, config);
90
96
 
91
97
  return new PublicProcessor(
92
98
  globalVariables,
@@ -100,15 +106,16 @@ export class PublicProcessorFactory {
100
106
  }
101
107
 
102
108
  protected createPublicTxSimulator(
103
- merkleTree: MerkleTreeWriteOperations,
104
- contractsDB: PublicContractsDB,
109
+ forkId: number,
105
110
  globalVariables: GlobalVariables,
111
+ contractsDB: PublicContractsDB,
106
112
  config?: Partial<PublicTxSimulatorConfig>,
107
113
  ): PublicTxSimulatorInterface {
108
114
  return new TelemetryPublicTxSimulator(
109
- merkleTree,
110
- contractsDB,
115
+ this.avmSimulator,
111
116
  globalVariables,
117
+ contractsDB,
118
+ forkId,
112
119
  this.telemetryClient,
113
120
  config,
114
121
  this.log.getBindings(),
@@ -130,10 +137,6 @@ class PublicProcessorAbortError extends Error {
130
137
  }
131
138
  }
132
139
 
133
- function isPublicProcessorInterruptError(err: any) {
134
- return err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError';
135
- }
136
-
137
140
  /**
138
141
  * Converts Txs lifted from the P2P module into ProcessedTx objects by executing
139
142
  * any public function calls in them. Txs with private calls only are unaffected.
@@ -326,11 +329,15 @@ export class PublicProcessor implements Traceable {
326
329
  // Commit the tx-level contracts checkpoint on success
327
330
  this.contractsDB.commitCheckpoint();
328
331
  } catch (err: any) {
329
- if (isPublicProcessorInterruptError(err)) {
330
- const interruptReason = err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort signal';
331
- this.log.warn(`Stopping tx processing due to ${interruptReason}.`);
332
- // The tx may still be executing on a worker thread (C++ via NAPI).
333
- // Signal cancellation AND WAIT for the simulation to actually stop before touching fork checkpoints.
332
+ if (err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError') {
333
+ this.log.warn(
334
+ `Stopping tx processing due to ${err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort'}.`,
335
+ );
336
+ // We hit the transaction execution deadline or an external abort signal.
337
+ // There may still be a simulation in progress.
338
+ // Signal cancellation AND WAIT for the simulation to actually stop. Cancellation is
339
+ // cooperative: the simulator may be mid slow-operation and won't observe the flag until it
340
+ // completes, and without waiting we'd revert checkpoints while it's still writing to state.
334
341
  await this.publicTxSimulator.cancel?.();
335
342
 
336
343
  // Now stop the guarded fork to prevent any further TS-side access to the world state.
@@ -4,35 +4,36 @@ import {
4
4
  AvmCircuitPublicInputs,
5
5
  AvmExecutionHints,
6
6
  type PublicSimulatorConfig,
7
- PublicTxResult,
7
+ type PublicTxResult,
8
8
  serializeWithMessagePack,
9
9
  } from '@aztec/stdlib/avm';
10
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
11
- import type { GlobalVariables, Tx, TxHash } from '@aztec/stdlib/tx';
10
+ import type { GlobalVariables, Tx } from '@aztec/stdlib/tx';
12
11
 
13
12
  import { strict as assert } from 'assert';
14
13
  import { mkdirSync, writeFileSync } from 'fs';
15
14
  import { join } from 'path';
16
15
 
16
+ import type { AvmSimulator } from '../avm_simulator.js';
17
17
  import type { PublicContractsDB } from '../public_db_sources.js';
18
18
  import { PublicTxSimulator } from './public_tx_simulator.js';
19
19
 
20
20
  /**
21
- * A C++ public tx simulator that dumps AVM circuit inputs to disk after simulation.
22
- * Used during nightly CI runs to collect circuit inputs for benchmarking.
21
+ * A {@link PublicTxSimulator} that dumps AVM circuit inputs to disk after simulation.
22
+ * Used during nightly CI runs to collect circuit inputs for AVM proving benchmarks.
23
23
  */
24
24
  export class DumpingPublicTxSimulator extends PublicTxSimulator {
25
25
  private readonly outputDir: string;
26
26
 
27
27
  constructor(
28
- merkleTree: MerkleTreeWriteOperations,
29
- contractsDB: PublicContractsDB,
28
+ avmSimulator: AvmSimulator,
30
29
  globalVariables: GlobalVariables,
30
+ contractsDB: PublicContractsDB,
31
+ forkId: number,
31
32
  config: Partial<PublicSimulatorConfig>,
32
33
  outputDir: string,
33
34
  bindings?: LoggerBindings,
34
35
  ) {
35
- super(merkleTree, contractsDB, globalVariables, config, bindings);
36
+ super(avmSimulator, globalVariables, contractsDB, forkId, config, bindings);
36
37
  assert(config.collectHints === true, 'collectHints must be enabled to dump AVM circuit inputs');
37
38
  assert(config.collectPublicInputs === true, 'collectPublicInputs must be enabled to dump AVM circuit inputs');
38
39
  this.outputDir = outputDir;
@@ -40,44 +41,27 @@ export class DumpingPublicTxSimulator extends PublicTxSimulator {
40
41
 
41
42
  public override async simulate(tx: Tx): Promise<PublicTxResult> {
42
43
  const result = await super.simulate(tx);
43
-
44
- // Dump the circuit inputs after successful simulation
45
- const txHash = this.computeTxHash(tx);
46
- this.dumpAvmCircuitInputs(result, txHash);
47
-
44
+ this.dumpAvmCircuitInputs(result, tx.getTxHash().toString());
48
45
  return result;
49
46
  }
50
47
 
51
- /**
52
- * Dumps AVM circuit inputs to disk.
53
- *
54
- * @param result - The simulation result containing hints and public inputs
55
- * @param txHash - The transaction hash to use in the filename
56
- */
57
- private dumpAvmCircuitInputs(result: PublicTxResult, txHash: TxHash): void {
48
+ private dumpAvmCircuitInputs(result: PublicTxResult, txHash: string): void {
58
49
  try {
59
- // Ensure the output directory exists
60
50
  mkdirSync(this.outputDir, { recursive: true });
61
51
 
62
- // Generate filename using transaction hash
63
- const filename = `avm-circuit-inputs-tx-${txHash.toString()}.bin`;
52
+ const filename = `avm-circuit-inputs-tx-${txHash}.bin`;
64
53
  const filepath = join(this.outputDir, filename);
65
54
 
66
- // Create circuit inputs from the result
67
55
  const hints = result.hints ?? AvmExecutionHints.empty();
68
56
  const publicInputs = result.publicInputs ?? AvmCircuitPublicInputs.empty();
69
57
  const avmCircuitInputs = new AvmCircuitInputs(hints, publicInputs);
70
58
 
71
- // Serialize the circuit inputs using MessagePack
72
59
  const serialized = serializeWithMessagePack(avmCircuitInputs);
73
-
74
- // Write to disk
75
60
  writeFileSync(filepath, serialized);
76
61
 
77
62
  this.log.debug(`Dumped AVM circuit inputs to ${filepath}`);
78
63
  } catch (error) {
79
- // Non-blocking error handling - log but don't interrupt processing
80
- this.log.warn(`Failed to dump AVM circuit inputs for tx ${txHash.toString()}: ${error}`);
64
+ this.log.warn(`Failed to dump AVM circuit inputs for tx ${txHash}: ${error}`);
81
65
  }
82
66
  }
83
67
  }
@@ -1,22 +1,23 @@
1
1
  import type { LoggerBindings } from '@aztec/foundation/log';
2
2
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
3
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
4
3
  import type { GlobalVariables } from '@aztec/stdlib/tx';
5
4
  import type { TelemetryClient } from '@aztec/telemetry-client';
6
5
 
6
+ import type { AvmSimulator } from '../avm_simulator.js';
7
7
  import type { PublicContractsDB } from '../public_db_sources.js';
8
8
  import { DumpingPublicTxSimulator } from './dumping_public_tx_simulator.js';
9
9
  import { TelemetryPublicTxSimulator } from './public_tx_simulator.js';
10
10
 
11
11
  /**
12
- * Creates a public tx simulator for block building.
13
- * Uses DumpingPublicTxSimulator if DUMP_AVM_INPUTS_TO_DIR env var is set (for CI/testing avm circuit),
12
+ * Creates an IPC-based public tx simulator for block building.
13
+ * Uses DumpingPublicTxSimulator if DUMP_AVM_INPUTS_TO_DIR env var is set (for CI/testing the AVM circuit),
14
14
  * otherwise uses TelemetryPublicTxSimulator (for production).
15
15
  */
16
16
  export function createPublicTxSimulatorForBlockBuilding(
17
- merkleTree: MerkleTreeWriteOperations,
18
- contractsDB: PublicContractsDB,
17
+ avmSimulator: AvmSimulator,
19
18
  globalVariables: GlobalVariables,
19
+ contractsDB: PublicContractsDB,
20
+ forkId: number,
20
21
  telemetryClient: TelemetryClient,
21
22
  bindings?: LoggerBindings,
22
23
  collectDebugLogs = false,
@@ -38,7 +39,23 @@ export function createPublicTxSimulatorForBlockBuilding(
38
39
  collectHints: true,
39
40
  collectPublicInputs: true,
40
41
  };
41
- return new DumpingPublicTxSimulator(merkleTree, contractsDB, globalVariables, dumpingConfig, dumpDir, bindings);
42
+ return new DumpingPublicTxSimulator(
43
+ avmSimulator,
44
+ globalVariables,
45
+ contractsDB,
46
+ forkId,
47
+ dumpingConfig,
48
+ dumpDir,
49
+ bindings,
50
+ );
42
51
  }
43
- return new TelemetryPublicTxSimulator(merkleTree, contractsDB, globalVariables, telemetryClient, config, bindings);
52
+ return new TelemetryPublicTxSimulator(
53
+ avmSimulator,
54
+ globalVariables,
55
+ contractsDB,
56
+ forkId,
57
+ telemetryClient,
58
+ config,
59
+ bindings,
60
+ );
44
61
  }
@@ -1,5 +1,8 @@
1
- export { PublicTxSimulator, TelemetryPublicTxSimulator } from './public_tx_simulator.js';
1
+ export { PublicTxSimulator, MeasuredPublicTxSimulator, TelemetryPublicTxSimulator } from './public_tx_simulator.js';
2
2
  export { DumpingPublicTxSimulator } from './dumping_public_tx_simulator.js';
3
3
  export { createPublicTxSimulatorForBlockBuilding } from './factories.js';
4
- export type { PublicTxSimulatorInterface } from './public_tx_simulator_interface.js';
4
+ export type {
5
+ PublicTxSimulatorInterface,
6
+ MeasuredPublicTxSimulatorInterface,
7
+ } from './public_tx_simulator_interface.js';
5
8
  export type { PublicTxResult, PublicSimulatorConfig as PublicTxSimulatorConfig } from '@aztec/stdlib/avm';
@@ -1,7 +1,5 @@
1
1
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
2
2
  import { sleep } from '@aztec/foundation/sleep';
3
- import { type CancellationToken, avmSimulate, cancelSimulation, createCancellationToken } from '@aztec/native';
4
- import { ProtocolContractsList } from '@aztec/protocol-contracts';
5
3
  import {
6
4
  AvmFastSimulationInputs,
7
5
  AvmTxHint,
@@ -10,14 +8,14 @@ import {
10
8
  deserializeFromMessagePack,
11
9
  } from '@aztec/stdlib/avm';
12
10
  import { SimulationError } from '@aztec/stdlib/errors';
13
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
14
11
  import type { GlobalVariables, Tx } from '@aztec/stdlib/tx';
12
+ import { WorldStateRevision } from '@aztec/stdlib/world-state';
15
13
  import { type TelemetryClient, type Tracer, getTelemetryClient } from '@aztec/telemetry-client';
16
14
 
15
+ import type { AvmContractsDBContext, AvmSimulator } from '../avm_simulator.js';
17
16
  import { ExecutorMetrics } from '../executor_metrics.js';
18
17
  import type { ExecutorMetricsInterface } from '../executor_metrics_interface.js';
19
18
  import type { PublicContractsDB } from '../public_db_sources.js';
20
- import { ContractProviderForCpp } from './contract_provider_for_cpp.js';
21
19
  import { PublicTxSimulatorBase } from './public_tx_simulator_base.js';
22
20
  import type {
23
21
  MeasuredPublicTxSimulatorInterface,
@@ -25,146 +23,136 @@ import type {
25
23
  } from './public_tx_simulator_interface.js';
26
24
 
27
25
  /**
28
- * Simulates a transaction's public portion using the C++ AVM simulator.
29
- * The C++ simulator accesses the world state directly/natively within C++.
30
- * For contract DB accesses, it makes callbacks through NAPI back to the TS PublicContractsDB cache.
26
+ * Simulates a transaction's public portion by running its public calls through an {@link AvmSimulator}.
27
+ * `forkId` selects the fork whose contract data the simulation reads.
31
28
  */
32
29
  export class PublicTxSimulator extends PublicTxSimulatorBase implements PublicTxSimulatorInterface {
33
30
  protected override log: Logger;
34
- /** Current cancellation token for in-flight simulation. */
35
- private cancellationToken?: CancellationToken;
31
+ /** Aborts the in-flight simulation. */
32
+ private abortController?: AbortController;
36
33
  /** Current simulation promise, used to wait for completion after cancellation. */
37
- private simulationPromise?: Promise<Buffer>;
34
+ private simulationPromise?: Promise<PublicTxResult>;
38
35
 
39
36
  constructor(
40
- merkleTree: MerkleTreeWriteOperations,
41
- contractsDB: PublicContractsDB,
37
+ avmSimulator: AvmSimulator,
42
38
  globalVariables: GlobalVariables,
39
+ contractsDB: PublicContractsDB,
40
+ forkId: number,
43
41
  config?: Partial<PublicSimulatorConfig>,
44
42
  bindings?: LoggerBindings,
45
43
  ) {
46
- super(merkleTree, contractsDB, globalVariables, config, undefined, bindings);
44
+ super(avmSimulator, globalVariables, contractsDB, forkId, config, undefined, bindings);
47
45
  this.log = createLogger(`simulator:public_tx_simulator`, bindings);
48
46
  }
49
47
 
50
48
  /**
51
- * Simulate a transaction's public portion using the C++ avvm simulator.
49
+ * Simulate a transaction's public portion.
52
50
  *
53
51
  * @param tx - The transaction to simulate.
54
52
  * @returns The result of the transaction's public execution.
55
53
  */
56
54
  public async simulate(tx: Tx): Promise<PublicTxResult> {
57
- const txHash = this.computeTxHash(tx);
58
- this.log.debug(`C++ simulation of ${tx.publicFunctionCalldata.length} public calls for tx ${txHash}`, {
59
- txHash,
60
- });
61
-
62
- const wsRevision = this.merkleTree.getRevision();
63
- const wsdbIpcPath = this.merkleTree.getIpcPath();
55
+ this.abortController = new AbortController();
56
+ this.simulationPromise = this.doSimulate(tx, this.abortController.signal);
57
+ try {
58
+ return await this.simulationPromise;
59
+ } finally {
60
+ this.abortController = undefined;
61
+ this.simulationPromise = undefined;
62
+ }
63
+ }
64
64
 
65
- this.log.trace(`Running C++ simulation with world state revision ${JSON.stringify(wsRevision)}`);
65
+ protected async doSimulate(tx: Tx, signal: AbortSignal): Promise<PublicTxResult> {
66
+ const txHash = this.computeTxHash(tx);
67
+ this.log.debug(
68
+ `Simulating ${tx.publicFunctionCalldata.length} public calls for tx ${txHash}, forkId=${this.forkId}`,
69
+ { txHash },
70
+ );
66
71
 
67
- // Create the fast simulation inputs
72
+ // Create the fast simulation inputs.
68
73
  const txHint = AvmTxHint.fromTx(tx, this.globalVariables.gasFees);
69
- const protocolContracts = ProtocolContractsList;
70
74
  const fastSimInputs = new AvmFastSimulationInputs(
71
- wsRevision,
75
+ // blockNumber: WorldStateRevision.LATEST sentinel so the WSDB walks the fork's current
76
+ // uncommitted state. Using 0 here makes WSDB treat this as a historical query against
77
+ // the empty genesis tree and miss any in-fork uncommitted leaves (deployed contracts,
78
+ // etc.) from earlier txs in the same block.
79
+ { forkId: this.forkId, blockNumber: WorldStateRevision.LATEST, includeUncommitted: true },
72
80
  this.config,
73
81
  txHint,
74
82
  this.globalVariables,
75
- protocolContracts,
83
+ this.protocolContracts,
76
84
  );
77
85
 
78
- // Create contract provider for callbacks to TypeScript PublicContractsDB from C++
79
- const contractProvider = new ContractProviderForCpp(this.contractsDB, this.globalVariables, this.bindings);
80
-
81
- // Serialize to msgpack and call the C++ simulator
82
86
  this.log.trace(`Serializing fast simulation inputs to msgpack...`);
83
87
  const inputBuffer = fastSimInputs.serializeWithMessagePack();
84
88
 
85
- // Create cancellation token for this simulation
86
- this.cancellationToken = createCancellationToken();
87
-
88
- // Store the promise so cancel() can wait for it
89
- this.log.debug(`Calling C++ simulator for tx ${txHash}`);
90
- this.simulationPromise = avmSimulate(
91
- inputBuffer,
92
- contractProvider,
93
- wsdbIpcPath,
94
- this.log.level,
95
- undefined,
96
- this.cancellationToken,
97
- );
98
-
99
- let resultBuffer: Buffer;
89
+ this.log.debug(`Running AVM simulation for tx ${txHash}`);
90
+ const context: AvmContractsDBContext = {
91
+ contractsDB: this.contractsDB,
92
+ forkId: this.forkId,
93
+ timestamp: this.globalVariables.timestamp,
94
+ };
95
+ let resultBuffer: Uint8Array;
100
96
  try {
101
- resultBuffer = await this.simulationPromise;
97
+ resultBuffer = await this.avmSimulator.simulate(inputBuffer, context, signal);
102
98
  } catch (error: any) {
103
- // Check if this was a cancellation
104
- if (error.message?.includes('Simulation cancelled')) {
105
- throw new SimulationError(`C++ simulation cancelled`, []);
99
+ if (error.message?.includes('cancelled')) {
100
+ throw new SimulationError(`AVM simulation cancelled`, []);
106
101
  }
107
- throw new SimulationError(`C++ simulation failed: ${error.message}`, []);
108
- } finally {
109
- this.cancellationToken = undefined;
110
- this.simulationPromise = undefined;
102
+ throw new SimulationError(`AVM simulation failed: ${error.message}`, []);
111
103
  }
112
104
 
113
- // If we've reached this point, C++ succeeded during simulation,
105
+ this.log.trace(`Deserializing simulation result from buffer (size: ${resultBuffer.length})...`);
106
+ const resultJSON: object = deserializeFromMessagePack(Buffer.from(resultBuffer));
107
+ const result = PublicTxResult.fromPlainObject(resultJSON);
114
108
 
115
- // Deserialize the msgpack result
116
- this.log.trace(`Deserializing C++ from buffer (size: ${resultBuffer.length})...`);
117
- const cppResultJSON: object = deserializeFromMessagePack(resultBuffer);
118
- this.log.trace(`Deserializing C++ result to PublicTxResult...`);
119
- const cppResult = PublicTxResult.fromPlainObject(cppResultJSON);
120
-
121
- this.log.trace(`C++ simulation completed for tx ${txHash}`, {
109
+ this.log.trace(`AVM simulation completed for tx ${txHash}`, {
122
110
  txHash,
123
- reverted: !cppResult.revertCode.isOK(),
124
- cppGasUsed: cppResult.gasUsed.totalGas.l2Gas,
111
+ reverted: !result.revertCode.isOK(),
112
+ l2GasUsed: result.gasUsed.totalGas.l2Gas,
125
113
  });
126
114
 
127
- return cppResult;
115
+ return result;
128
116
  }
129
117
 
130
118
  /**
131
119
  * Cancel the current simulation if one is in progress.
132
- * This signals the C++ simulator to stop at the next opcode or before the next WorldState write.
133
- * Safe to call even if no simulation is in progress.
120
+ * This signals the underlying simulator to stop at the next safe point (between opcodes, before a
121
+ * world-state write). Safe to call even if no simulation is in progress.
134
122
  *
135
123
  * @param waitTimeoutMs - If provided, wait up to this many ms for the simulation to actually stop.
136
- * This is important because C++ might be in the middle of a slow operation
137
- * (e.g., pad_trees) and won't check the cancellation flag until it completes.
124
+ * Cancellation is cooperative: the simulator may be mid slow-operation and
125
+ * won't observe the cancellation until it completes.
138
126
  * Default timeout of 100ms after cancellation.
139
127
  */
140
128
  public async cancel(waitTimeoutMs: number = 100): Promise<void> {
141
- if (this.cancellationToken) {
142
- this.log.debug('Cancelling C++ simulation');
143
- cancelSimulation(this.cancellationToken);
129
+ if (this.abortController) {
130
+ this.log.debug('Cancelling AVM simulation');
131
+ this.abortController.abort();
144
132
  }
145
133
 
146
- // Wait for the simulation to actually complete if not already done
147
134
  if (this.simulationPromise) {
148
- this.log.debug(`Waiting up to ${waitTimeoutMs}ms for C++ simulation to stop`);
135
+ this.log.debug(`Waiting up to ${waitTimeoutMs}ms for AVM simulation to stop`);
149
136
  await Promise.race([
150
137
  this.simulationPromise.catch(() => {}), // Ignore rejection, just wait for completion
151
138
  sleep(waitTimeoutMs),
152
139
  ]);
153
- this.log.debug('C++ simulation stopped or wait timed out');
140
+ this.log.debug('AVM simulation stopped or wait timed out');
154
141
  }
155
142
  }
156
143
  }
157
144
 
158
145
  export class MeasuredPublicTxSimulator extends PublicTxSimulator implements MeasuredPublicTxSimulatorInterface {
159
146
  constructor(
160
- merkleTree: MerkleTreeWriteOperations,
161
- contractsDB: PublicContractsDB,
147
+ avmSimulator: AvmSimulator,
162
148
  globalVariables: GlobalVariables,
149
+ contractsDB: PublicContractsDB,
150
+ forkId: number,
163
151
  protected readonly metrics: ExecutorMetricsInterface,
164
152
  config?: Partial<PublicSimulatorConfig>,
165
153
  bindings?: LoggerBindings,
166
154
  ) {
167
- super(merkleTree, contractsDB, globalVariables, config, bindings);
155
+ super(avmSimulator, globalVariables, contractsDB, forkId, config, bindings);
168
156
  }
169
157
 
170
158
  public override async simulate(tx: Tx, txLabel: string = 'unlabeledTx'): Promise<PublicTxResult> {
@@ -180,22 +168,23 @@ export class MeasuredPublicTxSimulator extends PublicTxSimulator implements Meas
180
168
  }
181
169
 
182
170
  /**
183
- * A C++ public tx simulator that tracks runtime/production metrics with telemetry.
171
+ * A public tx simulator that tracks runtime/production metrics with telemetry.
184
172
  */
185
173
  export class TelemetryPublicTxSimulator extends MeasuredPublicTxSimulator {
186
174
  /* tracer needed by trackSpans */
187
175
  public readonly tracer: Tracer;
188
176
 
189
177
  constructor(
190
- merkleTree: MerkleTreeWriteOperations,
191
- contractsDB: PublicContractsDB,
178
+ avmSimulator: AvmSimulator,
192
179
  globalVariables: GlobalVariables,
180
+ contractsDB: PublicContractsDB,
181
+ forkId: number,
193
182
  telemetryClient: TelemetryClient = getTelemetryClient(),
194
183
  config?: Partial<PublicSimulatorConfig>,
195
184
  bindings?: LoggerBindings,
196
185
  ) {
197
186
  const metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator');
198
- super(merkleTree, contractsDB, globalVariables, metrics, config, bindings);
187
+ super(avmSimulator, globalVariables, contractsDB, forkId, metrics, config, bindings);
199
188
  this.tracer = metrics.tracer;
200
189
  }
201
190
  }
@@ -1,15 +1,16 @@
1
1
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
2
2
  import { ProtocolContractsList } from '@aztec/protocol-contracts';
3
3
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
4
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
5
4
  import type { GlobalVariables, ProtocolContracts, Tx } from '@aztec/stdlib/tx';
6
5
 
6
+ import type { AvmSimulator } from '../avm_simulator.js';
7
7
  import type { PublicContractsDB } from '../public_db_sources.js';
8
8
 
9
9
  /**
10
- * Shared base for public tx simulators. Holds the common configuration, world-state and contract DB
11
- * handles, logger, and the tx-hash helper. Concrete simulators (e.g. the C++ simulator) extend this
12
- * and implement `simulate`.
10
+ * Shared base for public tx simulators: holds the common configuration, the {@link AvmSimulator} used
11
+ * to run the transaction's public calls, the contracts DB and fork id that scope the simulation's
12
+ * contract-data lookups, the logger, and the tx-hash helper. Concrete simulators extend this and
13
+ * implement `simulate`.
13
14
  */
14
15
  export abstract class PublicTxSimulatorBase {
15
16
  protected log: Logger;
@@ -17,9 +18,10 @@ export abstract class PublicTxSimulatorBase {
17
18
  protected readonly bindings?: LoggerBindings;
18
19
 
19
20
  constructor(
20
- protected merkleTree: MerkleTreeWriteOperations,
21
- protected contractsDB: PublicContractsDB,
21
+ protected avmSimulator: AvmSimulator,
22
22
  protected globalVariables: GlobalVariables,
23
+ protected contractsDB: PublicContractsDB,
24
+ protected forkId: number,
23
25
  config?: Partial<PublicSimulatorConfig>,
24
26
  protected protocolContracts: ProtocolContracts = ProtocolContractsList,
25
27
  bindings?: LoggerBindings,
@@ -5,14 +5,14 @@ export interface PublicTxSimulatorInterface {
5
5
  simulate(tx: Tx): Promise<PublicTxResult>;
6
6
  /**
7
7
  * Cancel the current simulation if one is in progress.
8
- * This signals the underlying simulator (e.g., C++) to stop at the next safe point.
8
+ * This signals the underlying simulator to stop at the next safe point.
9
9
  * Safe to call even if no simulation is in progress.
10
10
  * Optional - not all implementations support cancellation.
11
11
  *
12
12
  * @param waitTimeoutMs - If provided, wait up to this many ms for the simulation to actually stop.
13
- * This is important because signaling cancellation doesn't immediately stop C++ -
14
- * it only sets a flag that C++ checks at certain points. If C++ is in the middle
15
- * of a slow operation (e.g., pad_trees), it won't stop until that completes.
13
+ * Cancellation is cooperative: signaling it only sets a flag the simulator
14
+ * checks at certain points, so if it's mid slow-operation it won't stop until
15
+ * that completes.
16
16
  * @returns Promise that resolves when cancellation is signaled (and optionally when simulation stops)
17
17
  */
18
18
  cancel?(waitTimeoutMs?: number): Promise<void>;
@@ -22,7 +22,7 @@ export interface MeasuredPublicTxSimulatorInterface {
22
22
  simulate(tx: Tx, txLabel: string): Promise<PublicTxResult>;
23
23
  /**
24
24
  * Cancel the current simulation if one is in progress.
25
- * This signals the underlying simulator (e.g., C++) to stop at the next safe point.
25
+ * This signals the underlying simulator to stop at the next safe point.
26
26
  * Safe to call even if no simulation is in progress.
27
27
  * Optional - not all implementations support cancellation.
28
28
  *
@@ -1,19 +0,0 @@
1
- import { type LoggerBindings } from '@aztec/foundation/log';
2
- import type { ContractProvider } from '@aztec/native';
3
- import type { GlobalVariables } from '@aztec/stdlib/tx';
4
- import type { PublicContractsDB } from '../public_db_sources.js';
5
- export declare class ContractProviderForCpp implements ContractProvider {
6
- private contractsDB;
7
- private globalVariables;
8
- private log;
9
- constructor(contractsDB: PublicContractsDB, globalVariables: GlobalVariables, bindings?: LoggerBindings);
10
- getContractInstance: (address: string) => Promise<Buffer<ArrayBufferLike> | undefined>;
11
- getContractClass: (classId: string) => Promise<Buffer<ArrayBufferLike> | undefined>;
12
- addContracts: (contractDeploymentDataBuffer: Buffer<ArrayBufferLike>) => Promise<void>;
13
- getBytecodeCommitment: (classId: string) => Promise<Buffer<ArrayBufferLike> | undefined>;
14
- getDebugFunctionName: (address: string, selector: string) => Promise<string | undefined>;
15
- createCheckpoint: () => Promise<void>;
16
- commitCheckpoint: () => Promise<void>;
17
- revertCheckpoint: () => Promise<void>;
18
- }
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfcHJvdmlkZXJfZm9yX2NwcC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3B1YmxpYy9wdWJsaWNfdHhfc2ltdWxhdG9yL2NvbnRyYWN0X3Byb3ZpZGVyX2Zvcl9jcHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ3ZGLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBS3RELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFakUscUJBQWEsc0JBQXVCLFlBQVcsZ0JBQWdCO0lBSTNELE9BQU8sQ0FBQyxXQUFXO0lBQ25CLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLE9BQU8sQ0FBQyxHQUFHLENBQVM7SUFFcEIsWUFDVSxXQUFXLEVBQUUsaUJBQWlCLEVBQzlCLGVBQWUsRUFBRSxlQUFlLEVBQ3hDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFHMUI7SUFFTSxtQkFBbUIsb0VBYXhCO0lBRUssZ0JBQWdCLG9FQWVyQjtJQUdLLFlBQVksMkVBV2pCO0lBRUsscUJBQXFCLG9FQWdCMUI7SUFFSyxvQkFBb0IscUVBc0J6QjtJQUVLLGdCQUFnQixzQkFHckI7SUFFSyxnQkFBZ0Isc0JBR3JCO0lBRUssZ0JBQWdCLHNCQUdyQjtDQUNIIn0=
@@ -1 +0,0 @@
1
- {"version":3,"file":"contract_provider_for_cpp.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/contract_provider_for_cpp.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,qBAAa,sBAAuB,YAAW,gBAAgB;IAI3D,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IAJzB,OAAO,CAAC,GAAG,CAAS;IAEpB,YACU,WAAW,EAAE,iBAAiB,EAC9B,eAAe,EAAE,eAAe,EACxC,QAAQ,CAAC,EAAE,cAAc,EAG1B;IAEM,mBAAmB,oEAaxB;IAEK,gBAAgB,oEAerB;IAGK,YAAY,2EAWjB;IAEK,qBAAqB,oEAgB1B;IAEK,oBAAoB,qEAsBzB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;IAEK,gBAAgB,sBAGrB;CACH"}