@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
@@ -12,7 +12,7 @@ import { TreeSnapshots, TxExecutionPhase } from '@aztec/stdlib/tx';
12
12
  import { strict as assert } from 'assert';
13
13
  import { inspect } from 'util';
14
14
  import { AvmPersistableStateManager } from '../avm/index.js';
15
- import { HintingPublicContractsDB } from '../hinting_db_sources.js';
15
+ import { HintingPublicContractsDB, HintingPublicTreesDB } from '../hinting_db_sources.js';
16
16
  import { SideEffectArrayLengths, SideEffectTrace } from '../side_effect_trace.js';
17
17
  import { getCallRequestsWithCalldataByPhase } from '../utils.js';
18
18
  /**
@@ -69,9 +69,9 @@ import { getCallRequestsWithCalldataByPhase } from '../utils.js';
69
69
  // We wrap the DB to collect AVM hints.
70
70
  const hints = new AvmExecutionHints();
71
71
  const hintingContractsDB = new HintingPublicContractsDB(contractsDB, hints);
72
- // TODO: Wrap merkle db.
72
+ const hintingTreesDB = new HintingPublicTreesDB(treesDB, hints);
73
73
  // Transaction level state manager that will be forked for revertible phases.
74
- const txStateManager = AvmPersistableStateManager.create(treesDB, hintingContractsDB, trace, doMerkleOperations, firstNullifier, globalVariables.blockNumber.toNumber());
74
+ const txStateManager = AvmPersistableStateManager.create(hintingTreesDB, hintingContractsDB, trace, doMerkleOperations, firstNullifier, globalVariables.blockNumber.toNumber());
75
75
  const gasSettings = tx.data.constants.txContext.gasSettings;
76
76
  const gasUsedByPrivate = tx.data.gasUsed;
77
77
  // Gas allocated to public is "whatever's left" after private, but with some max applied.
@@ -215,13 +215,15 @@ import { getCallRequestsWithCalldataByPhase } from '../utils.js';
215
215
  }
216
216
  /**
217
217
  * Generate the public inputs for the AVM circuit.
218
- */ async generateAvmCircuitPublicInputs(endStateReference) {
218
+ */ async generateAvmCircuitPublicInputs() {
219
219
  assert(this.halted, 'Can only get AvmCircuitPublicInputs after tx execution ends');
220
220
  const stateManager = this.state.getActiveStateManager();
221
221
  const startTreeSnapshots = new TreeSnapshots(this.startStateReference.l1ToL2MessageTree, this.startStateReference.partial.noteHashTree, this.startStateReference.partial.nullifierTree, this.startStateReference.partial.publicDataTree);
222
- // Will be patched/padded at the end of this fn
223
- const endTreeSnapshots = new TreeSnapshots(endStateReference.l1ToL2MessageTree, endStateReference.partial.noteHashTree, endStateReference.partial.nullifierTree, endStateReference.partial.publicDataTree);
224
- const avmCircuitPublicInputs = this.trace.toAvmCircuitPublicInputs(this.globalVariables, startTreeSnapshots, /*startGasUsed=*/ this.gasUsedByPrivate, this.gasSettings, this.feePayer, this.setupCallRequests.map((r)=>r.request), this.appLogicCallRequests.map((r)=>r.request), /*teardownCallRequest=*/ this.teardownCallRequests.length ? this.teardownCallRequests[0].request : PublicCallRequest.empty(), endTreeSnapshots, /*endGasUsed=*/ this.getTotalGasUsed(), /*transactionFee=*/ this.getTransactionFeeUnsafe(), /*reverted=*/ !this.revertCode.isOK());
222
+ // FIXME: We are first creating the PIs with the wrong endTreeSnapshots, then patching them.
223
+ // This is because we need to know the lengths of the accumulated data arrays to pad them.
224
+ // We should refactor this to avoid this hack.
225
+ // We should just get the info we need from the trace, and create the rest of the PIs here.
226
+ const avmCircuitPublicInputs = this.trace.toAvmCircuitPublicInputs(this.globalVariables, startTreeSnapshots, /*startGasUsed=*/ this.gasUsedByPrivate, this.gasSettings, this.feePayer, this.setupCallRequests.map((r)=>r.request), this.appLogicCallRequests.map((r)=>r.request), /*teardownCallRequest=*/ this.teardownCallRequests.length ? this.teardownCallRequests[0].request : PublicCallRequest.empty(), /*endTreeSnapshots=*/ TreeSnapshots.empty(), /*endGasUsed=*/ this.getTotalGasUsed(), /*transactionFee=*/ this.getTransactionFeeUnsafe(), /*reverted=*/ !this.revertCode.isOK());
225
227
  const getArrayLengths = (from)=>new PrivateToAvmAccumulatedDataArrayLengths(countAccumulatedItems(from.noteHashes), countAccumulatedItems(from.nullifiers), countAccumulatedItems(from.l2ToL1Msgs));
226
228
  const convertAccumulatedData = (from)=>new PrivateToAvmAccumulatedData(from.noteHashes, from.nullifiers, from.l2ToL1Msgs);
227
229
  // Temporary overrides as these entries aren't yet populated in trace
@@ -1,14 +1,16 @@
1
+ import type { Fr } from '@aztec/foundation/fields';
2
+ import { type Logger } from '@aztec/foundation/log';
1
3
  import { type AvmProvingRequest, type RevertCode } from '@aztec/stdlib/avm';
2
4
  import { SimulationError } from '@aztec/stdlib/errors';
3
- import type { GasUsed } from '@aztec/stdlib/gas';
4
- import { type GlobalVariables, NestedProcessReturnValues, Tx, TxExecutionPhase } from '@aztec/stdlib/tx';
5
- import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
6
- import { ExecutorMetrics } from '../executor_metrics.js';
5
+ import type { Gas, GasUsed } from '@aztec/stdlib/gas';
6
+ import { type GlobalVariables, NestedProcessReturnValues, PublicCallRequestWithCalldata, Tx, TxExecutionPhase } from '@aztec/stdlib/tx';
7
+ import type { AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js';
8
+ import { type AvmPersistableStateManager } from '../avm/index.js';
7
9
  import type { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
8
10
  import { PublicTxContext } from './public_tx_context.js';
9
11
  export type ProcessedPhase = {
10
12
  phase: TxExecutionPhase;
11
- durationMs: number;
13
+ durationMs?: number;
12
14
  returnValues: NestedProcessReturnValues[];
13
15
  reverted: boolean;
14
16
  revertReason?: SimulationError;
@@ -24,20 +26,19 @@ export type PublicTxResult = {
24
26
  };
25
27
  export declare class PublicTxSimulator {
26
28
  private treesDB;
27
- private contractsDB;
29
+ protected contractsDB: PublicContractsDB;
28
30
  private globalVariables;
29
31
  private doMerkleOperations;
30
32
  private skipFeeEnforcement;
31
- metrics: ExecutorMetrics;
32
- private log;
33
- constructor(treesDB: PublicTreesDB, contractsDB: PublicContractsDB, globalVariables: GlobalVariables, doMerkleOperations?: boolean, skipFeeEnforcement?: boolean, telemetryClient?: TelemetryClient);
34
- get tracer(): Tracer;
33
+ protected log: Logger;
34
+ constructor(treesDB: PublicTreesDB, contractsDB: PublicContractsDB, globalVariables: GlobalVariables, doMerkleOperations?: boolean, skipFeeEnforcement?: boolean);
35
35
  /**
36
36
  * Simulate a transaction's public portion including all of its phases.
37
37
  * @param tx - The transaction to simulate.
38
38
  * @returns The result of the transaction's public execution.
39
39
  */
40
40
  simulate(tx: Tx): Promise<PublicTxResult>;
41
+ protected computeTxHash(tx: Tx): Promise<import("@aztec/stdlib/tx").TxHash>;
41
42
  /**
42
43
  * Simulate the setup phase of a transaction's public execution.
43
44
  * @param context - WILL BE MUTATED. The context of the currently executing public transaction portion
@@ -62,7 +63,7 @@ export declare class PublicTxSimulator {
62
63
  * @param context - WILL BE MUTATED. The context of the currently executing public transaction portion
63
64
  * @returns The phase result.
64
65
  */
65
- private simulatePhase;
66
+ protected simulatePhase(phase: TxExecutionPhase, context: PublicTxContext): Promise<ProcessedPhase>;
66
67
  /**
67
68
  * Simulate an enqueued public call.
68
69
  * @param phase - The current phase of public execution
@@ -70,7 +71,7 @@ export declare class PublicTxSimulator {
70
71
  * @param callRequest - The public function call request, including the calldata.
71
72
  * @returns The result of execution.
72
73
  */
73
- private simulateEnqueuedCall;
74
+ protected simulateEnqueuedCall(phase: TxExecutionPhase, context: PublicTxContext, callRequest: PublicCallRequestWithCalldata): Promise<AvmFinalizedCallResult>;
74
75
  /**
75
76
  * Simulate an enqueued public call, without modifying the context (PublicTxContext).
76
77
  * Resulting modifications to the context can be applied by the caller.
@@ -79,22 +80,21 @@ export declare class PublicTxSimulator {
79
80
  * while still simulating phases and generating a proving request.
80
81
  *
81
82
  * @param stateManager - The state manager for AvmSimulation
82
- * @param context - The context of the currently executing public transaction portion
83
83
  * @param callRequest - The public function call request, including the calldata.
84
84
  * @param allocatedGas - The gas allocated to the enqueued call
85
85
  * @param fnName - The name of the function
86
86
  * @returns The result of execution.
87
87
  */
88
- private simulateEnqueuedCallInternal;
88
+ protected simulateEnqueuedCallInternal(stateManager: AvmPersistableStateManager, { request, calldata }: PublicCallRequestWithCalldata, allocatedGas: Gas, transactionFee: Fr, fnName: string): Promise<AvmFinalizedCallResult>;
89
89
  /**
90
90
  * Insert the non-revertible accumulated data from private into the public state.
91
91
  */
92
- insertNonRevertiblesFromPrivate(context: PublicTxContext): Promise<void>;
92
+ protected insertNonRevertiblesFromPrivate(context: PublicTxContext, tx: Tx): Promise<void>;
93
93
  /**
94
94
  * Insert the revertible accumulated data from private into the public state.
95
95
  * Start by forking state so we can rollback to the end of setup if app logic or teardown reverts.
96
96
  */
97
- insertRevertiblesFromPrivate(context: PublicTxContext): Promise<boolean>;
97
+ protected insertRevertiblesFromPrivate(context: PublicTxContext, tx: Tx): Promise<boolean>;
98
98
  private payFee;
99
99
  /**
100
100
  * Generate the proving request for the AVM circuit.
@@ -1 +1 @@
1
- {"version":3,"file":"public_tx_simulator.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/public_tx_simulator.ts"],"names":[],"mappings":"AAKA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAO,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EACL,KAAK,eAAe,EACpB,yBAAyB,EAEzB,EAAE,EACF,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,MAAM,EAAiC,MAAM,yBAAyB,CAAC;AAQvH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,yBAAyB,EAAE,CAAC;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,eAAe,EAAE,cAAc,EAAE,CAAC;CACnC,CAAC;AAEF,qBAAa,iBAAiB;IAM1B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,kBAAkB;IAT5B,OAAO,EAAE,eAAe,CAAC;IAEzB,OAAO,CAAC,GAAG,CAAS;gBAGV,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,iBAAiB,EAC9B,eAAe,EAAE,eAAe,EAChC,kBAAkB,GAAE,OAAe,EACnC,kBAAkB,GAAE,OAAe,EAC3C,eAAe,GAAE,eAAsC;IAMzD,IAAI,MAAM,IAAI,MAAM,CAEnB;IACD;;;;OAIG;IACU,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAyFtD;;;;OAIG;YACW,kBAAkB;IAIhC;;;;OAIG;YACW,qBAAqB;IAkBnC;;;;OAIG;YACW,qBAAqB;IAoBnC;;;;;OAKG;YACW,aAAa;IAuC3B;;;;;;OAMG;YAOW,oBAAoB;IA8ClC;;;;;;;;;;;;;OAaG;YAOW,4BAA4B;IAgD1C;;OAEG;IACU,+BAA+B,CAAC,OAAO,EAAE,eAAe;IAkBrE;;;OAGG;IACU,4BAA4B,CAAC,OAAO,EAAE,eAAe,GAAgB,OAAO,CAAC,OAAO,CAAC;YA+BpF,MAAM;IAgCpB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;CAStC"}
1
+ {"version":3,"file":"public_tx_simulator.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/public_tx_simulator.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,14 @@
1
- function _ts_decorate(decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- }
7
1
  import { createLogger } from '@aztec/foundation/log';
8
- import { Timer } from '@aztec/foundation/timer';
9
2
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
10
3
  import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
11
4
  import { AvmCircuitInputs, AvmEnqueuedCallHint } from '@aztec/stdlib/avm';
12
5
  import { SimulationError } from '@aztec/stdlib/errors';
13
6
  import { ProvingRequestType } from '@aztec/stdlib/proofs';
14
7
  import { NestedProcessReturnValues, TxExecutionPhase } from '@aztec/stdlib/tx';
15
- import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
16
8
  import { strict as assert } from 'assert';
17
9
  import { getPublicFunctionDebugName } from '../../common/debug_fn_name.js';
18
10
  import { AvmSimulator } from '../avm/index.js';
19
11
  import { NullifierCollisionError } from '../avm/journal/nullifiers.js';
20
- import { ExecutorMetrics } from '../executor_metrics.js';
21
12
  import { PublicTxContext } from './public_tx_context.js';
22
13
  export class PublicTxSimulator {
23
14
  treesDB;
@@ -25,19 +16,14 @@ export class PublicTxSimulator {
25
16
  globalVariables;
26
17
  doMerkleOperations;
27
18
  skipFeeEnforcement;
28
- metrics;
29
19
  log;
30
- constructor(treesDB, contractsDB, globalVariables, doMerkleOperations = false, skipFeeEnforcement = false, telemetryClient = getTelemetryClient()){
20
+ constructor(treesDB, contractsDB, globalVariables, doMerkleOperations = false, skipFeeEnforcement = false){
31
21
  this.treesDB = treesDB;
32
22
  this.contractsDB = contractsDB;
33
23
  this.globalVariables = globalVariables;
34
24
  this.doMerkleOperations = doMerkleOperations;
35
25
  this.skipFeeEnforcement = skipFeeEnforcement;
36
26
  this.log = createLogger(`simulator:public_tx_simulator`);
37
- this.metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator');
38
- }
39
- get tracer() {
40
- return this.metrics.tracer;
41
27
  }
42
28
  /**
43
29
  * Simulate a transaction's public portion including all of its phases.
@@ -45,31 +31,19 @@ export class PublicTxSimulator {
45
31
  * @returns The result of the transaction's public execution.
46
32
  */ async simulate(tx) {
47
33
  try {
48
- const startTime = process.hrtime.bigint();
49
- const txHash = await tx.getTxHash();
34
+ const txHash = await this.computeTxHash(tx);
50
35
  this.log.debug(`Simulating ${tx.publicFunctionCalldata.length} public calls for tx ${txHash}`, {
51
36
  txHash
52
37
  });
53
38
  const context = await PublicTxContext.create(this.treesDB, this.contractsDB, tx, this.globalVariables, this.doMerkleOperations);
54
- const nonRevertStart = process.hrtime.bigint();
55
- await this.insertNonRevertiblesFromPrivate(context);
56
- // add new contracts to the contracts db so that their functions may be found and called
57
- // TODO(#6464): Should we allow emitting contracts in the private setup phase?
58
- await this.contractsDB.addNewNonRevertibleContracts(tx);
59
- const nonRevertEnd = process.hrtime.bigint();
60
- this.metrics.recordPrivateEffectsInsertion(Number(nonRevertEnd - nonRevertStart) / 1_000, 'non-revertible');
39
+ await this.insertNonRevertiblesFromPrivate(context, tx);
61
40
  const processedPhases = [];
62
41
  if (context.hasPhase(TxExecutionPhase.SETUP)) {
63
42
  const setupResult = await this.simulateSetupPhase(context);
64
43
  processedPhases.push(setupResult);
65
44
  }
66
- const revertStart = process.hrtime.bigint();
67
- const success = await this.insertRevertiblesFromPrivate(context);
45
+ const success = await this.insertRevertiblesFromPrivate(context, tx);
68
46
  if (success) {
69
- // add new contracts to the contracts db so that their functions may be found and called
70
- await this.contractsDB.addNewRevertibleContracts(tx);
71
- const revertEnd = process.hrtime.bigint();
72
- this.metrics.recordPrivateEffectsInsertion(Number(revertEnd - revertStart) / 1_000, 'revertible');
73
47
  // Only proceed with app logic if there was no revert during revertible insertion
74
48
  if (context.hasPhase(TxExecutionPhase.APP_LOGIC)) {
75
49
  const appLogicResult = await this.simulateAppLogicPhase(context);
@@ -84,7 +58,7 @@ export class PublicTxSimulator {
84
58
  }
85
59
  await context.halt();
86
60
  await this.payFee(context);
87
- const publicInputs = await context.generateAvmCircuitPublicInputs(await this.treesDB.getStateReference());
61
+ const publicInputs = await context.generateAvmCircuitPublicInputs();
88
62
  const avmProvingRequest = PublicTxSimulator.generateProvingRequest(publicInputs, context.hints);
89
63
  const revertCode = context.getFinalRevertCode();
90
64
  if (!revertCode.isOK()) {
@@ -93,9 +67,9 @@ export class PublicTxSimulator {
93
67
  // Commit contracts from this TX to the block-level cache and clear tx cache
94
68
  // If the tx reverted, only commit non-revertible contracts
95
69
  // NOTE: You can't create contracts in public, so this is only relevant for private-created contracts
70
+ // FIXME(fcarreiro): this should conceptually use the hinted contracts db.
71
+ // However things should work as they are now because the hinted db would still pick up the new contracts.
96
72
  this.contractsDB.commitContractsForTx(/*onlyNonRevertibles=*/ !revertCode.isOK());
97
- const endTime = process.hrtime.bigint();
98
- this.log.debug(`Public TX simulator took ${Number(endTime - startTime) / 1_000_000} ms\n`);
99
73
  return {
100
74
  avmProvingRequest,
101
75
  gasUsed: {
@@ -111,9 +85,14 @@ export class PublicTxSimulator {
111
85
  } finally{
112
86
  // Make sure there are no new contracts in the tx-level cache.
113
87
  // They should either be committed to block-level cache or cleared.
88
+ // FIXME(fcarreiro): this should conceptually use the hinted contracts db.
89
+ // However things should work as they are now because the hinted db would still pick up the new contracts.
114
90
  this.contractsDB.clearContractsForTx();
115
91
  }
116
92
  }
93
+ async computeTxHash(tx) {
94
+ return await tx.getTxHash();
95
+ }
117
96
  /**
118
97
  * Simulate the setup phase of a transaction's public execution.
119
98
  * @param context - WILL BE MUTATED. The context of the currently executing public transaction portion
@@ -174,7 +153,6 @@ export class PublicTxSimulator {
174
153
  const returnValues = [];
175
154
  let reverted = false;
176
155
  let revertReason;
177
- const phaseTimer = new Timer();
178
156
  for(let i = callRequests.length - 1; i >= 0; i--){
179
157
  if (reverted) {
180
158
  break;
@@ -189,7 +167,6 @@ export class PublicTxSimulator {
189
167
  }
190
168
  return {
191
169
  phase,
192
- durationMs: phaseTimer.ms(),
193
170
  returnValues,
194
171
  reverted,
195
172
  revertReason
@@ -229,7 +206,6 @@ export class PublicTxSimulator {
229
206
  * while still simulating phases and generating a proving request.
230
207
  *
231
208
  * @param stateManager - The state manager for AvmSimulation
232
- * @param context - The context of the currently executing public transaction portion
233
209
  * @param callRequest - The public function call request, including the calldata.
234
210
  * @param allocatedGas - The gas allocated to the enqueued call
235
211
  * @param fnName - The name of the function
@@ -238,25 +214,13 @@ export class PublicTxSimulator {
238
214
  const address = request.contractAddress;
239
215
  const sender = request.msgSender;
240
216
  this.log.debug(`Executing enqueued public call to external function ${fnName}@${address} with ${allocatedGas.l2Gas} allocated L2 gas.`);
241
- const timer = new Timer();
242
217
  const simulator = await AvmSimulator.create(stateManager, address, sender, transactionFee, this.globalVariables, request.isStaticCall, calldata, allocatedGas);
243
218
  const avmCallResult = await simulator.execute();
244
- const result = avmCallResult.finalize();
245
- this.log.verbose(result.reverted ? `Simulation of enqueued public call ${fnName} reverted with reason ${result.revertReason}.` : `Simulation of enqueued public call ${fnName} completed successfully.`, {
246
- eventName: 'avm-simulation',
247
- appCircuitName: fnName,
248
- duration: timer.ms()
249
- });
250
- if (result.reverted) {
251
- this.metrics.recordFunctionSimulationFailure();
252
- } else {
253
- this.metrics.recordFunctionSimulation(timer.ms(), allocatedGas.sub(result.gasLeft).l2Gas, fnName);
254
- }
255
- return result;
219
+ return avmCallResult.finalize();
256
220
  }
257
221
  /**
258
222
  * Insert the non-revertible accumulated data from private into the public state.
259
- */ async insertNonRevertiblesFromPrivate(context) {
223
+ */ async insertNonRevertiblesFromPrivate(context, tx) {
260
224
  const stateManager = context.state.getActiveStateManager();
261
225
  try {
262
226
  await stateManager.writeSiloedNullifiersFromPrivate(context.nonRevertibleAccumulatedDataFromPrivate.nullifiers);
@@ -270,11 +234,16 @@ export class PublicTxSimulator {
270
234
  await stateManager.writeUniqueNoteHash(noteHash);
271
235
  }
272
236
  }
237
+ // add new contracts to the contracts db so that their functions may be found and called
238
+ // TODO(#6464): Should we allow emitting contracts in the private setup phase?
239
+ // FIXME(fcarreiro): this should conceptually use the hinted contracts db.
240
+ // However things should work as they are now because the hinted db would still pick up the new contracts.
241
+ await this.contractsDB.addNewNonRevertibleContracts(tx);
273
242
  }
274
243
  /**
275
244
  * Insert the revertible accumulated data from private into the public state.
276
245
  * Start by forking state so we can rollback to the end of setup if app logic or teardown reverts.
277
- */ async insertRevertiblesFromPrivate(context) {
246
+ */ async insertRevertiblesFromPrivate(context, tx) {
278
247
  // Fork the state manager so we can rollback to end of setup if app logic reverts.
279
248
  await context.state.fork();
280
249
  const stateManager = context.state.getActiveStateManager();
@@ -295,6 +264,10 @@ export class PublicTxSimulator {
295
264
  await stateManager.writeSiloedNoteHash(noteHash);
296
265
  }
297
266
  }
267
+ // add new contracts to the contracts db so that their functions may be found and called
268
+ // FIXME(fcarreiro): this should conceptually use the hinted contracts db.
269
+ // However things should work as they are now because the hinted db would still pick up the new contracts.
270
+ await this.contractsDB.addNewRevertibleContracts(tx);
298
271
  return /*success=*/ true;
299
272
  }
300
273
  async payFee(context) {
@@ -329,16 +302,3 @@ export class PublicTxSimulator {
329
302
  };
330
303
  }
331
304
  }
332
- _ts_decorate([
333
- trackSpan('PublicTxSimulator.simulateEnqueuedCall', (phase, context, callRequest)=>({
334
- [Attributes.TX_HASH]: context.txHash.toString(),
335
- [Attributes.TARGET_ADDRESS]: callRequest.request.contractAddress.toString(),
336
- [Attributes.SENDER_ADDRESS]: callRequest.request.msgSender.toString(),
337
- [Attributes.SIMULATOR_PHASE]: TxExecutionPhase[phase].toString()
338
- }))
339
- ], PublicTxSimulator.prototype, "simulateEnqueuedCall", null);
340
- _ts_decorate([
341
- trackSpan('PublicTxSimulator.simulateEnqueuedCallInternal', (_stateManager, _callRequest, _allocatedGas, _transactionFee, fnName)=>({
342
- [Attributes.APP_CIRCUIT_NAME]: fnName
343
- }))
344
- ], PublicTxSimulator.prototype, "simulateEnqueuedCallInternal", null);
@@ -0,0 +1,19 @@
1
+ import type { Fr } from '@aztec/foundation/fields';
2
+ import type { Gas } from '@aztec/stdlib/gas';
3
+ import { type GlobalVariables, PublicCallRequestWithCalldata, TxExecutionPhase } from '@aztec/stdlib/tx';
4
+ import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
5
+ import type { AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js';
6
+ import type { AvmPersistableStateManager } from '../avm/index.js';
7
+ import type { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
8
+ import { MeasuredPublicTxSimulator } from './measured_public_tx_simulator.js';
9
+ import { PublicTxContext } from './public_tx_context.js';
10
+ /**
11
+ * A public tx simulator that tracks runtime/production metrics with telemetry.
12
+ */
13
+ export declare class TelemetryPublicTxSimulator extends MeasuredPublicTxSimulator {
14
+ readonly tracer: Tracer;
15
+ constructor(treesDB: PublicTreesDB, contractsDB: PublicContractsDB, globalVariables: GlobalVariables, doMerkleOperations?: boolean, skipFeeEnforcement?: boolean, telemetryClient?: TelemetryClient);
16
+ protected simulateEnqueuedCall(phase: TxExecutionPhase, context: PublicTxContext, callRequest: PublicCallRequestWithCalldata): Promise<AvmFinalizedCallResult>;
17
+ protected simulateEnqueuedCallInternal(stateManager: AvmPersistableStateManager, callRequest: PublicCallRequestWithCalldata, allocatedGas: Gas, transactionFee: Fr, fnName: string): Promise<AvmFinalizedCallResult>;
18
+ }
19
+ //# sourceMappingURL=telemetry_public_tx_simulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry_public_tx_simulator.d.ts","sourceRoot":"","sources":["../../../src/public/public_tx_simulator/telemetry_public_tx_simulator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,KAAK,eAAe,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,MAAM,EAAiC,MAAM,yBAAyB,CAAC;AAEvH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,yBAAyB;IAEvE,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAG7B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,iBAAiB,EAC9B,eAAe,EAAE,eAAe,EAChC,kBAAkB,GAAE,OAAe,EACnC,kBAAkB,GAAE,OAAe,EACnC,eAAe,GAAE,eAAsC;cAahC,oBAAoB,CAC3C,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,6BAA6B,GACzC,OAAO,CAAC,sBAAsB,CAAC;cAUT,4BAA4B,CACnD,YAAY,EAAE,0BAA0B,EACxC,WAAW,EAAE,6BAA6B,EAC1C,YAAY,EAAE,GAAG,EACjB,cAAc,EAAE,EAAE,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,sBAAsB,CAAC;CAGnC"}
@@ -0,0 +1,39 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ import { TxExecutionPhase } from '@aztec/stdlib/tx';
8
+ import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
9
+ import { ExecutorMetrics } from '../executor_metrics.js';
10
+ import { MeasuredPublicTxSimulator } from './measured_public_tx_simulator.js';
11
+ /**
12
+ * A public tx simulator that tracks runtime/production metrics with telemetry.
13
+ */ export class TelemetryPublicTxSimulator extends MeasuredPublicTxSimulator {
14
+ /* tracer needed by trackSpans */ tracer;
15
+ constructor(treesDB, contractsDB, globalVariables, doMerkleOperations = false, skipFeeEnforcement = false, telemetryClient = getTelemetryClient()){
16
+ const metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator');
17
+ super(treesDB, contractsDB, globalVariables, doMerkleOperations, skipFeeEnforcement, metrics);
18
+ this.tracer = metrics.tracer;
19
+ }
20
+ async simulateEnqueuedCall(phase, context, callRequest) {
21
+ return await super.simulateEnqueuedCall(phase, context, callRequest);
22
+ }
23
+ async simulateEnqueuedCallInternal(stateManager, callRequest, allocatedGas, transactionFee, fnName) {
24
+ return await super.simulateEnqueuedCallInternal(stateManager, callRequest, allocatedGas, transactionFee, fnName);
25
+ }
26
+ }
27
+ _ts_decorate([
28
+ trackSpan('PublicTxSimulator.simulateEnqueuedCall', (phase, context, callRequest)=>({
29
+ [Attributes.TX_HASH]: context.txHash.toString(),
30
+ [Attributes.TARGET_ADDRESS]: callRequest.request.contractAddress.toString(),
31
+ [Attributes.SENDER_ADDRESS]: callRequest.request.msgSender.toString(),
32
+ [Attributes.SIMULATOR_PHASE]: TxExecutionPhase[phase].toString()
33
+ }))
34
+ ], TelemetryPublicTxSimulator.prototype, "simulateEnqueuedCall", null);
35
+ _ts_decorate([
36
+ trackSpan('PublicTxSimulator.simulateEnqueuedCallInternal', (_stateManager, _callRequest, _allocatedGas, _transactionFee, fnName)=>({
37
+ [Attributes.APP_CIRCUIT_NAME]: fnName
38
+ }))
39
+ ], TelemetryPublicTxSimulator.prototype, "simulateEnqueuedCallInternal", null);
@@ -0,0 +1,43 @@
1
+ import type { RevertCode } from '@aztec/stdlib/avm';
2
+ import type { ExecutorMetricsInterface } from './executor_metrics_interface.js';
3
+ export interface PublicEnqueuedCallMetrics {
4
+ fnName: string;
5
+ durationMs: number;
6
+ manaUsed: number;
7
+ totalInstructions: number;
8
+ reverted: boolean;
9
+ }
10
+ export interface PublicTxMetrics {
11
+ totalDurationMs: number;
12
+ manaUsed: number;
13
+ totalInstructions: number;
14
+ txHashMs: number | undefined;
15
+ nonRevertiblePrivateInsertionsUs: number | undefined;
16
+ revertiblePrivateInsertionsUs: number | undefined;
17
+ enqueuedCalls: PublicEnqueuedCallMetrics[];
18
+ revertedCode: RevertCode | undefined;
19
+ }
20
+ export declare enum PublicTxMetricsFilter {
21
+ ALL = 0,
22
+ TOTALS = 1,
23
+ DURATIONS = 2,
24
+ INSTRUCTIONS = 3
25
+ }
26
+ export declare class TestExecutorMetrics implements ExecutorMetricsInterface {
27
+ #private;
28
+ private logger;
29
+ private txMetrics;
30
+ private currentTxLabel;
31
+ private txTimer;
32
+ constructor();
33
+ startRecordingTxSimulation(txLabel: string): void;
34
+ stopRecordingTxSimulation(txLabel: string, revertedCode?: RevertCode): void;
35
+ recordEnqueuedCallSimulation(fnName: string, durationMs: number, manaUsed: number, totalInstructions: number): void;
36
+ recordEnqueuedCallSimulationFailure(fnName: string, durationMs: number, manaUsed: number, totalInstructions: number): void;
37
+ recordTxHashComputation(durationMs: number): void;
38
+ recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible'): void;
39
+ prettyPrint(filter?: PublicTxMetricsFilter): void;
40
+ toPrettyString(filter?: PublicTxMetricsFilter): string;
41
+ toJSON(indent?: number): string;
42
+ }
43
+ //# sourceMappingURL=test_executor_metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_executor_metrics.d.ts","sourceRoot":"","sources":["../../src/public/test_executor_metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,gCAAgC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrD,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;CACtC;AAWD,oBAAY,qBAAqB;IAC/B,GAAG,IAAA;IACH,MAAM,IAAA;IACN,SAAS,IAAA;IACT,YAAY,IAAA;CACb;AAED,qBAAa,mBAAoB,YAAW,wBAAwB;;IAClE,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,OAAO,CAAoB;;IAMnC,0BAA0B,CAAC,OAAO,EAAE,MAAM;IAiB1C,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,UAAU;IAkBpE,4BAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;IAI5G,mCAAmC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;IAsBnH,uBAAuB,CAAC,UAAU,EAAE,MAAM;IAO1C,6BAA6B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,gBAAgB;IAkBvF,WAAW,CAAC,MAAM,GAAE,qBAAiD;IAIrE,cAAc,CAAC,MAAM,GAAE,qBAAiD;IAqExE,MAAM,CAAC,MAAM,SAAI;CAGlB"}
@@ -0,0 +1,158 @@
1
+ import { sum } from '@aztec/foundation/collection';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { Timer } from '@aztec/foundation/timer';
4
+ import { strict as assert } from 'assert';
5
+ const NUM_SPACES = 4;
6
+ const H1 = '# ';
7
+ const H2 = '\n## ';
8
+ const INDENT = ' '.repeat(NUM_SPACES);
9
+ const INDENT0 = '- ';
10
+ const INDENT1 = INDENT + '- ';
11
+ const INDENT2 = INDENT + INDENT + '- ';
12
+ const H_LINE = '\n---------------------------------------------------------------------';
13
+ export var PublicTxMetricsFilter = /*#__PURE__*/ function(PublicTxMetricsFilter) {
14
+ PublicTxMetricsFilter[PublicTxMetricsFilter["ALL"] = 0] = "ALL";
15
+ PublicTxMetricsFilter[PublicTxMetricsFilter["TOTALS"] = 1] = "TOTALS";
16
+ PublicTxMetricsFilter[PublicTxMetricsFilter["DURATIONS"] = 2] = "DURATIONS";
17
+ PublicTxMetricsFilter[PublicTxMetricsFilter["INSTRUCTIONS"] = 3] = "INSTRUCTIONS";
18
+ return PublicTxMetricsFilter;
19
+ }({});
20
+ export class TestExecutorMetrics {
21
+ logger;
22
+ // tx label -> tx metrics
23
+ txMetrics = new Map();
24
+ currentTxLabel;
25
+ txTimer;
26
+ constructor(){
27
+ this.logger = createLogger(`simulator:test_executor_metrics`);
28
+ }
29
+ startRecordingTxSimulation(txLabel) {
30
+ assert(!this.currentTxLabel, 'Cannot start recording tx simulation when another is live');
31
+ assert(!this.txMetrics.has(txLabel), 'Cannot start recording metrics for tx with duplicate label');
32
+ this.txMetrics.set(txLabel, {
33
+ totalDurationMs: 0,
34
+ manaUsed: 0,
35
+ totalInstructions: 0,
36
+ txHashMs: undefined,
37
+ nonRevertiblePrivateInsertionsUs: undefined,
38
+ revertiblePrivateInsertionsUs: undefined,
39
+ enqueuedCalls: [],
40
+ revertedCode: undefined
41
+ });
42
+ this.currentTxLabel = txLabel;
43
+ this.txTimer = new Timer();
44
+ }
45
+ stopRecordingTxSimulation(txLabel, revertedCode) {
46
+ assert(this.currentTxLabel === txLabel, 'Cannot stop recording metrics for tx when another is live');
47
+ const txMetrics = this.txMetrics.get(txLabel);
48
+ // total duration of tx
49
+ txMetrics.totalDurationMs = this.txTimer.ms();
50
+ this.logger.debug(`Public TX simulation of ${txLabel} took ${txMetrics.totalDurationMs}ms`);
51
+ // add manaUsed across all enqueued calls
52
+ txMetrics.manaUsed = sum(txMetrics.enqueuedCalls.map((call)=>call.manaUsed));
53
+ // add totalInstructions across all enqueued calls
54
+ txMetrics.totalInstructions = sum(txMetrics.enqueuedCalls.map((call)=>call.totalInstructions));
55
+ txMetrics.revertedCode = revertedCode;
56
+ this.currentTxLabel = undefined;
57
+ }
58
+ recordEnqueuedCallSimulation(fnName, durationMs, manaUsed, totalInstructions) {
59
+ this.#recordEnqueuedCallSimulation(fnName, durationMs, manaUsed, totalInstructions, false);
60
+ }
61
+ recordEnqueuedCallSimulationFailure(fnName, durationMs, manaUsed, totalInstructions) {
62
+ this.#recordEnqueuedCallSimulation(fnName, durationMs, manaUsed, totalInstructions, true);
63
+ }
64
+ #recordEnqueuedCallSimulation(fnName, durationMs, manaUsed, totalInstructions, reverted) {
65
+ assert(this.currentTxLabel, 'Cannot record enqueued call simulation when no tx is live');
66
+ const txMetrics = this.txMetrics.get(this.currentTxLabel);
67
+ txMetrics.enqueuedCalls.push({
68
+ fnName,
69
+ durationMs,
70
+ manaUsed,
71
+ totalInstructions,
72
+ reverted
73
+ });
74
+ }
75
+ recordTxHashComputation(durationMs) {
76
+ assert(this.currentTxLabel, 'Cannot record tx hash computation time when no tx is live');
77
+ const txMetrics = this.txMetrics.get(this.currentTxLabel);
78
+ assert(txMetrics.txHashMs === undefined, 'Cannot RE-record tx hash computation time');
79
+ txMetrics.txHashMs = durationMs;
80
+ }
81
+ recordPrivateEffectsInsertion(durationUs, type) {
82
+ assert(this.currentTxLabel, 'Cannot record private effects insertion when no tx is live');
83
+ const txMetrics = this.txMetrics.get(this.currentTxLabel);
84
+ if (type === 'revertible') {
85
+ assert(txMetrics.revertiblePrivateInsertionsUs === undefined, 'Cannot RE-record revertible insertions of private effects');
86
+ txMetrics.revertiblePrivateInsertionsUs = durationUs;
87
+ } else {
88
+ assert(txMetrics.nonRevertiblePrivateInsertionsUs === undefined, 'Cannot RE-record non-revertible insertions of private effects');
89
+ txMetrics.nonRevertiblePrivateInsertionsUs = durationUs;
90
+ }
91
+ }
92
+ prettyPrint(filter = 0) {
93
+ this.logger.info(this.toPrettyString(filter));
94
+ }
95
+ toPrettyString(filter = 0) {
96
+ let pretty = '';
97
+ //pretty += H_LINE + '\n';
98
+ pretty += `${H1}Public TX Simulation Metrics (${PublicTxMetricsFilter[filter]})\n`;
99
+ for (const [txLabel, txMetrics] of this.txMetrics.entries()){
100
+ //pretty += H_LINE + '\n';
101
+ pretty += `${H2}TX Label: ${txLabel}\n`;
102
+ if (filter == 2 || filter === 1 || filter === 0) {
103
+ pretty += `${INDENT0}Total duration: ${fmtNum(txMetrics.totalDurationMs, 'ms')}\n`;
104
+ }
105
+ if (filter === 1 || filter === 0) {
106
+ pretty += `${INDENT0}Total mana used: ${fmtNum(txMetrics.manaUsed)}\n`;
107
+ const manaPerSecond = Math.round(txMetrics.manaUsed * 1000 / txMetrics.totalDurationMs);
108
+ pretty += `${INDENT0}Mana per second: ${fmtNum(manaPerSecond)}\n`;
109
+ }
110
+ if (filter === 3 || filter === 1 || filter === 0) {
111
+ pretty += `${INDENT0}Total instructions executed: ${fmtNum(txMetrics.totalInstructions)}\n`;
112
+ }
113
+ if (filter === 2 || filter === 0) {
114
+ pretty += `${INDENT0}Tx hash computation: ${fmtNum(txMetrics.txHashMs, 'ms')}\n`;
115
+ pretty += `${INDENT0}Private insertions:\n`;
116
+ pretty += `${INDENT1}Non-revertible: ${fmtNum(txMetrics.nonRevertiblePrivateInsertionsUs / 1_000, 'ms')}\n`;
117
+ pretty += `${INDENT1}Revertible: ${fmtNum(txMetrics.revertiblePrivateInsertionsUs / 1_000, 'ms')}\n`;
118
+ }
119
+ if (filter !== 1) {
120
+ // totals exclude enqueued calls
121
+ pretty += this.#enqueuedCallsToPrettyString(txMetrics, filter);
122
+ }
123
+ if (txMetrics.revertedCode !== undefined && !txMetrics.revertedCode.isOK()) {
124
+ pretty += `${INDENT0}Reverted code: ${txMetrics.revertedCode?.getDescription()}\n`;
125
+ }
126
+ pretty += H_LINE + '\n';
127
+ }
128
+ return pretty;
129
+ }
130
+ #enqueuedCallsToPrettyString(txMetrics, filter) {
131
+ let pretty = '';
132
+ pretty += `${INDENT0}Enqueued public calls:\n`;
133
+ for (const enqueuedCall of txMetrics.enqueuedCalls){
134
+ pretty += `${INDENT1}**Fn: ${enqueuedCall.fnName}**\n`;
135
+ if (filter === 2 || filter === 0) {
136
+ pretty += `${INDENT2}Duration: ${fmtNum(enqueuedCall.durationMs, 'ms')}\n`;
137
+ }
138
+ if (filter === 0) {
139
+ pretty += `${INDENT2}Mana used: ${fmtNum(enqueuedCall.manaUsed)}\n`;
140
+ const manaPerSecond = Math.round(enqueuedCall.manaUsed * 1000 / enqueuedCall.durationMs);
141
+ pretty += `${INDENT2}Mana per second: ${fmtNum(manaPerSecond)}\n`;
142
+ }
143
+ if (filter === 3 || filter === 0) {
144
+ pretty += `${INDENT2}Instructions executed: ${fmtNum(enqueuedCall.totalInstructions)}\n`;
145
+ }
146
+ if (enqueuedCall.reverted) {
147
+ pretty += `${INDENT2}Reverted!\n`;
148
+ }
149
+ }
150
+ return pretty;
151
+ }
152
+ toJSON(indent = 2) {
153
+ return JSON.stringify(Object.fromEntries(this.txMetrics.entries()), null, indent);
154
+ }
155
+ }
156
+ function fmtNum(num, unit) {
157
+ return `\`${num.toLocaleString()}${unit ? ` ${unit}` : ''}\``;
158
+ }