@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.
- package/README.md +6 -0
- package/dest/private/acvm/oracle/oracle.d.ts +1 -1
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +1 -3
- package/dest/public/avm/avm_contract_call_result.d.ts +4 -2
- package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.js +9 -5
- package/dest/public/avm/avm_machine_state.d.ts +2 -0
- package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/public/avm/avm_machine_state.js +2 -0
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +5 -6
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +1 -2
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +1 -2
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +0 -5
- package/dest/public/avm/fixtures/index.d.ts +1 -0
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +1 -1
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +3 -2
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -1
- package/dest/public/avm/fixtures/simple_contract_data_source.js +30 -6
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +2 -0
- package/dest/public/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/public/avm/opcodes/memory.js +8 -10
- package/dest/public/avm/serialization/instruction_serialization.d.ts +5 -2
- package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/public/avm/serialization/instruction_serialization.js +23 -3
- package/dest/public/executor_metrics.d.ts +11 -3
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +40 -6
- package/dest/public/executor_metrics_interface.d.ts +10 -0
- package/dest/public/executor_metrics_interface.d.ts.map +1 -0
- package/dest/public/executor_metrics_interface.js +1 -0
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +12 -6
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +39 -19
- package/dest/public/hinting_db_sources.d.ts +26 -3
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +102 -1
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_db_sources.d.ts +2 -3
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +26 -16
- package/dest/public/public_processor/public_processor.d.ts +1 -1
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +3 -3
- package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts +9 -0
- package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/apps_tests/amm_test.js +237 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts +7 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.js +109 -0
- package/dest/public/public_tx_simulator/index.d.ts +3 -0
- package/dest/public/public_tx_simulator/index.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/index.js +2 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +23 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +58 -0
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +2 -2
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +9 -7
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +16 -16
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +24 -64
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +19 -0
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +39 -0
- package/dest/public/test_executor_metrics.d.ts +43 -0
- package/dest/public/test_executor_metrics.d.ts.map +1 -0
- package/dest/public/test_executor_metrics.js +158 -0
- package/package.json +14 -14
- package/src/private/acvm/oracle/oracle.ts +2 -2
- package/src/public/avm/avm_contract_call_result.ts +15 -3
- package/src/public/avm/avm_machine_state.ts +5 -0
- package/src/public/avm/avm_simulator.ts +18 -7
- package/src/public/avm/fixtures/avm_simulation_tester.ts +1 -1
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -7
- package/src/public/avm/fixtures/index.ts +1 -1
- package/src/public/avm/fixtures/simple_contract_data_source.ts +33 -6
- package/src/public/avm/opcodes/external_calls.ts +3 -0
- package/src/public/avm/opcodes/memory.ts +8 -10
- package/src/public/avm/serialization/instruction_serialization.ts +22 -5
- package/src/public/executor_metrics.ts +54 -6
- package/src/public/executor_metrics_interface.ts +15 -0
- package/src/public/fixtures/public_tx_simulation_tester.ts +74 -18
- package/src/public/hinting_db_sources.ts +184 -3
- package/src/public/index.ts +1 -1
- package/src/public/public_db_sources.ts +36 -23
- package/src/public/public_processor/public_processor.ts +4 -4
- package/src/public/public_tx_simulator/apps_tests/amm_test.ts +316 -0
- package/src/public/public_tx_simulator/apps_tests/token_test.ts +138 -0
- package/src/public/public_tx_simulator/index.ts +2 -0
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +111 -0
- package/src/public/public_tx_simulator/public_tx_context.ts +9 -13
- package/src/public/public_tx_simulator/public_tx_simulator.ts +31 -76
- package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +62 -0
- 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.
|
|
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.
|
|
64
|
-
"@aztec/foundation": "0.82.
|
|
65
|
-
"@aztec/noir-acvm_js": "0.82.
|
|
66
|
-
"@aztec/noir-noirc_abi": "0.82.
|
|
67
|
-
"@aztec/noir-protocol-circuits-types": "0.82.
|
|
68
|
-
"@aztec/noir-types": "0.82.
|
|
69
|
-
"@aztec/protocol-contracts": "0.82.
|
|
70
|
-
"@aztec/stdlib": "0.82.
|
|
71
|
-
"@aztec/telemetry-client": "0.82.
|
|
72
|
-
"@aztec/world-state": "0.82.
|
|
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.
|
|
81
|
-
"@aztec/merkle-tree": "0.82.
|
|
82
|
-
"@aztec/noir-contracts.js": "0.82.
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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 {
|
|
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)
|
|
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
|
|
90
|
+
return this.contractArtifacts.get(contractInstance!.currentContractClassId.toString());
|
|
77
91
|
}
|
|
78
92
|
|
|
79
|
-
getDebugFunctionName(
|
|
80
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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[]):
|
|
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
|
|
170
|
-
const opType = op;
|
|
175
|
+
for (const opType of operands) {
|
|
171
176
|
const [sizeBytes, reader, _writer] = OPERAND_SPEC.get(opType)!;
|
|
172
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
+
}
|