@aztec/simulator 0.37.0 → 0.39.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 +1 -1
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +2 -2
- package/dest/acvm/oracle/oracle.d.ts +6 -5
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +26 -30
- 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 +9 -9
- package/dest/avm/avm_execution_environment.d.ts +4 -3
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +17 -11
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +4 -1
- package/dest/avm/avm_machine_state.d.ts +5 -8
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +10 -22
- package/dest/avm/avm_memory_types.d.ts +1 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_message_call_result.d.ts +5 -8
- package/dest/avm/avm_message_call_result.d.ts.map +1 -1
- package/dest/avm/avm_message_call_result.js +1 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +19 -13
- package/dest/avm/errors.d.ts +43 -2
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +86 -4
- package/dest/avm/journal/journal.d.ts +20 -1
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +70 -9
- package/dest/avm/journal/nullifiers.d.ts +3 -1
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +14 -6
- package/dest/avm/journal/public_storage.d.ts +10 -1
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +17 -2
- package/dest/avm/journal/trace.d.ts +1 -4
- package/dest/avm/journal/trace.d.ts.map +1 -1
- package/dest/avm/journal/trace.js +4 -5
- package/dest/avm/journal/trace_types.d.ts +1 -0
- package/dest/avm/journal/trace_types.d.ts.map +1 -1
- package/dest/avm/journal/trace_types.js +1 -1
- package/dest/avm/opcodes/bitwise.d.ts +4 -1
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +14 -2
- package/dest/avm/opcodes/conversion.d.ts +16 -0
- package/dest/avm/opcodes/conversion.d.ts.map +1 -0
- package/dest/avm/opcodes/conversion.js +48 -0
- package/dest/avm/opcodes/environment_getters.d.ts +16 -12
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +19 -48
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +24 -13
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +6 -2
- package/dest/avm/serialization/instruction_serialization.d.ts +40 -38
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +42 -39
- package/dest/client/client_execution_context.d.ts +59 -19
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +97 -45
- package/dest/client/db_oracle.d.ts +4 -11
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/execution_result.d.ts +22 -15
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +59 -13
- package/dest/client/logs_cache.d.ts +33 -0
- package/dest/client/logs_cache.d.ts.map +1 -0
- package/dest/client/logs_cache.js +59 -0
- package/dest/client/private_execution.d.ts +2 -2
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +5 -7
- package/dest/client/simulator.d.ts +4 -34
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +5 -43
- package/dest/client/unconstrained_execution.d.ts +2 -2
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +1 -1
- package/dest/client/view_data_oracle.d.ts +0 -7
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +1 -10
- package/dest/common/errors.d.ts +5 -0
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +6 -1
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +3 -1
- package/dest/public/abstract_phase_manager.d.ts +10 -4
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +50 -19
- package/dest/public/app_logic_phase_manager.d.ts +1 -0
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/public/app_logic_phase_manager.js +3 -3
- package/dest/public/execution.d.ts +9 -0
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/executor.d.ts +2 -2
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +34 -17
- package/dest/public/hints_builder.d.ts +3 -3
- package/dest/public/hints_builder.d.ts.map +1 -1
- package/dest/public/hints_builder.js +3 -3
- package/dest/public/public_execution_context.d.ts +10 -4
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +19 -6
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +5 -3
- package/dest/public/setup_phase_manager.d.ts +1 -0
- package/dest/public/setup_phase_manager.d.ts.map +1 -1
- package/dest/public/setup_phase_manager.js +3 -2
- package/dest/public/tail_phase_manager.d.ts +1 -1
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +4 -26
- package/dest/public/teardown_phase_manager.d.ts +1 -0
- package/dest/public/teardown_phase_manager.d.ts.map +1 -1
- package/dest/public/teardown_phase_manager.js +3 -2
- package/dest/public/transitional_adaptors.d.ts +4 -17
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +27 -119
- package/dest/rollup/index.d.ts +2 -0
- package/dest/rollup/index.d.ts.map +1 -0
- package/dest/rollup/index.js +2 -0
- package/dest/rollup/rollup.d.ts +77 -0
- package/dest/rollup/rollup.d.ts.map +1 -0
- package/dest/rollup/rollup.js +78 -0
- package/dest/stats/index.d.ts +2 -0
- package/dest/stats/index.d.ts.map +1 -0
- package/dest/stats/index.js +2 -0
- package/dest/stats/stats.d.ts +4 -0
- package/dest/stats/stats.d.ts.map +1 -0
- package/dest/stats/stats.js +11 -0
- package/package.json +8 -8
- package/src/acvm/acvm.ts +2 -2
- package/src/acvm/oracle/oracle.ts +62 -36
- package/src/acvm/oracle/typed_oracle.ts +19 -11
- package/src/avm/avm_execution_environment.ts +34 -42
- package/src/avm/avm_gas.ts +3 -0
- package/src/avm/avm_machine_state.ts +14 -25
- package/src/avm/avm_memory_types.ts +1 -1
- package/src/avm/avm_message_call_result.ts +3 -14
- package/src/avm/avm_simulator.ts +24 -12
- package/src/avm/errors.ts +94 -4
- package/src/avm/journal/journal.ts +134 -9
- package/src/avm/journal/nullifiers.ts +19 -8
- package/src/avm/journal/public_storage.ts +23 -2
- package/src/avm/journal/trace.ts +3 -4
- package/src/avm/journal/trace_types.ts +1 -0
- package/src/avm/opcodes/bitwise.ts +18 -7
- package/src/avm/opcodes/conversion.ts +59 -0
- package/src/avm/opcodes/environment_getters.ts +21 -65
- package/src/avm/opcodes/external_calls.ts +32 -16
- package/src/avm/serialization/bytecode_serialization.ts +5 -0
- package/src/avm/serialization/instruction_serialization.ts +3 -0
- package/src/client/client_execution_context.ts +142 -46
- package/src/client/db_oracle.ts +4 -18
- package/src/client/execution_result.ts +75 -25
- package/src/client/logs_cache.ts +65 -0
- package/src/client/private_execution.ts +6 -10
- package/src/client/simulator.ts +8 -84
- package/src/client/unconstrained_execution.ts +2 -2
- package/src/client/view_data_oracle.ts +0 -10
- package/src/common/errors.ts +5 -0
- package/src/index.ts +1 -0
- package/src/mocks/fixtures.ts +2 -0
- package/src/public/abstract_phase_manager.ts +59 -23
- package/src/public/app_logic_phase_manager.ts +2 -1
- package/src/public/execution.ts +9 -0
- package/src/public/executor.ts +47 -14
- package/src/public/hints_builder.ts +5 -5
- package/src/public/public_execution_context.ts +18 -4
- package/src/public/public_processor.ts +8 -2
- package/src/public/setup_phase_manager.ts +16 -8
- package/src/public/tail_phase_manager.ts +8 -35
- package/src/public/teardown_phase_manager.ts +16 -8
- package/src/public/transitional_adaptors.ts +39 -177
- package/src/rollup/index.ts +1 -0
- package/src/rollup/rollup.ts +160 -0
- package/src/stats/index.ts +1 -0
- package/src/stats/stats.ts +20 -0
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
MerkleTreeId,
|
|
3
3
|
type ProcessReturnValues,
|
|
4
4
|
type PublicKernelRequest,
|
|
5
|
+
PublicKernelType,
|
|
5
6
|
type SimulationError,
|
|
6
7
|
type Tx,
|
|
7
8
|
type UnencryptedFunctionL2Logs,
|
|
@@ -31,7 +32,6 @@ import {
|
|
|
31
32
|
MembershipWitness,
|
|
32
33
|
NoteHash,
|
|
33
34
|
Nullifier,
|
|
34
|
-
type PrivateKernelTailCircuitPublicInputs,
|
|
35
35
|
type Proof,
|
|
36
36
|
PublicCallData,
|
|
37
37
|
type PublicCallRequest,
|
|
@@ -81,6 +81,20 @@ export const PhaseIsRevertible: Record<PublicKernelPhase, boolean> = {
|
|
|
81
81
|
[PublicKernelPhase.TAIL]: false,
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
// REFACTOR: Unify both enums and move to types or circuit-types.
|
|
85
|
+
export function publicKernelPhaseToKernelType(phase: PublicKernelPhase): PublicKernelType {
|
|
86
|
+
switch (phase) {
|
|
87
|
+
case PublicKernelPhase.SETUP:
|
|
88
|
+
return PublicKernelType.SETUP;
|
|
89
|
+
case PublicKernelPhase.APP_LOGIC:
|
|
90
|
+
return PublicKernelType.APP_LOGIC;
|
|
91
|
+
case PublicKernelPhase.TEARDOWN:
|
|
92
|
+
return PublicKernelType.TEARDOWN;
|
|
93
|
+
case PublicKernelPhase.TAIL:
|
|
94
|
+
return PublicKernelType.TAIL;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
84
98
|
export abstract class AbstractPhaseManager {
|
|
85
99
|
protected hintsBuilder: HintsBuilder;
|
|
86
100
|
protected log: DebugLogger;
|
|
@@ -127,13 +141,12 @@ export abstract class AbstractPhaseManager {
|
|
|
127
141
|
*/
|
|
128
142
|
revertReason: SimulationError | undefined;
|
|
129
143
|
returnValues: ProcessReturnValues;
|
|
144
|
+
/** Gas used during the execution this particular phase. */
|
|
145
|
+
gasUsed: Gas | undefined;
|
|
130
146
|
}>;
|
|
131
147
|
|
|
132
|
-
public static extractEnqueuedPublicCallsByPhase(
|
|
133
|
-
|
|
134
|
-
enqueuedPublicFunctionCalls: PublicCallRequest[],
|
|
135
|
-
): Record<PublicKernelPhase, PublicCallRequest[]> {
|
|
136
|
-
const data = publicInputs.forPublic;
|
|
148
|
+
public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelPhase, PublicCallRequest[]> {
|
|
149
|
+
const data = tx.data.forPublic;
|
|
137
150
|
if (!data) {
|
|
138
151
|
return {
|
|
139
152
|
[PublicKernelPhase.SETUP]: [],
|
|
@@ -142,7 +155,7 @@ export abstract class AbstractPhaseManager {
|
|
|
142
155
|
[PublicKernelPhase.TAIL]: [],
|
|
143
156
|
};
|
|
144
157
|
}
|
|
145
|
-
const publicCallsStack = enqueuedPublicFunctionCalls.slice().reverse();
|
|
158
|
+
const publicCallsStack = tx.enqueuedPublicFunctionCalls.slice().reverse();
|
|
146
159
|
const nonRevertibleCallStack = data.endNonRevertibleData.publicCallStack.filter(i => !i.isEmpty());
|
|
147
160
|
const revertibleCallStack = data.end.publicCallStack.filter(i => !i.isEmpty());
|
|
148
161
|
|
|
@@ -169,39 +182,40 @@ export abstract class AbstractPhaseManager {
|
|
|
169
182
|
c => revertibleCallStack.findIndex(p => p.equals(c)) !== -1,
|
|
170
183
|
);
|
|
171
184
|
|
|
185
|
+
const teardownCallStack = tx.publicTeardownFunctionCall.isEmpty() ? [] : [tx.publicTeardownFunctionCall];
|
|
186
|
+
|
|
172
187
|
if (firstRevertibleCallIndex === 0) {
|
|
173
188
|
return {
|
|
174
189
|
[PublicKernelPhase.SETUP]: [],
|
|
175
190
|
[PublicKernelPhase.APP_LOGIC]: publicCallsStack,
|
|
176
|
-
[PublicKernelPhase.TEARDOWN]:
|
|
191
|
+
[PublicKernelPhase.TEARDOWN]: teardownCallStack,
|
|
177
192
|
[PublicKernelPhase.TAIL]: [],
|
|
178
193
|
};
|
|
179
194
|
} else if (firstRevertibleCallIndex === -1) {
|
|
180
195
|
// there's no app logic, split the functions between setup (many) and teardown (just one function call)
|
|
181
196
|
return {
|
|
182
|
-
[PublicKernelPhase.SETUP]: publicCallsStack
|
|
197
|
+
[PublicKernelPhase.SETUP]: publicCallsStack,
|
|
183
198
|
[PublicKernelPhase.APP_LOGIC]: [],
|
|
184
|
-
[PublicKernelPhase.TEARDOWN]:
|
|
199
|
+
[PublicKernelPhase.TEARDOWN]: teardownCallStack,
|
|
185
200
|
[PublicKernelPhase.TAIL]: [],
|
|
186
201
|
};
|
|
187
202
|
} else {
|
|
188
203
|
return {
|
|
189
|
-
[PublicKernelPhase.SETUP]: publicCallsStack.slice(0, firstRevertibleCallIndex
|
|
204
|
+
[PublicKernelPhase.SETUP]: publicCallsStack.slice(0, firstRevertibleCallIndex),
|
|
190
205
|
[PublicKernelPhase.APP_LOGIC]: publicCallsStack.slice(firstRevertibleCallIndex),
|
|
191
|
-
[PublicKernelPhase.TEARDOWN]:
|
|
206
|
+
[PublicKernelPhase.TEARDOWN]: teardownCallStack,
|
|
192
207
|
[PublicKernelPhase.TAIL]: [],
|
|
193
208
|
};
|
|
194
209
|
}
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
protected extractEnqueuedPublicCalls(tx: Tx): PublicCallRequest[] {
|
|
198
|
-
const calls = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx
|
|
199
|
-
this.phase
|
|
200
|
-
];
|
|
213
|
+
const calls = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx)[this.phase];
|
|
201
214
|
|
|
202
215
|
return calls;
|
|
203
216
|
}
|
|
204
217
|
|
|
218
|
+
// REFACTOR: Do not return an array and instead return a struct with similar shape to that returned by `handle`
|
|
205
219
|
protected async processEnqueuedPublicCalls(
|
|
206
220
|
tx: Tx,
|
|
207
221
|
previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
|
|
@@ -214,6 +228,7 @@ export abstract class AbstractPhaseManager {
|
|
|
214
228
|
UnencryptedFunctionL2Logs[],
|
|
215
229
|
SimulationError | undefined,
|
|
216
230
|
ProcessReturnValues,
|
|
231
|
+
Gas,
|
|
217
232
|
]
|
|
218
233
|
> {
|
|
219
234
|
let kernelOutput = previousPublicKernelOutput;
|
|
@@ -223,7 +238,7 @@ export abstract class AbstractPhaseManager {
|
|
|
223
238
|
const enqueuedCalls = this.extractEnqueuedPublicCalls(tx);
|
|
224
239
|
|
|
225
240
|
if (!enqueuedCalls || !enqueuedCalls.length) {
|
|
226
|
-
return [[], kernelOutput, kernelProof, [], undefined, undefined];
|
|
241
|
+
return [[], kernelOutput, kernelProof, [], undefined, undefined, Gas.empty()];
|
|
227
242
|
}
|
|
228
243
|
|
|
229
244
|
const newUnencryptedFunctionLogs: UnencryptedFunctionL2Logs[] = [];
|
|
@@ -236,6 +251,7 @@ export abstract class AbstractPhaseManager {
|
|
|
236
251
|
// and submitted separately to the base rollup?
|
|
237
252
|
|
|
238
253
|
let returns: ProcessReturnValues = undefined;
|
|
254
|
+
let gasUsed = Gas.empty();
|
|
239
255
|
|
|
240
256
|
for (const enqueuedCall of enqueuedCalls) {
|
|
241
257
|
const executionStack: (PublicExecution | PublicExecutionResult)[] = [enqueuedCall];
|
|
@@ -246,8 +262,10 @@ export abstract class AbstractPhaseManager {
|
|
|
246
262
|
while (executionStack.length) {
|
|
247
263
|
const current = executionStack.pop()!;
|
|
248
264
|
const isExecutionRequest = !isPublicExecutionResult(current);
|
|
265
|
+
// TODO(6052): Extract correct new counter from nested calls
|
|
249
266
|
const sideEffectCounter = lastSideEffectCounter(tx) + 1;
|
|
250
|
-
const availableGas = this.getAvailableGas(tx,
|
|
267
|
+
const availableGas = this.getAvailableGas(tx, kernelOutput);
|
|
268
|
+
const pendingNullifiers = this.getSiloedPendingNullifiers(kernelOutput);
|
|
251
269
|
|
|
252
270
|
const result = isExecutionRequest
|
|
253
271
|
? await this.publicExecutor.simulate(
|
|
@@ -255,12 +273,24 @@ export abstract class AbstractPhaseManager {
|
|
|
255
273
|
this.globalVariables,
|
|
256
274
|
availableGas,
|
|
257
275
|
tx.data.constants.txContext,
|
|
276
|
+
pendingNullifiers,
|
|
258
277
|
transactionFee,
|
|
259
278
|
sideEffectCounter,
|
|
260
279
|
)
|
|
261
280
|
: current;
|
|
262
281
|
|
|
282
|
+
// Sanity check for a current upstream assumption.
|
|
283
|
+
// Consumers of the result seem to expect "reverted <=> revertReason !== undefined".
|
|
263
284
|
const functionSelector = result.execution.functionData.selector.toString();
|
|
285
|
+
if (result.reverted && !result.revertReason) {
|
|
286
|
+
throw new Error(
|
|
287
|
+
`Simulation of ${result.execution.contractAddress.toString()}:${functionSelector} reverted with no reason.`,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Accumulate gas used in this execution
|
|
292
|
+
gasUsed = gasUsed.add(Gas.from(result.startGasLeft).sub(Gas.from(result.endGasLeft)));
|
|
293
|
+
|
|
264
294
|
if (result.reverted && !PhaseIsRevertible[this.phase]) {
|
|
265
295
|
this.log.debug(
|
|
266
296
|
`Simulation error on ${result.execution.contractAddress.toString()}:${functionSelector} with reason: ${
|
|
@@ -270,7 +300,9 @@ export abstract class AbstractPhaseManager {
|
|
|
270
300
|
throw result.revertReason;
|
|
271
301
|
}
|
|
272
302
|
|
|
273
|
-
|
|
303
|
+
if (isExecutionRequest) {
|
|
304
|
+
newUnencryptedFunctionLogs.push(result.allUnencryptedLogs);
|
|
305
|
+
}
|
|
274
306
|
|
|
275
307
|
this.log.debug(
|
|
276
308
|
`Running public kernel circuit for ${result.execution.contractAddress.toString()}:${functionSelector}`,
|
|
@@ -301,7 +333,8 @@ export abstract class AbstractPhaseManager {
|
|
|
301
333
|
result.revertReason
|
|
302
334
|
}`,
|
|
303
335
|
);
|
|
304
|
-
|
|
336
|
+
// TODO(@spalladino): Check gasUsed is correct. The AVM should take care of setting gasLeft to zero upon a revert.
|
|
337
|
+
return [[], kernelOutput, kernelProof, [], result.revertReason, undefined, gasUsed];
|
|
305
338
|
}
|
|
306
339
|
|
|
307
340
|
if (!enqueuedExecutionResult) {
|
|
@@ -317,7 +350,12 @@ export abstract class AbstractPhaseManager {
|
|
|
317
350
|
// TODO(#3675): This should be done in a public kernel circuit
|
|
318
351
|
removeRedundantPublicDataWrites(kernelOutput, this.phase);
|
|
319
352
|
|
|
320
|
-
return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns];
|
|
353
|
+
return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns, gasUsed];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Returns all pending private and public nullifiers. */
|
|
357
|
+
private getSiloedPendingNullifiers(ko: PublicKernelCircuitPublicInputs) {
|
|
358
|
+
return [...ko.end.newNullifiers, ...ko.endNonRevertibleData.newNullifiers].filter(n => !n.isEmpty());
|
|
321
359
|
}
|
|
322
360
|
|
|
323
361
|
protected getAvailableGas(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
|
|
@@ -382,8 +420,6 @@ export abstract class AbstractPhaseManager {
|
|
|
382
420
|
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
|
|
383
421
|
);
|
|
384
422
|
|
|
385
|
-
const unencryptedLogPreimagesLength = new Fr(result.unencryptedLogs.getSerializedLength());
|
|
386
|
-
|
|
387
423
|
const publicCircuitPublicInputs = PublicCircuitPublicInputs.from({
|
|
388
424
|
callContext: result.execution.callContext,
|
|
389
425
|
proverAddress: AztecAddress.ZERO,
|
|
@@ -420,7 +456,7 @@ export abstract class AbstractPhaseManager {
|
|
|
420
456
|
SideEffect.empty(),
|
|
421
457
|
MAX_UNENCRYPTED_LOGS_PER_CALL,
|
|
422
458
|
),
|
|
423
|
-
unencryptedLogPreimagesLength,
|
|
459
|
+
unencryptedLogPreimagesLength: result.unencryptedLogPreimagesLength,
|
|
424
460
|
historicalHeader: this.historicalHeader,
|
|
425
461
|
globalVariables: this.globalVariables,
|
|
426
462
|
startGasLeft: Gas.from(result.startGasLeft),
|
|
@@ -47,6 +47,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
|
|
|
47
47
|
newUnencryptedFunctionLogs,
|
|
48
48
|
revertReason,
|
|
49
49
|
returnValues,
|
|
50
|
+
gasUsed,
|
|
50
51
|
] = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousPublicKernelProof).catch(
|
|
51
52
|
// if we throw for any reason other than simulation, we need to rollback and drop the TX
|
|
52
53
|
async err => {
|
|
@@ -71,6 +72,6 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
|
|
|
71
72
|
};
|
|
72
73
|
return request;
|
|
73
74
|
});
|
|
74
|
-
return { kernelRequests, publicKernelOutput, publicKernelProof, revertReason, returnValues };
|
|
75
|
+
return { kernelRequests, publicKernelOutput, publicKernelProof, revertReason, returnValues, gasUsed };
|
|
75
76
|
}
|
|
76
77
|
}
|
package/src/public/execution.ts
CHANGED
|
@@ -54,6 +54,15 @@ export interface PublicExecutionResult {
|
|
|
54
54
|
* Note: These are preimages to `unencryptedLogsHashes`.
|
|
55
55
|
*/
|
|
56
56
|
unencryptedLogs: UnencryptedFunctionL2Logs;
|
|
57
|
+
/**
|
|
58
|
+
* Length of the unencrypted log preimages emitted in this function call.
|
|
59
|
+
*/
|
|
60
|
+
unencryptedLogPreimagesLength: Fr;
|
|
61
|
+
/**
|
|
62
|
+
* Unencrypted logs emitted during this call AND any nested calls.
|
|
63
|
+
* Useful for maintaining correct ordering in ts.
|
|
64
|
+
*/
|
|
65
|
+
allUnencryptedLogs: UnencryptedFunctionL2Logs;
|
|
57
66
|
/**
|
|
58
67
|
* Whether the execution reverted.
|
|
59
68
|
*/
|
package/src/public/executor.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Gas,
|
|
5
5
|
type GlobalVariables,
|
|
6
6
|
type Header,
|
|
7
|
+
type Nullifier,
|
|
7
8
|
PublicCircuitPublicInputs,
|
|
8
9
|
type TxContext,
|
|
9
10
|
} from '@aztec/circuits.js';
|
|
@@ -26,7 +27,7 @@ import { PackedValuesCache } from '../common/packed_values_cache.js';
|
|
|
26
27
|
import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db.js';
|
|
27
28
|
import { type PublicExecution, type PublicExecutionResult, checkValidStaticCall } from './execution.js';
|
|
28
29
|
import { PublicExecutionContext } from './public_execution_context.js';
|
|
29
|
-
import {
|
|
30
|
+
import { convertAvmResultsToPxResult, createAvmExecutionEnvironment, isAvmBytecode } from './transitional_adaptors.js';
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Execute a public function and return the execution result.
|
|
@@ -46,15 +47,23 @@ export async function executePublicFunction(
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
if (isAvmBytecode(bytecode)) {
|
|
49
|
-
return await
|
|
50
|
+
return await executeTopLevelPublicFunctionAvm(context, bytecode);
|
|
50
51
|
} else {
|
|
51
52
|
return await executePublicFunctionAcvm(context, bytecode, nested);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Execute a top-level public function call (the first call in an enqueued-call/execution-request) in the AVM.
|
|
58
|
+
* Translate the results back to the PublicExecutionResult format.
|
|
59
|
+
*/
|
|
60
|
+
async function executeTopLevelPublicFunctionAvm(
|
|
61
|
+
executionContext: PublicExecutionContext,
|
|
62
|
+
bytecode: Buffer,
|
|
63
|
+
): Promise<PublicExecutionResult> {
|
|
56
64
|
const address = executionContext.execution.contractAddress;
|
|
57
65
|
const selector = executionContext.execution.functionData.selector;
|
|
66
|
+
const startGas = executionContext.availableGas;
|
|
58
67
|
const log = createDebugLogger('aztec:simulator:public_execution');
|
|
59
68
|
log.verbose(`[AVM] Executing public external function ${address.toString()}:${selector}.`);
|
|
60
69
|
|
|
@@ -65,7 +74,15 @@ async function executePublicFunctionAvm(executionContext: PublicExecutionContext
|
|
|
65
74
|
executionContext.contractsDb,
|
|
66
75
|
executionContext.commitmentsDb,
|
|
67
76
|
);
|
|
77
|
+
|
|
78
|
+
// TODO(6207): add sideEffectCounter to persistableState construction
|
|
79
|
+
// or modify the PersistableStateManager to manage rollbacks across enqueued-calls and transactions.
|
|
68
80
|
const worldStateJournal = new AvmPersistableStateManager(hostStorage);
|
|
81
|
+
const startSideEffectCounter = executionContext.execution.callContext.sideEffectCounter;
|
|
82
|
+
for (const nullifier of executionContext.pendingNullifiers) {
|
|
83
|
+
worldStateJournal.nullifiers.cache.appendSiloed(nullifier.value);
|
|
84
|
+
}
|
|
85
|
+
worldStateJournal.trace.accessCounter = startSideEffectCounter;
|
|
69
86
|
|
|
70
87
|
const executionEnv = createAvmExecutionEnvironment(
|
|
71
88
|
executionContext.execution,
|
|
@@ -75,18 +92,30 @@ async function executePublicFunctionAvm(executionContext: PublicExecutionContext
|
|
|
75
92
|
executionContext.transactionFee,
|
|
76
93
|
);
|
|
77
94
|
|
|
78
|
-
const machineState = new AvmMachineState(
|
|
79
|
-
const
|
|
80
|
-
const simulator = new AvmSimulator(
|
|
95
|
+
const machineState = new AvmMachineState(startGas);
|
|
96
|
+
const avmContext = new AvmContext(worldStateJournal, executionEnv, machineState);
|
|
97
|
+
const simulator = new AvmSimulator(avmContext);
|
|
98
|
+
|
|
99
|
+
const avmResult = await simulator.executeBytecode(bytecode);
|
|
81
100
|
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
// Commit the journals state to the DBs since this is a top-level execution.
|
|
102
|
+
// Observe that this will write all the state changes to the DBs, not only the latest for each slot.
|
|
103
|
+
// However, the underlying DB keep a cache and will only write the latest state to disk.
|
|
104
|
+
await avmContext.persistableState.publicStorage.commitToDB();
|
|
84
105
|
|
|
85
106
|
log.verbose(
|
|
86
|
-
`[AVM] ${address.toString()}:${selector} returned, reverted: ${
|
|
107
|
+
`[AVM] ${address.toString()}:${selector} returned, reverted: ${avmResult.reverted}, reason: ${
|
|
108
|
+
avmResult.revertReason
|
|
109
|
+
}.`,
|
|
87
110
|
);
|
|
88
111
|
|
|
89
|
-
return
|
|
112
|
+
return convertAvmResultsToPxResult(
|
|
113
|
+
avmResult,
|
|
114
|
+
startSideEffectCounter,
|
|
115
|
+
executionContext.execution,
|
|
116
|
+
startGas,
|
|
117
|
+
avmContext,
|
|
118
|
+
);
|
|
90
119
|
}
|
|
91
120
|
|
|
92
121
|
async function executePublicFunctionAcvm(
|
|
@@ -139,10 +168,6 @@ async function executePublicFunctionAcvm(
|
|
|
139
168
|
})();
|
|
140
169
|
|
|
141
170
|
if (reverted) {
|
|
142
|
-
if (!revertReason) {
|
|
143
|
-
throw new Error('Reverted but no revert reason');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
171
|
return {
|
|
147
172
|
execution,
|
|
148
173
|
returnValues: [],
|
|
@@ -159,6 +184,8 @@ async function executePublicFunctionAcvm(
|
|
|
159
184
|
nestedExecutions: [],
|
|
160
185
|
unencryptedLogsHashes: [],
|
|
161
186
|
unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|
|
187
|
+
unencryptedLogPreimagesLength: new Fr(4n), // empty logs have len 4
|
|
188
|
+
allUnencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|
|
162
189
|
reverted,
|
|
163
190
|
revertReason,
|
|
164
191
|
startGasLeft: context.availableGas,
|
|
@@ -182,6 +209,7 @@ async function executePublicFunctionAcvm(
|
|
|
182
209
|
startSideEffectCounter,
|
|
183
210
|
endSideEffectCounter,
|
|
184
211
|
unencryptedLogsHashes: unencryptedLogsHashesPadded,
|
|
212
|
+
unencryptedLogPreimagesLength,
|
|
185
213
|
} = PublicCircuitPublicInputs.fromFields(returnWitness);
|
|
186
214
|
const returnValues = await context.unpackReturns(returnsHash);
|
|
187
215
|
|
|
@@ -207,6 +235,7 @@ async function executePublicFunctionAcvm(
|
|
|
207
235
|
|
|
208
236
|
const nestedExecutions = context.getNestedExecutions();
|
|
209
237
|
const unencryptedLogs = context.getUnencryptedLogs();
|
|
238
|
+
const allUnencryptedLogs = context.getAllUnencryptedLogs();
|
|
210
239
|
|
|
211
240
|
// TODO(palla/gas): We should be loading these values from the returned PublicCircuitPublicInputs
|
|
212
241
|
const startGasLeft = context.availableGas;
|
|
@@ -227,6 +256,8 @@ async function executePublicFunctionAcvm(
|
|
|
227
256
|
nestedExecutions,
|
|
228
257
|
unencryptedLogsHashes,
|
|
229
258
|
unencryptedLogs,
|
|
259
|
+
unencryptedLogPreimagesLength,
|
|
260
|
+
allUnencryptedLogs,
|
|
230
261
|
reverted: false,
|
|
231
262
|
revertReason: undefined,
|
|
232
263
|
startGasLeft,
|
|
@@ -258,6 +289,7 @@ export class PublicExecutor {
|
|
|
258
289
|
globalVariables: GlobalVariables,
|
|
259
290
|
availableGas: Gas,
|
|
260
291
|
txContext: TxContext,
|
|
292
|
+
pendingNullifiers: Nullifier[],
|
|
261
293
|
transactionFee: Fr = Fr.ZERO,
|
|
262
294
|
sideEffectCounter: number = 0,
|
|
263
295
|
): Promise<PublicExecutionResult> {
|
|
@@ -277,6 +309,7 @@ export class PublicExecutor {
|
|
|
277
309
|
availableGas,
|
|
278
310
|
transactionFee,
|
|
279
311
|
txContext.gasSettings,
|
|
312
|
+
pendingNullifiers,
|
|
280
313
|
);
|
|
281
314
|
|
|
282
315
|
const executionResult = await executePublicFunction(context, /*nested=*/ false);
|
|
@@ -15,11 +15,11 @@ import {
|
|
|
15
15
|
type PublicDataRead,
|
|
16
16
|
type PublicDataTreeLeafPreimage,
|
|
17
17
|
type PublicDataUpdateRequest,
|
|
18
|
-
type
|
|
18
|
+
type ScopedReadRequest,
|
|
19
19
|
buildNullifierNonExistentReadRequestHints,
|
|
20
|
-
buildNullifierReadRequestHints,
|
|
21
20
|
buildPublicDataHints,
|
|
22
21
|
buildPublicDataReadRequestHints,
|
|
22
|
+
buildSiloedNullifierReadRequestHints,
|
|
23
23
|
} from '@aztec/circuits.js';
|
|
24
24
|
import { type Tuple } from '@aztec/foundation/serialize';
|
|
25
25
|
import { type IndexedTreeId, type MerkleTreeOperations } from '@aztec/world-state';
|
|
@@ -28,14 +28,14 @@ export class HintsBuilder {
|
|
|
28
28
|
constructor(private db: MerkleTreeOperations) {}
|
|
29
29
|
|
|
30
30
|
getNullifierReadRequestHints(
|
|
31
|
-
nullifierReadRequests: Tuple<
|
|
31
|
+
nullifierReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
32
32
|
pendingNullifiers: Tuple<Nullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
33
33
|
) {
|
|
34
|
-
return
|
|
34
|
+
return buildSiloedNullifierReadRequestHints(this, nullifierReadRequests, pendingNullifiers);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
getNullifierNonExistentReadRequestHints(
|
|
38
|
-
nullifierNonExistentReadRequests: Tuple<
|
|
38
|
+
nullifierNonExistentReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX>,
|
|
39
39
|
pendingNullifiers: Tuple<Nullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
40
40
|
) {
|
|
41
41
|
return buildNullifierNonExistentReadRequestHints(this, nullifierNonExistentReadRequests, pendingNullifiers);
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type GasSettings,
|
|
8
8
|
type GlobalVariables,
|
|
9
9
|
type Header,
|
|
10
|
+
type Nullifier,
|
|
10
11
|
PublicContextInputs,
|
|
11
12
|
} from '@aztec/circuits.js';
|
|
12
13
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
@@ -37,13 +38,18 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
37
38
|
public readonly header: Header,
|
|
38
39
|
public readonly globalVariables: GlobalVariables,
|
|
39
40
|
private readonly packedValuesCache: PackedValuesCache,
|
|
40
|
-
|
|
41
|
+
// TRANSITIONAL: once AVM-ACVM interoperability is removed (fully functional AVM), sideEffectCounter can be made private
|
|
42
|
+
public readonly sideEffectCounter: SideEffectCounter,
|
|
41
43
|
public readonly stateDb: PublicStateDB,
|
|
42
44
|
public readonly contractsDb: PublicContractsDB,
|
|
43
45
|
public readonly commitmentsDb: CommitmentsDB,
|
|
44
46
|
public readonly availableGas: Gas,
|
|
45
47
|
public readonly transactionFee: Fr,
|
|
46
48
|
public readonly gasSettings: GasSettings,
|
|
49
|
+
public readonly pendingNullifiers: Nullifier[],
|
|
50
|
+
// Unencrypted logs emitted during this call AND any nested calls
|
|
51
|
+
// Useful for maintaining correct ordering in ts
|
|
52
|
+
private allUnencryptedLogs: UnencryptedL2Log[] = [],
|
|
47
53
|
private log = createDebugLogger('aztec:simulator:public_execution_context'),
|
|
48
54
|
) {
|
|
49
55
|
super();
|
|
@@ -87,6 +93,13 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
87
93
|
return new UnencryptedFunctionL2Logs(this.unencryptedLogs);
|
|
88
94
|
}
|
|
89
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Return the encrypted logs emitted during this execution, including nested calls.
|
|
98
|
+
*/
|
|
99
|
+
public getAllUnencryptedLogs() {
|
|
100
|
+
return new UnencryptedFunctionL2Logs(this.allUnencryptedLogs);
|
|
101
|
+
}
|
|
102
|
+
|
|
90
103
|
/**
|
|
91
104
|
* Return the data read and updated during this execution.
|
|
92
105
|
*/
|
|
@@ -135,11 +148,10 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
135
148
|
* Emit an unencrypted log.
|
|
136
149
|
* @param log - The unencrypted log to be emitted.
|
|
137
150
|
*/
|
|
138
|
-
public override emitUnencryptedLog(log: UnencryptedL2Log) {
|
|
139
|
-
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/885)
|
|
151
|
+
public override emitUnencryptedLog(log: UnencryptedL2Log, _counter: number) {
|
|
140
152
|
this.unencryptedLogs.push(log);
|
|
153
|
+
this.allUnencryptedLogs.push(log);
|
|
141
154
|
this.log.verbose(`Emitted unencrypted log: "${log.toHumanReadable()}"`);
|
|
142
|
-
return Fr.fromBuffer(log.hash());
|
|
143
155
|
}
|
|
144
156
|
|
|
145
157
|
/**
|
|
@@ -229,6 +241,8 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
229
241
|
this.availableGas,
|
|
230
242
|
this.transactionFee,
|
|
231
243
|
this.gasSettings,
|
|
244
|
+
/*pendingNullifiers=*/ [],
|
|
245
|
+
this.allUnencryptedLogs,
|
|
232
246
|
this.log,
|
|
233
247
|
);
|
|
234
248
|
|
|
@@ -20,7 +20,11 @@ import { PublicExecutor, type PublicStateDB, type SimulationProvider } from '@az
|
|
|
20
20
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
21
21
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
22
22
|
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
type AbstractPhaseManager,
|
|
25
|
+
PublicKernelPhase,
|
|
26
|
+
publicKernelPhaseToKernelType,
|
|
27
|
+
} from './abstract_phase_manager.js';
|
|
24
28
|
import { PhaseManagerFactory } from './phase_manager_factory.js';
|
|
25
29
|
import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from './public_executor.js';
|
|
26
30
|
import { RealPublicKernelCircuitSimulator } from './public_kernel.js';
|
|
@@ -169,8 +173,10 @@ export class PublicProcessor {
|
|
|
169
173
|
let finalKernelOutput: KernelCircuitPublicInputs | undefined;
|
|
170
174
|
let revertReason: SimulationError | undefined;
|
|
171
175
|
const timer = new Timer();
|
|
176
|
+
const gasUsed: ProcessedTx['gasUsed'] = {};
|
|
172
177
|
while (phase) {
|
|
173
178
|
const output = await phase.handle(tx, publicKernelPublicInput, proof);
|
|
179
|
+
gasUsed[publicKernelPhaseToKernelType(phase.phase)] = output.gasUsed;
|
|
174
180
|
if (phase.phase === PublicKernelPhase.APP_LOGIC) {
|
|
175
181
|
returnValues = output.returnValues;
|
|
176
182
|
}
|
|
@@ -196,7 +202,7 @@ export class PublicProcessor {
|
|
|
196
202
|
throw new Error('Final public kernel was not executed.');
|
|
197
203
|
}
|
|
198
204
|
|
|
199
|
-
const processedTx = makeProcessedTx(tx, finalKernelOutput, proof, publicRequests, revertReason);
|
|
205
|
+
const processedTx = makeProcessedTx(tx, finalKernelOutput, proof, publicRequests, revertReason, gasUsed);
|
|
200
206
|
|
|
201
207
|
this.log.debug(`Processed public part of ${tx.getTxHash()}`, {
|
|
202
208
|
eventName: 'tx-sequencer-processing',
|
|
@@ -35,14 +35,21 @@ export class SetupPhaseManager extends AbstractPhaseManager {
|
|
|
35
35
|
previousPublicKernelProof: Proof,
|
|
36
36
|
) {
|
|
37
37
|
this.log.verbose(`Processing tx ${tx.getTxHash()}`);
|
|
38
|
-
const [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
const [
|
|
39
|
+
kernelInputs,
|
|
40
|
+
publicKernelOutput,
|
|
41
|
+
publicKernelProof,
|
|
42
|
+
newUnencryptedFunctionLogs,
|
|
43
|
+
revertReason,
|
|
44
|
+
_returnValues,
|
|
45
|
+
gasUsed,
|
|
46
|
+
] = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousPublicKernelProof).catch(
|
|
47
|
+
// the abstract phase manager throws if simulation gives error in a non-revertible phase
|
|
48
|
+
async err => {
|
|
49
|
+
await this.publicStateDB.rollbackToCommit();
|
|
50
|
+
throw err;
|
|
51
|
+
},
|
|
52
|
+
);
|
|
46
53
|
tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs);
|
|
47
54
|
await this.publicStateDB.checkpoint();
|
|
48
55
|
|
|
@@ -61,6 +68,7 @@ export class SetupPhaseManager extends AbstractPhaseManager {
|
|
|
61
68
|
publicKernelProof,
|
|
62
69
|
revertReason,
|
|
63
70
|
returnValues: undefined,
|
|
71
|
+
gasUsed,
|
|
64
72
|
};
|
|
65
73
|
}
|
|
66
74
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type PublicKernelRequest,
|
|
3
|
-
PublicKernelType,
|
|
4
|
-
type Tx,
|
|
5
|
-
UnencryptedFunctionL2Logs,
|
|
6
|
-
type UnencryptedL2Log,
|
|
7
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { type PublicKernelRequest, PublicKernelType, type Tx } from '@aztec/circuit-types';
|
|
8
2
|
import {
|
|
9
3
|
Fr,
|
|
10
4
|
type GlobalVariables,
|
|
@@ -45,7 +39,11 @@ export class TailPhaseManager extends AbstractPhaseManager {
|
|
|
45
39
|
super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
|
|
46
40
|
}
|
|
47
41
|
|
|
48
|
-
async handle(
|
|
42
|
+
override async handle(
|
|
43
|
+
tx: Tx,
|
|
44
|
+
previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
|
|
45
|
+
previousPublicKernelProof: Proof,
|
|
46
|
+
) {
|
|
49
47
|
this.log.verbose(`Processing tx ${tx.getTxHash()}`);
|
|
50
48
|
const [inputs, finalKernelOutput] = await this.runTailKernelCircuit(
|
|
51
49
|
previousPublicKernelOutput,
|
|
@@ -57,8 +55,6 @@ export class TailPhaseManager extends AbstractPhaseManager {
|
|
|
57
55
|
throw err;
|
|
58
56
|
},
|
|
59
57
|
);
|
|
60
|
-
// Temporary hack. Should sort them in the tail circuit.
|
|
61
|
-
this.patchLogsOrdering(tx, previousPublicKernelOutput);
|
|
62
58
|
// commit the state updates from this transaction
|
|
63
59
|
await this.publicStateDB.commit();
|
|
64
60
|
|
|
@@ -75,6 +71,7 @@ export class TailPhaseManager extends AbstractPhaseManager {
|
|
|
75
71
|
publicKernelProof: makeEmptyProof(),
|
|
76
72
|
revertReason: undefined,
|
|
77
73
|
returnValues: undefined,
|
|
74
|
+
gasUsed: undefined,
|
|
78
75
|
};
|
|
79
76
|
}
|
|
80
77
|
|
|
@@ -163,33 +160,9 @@ export class TailPhaseManager extends AbstractPhaseManager {
|
|
|
163
160
|
}
|
|
164
161
|
|
|
165
162
|
private sortLogsHashes<N extends number>(unencryptedLogsHashes: Tuple<SideEffect, N>): Tuple<SideEffect, N> {
|
|
163
|
+
// TODO(6052): logs here may have duplicate counters from nested calls
|
|
166
164
|
return sortByCounter(
|
|
167
165
|
unencryptedLogsHashes.map(n => ({ ...n, counter: n.counter.toNumber(), isEmpty: () => n.isEmpty() })),
|
|
168
166
|
).map(h => new SideEffect(h.value, new Fr(h.counter))) as Tuple<SideEffect, N>;
|
|
169
167
|
}
|
|
170
|
-
|
|
171
|
-
// As above, this is a hack for unencrypted logs ordering, now they are sorted. Since the public kernel
|
|
172
|
-
// cannot keep track of side effects that happen after or before a nested call, we override the gathered logs.
|
|
173
|
-
// As a sanity check, we at least verify that the elements are the same, so we are only tweaking their ordering.
|
|
174
|
-
// See same fn in pxe_service.ts
|
|
175
|
-
// Added as part of resolving #5017
|
|
176
|
-
private patchLogsOrdering(tx: Tx, publicInputs: PublicKernelCircuitPublicInputs) {
|
|
177
|
-
const unencLogs = tx.unencryptedLogs.unrollLogs();
|
|
178
|
-
const sortedUnencLogs = publicInputs.end.unencryptedLogsHashes;
|
|
179
|
-
|
|
180
|
-
const finalUnencLogs: UnencryptedL2Log[] = [];
|
|
181
|
-
sortedUnencLogs.forEach((sideEffect: SideEffect) => {
|
|
182
|
-
if (!sideEffect.isEmpty()) {
|
|
183
|
-
const isLog = (log: UnencryptedL2Log) => Fr.fromBuffer(log.hash()).equals(sideEffect.value);
|
|
184
|
-
const thisLogIndex = unencLogs.findIndex(isLog);
|
|
185
|
-
finalUnencLogs.push(unencLogs[thisLogIndex]);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
const unencryptedLogs = new UnencryptedFunctionL2Logs(finalUnencLogs);
|
|
189
|
-
|
|
190
|
-
tx.unencryptedLogs.functionLogs[0] = unencryptedLogs;
|
|
191
|
-
for (let i = 1; i < tx.unencryptedLogs.functionLogs.length; i++) {
|
|
192
|
-
tx.unencryptedLogs.functionLogs[i] = UnencryptedFunctionL2Logs.empty();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
168
|
}
|