@aztec/simulator 0.82.2 → 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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "0.82.2",
3
+ "version": "0.82.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/server.js",
@@ -60,16 +60,16 @@
60
60
  ]
61
61
  },
62
62
  "dependencies": {
63
- "@aztec/constants": "0.82.2",
64
- "@aztec/foundation": "0.82.2",
65
- "@aztec/noir-acvm_js": "0.82.2",
66
- "@aztec/noir-noirc_abi": "0.82.2",
67
- "@aztec/noir-protocol-circuits-types": "0.82.2",
68
- "@aztec/noir-types": "0.82.2",
69
- "@aztec/protocol-contracts": "0.82.2",
70
- "@aztec/stdlib": "0.82.2",
71
- "@aztec/telemetry-client": "0.82.2",
72
- "@aztec/world-state": "0.82.2",
63
+ "@aztec/constants": "0.82.3",
64
+ "@aztec/foundation": "0.82.3",
65
+ "@aztec/noir-acvm_js": "0.82.3",
66
+ "@aztec/noir-noirc_abi": "0.82.3",
67
+ "@aztec/noir-protocol-circuits-types": "0.82.3",
68
+ "@aztec/noir-types": "0.82.3",
69
+ "@aztec/protocol-contracts": "0.82.3",
70
+ "@aztec/stdlib": "0.82.3",
71
+ "@aztec/telemetry-client": "0.82.3",
72
+ "@aztec/world-state": "0.82.3",
73
73
  "levelup": "^5.1.1",
74
74
  "lodash.clonedeep": "^4.5.0",
75
75
  "lodash.merge": "^4.6.2",
@@ -77,9 +77,9 @@
77
77
  "tslib": "^2.4.0"
78
78
  },
79
79
  "devDependencies": {
80
- "@aztec/kv-store": "0.82.2",
81
- "@aztec/merkle-tree": "0.82.2",
82
- "@aztec/noir-contracts.js": "0.82.2",
80
+ "@aztec/kv-store": "0.82.3",
81
+ "@aztec/merkle-tree": "0.82.3",
82
+ "@aztec/noir-contracts.js": "0.82.3",
83
83
  "@jest/globals": "^29.5.0",
84
84
  "@types/jest": "^29.5.0",
85
85
  "@types/levelup": "^5.1.3",
@@ -355,12 +355,12 @@ export class Oracle {
355
355
  return Promise.resolve([]);
356
356
  }
357
357
 
358
- async getIndexedTaggingSecretAsSender([sender]: ACVMField[], [recipient]: ACVMField[]): Promise<ACVMField[][]> {
358
+ async getIndexedTaggingSecretAsSender([sender]: ACVMField[], [recipient]: ACVMField[]): Promise<ACVMField[]> {
359
359
  const taggingSecret = await this.typedOracle.getIndexedTaggingSecretAsSender(
360
360
  AztecAddress.fromString(sender),
361
361
  AztecAddress.fromString(recipient),
362
362
  );
363
- return [taggingSecret.toFields().map(toACVMField)];
363
+ return taggingSecret.toFields().map(toACVMField);
364
364
  }
365
365
 
366
366
  async incrementAppTaggingSecretIndexAsSender([sender]: ACVMField[], [recipient]: ACVMField[]): Promise<ACVMField[]> {
@@ -17,10 +17,13 @@ export class AvmContractCallResult {
17
17
  public output: Fr[],
18
18
  public gasLeft: AvmGas,
19
19
  public revertReason?: AvmRevertReason,
20
+ public totalInstructions: number = 0, // including nested calls
20
21
  ) {}
21
22
 
22
23
  toString(): string {
23
- let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(this.gasLeft)}`;
24
+ let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(
25
+ this.gasLeft,
26
+ )}, totalInstructions: ${this.totalInstructions}`;
24
27
  if (this.revertReason) {
25
28
  resultsStr += `, revertReason: ${this.revertReason}`;
26
29
  }
@@ -29,7 +32,13 @@ export class AvmContractCallResult {
29
32
 
30
33
  finalize(): AvmFinalizedCallResult {
31
34
  const revertReason = this.revertReason ? createSimulationError(this.revertReason, this.output) : undefined;
32
- return new AvmFinalizedCallResult(this.reverted, this.output, Gas.from(this.gasLeft), revertReason);
35
+ return new AvmFinalizedCallResult(
36
+ this.reverted,
37
+ this.output,
38
+ Gas.from(this.gasLeft),
39
+ revertReason,
40
+ this.totalInstructions,
41
+ );
33
42
  }
34
43
  }
35
44
 
@@ -43,10 +52,13 @@ export class AvmFinalizedCallResult {
43
52
  public output: Fr[],
44
53
  public gasLeft: Gas,
45
54
  public revertReason?: SimulationError,
55
+ public totalInstructions: number = 0, // including nested calls
46
56
  ) {}
47
57
 
48
58
  toString(): string {
49
- let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(this.gasLeft)}`;
59
+ let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(
60
+ this.gasLeft,
61
+ )}, totalInstructions: ${this.totalInstructions}`;
50
62
  if (this.revertReason) {
51
63
  resultsStr += `, revertReason: ${this.revertReason}`;
52
64
  }
@@ -68,6 +68,11 @@ export class AvmMachineState {
68
68
  /** Output data must NOT be modified once it is set */
69
69
  private output: Fr[] = [];
70
70
 
71
+ // Metrics only - not needed for execution
72
+ /** instruction counter, including nested calls */
73
+ public instrCounter: number = 0;
74
+ // End metrics only
75
+
71
76
  constructor(gasLeft: Gas);
72
77
  constructor(l2GasLeft: number, daGasLeft: number);
73
78
  constructor(gasLeftOrL2GasLeft: Gas | number, daGasLeft?: number) {
@@ -147,7 +147,6 @@ export class AvmSimulator {
147
147
  try {
148
148
  // Execute instruction pointed to by the current program counter
149
149
  // continuing until the machine state signifies a halt
150
- let instrCounter = 0;
151
150
  while (!machineState.getHalted()) {
152
151
  // Get the instruction from cache, or deserialize for the first time
153
152
  let cachedInstruction = this.deserializedInstructionsCache.get(machineState.pc);
@@ -163,13 +162,11 @@ export class AvmSimulator {
163
162
  if (this.log.isLevelEnabled('trace')) {
164
163
  // Skip this entirely to avoid toStringing etc if trace is not enabled
165
164
  this.log.trace(
166
- `[PC:${machineState.pc}] [IC:${instrCounter}] ${instruction.toString()} (gasLeft l2=${
165
+ `[PC:${machineState.pc}] [IC:${machineState.instrCounter}] ${instruction.toString()} (gasLeft l2=${
167
166
  machineState.l2GasLeft
168
167
  } da=${machineState.daGasLeft})`,
169
168
  );
170
169
  }
171
- instrCounter++;
172
-
173
170
  machineState.nextPc = machineState.pc + bytesRead;
174
171
 
175
172
  // Execute the instruction.
@@ -181,6 +178,8 @@ export class AvmSimulator {
181
178
  machineState.pc += bytesRead;
182
179
  }
183
180
 
181
+ machineState.instrCounter++;
182
+
184
183
  // gas used by this instruction - used for profiling/tallying
185
184
  const gasUsed: Gas = {
186
185
  l2Gas: instrStartGas.l2Gas - machineState.l2GasLeft,
@@ -197,13 +196,19 @@ export class AvmSimulator {
197
196
  const output = machineState.getOutput();
198
197
  const reverted = machineState.getReverted();
199
198
  const revertReason = reverted ? await revertReasonFromExplicitRevert(output, this.context) : undefined;
200
- const results = new AvmContractCallResult(reverted, output, machineState.gasLeft, revertReason);
199
+ const results = new AvmContractCallResult(
200
+ reverted,
201
+ output,
202
+ machineState.gasLeft,
203
+ revertReason,
204
+ machineState.instrCounter,
205
+ );
201
206
  this.log.debug(`Context execution results: ${results.toString()}`);
202
207
  const totalGasUsed: Gas = {
203
208
  l2Gas: callStartGas.l2Gas - machineState.l2GasLeft,
204
209
  daGas: callStartGas.daGas - machineState.daGasLeft,
205
210
  };
206
- this.log.debug(`Executed ${instrCounter} instructions and consumed ${totalGasUsed.l2Gas} L2 Gas`);
211
+ this.log.debug(`Executed ${machineState.instrCounter} instructions and consumed ${totalGasUsed.l2Gas} L2 Gas`);
207
212
 
208
213
  this.tallyPrintFunction();
209
214
 
@@ -233,7 +238,13 @@ export class AvmSimulator {
233
238
  // Exceptional halts consume all allocated gas
234
239
  const noGasLeft = { l2Gas: 0, daGas: 0 };
235
240
  // Note: "exceptional halts" cannot return data, hence [].
236
- const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], noGasLeft, revertReason);
241
+ const results = new AvmContractCallResult(
242
+ /*reverted=*/ true,
243
+ /*output=*/ [],
244
+ noGasLeft,
245
+ revertReason,
246
+ machineState.instrCounter,
247
+ );
237
248
  this.log.debug(`Context execution results: ${results.toString()}`);
238
249
 
239
250
  this.tallyPrintFunction();
@@ -9,6 +9,7 @@ import { NativeWorldStateService } from '@aztec/world-state';
9
9
  import { SideEffectTrace } from '../../../public/side_effect_trace.js';
10
10
  import type { AvmContractCallResult } from '../../avm/avm_contract_call_result.js';
11
11
  import {
12
+ DEFAULT_BLOCK_NUMBER,
12
13
  getContractFunctionAbi,
13
14
  getFunctionSelector,
14
15
  initContext,
@@ -16,7 +17,6 @@ import {
16
17
  resolveContractAssertionMessage,
17
18
  } from '../../avm/fixtures/index.js';
18
19
  import { AvmPersistableStateManager } from '../../avm/journal/journal.js';
19
- import { DEFAULT_BLOCK_NUMBER } from '../../fixtures/public_tx_simulation_tester.js';
20
20
  import { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
21
21
  import { AvmSimulator } from '../avm_simulator.js';
22
22
  import { BaseAvmSimulationTester } from './base_avm_simulation_tester.js';
@@ -6,7 +6,7 @@ import { computeFeePayerBalanceStorageSlot, getCanonicalFeeJuice } from '@aztec/
6
6
  import type { ContractArtifact } from '@aztec/stdlib/abi';
7
7
  import { PublicDataWrite } from '@aztec/stdlib/avm';
8
8
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
9
- import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
9
+ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
10
10
  import { computePublicDataTreeLeafSlot, siloNullifier } from '@aztec/stdlib/hash';
11
11
  import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
12
12
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -86,12 +86,6 @@ export abstract class BaseAvmSimulationTester {
86
86
  return feeJuice.instance;
87
87
  }
88
88
 
89
- addContractClass(contractClass: ContractClassPublic, contractArtifact: ContractArtifact): Promise<void> {
90
- this.logger.debug(`Adding contract class with Id ${contractClass.id}`);
91
- this.contractDataSource.addContractArtifact(contractClass.id, contractArtifact);
92
- return this.contractDataSource.addContractClass(contractClass);
93
- }
94
-
95
89
  async addContractInstance(contractInstance: ContractInstanceWithAddress, skipNullifierInsertion = false) {
96
90
  if (!skipNullifierInsertion) {
97
91
  await this.insertContractAddressNullifier(contractInstance.address);
@@ -28,7 +28,6 @@ import { mock } from 'jest-mock-extended';
28
28
  import merge from 'lodash.merge';
29
29
 
30
30
  import { resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../../common/index.js';
31
- import { DEFAULT_BLOCK_NUMBER } from '../../fixtures/public_tx_simulation_tester.js';
32
31
  import type { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
33
32
  import type { PublicSideEffectTraceInterface } from '../../side_effect_trace_interface.js';
34
33
  import { AvmContext } from '../avm_context.js';
@@ -42,6 +41,7 @@ import { NullifierManager } from '../journal/nullifiers.js';
42
41
  import { PublicStorage } from '../journal/public_storage.js';
43
42
 
44
43
  export const PUBLIC_DISPATCH_FN_NAME = 'public_dispatch';
44
+ export const DEFAULT_BLOCK_NUMBER = 42;
45
45
 
46
46
  /**
47
47
  * Create a new AVM context with default values.
@@ -4,7 +4,7 @@ import type { ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
4
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
5
5
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
6
6
 
7
- import { PUBLIC_DISPATCH_FN_NAME } from './index.js';
7
+ import { getFunctionSelector } from './index.js';
8
8
 
9
9
  /**
10
10
  * This class is used during public/avm testing to function as a database of
@@ -22,6 +22,8 @@ export class SimpleContractDataSource implements ContractDataSource {
22
22
  private contractInstances: Map<string, ContractInstanceWithAddress> = new Map();
23
23
  // maps contract instance address to address
24
24
  private contractArtifacts: Map<string, ContractArtifact> = new Map();
25
+ // maps `${classID}:${fnSelector}` to name
26
+ private debugFunctionName: Map<string, string> = new Map();
25
27
 
26
28
  /////////////////////////////////////////////////////////////
27
29
  // Helper functions not in the contract data source interface
@@ -34,13 +36,25 @@ export class SimpleContractDataSource implements ContractDataSource {
34
36
  contractClass: ContractClassPublic,
35
37
  contractInstance: ContractInstanceWithAddress,
36
38
  ) {
37
- this.addContractArtifact(contractClass.id, contractArtifact);
39
+ await this.addContractArtifact(contractClass.id, contractArtifact);
38
40
  await this.addContractClass(contractClass);
39
41
  await this.addContractInstance(contractInstance);
40
42
  }
41
43
 
42
- addContractArtifact(classId: Fr, artifact: ContractArtifact): void {
44
+ async addContractArtifact(classId: Fr, artifact: ContractArtifact) {
43
45
  this.contractArtifacts.set(classId.toString(), artifact);
46
+ const classIdStr = classId.toString();
47
+ const publicFns = artifact.nonDispatchPublicFunctions;
48
+ if (publicFns.length !== 0) {
49
+ for (const fn of publicFns) {
50
+ const actualFnName = `${fn.name}`;
51
+ const fnSelector = await getFunctionSelector(actualFnName, artifact);
52
+ const key = `${classIdStr}:${fnSelector.toString()}`;
53
+
54
+ const longFnName = `${artifact.name}.${actualFnName}`;
55
+ this.debugFunctionName.set(key, longFnName);
56
+ }
57
+ }
44
58
  }
45
59
 
46
60
  /////////////////////////////////////////////////////////////
@@ -73,11 +87,24 @@ export class SimpleContractDataSource implements ContractDataSource {
73
87
  }
74
88
  this.logger.debug(`Retrieved contract artifact for address: ${address}`);
75
89
  this.logger.debug(`Contract class ID: ${contractInstance.currentContractClassId}`);
76
- return Promise.resolve(this.contractArtifacts.get(contractInstance!.currentContractClassId.toString()));
90
+ return this.contractArtifacts.get(contractInstance!.currentContractClassId.toString());
77
91
  }
78
92
 
79
- getDebugFunctionName(_address: AztecAddress, _selector: FunctionSelector): Promise<string> {
80
- return Promise.resolve(PUBLIC_DISPATCH_FN_NAME);
93
+ async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string> {
94
+ const contractInstance = await this.getContract(address);
95
+ 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()}`;
100
+ }
101
+ const key = `${contractInstance.currentContractClassId.toString()}:${selector.toString()}`;
102
+ const fnName = this.debugFunctionName.get(key);
103
+ if (!fnName) {
104
+ this.logger.warn(`Couldn't get fn name for debugging. Using selector:${selector} instead...`);
105
+ return selector.toString();
106
+ }
107
+ return fnName;
81
108
  }
82
109
 
83
110
  registerContractFunctionSignatures(_address: AztecAddress, _signatures: string[]): Promise<void> {
@@ -70,6 +70,9 @@ abstract class ExternalCall extends Instruction {
70
70
  // Track the success status directly
71
71
  context.machineState.nestedCallSuccess = success;
72
72
 
73
+ // Account for all instructions executed in the nested call
74
+ context.machineState.instrCounter += nestedCallResults.totalInstructions;
75
+
73
76
  // If the nested call reverted, we try to save the reason and the revert data.
74
77
  // This will be used by the caller to try to reconstruct the call stack.
75
78
  // This is only a heuristic and may not always work. It is intended to work
@@ -13,42 +13,42 @@ export class Set extends Instruction {
13
13
  OperandType.UINT8, // opcode
14
14
  OperandType.UINT8, // indirect
15
15
  OperandType.UINT8, // dstOffset
16
- OperandType.UINT8, // tag
16
+ OperandType.TAG, // tag
17
17
  OperandType.UINT8, // const (value)
18
18
  ];
19
19
  public static readonly wireFormat16: OperandType[] = [
20
20
  OperandType.UINT8, // opcode
21
21
  OperandType.UINT8, // indirect
22
22
  OperandType.UINT16, // dstOffset
23
- OperandType.UINT8, // tag
23
+ OperandType.TAG, // tag
24
24
  OperandType.UINT16, // const (value)
25
25
  ];
26
26
  public static readonly wireFormat32: OperandType[] = [
27
27
  OperandType.UINT8, // opcode
28
28
  OperandType.UINT8, // indirect
29
29
  OperandType.UINT16, // dstOffset
30
- OperandType.UINT8, // tag
30
+ OperandType.TAG, // tag
31
31
  OperandType.UINT32, // const (value)
32
32
  ];
33
33
  public static readonly wireFormat64: OperandType[] = [
34
34
  OperandType.UINT8, // opcode
35
35
  OperandType.UINT8, // indirect
36
36
  OperandType.UINT16, // dstOffset
37
- OperandType.UINT8, // tag
37
+ OperandType.TAG, // tag
38
38
  OperandType.UINT64, // const (value)
39
39
  ];
40
40
  public static readonly wireFormat128: OperandType[] = [
41
41
  OperandType.UINT8, // opcode
42
42
  OperandType.UINT8, // indirect
43
43
  OperandType.UINT16, // dstOffset
44
- OperandType.UINT8, // tag
44
+ OperandType.TAG, // tag
45
45
  OperandType.UINT128, // const (value)
46
46
  ];
47
47
  public static readonly wireFormatFF: OperandType[] = [
48
48
  OperandType.UINT8, // opcode
49
49
  OperandType.UINT8, // indirect
50
50
  OperandType.UINT16, // dstOffset
51
- OperandType.UINT8, // tag
51
+ OperandType.TAG, // tag
52
52
  OperandType.FF, // const (value)
53
53
  ];
54
54
 
@@ -59,7 +59,6 @@ export class Set extends Instruction {
59
59
  private value: bigint | number,
60
60
  ) {
61
61
  super();
62
- TaggedMemory.checkIsValidTag(inTag);
63
62
  }
64
63
 
65
64
  public async execute(context: AvmContext): Promise<void> {
@@ -85,19 +84,18 @@ export class Cast extends Instruction {
85
84
  OperandType.UINT8,
86
85
  OperandType.UINT8,
87
86
  OperandType.UINT8,
88
- OperandType.UINT8,
87
+ OperandType.TAG,
89
88
  ];
90
89
  static readonly wireFormat16 = [
91
90
  OperandType.UINT8,
92
91
  OperandType.UINT8,
93
92
  OperandType.UINT16,
94
93
  OperandType.UINT16,
95
- OperandType.UINT8,
94
+ OperandType.TAG,
96
95
  ];
97
96
 
98
97
  constructor(private indirect: number, private srcOffset: number, private dstOffset: number, private dstTag: number) {
99
98
  super();
100
- TaggedMemory.checkIsValidTag(dstTag);
101
99
  }
102
100
 
103
101
  public async execute(context: AvmContext): Promise<void> {
@@ -1,5 +1,6 @@
1
1
  import { strict as assert } from 'assert';
2
2
 
3
+ import { TaggedMemory } from '../avm_memory_types.js';
3
4
  import { BufferCursor } from './buffer_cursor.js';
4
5
 
5
6
  /**
@@ -103,8 +104,12 @@ export enum OperandType {
103
104
  UINT64,
104
105
  UINT128,
105
106
  FF,
107
+ TAG,
106
108
  }
107
109
 
110
+ // Define a type that represents the possible types of the deserialized values.
111
+ type DeserializedValue = number | bigint;
112
+
108
113
  type OperandNativeType = number | bigint;
109
114
  type OperandWriter = (value: any) => void;
110
115
 
@@ -116,6 +121,7 @@ const OPERAND_SPEC = new Map<OperandType, [number, (offset: number) => OperandNa
116
121
  [OperandType.UINT64, [8, Buffer.prototype.readBigInt64BE, Buffer.prototype.writeBigInt64BE]],
117
122
  [OperandType.UINT128, [16, readBigInt128BE, writeBigInt128BE]],
118
123
  [OperandType.FF, [32, readBigInt254BE, writeBigInt254BE]],
124
+ [OperandType.TAG, [1, Buffer.prototype.readUint8, Buffer.prototype.writeUint8]],
119
125
  ]);
120
126
 
121
127
  function readBigInt254BE(this: Buffer, offset: number): bigint {
@@ -160,19 +166,30 @@ function writeBigInt128BE(this: Buffer, value: bigint): void {
160
166
  * @param operands Specification of the operand types.
161
167
  * @returns An array as big as {@code operands}, with the converted TS values.
162
168
  */
163
- export function deserialize(cursor: BufferCursor | Buffer, operands: OperandType[]): (number | bigint)[] {
164
- const argValues = [];
169
+ export function deserialize(cursor: BufferCursor | Buffer, operands: OperandType[]): DeserializedValue[] {
170
+ const argValues: DeserializedValue[] = [];
165
171
  if (Buffer.isBuffer(cursor)) {
166
172
  cursor = new BufferCursor(cursor);
167
173
  }
168
174
 
169
- for (const op of operands) {
170
- const opType = op;
175
+ for (const opType of operands) {
171
176
  const [sizeBytes, reader, _writer] = OPERAND_SPEC.get(opType)!;
172
- argValues.push(reader.call(cursor.buffer(), cursor.position()));
177
+ const value = reader.call(cursor.buffer(), cursor.position());
178
+ argValues.push(value);
173
179
  cursor.advance(sizeBytes);
174
180
  }
175
181
 
182
+ // We first want to detect other parsing errors (e.g., instruction size
183
+ // is longer than remaining bytes) first and therefore tag validation is done after completion
184
+ // of parsing above. Order of errors need to match with circuit.
185
+ for (let i = 0; i < operands.length; i++) {
186
+ if (operands[i] === OperandType.TAG) {
187
+ // We parsed a single byte (readUInt8()) and therefore value is of number type (not bigint)
188
+ // We need to cast to number because checkIsValidTag expects a number.
189
+ TaggedMemory.checkIsValidTag(Number(argValues[i]) ?? 0);
190
+ }
191
+ }
192
+
176
193
  return argValues;
177
194
  }
178
195
 
@@ -1,3 +1,4 @@
1
+ import type { RevertCode } from '@aztec/stdlib/avm';
1
2
  import {
2
3
  Attributes,
3
4
  type Histogram,
@@ -8,11 +9,16 @@ import {
8
9
  ValueType,
9
10
  } from '@aztec/telemetry-client';
10
11
 
11
- export class ExecutorMetrics {
12
+ import type { ExecutorMetricsInterface } from './executor_metrics_interface.js';
13
+
14
+ export class ExecutorMetrics implements ExecutorMetricsInterface {
12
15
  public readonly tracer: Tracer;
13
16
  private fnCount: UpDownCounter;
14
17
  private fnDuration: Histogram;
15
18
  private manaPerSecond: Histogram;
19
+ private manaUsed: Histogram;
20
+ private totalInstructions: Histogram;
21
+ private txHashing: Histogram;
16
22
  private privateEffectsInsertions: Histogram;
17
23
 
18
24
  constructor(client: TelemetryClient, name = 'PublicExecutor') {
@@ -35,20 +41,53 @@ export class ExecutorMetrics {
35
41
  valueType: ValueType.INT,
36
42
  });
37
43
 
38
- this.privateEffectsInsertions = meter.createHistogram(Metrics.PUBLIC_EXECUTION_PRIVATE_EFFECTS_INSERTION, {
44
+ this.manaUsed = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_SIMULATION_MANA_USED, {
45
+ description: 'Total mana used',
46
+ unit: 'mana',
47
+ valueType: ValueType.INT,
48
+ });
49
+
50
+ this.totalInstructions = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_SIMULATION_TOTAL_INSTRUCTIONS, {
51
+ description: 'Total number of instructions executed',
52
+ unit: 'instructions',
53
+ valueType: ValueType.INT,
54
+ });
55
+
56
+ this.txHashing = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_TX_HASHING, {
57
+ description: 'Tx hashing time',
58
+ unit: 'ms',
59
+ valueType: ValueType.INT,
60
+ });
61
+
62
+ this.privateEffectsInsertions = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_PRIVATE_EFFECTS_INSERTION, {
39
63
  description: 'Private effects insertion time',
40
64
  unit: 'us',
41
65
  valueType: ValueType.INT,
42
66
  });
43
67
  }
44
68
 
45
- recordFunctionSimulation(durationMs: number, manaUsed: number, fnName: string) {
69
+ startRecordingTxSimulation(_txLabel: string) {
70
+ // do nothing (unimplemented)
71
+ }
72
+
73
+ stopRecordingTxSimulation(_txLabel: string, _revertedCode?: RevertCode) {
74
+ // do nothing (unimplemented)
75
+ }
76
+
77
+ recordEnqueuedCallSimulation(fnName: string, durationMs: number, manaUsed: number, totalInstructions: number) {
46
78
  this.fnCount.add(1, {
47
79
  [Attributes.OK]: true,
48
80
  [Attributes.APP_CIRCUIT_NAME]: fnName,
49
- [Attributes.MANA_USED]: manaUsed,
50
81
  });
51
- this.fnDuration.record(Math.ceil(durationMs));
82
+ this.manaUsed.record(Math.ceil(manaUsed), {
83
+ [Attributes.APP_CIRCUIT_NAME]: fnName,
84
+ });
85
+ this.totalInstructions.record(Math.ceil(totalInstructions), {
86
+ [Attributes.APP_CIRCUIT_NAME]: fnName,
87
+ });
88
+ this.fnDuration.record(Math.ceil(durationMs), {
89
+ [Attributes.APP_CIRCUIT_NAME]: fnName,
90
+ });
52
91
  if (durationMs > 0 && manaUsed > 0) {
53
92
  const manaPerSecond = Math.round((manaUsed * 1000) / durationMs);
54
93
  this.manaPerSecond.record(manaPerSecond, {
@@ -57,12 +96,21 @@ export class ExecutorMetrics {
57
96
  }
58
97
  }
59
98
 
60
- recordFunctionSimulationFailure() {
99
+ recordEnqueuedCallSimulationFailure(
100
+ _fnName: string,
101
+ _durationMs: number,
102
+ _manaUsed: number,
103
+ _totalInstructions: number,
104
+ ) {
61
105
  this.fnCount.add(1, {
62
106
  [Attributes.OK]: false,
63
107
  });
64
108
  }
65
109
 
110
+ recordTxHashComputation(durationMs: number) {
111
+ this.txHashing.record(Math.ceil(durationMs));
112
+ }
113
+
66
114
  recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible') {
67
115
  this.privateEffectsInsertions.record(Math.ceil(durationUs), {
68
116
  [Attributes.REVERTIBILITY]: type,
@@ -0,0 +1,15 @@
1
+ import type { RevertCode } from '@aztec/stdlib/avm';
2
+
3
+ export interface ExecutorMetricsInterface {
4
+ startRecordingTxSimulation(txLabel: string): void;
5
+ stopRecordingTxSimulation(txLabel: string, revertedCode?: RevertCode): void;
6
+ recordEnqueuedCallSimulation(fnName: string, durationMs: number, manaUsed: number, totalInstructions: number): void;
7
+ recordEnqueuedCallSimulationFailure(
8
+ fnName: string,
9
+ durationMs: number,
10
+ manaUsed: number,
11
+ totalInstructions: number,
12
+ ): void;
13
+ recordTxHashComputation(durationMs: number): void;
14
+ recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible'): void;
15
+ }