@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
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
2
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
1
|
+
import { FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/constants';
|
|
3
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
5
|
import { PublicDataUpdateRequest } from '@aztec/stdlib/avm';
|
|
7
6
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
8
7
|
import { NoteHash, Nullifier } from '@aztec/stdlib/kernel';
|
|
9
|
-
import { PublicLog } from '@aztec/stdlib/logs';
|
|
8
|
+
import { DebugLog, PublicLog } from '@aztec/stdlib/logs';
|
|
10
9
|
import { L2ToL1Message } from '@aztec/stdlib/messaging';
|
|
11
10
|
import { strict as assert } from 'assert';
|
|
12
|
-
import { SideEffectLimitReachedError } from './side_effect_errors.js';
|
|
11
|
+
import { L2ToL1MessageLimitReachedError, MaxCallsToUniqueContractClassIdsError, NoteHashLimitReachedError, NullifierLimitReachedError, SideEffectLimitReachedError } from './side_effect_errors.js';
|
|
13
12
|
import { UniqueClassIds } from './unique_class_ids.js';
|
|
14
13
|
export class SideEffectArrayLengths {
|
|
15
14
|
publicDataWrites;
|
|
@@ -17,14 +16,14 @@ export class SideEffectArrayLengths {
|
|
|
17
16
|
noteHashes;
|
|
18
17
|
nullifiers;
|
|
19
18
|
l2ToL1Msgs;
|
|
20
|
-
|
|
21
|
-
constructor(publicDataWrites, protocolPublicDataWrites, noteHashes, nullifiers, l2ToL1Msgs,
|
|
19
|
+
publicLogFields;
|
|
20
|
+
constructor(publicDataWrites, protocolPublicDataWrites, noteHashes, nullifiers, l2ToL1Msgs, publicLogFields){
|
|
22
21
|
this.publicDataWrites = publicDataWrites;
|
|
23
22
|
this.protocolPublicDataWrites = protocolPublicDataWrites;
|
|
24
23
|
this.noteHashes = noteHashes;
|
|
25
24
|
this.nullifiers = nullifiers;
|
|
26
25
|
this.l2ToL1Msgs = l2ToL1Msgs;
|
|
27
|
-
this.
|
|
26
|
+
this.publicLogFields = publicLogFields;
|
|
28
27
|
}
|
|
29
28
|
static empty() {
|
|
30
29
|
return new this(0, 0, 0, 0, 0, 0);
|
|
@@ -37,6 +36,8 @@ export class SideEffectArrayLengths {
|
|
|
37
36
|
previousSideEffectArrayLengths;
|
|
38
37
|
uniqueClassIds;
|
|
39
38
|
writtenPublicDataSlots;
|
|
39
|
+
debugLogs;
|
|
40
|
+
debugLogMemoryReads;
|
|
40
41
|
log;
|
|
41
42
|
/** The side effect counter increments with every call to the trace. */ sideEffectCounter;
|
|
42
43
|
publicDataWrites;
|
|
@@ -49,11 +50,13 @@ export class SideEffectArrayLengths {
|
|
|
49
50
|
/** Make sure a forked trace is never merged twice. */ alreadyMergedIntoParent;
|
|
50
51
|
constructor(/** The counter of this trace's first side effect. */ startSideEffectCounter = 0, /** Track parent's (or previous kernel's) lengths so the AVM can properly enforce TX-wide limits,
|
|
51
52
|
* otherwise the public kernel can fail to prove because TX limits are breached.
|
|
52
|
-
*/ previousSideEffectArrayLengths = SideEffectArrayLengths.empty(), /** We need to track the set of class IDs used, to enforce limits. */ uniqueClassIds = new UniqueClassIds(), writtenPublicDataSlots = new Set()){
|
|
53
|
+
*/ previousSideEffectArrayLengths = SideEffectArrayLengths.empty(), /** We need to track the set of class IDs used, to enforce limits. */ uniqueClassIds = new UniqueClassIds(), writtenPublicDataSlots = new Set(), debugLogs = [], debugLogMemoryReads = 0){
|
|
53
54
|
this.startSideEffectCounter = startSideEffectCounter;
|
|
54
55
|
this.previousSideEffectArrayLengths = previousSideEffectArrayLengths;
|
|
55
56
|
this.uniqueClassIds = uniqueClassIds;
|
|
56
57
|
this.writtenPublicDataSlots = writtenPublicDataSlots;
|
|
58
|
+
this.debugLogs = debugLogs;
|
|
59
|
+
this.debugLogMemoryReads = debugLogMemoryReads;
|
|
57
60
|
this.log = createLogger('simulator:side_effect_trace');
|
|
58
61
|
this.publicDataWrites = [];
|
|
59
62
|
this.protocolPublicDataWritesLength = 0;
|
|
@@ -66,7 +69,7 @@ export class SideEffectArrayLengths {
|
|
|
66
69
|
this.sideEffectCounter = startSideEffectCounter;
|
|
67
70
|
}
|
|
68
71
|
fork() {
|
|
69
|
-
return new SideEffectTrace(this.sideEffectCounter, new SideEffectArrayLengths(this.previousSideEffectArrayLengths.publicDataWrites + this.userPublicDataWritesLength, this.previousSideEffectArrayLengths.protocolPublicDataWrites + this.protocolPublicDataWritesLength, this.previousSideEffectArrayLengths.noteHashes + this.noteHashes.length, this.previousSideEffectArrayLengths.nullifiers + this.nullifiers.length, this.previousSideEffectArrayLengths.l2ToL1Msgs + this.l2ToL1Messages.length, this.previousSideEffectArrayLengths.
|
|
72
|
+
return new SideEffectTrace(this.sideEffectCounter, new SideEffectArrayLengths(this.previousSideEffectArrayLengths.publicDataWrites + this.userPublicDataWritesLength, this.previousSideEffectArrayLengths.protocolPublicDataWrites + this.protocolPublicDataWritesLength, this.previousSideEffectArrayLengths.noteHashes + this.noteHashes.length, this.previousSideEffectArrayLengths.nullifiers + this.nullifiers.length, this.previousSideEffectArrayLengths.l2ToL1Msgs + this.l2ToL1Messages.length, this.previousSideEffectArrayLengths.publicLogFields + this.publicLogs.reduce((acc, log)=>acc + log.sizeInFields(), 0)), this.uniqueClassIds.fork(), new Set(this.writtenPublicDataSlots), this.debugLogs.slice(), this.debugLogMemoryReads);
|
|
70
73
|
}
|
|
71
74
|
merge(forkedTrace, reverted = false) {
|
|
72
75
|
// sanity check to avoid merging the same forked trace twice
|
|
@@ -74,6 +77,8 @@ export class SideEffectArrayLengths {
|
|
|
74
77
|
forkedTrace.alreadyMergedIntoParent = true;
|
|
75
78
|
this.sideEffectCounter = forkedTrace.sideEffectCounter;
|
|
76
79
|
this.uniqueClassIds.acceptAndMerge(forkedTrace.uniqueClassIds);
|
|
80
|
+
this.debugLogs = forkedTrace.debugLogs;
|
|
81
|
+
this.debugLogMemoryReads = forkedTrace.debugLogMemoryReads;
|
|
77
82
|
if (!reverted) {
|
|
78
83
|
this.publicDataWrites.push(...forkedTrace.publicDataWrites);
|
|
79
84
|
this.noteHashes.push(...forkedTrace.noteHashes);
|
|
@@ -125,7 +130,7 @@ export class SideEffectArrayLengths {
|
|
|
125
130
|
}
|
|
126
131
|
traceNewNoteHash(noteHash) {
|
|
127
132
|
if (this.noteHashes.length + this.previousSideEffectArrayLengths.noteHashes >= MAX_NOTE_HASHES_PER_TX) {
|
|
128
|
-
throw new
|
|
133
|
+
throw new NoteHashLimitReachedError();
|
|
129
134
|
}
|
|
130
135
|
this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
|
|
131
136
|
this.log.trace(`Tracing new note hash (counter=${this.sideEffectCounter})`);
|
|
@@ -133,15 +138,15 @@ export class SideEffectArrayLengths {
|
|
|
133
138
|
}
|
|
134
139
|
traceNewNullifier(siloedNullifier) {
|
|
135
140
|
if (this.nullifiers.length + this.previousSideEffectArrayLengths.nullifiers >= MAX_NULLIFIERS_PER_TX) {
|
|
136
|
-
throw new
|
|
141
|
+
throw new NullifierLimitReachedError();
|
|
137
142
|
}
|
|
138
|
-
this.nullifiers.push(new Nullifier(siloedNullifier,
|
|
143
|
+
this.nullifiers.push(new Nullifier(siloedNullifier, /*noteHash=*/ Fr.ZERO, this.sideEffectCounter));
|
|
139
144
|
this.log.trace(`Tracing new nullifier (counter=${this.sideEffectCounter})`);
|
|
140
145
|
this.incrementSideEffectCounter();
|
|
141
146
|
}
|
|
142
147
|
traceNewL2ToL1Message(contractAddress, recipient, content) {
|
|
143
148
|
if (this.l2ToL1Messages.length + this.previousSideEffectArrayLengths.l2ToL1Msgs >= MAX_L2_TO_L1_MSGS_PER_TX) {
|
|
144
|
-
throw new
|
|
149
|
+
throw new L2ToL1MessageLimitReachedError();
|
|
145
150
|
}
|
|
146
151
|
const recipientAddress = EthAddress.fromField(recipient);
|
|
147
152
|
this.l2ToL1Messages.push(new L2ToL1Message(recipientAddress, content).scope(contractAddress));
|
|
@@ -149,23 +154,33 @@ export class SideEffectArrayLengths {
|
|
|
149
154
|
this.incrementSideEffectCounter();
|
|
150
155
|
}
|
|
151
156
|
tracePublicLog(contractAddress, log) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
throw new Error(`Emitted public log is too large, max: ${PUBLIC_LOG_SIZE_IN_FIELDS}, passed: ${log.length}`);
|
|
157
|
+
const previouslyEmittedPublicLogFieldsCount = this.previousSideEffectArrayLengths.publicLogFields + this.publicLogs.reduce((acc, log)=>acc + log.sizeInFields(), 0);
|
|
158
|
+
const publicLog = new PublicLog(contractAddress, log);
|
|
159
|
+
if (previouslyEmittedPublicLogFieldsCount + publicLog.sizeInFields() > FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH) {
|
|
160
|
+
throw new SideEffectLimitReachedError('public log fields', FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH);
|
|
157
161
|
}
|
|
158
|
-
const publicLog = new PublicLog(contractAddress, padArrayEnd(log, Fr.ZERO, PUBLIC_LOG_SIZE_IN_FIELDS), log.length);
|
|
159
162
|
this.publicLogs.push(publicLog);
|
|
160
163
|
this.log.trace(`Tracing new public log (counter=${this.sideEffectCounter})`);
|
|
161
164
|
this.incrementSideEffectCounter();
|
|
162
165
|
}
|
|
166
|
+
traceDebugLog(contractAddress, level, message, fields) {
|
|
167
|
+
this.debugLogs.push(new DebugLog(contractAddress, level, message, fields));
|
|
168
|
+
}
|
|
169
|
+
getDebugLogs() {
|
|
170
|
+
return this.debugLogs;
|
|
171
|
+
}
|
|
172
|
+
getDebugLogMemoryReads() {
|
|
173
|
+
return this.debugLogMemoryReads;
|
|
174
|
+
}
|
|
175
|
+
traceDebugLogMemoryReads(memoryReads) {
|
|
176
|
+
this.debugLogMemoryReads += memoryReads;
|
|
177
|
+
}
|
|
163
178
|
traceGetContractClass(contractClassId, exists) {
|
|
164
179
|
// We limit the number of unique contract class IDs due to hashing and the trace length limit.
|
|
165
180
|
if (exists && !this.uniqueClassIds.has(contractClassId.toString())) {
|
|
166
181
|
if (this.uniqueClassIds.size() >= MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS) {
|
|
167
182
|
this.log.debug(`Bytecode retrieval failure for contract class ID ${contractClassId} (limit reached)`);
|
|
168
|
-
throw new
|
|
183
|
+
throw new MaxCallsToUniqueContractClassIdsError();
|
|
169
184
|
}
|
|
170
185
|
this.log.trace(`Adding contract class ID ${contractClassId} (counter=${this.sideEffectCounter})`);
|
|
171
186
|
this.uniqueClassIds.add(contractClassId.toString());
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import type { LogLevel } from '@aztec/foundation/log';
|
|
2
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import type { DebugLog } from '@aztec/stdlib/logs';
|
|
3
5
|
export interface PublicSideEffectTraceInterface {
|
|
4
6
|
fork(): PublicSideEffectTraceInterface;
|
|
5
7
|
merge(nestedTrace: PublicSideEffectTraceInterface, reverted?: boolean): void;
|
|
@@ -12,6 +14,10 @@ export interface PublicSideEffectTraceInterface {
|
|
|
12
14
|
traceNewNullifier(siloedNullifier: Fr): void;
|
|
13
15
|
traceNewL2ToL1Message(contractAddress: AztecAddress, recipient: Fr, content: Fr): void;
|
|
14
16
|
tracePublicLog(contractAddress: AztecAddress, log: Fr[]): void;
|
|
17
|
+
traceDebugLog(contractAddress: AztecAddress, level: LogLevel, message: string, fields: Fr[]): void;
|
|
18
|
+
getDebugLogs(): DebugLog[];
|
|
19
|
+
getDebugLogMemoryReads(): number;
|
|
20
|
+
traceDebugLogMemoryReads(memoryReads: number): void;
|
|
15
21
|
traceGetContractClass(contractClassId: Fr, exists: boolean): void;
|
|
16
22
|
}
|
|
17
23
|
//# sourceMappingURL=side_effect_trace_interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"side_effect_trace_interface.d.ts","sourceRoot":"","sources":["../../src/public/side_effect_trace_interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"side_effect_trace_interface.d.ts","sourceRoot":"","sources":["../../src/public/side_effect_trace_interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,WAAW,8BAA8B;IAC7C,IAAI,IAAI,8BAA8B,CAAC;IACvC,KAAK,CAAC,WAAW,EAAE,8BAA8B,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7E,UAAU,IAAI,MAAM,CAAC;IAErB,uBAAuB,CACrB,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,EAAE,EAAE,sDAAsD;IAChE,KAAK,EAAE,EAAE,EACT,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC;IAChE,gBAAgB,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC;IAC3C,gBAAgB,IAAI,MAAM,CAAC;IAC3B,iBAAiB,CAAC,eAAe,EAAE,EAAE,GAAG,IAAI,CAAC;IAC7C,qBAAqB,CAAC,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC;IACvF,cAAc,CAAC,eAAe,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAC/D,aAAa,CAAC,eAAe,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IACnG,YAAY,IAAI,QAAQ,EAAE,CAAC;IAC3B,sBAAsB,IAAI,MAAM,CAAC;IACjC,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,qBAAqB,CAAC,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACnE"}
|
|
@@ -58,7 +58,4 @@ export declare class NullifierManager {
|
|
|
58
58
|
*/
|
|
59
59
|
acceptAndMerge(incomingNullifiers: NullifierManager): void;
|
|
60
60
|
}
|
|
61
|
-
export declare class NullifierCollisionError extends Error {
|
|
62
|
-
constructor(message: string, ...rest: any[]);
|
|
63
|
-
}
|
|
64
61
|
//# sourceMappingURL=nullifiers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../src/public/state_manager/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../src/public/state_manager/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,kCAAkC;IAClC,OAAO,CAAC,KAAK;IACb,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;;IALxB,+DAA+D;IAC9C,cAAc,EAAE,aAAa;IAC9C,kCAAkC;IAC1B,KAAK,GAAE,GAAG,CAAC,MAAM,CAAa;IACtC,+CAA+C;IAC9B,MAAM,CAAC,EAAE,gBAAgB,YAAA;IAG5C;;OAEG;IACI,IAAI;IAIX;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAW/B;;;;;;;;;;OAUG;IACU,WAAW,CAAC,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAmB9F;;;;OAIG;IACU,MAAM,CAAC,eAAe,EAAE,EAAE;IAQvC;;;;OAIG;IACI,cAAc,CAAC,kBAAkB,EAAE,gBAAgB;CAU3D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NullifierCollisionError } from '../side_effect_errors.js';
|
|
1
2
|
/**
|
|
2
3
|
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
3
4
|
* Maintains a siloed nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
@@ -89,9 +90,3 @@
|
|
|
89
90
|
]);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
|
-
export class NullifierCollisionError extends Error {
|
|
93
|
-
constructor(message, ...rest){
|
|
94
|
-
super(message, ...rest);
|
|
95
|
-
this.name = 'NullifierCollisionError';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { type LogLevel } from '@aztec/foundation/log';
|
|
2
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
-
import type { ContractClassPublicWithCommitment } from '@aztec/stdlib/contract';
|
|
4
4
|
import { SerializableContractInstance } from '@aztec/stdlib/contract';
|
|
5
|
+
import type { DebugLog } from '@aztec/stdlib/logs';
|
|
5
6
|
import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
|
|
6
7
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
7
8
|
import type { TreeSnapshots } from '@aztec/stdlib/tx';
|
|
@@ -131,6 +132,10 @@ export declare class PublicPersistableStateManager {
|
|
|
131
132
|
* @param l2ToL1Message - The L2 to L1 message to write.
|
|
132
133
|
*/
|
|
133
134
|
writeScopedL2ToL1Message(l2ToL1Message: ScopedL2ToL1Message): void;
|
|
135
|
+
writeDebugLog(contractAddress: AztecAddress, level: LogLevel, message: string, fields: Fr[]): void;
|
|
136
|
+
writeDebugLogMemoryReads(memoryReads: number): void;
|
|
137
|
+
getDebugLogMemoryReads(): number;
|
|
138
|
+
getLogs(): DebugLog[];
|
|
134
139
|
/**
|
|
135
140
|
* Write a public log
|
|
136
141
|
* @param contractAddress - address of the contract that emitted the log
|
|
@@ -149,7 +154,7 @@ export declare class PublicPersistableStateManager {
|
|
|
149
154
|
* @param classId - class id to retrieve.
|
|
150
155
|
* @returns the contract class or undefined if it does not exist.
|
|
151
156
|
*/
|
|
152
|
-
getContractClass
|
|
157
|
+
private getContractClass;
|
|
153
158
|
/**
|
|
154
159
|
* Get a contract's bytecode from the contracts DB, also trace the contract class and instance indirectly.
|
|
155
160
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state_manager.d.ts","sourceRoot":"","sources":["../../../src/public/state_manager/state_manager.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"state_manager.d.ts","sourceRoot":"","sources":["../../../src/public/state_manager/state_manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,8 @@ import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '
|
|
|
9
9
|
import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
10
10
|
import { strict as assert } from 'assert';
|
|
11
11
|
import { getPublicFunctionDebugName } from '../debug_fn_name.js';
|
|
12
|
-
import {
|
|
12
|
+
import { L1ToL2MessageIndexOutOfRangeError, MaxCallsToUniqueContractClassIdsError, NoteHashIndexOutOfRangeError, NullifierCollisionError } from '../side_effect_errors.js';
|
|
13
|
+
import { NullifierManager } from './nullifiers.js';
|
|
13
14
|
import { PublicStorage } from './public_storage.js';
|
|
14
15
|
/**
|
|
15
16
|
* A class to manage persistable AVM state for contract calls.
|
|
@@ -123,10 +124,19 @@ import { PublicStorage } from './public_storage.js';
|
|
|
123
124
|
* @param leafIndex - the leaf index being checked
|
|
124
125
|
* @returns true if the note hash exists at the given leaf index, false otherwise
|
|
125
126
|
*/ async checkNoteHashExists(contractAddress, noteHash, leafIndex) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
try {
|
|
128
|
+
const gotLeafValue = await this.treesDB.getNoteHash(leafIndex);
|
|
129
|
+
const exists = gotLeafValue.equals(noteHash);
|
|
130
|
+
this.log.trace(`noteHashes(${contractAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`);
|
|
131
|
+
return Promise.resolve(exists);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
// If the index is out of range, note_hash_leaf_in_range = 0 and the circuit returns false:
|
|
134
|
+
if (error instanceof NoteHashIndexOutOfRangeError) {
|
|
135
|
+
return Promise.resolve(false);
|
|
136
|
+
}
|
|
137
|
+
// Otherwise, unknown error. This is a bug.
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
130
140
|
}
|
|
131
141
|
/**
|
|
132
142
|
* Write a raw note hash, silo it and make it unique, then trace the write.
|
|
@@ -206,10 +216,19 @@ import { PublicStorage } from './public_storage.js';
|
|
|
206
216
|
* @param msgLeafIndex - the message leaf index to use in the check
|
|
207
217
|
* @returns exists - whether the message exists in the L1 to L2 Messages tree
|
|
208
218
|
*/ async checkL1ToL2MessageExists(msgHash, msgLeafIndex) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
try {
|
|
220
|
+
const valueAtIndex = await this.treesDB.getL1ToL2LeafValue(msgLeafIndex.toBigInt());
|
|
221
|
+
const exists = valueAtIndex.equals(msgHash);
|
|
222
|
+
this.log.trace(`l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`);
|
|
223
|
+
return Promise.resolve(exists);
|
|
224
|
+
} catch (error) {
|
|
225
|
+
// If the index is out of range, l1_to_l2_msg_leaf_in_range = 0 and the circuit returns false:
|
|
226
|
+
if (error instanceof L1ToL2MessageIndexOutOfRangeError) {
|
|
227
|
+
return Promise.resolve(false);
|
|
228
|
+
}
|
|
229
|
+
// Otherwise, unknown error. This is a bug.
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
213
232
|
}
|
|
214
233
|
/**
|
|
215
234
|
* Write an L2 to L1 message.
|
|
@@ -226,6 +245,18 @@ import { PublicStorage } from './public_storage.js';
|
|
|
226
245
|
*/ writeScopedL2ToL1Message(l2ToL1Message) {
|
|
227
246
|
this.writeL2ToL1Message(l2ToL1Message.contractAddress, l2ToL1Message.message.recipient.toField(), l2ToL1Message.message.content);
|
|
228
247
|
}
|
|
248
|
+
writeDebugLog(contractAddress, level, message, fields) {
|
|
249
|
+
this.trace.traceDebugLog(contractAddress, level, message, fields);
|
|
250
|
+
}
|
|
251
|
+
writeDebugLogMemoryReads(memoryReads) {
|
|
252
|
+
this.trace.traceDebugLogMemoryReads(memoryReads);
|
|
253
|
+
}
|
|
254
|
+
getDebugLogMemoryReads() {
|
|
255
|
+
return this.trace.getDebugLogMemoryReads();
|
|
256
|
+
}
|
|
257
|
+
getLogs() {
|
|
258
|
+
return this.trace.getDebugLogs();
|
|
259
|
+
}
|
|
229
260
|
/**
|
|
230
261
|
* Write a public log
|
|
231
262
|
* @param contractAddress - address of the contract that emitted the log
|
|
@@ -257,7 +288,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
257
288
|
return undefined;
|
|
258
289
|
}
|
|
259
290
|
this.log.trace(`Got contract instance (address=${contractAddress}): instance=${jsonStringify(instance)}`);
|
|
260
|
-
// All that is left is
|
|
291
|
+
// All that is left is to check that the contract updatability information is correct.
|
|
261
292
|
// That is, that the current and original contract class ids are correct.
|
|
262
293
|
await this.checkContractUpdateInformation(instanceWithAddress);
|
|
263
294
|
return instance;
|
|
@@ -276,7 +307,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
276
307
|
//
|
|
277
308
|
// However, we will also be checking the hash of the delayed public mutable values.
|
|
278
309
|
// This is a bit of a leak of information, since the circuit will use it to prove
|
|
279
|
-
// one public read
|
|
310
|
+
// one public read instead of N of the delayed public mutable values.
|
|
280
311
|
const { delayedPublicMutableSlot, delayedPublicMutableHashSlot } = await DelayedPublicMutableValuesWithHash.getContractUpdateSlots(instance.address);
|
|
281
312
|
const readDeployerStorage = async (storageSlot)=>await this.readStorage(ProtocolContractAddress.ContractInstanceRegistry, storageSlot);
|
|
282
313
|
const hash = await readDeployerStorage(delayedPublicMutableHashSlot);
|
|
@@ -319,7 +350,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
319
350
|
publicBytecodeCommitment: bytecodeCommitment
|
|
320
351
|
};
|
|
321
352
|
} else {
|
|
322
|
-
this.log.debug(`Contract
|
|
353
|
+
this.log.debug(`Contract class NOT FOUND (id=${classId})`);
|
|
323
354
|
}
|
|
324
355
|
// TODO(dbanks12): does this need to be moved to before the DB accesses as was done with writeNullifier?
|
|
325
356
|
this.trace.traceGetContractClass(classId, exists);
|
|
@@ -333,9 +364,17 @@ import { PublicStorage } from './public_storage.js';
|
|
|
333
364
|
if (!contractInstance) {
|
|
334
365
|
return undefined;
|
|
335
366
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
367
|
+
try {
|
|
368
|
+
const contractClass = await this.getContractClass(contractInstance.currentContractClassId);
|
|
369
|
+
assert(contractClass, `Contract class not found in DB, but a contract instance was found with this class ID (${contractInstance.currentContractClassId}). This should not happen!`);
|
|
370
|
+
return contractClass.packedBytecode;
|
|
371
|
+
} catch (error) {
|
|
372
|
+
if (error instanceof MaxCallsToUniqueContractClassIdsError) {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
// Otherwise, unknown error. This is a bug.
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
339
378
|
}
|
|
340
379
|
async getPublicFunctionDebugName(avmEnvironment) {
|
|
341
380
|
return await getPublicFunctionDebugName(this.contractsDB, avmEnvironment.address, avmEnvironment.calldata);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/simulator",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-devnet.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/server.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"build": "yarn clean && tsc -b",
|
|
21
21
|
"build:dev": "tsc -b --watch",
|
|
22
22
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
23
|
-
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
23
|
+
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}",
|
|
24
|
+
"build:fuzzer": "tsc scripts/fuzzing/avm_simulator_bin.ts --outDir dest/scripts/fuzzing --module commonjs --target es2022 --esModuleInterop --allowSyntheticDefaultImports --resolveJsonModule --skipLibCheck"
|
|
24
25
|
},
|
|
25
26
|
"inherits": [
|
|
26
27
|
"../package.common.json"
|
|
@@ -63,35 +64,38 @@
|
|
|
63
64
|
]
|
|
64
65
|
},
|
|
65
66
|
"dependencies": {
|
|
66
|
-
"@aztec/constants": "
|
|
67
|
-
"@aztec/foundation": "
|
|
68
|
-
"@aztec/
|
|
69
|
-
"@aztec/noir-
|
|
70
|
-
"@aztec/noir-
|
|
71
|
-
"@aztec/noir-types": "
|
|
72
|
-
"@aztec/
|
|
73
|
-
"@aztec/
|
|
74
|
-
"@aztec/
|
|
75
|
-
"@aztec/
|
|
67
|
+
"@aztec/constants": "3.0.0-devnet.2",
|
|
68
|
+
"@aztec/foundation": "3.0.0-devnet.2",
|
|
69
|
+
"@aztec/native": "3.0.0-devnet.2",
|
|
70
|
+
"@aztec/noir-acvm_js": "3.0.0-devnet.2",
|
|
71
|
+
"@aztec/noir-noirc_abi": "3.0.0-devnet.2",
|
|
72
|
+
"@aztec/noir-protocol-circuits-types": "3.0.0-devnet.2",
|
|
73
|
+
"@aztec/noir-types": "3.0.0-devnet.2",
|
|
74
|
+
"@aztec/protocol-contracts": "3.0.0-devnet.2",
|
|
75
|
+
"@aztec/stdlib": "3.0.0-devnet.2",
|
|
76
|
+
"@aztec/telemetry-client": "3.0.0-devnet.2",
|
|
77
|
+
"@aztec/world-state": "3.0.0-devnet.2",
|
|
76
78
|
"lodash.clonedeep": "^4.5.0",
|
|
77
79
|
"lodash.merge": "^4.6.2",
|
|
78
80
|
"tslib": "^2.4.0"
|
|
79
81
|
},
|
|
80
82
|
"devDependencies": {
|
|
81
|
-
"@aztec/kv-store": "
|
|
82
|
-
"@aztec/merkle-tree": "
|
|
83
|
-
"@aztec/noir-contracts.js": "
|
|
84
|
-
"@aztec/noir-test-contracts.js": "
|
|
83
|
+
"@aztec/kv-store": "3.0.0-devnet.2",
|
|
84
|
+
"@aztec/merkle-tree": "3.0.0-devnet.2",
|
|
85
|
+
"@aztec/noir-contracts.js": "3.0.0-devnet.2",
|
|
86
|
+
"@aztec/noir-test-contracts.js": "3.0.0-devnet.2",
|
|
85
87
|
"@jest/globals": "^30.0.0",
|
|
86
88
|
"@types/jest": "^30.0.0",
|
|
87
89
|
"@types/lodash.clonedeep": "^4.5.7",
|
|
88
90
|
"@types/lodash.merge": "^4.6.9",
|
|
89
91
|
"@types/node": "^22.15.17",
|
|
92
|
+
"istanbul-lib-hook": "^3.0.0",
|
|
93
|
+
"istanbul-lib-instrument": "^6.0.3",
|
|
90
94
|
"jest": "^30.0.0",
|
|
91
95
|
"jest-mock-extended": "^4.0.0",
|
|
92
96
|
"ts-node": "^10.9.1",
|
|
93
97
|
"typescript": "^5.3.3",
|
|
94
|
-
"viem": "2.
|
|
98
|
+
"viem": "npm:@spalladino/viem@2.38.2-eip7594.0"
|
|
95
99
|
},
|
|
96
100
|
"files": [
|
|
97
101
|
"dest",
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { runInDirectory } from '@aztec/foundation/fs';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { Timer } from '@aztec/foundation/timer';
|
|
4
|
-
import type { WitnessMap } from '@aztec/noir-acvm_js';
|
|
5
|
-
import type { ForeignCallHandler } from '@aztec/noir-protocol-circuits-types/types';
|
|
4
|
+
import type { ForeignCallHandler, WitnessMap } from '@aztec/noir-acvm_js';
|
|
6
5
|
import type { FunctionArtifactWithContractName } from '@aztec/stdlib/abi';
|
|
7
6
|
import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
|
|
8
7
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ForeignCallHandler } from '@aztec/noir-
|
|
1
|
+
import type { ForeignCallHandler } from '@aztec/noir-acvm_js';
|
|
2
2
|
import type { FunctionArtifactWithContractName } from '@aztec/stdlib/abi';
|
|
3
3
|
import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
|
|
4
4
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '@aztec/constants';
|
|
1
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
4
|
import type { GlobalVariables } from '@aztec/stdlib/tx';
|
|
@@ -16,6 +17,7 @@ export class AvmExecutionEnvironment {
|
|
|
16
17
|
public readonly isStaticCall: boolean,
|
|
17
18
|
public readonly calldata: Fr[],
|
|
18
19
|
public readonly clientInitiatedSimulation: boolean = false,
|
|
20
|
+
public readonly maxDebugLogMemoryReads: number = DEFAULT_MAX_DEBUG_LOG_MEMORY_READS,
|
|
19
21
|
) {}
|
|
20
22
|
|
|
21
23
|
private deriveEnvironmentForNestedCallInternal(
|
|
@@ -31,7 +33,8 @@ export class AvmExecutionEnvironment {
|
|
|
31
33
|
this.globals,
|
|
32
34
|
isStaticCall,
|
|
33
35
|
calldata,
|
|
34
|
-
|
|
36
|
+
this.clientInitiatedSimulation,
|
|
37
|
+
this.maxDebugLogMemoryReads,
|
|
35
38
|
);
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -110,7 +110,7 @@ const BASE_GAS_COSTS: Record<Opcode, Gas> = {
|
|
|
110
110
|
[Opcode.NULLIFIEREXISTS]: makeCost(c.AVM_NULLIFIEREXISTS_BASE_L2_GAS, 0),
|
|
111
111
|
[Opcode.EMITNULLIFIER]: makeCost(c.AVM_EMITNULLIFIER_BASE_L2_GAS, c.AVM_EMITNULLIFIER_BASE_DA_GAS),
|
|
112
112
|
[Opcode.L1TOL2MSGEXISTS]: makeCost(c.AVM_L1TOL2MSGEXISTS_BASE_L2_GAS, 0),
|
|
113
|
-
[Opcode.EMITUNENCRYPTEDLOG]: makeCost(c.AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS,
|
|
113
|
+
[Opcode.EMITUNENCRYPTEDLOG]: makeCost(c.AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS, c.AVM_EMITUNENCRYPTEDLOG_BASE_DA_GAS),
|
|
114
114
|
[Opcode.SENDL2TOL1MSG]: makeCost(c.AVM_SENDL2TOL1MSG_BASE_L2_GAS, c.AVM_SENDL2TOL1MSG_BASE_DA_GAS),
|
|
115
115
|
[Opcode.GETCONTRACTINSTANCE]: makeCost(c.AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, 0),
|
|
116
116
|
[Opcode.CALL]: makeCost(c.AVM_CALL_BASE_L2_GAS, 0),
|
|
@@ -130,7 +130,7 @@ const DYNAMIC_GAS_COSTS = new Map<Opcode, Gas>([
|
|
|
130
130
|
[Opcode.CALLDATACOPY, makeCost(c.AVM_CALLDATACOPY_DYN_L2_GAS, 0)],
|
|
131
131
|
[Opcode.RETURNDATACOPY, makeCost(c.AVM_RETURNDATACOPY_DYN_L2_GAS, 0)],
|
|
132
132
|
// TODO: Call and static call based on bytecode length
|
|
133
|
-
[Opcode.EMITUNENCRYPTEDLOG, makeCost(
|
|
133
|
+
[Opcode.EMITUNENCRYPTEDLOG, makeCost(c.AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS, c.AVM_EMITUNENCRYPTEDLOG_DYN_DA_GAS)],
|
|
134
134
|
[Opcode.TORADIXBE, makeCost(c.AVM_TORADIXBE_DYN_L2_GAS, 0)],
|
|
135
135
|
[Opcode.AND_8, makeCost(c.AVM_BITWISE_DYN_L2_GAS, 0)],
|
|
136
136
|
[Opcode.AND_16, makeCost(c.AVM_BITWISE_DYN_L2_GAS, 0)],
|
|
@@ -6,7 +6,7 @@ import type { GlobalVariables } from '@aztec/stdlib/tx';
|
|
|
6
6
|
|
|
7
7
|
import { strict as assert } from 'assert';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { CheckedPublicExecutionError } from '../public_errors.js';
|
|
10
10
|
import type { PublicPersistableStateManager } from '../state_manager/state_manager.js';
|
|
11
11
|
import { AvmContext } from './avm_context.js';
|
|
12
12
|
import { AvmContractCallResult } from './avm_contract_call_result.js';
|
|
@@ -14,7 +14,7 @@ import { AvmExecutionEnvironment } from './avm_execution_environment.js';
|
|
|
14
14
|
import type { Gas } from './avm_gas.js';
|
|
15
15
|
import { AvmMachineState } from './avm_machine_state.js';
|
|
16
16
|
import type { AvmSimulatorInterface } from './avm_simulator_interface.js';
|
|
17
|
-
import {
|
|
17
|
+
import { AvmRevertReason, InvalidProgramCounterError } from './errors.js';
|
|
18
18
|
import type { Instruction } from './opcodes/instruction.js';
|
|
19
19
|
import { revertReasonFromExceptionalHalt, revertReasonFromExplicitRevert } from './revert_reason.js';
|
|
20
20
|
import {
|
|
@@ -76,6 +76,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
76
76
|
calldata: Fr[],
|
|
77
77
|
allocatedGas: Gas,
|
|
78
78
|
clientInitiatedSimulation: boolean = false,
|
|
79
|
+
maxDebugLogMemoryReads?: number,
|
|
79
80
|
) {
|
|
80
81
|
const avmExecutionEnv = new AvmExecutionEnvironment(
|
|
81
82
|
address,
|
|
@@ -86,6 +87,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
86
87
|
isStaticCall,
|
|
87
88
|
calldata,
|
|
88
89
|
clientInitiatedSimulation,
|
|
90
|
+
maxDebugLogMemoryReads,
|
|
89
91
|
);
|
|
90
92
|
|
|
91
93
|
const avmMachineState = new AvmMachineState(allocatedGas);
|
|
@@ -97,22 +99,13 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
97
99
|
* Fetch the bytecode and execute it in the current context.
|
|
98
100
|
*/
|
|
99
101
|
public async execute(): Promise<AvmContractCallResult> {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} catch (err: any) {
|
|
104
|
-
if (!(err instanceof AvmExecutionError || err instanceof SideEffectLimitReachedError)) {
|
|
105
|
-
this.log.error(`Unknown error thrown by AVM during bytecode retrieval: ${err}`);
|
|
106
|
-
throw err;
|
|
107
|
-
}
|
|
108
|
-
return await this.handleFailureToRetrieveBytecode(
|
|
109
|
-
`Bytecode retrieval for contract '${this.context.environment.address}' failed with ${err.message}. Reverting...`,
|
|
110
|
-
);
|
|
111
|
-
}
|
|
102
|
+
const bytecode = await this.context.persistableState.getBytecode(this.context.environment.address);
|
|
103
|
+
// getBytecode returns undefined if bytecode is not found or if the limit of contract calls to unique class IDs is reached.
|
|
104
|
+
// If it throws an error that reaches this point, it is a bug.
|
|
112
105
|
|
|
113
106
|
if (!bytecode) {
|
|
114
107
|
return await this.handleFailureToRetrieveBytecode(
|
|
115
|
-
`No bytecode found
|
|
108
|
+
`No bytecode found, or limit encountered for max calls to unique contract class IDs. Contract address: ${this.context.environment.address}. Reverting...`,
|
|
116
109
|
);
|
|
117
110
|
}
|
|
118
111
|
|
|
@@ -135,6 +128,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
135
128
|
assert(bytecode.length > 0, "AVM simulator can't execute empty bytecode");
|
|
136
129
|
|
|
137
130
|
this.bytecode = bytecode;
|
|
131
|
+
let instructionName = 'NONE'; // This is used for logging purposes
|
|
138
132
|
|
|
139
133
|
const { machineState } = this.context;
|
|
140
134
|
const callStartGas = machineState.gasLeft; // Save gas before executing instruction (for profiling)
|
|
@@ -163,6 +157,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
163
157
|
}
|
|
164
158
|
machineState.nextPc = machineState.pc + bytesRead;
|
|
165
159
|
|
|
160
|
+
instructionName = instruction.constructor.name;
|
|
166
161
|
// Execute the instruction.
|
|
167
162
|
// Normal returns and reverts will return normally here.
|
|
168
163
|
// "Exceptional halts" will throw.
|
|
@@ -211,18 +206,12 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
211
206
|
// Return results for processing by calling context
|
|
212
207
|
return results;
|
|
213
208
|
} catch (err: any) {
|
|
214
|
-
this.log.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
err.constructor.name == 'OutOfGasError' ||
|
|
221
|
-
err instanceof AvmExecutionError ||
|
|
222
|
-
err instanceof SideEffectLimitReachedError
|
|
223
|
-
)
|
|
224
|
-
) {
|
|
225
|
-
this.log.error(`Unknown error thrown by AVM: ${err}`);
|
|
209
|
+
this.log.info(
|
|
210
|
+
`Exceptional halt (revert by something other than REVERT opcode) for instruction
|
|
211
|
+
${instructionName} at pc ${machineState.pc} and instruction counter ${machineState.instrCounter}`,
|
|
212
|
+
);
|
|
213
|
+
if (!(err instanceof CheckedPublicExecutionError)) {
|
|
214
|
+
this.log.error(`Unchecked/unknown error thrown by AVM. This is a bug. Error: ${err}`);
|
|
226
215
|
throw err;
|
|
227
216
|
}
|
|
228
217
|
|