@aztec/simulator 2.1.0-rc.9 → 3.0.0-devnet.2
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/dest/private/acvm_native.d.ts +1 -2
- package/dest/private/acvm_native.d.ts.map +1 -1
- package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts +1 -1
- package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts.map +1 -1
- package/dest/public/avm/avm_execution_environment.d.ts +2 -1
- package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/public/avm/avm_execution_environment.js +5 -2
- package/dest/public/avm/avm_gas.js +2 -2
- package/dest/public/avm/avm_simulator.d.ts +1 -1
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +14 -21
- package/dest/public/avm/errors.d.ts +5 -14
- package/dest/public/avm/errors.d.ts.map +1 -1
- package/dest/public/avm/errors.js +7 -20
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +2 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +2 -3
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +2 -0
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +22 -0
- package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
- package/dest/public/avm/fixtures/initializers.js +2 -2
- package/dest/public/avm/opcodes/accrued_substate.d.ts +2 -2
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +7 -7
- package/dest/public/avm/opcodes/addressing_mode.d.ts.map +1 -1
- package/dest/public/avm/opcodes/addressing_mode.js +2 -3
- package/dest/public/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/public/avm/opcodes/conversion.js +3 -0
- package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/public/avm/opcodes/ec_add.js +3 -2
- package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/public/avm/opcodes/environment_getters.js +5 -7
- package/dest/public/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/public/avm/opcodes/instruction.js +5 -6
- package/dest/public/avm/opcodes/misc.d.ts +2 -1
- package/dest/public/avm/opcodes/misc.d.ts.map +1 -1
- package/dest/public/avm/opcodes/misc.js +28 -8
- package/dest/public/avm/serialization/instruction_serialization.d.ts +8 -0
- package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/public/avm/serialization/instruction_serialization.js +10 -0
- package/dest/public/avm/test_utils.d.ts +2 -2
- package/dest/public/avm/test_utils.d.ts.map +1 -1
- package/dest/public/avm/test_utils.js +6 -9
- package/dest/public/fixtures/bulk_test.d.ts.map +1 -1
- package/dest/public/fixtures/bulk_test.js +63 -130
- package/dest/public/fixtures/custom_bytecode_tester.d.ts +12 -0
- package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -0
- package/dest/public/fixtures/custom_bytecode_tester.js +29 -0
- package/dest/public/fixtures/custom_bytecode_tests.d.ts +9 -0
- package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -0
- package/dest/public/fixtures/custom_bytecode_tests.js +109 -0
- package/dest/public/fixtures/index.d.ts +2 -1
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +2 -1
- package/dest/public/fixtures/minimal_public_tx.d.ts +2 -1
- package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -1
- package/dest/public/fixtures/minimal_public_tx.js +8 -22
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +4 -2
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +11 -6
- package/dest/public/fixtures/utils.js +1 -1
- package/dest/public/hinting_db_sources.d.ts +2 -0
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +3 -0
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/public_db_sources.d.ts +2 -2
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +11 -1
- package/dest/public/public_errors.d.ts +12 -0
- package/dest/public/public_errors.d.ts.map +1 -0
- package/dest/public/public_errors.js +13 -0
- package/dest/public/public_processor/guarded_merkle_tree.d.ts +2 -0
- package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
- package/dest/public/public_processor/guarded_merkle_tree.js +3 -0
- package/dest/public/public_processor/public_processor.d.ts +9 -4
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +12 -6
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +41 -0
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +89 -0
- package/dest/public/public_tx_simulator/index.d.ts +1 -0
- package/dest/public/public_tx_simulator/index.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +5 -4
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +3 -4
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +4 -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 +12 -8
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +24 -11
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +112 -44
- package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +9 -0
- package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/public_tx_simulator_interface.js +1 -0
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +2 -1
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +2 -2
- package/dest/public/side_effect_errors.d.ts +41 -1
- package/dest/public/side_effect_errors.d.ts.map +1 -1
- package/dest/public/side_effect_errors.js +70 -1
- package/dest/public/side_effect_trace.d.ts +11 -4
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +35 -20
- package/dest/public/side_effect_trace_interface.d.ts +6 -0
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/state_manager/nullifiers.d.ts +0 -3
- package/dest/public/state_manager/nullifiers.d.ts.map +1 -1
- package/dest/public/state_manager/nullifiers.js +1 -6
- package/dest/public/state_manager/state_manager.d.ts +7 -2
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +54 -15
- package/package.json +21 -17
- package/src/private/acvm_native.ts +1 -2
- package/src/private/circuit_recording/simulator_recorder_wrapper.ts +1 -1
- package/src/public/avm/avm_execution_environment.ts +4 -1
- package/src/public/avm/avm_gas.ts +2 -2
- package/src/public/avm/avm_simulator.ts +16 -27
- package/src/public/avm/errors.ts +7 -24
- package/src/public/avm/fixtures/avm_simulation_tester.ts +4 -2
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +32 -0
- package/src/public/avm/fixtures/initializers.ts +2 -1
- package/src/public/avm/opcodes/accrued_substate.ts +4 -4
- package/src/public/avm/opcodes/addressing_mode.ts +3 -3
- package/src/public/avm/opcodes/conversion.ts +4 -0
- package/src/public/avm/opcodes/ec_add.ts +3 -2
- package/src/public/avm/opcodes/environment_getters.ts +6 -8
- package/src/public/avm/opcodes/instruction.ts +8 -6
- package/src/public/avm/opcodes/misc.ts +41 -7
- package/src/public/avm/serialization/instruction_serialization.ts +12 -0
- package/src/public/avm/test_utils.ts +6 -14
- package/src/public/fixtures/bulk_test.ts +41 -23
- package/src/public/fixtures/custom_bytecode_tester.ts +49 -0
- package/src/public/fixtures/custom_bytecode_tests.ts +135 -0
- package/src/public/fixtures/index.ts +2 -1
- package/src/public/fixtures/minimal_public_tx.ts +8 -31
- package/src/public/fixtures/public_tx_simulation_tester.ts +16 -12
- package/src/public/fixtures/utils.ts +1 -1
- package/src/public/hinting_db_sources.ts +5 -0
- package/src/public/index.ts +6 -1
- package/src/public/public_db_sources.ts +19 -3
- package/src/public/public_errors.ts +14 -0
- package/src/public/public_processor/guarded_merkle_tree.ts +4 -0
- package/src/public/public_processor/public_processor.ts +23 -25
- package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +128 -0
- package/src/public/public_tx_simulator/index.ts +1 -0
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +12 -9
- package/src/public/public_tx_simulator/public_tx_context.ts +11 -4
- package/src/public/public_tx_simulator/public_tx_simulator.ts +178 -60
- package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +11 -0
- package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +3 -12
- package/src/public/side_effect_errors.ts +91 -1
- package/src/public/side_effect_trace.ts +48 -23
- package/src/public/side_effect_trace_interface.ts +6 -0
- package/src/public/state_manager/nullifiers.ts +1 -7
- package/src/public/state_manager/state_manager.ts +73 -25
- package/dest/public/bytecode_errors.d.ts +0 -4
- package/dest/public/bytecode_errors.d.ts.map +0 -1
- package/dest/public/bytecode_errors.js +0 -6
- package/src/public/bytecode_errors.ts +0 -6
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { strict as assert } from 'assert';
|
|
2
|
+
|
|
3
|
+
import { TypeTag } from '../avm/avm_memory_types.js';
|
|
4
|
+
import { Addressing, AddressingMode } from '../avm/opcodes/addressing_mode.js';
|
|
5
|
+
import { CalldataCopy, Jump, Return, Set } from '../avm/opcodes/index.js';
|
|
6
|
+
import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
|
|
7
|
+
import {
|
|
8
|
+
MAX_OPCODE_VALUE,
|
|
9
|
+
Opcode,
|
|
10
|
+
OperandType,
|
|
11
|
+
getOperandSize,
|
|
12
|
+
} from '../avm/serialization/instruction_serialization.js';
|
|
13
|
+
import { testCustomBytecode } from './custom_bytecode_tester.js';
|
|
14
|
+
import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
|
|
15
|
+
|
|
16
|
+
// First instruction resolved a base address (offset 0) which is uninitialized and therefore
|
|
17
|
+
// of invalid tag (FF). This will trigger an exceptional halt.
|
|
18
|
+
export async function addressingWithBaseTagIssueTest(isIndirect: boolean, tester: PublicTxSimulationTester) {
|
|
19
|
+
const addressingMode = Addressing.fromModes([
|
|
20
|
+
isIndirect ? AddressingMode.INDIRECT_RELATIVE : AddressingMode.RELATIVE,
|
|
21
|
+
AddressingMode.DIRECT,
|
|
22
|
+
AddressingMode.DIRECT,
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const bytecode = encodeToBytecode([
|
|
26
|
+
new CalldataCopy(/*indirect=*/ addressingMode.toWire(), /*copySize=*/ 1, /*cdOffset=*/ 0, /*dstOffset=*/ 0),
|
|
27
|
+
new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
const txLabel = isIndirect ? 'AddressingWithBaseTagInvalidIndirect' : 'AddressingWithBaseTagInvalidDirect';
|
|
31
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function pcOutOfRangeTest(tester: PublicTxSimulationTester) {
|
|
35
|
+
const bytecode = encodeToBytecode([
|
|
36
|
+
new Jump(/*jumpOffset=*/ 123), // Jump to out-of-range pc offset.
|
|
37
|
+
new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
const txLabel = 'PcOutOfRange';
|
|
41
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function invalidOpcodeTest(tester: PublicTxSimulationTester) {
|
|
45
|
+
let bytecode = encodeToBytecode([
|
|
46
|
+
new Set(/*indirect=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
const offsetReturnOpcodeByte = bytecode.length;
|
|
50
|
+
|
|
51
|
+
bytecode = Buffer.concat([
|
|
52
|
+
bytecode,
|
|
53
|
+
encodeToBytecode([new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0)]),
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
// Manipulate the Return opcode to make the opcode invalid (out of range).
|
|
57
|
+
bytecode[offsetReturnOpcodeByte] = MAX_OPCODE_VALUE + 1; // opcode is invalid.
|
|
58
|
+
|
|
59
|
+
const txLabel = 'InvalidOpcode';
|
|
60
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Single invalid byte in the bytecode.
|
|
64
|
+
export async function invalidByteTest(tester: PublicTxSimulationTester) {
|
|
65
|
+
const invalidOpcode = MAX_OPCODE_VALUE + 7;
|
|
66
|
+
assert(invalidOpcode < 256, 'Invalid opcode must fit in a single byte');
|
|
67
|
+
const bytecode = Buffer.from([invalidOpcode]);
|
|
68
|
+
|
|
69
|
+
const txLabel = 'InvalidByte';
|
|
70
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Truncate the last instruction in the bytecode.
|
|
74
|
+
export async function instructionTruncatedTest(tester: PublicTxSimulationTester) {
|
|
75
|
+
let bytecode = encodeToBytecode([
|
|
76
|
+
new Set(/*indirect=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
// Truncate the bytecode.
|
|
80
|
+
bytecode = bytecode.subarray(0, -1);
|
|
81
|
+
|
|
82
|
+
const txLabel = 'InstructionTruncated';
|
|
83
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Invalid tag value byte in an instruction.
|
|
87
|
+
export async function invalidTagValueTest(tester: PublicTxSimulationTester) {
|
|
88
|
+
const bytecode = encodeToBytecode([
|
|
89
|
+
new Set(/*indirect=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
|
|
90
|
+
new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
|
|
91
|
+
]);
|
|
92
|
+
|
|
93
|
+
const tagOffset = getTagOffsetInInstruction(Set.wireFormat8);
|
|
94
|
+
assert(bytecode[tagOffset].valueOf() == TypeTag.UINT32.valueOf(), 'Set instruction tag should be UINT32 in test');
|
|
95
|
+
bytecode[tagOffset] = TypeTag.INVALID;
|
|
96
|
+
|
|
97
|
+
const txLabel = 'InvalidTagValue';
|
|
98
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Combine an invalid tag in the last instruction that is truncated.
|
|
102
|
+
export async function invalidTagValueAndInstructionTruncatedTest(tester: PublicTxSimulationTester) {
|
|
103
|
+
let bytecode = encodeToBytecode([
|
|
104
|
+
// Important: value argument must be a bigint otherwise a type error will be thrown.
|
|
105
|
+
new Set(/*indirect=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT128, /*value=*/ 0n).as(Opcode.SET_128, Set.wireFormat128),
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
// Truncate the bytecode.
|
|
109
|
+
bytecode = bytecode.subarray(0, -5);
|
|
110
|
+
const tagOffset = getTagOffsetInInstruction(Set.wireFormat128);
|
|
111
|
+
assert(bytecode[tagOffset].valueOf() == TypeTag.UINT128.valueOf(), 'Set instruction tag should be UINT128 in test');
|
|
112
|
+
bytecode[tagOffset] = 0x6f; // Invalid tag value.
|
|
113
|
+
|
|
114
|
+
const txLabel = 'InvalidTagValueAndInstructionTruncated';
|
|
115
|
+
return await testCustomBytecode(bytecode, tester, txLabel);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Returns the offset of the tag in an instruction.
|
|
120
|
+
* @details Loops over the wire format operand type entries until it finds the tag.
|
|
121
|
+
* Returns the byte offset of the tag based on each operand size that is passed.
|
|
122
|
+
*
|
|
123
|
+
* @param wireFormat array of operand types
|
|
124
|
+
* @returns byte offset of the tag
|
|
125
|
+
*/
|
|
126
|
+
function getTagOffsetInInstruction(wireFormat: OperandType[]): number {
|
|
127
|
+
let offset = 0;
|
|
128
|
+
for (const operand of wireFormat) {
|
|
129
|
+
if (operand === OperandType.TAG) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
offset += getOperandSize(operand);
|
|
133
|
+
}
|
|
134
|
+
return offset;
|
|
135
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export * from './public_tx_simulation_tester.js';
|
|
2
2
|
export * from './utils.js';
|
|
3
3
|
export * from './simple_contract_data_source.js';
|
|
4
|
-
export { readAvmMinimalPublicTxInputsFromFile,
|
|
4
|
+
export { readAvmMinimalPublicTxInputsFromFile, executeAvmMinimalPublicTx } from './minimal_public_tx.js';
|
|
5
5
|
export { TestExecutorMetrics } from '../test_executor_metrics.js';
|
|
6
6
|
export { ammTest } from './amm_test.js';
|
|
7
7
|
export { bulkTest, megaBulkTest } from './bulk_test.js';
|
|
8
8
|
export { tokenTest } from './token_test.js';
|
|
9
|
+
export * from './custom_bytecode_tests.js';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { FunctionType, emptyContractArtifact, emptyFunctionArtifact } from '@aztec/stdlib/abi';
|
|
2
1
|
import { AvmCircuitInputs } from '@aztec/stdlib/avm';
|
|
3
|
-
import {
|
|
2
|
+
import { ProtocolContracts } from '@aztec/stdlib/tx';
|
|
4
3
|
|
|
5
4
|
import avmMinimalCircuitInputsJson from '../../../artifacts/avm_minimal_inputs.json' with { type: 'json' };
|
|
6
5
|
import { TypeTag } from '../avm/avm_memory_types.js';
|
|
@@ -8,13 +7,10 @@ import { Add, Return, Set } from '../avm/opcodes/index.js';
|
|
|
8
7
|
import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
|
|
9
8
|
import { Opcode } from '../avm/serialization/instruction_serialization.js';
|
|
10
9
|
import type { PublicTxResult } from '../public_tx_simulator/public_tx_simulator.js';
|
|
10
|
+
import { testCustomBytecode } from './custom_bytecode_tester.js';
|
|
11
11
|
import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
|
|
12
12
|
|
|
13
|
-
export async function
|
|
14
|
-
const deployer = AztecAddress.fromNumber(42);
|
|
15
|
-
|
|
16
|
-
const simTester = await PublicTxSimulationTester.create();
|
|
17
|
-
|
|
13
|
+
export async function executeAvmMinimalPublicTx(tester: PublicTxSimulationTester): Promise<PublicTxResult> {
|
|
18
14
|
const minimalBytecode = encodeToBytecode([
|
|
19
15
|
new Set(/*indirect*/ 0, /*dstOffset*/ 0, TypeTag.UINT32, /*value*/ 1).as(Opcode.SET_8, Set.wireFormat8),
|
|
20
16
|
new Set(/*indirect*/ 0, /*dstOffset*/ 1, TypeTag.UINT32, /*value*/ 2).as(Opcode.SET_8, Set.wireFormat8),
|
|
@@ -22,32 +18,13 @@ export async function createAvmMinimalPublicTx(): Promise<PublicTxResult> {
|
|
|
22
18
|
new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 2),
|
|
23
19
|
]);
|
|
24
20
|
|
|
25
|
-
const
|
|
26
|
-
minimalContractArtifact.name = 'MinimalContract';
|
|
27
|
-
minimalContractArtifact.functions = [emptyFunctionArtifact()];
|
|
28
|
-
minimalContractArtifact.functions[0].name = 'public_dispatch';
|
|
29
|
-
minimalContractArtifact.functions[0].functionType = FunctionType.PUBLIC;
|
|
30
|
-
minimalContractArtifact.functions[0].bytecode = minimalBytecode;
|
|
21
|
+
const result = await testCustomBytecode(minimalBytecode, tester, 'MinimalTx', 'AvmMinimalContract');
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/*contractArtifact=*/ minimalContractArtifact,
|
|
36
|
-
);
|
|
23
|
+
// Modify the protocol contracts to be all zeros
|
|
24
|
+
result.avmProvingRequest.inputs.hints.protocolContracts = ProtocolContracts.empty();
|
|
25
|
+
result.avmProvingRequest.inputs.publicInputs.protocolContracts = ProtocolContracts.empty();
|
|
37
26
|
|
|
38
|
-
return
|
|
39
|
-
/*sender=*/ deployer,
|
|
40
|
-
/*setupCalls=*/ [],
|
|
41
|
-
/*appCalls=*/ [
|
|
42
|
-
{
|
|
43
|
-
address: minimalTestContract.address,
|
|
44
|
-
fnName: 'public_dispatch',
|
|
45
|
-
args: [],
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
/*teardownCall=*/ undefined,
|
|
49
|
-
/*feePayer=*/ deployer,
|
|
50
|
-
);
|
|
27
|
+
return result;
|
|
51
28
|
}
|
|
52
29
|
|
|
53
30
|
/**
|
|
@@ -16,8 +16,10 @@ import {
|
|
|
16
16
|
getFunctionSelector,
|
|
17
17
|
} from '../avm/fixtures/utils.js';
|
|
18
18
|
import { PublicContractsDB } from '../public_db_sources.js';
|
|
19
|
+
import { MeasuredCppPublicTxSimulatorHintedDbs } from '../public_tx_simulator/cpp_public_tx_simulator.js';
|
|
19
20
|
import { MeasuredPublicTxSimulator } from '../public_tx_simulator/measured_public_tx_simulator.js';
|
|
20
21
|
import type { PublicTxResult } from '../public_tx_simulator/public_tx_simulator.js';
|
|
22
|
+
import type { MeasuredPublicTxSimulatorInterface } from '../public_tx_simulator/public_tx_simulator_interface.js';
|
|
21
23
|
import { TestExecutorMetrics } from '../test_executor_metrics.js';
|
|
22
24
|
import { SimpleContractDataSource } from './simple_contract_data_source.js';
|
|
23
25
|
import { type TestPrivateInsertions, createTxForPublicCalls } from './utils.js';
|
|
@@ -40,7 +42,7 @@ export type TestEnqueuedCall = {
|
|
|
40
42
|
*/
|
|
41
43
|
export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
42
44
|
protected txCount: number = 0;
|
|
43
|
-
private simulator:
|
|
45
|
+
private simulator: MeasuredPublicTxSimulatorInterface;
|
|
44
46
|
private metricsPrefix?: string;
|
|
45
47
|
|
|
46
48
|
constructor(
|
|
@@ -48,28 +50,30 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
|
48
50
|
contractDataSource: SimpleContractDataSource,
|
|
49
51
|
globals: GlobalVariables = defaultGlobals(),
|
|
50
52
|
private metrics: TestExecutorMetrics = new TestExecutorMetrics(),
|
|
53
|
+
useCppSimulator: boolean = false,
|
|
51
54
|
) {
|
|
52
55
|
super(contractDataSource, merkleTree);
|
|
53
56
|
|
|
54
57
|
const contractsDB = new PublicContractsDB(contractDataSource);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.metrics,
|
|
63
|
-
);
|
|
58
|
+
const config = {
|
|
59
|
+
doMerkleOperations: true,
|
|
60
|
+
skipFeeEnforcement: false,
|
|
61
|
+
clientInitiatedSimulation: true,
|
|
62
|
+
};
|
|
63
|
+
this.simulator = useCppSimulator
|
|
64
|
+
? new MeasuredCppPublicTxSimulatorHintedDbs(merkleTree, contractsDB, globals, this.metrics, config)
|
|
65
|
+
: new MeasuredPublicTxSimulator(merkleTree, contractsDB, globals, this.metrics, config);
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
public static async create(
|
|
69
|
+
worldStateService: NativeWorldStateService, // make sure to close this later
|
|
67
70
|
globals: GlobalVariables = defaultGlobals(),
|
|
68
71
|
metrics: TestExecutorMetrics = new TestExecutorMetrics(),
|
|
72
|
+
useCppSimulator = false,
|
|
69
73
|
): Promise<PublicTxSimulationTester> {
|
|
70
74
|
const contractDataSource = new SimpleContractDataSource();
|
|
71
|
-
const merkleTree = await
|
|
72
|
-
return new PublicTxSimulationTester(merkleTree, contractDataSource, globals, metrics);
|
|
75
|
+
const merkleTree = await worldStateService.fork();
|
|
76
|
+
return new PublicTxSimulationTester(merkleTree, contractDataSource, globals, metrics, useCppSimulator);
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
public setMetricsPrefix(prefix: string) {
|
|
@@ -153,7 +153,7 @@ export async function createTxForPublicCalls(
|
|
|
153
153
|
|
|
154
154
|
return await Tx.create({
|
|
155
155
|
data: txData,
|
|
156
|
-
clientIvcProof: ClientIvcProof.
|
|
156
|
+
clientIvcProof: ClientIvcProof.random(),
|
|
157
157
|
contractClassLogFields: [],
|
|
158
158
|
publicFunctionCalldata: calldata,
|
|
159
159
|
});
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
} from '@aztec/stdlib/trees';
|
|
41
41
|
import { TreeSnapshots } from '@aztec/stdlib/tx';
|
|
42
42
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
43
|
+
import type { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
43
44
|
|
|
44
45
|
import { strict as assert } from 'assert';
|
|
45
46
|
|
|
@@ -449,6 +450,10 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
|
|
|
449
450
|
return this.db.getInitialHeader();
|
|
450
451
|
}
|
|
451
452
|
|
|
453
|
+
public getRevision(): WorldStateRevision {
|
|
454
|
+
return this.db.getRevision();
|
|
455
|
+
}
|
|
456
|
+
|
|
452
457
|
public async updateArchive(header: any): Promise<void> {
|
|
453
458
|
return await this.db.updateArchive(header);
|
|
454
459
|
}
|
package/src/public/index.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export { PublicContractsDB } from './public_db_sources.js';
|
|
2
2
|
export { GuardedMerkleTreeOperations } from './public_processor/guarded_merkle_tree.js';
|
|
3
3
|
export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js';
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
PublicTxSimulator,
|
|
6
|
+
type PublicTxSimulatorConfig,
|
|
7
|
+
TelemetryPublicTxSimulator,
|
|
8
|
+
type PublicTxResult,
|
|
9
|
+
} from './public_tx_simulator/index.js';
|
|
5
10
|
export { getCallRequestsWithCalldataByPhase } from './utils.js';
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
L1_TO_L2_MSG_TREE_LEAF_COUNT,
|
|
3
|
+
NOTE_HASH_TREE_LEAF_COUNT,
|
|
4
|
+
NULLIFIER_SUBTREE_HEIGHT,
|
|
5
|
+
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
6
|
+
} from '@aztec/constants';
|
|
2
7
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
9
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -27,7 +32,10 @@ import {
|
|
|
27
32
|
import { TreeSnapshots, type Tx } from '@aztec/stdlib/tx';
|
|
28
33
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
29
34
|
|
|
35
|
+
import { strict as assert } from 'assert';
|
|
36
|
+
|
|
30
37
|
import type { PublicContractsDBInterface, PublicStateDBInterface } from './db_interfaces.js';
|
|
38
|
+
import { L1ToL2MessageIndexOutOfRangeError, NoteHashIndexOutOfRangeError } from './side_effect_errors.js';
|
|
31
39
|
import { TxContractCache } from './tx_contract_cache.js';
|
|
32
40
|
|
|
33
41
|
/**
|
|
@@ -323,9 +331,13 @@ export class PublicTreesDB implements PublicStateDBInterface {
|
|
|
323
331
|
} satisfies PublicDBAccessStats);
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
public async getL1ToL2LeafValue(leafIndex: bigint): Promise<Fr
|
|
334
|
+
public async getL1ToL2LeafValue(leafIndex: bigint): Promise<Fr> {
|
|
327
335
|
const timer = new Timer();
|
|
336
|
+
if (leafIndex > L1_TO_L2_MSG_TREE_LEAF_COUNT) {
|
|
337
|
+
throw new L1ToL2MessageIndexOutOfRangeError(Number(leafIndex));
|
|
338
|
+
}
|
|
328
339
|
const leafValue = await this.db.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
340
|
+
assert(leafValue !== undefined, 'Unexpected null response from l1 to l2 message tree');
|
|
329
341
|
// TODO: We need this for the hints. See class comment for more details.
|
|
330
342
|
await this.db.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
331
343
|
|
|
@@ -337,9 +349,13 @@ export class PublicTreesDB implements PublicStateDBInterface {
|
|
|
337
349
|
return leafValue;
|
|
338
350
|
}
|
|
339
351
|
|
|
340
|
-
public async getNoteHash(leafIndex: bigint): Promise<Fr
|
|
352
|
+
public async getNoteHash(leafIndex: bigint): Promise<Fr> {
|
|
341
353
|
const timer = new Timer();
|
|
354
|
+
if (leafIndex > NOTE_HASH_TREE_LEAF_COUNT) {
|
|
355
|
+
throw new NoteHashIndexOutOfRangeError(Number(leafIndex));
|
|
356
|
+
}
|
|
342
357
|
const leafValue = await this.db.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
358
|
+
assert(leafValue !== undefined, 'Unexpected null response from note hash tree');
|
|
343
359
|
// TODO: We need this for the hints. See class comment for more details.
|
|
344
360
|
await this.db.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
345
361
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Any known (and checked) error that can be thrown during public execution.
|
|
3
|
+
* Includes AvmExecutionErrors and SideEffectErrors.
|
|
4
|
+
*
|
|
5
|
+
* AvmSimulator catches any checked errors before returning a boolean "reverted".
|
|
6
|
+
* Unchecked errors are generally the result of a bug. They are propagated and
|
|
7
|
+
* ultimately will be the resonsibility of PublicProcessor to handle.
|
|
8
|
+
*/
|
|
9
|
+
export abstract class CheckedPublicExecutionError extends Error {
|
|
10
|
+
constructor(message: string) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'CheckedPublicExecutionError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TreeInfo,
|
|
12
12
|
} from '@aztec/stdlib/trees';
|
|
13
13
|
import type { BlockHeader, StateReference } from '@aztec/stdlib/tx';
|
|
14
|
+
import type { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Wraps an instance of `MerkleTreeWriteOperations` to allow the sequencer to gate access.
|
|
@@ -88,6 +89,9 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
|
|
|
88
89
|
getInitialHeader(): BlockHeader {
|
|
89
90
|
return this.target.getInitialHeader();
|
|
90
91
|
}
|
|
92
|
+
public getRevision(): WorldStateRevision {
|
|
93
|
+
return this.target.getRevision();
|
|
94
|
+
}
|
|
91
95
|
getSiblingPath<ID extends MerkleTreeId>(treeId: ID, index: bigint): Promise<SiblingPath<TreeHeights[ID]>> {
|
|
92
96
|
return this.guardAndPush(() => this.target.getSiblingPath(treeId, index));
|
|
93
97
|
}
|
|
@@ -40,8 +40,14 @@ import {
|
|
|
40
40
|
} from '@aztec/telemetry-client';
|
|
41
41
|
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
42
42
|
|
|
43
|
+
import { AssertionError } from 'assert';
|
|
44
|
+
|
|
43
45
|
import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
|
|
44
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
type PublicTxSimulator,
|
|
48
|
+
type PublicTxSimulatorConfig,
|
|
49
|
+
TelemetryPublicTxSimulator,
|
|
50
|
+
} from '../public_tx_simulator/index.js';
|
|
45
51
|
import { GuardedMerkleTreeOperations } from './guarded_merkle_tree.js';
|
|
46
52
|
import { PublicProcessorMetrics } from './public_processor_metrics.js';
|
|
47
53
|
|
|
@@ -57,7 +63,6 @@ export class PublicProcessorFactory {
|
|
|
57
63
|
|
|
58
64
|
/**
|
|
59
65
|
* Creates a new instance of a PublicProcessor.
|
|
60
|
-
* @param historicalHeader - The header of a block previous to the one in which the tx is included.
|
|
61
66
|
* @param globalVariables - The global variables for the block being processed.
|
|
62
67
|
* @param skipFeeEnforcement - Allows disabling balance checks for fee estimations.
|
|
63
68
|
* @returns A new instance of a PublicProcessor.
|
|
@@ -65,20 +70,23 @@ export class PublicProcessorFactory {
|
|
|
65
70
|
public create(
|
|
66
71
|
merkleTree: MerkleTreeWriteOperations,
|
|
67
72
|
globalVariables: GlobalVariables,
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
config: {
|
|
74
|
+
skipFeeEnforcement: boolean;
|
|
75
|
+
clientInitiatedSimulation: boolean;
|
|
76
|
+
proverId?: Fr;
|
|
77
|
+
maxDebugLogMemoryReads?: number;
|
|
78
|
+
},
|
|
70
79
|
): PublicProcessor {
|
|
71
80
|
const contractsDB = new PublicContractsDB(this.contractDataSource);
|
|
72
81
|
|
|
73
82
|
const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
|
|
74
|
-
const publicTxSimulator = this.createPublicTxSimulator(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
);
|
|
83
|
+
const publicTxSimulator = this.createPublicTxSimulator(guardedFork, contractsDB, globalVariables, {
|
|
84
|
+
proverId: config.proverId,
|
|
85
|
+
doMerkleOperations: true,
|
|
86
|
+
skipFeeEnforcement: config.skipFeeEnforcement,
|
|
87
|
+
clientInitiatedSimulation: config.clientInitiatedSimulation,
|
|
88
|
+
maxDebugLogMemoryReads: config.maxDebugLogMemoryReads,
|
|
89
|
+
});
|
|
82
90
|
|
|
83
91
|
return new PublicProcessor(
|
|
84
92
|
globalVariables,
|
|
@@ -94,19 +102,9 @@ export class PublicProcessorFactory {
|
|
|
94
102
|
merkleTree: MerkleTreeWriteOperations,
|
|
95
103
|
contractsDB: PublicContractsDB,
|
|
96
104
|
globalVariables: GlobalVariables,
|
|
97
|
-
|
|
98
|
-
skipFeeEnforcement: boolean,
|
|
99
|
-
clientInitiatedSimulation: boolean,
|
|
105
|
+
config?: Partial<PublicTxSimulatorConfig>,
|
|
100
106
|
): PublicTxSimulator {
|
|
101
|
-
return new TelemetryPublicTxSimulator(
|
|
102
|
-
merkleTree,
|
|
103
|
-
contractsDB,
|
|
104
|
-
globalVariables,
|
|
105
|
-
doMerkleOperations,
|
|
106
|
-
skipFeeEnforcement,
|
|
107
|
-
clientInitiatedSimulation,
|
|
108
|
-
this.telemetryClient,
|
|
109
|
-
);
|
|
107
|
+
return new TelemetryPublicTxSimulator(merkleTree, contractsDB, globalVariables, this.telemetryClient, config);
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
110
|
|
|
@@ -310,7 +308,7 @@ export class PublicProcessor implements Traceable {
|
|
|
310
308
|
// Roll back state to start of TX before proceeding to next TX
|
|
311
309
|
await checkpoint.revert();
|
|
312
310
|
await this.guardedMerkleTree.getUnderlyingFork().revertAllCheckpoints();
|
|
313
|
-
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
311
|
+
const errorMessage = err instanceof Error || err instanceof AssertionError ? err.message : 'Unknown error';
|
|
314
312
|
this.log.warn(`Failed to process tx ${txHash.toString()}: ${errorMessage} ${err?.stack}`);
|
|
315
313
|
failed.push({ tx, error: err instanceof Error ? err : new Error(errorMessage) });
|
|
316
314
|
returns.push(new NestedProcessReturnValues([]));
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { avmSimulateWithHintedDbs } from '@aztec/native';
|
|
3
|
+
import { deserializeFromMessagePack } from '@aztec/stdlib/avm';
|
|
4
|
+
import { SimulationError } from '@aztec/stdlib/errors';
|
|
5
|
+
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
|
|
6
|
+
import type { GlobalVariables, Tx } from '@aztec/stdlib/tx';
|
|
7
|
+
|
|
8
|
+
import type { ExecutorMetricsInterface } from '../executor_metrics_interface.js';
|
|
9
|
+
import type { PublicContractsDB } from '../public_db_sources.js';
|
|
10
|
+
import { type PublicTxResult, PublicTxSimulator, type PublicTxSimulatorConfig } from './public_tx_simulator.js';
|
|
11
|
+
import type {
|
|
12
|
+
MeasuredPublicTxSimulatorInterface,
|
|
13
|
+
PublicTxSimulatorInterface,
|
|
14
|
+
} from './public_tx_simulator_interface.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* C++ implementation of PublicTxSimulator using pre-collected hints.
|
|
18
|
+
* This implementation runs TS simulation first to collect all hints,
|
|
19
|
+
* then passes the complete AvmCircuitInputs (hints + public inputs)
|
|
20
|
+
* to C++ to run hinted simulation.
|
|
21
|
+
*/
|
|
22
|
+
export class CppPublicTxSimulatorHintedDbs extends PublicTxSimulator implements PublicTxSimulatorInterface {
|
|
23
|
+
protected override log: Logger;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
merkleTree: MerkleTreeWriteOperations,
|
|
27
|
+
contractsDB: PublicContractsDB,
|
|
28
|
+
globalVariables: GlobalVariables,
|
|
29
|
+
config?: Partial<PublicTxSimulatorConfig>,
|
|
30
|
+
) {
|
|
31
|
+
super(merkleTree, contractsDB, globalVariables, config);
|
|
32
|
+
this.log = createLogger(`simulator:cpp_public_tx_simulator_hinted_dbs`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Simulate a transaction's public portion using the C++ vm2 simulator with hinted DBs.
|
|
37
|
+
*
|
|
38
|
+
* This implementation:
|
|
39
|
+
* 1. Runs the full TypeScript simulation to generate AvmCircuitInputs (hints + public inputs)
|
|
40
|
+
* 2. Passes the complete AvmCircuitInputs to C++ to run hinted simulation
|
|
41
|
+
*
|
|
42
|
+
* @param tx - The transaction to simulate.
|
|
43
|
+
* @returns The result of the transaction's public execution.
|
|
44
|
+
*/
|
|
45
|
+
public override async simulate(tx: Tx): Promise<PublicTxResult> {
|
|
46
|
+
const txHash = this.computeTxHash(tx);
|
|
47
|
+
this.log.debug(`C++ hinted DB simulation of ${tx.publicFunctionCalldata.length} public calls for tx ${txHash}`, {
|
|
48
|
+
txHash,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// First, run TS simulation to generate hints and public inputs
|
|
52
|
+
this.log.debug(`Running TS simulation for tx ${txHash}`);
|
|
53
|
+
|
|
54
|
+
let tsResult: PublicTxResult;
|
|
55
|
+
try {
|
|
56
|
+
// Run the full TypeScript simulation using the parent class
|
|
57
|
+
// This will modify the merkle tree with the transaction's state changes
|
|
58
|
+
tsResult = await super.simulate(tx);
|
|
59
|
+
this.log.debug(`TS simulation succeeded for tx ${txHash}`);
|
|
60
|
+
} catch (error: any) {
|
|
61
|
+
// If TS simulation fails, clear any partial contract additions and re-throw the error
|
|
62
|
+
this.contractsDB.clearContractsForTx();
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Extract the full AvmCircuitInputs from the TS result
|
|
67
|
+
const avmCircuitInputs = tsResult.avmProvingRequest.inputs;
|
|
68
|
+
|
|
69
|
+
// Second, run C++ simulation with hinted DBs
|
|
70
|
+
this.log.debug(`Running C++ simulation with hinted DBs for tx ${txHash}`);
|
|
71
|
+
|
|
72
|
+
// Serialize to msgpack and call the C++ simulator
|
|
73
|
+
const inputBuffer = avmCircuitInputs.serializeWithMessagePack();
|
|
74
|
+
|
|
75
|
+
let resultBuffer: Buffer;
|
|
76
|
+
try {
|
|
77
|
+
resultBuffer = await avmSimulateWithHintedDbs(inputBuffer);
|
|
78
|
+
} catch (error: any) {
|
|
79
|
+
throw new SimulationError(`C++ hinted simulation failed: ${error.message}`, []);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Deserialize the msgpack result
|
|
83
|
+
const _success = deserializeFromMessagePack<boolean>(resultBuffer);
|
|
84
|
+
|
|
85
|
+
this.log.debug(`C++ hinted simulation completed for tx ${txHash}`, {
|
|
86
|
+
txHash,
|
|
87
|
+
reverted: !tsResult.revertCode.isOK(),
|
|
88
|
+
tsGasUsed: tsResult.gasUsed.totalGas.l2Gas,
|
|
89
|
+
cppGasUsed: tsResult.gasUsed.totalGas.l2Gas,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// TODO(dbanks12): C++ should return PublicTxResult (or something similar)
|
|
93
|
+
return tsResult;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Class to record metrics for simulation.
|
|
99
|
+
*
|
|
100
|
+
* Note(dbanks12): We might not be able to collect all the same metrics in C++ as we do in TS!
|
|
101
|
+
* Unless we move some of the metrics collection to C++, we don't have inner functions exposed
|
|
102
|
+
* to TS for tracking.
|
|
103
|
+
*/
|
|
104
|
+
export class MeasuredCppPublicTxSimulatorHintedDbs
|
|
105
|
+
extends CppPublicTxSimulatorHintedDbs
|
|
106
|
+
implements MeasuredPublicTxSimulatorInterface
|
|
107
|
+
{
|
|
108
|
+
constructor(
|
|
109
|
+
merkleTree: MerkleTreeWriteOperations,
|
|
110
|
+
contractsDB: PublicContractsDB,
|
|
111
|
+
globalVariables: GlobalVariables,
|
|
112
|
+
protected readonly metrics: ExecutorMetricsInterface,
|
|
113
|
+
config?: Partial<PublicTxSimulatorConfig>,
|
|
114
|
+
) {
|
|
115
|
+
super(merkleTree, contractsDB, globalVariables, config);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public override async simulate(tx: Tx, txLabel: string = 'unlabeledTx'): Promise<PublicTxResult> {
|
|
119
|
+
this.metrics.startRecordingTxSimulation(txLabel);
|
|
120
|
+
let result: PublicTxResult | undefined;
|
|
121
|
+
try {
|
|
122
|
+
result = await super.simulate(tx);
|
|
123
|
+
} finally {
|
|
124
|
+
this.metrics.stopRecordingTxSimulation(txLabel, result?.revertCode);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -10,22 +10,26 @@ import type { ExecutorMetricsInterface } from '../executor_metrics_interface.js'
|
|
|
10
10
|
import type { PublicContractsDB } from '../public_db_sources.js';
|
|
11
11
|
import type { PublicPersistableStateManager } from '../state_manager/state_manager.js';
|
|
12
12
|
import { PublicTxContext } from './public_tx_context.js';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
type ProcessedPhase,
|
|
15
|
+
type PublicTxResult,
|
|
16
|
+
PublicTxSimulator,
|
|
17
|
+
type PublicTxSimulatorConfig,
|
|
18
|
+
} from './public_tx_simulator.js';
|
|
19
|
+
import type { MeasuredPublicTxSimulatorInterface } from './public_tx_simulator_interface.js';
|
|
14
20
|
|
|
15
21
|
/**
|
|
16
22
|
* A public tx simulator that tracks miscellaneous simulation metrics without telemetry.
|
|
17
23
|
*/
|
|
18
|
-
export class MeasuredPublicTxSimulator extends PublicTxSimulator {
|
|
24
|
+
export class MeasuredPublicTxSimulator extends PublicTxSimulator implements MeasuredPublicTxSimulatorInterface {
|
|
19
25
|
constructor(
|
|
20
26
|
merkleTree: MerkleTreeWriteOperations,
|
|
21
27
|
contractsDB: PublicContractsDB,
|
|
22
28
|
globalVariables: GlobalVariables,
|
|
23
|
-
doMerkleOperations: boolean = false,
|
|
24
|
-
skipFeeEnforcement: boolean = false,
|
|
25
|
-
clientInitiatedSimulation: boolean = false,
|
|
26
29
|
protected readonly metrics: ExecutorMetricsInterface,
|
|
30
|
+
config?: Partial<PublicTxSimulatorConfig>,
|
|
27
31
|
) {
|
|
28
|
-
super(merkleTree, contractsDB, globalVariables,
|
|
32
|
+
super(merkleTree, contractsDB, globalVariables, config);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
public override async simulate(tx: Tx, txLabel: string = 'unlabeledTx'): Promise<PublicTxResult> {
|
|
@@ -45,11 +49,10 @@ export class MeasuredPublicTxSimulator extends PublicTxSimulator {
|
|
|
45
49
|
this.metrics.recordPrivateEffectsInsertion(timer.us(), 'non-revertible');
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
protected override async insertRevertiblesFromPrivate(context: PublicTxContext, tx: Tx)
|
|
52
|
+
protected override async insertRevertiblesFromPrivate(context: PublicTxContext, tx: Tx) {
|
|
49
53
|
const timer = new Timer();
|
|
50
|
-
|
|
54
|
+
await super.insertRevertiblesFromPrivate(context, tx);
|
|
51
55
|
this.metrics.recordPrivateEffectsInsertion(timer.us(), 'revertible');
|
|
52
|
-
return result;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
protected override async simulatePhase(phase: TxExecutionPhase, context: PublicTxContext): Promise<ProcessedPhase> {
|