@aztec/simulator 3.0.0-canary.a9708bd → 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_memory_types.d.ts +6 -0
- package/dest/public/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/public/avm/avm_memory_types.js +9 -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 +33 -16
- 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_memory_types.ts +11 -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 +46 -39
- 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,49 @@
|
|
|
1
|
+
import { FunctionType, emptyContractArtifact, emptyFunctionArtifact } from '@aztec/stdlib/abi';
|
|
2
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
+
|
|
4
|
+
import type { PublicTxResult } from '../public_tx_simulator/public_tx_simulator.js';
|
|
5
|
+
import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* Test custom bytecode (simulation or proving) with the provided bytecode.
|
|
10
|
+
* @param bytecode - The bytecode buffer to use
|
|
11
|
+
* @param tester - The tester to use (simulation or proving)
|
|
12
|
+
* @param txLabel - The label of the transaction
|
|
13
|
+
* @param contractName - The name of the contract (default: 'CustomBytecodeContract')
|
|
14
|
+
*/
|
|
15
|
+
export async function testCustomBytecode(
|
|
16
|
+
bytecode: Buffer,
|
|
17
|
+
tester: PublicTxSimulationTester,
|
|
18
|
+
txLabel: string,
|
|
19
|
+
contractName: string = 'CustomBytecodeContract',
|
|
20
|
+
): Promise<PublicTxResult> {
|
|
21
|
+
const deployer = AztecAddress.fromNumber(42);
|
|
22
|
+
|
|
23
|
+
const contractArtifact = emptyContractArtifact();
|
|
24
|
+
contractArtifact.name = contractName;
|
|
25
|
+
contractArtifact.functions = [emptyFunctionArtifact()];
|
|
26
|
+
contractArtifact.functions[0].name = 'public_dispatch';
|
|
27
|
+
contractArtifact.functions[0].functionType = FunctionType.PUBLIC;
|
|
28
|
+
contractArtifact.functions[0].bytecode = bytecode;
|
|
29
|
+
|
|
30
|
+
const testContract = await tester.registerAndDeployContract(
|
|
31
|
+
/*constructorArgs=*/ [],
|
|
32
|
+
deployer,
|
|
33
|
+
/*contractArtifact=*/ contractArtifact,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// EXECUTE! This means that if using AvmProvingTester subclass, it will PROVE the transaction!
|
|
37
|
+
return await tester.executeTxWithLabel(
|
|
38
|
+
/*txLabel=*/ txLabel,
|
|
39
|
+
/*sender=*/ deployer,
|
|
40
|
+
/*setupCalls=*/ [],
|
|
41
|
+
/*appCalls=*/ [
|
|
42
|
+
{
|
|
43
|
+
address: testContract.address,
|
|
44
|
+
fnName: 'public_dispatch',
|
|
45
|
+
args: [],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -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
|
}
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
StateReference,
|
|
28
28
|
Tx,
|
|
29
29
|
TxExecutionPhase,
|
|
30
|
-
type TxValidator,
|
|
31
30
|
makeProcessedTxFromPrivateOnlyTx,
|
|
32
31
|
makeProcessedTxFromTxWithPublicCalls,
|
|
33
32
|
} from '@aztec/stdlib/tx';
|
|
@@ -41,8 +40,14 @@ import {
|
|
|
41
40
|
} from '@aztec/telemetry-client';
|
|
42
41
|
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
43
42
|
|
|
43
|
+
import { AssertionError } from 'assert';
|
|
44
|
+
|
|
44
45
|
import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
|
|
45
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
type PublicTxSimulator,
|
|
48
|
+
type PublicTxSimulatorConfig,
|
|
49
|
+
TelemetryPublicTxSimulator,
|
|
50
|
+
} from '../public_tx_simulator/index.js';
|
|
46
51
|
import { GuardedMerkleTreeOperations } from './guarded_merkle_tree.js';
|
|
47
52
|
import { PublicProcessorMetrics } from './public_processor_metrics.js';
|
|
48
53
|
|
|
@@ -58,7 +63,6 @@ export class PublicProcessorFactory {
|
|
|
58
63
|
|
|
59
64
|
/**
|
|
60
65
|
* Creates a new instance of a PublicProcessor.
|
|
61
|
-
* @param historicalHeader - The header of a block previous to the one in which the tx is included.
|
|
62
66
|
* @param globalVariables - The global variables for the block being processed.
|
|
63
67
|
* @param skipFeeEnforcement - Allows disabling balance checks for fee estimations.
|
|
64
68
|
* @returns A new instance of a PublicProcessor.
|
|
@@ -66,20 +70,23 @@ export class PublicProcessorFactory {
|
|
|
66
70
|
public create(
|
|
67
71
|
merkleTree: MerkleTreeWriteOperations,
|
|
68
72
|
globalVariables: GlobalVariables,
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
config: {
|
|
74
|
+
skipFeeEnforcement: boolean;
|
|
75
|
+
clientInitiatedSimulation: boolean;
|
|
76
|
+
proverId?: Fr;
|
|
77
|
+
maxDebugLogMemoryReads?: number;
|
|
78
|
+
},
|
|
71
79
|
): PublicProcessor {
|
|
72
80
|
const contractsDB = new PublicContractsDB(this.contractDataSource);
|
|
73
81
|
|
|
74
82
|
const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
|
|
75
|
-
const publicTxSimulator = this.createPublicTxSimulator(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
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
|
+
});
|
|
83
90
|
|
|
84
91
|
return new PublicProcessor(
|
|
85
92
|
globalVariables,
|
|
@@ -95,19 +102,9 @@ export class PublicProcessorFactory {
|
|
|
95
102
|
merkleTree: MerkleTreeWriteOperations,
|
|
96
103
|
contractsDB: PublicContractsDB,
|
|
97
104
|
globalVariables: GlobalVariables,
|
|
98
|
-
|
|
99
|
-
skipFeeEnforcement: boolean,
|
|
100
|
-
clientInitiatedSimulation: boolean,
|
|
105
|
+
config?: Partial<PublicTxSimulatorConfig>,
|
|
101
106
|
): PublicTxSimulator {
|
|
102
|
-
return new TelemetryPublicTxSimulator(
|
|
103
|
-
merkleTree,
|
|
104
|
-
contractsDB,
|
|
105
|
-
globalVariables,
|
|
106
|
-
doMerkleOperations,
|
|
107
|
-
skipFeeEnforcement,
|
|
108
|
-
clientInitiatedSimulation,
|
|
109
|
-
this.telemetryClient,
|
|
110
|
-
);
|
|
107
|
+
return new TelemetryPublicTxSimulator(merkleTree, contractsDB, globalVariables, this.telemetryClient, config);
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
110
|
|
|
@@ -154,7 +151,7 @@ export class PublicProcessor implements Traceable {
|
|
|
154
151
|
limits: PublicProcessorLimits = {},
|
|
155
152
|
validator: PublicProcessorValidator = {},
|
|
156
153
|
): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[]]> {
|
|
157
|
-
const { maxTransactions, maxBlockSize, deadline, maxBlockGas } = limits;
|
|
154
|
+
const { maxTransactions, maxBlockSize, deadline, maxBlockGas, maxBlobFields } = limits;
|
|
158
155
|
const { preprocessValidator, nullifierCache } = validator;
|
|
159
156
|
const result: ProcessedTx[] = [];
|
|
160
157
|
const usedTxs: Tx[] = [];
|
|
@@ -165,6 +162,7 @@ export class PublicProcessor implements Traceable {
|
|
|
165
162
|
let returns: NestedProcessReturnValues[] = [];
|
|
166
163
|
let totalPublicGas = new Gas(0, 0);
|
|
167
164
|
let totalBlockGas = new Gas(0, 0);
|
|
165
|
+
let totalBlobFields = 0;
|
|
168
166
|
|
|
169
167
|
for await (const origTx of txs) {
|
|
170
168
|
// Only process up to the max tx limit
|
|
@@ -252,6 +250,23 @@ export class PublicProcessor implements Traceable {
|
|
|
252
250
|
continue;
|
|
253
251
|
}
|
|
254
252
|
|
|
253
|
+
// If the actual blob fields of this tx would exceed the limit, skip it
|
|
254
|
+
const txBlobFields = processedTx.txEffect.toBlobFields().length;
|
|
255
|
+
if (maxBlobFields !== undefined && totalBlobFields + txBlobFields > maxBlobFields) {
|
|
256
|
+
this.log.debug(
|
|
257
|
+
`Skipping processed tx ${txHash} with ${txBlobFields} blob fields due to max blob fields limit.`,
|
|
258
|
+
{
|
|
259
|
+
txHash,
|
|
260
|
+
txBlobFields,
|
|
261
|
+
totalBlobFields,
|
|
262
|
+
maxBlobFields,
|
|
263
|
+
},
|
|
264
|
+
);
|
|
265
|
+
// Need to revert the checkpoint here and don't go any further
|
|
266
|
+
await checkpoint.revert();
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
|
|
255
270
|
// FIXME(fcarreiro): it's ugly to have to notify the validator of nullifiers.
|
|
256
271
|
// I'd rather pass the validators the processedTx as well and let them deal with it.
|
|
257
272
|
nullifierCache?.addNullifiers(processedTx.txEffect.nullifiers.map(n => n.toBuffer()));
|
|
@@ -262,6 +277,7 @@ export class PublicProcessor implements Traceable {
|
|
|
262
277
|
totalPublicGas = totalPublicGas.add(processedTx.gasUsed.publicGas);
|
|
263
278
|
totalBlockGas = totalBlockGas.add(processedTx.gasUsed.totalGas);
|
|
264
279
|
totalSizeInBytes += txSize;
|
|
280
|
+
totalBlobFields += txBlobFields;
|
|
265
281
|
} catch (err: any) {
|
|
266
282
|
if (err?.name === 'PublicProcessorTimeoutError') {
|
|
267
283
|
this.log.warn(`Stopping tx processing due to timeout.`);
|
|
@@ -292,7 +308,7 @@ export class PublicProcessor implements Traceable {
|
|
|
292
308
|
// Roll back state to start of TX before proceeding to next TX
|
|
293
309
|
await checkpoint.revert();
|
|
294
310
|
await this.guardedMerkleTree.getUnderlyingFork().revertAllCheckpoints();
|
|
295
|
-
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
311
|
+
const errorMessage = err instanceof Error || err instanceof AssertionError ? err.message : 'Unknown error';
|
|
296
312
|
this.log.warn(`Failed to process tx ${txHash.toString()}: ${errorMessage} ${err?.stack}`);
|
|
297
313
|
failed.push({ tx, error: err instanceof Error ? err : new Error(errorMessage) });
|
|
298
314
|
returns.push(new NestedProcessReturnValues([]));
|
|
@@ -366,10 +382,7 @@ export class PublicProcessor implements Traceable {
|
|
|
366
382
|
return [processedTx, returnValues ?? []];
|
|
367
383
|
}
|
|
368
384
|
|
|
369
|
-
private async doTreeInsertionsForPrivateOnlyTx(
|
|
370
|
-
processedTx: ProcessedTx,
|
|
371
|
-
txValidator?: TxValidator<ProcessedTx>,
|
|
372
|
-
): Promise<void> {
|
|
385
|
+
private async doTreeInsertionsForPrivateOnlyTx(processedTx: ProcessedTx): Promise<void> {
|
|
373
386
|
const treeInsertionStart = process.hrtime.bigint();
|
|
374
387
|
|
|
375
388
|
// Update the state so that the next tx in the loop has the correct .startState
|
|
@@ -388,14 +401,8 @@ export class PublicProcessor implements Traceable {
|
|
|
388
401
|
padArrayEnd(processedTx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
389
402
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
390
403
|
);
|
|
391
|
-
} catch {
|
|
392
|
-
|
|
393
|
-
// Ideally the validator has already caught this above, but just in case:
|
|
394
|
-
throw new Error(`Transaction ${processedTx.hash} invalid after processing public functions`);
|
|
395
|
-
} else {
|
|
396
|
-
// We have no validator and assume this call should blindly process txs with duplicates being caught later
|
|
397
|
-
this.log.warn(`Detected duplicate nullifier after public processing for: ${processedTx.hash}.`);
|
|
398
|
-
}
|
|
404
|
+
} catch (cause) {
|
|
405
|
+
throw new Error(`Transaction ${processedTx.hash} failed with duplicate nullifiers`, { cause });
|
|
399
406
|
}
|
|
400
407
|
|
|
401
408
|
const treeInsertionEnd = process.hrtime.bigint();
|