@aztec/simulator 0.62.0 → 0.63.0
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/acvm/acvm.d.ts +2 -16
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +2 -70
- package/dest/acvm/oracle/oracle.d.ts +4 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +10 -11
- package/dest/acvm/oracle/typed_oracle.d.ts +5 -5
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +8 -8
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +2 -1
- package/dest/avm/avm_machine_state.d.ts +27 -8
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +6 -10
- package/dest/avm/avm_memory_types.d.ts +8 -0
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +5 -1
- package/dest/avm/avm_simulator.d.ts +2 -19
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +12 -14
- package/dest/avm/avm_tree.d.ts +249 -0
- package/dest/avm/avm_tree.d.ts.map +1 -0
- package/dest/avm/avm_tree.js +637 -0
- package/dest/avm/errors.d.ts +4 -17
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +21 -50
- package/dest/avm/fixtures/index.d.ts +7 -2
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +12 -12
- package/dest/avm/index.d.ts +1 -0
- package/dest/avm/index.d.ts.map +1 -1
- package/dest/avm/index.js +2 -1
- package/dest/avm/journal/journal.d.ts +43 -24
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +172 -39
- package/dest/avm/journal/nullifiers.d.ts +5 -4
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +2 -3
- package/dest/avm/journal/public_storage.d.ts +6 -5
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +1 -1
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +4 -10
- package/dest/avm/opcodes/arithmetic.d.ts +4 -1
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +18 -4
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +1 -3
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +1 -2
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +2 -3
- package/dest/avm/opcodes/control_flow.d.ts +4 -0
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +21 -6
- package/dest/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/avm/opcodes/conversion.js +1 -2
- package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/avm/opcodes/ec_add.js +5 -11
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +1 -2
- package/dest/avm/opcodes/external_calls.d.ts +4 -2
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +38 -22
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +1 -4
- package/dest/avm/opcodes/instruction.d.ts +4 -0
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +7 -1
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +1 -7
- package/dest/avm/opcodes/misc.js +3 -3
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
- package/dest/avm/opcodes/multi_scalar_mul.js +6 -5
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +2 -4
- package/dest/avm/serialization/bytecode_serialization.d.ts +1 -6
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +24 -20
- package/dest/client/client_execution_context.d.ts +7 -11
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +18 -20
- package/dest/client/db_oracle.d.ts +17 -10
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/db_oracle.js +1 -1
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +5 -4
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +3 -2
- package/dest/client/view_data_oracle.d.ts +6 -12
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +10 -12
- package/dest/common/errors.d.ts +15 -2
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +85 -4
- package/dest/mocks/fixtures.d.ts +9 -28
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +12 -57
- package/dest/public/dual_side_effect_trace.d.ts +34 -26
- package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.js +48 -36
- package/dest/public/enqueued_call_side_effect_trace.d.ts +96 -33
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +212 -138
- package/dest/public/execution.d.ts +50 -17
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -29
- package/dest/public/executor.d.ts +28 -11
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +33 -33
- package/dest/public/index.d.ts +4 -5
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +4 -5
- package/dest/public/public_db_sources.d.ts +1 -0
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +12 -5
- package/dest/public/public_processor.d.ts +7 -11
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +60 -42
- package/dest/public/public_processor_metrics.d.ts +3 -3
- package/dest/public/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_processor_metrics.js +1 -1
- package/dest/public/public_tx_context.d.ts +130 -0
- package/dest/public/public_tx_context.d.ts.map +1 -0
- package/dest/public/public_tx_context.js +293 -0
- package/dest/public/public_tx_simulator.d.ts +36 -0
- package/dest/public/public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator.js +148 -0
- package/dest/public/side_effect_trace.d.ts +30 -15
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +70 -16
- package/dest/public/side_effect_trace_interface.d.ts +43 -12
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/transitional_adapters.d.ts +9 -0
- package/dest/public/transitional_adapters.d.ts.map +1 -0
- package/dest/public/transitional_adapters.js +127 -0
- package/dest/public/utils.d.ts +5 -0
- package/dest/public/utils.d.ts.map +1 -0
- package/dest/public/utils.js +30 -0
- package/package.json +12 -9
- package/src/acvm/acvm.ts +3 -94
- package/src/acvm/oracle/oracle.ts +9 -14
- package/src/acvm/oracle/typed_oracle.ts +8 -8
- package/src/avm/avm_gas.ts +1 -0
- package/src/avm/avm_machine_state.ts +28 -12
- package/src/avm/avm_memory_types.ts +5 -0
- package/src/avm/avm_simulator.ts +13 -16
- package/src/avm/avm_tree.ts +785 -0
- package/src/avm/errors.ts +25 -48
- package/src/avm/fixtures/index.ts +16 -12
- package/src/avm/index.ts +1 -0
- package/src/avm/journal/journal.ts +291 -52
- package/src/avm/journal/nullifiers.ts +7 -7
- package/src/avm/journal/public_storage.ts +5 -5
- package/src/avm/opcodes/accrued_substate.ts +3 -9
- package/src/avm/opcodes/arithmetic.ts +26 -4
- package/src/avm/opcodes/bitwise.ts +0 -2
- package/src/avm/opcodes/comparators.ts +0 -1
- package/src/avm/opcodes/contract.ts +1 -2
- package/src/avm/opcodes/control_flow.ts +24 -5
- package/src/avm/opcodes/conversion.ts +0 -1
- package/src/avm/opcodes/ec_add.ts +6 -9
- package/src/avm/opcodes/environment_getters.ts +0 -1
- package/src/avm/opcodes/external_calls.ts +39 -21
- package/src/avm/opcodes/hashing.ts +0 -3
- package/src/avm/opcodes/instruction.ts +7 -0
- package/src/avm/opcodes/memory.ts +0 -6
- package/src/avm/opcodes/misc.ts +2 -2
- package/src/avm/opcodes/multi_scalar_mul.ts +5 -4
- package/src/avm/opcodes/storage.ts +1 -3
- package/src/avm/serialization/bytecode_serialization.ts +31 -22
- package/src/client/client_execution_context.ts +22 -23
- package/src/client/db_oracle.ts +22 -11
- package/src/client/private_execution.ts +5 -4
- package/src/client/unconstrained_execution.ts +2 -1
- package/src/client/view_data_oracle.ts +14 -13
- package/src/common/errors.ts +119 -3
- package/src/mocks/fixtures.ts +15 -106
- package/src/public/dual_side_effect_trace.ts +138 -50
- package/src/public/enqueued_call_side_effect_trace.ts +352 -212
- package/src/public/execution.ts +58 -42
- package/src/public/executor.ts +52 -67
- package/src/public/index.ts +7 -5
- package/src/public/public_db_sources.ts +12 -4
- package/src/public/public_processor.ts +111 -73
- package/src/public/public_processor_metrics.ts +3 -3
- package/src/public/public_tx_context.ts +411 -0
- package/src/public/public_tx_simulator.ts +232 -0
- package/src/public/side_effect_trace.ts +154 -28
- package/src/public/side_effect_trace_interface.ts +92 -14
- package/src/public/transitional_adapters.ts +347 -0
- package/src/public/utils.ts +32 -0
- package/dest/public/enqueued_call_simulator.d.ts +0 -43
- package/dest/public/enqueued_call_simulator.d.ts.map +0 -1
- package/dest/public/enqueued_call_simulator.js +0 -156
- package/dest/public/enqueued_calls_processor.d.ts +0 -43
- package/dest/public/enqueued_calls_processor.d.ts.map +0 -1
- package/dest/public/enqueued_calls_processor.js +0 -209
- package/dest/public/hints_builder.d.ts +0 -29
- package/dest/public/hints_builder.d.ts.map +0 -1
- package/dest/public/hints_builder.js +0 -75
- package/dest/public/public_kernel.d.ts +0 -30
- package/dest/public/public_kernel.d.ts.map +0 -1
- package/dest/public/public_kernel.js +0 -67
- package/dest/public/public_kernel_circuit_simulator.d.ts +0 -25
- package/dest/public/public_kernel_circuit_simulator.d.ts.map +0 -1
- package/dest/public/public_kernel_circuit_simulator.js +0 -2
- package/dest/public/public_kernel_tail_simulator.d.ts +0 -15
- package/dest/public/public_kernel_tail_simulator.d.ts.map +0 -1
- package/dest/public/public_kernel_tail_simulator.js +0 -39
- package/src/public/enqueued_call_simulator.ts +0 -360
- package/src/public/enqueued_calls_processor.ts +0 -372
- package/src/public/hints_builder.ts +0 -168
- package/src/public/public_kernel.ts +0 -100
- package/src/public/public_kernel_circuit_simulator.ts +0 -32
- package/src/public/public_kernel_tail_simulator.ts +0 -97
|
@@ -1,80 +1,96 @@
|
|
|
1
|
-
import { UnencryptedL2Log } from '@aztec/circuit-types';
|
|
1
|
+
import { UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
|
+
AvmAccumulatedData,
|
|
4
|
+
AvmAppendTreeHint,
|
|
5
|
+
AvmCircuitPublicInputs,
|
|
3
6
|
AvmContractBytecodeHints,
|
|
4
7
|
AvmContractInstanceHint,
|
|
8
|
+
AvmEnqueuedCallHint,
|
|
5
9
|
AvmExecutionHints,
|
|
6
10
|
AvmExternalCallHint,
|
|
7
11
|
AvmKeyValueHint,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
AvmNullifierReadTreeHint,
|
|
13
|
+
AvmNullifierWriteTreeHint,
|
|
14
|
+
AvmPublicDataReadTreeHint,
|
|
15
|
+
AvmPublicDataWriteTreeHint,
|
|
16
|
+
type AztecAddress,
|
|
11
17
|
type ContractClassIdPreimage,
|
|
12
|
-
ContractStorageRead,
|
|
13
|
-
ContractStorageUpdateRequest,
|
|
14
18
|
EthAddress,
|
|
15
19
|
Gas,
|
|
20
|
+
type GasSettings,
|
|
21
|
+
type GlobalVariables,
|
|
22
|
+
L1_TO_L2_MSG_TREE_HEIGHT,
|
|
16
23
|
L2ToL1Message,
|
|
17
24
|
LogHash,
|
|
18
|
-
|
|
25
|
+
MAX_ENQUEUED_CALLS_PER_TX,
|
|
19
26
|
MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX,
|
|
20
27
|
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
21
|
-
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
22
28
|
MAX_NOTE_HASHES_PER_TX,
|
|
23
29
|
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
24
30
|
MAX_NULLIFIERS_PER_TX,
|
|
25
31
|
MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
|
|
26
32
|
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
27
|
-
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
28
33
|
MAX_PUBLIC_DATA_READS_PER_TX,
|
|
29
34
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
30
35
|
MAX_UNENCRYPTED_LOGS_PER_TX,
|
|
36
|
+
NOTE_HASH_TREE_HEIGHT,
|
|
37
|
+
NULLIFIER_TREE_HEIGHT,
|
|
31
38
|
NoteHash,
|
|
32
39
|
Nullifier,
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
NullifierLeafPreimage,
|
|
41
|
+
PUBLIC_DATA_TREE_HEIGHT,
|
|
42
|
+
PrivateToAvmAccumulatedData,
|
|
43
|
+
PrivateToAvmAccumulatedDataArrayLengths,
|
|
35
44
|
PublicCallRequest,
|
|
36
45
|
PublicDataRead,
|
|
46
|
+
PublicDataTreeLeafPreimage,
|
|
37
47
|
PublicDataUpdateRequest,
|
|
38
|
-
|
|
39
|
-
PublicValidationRequestArrayLengths,
|
|
40
|
-
PublicValidationRequests,
|
|
48
|
+
PublicDataWrite,
|
|
41
49
|
ReadRequest,
|
|
42
|
-
RollupValidationRequests,
|
|
43
50
|
ScopedL2ToL1Message,
|
|
44
51
|
ScopedLogHash,
|
|
45
|
-
ScopedNoteHash,
|
|
46
|
-
type
|
|
47
|
-
ScopedReadRequest,
|
|
52
|
+
type ScopedNoteHash,
|
|
53
|
+
type ScopedReadRequest,
|
|
48
54
|
SerializableContractInstance,
|
|
49
55
|
TreeLeafReadRequest,
|
|
50
|
-
|
|
56
|
+
type TreeSnapshots,
|
|
51
57
|
} from '@aztec/circuits.js';
|
|
52
|
-
import {
|
|
53
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
58
|
+
import { computePublicDataTreeLeafSlot, siloNullifier } from '@aztec/circuits.js/hash';
|
|
54
59
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
55
60
|
import { Fr } from '@aztec/foundation/fields';
|
|
56
61
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
57
62
|
|
|
63
|
+
import { assert } from 'console';
|
|
64
|
+
|
|
58
65
|
import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js';
|
|
59
66
|
import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
|
|
67
|
+
import { createSimulationError } from '../common/errors.js';
|
|
68
|
+
import { type EnqueuedPublicCallExecutionResultWithSideEffects, type PublicFunctionCallResult } from './execution.js';
|
|
60
69
|
import { SideEffectLimitReachedError } from './side_effect_errors.js';
|
|
61
70
|
import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
|
|
62
71
|
|
|
72
|
+
const emptyPublicDataPath = () => new Array(PUBLIC_DATA_TREE_HEIGHT).fill(Fr.zero());
|
|
73
|
+
const emptyNoteHashPath = () => new Array(NOTE_HASH_TREE_HEIGHT).fill(Fr.zero());
|
|
74
|
+
const emptyNullifierPath = () => new Array(NULLIFIER_TREE_HEIGHT).fill(Fr.zero());
|
|
75
|
+
const emptyL1ToL2MessagePath = () => new Array(L1_TO_L2_MSG_TREE_HEIGHT).fill(Fr.zero());
|
|
76
|
+
|
|
63
77
|
/**
|
|
64
78
|
* A struct containing just the side effects as regular arrays
|
|
65
79
|
* as opposed to "Tuple" arrays used by circuit public inputs.
|
|
66
80
|
* This struct is helpful for testing and checking array lengths.
|
|
67
81
|
**/
|
|
68
82
|
export type SideEffects = {
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
enqueuedCalls: PublicCallRequest[];
|
|
84
|
+
|
|
85
|
+
publicDataReads: PublicDataRead[];
|
|
86
|
+
publicDataWrites: PublicDataUpdateRequest[];
|
|
71
87
|
|
|
72
88
|
noteHashReadRequests: TreeLeafReadRequest[];
|
|
73
89
|
noteHashes: ScopedNoteHash[];
|
|
74
90
|
|
|
75
91
|
nullifierReadRequests: ScopedReadRequest[];
|
|
76
92
|
nullifierNonExistentReadRequests: ScopedReadRequest[];
|
|
77
|
-
nullifiers:
|
|
93
|
+
nullifiers: Nullifier[];
|
|
78
94
|
|
|
79
95
|
l1ToL2MsgReadRequests: TreeLeafReadRequest[];
|
|
80
96
|
l2ToL1Msgs: ScopedL2ToL1Message[];
|
|
@@ -83,6 +99,29 @@ export type SideEffects = {
|
|
|
83
99
|
unencryptedLogsHashes: ScopedLogHash[];
|
|
84
100
|
};
|
|
85
101
|
|
|
102
|
+
export class SideEffectArrayLengths {
|
|
103
|
+
constructor(
|
|
104
|
+
public readonly publicDataReads: number,
|
|
105
|
+
public readonly publicDataWrites: number,
|
|
106
|
+
|
|
107
|
+
public readonly noteHashReadRequests: number,
|
|
108
|
+
public readonly noteHashes: number,
|
|
109
|
+
|
|
110
|
+
public readonly nullifierReadRequests: number,
|
|
111
|
+
public readonly nullifierNonExistentReadRequests: number,
|
|
112
|
+
public readonly nullifiers: number,
|
|
113
|
+
|
|
114
|
+
public readonly l1ToL2MsgReadRequests: number,
|
|
115
|
+
public readonly l2ToL1Msgs: number,
|
|
116
|
+
|
|
117
|
+
public readonly unencryptedLogs: number,
|
|
118
|
+
) {}
|
|
119
|
+
|
|
120
|
+
static empty() {
|
|
121
|
+
return new this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
86
125
|
/**
|
|
87
126
|
* Trace side effects for an entire enqueued call.
|
|
88
127
|
*/
|
|
@@ -92,35 +131,38 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
92
131
|
/** The side effect counter increments with every call to the trace. */
|
|
93
132
|
private sideEffectCounter: number;
|
|
94
133
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
private
|
|
98
|
-
private
|
|
134
|
+
private enqueuedCalls: PublicCallRequest[] = [];
|
|
135
|
+
|
|
136
|
+
private publicDataReads: PublicDataRead[] = [];
|
|
137
|
+
private publicDataWrites: PublicDataUpdateRequest[] = [];
|
|
99
138
|
|
|
100
139
|
private noteHashReadRequests: TreeLeafReadRequest[] = [];
|
|
101
140
|
private noteHashes: ScopedNoteHash[] = [];
|
|
102
141
|
|
|
103
142
|
private nullifierReadRequests: ScopedReadRequest[] = [];
|
|
104
143
|
private nullifierNonExistentReadRequests: ScopedReadRequest[] = [];
|
|
105
|
-
private nullifiers:
|
|
144
|
+
private nullifiers: Nullifier[] = [];
|
|
106
145
|
|
|
107
146
|
private l1ToL2MsgReadRequests: TreeLeafReadRequest[] = [];
|
|
108
|
-
private
|
|
147
|
+
private l2ToL1Messages: ScopedL2ToL1Message[] = [];
|
|
109
148
|
|
|
110
149
|
private unencryptedLogs: UnencryptedL2Log[] = [];
|
|
111
150
|
private unencryptedLogsHashes: ScopedLogHash[] = [];
|
|
112
151
|
|
|
113
152
|
private avmCircuitHints: AvmExecutionHints;
|
|
114
153
|
|
|
154
|
+
/** Make sure a forked trace is never merged twice. */
|
|
155
|
+
private alreadyMergedIntoParent = false;
|
|
156
|
+
|
|
115
157
|
constructor(
|
|
116
158
|
/** The counter of this trace's first side effect. */
|
|
117
159
|
public readonly startSideEffectCounter: number = 0,
|
|
118
160
|
/** Track parent's (or previous kernel's) lengths so the AVM can properly enforce TX-wide limits,
|
|
119
161
|
* otherwise the public kernel can fail to prove because TX limits are breached.
|
|
120
162
|
*/
|
|
121
|
-
private readonly
|
|
122
|
-
private readonly previousAccumulatedDataArrayLengths: PublicAccumulatedDataArrayLengths = PublicAccumulatedDataArrayLengths.empty(),
|
|
163
|
+
private readonly previousSideEffectArrayLengths: SideEffectArrayLengths = SideEffectArrayLengths.empty(),
|
|
123
164
|
) {
|
|
165
|
+
this.log.debug(`Creating trace instance with startSideEffectCounter: ${startSideEffectCounter}`);
|
|
124
166
|
this.sideEffectCounter = startSideEffectCounter;
|
|
125
167
|
this.avmCircuitHints = AvmExecutionHints.empty();
|
|
126
168
|
}
|
|
@@ -128,27 +170,46 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
128
170
|
public fork() {
|
|
129
171
|
return new PublicEnqueuedCallSideEffectTrace(
|
|
130
172
|
this.sideEffectCounter,
|
|
131
|
-
new
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
this.
|
|
173
|
+
new SideEffectArrayLengths(
|
|
174
|
+
this.previousSideEffectArrayLengths.publicDataReads + this.publicDataReads.length,
|
|
175
|
+
this.previousSideEffectArrayLengths.publicDataWrites + this.publicDataWrites.length,
|
|
176
|
+
this.previousSideEffectArrayLengths.noteHashReadRequests + this.noteHashReadRequests.length,
|
|
177
|
+
this.previousSideEffectArrayLengths.noteHashes + this.noteHashes.length,
|
|
178
|
+
this.previousSideEffectArrayLengths.nullifierReadRequests + this.nullifierReadRequests.length,
|
|
179
|
+
this.previousSideEffectArrayLengths.nullifierNonExistentReadRequests +
|
|
135
180
|
this.nullifierNonExistentReadRequests.length,
|
|
136
|
-
this.
|
|
137
|
-
this.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.previousAccumulatedDataArrayLengths.noteHashes + this.noteHashes.length,
|
|
141
|
-
this.previousAccumulatedDataArrayLengths.nullifiers + this.nullifiers.length,
|
|
142
|
-
this.previousAccumulatedDataArrayLengths.l2ToL1Msgs + this.l2ToL1Msgs.length,
|
|
143
|
-
this.previousAccumulatedDataArrayLengths.noteEncryptedLogsHashes,
|
|
144
|
-
this.previousAccumulatedDataArrayLengths.encryptedLogsHashes,
|
|
145
|
-
this.previousAccumulatedDataArrayLengths.unencryptedLogsHashes + this.unencryptedLogsHashes.length,
|
|
146
|
-
this.previousAccumulatedDataArrayLengths.publicDataUpdateRequests + this.contractStorageUpdateRequests.length,
|
|
147
|
-
this.previousAccumulatedDataArrayLengths.publicCallStack,
|
|
181
|
+
this.previousSideEffectArrayLengths.nullifiers + this.nullifiers.length,
|
|
182
|
+
this.previousSideEffectArrayLengths.l1ToL2MsgReadRequests + this.l1ToL2MsgReadRequests.length,
|
|
183
|
+
this.previousSideEffectArrayLengths.l2ToL1Msgs + this.l2ToL1Messages.length,
|
|
184
|
+
this.previousSideEffectArrayLengths.unencryptedLogs + this.unencryptedLogs.length,
|
|
148
185
|
),
|
|
149
186
|
);
|
|
150
187
|
}
|
|
151
188
|
|
|
189
|
+
public merge(forkedTrace: this, reverted: boolean = false) {
|
|
190
|
+
// sanity check to avoid merging the same forked trace twice
|
|
191
|
+
assert(!this.alreadyMergedIntoParent, 'Cannot merge a forked trace that has already been merged into its parent!');
|
|
192
|
+
forkedTrace.alreadyMergedIntoParent = true;
|
|
193
|
+
|
|
194
|
+
// TODO(dbanks12): accept & merge forked trace's hints!
|
|
195
|
+
this.sideEffectCounter = forkedTrace.sideEffectCounter;
|
|
196
|
+
this.enqueuedCalls.push(...forkedTrace.enqueuedCalls);
|
|
197
|
+
|
|
198
|
+
if (!reverted) {
|
|
199
|
+
this.publicDataReads.push(...forkedTrace.publicDataReads);
|
|
200
|
+
this.publicDataWrites.push(...forkedTrace.publicDataWrites);
|
|
201
|
+
this.noteHashReadRequests.push(...forkedTrace.noteHashReadRequests);
|
|
202
|
+
this.noteHashes.push(...forkedTrace.noteHashes);
|
|
203
|
+
this.nullifierReadRequests.push(...forkedTrace.nullifierReadRequests);
|
|
204
|
+
this.nullifierNonExistentReadRequests.push(...forkedTrace.nullifierNonExistentReadRequests);
|
|
205
|
+
this.nullifiers.push(...forkedTrace.nullifiers);
|
|
206
|
+
this.l1ToL2MsgReadRequests.push(...forkedTrace.l1ToL2MsgReadRequests);
|
|
207
|
+
this.l2ToL1Messages.push(...forkedTrace.l2ToL1Messages);
|
|
208
|
+
this.unencryptedLogs.push(...forkedTrace.unencryptedLogs);
|
|
209
|
+
this.unencryptedLogsHashes.push(...forkedTrace.unencryptedLogsHashes);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
152
213
|
public getCounter() {
|
|
153
214
|
return this.sideEffectCounter;
|
|
154
215
|
}
|
|
@@ -157,74 +218,136 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
157
218
|
this.sideEffectCounter++;
|
|
158
219
|
}
|
|
159
220
|
|
|
160
|
-
public tracePublicStorageRead(
|
|
221
|
+
public tracePublicStorageRead(
|
|
222
|
+
contractAddress: AztecAddress,
|
|
223
|
+
slot: Fr,
|
|
224
|
+
value: Fr,
|
|
225
|
+
leafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
|
|
226
|
+
leafIndex: Fr = Fr.zero(),
|
|
227
|
+
path: Fr[] = emptyPublicDataPath(),
|
|
228
|
+
) {
|
|
229
|
+
if (!leafIndex.equals(Fr.zero())) {
|
|
230
|
+
// if we have real merkle hint content, make sure the value matches the the provided preimage
|
|
231
|
+
assert(leafPreimage.value.equals(value), 'Value mismatch when tracing in public data write');
|
|
232
|
+
}
|
|
161
233
|
// NOTE: exists and cached are unused for now but may be used for optimizations or kernel hints later
|
|
162
234
|
if (
|
|
163
|
-
this.
|
|
235
|
+
this.publicDataReads.length + this.previousSideEffectArrayLengths.publicDataReads >=
|
|
164
236
|
MAX_PUBLIC_DATA_READS_PER_TX
|
|
165
237
|
) {
|
|
166
|
-
throw new SideEffectLimitReachedError('contract storage read', MAX_PUBLIC_DATA_READS_PER_TX);
|
|
238
|
+
throw new SideEffectLimitReachedError('public data (contract storage) read', MAX_PUBLIC_DATA_READS_PER_TX);
|
|
167
239
|
}
|
|
168
240
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
);
|
|
241
|
+
const leafSlot = computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
242
|
+
|
|
243
|
+
this.publicDataReads.push(new PublicDataRead(leafSlot, value, this.sideEffectCounter));
|
|
244
|
+
|
|
172
245
|
this.avmCircuitHints.storageValues.items.push(
|
|
173
246
|
new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value),
|
|
174
247
|
);
|
|
248
|
+
this.avmCircuitHints.storageReadRequest.items.push(new AvmPublicDataReadTreeHint(leafPreimage, leafIndex, path));
|
|
175
249
|
this.log.debug(`SLOAD cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
|
|
176
250
|
this.incrementSideEffectCounter();
|
|
177
251
|
}
|
|
178
252
|
|
|
179
|
-
public tracePublicStorageWrite(
|
|
253
|
+
public tracePublicStorageWrite(
|
|
254
|
+
contractAddress: AztecAddress,
|
|
255
|
+
slot: Fr,
|
|
256
|
+
value: Fr,
|
|
257
|
+
lowLeafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
|
|
258
|
+
lowLeafIndex: Fr = Fr.zero(),
|
|
259
|
+
lowLeafPath: Fr[] = emptyPublicDataPath(),
|
|
260
|
+
newLeafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
|
|
261
|
+
insertionPath: Fr[] = emptyPublicDataPath(),
|
|
262
|
+
) {
|
|
263
|
+
if (!lowLeafIndex.equals(Fr.zero())) {
|
|
264
|
+
// if we have real merkle hint content, make sure the value matches the the provided preimage
|
|
265
|
+
assert(newLeafPreimage.value.equals(value), 'Value mismatch when tracing in public data read');
|
|
266
|
+
}
|
|
180
267
|
if (
|
|
181
|
-
this.
|
|
268
|
+
this.publicDataWrites.length + this.previousSideEffectArrayLengths.publicDataWrites >=
|
|
182
269
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
|
|
183
270
|
) {
|
|
184
|
-
throw new SideEffectLimitReachedError(
|
|
271
|
+
throw new SideEffectLimitReachedError(
|
|
272
|
+
'public data (contract storage) write',
|
|
273
|
+
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
274
|
+
);
|
|
185
275
|
}
|
|
186
276
|
|
|
187
|
-
|
|
188
|
-
|
|
277
|
+
const leafSlot = computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
278
|
+
this.publicDataWrites.push(new PublicDataUpdateRequest(leafSlot, value, this.sideEffectCounter));
|
|
279
|
+
|
|
280
|
+
// New hinting
|
|
281
|
+
const readHint = new AvmPublicDataReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath);
|
|
282
|
+
this.avmCircuitHints.storageUpdateRequest.items.push(
|
|
283
|
+
new AvmPublicDataWriteTreeHint(readHint, newLeafPreimage, insertionPath),
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
this.log.debug(
|
|
287
|
+
`Traced public data write (address=${contractAddress}, slot=${slot}, leafSlot=${leafSlot}): value=${value} (counter=${this.sideEffectCounter})`,
|
|
189
288
|
);
|
|
190
|
-
this.log.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
|
|
191
289
|
this.incrementSideEffectCounter();
|
|
192
290
|
}
|
|
193
291
|
|
|
194
292
|
// TODO(8287): _exists can be removed once we have the vm properly handling the equality check
|
|
195
|
-
public traceNoteHashCheck(
|
|
293
|
+
public traceNoteHashCheck(
|
|
294
|
+
_contractAddress: AztecAddress,
|
|
295
|
+
noteHash: Fr,
|
|
296
|
+
leafIndex: Fr,
|
|
297
|
+
exists: boolean,
|
|
298
|
+
path: Fr[] = emptyNoteHashPath(),
|
|
299
|
+
) {
|
|
196
300
|
// NOTE: contractAddress is unused because noteHash is an already-siloed leaf
|
|
197
301
|
if (
|
|
198
|
-
this.noteHashReadRequests.length + this.
|
|
302
|
+
this.noteHashReadRequests.length + this.previousSideEffectArrayLengths.noteHashReadRequests >=
|
|
199
303
|
MAX_NOTE_HASH_READ_REQUESTS_PER_TX
|
|
200
304
|
) {
|
|
201
305
|
throw new SideEffectLimitReachedError('note hash read request', MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
|
|
202
306
|
}
|
|
203
307
|
|
|
308
|
+
// note hash is already siloed here
|
|
204
309
|
this.noteHashReadRequests.push(new TreeLeafReadRequest(noteHash, leafIndex));
|
|
205
310
|
this.avmCircuitHints.noteHashExists.items.push(
|
|
206
311
|
new AvmKeyValueHint(/*key=*/ new Fr(leafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO),
|
|
207
312
|
);
|
|
313
|
+
// New Hinting
|
|
314
|
+
this.avmCircuitHints.noteHashReadRequest.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
|
|
208
315
|
// NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes)
|
|
209
316
|
}
|
|
210
317
|
|
|
211
|
-
public traceNewNoteHash(
|
|
212
|
-
|
|
318
|
+
public traceNewNoteHash(
|
|
319
|
+
contractAddress: AztecAddress,
|
|
320
|
+
noteHash: Fr,
|
|
321
|
+
leafIndex: Fr,
|
|
322
|
+
path: Fr[] = emptyNoteHashPath(),
|
|
323
|
+
) {
|
|
324
|
+
if (this.noteHashes.length + this.previousSideEffectArrayLengths.noteHashes >= MAX_NOTE_HASHES_PER_TX) {
|
|
213
325
|
throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX);
|
|
214
326
|
}
|
|
215
327
|
|
|
216
|
-
|
|
328
|
+
// TODO(dbanks12): make unique and silo instead of scoping
|
|
329
|
+
//const siloedNoteHash = siloNoteHash(contractAddress, noteHash);
|
|
330
|
+
this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter).scope(contractAddress));
|
|
217
331
|
this.log.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`);
|
|
332
|
+
this.avmCircuitHints.noteHashWriteRequest.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
|
|
218
333
|
this.incrementSideEffectCounter();
|
|
219
334
|
}
|
|
220
335
|
|
|
221
|
-
public traceNullifierCheck(
|
|
336
|
+
public traceNullifierCheck(
|
|
337
|
+
contractAddress: AztecAddress,
|
|
338
|
+
nullifier: Fr,
|
|
339
|
+
exists: boolean,
|
|
340
|
+
lowLeafPreimage: NullifierLeafPreimage = NullifierLeafPreimage.empty(),
|
|
341
|
+
lowLeafIndex: Fr = Fr.zero(),
|
|
342
|
+
lowLeafPath: Fr[] = emptyNullifierPath(),
|
|
343
|
+
) {
|
|
222
344
|
// NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later
|
|
223
345
|
this.enforceLimitOnNullifierChecks();
|
|
224
346
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
);
|
|
347
|
+
// TODO(dbanks12): use siloed nullifier instead of scoped once public kernel stops siloing
|
|
348
|
+
// and once VM public inputs are meant to contain siloed nullifiers.
|
|
349
|
+
//const siloedNullifier = siloNullifier(contractAddress, nullifier);
|
|
350
|
+
const readRequest = new ReadRequest(nullifier, this.sideEffectCounter).scope(contractAddress);
|
|
228
351
|
if (exists) {
|
|
229
352
|
this.nullifierReadRequests.push(readRequest);
|
|
230
353
|
} else {
|
|
@@ -233,29 +356,47 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
233
356
|
this.avmCircuitHints.nullifierExists.items.push(
|
|
234
357
|
new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)),
|
|
235
358
|
);
|
|
359
|
+
// New Hints
|
|
360
|
+
this.avmCircuitHints.nullifierReadRequest.items.push(
|
|
361
|
+
new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath),
|
|
362
|
+
);
|
|
236
363
|
this.log.debug(`NULLIFIER_EXISTS cnt: ${this.sideEffectCounter}`);
|
|
237
364
|
this.incrementSideEffectCounter();
|
|
238
365
|
}
|
|
239
366
|
|
|
240
|
-
public traceNewNullifier(
|
|
241
|
-
|
|
367
|
+
public traceNewNullifier(
|
|
368
|
+
contractAddress: AztecAddress,
|
|
369
|
+
nullifier: Fr,
|
|
370
|
+
lowLeafPreimage: NullifierLeafPreimage = NullifierLeafPreimage.empty(),
|
|
371
|
+
lowLeafIndex: Fr = Fr.zero(),
|
|
372
|
+
lowLeafPath: Fr[] = emptyNullifierPath(),
|
|
373
|
+
insertionPath: Fr[] = emptyNullifierPath(),
|
|
374
|
+
) {
|
|
375
|
+
if (this.nullifiers.length + this.previousSideEffectArrayLengths.nullifiers >= MAX_NULLIFIERS_PER_TX) {
|
|
242
376
|
throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX);
|
|
243
377
|
}
|
|
244
378
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
);
|
|
379
|
+
const siloedNullifier = siloNullifier(contractAddress, nullifier);
|
|
380
|
+
this.nullifiers.push(new Nullifier(siloedNullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
|
|
381
|
+
|
|
382
|
+
// New hinting
|
|
383
|
+
const lowLeafReadHint = new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath);
|
|
384
|
+
this.avmCircuitHints.nullifierWriteHints.items.push(new AvmNullifierWriteTreeHint(lowLeafReadHint, insertionPath));
|
|
250
385
|
this.log.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`);
|
|
251
386
|
this.incrementSideEffectCounter();
|
|
252
387
|
}
|
|
253
388
|
|
|
254
389
|
// TODO(8287): _exists can be removed once we have the vm properly handling the equality check
|
|
255
|
-
public traceL1ToL2MessageCheck(
|
|
390
|
+
public traceL1ToL2MessageCheck(
|
|
391
|
+
_contractAddress: AztecAddress,
|
|
392
|
+
msgHash: Fr,
|
|
393
|
+
msgLeafIndex: Fr,
|
|
394
|
+
exists: boolean,
|
|
395
|
+
path: Fr[] = emptyL1ToL2MessagePath(),
|
|
396
|
+
) {
|
|
256
397
|
// NOTE: contractAddress is unused because msgHash is an already-siloed leaf
|
|
257
398
|
if (
|
|
258
|
-
this.l1ToL2MsgReadRequests.length + this.
|
|
399
|
+
this.l1ToL2MsgReadRequests.length + this.previousSideEffectArrayLengths.l1ToL2MsgReadRequests >=
|
|
259
400
|
MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX
|
|
260
401
|
) {
|
|
261
402
|
throw new SideEffectLimitReachedError('l1 to l2 message read request', MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX);
|
|
@@ -265,50 +406,45 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
265
406
|
this.avmCircuitHints.l1ToL2MessageExists.items.push(
|
|
266
407
|
new AvmKeyValueHint(/*key=*/ new Fr(msgLeafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO),
|
|
267
408
|
);
|
|
409
|
+
// New Hinting
|
|
410
|
+
this.avmCircuitHints.l1ToL2MessageReadRequest.items.push(new AvmAppendTreeHint(msgLeafIndex, msgHash, path));
|
|
268
411
|
}
|
|
269
412
|
|
|
270
|
-
public traceNewL2ToL1Message(contractAddress:
|
|
271
|
-
if (this.
|
|
413
|
+
public traceNewL2ToL1Message(contractAddress: AztecAddress, recipient: Fr, content: Fr) {
|
|
414
|
+
if (this.l2ToL1Messages.length + this.previousSideEffectArrayLengths.l2ToL1Msgs >= MAX_L2_TO_L1_MSGS_PER_TX) {
|
|
272
415
|
throw new SideEffectLimitReachedError('l2 to l1 message', MAX_L2_TO_L1_MSGS_PER_TX);
|
|
273
416
|
}
|
|
274
417
|
|
|
275
418
|
const recipientAddress = EthAddress.fromField(recipient);
|
|
276
|
-
this.
|
|
277
|
-
new L2ToL1Message(recipientAddress, content, this.sideEffectCounter).scope(
|
|
278
|
-
AztecAddress.fromField(contractAddress),
|
|
279
|
-
),
|
|
419
|
+
this.l2ToL1Messages.push(
|
|
420
|
+
new L2ToL1Message(recipientAddress, content, this.sideEffectCounter).scope(contractAddress),
|
|
280
421
|
);
|
|
281
422
|
this.log.debug(`NEW_L2_TO_L1_MSG cnt: ${this.sideEffectCounter}`);
|
|
282
423
|
this.incrementSideEffectCounter();
|
|
283
424
|
}
|
|
284
425
|
|
|
285
|
-
public traceUnencryptedLog(contractAddress:
|
|
426
|
+
public traceUnencryptedLog(contractAddress: AztecAddress, log: Fr[]) {
|
|
286
427
|
if (
|
|
287
|
-
this.unencryptedLogs.length + this.
|
|
428
|
+
this.unencryptedLogs.length + this.previousSideEffectArrayLengths.unencryptedLogs >=
|
|
288
429
|
MAX_UNENCRYPTED_LOGS_PER_TX
|
|
289
430
|
) {
|
|
290
431
|
throw new SideEffectLimitReachedError('unencrypted log', MAX_UNENCRYPTED_LOGS_PER_TX);
|
|
291
432
|
}
|
|
292
433
|
|
|
293
|
-
const ulog = new UnencryptedL2Log(
|
|
294
|
-
AztecAddress.fromField(contractAddress),
|
|
295
|
-
Buffer.concat(log.map(f => f.toBuffer())),
|
|
296
|
-
);
|
|
434
|
+
const ulog = new UnencryptedL2Log(contractAddress, Buffer.concat(log.map(f => f.toBuffer())));
|
|
297
435
|
const basicLogHash = Fr.fromBuffer(ulog.hash());
|
|
298
436
|
this.unencryptedLogs.push(ulog);
|
|
299
437
|
// This length is for charging DA and is checked on-chain - has to be length of log preimage + 4 bytes.
|
|
300
438
|
// The .length call also has a +4 but that is unrelated
|
|
301
439
|
this.unencryptedLogsHashes.push(
|
|
302
|
-
new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)).scope(
|
|
303
|
-
AztecAddress.fromField(contractAddress),
|
|
304
|
-
),
|
|
440
|
+
new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)).scope(contractAddress),
|
|
305
441
|
);
|
|
306
442
|
this.log.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`);
|
|
307
443
|
this.incrementSideEffectCounter();
|
|
308
444
|
}
|
|
309
445
|
|
|
310
446
|
public traceGetContractInstance(
|
|
311
|
-
contractAddress:
|
|
447
|
+
contractAddress: AztecAddress,
|
|
312
448
|
exists: boolean,
|
|
313
449
|
instance: SerializableContractInstance = SerializableContractInstance.default(),
|
|
314
450
|
) {
|
|
@@ -330,10 +466,10 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
330
466
|
}
|
|
331
467
|
|
|
332
468
|
// This tracing function gets called everytime we start simulation/execution.
|
|
333
|
-
// This happens both when starting a new top-level trace and the start of every
|
|
469
|
+
// This happens both when starting a new top-level trace and the start of every forked trace
|
|
334
470
|
// We use this to collect the AvmContractBytecodeHints
|
|
335
471
|
public traceGetBytecode(
|
|
336
|
-
contractAddress:
|
|
472
|
+
contractAddress: AztecAddress,
|
|
337
473
|
exists: boolean,
|
|
338
474
|
bytecode: Buffer = Buffer.alloc(0),
|
|
339
475
|
contractInstance: SerializableContractInstance = SerializableContractInstance.default(),
|
|
@@ -369,7 +505,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
369
505
|
*/
|
|
370
506
|
public traceNestedCall(
|
|
371
507
|
/** The trace of the nested call. */
|
|
372
|
-
|
|
508
|
+
_nestedCallTrace: this,
|
|
373
509
|
/** The execution environment of the nested call. */
|
|
374
510
|
nestedEnvironment: AvmExecutionEnvironment,
|
|
375
511
|
/** How much gas was available for this public execution. */
|
|
@@ -383,20 +519,11 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
383
519
|
/** Function name for logging */
|
|
384
520
|
_functionName: string = 'unknown',
|
|
385
521
|
) {
|
|
522
|
+
// TODO(4805): check if some threshold is reached for max nested calls (to unique contracts?)
|
|
523
|
+
//
|
|
386
524
|
// Store end side effect counter before it gets updated by absorbing nested call trace
|
|
387
525
|
const endSideEffectCounter = new Fr(this.sideEffectCounter);
|
|
388
526
|
|
|
389
|
-
// TODO(4805): check if some threshold is reached for max nested calls (to unique contracts?)
|
|
390
|
-
// TODO(dbanks12): should emit a nullifier read request. There should be two thresholds.
|
|
391
|
-
// one for max unique contract calls, and another based on max nullifier reads.
|
|
392
|
-
// Since this trace function happens _after_ a nested call, such threshold limits must take
|
|
393
|
-
// place in another trace function that occurs _before_ a nested call.
|
|
394
|
-
if (avmCallResults.reverted) {
|
|
395
|
-
this.absorbRevertedNestedTrace(nestedCallTrace);
|
|
396
|
-
} else {
|
|
397
|
-
this.absorbSuccessfulNestedTrace(nestedCallTrace);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
527
|
const gasUsed = new Gas(startGasLeft.daGas - endGasLeft.daGas, startGasLeft.l2Gas - endGasLeft.l2Gas);
|
|
401
528
|
|
|
402
529
|
this.avmCircuitHints.externalCalls.items.push(
|
|
@@ -410,85 +537,133 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
410
537
|
);
|
|
411
538
|
}
|
|
412
539
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
this.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
this.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
// All read requests, and any writes (storage & nullifiers) that
|
|
430
|
-
// require complex validation in public kernel (with end lifetimes)
|
|
431
|
-
// must be absorbed even on revert.
|
|
432
|
-
|
|
433
|
-
// TODO(dbanks12): What should happen to side effect counter on revert?
|
|
434
|
-
this.sideEffectCounter = nestedTrace.sideEffectCounter;
|
|
435
|
-
this.contractStorageReads.push(...nestedTrace.contractStorageReads);
|
|
436
|
-
this.contractStorageUpdateRequests.push(...nestedTrace.contractStorageUpdateRequests);
|
|
437
|
-
this.noteHashReadRequests.push(...nestedTrace.noteHashReadRequests);
|
|
438
|
-
// new noteHashes are tossed on revert
|
|
439
|
-
this.nullifierReadRequests.push(...nestedTrace.nullifierReadRequests);
|
|
440
|
-
this.nullifierNonExistentReadRequests.push(...nestedTrace.nullifierNonExistentReadRequests);
|
|
441
|
-
this.nullifiers.push(...nestedTrace.nullifiers);
|
|
442
|
-
this.l1ToL2MsgReadRequests.push(...nestedTrace.l1ToL2MsgReadRequests);
|
|
443
|
-
// new l2-to-l1 messages are tossed on revert
|
|
444
|
-
// new unencrypted logs are tossed on revert
|
|
540
|
+
/**
|
|
541
|
+
* Trace an enqueued call.
|
|
542
|
+
* Accept some results from a finished call's trace into this one.
|
|
543
|
+
*/
|
|
544
|
+
public traceEnqueuedCall(
|
|
545
|
+
/** The call request from private that enqueued this call. */
|
|
546
|
+
publicCallRequest: PublicCallRequest,
|
|
547
|
+
/** The call's calldata */
|
|
548
|
+
calldata: Fr[],
|
|
549
|
+
/** Did the call revert? */
|
|
550
|
+
_reverted: boolean,
|
|
551
|
+
) {
|
|
552
|
+
this.log.debug(`Tracing enqueued call`);
|
|
553
|
+
// TODO(4805): check if some threshold is reached for max enqueued or nested calls (to unique contracts?)
|
|
554
|
+
this.enqueuedCalls.push(publicCallRequest);
|
|
555
|
+
this.avmCircuitHints.enqueuedCalls.items.push(new AvmEnqueuedCallHint(publicCallRequest.contractAddress, calldata));
|
|
445
556
|
}
|
|
446
557
|
|
|
447
558
|
public getSideEffects(): SideEffects {
|
|
448
559
|
return {
|
|
449
|
-
|
|
450
|
-
|
|
560
|
+
enqueuedCalls: this.enqueuedCalls,
|
|
561
|
+
publicDataReads: this.publicDataReads,
|
|
562
|
+
publicDataWrites: this.publicDataWrites,
|
|
451
563
|
noteHashReadRequests: this.noteHashReadRequests,
|
|
452
564
|
noteHashes: this.noteHashes,
|
|
453
565
|
nullifierReadRequests: this.nullifierReadRequests,
|
|
454
566
|
nullifierNonExistentReadRequests: this.nullifierNonExistentReadRequests,
|
|
455
567
|
nullifiers: this.nullifiers,
|
|
456
568
|
l1ToL2MsgReadRequests: this.l1ToL2MsgReadRequests,
|
|
457
|
-
l2ToL1Msgs: this.
|
|
569
|
+
l2ToL1Msgs: this.l2ToL1Messages,
|
|
458
570
|
unencryptedLogs: this.unencryptedLogs,
|
|
459
571
|
unencryptedLogsHashes: this.unencryptedLogsHashes,
|
|
460
572
|
};
|
|
461
573
|
}
|
|
462
574
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
avmEnvironment: AvmExecutionEnvironment,
|
|
468
|
-
/** How much gas was available for this public execution. */
|
|
469
|
-
startGasLeft: Gas,
|
|
575
|
+
/**
|
|
576
|
+
* Get the results of public execution.
|
|
577
|
+
*/
|
|
578
|
+
public toPublicEnqueuedCallExecutionResult(
|
|
470
579
|
/** How much gas was left after this public execution. */
|
|
471
580
|
endGasLeft: Gas,
|
|
472
581
|
/** The call's results */
|
|
473
582
|
avmCallResults: AvmContractCallResult,
|
|
474
|
-
):
|
|
475
|
-
return
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
583
|
+
): EnqueuedPublicCallExecutionResultWithSideEffects {
|
|
584
|
+
return {
|
|
585
|
+
endGasLeft,
|
|
586
|
+
endSideEffectCounter: new Fr(this.sideEffectCounter),
|
|
587
|
+
returnValues: avmCallResults.output,
|
|
588
|
+
reverted: avmCallResults.reverted,
|
|
589
|
+
revertReason: avmCallResults.revertReason
|
|
590
|
+
? createSimulationError(avmCallResults.revertReason, avmCallResults.output)
|
|
591
|
+
: undefined,
|
|
592
|
+
sideEffects: {
|
|
593
|
+
publicDataWrites: this.publicDataWrites,
|
|
594
|
+
noteHashes: this.noteHashes,
|
|
595
|
+
nullifiers: this.nullifiers,
|
|
596
|
+
l2ToL1Messages: this.l2ToL1Messages,
|
|
597
|
+
unencryptedLogsHashes: this.unencryptedLogsHashes, // Scoped?
|
|
598
|
+
unencryptedLogs: new UnencryptedFunctionL2Logs(this.unencryptedLogs),
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
public toAvmCircuitPublicInputs(
|
|
604
|
+
/** Globals. */
|
|
605
|
+
globalVariables: GlobalVariables,
|
|
606
|
+
/** Start tree snapshots. */
|
|
607
|
+
startTreeSnapshots: TreeSnapshots,
|
|
608
|
+
/** Gas used at start of TX. */
|
|
609
|
+
startGasUsed: Gas,
|
|
610
|
+
/** How much gas was available for this public execution. */
|
|
611
|
+
gasLimits: GasSettings,
|
|
612
|
+
/** Call requests for setup phase. */
|
|
613
|
+
publicSetupCallRequests: PublicCallRequest[],
|
|
614
|
+
/** Call requests for app logic phase. */
|
|
615
|
+
publicAppLogicCallRequests: PublicCallRequest[],
|
|
616
|
+
/** Call request for teardown phase. */
|
|
617
|
+
publicTeardownCallRequest: PublicCallRequest,
|
|
618
|
+
/** End tree snapshots. */
|
|
619
|
+
endTreeSnapshots: TreeSnapshots,
|
|
620
|
+
/**
|
|
621
|
+
* Gas used by the whole transaction, assuming entire teardown limit is used.
|
|
622
|
+
* This is the gas used when computing transaction fee.
|
|
623
|
+
*/
|
|
624
|
+
endGasUsed: Gas,
|
|
625
|
+
/** Transaction fee. */
|
|
626
|
+
transactionFee: Fr,
|
|
627
|
+
/** The call's results */
|
|
628
|
+
reverted: boolean,
|
|
629
|
+
): AvmCircuitPublicInputs {
|
|
630
|
+
return new AvmCircuitPublicInputs(
|
|
631
|
+
globalVariables,
|
|
632
|
+
startTreeSnapshots,
|
|
633
|
+
startGasUsed,
|
|
634
|
+
gasLimits,
|
|
635
|
+
padArrayEnd(publicSetupCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
|
|
636
|
+
padArrayEnd(publicAppLogicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
|
|
637
|
+
publicTeardownCallRequest,
|
|
638
|
+
/*previousNonRevertibleAccumulatedDataArrayLengths=*/ PrivateToAvmAccumulatedDataArrayLengths.empty(),
|
|
639
|
+
/*previousRevertibleAccumulatedDataArrayLengths=*/ PrivateToAvmAccumulatedDataArrayLengths.empty(),
|
|
640
|
+
/*previousNonRevertibleAccumulatedDataArray=*/ PrivateToAvmAccumulatedData.empty(),
|
|
641
|
+
/*previousRevertibleAccumulatedDataArray=*/ PrivateToAvmAccumulatedData.empty(),
|
|
642
|
+
endTreeSnapshots,
|
|
643
|
+
endGasUsed,
|
|
644
|
+
/*accumulatedData=*/ this.getAvmAccumulatedData(),
|
|
645
|
+
transactionFee,
|
|
646
|
+
reverted,
|
|
489
647
|
);
|
|
490
648
|
}
|
|
491
649
|
|
|
650
|
+
public toPublicFunctionCallResult(
|
|
651
|
+
/** The execution environment of the nested call. */
|
|
652
|
+
_avmEnvironment: AvmExecutionEnvironment,
|
|
653
|
+
/** How much gas was available for this public execution. */
|
|
654
|
+
_startGasLeft: Gas,
|
|
655
|
+
/** How much gas was left after this public execution. */
|
|
656
|
+
_endGasLeft: Gas,
|
|
657
|
+
/** Bytecode used for this execution. */
|
|
658
|
+
_bytecode: Buffer,
|
|
659
|
+
/** The call's results */
|
|
660
|
+
_avmCallResults: AvmContractCallResult,
|
|
661
|
+
/** Function name for logging */
|
|
662
|
+
_functionName: string = 'unknown',
|
|
663
|
+
): PublicFunctionCallResult {
|
|
664
|
+
throw new Error('Not implemented');
|
|
665
|
+
}
|
|
666
|
+
|
|
492
667
|
public getUnencryptedLogs() {
|
|
493
668
|
return this.unencryptedLogs;
|
|
494
669
|
}
|
|
@@ -497,47 +672,25 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
497
672
|
return this.avmCircuitHints;
|
|
498
673
|
}
|
|
499
674
|
|
|
500
|
-
private
|
|
501
|
-
return new
|
|
502
|
-
RollupValidationRequests.empty(), // TODO(dbanks12): what should this be?
|
|
503
|
-
padArrayEnd(this.noteHashReadRequests, TreeLeafReadRequest.empty(), MAX_NOTE_HASH_READ_REQUESTS_PER_TX),
|
|
504
|
-
padArrayEnd(this.nullifierReadRequests, ScopedReadRequest.empty(), MAX_NULLIFIER_READ_REQUESTS_PER_TX),
|
|
675
|
+
private getAvmAccumulatedData() {
|
|
676
|
+
return new AvmAccumulatedData(
|
|
505
677
|
padArrayEnd(
|
|
506
|
-
this.
|
|
507
|
-
|
|
508
|
-
|
|
678
|
+
this.noteHashes.map(n => n.value),
|
|
679
|
+
Fr.zero(),
|
|
680
|
+
MAX_NOTE_HASHES_PER_TX,
|
|
509
681
|
),
|
|
510
|
-
padArrayEnd(this.l1ToL2MsgReadRequests, TreeLeafReadRequest.empty(), MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX),
|
|
511
|
-
// TODO(dbanks12): this is only necessary until VMCircuitPublicInputs uses unsiloed storage slots and pairs storage accesses with contract address
|
|
512
682
|
padArrayEnd(
|
|
513
|
-
this.
|
|
514
|
-
|
|
515
|
-
MAX_PUBLIC_DATA_READS_PER_TX,
|
|
516
|
-
),
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
private getAccumulatedData(gasUsed: Gas) {
|
|
521
|
-
return new PublicAccumulatedData(
|
|
522
|
-
padArrayEnd(this.noteHashes, ScopedNoteHash.empty(), MAX_NOTE_HASHES_PER_TX),
|
|
523
|
-
// TODO(dbanks12): should be able to use ScopedNullifier here
|
|
524
|
-
padArrayEnd(
|
|
525
|
-
this.nullifiers.map(n => new Nullifier(n.nullifier.value, n.nullifier.counter, n.nullifier.noteHash)),
|
|
526
|
-
Nullifier.empty(),
|
|
683
|
+
this.nullifiers.map(n => n.value),
|
|
684
|
+
Fr.zero(),
|
|
527
685
|
MAX_NULLIFIERS_PER_TX,
|
|
528
686
|
),
|
|
529
|
-
padArrayEnd(this.
|
|
530
|
-
/*noteEncryptedLogsHashes=*/ makeTuple(MAX_NOTE_ENCRYPTED_LOGS_PER_TX, LogHash.empty),
|
|
531
|
-
/*encryptedLogsHashes=*/ makeTuple(MAX_ENCRYPTED_LOGS_PER_TX, ScopedLogHash.empty),
|
|
687
|
+
padArrayEnd(this.l2ToL1Messages, ScopedL2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_TX),
|
|
532
688
|
padArrayEnd(this.unencryptedLogsHashes, ScopedLogHash.empty(), MAX_UNENCRYPTED_LOGS_PER_TX),
|
|
533
|
-
// TODO(dbanks12): this is only necessary until VMCircuitPublicInputs uses unsiloed storage slots and pairs storage accesses with contract address
|
|
534
689
|
padArrayEnd(
|
|
535
|
-
this.
|
|
536
|
-
|
|
690
|
+
this.publicDataWrites.map(w => new PublicDataWrite(w.leafSlot, w.newValue)),
|
|
691
|
+
PublicDataWrite.empty(),
|
|
537
692
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
538
693
|
),
|
|
539
|
-
/*publicCallStack=*/ makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicCallRequest.empty),
|
|
540
|
-
/*gasUsed=*/ gasUsed,
|
|
541
694
|
);
|
|
542
695
|
}
|
|
543
696
|
|
|
@@ -549,7 +702,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
549
702
|
// going to skip the read request and just revert instead" when the nullifier actually doesn't exist
|
|
550
703
|
// (or vice versa). So, if either maximum has been reached, any nullifier-reading operation must error.
|
|
551
704
|
if (
|
|
552
|
-
this.nullifierReadRequests.length + this.
|
|
705
|
+
this.nullifierReadRequests.length + this.previousSideEffectArrayLengths.nullifierReadRequests >=
|
|
553
706
|
MAX_NULLIFIER_READ_REQUESTS_PER_TX
|
|
554
707
|
) {
|
|
555
708
|
throw new SideEffectLimitReachedError(
|
|
@@ -559,7 +712,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
559
712
|
}
|
|
560
713
|
if (
|
|
561
714
|
this.nullifierNonExistentReadRequests.length +
|
|
562
|
-
this.
|
|
715
|
+
this.previousSideEffectArrayLengths.nullifierNonExistentReadRequests >=
|
|
563
716
|
MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX
|
|
564
717
|
) {
|
|
565
718
|
throw new SideEffectLimitReachedError(
|
|
@@ -569,16 +722,3 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
569
722
|
}
|
|
570
723
|
}
|
|
571
724
|
}
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* Helper function to create a public execution request from an AVM execution environment
|
|
575
|
-
*/
|
|
576
|
-
function createPublicCallRequest(avmEnvironment: AvmExecutionEnvironment): PublicCallRequest {
|
|
577
|
-
const callContext = CallContext.from({
|
|
578
|
-
msgSender: avmEnvironment.sender,
|
|
579
|
-
contractAddress: avmEnvironment.address,
|
|
580
|
-
functionSelector: avmEnvironment.functionSelector,
|
|
581
|
-
isStaticCall: avmEnvironment.isStaticCall,
|
|
582
|
-
});
|
|
583
|
-
return new PublicCallRequest(callContext, computeVarArgsHash(avmEnvironment.calldata), /*counter=*/ 0);
|
|
584
|
-
}
|