@aztec/simulator 0.82.2-alpha-testnet.4 → 0.82.3

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 (102) hide show
  1. package/README.md +6 -0
  2. package/dest/private/acvm/oracle/oracle.d.ts +1 -1
  3. package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
  4. package/dest/private/acvm/oracle/oracle.js +1 -3
  5. package/dest/public/avm/avm_contract_call_result.d.ts +4 -2
  6. package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
  7. package/dest/public/avm/avm_contract_call_result.js +9 -5
  8. package/dest/public/avm/avm_machine_state.d.ts +2 -0
  9. package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
  10. package/dest/public/avm/avm_machine_state.js +2 -0
  11. package/dest/public/avm/avm_simulator.d.ts.map +1 -1
  12. package/dest/public/avm/avm_simulator.js +5 -6
  13. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
  14. package/dest/public/avm/fixtures/avm_simulation_tester.js +1 -2
  15. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +1 -2
  16. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
  17. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +0 -5
  18. package/dest/public/avm/fixtures/index.d.ts +1 -0
  19. package/dest/public/avm/fixtures/index.d.ts.map +1 -1
  20. package/dest/public/avm/fixtures/index.js +1 -1
  21. package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +3 -2
  22. package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -1
  23. package/dest/public/avm/fixtures/simple_contract_data_source.js +30 -6
  24. package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
  25. package/dest/public/avm/opcodes/external_calls.js +2 -0
  26. package/dest/public/avm/opcodes/memory.d.ts.map +1 -1
  27. package/dest/public/avm/opcodes/memory.js +8 -10
  28. package/dest/public/avm/serialization/instruction_serialization.d.ts +5 -2
  29. package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
  30. package/dest/public/avm/serialization/instruction_serialization.js +23 -3
  31. package/dest/public/executor_metrics.d.ts +11 -3
  32. package/dest/public/executor_metrics.d.ts.map +1 -1
  33. package/dest/public/executor_metrics.js +40 -6
  34. package/dest/public/executor_metrics_interface.d.ts +10 -0
  35. package/dest/public/executor_metrics_interface.d.ts.map +1 -0
  36. package/dest/public/executor_metrics_interface.js +1 -0
  37. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +12 -6
  38. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  39. package/dest/public/fixtures/public_tx_simulation_tester.js +39 -19
  40. package/dest/public/hinting_db_sources.d.ts +26 -3
  41. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  42. package/dest/public/hinting_db_sources.js +102 -1
  43. package/dest/public/index.d.ts +1 -1
  44. package/dest/public/index.d.ts.map +1 -1
  45. package/dest/public/index.js +1 -1
  46. package/dest/public/public_db_sources.d.ts +2 -3
  47. package/dest/public/public_db_sources.d.ts.map +1 -1
  48. package/dest/public/public_db_sources.js +26 -16
  49. package/dest/public/public_processor/public_processor.d.ts +1 -1
  50. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  51. package/dest/public/public_processor/public_processor.js +3 -3
  52. package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts +9 -0
  53. package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts.map +1 -0
  54. package/dest/public/public_tx_simulator/apps_tests/amm_test.js +237 -0
  55. package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts +7 -0
  56. package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts.map +1 -0
  57. package/dest/public/public_tx_simulator/apps_tests/token_test.js +109 -0
  58. package/dest/public/public_tx_simulator/index.d.ts +3 -0
  59. package/dest/public/public_tx_simulator/index.d.ts.map +1 -0
  60. package/dest/public/public_tx_simulator/index.js +2 -0
  61. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +23 -0
  62. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -0
  63. package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +58 -0
  64. package/dest/public/public_tx_simulator/public_tx_context.d.ts +2 -2
  65. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  66. package/dest/public/public_tx_simulator/public_tx_context.js +9 -7
  67. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +16 -16
  68. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  69. package/dest/public/public_tx_simulator/public_tx_simulator.js +24 -64
  70. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +19 -0
  71. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -0
  72. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +39 -0
  73. package/dest/public/test_executor_metrics.d.ts +43 -0
  74. package/dest/public/test_executor_metrics.d.ts.map +1 -0
  75. package/dest/public/test_executor_metrics.js +158 -0
  76. package/package.json +14 -14
  77. package/src/private/acvm/oracle/oracle.ts +2 -2
  78. package/src/public/avm/avm_contract_call_result.ts +15 -3
  79. package/src/public/avm/avm_machine_state.ts +5 -0
  80. package/src/public/avm/avm_simulator.ts +18 -7
  81. package/src/public/avm/fixtures/avm_simulation_tester.ts +1 -1
  82. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -7
  83. package/src/public/avm/fixtures/index.ts +1 -1
  84. package/src/public/avm/fixtures/simple_contract_data_source.ts +33 -6
  85. package/src/public/avm/opcodes/external_calls.ts +3 -0
  86. package/src/public/avm/opcodes/memory.ts +8 -10
  87. package/src/public/avm/serialization/instruction_serialization.ts +22 -5
  88. package/src/public/executor_metrics.ts +54 -6
  89. package/src/public/executor_metrics_interface.ts +15 -0
  90. package/src/public/fixtures/public_tx_simulation_tester.ts +74 -18
  91. package/src/public/hinting_db_sources.ts +184 -3
  92. package/src/public/index.ts +1 -1
  93. package/src/public/public_db_sources.ts +36 -23
  94. package/src/public/public_processor/public_processor.ts +4 -4
  95. package/src/public/public_tx_simulator/apps_tests/amm_test.ts +316 -0
  96. package/src/public/public_tx_simulator/apps_tests/token_test.ts +138 -0
  97. package/src/public/public_tx_simulator/index.ts +2 -0
  98. package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +111 -0
  99. package/src/public/public_tx_simulator/public_tx_context.ts +9 -13
  100. package/src/public/public_tx_simulator/public_tx_simulator.ts +31 -76
  101. package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +62 -0
  102. package/src/public/test_executor_metrics.ts +222 -0
@@ -9,17 +9,19 @@ import { GlobalVariables, PublicCallRequestWithCalldata, type Tx } from '@aztec/
9
9
  import { NativeWorldStateService } from '@aztec/world-state';
10
10
 
11
11
  import { BaseAvmSimulationTester } from '../avm/fixtures/base_avm_simulation_tester.js';
12
- import { getContractFunctionAbi, getFunctionSelector } from '../avm/fixtures/index.js';
12
+ import { DEFAULT_BLOCK_NUMBER, getContractFunctionAbi, getFunctionSelector } from '../avm/fixtures/index.js';
13
13
  import { SimpleContractDataSource } from '../avm/fixtures/simple_contract_data_source.js';
14
14
  import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
15
- import { type PublicTxResult, PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js';
15
+ import { MeasuredPublicTxSimulator } from '../public_tx_simulator/measured_public_tx_simulator.js';
16
+ import type { PublicTxResult } from '../public_tx_simulator/public_tx_simulator.js';
17
+ import { TestExecutorMetrics } from '../test_executor_metrics.js';
16
18
  import { createTxForPublicCalls } from './utils.js';
17
19
 
18
20
  const TIMESTAMP = new Fr(99833);
19
21
  const DEFAULT_GAS_FEES = new GasFees(2, 3);
20
- export const DEFAULT_BLOCK_NUMBER = 42;
21
22
 
22
23
  export type TestEnqueuedCall = {
24
+ sender?: AztecAddress;
23
25
  address: AztecAddress;
24
26
  fnName: string;
25
27
  args: any[];
@@ -34,15 +36,41 @@ export type TestEnqueuedCall = {
34
36
  */
35
37
  export class PublicTxSimulationTester extends BaseAvmSimulationTester {
36
38
  private txCount = 0;
37
-
38
- constructor(private merkleTree: MerkleTreeWriteOperations, contractDataSource: SimpleContractDataSource) {
39
+ private simulator: MeasuredPublicTxSimulator;
40
+ private metricsPrefix?: string;
41
+
42
+ constructor(
43
+ merkleTree: MerkleTreeWriteOperations,
44
+ contractDataSource: SimpleContractDataSource,
45
+ globals: GlobalVariables = defaultGlobals(),
46
+ private metrics: TestExecutorMetrics = new TestExecutorMetrics(),
47
+ ) {
39
48
  super(contractDataSource, merkleTree);
49
+
50
+ const treesDB = new PublicTreesDB(merkleTree);
51
+ const contractsDB = new PublicContractsDB(contractDataSource);
52
+
53
+ this.simulator = new MeasuredPublicTxSimulator(
54
+ treesDB,
55
+ contractsDB,
56
+ globals,
57
+ /*doMerkleOperations=*/ true,
58
+ /*skipFeeEnforcement=*/ false,
59
+ this.metrics,
60
+ );
40
61
  }
41
62
 
42
- public static async create(): Promise<PublicTxSimulationTester> {
63
+ public static async create(
64
+ globals: GlobalVariables = defaultGlobals(),
65
+ metrics: TestExecutorMetrics = new TestExecutorMetrics(),
66
+ ): Promise<PublicTxSimulationTester> {
43
67
  const contractDataSource = new SimpleContractDataSource();
44
68
  const merkleTree = await (await NativeWorldStateService.tmp()).fork();
45
- return new PublicTxSimulationTester(merkleTree, contractDataSource);
69
+ return new PublicTxSimulationTester(merkleTree, contractDataSource, globals, metrics);
70
+ }
71
+
72
+ public setMetricsPrefix(prefix: string) {
73
+ this.metricsPrefix = prefix;
46
74
  }
47
75
 
48
76
  public async createTx(
@@ -54,10 +82,14 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
54
82
  /* need some unique first nullifier for note-nonce computations */
55
83
  firstNullifier = new Fr(420000 + this.txCount++),
56
84
  ): Promise<Tx> {
57
- const setupCallRequests = await asyncMap(setupCalls, call => this.#createPubicCallRequestForCall(call, sender));
58
- const appCallRequests = await asyncMap(appCalls, call => this.#createPubicCallRequestForCall(call, sender));
85
+ const setupCallRequests = await asyncMap(setupCalls, call =>
86
+ this.#createPubicCallRequestForCall(call, call.sender ?? sender),
87
+ );
88
+ const appCallRequests = await asyncMap(appCalls, call =>
89
+ this.#createPubicCallRequestForCall(call, call.sender ?? sender),
90
+ );
59
91
  const teardownCallRequest = teardownCall
60
- ? await this.#createPubicCallRequestForCall(teardownCall, sender)
92
+ ? await this.#createPubicCallRequestForCall(teardownCall, teardownCall.sender ?? sender)
61
93
  : undefined;
62
94
 
63
95
  return createTxForPublicCalls(firstNullifier, setupCallRequests, appCallRequests, teardownCallRequest, feePayer);
@@ -71,24 +103,48 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
71
103
  feePayer: AztecAddress = sender,
72
104
  /* need some unique first nullifier for note-nonce computations */
73
105
  firstNullifier = new Fr(420000 + this.txCount++),
74
- globals = defaultGlobals(),
106
+ txLabel: string = 'unlabeledTx',
75
107
  ): Promise<PublicTxResult> {
76
108
  const tx = await this.createTx(sender, setupCalls, appCalls, teardownCall, feePayer, firstNullifier);
77
109
 
78
110
  await this.setFeePayerBalance(feePayer);
79
111
 
80
- const treesDB = new PublicTreesDB(this.merkleTree);
81
- const contractsDB = new PublicContractsDB(this.contractDataSource);
82
- const simulator = new PublicTxSimulator(treesDB, contractsDB, globals, /*doMerkleOperations=*/ true);
112
+ const txLabelWithCount = `${txLabel}.${this.txCount - 1}`;
113
+ const fullTxLabel = this.metricsPrefix ? `${this.metricsPrefix}.${txLabelWithCount}` : txLabelWithCount;
83
114
 
84
- const startTime = performance.now();
85
- const avmResult = await simulator.simulate(tx);
86
- const endTime = performance.now();
87
- this.logger.debug(`Public transaction simulation took ${endTime - startTime}ms`);
115
+ const avmResult = await this.simulator.simulate(tx, fullTxLabel);
116
+
117
+ // Something like this is often useful for debugging:
118
+ //if (avmResult.revertReason) {
119
+ // // resolve / enrich revert reason
120
+ // const lastAppCall = appCalls[appCalls.length - 1];
121
+
122
+ // const contractArtifact =
123
+ // lastAppCall.contractArtifact || (await this.contractDataSource.getContractArtifact(lastAppCall.address));
124
+ // const fnAbi = getContractFunctionAbi(lastAppCall.fnName, contractArtifact!);
125
+ // const revertReason = resolveAssertionMessageFromRevertData(avmResult.revertReason.revertData, fnAbi!);
126
+ // this.logger.debug(`Revert reason: ${revertReason}`);
127
+ //}
88
128
 
89
129
  return avmResult;
90
130
  }
91
131
 
132
+ public async simulateTxWithLabel(
133
+ txLabel: string,
134
+ sender: AztecAddress,
135
+ setupCalls?: TestEnqueuedCall[],
136
+ appCalls?: TestEnqueuedCall[],
137
+ teardownCall?: TestEnqueuedCall,
138
+ feePayer?: AztecAddress,
139
+ firstNullifier?: Fr,
140
+ ): Promise<PublicTxResult> {
141
+ return await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer, firstNullifier, txLabel);
142
+ }
143
+
144
+ public prettyPrintMetrics() {
145
+ this.metrics.prettyPrint();
146
+ }
147
+
92
148
  async #createPubicCallRequestForCall(
93
149
  call: TestEnqueuedCall,
94
150
  sender: AztecAddress,
@@ -1,21 +1,41 @@
1
- import type { Fr } from '@aztec/foundation/fields';
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import type { IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
2
4
  import type { FunctionSelector } from '@aztec/stdlib/abi';
3
5
  import {
4
6
  AvmBytecodeCommitmentHint,
5
7
  AvmContractClassHint,
6
8
  AvmContractInstanceHint,
7
9
  type AvmExecutionHints,
10
+ AvmGetLeafPreimageHintNullifierTree,
11
+ AvmGetLeafPreimageHintPublicDataTree,
12
+ AvmGetLeafValueHint,
13
+ AvmGetPreviousValueIndexHint,
14
+ AvmGetSiblingPathHint,
8
15
  } from '@aztec/stdlib/avm';
9
16
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
17
  import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
18
+ import {
19
+ AppendOnlyTreeSnapshot,
20
+ type IndexedTreeId,
21
+ MerkleTreeId,
22
+ type MerkleTreeLeafType,
23
+ NullifierLeaf,
24
+ PublicDataTreeLeaf,
25
+ type SequentialInsertionResult,
26
+ getTreeName,
27
+ } from '@aztec/stdlib/trees';
28
+
29
+ import { strict as assert } from 'assert';
11
30
 
12
- import type { PublicContractsDBInterface } from '../server.js';
31
+ import type { PublicContractsDBInterface } from '../common/db_interfaces.js';
32
+ import { PublicTreesDB } from './public_db_sources.js';
13
33
 
14
34
  /**
15
35
  * A public contracts database that forwards requests and collects AVM hints.
16
36
  */
17
37
  export class HintingPublicContractsDB implements PublicContractsDBInterface {
18
- constructor(private readonly db: PublicContractsDBInterface, public readonly hints: AvmExecutionHints) {}
38
+ constructor(private readonly db: PublicContractsDBInterface, private hints: AvmExecutionHints) {}
19
39
 
20
40
  public async getContractInstance(
21
41
  address: AztecAddress,
@@ -69,3 +89,164 @@ export class HintingPublicContractsDB implements PublicContractsDBInterface {
69
89
  return await this.db.getDebugFunctionName(contractAddress, selector);
70
90
  }
71
91
  }
92
+
93
+ /**
94
+ * A public trees database that forwards requests and collects AVM hints.
95
+ */
96
+ export class HintingPublicTreesDB extends PublicTreesDB {
97
+ private static readonly log: Logger = createLogger('HintingPublicTreesDB');
98
+
99
+ constructor(db: PublicTreesDB, private hints: AvmExecutionHints) {
100
+ super(db);
101
+ }
102
+
103
+ // Getters.
104
+ public override async getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
105
+ const path = await super.getSiblingPath<N>(treeId, index);
106
+ const key = await this.getHintKey(treeId);
107
+ this.hints.getSiblingPathHints.push(new AvmGetSiblingPathHint(key, treeId, index, path.toFields()));
108
+ return Promise.resolve(path);
109
+ }
110
+
111
+ public override async getPreviousValueIndex<ID extends IndexedTreeId>(
112
+ treeId: ID,
113
+ value: bigint,
114
+ ): Promise<
115
+ | {
116
+ index: bigint;
117
+ alreadyPresent: boolean;
118
+ }
119
+ | undefined
120
+ > {
121
+ const result = await super.getPreviousValueIndex(treeId, value);
122
+ if (result === undefined) {
123
+ throw new Error(
124
+ `getPreviousValueIndex(${getTreeName(
125
+ treeId,
126
+ )}, ${value}}) returned undefined. Possible wrong tree setup or corrupted state.`,
127
+ );
128
+ }
129
+ const key = await this.getHintKey(treeId);
130
+ this.hints.getPreviousValueIndexHints.push(
131
+ new AvmGetPreviousValueIndexHint(key, treeId, new Fr(value), result.index, result.alreadyPresent),
132
+ );
133
+ return result;
134
+ }
135
+
136
+ public override async getLeafPreimage<ID extends IndexedTreeId>(
137
+ treeId: ID,
138
+ index: bigint,
139
+ ): Promise<IndexedTreeLeafPreimage | undefined> {
140
+ const preimage = await super.getLeafPreimage<ID>(treeId, index);
141
+ if (preimage) {
142
+ const key = await this.getHintKey(treeId);
143
+
144
+ switch (treeId) {
145
+ case MerkleTreeId.PUBLIC_DATA_TREE:
146
+ this.hints.getLeafPreimageHintsPublicDataTree.push(
147
+ new AvmGetLeafPreimageHintPublicDataTree(
148
+ key,
149
+ index,
150
+ preimage.asLeaf() as PublicDataTreeLeaf,
151
+ preimage.getNextIndex(),
152
+ new Fr(preimage.getNextKey()),
153
+ ),
154
+ );
155
+ break;
156
+ case MerkleTreeId.NULLIFIER_TREE:
157
+ this.hints.getLeafPreimageHintsNullifierTree.push(
158
+ new AvmGetLeafPreimageHintNullifierTree(
159
+ key,
160
+ index,
161
+ preimage.asLeaf() as NullifierLeaf,
162
+ preimage.getNextIndex(),
163
+ new Fr(preimage.getNextKey()),
164
+ ),
165
+ );
166
+ break;
167
+ default:
168
+ // Use getLeafValue for the other trees.
169
+ throw new Error('getLeafPreimage only supported for PublicDataTree and NullifierTree!');
170
+ break;
171
+ }
172
+ }
173
+
174
+ return preimage;
175
+ }
176
+
177
+ public override async getLeafValue<ID extends MerkleTreeId>(
178
+ treeId: ID,
179
+ index: bigint,
180
+ ): Promise<MerkleTreeLeafType<typeof treeId> | undefined> {
181
+ // Use getLeafPreimage for PublicDataTree and NullifierTree.
182
+ assert(treeId == MerkleTreeId.NOTE_HASH_TREE || treeId == MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
183
+
184
+ const value = await super.getLeafValue<ID>(treeId, index);
185
+ if (value) {
186
+ const key = await this.getHintKey(treeId);
187
+ // We can cast to Fr because we know the type of the tree.
188
+ this.hints.getLeafValueHints.push(new AvmGetLeafValueHint(key, treeId, index, value as Fr));
189
+ }
190
+
191
+ return value;
192
+ }
193
+
194
+ // State modification.
195
+ public override async sequentialInsert<TreeHeight extends number, ID extends IndexedTreeId>(
196
+ treeId: ID,
197
+ leaves: Buffer[],
198
+ ): Promise<SequentialInsertionResult<TreeHeight>> {
199
+ HintingPublicTreesDB.log.debug('sequentialInsert not hinted yet!');
200
+ const beforeState = await this.getHintKey(treeId);
201
+
202
+ const result = await super.sequentialInsert<TreeHeight, ID>(treeId, leaves);
203
+
204
+ const afterState = await this.getHintKey(treeId);
205
+ HintingPublicTreesDB.log.debug(
206
+ `Evolved tree state (${getTreeName(treeId)}): ${beforeState.root}, ${beforeState.nextAvailableLeafIndex} -> ${
207
+ afterState.root
208
+ }, ${afterState.nextAvailableLeafIndex}.`,
209
+ );
210
+
211
+ return result;
212
+ }
213
+
214
+ public override async revertCheckpoint(): Promise<void> {
215
+ HintingPublicTreesDB.log.debug('revertCheckpoint not hinted yet!');
216
+ // TODO(fcarreiro): we probably want to hint on StateReference hash.
217
+ // WARNING: is this enough? we might actually need the number of the checkpoint or similar...
218
+ // We will need to keep a stack of checkpoints on the C++ side.
219
+ const beforeState = {
220
+ [MerkleTreeId.PUBLIC_DATA_TREE]: await this.getHintKey(MerkleTreeId.PUBLIC_DATA_TREE),
221
+ [MerkleTreeId.NULLIFIER_TREE]: await this.getHintKey(MerkleTreeId.NULLIFIER_TREE),
222
+ [MerkleTreeId.NOTE_HASH_TREE]: await this.getHintKey(MerkleTreeId.NOTE_HASH_TREE),
223
+ [MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: await this.getHintKey(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
224
+ [MerkleTreeId.ARCHIVE]: await this.getHintKey(MerkleTreeId.ARCHIVE),
225
+ };
226
+
227
+ await super.revertCheckpoint();
228
+
229
+ const afterState = {
230
+ [MerkleTreeId.PUBLIC_DATA_TREE]: await this.getHintKey(MerkleTreeId.PUBLIC_DATA_TREE),
231
+ [MerkleTreeId.NULLIFIER_TREE]: await this.getHintKey(MerkleTreeId.NULLIFIER_TREE),
232
+ [MerkleTreeId.NOTE_HASH_TREE]: await this.getHintKey(MerkleTreeId.NOTE_HASH_TREE),
233
+ [MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: await this.getHintKey(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
234
+ [MerkleTreeId.ARCHIVE]: await this.getHintKey(MerkleTreeId.ARCHIVE),
235
+ };
236
+
237
+ HintingPublicTreesDB.log.debug('Evolved tree state:');
238
+ for (const treeId of Object.keys(beforeState)) {
239
+ const id: MerkleTreeId = treeId as unknown as MerkleTreeId;
240
+ const treeName = getTreeName(id);
241
+ HintingPublicTreesDB.log.debug(
242
+ `${treeName}: ${beforeState[id].root}, ${beforeState[id].nextAvailableLeafIndex} -> ${afterState[id].root}, ${afterState[id].nextAvailableLeafIndex}.`,
243
+ );
244
+ }
245
+ }
246
+
247
+ // Private methods.
248
+ private async getHintKey(treeId: MerkleTreeId): Promise<AppendOnlyTreeSnapshot> {
249
+ const treeInfo = await super.getTreeInfo(treeId);
250
+ return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
251
+ }
252
+ }
@@ -1,5 +1,5 @@
1
1
  export * from '../common/db_interfaces.js';
2
- export * from './public_tx_simulator/public_tx_simulator.js';
2
+ export * from './public_tx_simulator/index.js';
3
3
  export * from './public_db_sources.js';
4
4
  export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js';
5
5
  export { SideEffectTrace } from './side_effect_trace.js';
@@ -18,7 +18,6 @@ import type {
18
18
  BatchInsertionResult,
19
19
  IndexedTreeId,
20
20
  MerkleTreeLeafType,
21
- MerkleTreeReadOperations,
22
21
  MerkleTreeWriteOperations,
23
22
  SequentialInsertionResult,
24
23
  TreeInfo,
@@ -393,7 +392,7 @@ class ForwardMerkleTree implements MerkleTreeWriteOperations {
393
392
  export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInterface {
394
393
  private logger = createLogger('simulator:public-trees-db');
395
394
 
396
- constructor(public db: MerkleTreeWriteOperations) {
395
+ constructor(private readonly db: MerkleTreeWriteOperations) {
397
396
  super(db);
398
397
  }
399
398
 
@@ -404,7 +403,22 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
404
403
  * @returns The current value in the storage slot.
405
404
  */
406
405
  public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
407
- return await readPublicState(this.db, contract, slot);
406
+ const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
407
+
408
+ const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
409
+ if (!lowLeafResult) {
410
+ throw new Error('Low leaf not found');
411
+ }
412
+
413
+ // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
414
+ await this.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
415
+ // Unconditionally fetching the preimage for the hints. Move it to the hinting layer?
416
+ const preimage = (await this.getLeafPreimage(
417
+ MerkleTreeId.PUBLIC_DATA_TREE,
418
+ lowLeafResult.index,
419
+ )) as PublicDataTreeLeafPreimage;
420
+
421
+ return lowLeafResult.alreadyPresent ? preimage.value : Fr.ZERO;
408
422
  }
409
423
 
410
424
  /**
@@ -417,12 +431,15 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
417
431
  public async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
418
432
  const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
419
433
  const publicDataWrite = new PublicDataWrite(leafSlot, newValue);
420
- await this.db.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [publicDataWrite.toBuffer()]);
434
+ await this.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [publicDataWrite.toBuffer()]);
421
435
  }
422
436
 
423
437
  public async getL1ToL2LeafValue(leafIndex: bigint): Promise<Fr | undefined> {
424
438
  const timer = new Timer();
425
- const leafValue = await this.db.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
439
+ const leafValue = await this.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
440
+ // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
441
+ await this.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
442
+
426
443
  this.logger.debug(`[DB] Fetched L1 to L2 message leaf value`, {
427
444
  eventName: 'public-db-access',
428
445
  duration: timer.ms(),
@@ -433,7 +450,10 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
433
450
 
434
451
  public async getNoteHash(leafIndex: bigint): Promise<Fr | undefined> {
435
452
  const timer = new Timer();
436
- const leafValue = await this.db.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
453
+ const leafValue = await this.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
454
+ // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
455
+ await this.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
456
+
437
457
  this.logger.debug(`[DB] Fetched note hash leaf value`, {
438
458
  eventName: 'public-db-access',
439
459
  duration: timer.ms(),
@@ -444,7 +464,16 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
444
464
 
445
465
  public async getNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
446
466
  const timer = new Timer();
447
- const index = (await this.db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]))[0];
467
+ const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
468
+ if (!lowLeafResult) {
469
+ throw new Error('Low leaf not found');
470
+ }
471
+ // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
472
+ await this.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
473
+ // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
474
+ await this.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
475
+ const index = lowLeafResult.alreadyPresent ? lowLeafResult.index : undefined;
476
+
448
477
  this.logger.debug(`[DB] Fetched nullifier index`, {
449
478
  eventName: 'public-db-access',
450
479
  duration: timer.ms(),
@@ -453,19 +482,3 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
453
482
  return index;
454
483
  }
455
484
  }
456
-
457
- export async function readPublicState(db: MerkleTreeReadOperations, contract: AztecAddress, slot: Fr): Promise<Fr> {
458
- const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
459
-
460
- const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
461
- if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
462
- return Fr.ZERO;
463
- }
464
-
465
- const preimage = (await db.getLeafPreimage(
466
- MerkleTreeId.PUBLIC_DATA_TREE,
467
- lowLeafResult.index,
468
- )) as PublicDataTreeLeafPreimage;
469
-
470
- return preimage.value;
471
- }
@@ -34,7 +34,7 @@ import {
34
34
  import { ForkCheckpoint } from '@aztec/world-state/native';
35
35
 
36
36
  import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
37
- import { PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js';
37
+ import { type PublicTxSimulator, TelemetryPublicTxSimulator } from '../public_tx_simulator/index.js';
38
38
  import { PublicProcessorMetrics } from './public_processor_metrics.js';
39
39
 
40
40
  /**
@@ -87,8 +87,8 @@ export class PublicProcessorFactory {
87
87
  doMerkleOperations: boolean,
88
88
  skipFeeEnforcement: boolean,
89
89
  telemetryClient: TelemetryClient,
90
- ) {
91
- return new PublicTxSimulator(
90
+ ): PublicTxSimulator {
91
+ return new TelemetryPublicTxSimulator(
92
92
  treesDB,
93
93
  contractsDB,
94
94
  globalVariables,
@@ -488,7 +488,7 @@ export class PublicProcessor implements Traceable {
488
488
  if (phase.reverted) {
489
489
  this.metrics.recordRevertedPhase(phase.phase);
490
490
  } else {
491
- this.metrics.recordPhaseDuration(phase.phase, phase.durationMs);
491
+ this.metrics.recordPhaseDuration(phase.phase, phase.durationMs ?? 0);
492
492
  }
493
493
  });
494
494