@aztec/simulator 0.38.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/oracle/oracle.d.ts +1 -1
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +8 -23
- package/dest/acvm/oracle/typed_oracle.d.ts +2 -3
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +4 -7
- 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 +3 -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_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 +17 -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.map +1 -1
- package/dest/avm/journal/journal.js +4 -3
- 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 +12 -13
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +13 -49
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +11 -1
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +4 -1
- package/dest/avm/serialization/instruction_serialization.d.ts +2 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +3 -1
- package/dest/client/client_execution_context.d.ts +28 -1
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +50 -15
- package/dest/client/db_oracle.d.ts +1 -8
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/execution_result.d.ts +4 -1
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +16 -3
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +3 -1
- package/dest/client/simulator.d.ts +1 -31
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +3 -42
- 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/public/abstract_phase_manager.d.ts +8 -4
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +38 -14
- 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/executor.d.ts.map +1 -1
- package/dest/public/executor.js +1 -4
- 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_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 -0
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +2 -1
- 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.map +1 -1
- package/dest/public/transitional_adaptors.js +1 -1
- 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/oracle/oracle.ts +23 -27
- package/src/acvm/oracle/typed_oracle.ts +12 -9
- package/src/avm/avm_execution_environment.ts +34 -42
- package/src/avm/avm_gas.ts +2 -0
- package/src/avm/avm_machine_state.ts +14 -25
- package/src/avm/avm_message_call_result.ts +3 -14
- package/src/avm/avm_simulator.ts +22 -12
- package/src/avm/errors.ts +94 -4
- package/src/avm/journal/journal.ts +3 -2
- package/src/avm/opcodes/conversion.ts +59 -0
- package/src/avm/opcodes/environment_getters.ts +13 -66
- package/src/avm/opcodes/external_calls.ts +11 -0
- package/src/avm/serialization/bytecode_serialization.ts +3 -0
- package/src/avm/serialization/instruction_serialization.ts +2 -0
- package/src/client/client_execution_context.ts +87 -15
- package/src/client/db_oracle.ts +1 -9
- package/src/client/execution_result.ts +21 -2
- package/src/client/private_execution.ts +2 -0
- package/src/client/simulator.ts +2 -80
- package/src/client/view_data_oracle.ts +0 -10
- package/src/common/errors.ts +5 -0
- package/src/index.ts +1 -0
- package/src/public/abstract_phase_manager.ts +46 -18
- package/src/public/app_logic_phase_manager.ts +2 -1
- package/src/public/executor.ts +0 -4
- package/src/public/hints_builder.ts +5 -5
- package/src/public/public_processor.ts +8 -2
- package/src/public/setup_phase_manager.ts +16 -8
- package/src/public/tail_phase_manager.ts +6 -1
- package/src/public/teardown_phase_manager.ts +16 -8
- package/src/public/transitional_adaptors.ts +1 -0
- 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
|
@@ -63,6 +63,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
63
63
|
private unencryptedLogs: CountedLog<UnencryptedL2Log>[] = [];
|
|
64
64
|
private nestedExecutions: ExecutionResult[] = [];
|
|
65
65
|
private enqueuedPublicFunctionCalls: PublicCallRequest[] = [];
|
|
66
|
+
private publicTeardownFunctionCall: PublicCallRequest = PublicCallRequest.empty();
|
|
66
67
|
|
|
67
68
|
constructor(
|
|
68
69
|
contractAddress: AztecAddress,
|
|
@@ -173,6 +174,13 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
173
174
|
return this.enqueuedPublicFunctionCalls;
|
|
174
175
|
}
|
|
175
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Return the public teardown function call set during this execution.
|
|
179
|
+
*/
|
|
180
|
+
public getPublicTeardownFunctionCall() {
|
|
181
|
+
return this.publicTeardownFunctionCall;
|
|
182
|
+
}
|
|
183
|
+
|
|
176
184
|
/**
|
|
177
185
|
* Pack the given array of arguments.
|
|
178
186
|
* @param args - Arguments to pack
|
|
@@ -262,11 +270,11 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
262
270
|
|
|
263
271
|
notes.forEach(n => {
|
|
264
272
|
if (n.index !== undefined) {
|
|
265
|
-
const siloedNoteHash = siloNoteHash(n.contractAddress, n.innerNoteHash);
|
|
266
|
-
const uniqueSiloedNoteHash = computeUniqueNoteHash(n.nonce, siloedNoteHash);
|
|
267
273
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
|
|
268
|
-
// Should always
|
|
269
|
-
const
|
|
274
|
+
// Should always call computeUniqueNoteHash when publicly created notes include nonces.
|
|
275
|
+
const uniqueNoteHash = n.nonce.isZero() ? n.innerNoteHash : computeUniqueNoteHash(n.nonce, n.innerNoteHash);
|
|
276
|
+
const siloedNoteHash = siloNoteHash(n.contractAddress, uniqueNoteHash);
|
|
277
|
+
const noteHashForReadRequest = siloedNoteHash;
|
|
270
278
|
this.noteHashLeafIndexMap.set(noteHashForReadRequest.toBigInt(), n.index);
|
|
271
279
|
}
|
|
272
280
|
});
|
|
@@ -465,9 +473,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
465
473
|
}
|
|
466
474
|
|
|
467
475
|
/**
|
|
468
|
-
* Creates a PublicCallStackItem object representing the request to call a public function.
|
|
469
|
-
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
470
|
-
* of the execution are empty.
|
|
476
|
+
* Creates a PublicCallStackItem object representing the request to call a public function.
|
|
471
477
|
* @param targetContractAddress - The address of the contract to call.
|
|
472
478
|
* @param functionSelector - The function selector of the function to call.
|
|
473
479
|
* @param argsHash - The packed arguments to pass to the function.
|
|
@@ -475,7 +481,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
475
481
|
* @param isStaticCall - Whether the call is a static call.
|
|
476
482
|
* @returns The public call stack item with the request information.
|
|
477
483
|
*/
|
|
478
|
-
|
|
484
|
+
protected async createPublicCallRequest(
|
|
485
|
+
callType: 'enqueued' | 'teardown',
|
|
479
486
|
targetContractAddress: AztecAddress,
|
|
480
487
|
functionSelector: FunctionSelector,
|
|
481
488
|
argsHash: Fr,
|
|
@@ -494,20 +501,51 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
494
501
|
isStaticCall,
|
|
495
502
|
);
|
|
496
503
|
const args = this.packedValuesCache.unpack(argsHash);
|
|
497
|
-
|
|
504
|
+
|
|
505
|
+
// TODO($846): if enqueued public calls are associated with global
|
|
506
|
+
// side-effect counter, that will leak info about how many other private
|
|
507
|
+
// side-effects occurred in the TX. Ultimately the private kernel should
|
|
508
|
+
// just output everything in the proper order without any counters.
|
|
509
|
+
this.log.verbose(
|
|
510
|
+
`Created PublicCallRequest of type [${callType}], side-effect counter [${sideEffectCounter}] to ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
return PublicCallRequest.from({
|
|
498
514
|
args,
|
|
499
515
|
callContext: derivedCallContext,
|
|
500
516
|
parentCallContext: this.callContext,
|
|
501
517
|
functionData: FunctionData.fromAbi(targetArtifact),
|
|
502
518
|
contractAddress: targetContractAddress,
|
|
503
519
|
});
|
|
520
|
+
}
|
|
504
521
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
522
|
+
/**
|
|
523
|
+
* Creates and enqueues a PublicCallStackItem object representing the request to call a public function. No function
|
|
524
|
+
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
525
|
+
* of the execution are empty.
|
|
526
|
+
* @param targetContractAddress - The address of the contract to call.
|
|
527
|
+
* @param functionSelector - The function selector of the function to call.
|
|
528
|
+
* @param argsHash - The packed arguments to pass to the function.
|
|
529
|
+
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
530
|
+
* @param isStaticCall - Whether the call is a static call.
|
|
531
|
+
* @returns The public call stack item with the request information.
|
|
532
|
+
*/
|
|
533
|
+
public override async enqueuePublicFunctionCall(
|
|
534
|
+
targetContractAddress: AztecAddress,
|
|
535
|
+
functionSelector: FunctionSelector,
|
|
536
|
+
argsHash: Fr,
|
|
537
|
+
sideEffectCounter: number,
|
|
538
|
+
isStaticCall: boolean,
|
|
539
|
+
isDelegateCall: boolean,
|
|
540
|
+
): Promise<PublicCallRequest> {
|
|
541
|
+
const enqueuedRequest = await this.createPublicCallRequest(
|
|
542
|
+
'enqueued',
|
|
543
|
+
targetContractAddress,
|
|
544
|
+
functionSelector,
|
|
545
|
+
argsHash,
|
|
546
|
+
sideEffectCounter,
|
|
547
|
+
isStaticCall,
|
|
548
|
+
isDelegateCall,
|
|
511
549
|
);
|
|
512
550
|
|
|
513
551
|
this.enqueuedPublicFunctionCalls.push(enqueuedRequest);
|
|
@@ -515,6 +553,40 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
515
553
|
return enqueuedRequest;
|
|
516
554
|
}
|
|
517
555
|
|
|
556
|
+
/**
|
|
557
|
+
* Creates a PublicCallStackItem and sets it as the public teardown function. No function
|
|
558
|
+
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
559
|
+
* of the execution are empty.
|
|
560
|
+
* @param targetContractAddress - The address of the contract to call.
|
|
561
|
+
* @param functionSelector - The function selector of the function to call.
|
|
562
|
+
* @param argsHash - The packed arguments to pass to the function.
|
|
563
|
+
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
564
|
+
* @param isStaticCall - Whether the call is a static call.
|
|
565
|
+
* @returns The public call stack item with the request information.
|
|
566
|
+
*/
|
|
567
|
+
public override async setPublicTeardownFunctionCall(
|
|
568
|
+
targetContractAddress: AztecAddress,
|
|
569
|
+
functionSelector: FunctionSelector,
|
|
570
|
+
argsHash: Fr,
|
|
571
|
+
sideEffectCounter: number,
|
|
572
|
+
isStaticCall: boolean,
|
|
573
|
+
isDelegateCall: boolean,
|
|
574
|
+
): Promise<PublicCallRequest> {
|
|
575
|
+
const publicTeardownFunctionCall = await this.createPublicCallRequest(
|
|
576
|
+
'teardown',
|
|
577
|
+
targetContractAddress,
|
|
578
|
+
functionSelector,
|
|
579
|
+
argsHash,
|
|
580
|
+
sideEffectCounter,
|
|
581
|
+
isStaticCall,
|
|
582
|
+
isDelegateCall,
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
this.publicTeardownFunctionCall = publicTeardownFunctionCall;
|
|
586
|
+
|
|
587
|
+
return publicTeardownFunctionCall;
|
|
588
|
+
}
|
|
589
|
+
|
|
518
590
|
/**
|
|
519
591
|
* Derives the call context for a nested execution.
|
|
520
592
|
* @param targetContractAddress - The address of the contract being called.
|
package/src/client/db_oracle.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { type CompleteAddress, type Header } from '@aztec/circuits.js';
|
|
9
9
|
import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi';
|
|
10
10
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
11
|
-
import { type Fr
|
|
11
|
+
import { type Fr } from '@aztec/foundation/fields';
|
|
12
12
|
import { type ContractInstance } from '@aztec/types/contracts';
|
|
13
13
|
|
|
14
14
|
import { type NoteData, type NullifierKeys } from '../acvm/index.js';
|
|
@@ -64,14 +64,6 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
64
64
|
*/
|
|
65
65
|
popCapsule(): Promise<Fr[]>;
|
|
66
66
|
|
|
67
|
-
/**
|
|
68
|
-
* Gets public keys for an address.
|
|
69
|
-
* @param The address to look up
|
|
70
|
-
* @returns The public keys for a specific address
|
|
71
|
-
* TODO(#5834): Replace with `getCompleteAddress`.
|
|
72
|
-
*/
|
|
73
|
-
getPublicKeysForAddress(address: AztecAddress): Promise<Point[]>;
|
|
74
|
-
|
|
75
67
|
/**
|
|
76
68
|
* Retrieve nullifier keys associated with a specific account and app/contract address.
|
|
77
69
|
*
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
UnencryptedFunctionL2Logs,
|
|
6
6
|
type UnencryptedL2Log,
|
|
7
7
|
} from '@aztec/circuit-types';
|
|
8
|
-
import { type IsEmpty, type PrivateCallStackItem,
|
|
8
|
+
import { type IsEmpty, type PrivateCallStackItem, PublicCallRequest, sortByCounter } from '@aztec/circuits.js';
|
|
9
9
|
import { type Fr } from '@aztec/foundation/fields';
|
|
10
10
|
|
|
11
11
|
import { type ACVMField } from '../acvm/index.js';
|
|
@@ -56,6 +56,8 @@ export interface ExecutionResult {
|
|
|
56
56
|
nestedExecutions: this[];
|
|
57
57
|
/** Enqueued public function execution requests to be picked up by the sequencer. */
|
|
58
58
|
enqueuedPublicFunctionCalls: PublicCallRequest[];
|
|
59
|
+
/** Public function execution requested for teardown */
|
|
60
|
+
publicTeardownFunctionCall: PublicCallRequest;
|
|
59
61
|
/**
|
|
60
62
|
* Encrypted logs emitted during execution of this function call.
|
|
61
63
|
* Note: These are preimages to `encryptedLogsHashes`.
|
|
@@ -130,6 +132,23 @@ export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult):
|
|
|
130
132
|
// as the kernel processes it like a stack, popping items off and pushing them to output
|
|
131
133
|
return [
|
|
132
134
|
...execResult.enqueuedPublicFunctionCalls,
|
|
133
|
-
...
|
|
135
|
+
...execResult.nestedExecutions.flatMap(collectEnqueuedPublicFunctionCalls),
|
|
134
136
|
].sort((a, b) => b.callContext.sideEffectCounter - a.callContext.sideEffectCounter);
|
|
135
137
|
}
|
|
138
|
+
|
|
139
|
+
export function collectPublicTeardownFunctionCall(execResult: ExecutionResult): PublicCallRequest {
|
|
140
|
+
const teardownCalls = [
|
|
141
|
+
execResult.publicTeardownFunctionCall,
|
|
142
|
+
...execResult.nestedExecutions.flatMap(collectPublicTeardownFunctionCall),
|
|
143
|
+
].filter(call => !call.isEmpty());
|
|
144
|
+
|
|
145
|
+
if (teardownCalls.length === 1) {
|
|
146
|
+
return teardownCalls[0];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (teardownCalls.length > 1) {
|
|
150
|
+
throw new Error('Multiple public teardown calls detected');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return PublicCallRequest.empty();
|
|
154
|
+
}
|
|
@@ -54,6 +54,7 @@ export async function executePrivateFunction(
|
|
|
54
54
|
const nullifiedNoteHashCounters = context.getNullifiedNoteHashCounters();
|
|
55
55
|
const nestedExecutions = context.getNestedExecutions();
|
|
56
56
|
const enqueuedPublicFunctionCalls = context.getEnqueuedPublicFunctionCalls();
|
|
57
|
+
const publicTeardownFunctionCall = context.getPublicTeardownFunctionCall();
|
|
57
58
|
|
|
58
59
|
log.debug(`Returning from call to ${contractAddress.toString()}:${functionSelector}`);
|
|
59
60
|
|
|
@@ -68,6 +69,7 @@ export async function executePrivateFunction(
|
|
|
68
69
|
vk: Buffer.from(artifact.verificationKey!, 'hex'),
|
|
69
70
|
nestedExecutions,
|
|
70
71
|
enqueuedPublicFunctionCalls,
|
|
72
|
+
publicTeardownFunctionCall,
|
|
71
73
|
encryptedLogs,
|
|
72
74
|
unencryptedLogs,
|
|
73
75
|
};
|
package/src/client/simulator.ts
CHANGED
|
@@ -200,7 +200,7 @@ export class AcirSimulator {
|
|
|
200
200
|
args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, noteTypeId, extendedNoteItems]),
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
-
const [innerNoteHash,
|
|
203
|
+
const [innerNoteHash, uniqueNoteHash, siloedNoteHash, innerNullifier] = (await this.runUnconstrained(
|
|
204
204
|
execRequest,
|
|
205
205
|
artifact,
|
|
206
206
|
contractAddress,
|
|
@@ -208,8 +208,8 @@ export class AcirSimulator {
|
|
|
208
208
|
|
|
209
209
|
return {
|
|
210
210
|
innerNoteHash: new Fr(innerNoteHash),
|
|
211
|
+
uniqueNoteHash: new Fr(uniqueNoteHash),
|
|
211
212
|
siloedNoteHash: new Fr(siloedNoteHash),
|
|
212
|
-
uniqueSiloedNoteHash: new Fr(uniqueSiloedNoteHash),
|
|
213
213
|
innerNullifier: new Fr(innerNullifier),
|
|
214
214
|
};
|
|
215
215
|
}
|
|
@@ -232,82 +232,4 @@ export class AcirSimulator {
|
|
|
232
232
|
);
|
|
233
233
|
return innerNoteHash;
|
|
234
234
|
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Computes the unique note hash of a note.
|
|
238
|
-
* @param contractAddress - The address of the contract.
|
|
239
|
-
* @param nonce - The nonce of the note hash.
|
|
240
|
-
* @param storageSlot - The storage slot.
|
|
241
|
-
* @param noteTypeId - The note type identifier.
|
|
242
|
-
* @param note - The note.
|
|
243
|
-
* @returns The note hash.
|
|
244
|
-
*/
|
|
245
|
-
public async computeUniqueSiloedNoteHash(
|
|
246
|
-
contractAddress: AztecAddress,
|
|
247
|
-
nonce: Fr,
|
|
248
|
-
storageSlot: Fr,
|
|
249
|
-
noteTypeId: Fr,
|
|
250
|
-
note: Note,
|
|
251
|
-
) {
|
|
252
|
-
const { uniqueSiloedNoteHash } = await this.computeNoteHashAndNullifier(
|
|
253
|
-
contractAddress,
|
|
254
|
-
nonce,
|
|
255
|
-
storageSlot,
|
|
256
|
-
noteTypeId,
|
|
257
|
-
note,
|
|
258
|
-
);
|
|
259
|
-
return uniqueSiloedNoteHash;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Computes the siloed note hash of a note.
|
|
264
|
-
* @param contractAddress - The address of the contract.
|
|
265
|
-
* @param nonce - The nonce of the note hash.
|
|
266
|
-
* @param storageSlot - The storage slot.
|
|
267
|
-
* @param noteTypeId - The note type identifier.
|
|
268
|
-
* @param note - The note.
|
|
269
|
-
* @returns The note hash.
|
|
270
|
-
*/
|
|
271
|
-
public async computeSiloedNoteHash(
|
|
272
|
-
contractAddress: AztecAddress,
|
|
273
|
-
nonce: Fr,
|
|
274
|
-
storageSlot: Fr,
|
|
275
|
-
noteTypeId: Fr,
|
|
276
|
-
note: Note,
|
|
277
|
-
) {
|
|
278
|
-
const { siloedNoteHash } = await this.computeNoteHashAndNullifier(
|
|
279
|
-
contractAddress,
|
|
280
|
-
nonce,
|
|
281
|
-
storageSlot,
|
|
282
|
-
noteTypeId,
|
|
283
|
-
note,
|
|
284
|
-
);
|
|
285
|
-
return siloedNoteHash;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Computes the inner note hash of a note, which contains storage slot and the custom note hash.
|
|
290
|
-
* @param contractAddress - The address of the contract.
|
|
291
|
-
* @param nonce - The nonce of the unique note hash.
|
|
292
|
-
* @param storageSlot - The storage slot.
|
|
293
|
-
* @param noteTypeId - The note type identifier.
|
|
294
|
-
* @param note - The note.
|
|
295
|
-
* @returns The note hash.
|
|
296
|
-
*/
|
|
297
|
-
public async computeInnerNullifier(
|
|
298
|
-
contractAddress: AztecAddress,
|
|
299
|
-
nonce: Fr,
|
|
300
|
-
storageSlot: Fr,
|
|
301
|
-
noteTypeId: Fr,
|
|
302
|
-
note: Note,
|
|
303
|
-
) {
|
|
304
|
-
const { innerNullifier } = await this.computeNoteHashAndNullifier(
|
|
305
|
-
contractAddress,
|
|
306
|
-
nonce,
|
|
307
|
-
storageSlot,
|
|
308
|
-
noteTypeId,
|
|
309
|
-
note,
|
|
310
|
-
);
|
|
311
|
-
return innerNullifier;
|
|
312
|
-
}
|
|
313
235
|
}
|
|
@@ -166,16 +166,6 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
166
166
|
return this.db.popCapsule();
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
/**
|
|
170
|
-
* Gets public keys for an address.
|
|
171
|
-
* @param The address to look up
|
|
172
|
-
* @returns The public keys for a specific address
|
|
173
|
-
* TODO(#5834): Replace with `getCompleteAddress`.
|
|
174
|
-
*/
|
|
175
|
-
public override getPublicKeysForAddress(address: AztecAddress) {
|
|
176
|
-
return this.db.getPublicKeysForAddress(address);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
169
|
/**
|
|
180
170
|
* Gets some notes for a contract address and storage slot.
|
|
181
171
|
* Returns a flattened array containing filtered notes.
|
package/src/common/errors.ts
CHANGED
|
@@ -2,6 +2,11 @@ import { type FailingFunction, type NoirCallStack, SimulationError } from '@azte
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* An error that occurred during the execution of a function.
|
|
5
|
+
* @param message - the error message
|
|
6
|
+
* @param failingFunction - the Aztec function that failed
|
|
7
|
+
* @param noirCallStack - the internal call stack of the function that failed (within the failing Aztec function)
|
|
8
|
+
* @param options - additional error options (an optional "cause" entry allows for a recursive error stack where
|
|
9
|
+
* an error's cause may be an ExecutionError itself)
|
|
5
10
|
*/
|
|
6
11
|
export class ExecutionError extends Error {
|
|
7
12
|
constructor(
|
package/src/index.ts
CHANGED
|
@@ -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];
|
|
@@ -263,7 +279,18 @@ export abstract class AbstractPhaseManager {
|
|
|
263
279
|
)
|
|
264
280
|
: current;
|
|
265
281
|
|
|
282
|
+
// Sanity check for a current upstream assumption.
|
|
283
|
+
// Consumers of the result seem to expect "reverted <=> revertReason !== undefined".
|
|
266
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
|
+
|
|
267
294
|
if (result.reverted && !PhaseIsRevertible[this.phase]) {
|
|
268
295
|
this.log.debug(
|
|
269
296
|
`Simulation error on ${result.execution.contractAddress.toString()}:${functionSelector} with reason: ${
|
|
@@ -306,7 +333,8 @@ export abstract class AbstractPhaseManager {
|
|
|
306
333
|
result.revertReason
|
|
307
334
|
}`,
|
|
308
335
|
);
|
|
309
|
-
|
|
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];
|
|
310
338
|
}
|
|
311
339
|
|
|
312
340
|
if (!enqueuedExecutionResult) {
|
|
@@ -322,7 +350,7 @@ export abstract class AbstractPhaseManager {
|
|
|
322
350
|
// TODO(#3675): This should be done in a public kernel circuit
|
|
323
351
|
removeRedundantPublicDataWrites(kernelOutput, this.phase);
|
|
324
352
|
|
|
325
|
-
return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns];
|
|
353
|
+
return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns, gasUsed];
|
|
326
354
|
}
|
|
327
355
|
|
|
328
356
|
/** Returns all pending private and public nullifiers. */
|
|
@@ -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/executor.ts
CHANGED
|
@@ -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);
|
|
@@ -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',
|