@aztec/simulator 0.46.7 → 0.47.1
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/oracle/oracle.d.ts +4 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +10 -12
- package/dest/acvm/oracle/typed_oracle.d.ts +9 -6
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +3 -3
- package/dest/acvm/serialize.d.ts +0 -11
- package/dest/acvm/serialize.d.ts.map +1 -1
- package/dest/acvm/serialize.js +1 -26
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +5 -1
- package/dest/avm/fixtures/index.d.ts +2 -1
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +5 -2
- package/dest/avm/opcodes/commitment.d.ts +16 -0
- package/dest/avm/opcodes/commitment.d.ts.map +1 -0
- package/dest/avm/opcodes/commitment.js +50 -0
- package/dest/avm/opcodes/hashing.d.ts +11 -0
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +42 -3
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +7 -2
- package/dest/avm/serialization/instruction_serialization.d.ts +4 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +6 -2
- package/dest/client/client_execution_context.d.ts +17 -12
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +25 -31
- package/dest/client/execution_result.d.ts +12 -6
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +21 -8
- package/dest/mocks/fixtures.d.ts +5 -5
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +6 -9
- package/dest/providers/factory.d.ts +12 -0
- package/dest/providers/factory.d.ts.map +1 -0
- package/dest/providers/factory.js +27 -0
- package/dest/providers/index.d.ts +1 -0
- package/dest/providers/index.d.ts.map +1 -1
- package/dest/providers/index.js +2 -1
- package/dest/public/abstract_phase_manager.d.ts +4 -5
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +16 -83
- package/dest/public/execution.d.ts +8 -10
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +10 -1
- package/dest/public/executor.d.ts +2 -1
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +3 -3
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_processor.d.ts +1 -1
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +9 -3
- package/dest/public/side_effect_trace.d.ts +1 -0
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +9 -9
- package/package.json +9 -9
- package/src/acvm/acvm.ts +1 -1
- package/src/acvm/oracle/oracle.ts +9 -7
- package/src/acvm/oracle/typed_oracle.ts +6 -10
- package/src/acvm/serialize.ts +0 -29
- package/src/avm/avm_gas.ts +4 -0
- package/src/avm/fixtures/index.ts +5 -1
- package/src/avm/opcodes/commitment.ts +66 -0
- package/src/avm/opcodes/hashing.ts +53 -2
- package/src/avm/serialization/bytecode_serialization.ts +6 -1
- package/src/avm/serialization/instruction_serialization.ts +4 -0
- package/src/client/client_execution_context.ts +34 -38
- package/src/client/execution_result.ts +25 -10
- package/src/mocks/fixtures.ts +13 -11
- package/src/providers/factory.ts +38 -0
- package/src/providers/index.ts +1 -0
- package/src/public/abstract_phase_manager.ts +22 -102
- package/src/public/execution.ts +30 -14
- package/src/public/executor.ts +4 -3
- package/src/public/index.ts +1 -1
- package/src/public/public_processor.ts +8 -5
- package/src/public/side_effect_trace.ts +13 -7
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
L1NotePayload,
|
|
9
9
|
Note,
|
|
10
10
|
type NoteStatus,
|
|
11
|
+
PublicExecutionRequest,
|
|
11
12
|
TaggedLog,
|
|
12
13
|
type UnencryptedL2Log,
|
|
13
14
|
} from '@aztec/circuit-types';
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
type Header,
|
|
18
19
|
type KeyValidationRequest,
|
|
19
20
|
PrivateContextInputs,
|
|
20
|
-
PublicCallRequest,
|
|
21
21
|
type TxContext,
|
|
22
22
|
} from '@aztec/circuits.js';
|
|
23
23
|
import { Aes128 } from '@aztec/circuits.js/barretenberg';
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
type NoteSelector,
|
|
30
30
|
countArgumentsSize,
|
|
31
31
|
} from '@aztec/foundation/abi';
|
|
32
|
-
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
32
|
+
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
33
33
|
import { pedersenHash } from '@aztec/foundation/crypto';
|
|
34
34
|
import { Fr, GrumpkinScalar, type Point } from '@aztec/foundation/fields';
|
|
35
35
|
import { applyStringFormatting, createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -38,7 +38,13 @@ import { type NoteData, toACVMWitness } from '../acvm/index.js';
|
|
|
38
38
|
import { type PackedValuesCache } from '../common/packed_values_cache.js';
|
|
39
39
|
import { type DBOracle } from './db_oracle.js';
|
|
40
40
|
import { type ExecutionNoteCache } from './execution_note_cache.js';
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
CountedLog,
|
|
43
|
+
CountedNoteLog,
|
|
44
|
+
CountedPublicExecutionRequest,
|
|
45
|
+
type ExecutionResult,
|
|
46
|
+
type NoteAndSlot,
|
|
47
|
+
} from './execution_result.js';
|
|
42
48
|
import { pickNotes } from './pick_notes.js';
|
|
43
49
|
import { executePrivateFunction } from './private_execution.js';
|
|
44
50
|
import { ViewDataOracle } from './view_data_oracle.js';
|
|
@@ -70,8 +76,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
70
76
|
private encryptedLogs: CountedLog<EncryptedL2Log>[] = [];
|
|
71
77
|
private unencryptedLogs: CountedLog<UnencryptedL2Log>[] = [];
|
|
72
78
|
private nestedExecutions: ExecutionResult[] = [];
|
|
73
|
-
private enqueuedPublicFunctionCalls:
|
|
74
|
-
private publicTeardownFunctionCall:
|
|
79
|
+
private enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[] = [];
|
|
80
|
+
private publicTeardownFunctionCall: PublicExecutionRequest = PublicExecutionRequest.empty();
|
|
75
81
|
|
|
76
82
|
constructor(
|
|
77
83
|
contractAddress: AztecAddress,
|
|
@@ -377,6 +383,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
377
383
|
* @param eventTypeId - The type ID of the event (function selector).
|
|
378
384
|
* @param ovKeys - The outgoing viewing keys to use to encrypt.
|
|
379
385
|
* @param ivpkM - The master incoming viewing public key.
|
|
386
|
+
* @param recipient - The recipient of the encrypted event log.
|
|
380
387
|
* @param preimage - The event preimage.
|
|
381
388
|
*/
|
|
382
389
|
public override computeEncryptedEventLog(
|
|
@@ -385,6 +392,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
385
392
|
eventTypeId: Fr,
|
|
386
393
|
ovKeys: KeyValidationRequest,
|
|
387
394
|
ivpkM: Point,
|
|
395
|
+
recipient: AztecAddress,
|
|
388
396
|
preimage: Fr[],
|
|
389
397
|
) {
|
|
390
398
|
const event = new Event(preimage);
|
|
@@ -393,8 +401,6 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
393
401
|
|
|
394
402
|
const ephSk = GrumpkinScalar.random();
|
|
395
403
|
|
|
396
|
-
const recipient = AztecAddress.random();
|
|
397
|
-
|
|
398
404
|
return taggedEvent.encrypt(ephSk, recipient, ivpkM, ovKeys);
|
|
399
405
|
}
|
|
400
406
|
|
|
@@ -405,6 +411,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
405
411
|
* @param noteTypeId - The type ID of the note.
|
|
406
412
|
* @param ovKeys - The outgoing viewing keys to use to encrypt.
|
|
407
413
|
* @param ivpkM - The master incoming viewing public key.
|
|
414
|
+
* @param recipient - The recipient of the encrypted note log.
|
|
408
415
|
* @param preimage - The note preimage.
|
|
409
416
|
*/
|
|
410
417
|
public override computeEncryptedNoteLog(
|
|
@@ -413,6 +420,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
413
420
|
noteTypeId: NoteSelector,
|
|
414
421
|
ovKeys: KeyValidationRequest,
|
|
415
422
|
ivpkM: Point,
|
|
423
|
+
recipient: AztecAddress,
|
|
416
424
|
preimage: Fr[],
|
|
417
425
|
) {
|
|
418
426
|
const note = new Note(preimage);
|
|
@@ -421,11 +429,6 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
421
429
|
|
|
422
430
|
const ephSk = GrumpkinScalar.random();
|
|
423
431
|
|
|
424
|
-
// @todo This should be populated properly.
|
|
425
|
-
// Note that this encryption function SHOULD not be used, but is currently used
|
|
426
|
-
// as oracle for encrypted event logs.
|
|
427
|
-
const recipient = AztecAddress.random();
|
|
428
|
-
|
|
429
432
|
return taggedNote.encrypt(ephSk, recipient, ivpkM, ovKeys);
|
|
430
433
|
}
|
|
431
434
|
|
|
@@ -531,7 +534,11 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
531
534
|
|
|
532
535
|
this.nestedExecutions.push(childExecutionResult);
|
|
533
536
|
|
|
534
|
-
|
|
537
|
+
const publicInputs = childExecutionResult.callStackItem.publicInputs;
|
|
538
|
+
return {
|
|
539
|
+
endSideEffectCounter: publicInputs.endSideEffectCounter,
|
|
540
|
+
returnsHash: publicInputs.returnsHash,
|
|
541
|
+
};
|
|
535
542
|
}
|
|
536
543
|
|
|
537
544
|
/**
|
|
@@ -543,7 +550,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
543
550
|
* @param isStaticCall - Whether the call is a static call.
|
|
544
551
|
* @returns The public call stack item with the request information.
|
|
545
552
|
*/
|
|
546
|
-
protected async
|
|
553
|
+
protected async createPublicExecutionRequest(
|
|
547
554
|
callType: 'enqueued' | 'teardown',
|
|
548
555
|
targetContractAddress: AztecAddress,
|
|
549
556
|
functionSelector: FunctionSelector,
|
|
@@ -551,9 +558,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
551
558
|
sideEffectCounter: number,
|
|
552
559
|
isStaticCall: boolean,
|
|
553
560
|
isDelegateCall: boolean,
|
|
554
|
-
)
|
|
555
|
-
isStaticCall = isStaticCall || this.callContext.isStaticCall;
|
|
556
|
-
|
|
561
|
+
) {
|
|
557
562
|
const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
558
563
|
const derivedCallContext = this.deriveCallContext(
|
|
559
564
|
targetContractAddress,
|
|
@@ -563,22 +568,21 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
563
568
|
);
|
|
564
569
|
const args = this.packedValuesCache.unpack(argsHash);
|
|
565
570
|
|
|
566
|
-
// TODO($846): if enqueued public calls are associated with global
|
|
567
|
-
// side-effect counter, that will leak info about how many other private
|
|
568
|
-
// side-effects occurred in the TX. Ultimately the private kernel should
|
|
569
|
-
// just output everything in the proper order without any counters.
|
|
570
571
|
this.log.verbose(
|
|
571
|
-
`Created
|
|
572
|
+
`Created PublicExecutionRequest of type [${callType}], side-effect counter [${sideEffectCounter}] to ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
|
|
572
573
|
);
|
|
573
574
|
|
|
574
|
-
|
|
575
|
+
const request = PublicExecutionRequest.from({
|
|
575
576
|
args,
|
|
576
577
|
callContext: derivedCallContext,
|
|
577
|
-
parentCallContext: this.callContext,
|
|
578
|
-
functionSelector,
|
|
579
578
|
contractAddress: targetContractAddress,
|
|
580
|
-
sideEffectCounter,
|
|
581
579
|
});
|
|
580
|
+
|
|
581
|
+
if (callType === 'enqueued') {
|
|
582
|
+
this.enqueuedPublicFunctionCalls.push(new CountedPublicExecutionRequest(request, sideEffectCounter));
|
|
583
|
+
} else {
|
|
584
|
+
this.publicTeardownFunctionCall = request;
|
|
585
|
+
}
|
|
582
586
|
}
|
|
583
587
|
|
|
584
588
|
/**
|
|
@@ -599,8 +603,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
599
603
|
sideEffectCounter: number,
|
|
600
604
|
isStaticCall: boolean,
|
|
601
605
|
isDelegateCall: boolean,
|
|
602
|
-
)
|
|
603
|
-
|
|
606
|
+
) {
|
|
607
|
+
await this.createPublicExecutionRequest(
|
|
604
608
|
'enqueued',
|
|
605
609
|
targetContractAddress,
|
|
606
610
|
functionSelector,
|
|
@@ -609,10 +613,6 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
609
613
|
isStaticCall,
|
|
610
614
|
isDelegateCall,
|
|
611
615
|
);
|
|
612
|
-
|
|
613
|
-
this.enqueuedPublicFunctionCalls.push(enqueuedRequest);
|
|
614
|
-
|
|
615
|
-
return enqueuedRequest;
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
/**
|
|
@@ -633,8 +633,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
633
633
|
sideEffectCounter: number,
|
|
634
634
|
isStaticCall: boolean,
|
|
635
635
|
isDelegateCall: boolean,
|
|
636
|
-
)
|
|
637
|
-
|
|
636
|
+
) {
|
|
637
|
+
await this.createPublicExecutionRequest(
|
|
638
638
|
'teardown',
|
|
639
639
|
targetContractAddress,
|
|
640
640
|
functionSelector,
|
|
@@ -643,10 +643,6 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
643
643
|
isStaticCall,
|
|
644
644
|
isDelegateCall,
|
|
645
645
|
);
|
|
646
|
-
|
|
647
|
-
this.publicTeardownFunctionCall = publicTeardownFunctionCall;
|
|
648
|
-
|
|
649
|
-
return publicTeardownFunctionCall;
|
|
650
646
|
}
|
|
651
647
|
|
|
652
648
|
/**
|
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
type EncryptedL2NoteLog,
|
|
5
5
|
EncryptedNoteFunctionL2Logs,
|
|
6
6
|
type Note,
|
|
7
|
+
PublicExecutionRequest,
|
|
7
8
|
UnencryptedFunctionL2Logs,
|
|
8
9
|
type UnencryptedL2Log,
|
|
9
10
|
} from '@aztec/circuit-types';
|
|
10
|
-
import { type IsEmpty, type PrivateCallStackItem,
|
|
11
|
+
import { type IsEmpty, type PrivateCallStackItem, sortByCounter } from '@aztec/circuits.js';
|
|
11
12
|
import { type NoteSelector } from '@aztec/foundation/abi';
|
|
12
13
|
import { type Fr } from '@aztec/foundation/fields';
|
|
13
14
|
|
|
@@ -38,6 +39,15 @@ export class CountedNoteLog extends CountedLog<EncryptedL2NoteLog> {
|
|
|
38
39
|
super(log, counter);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
|
|
43
|
+
export class CountedPublicExecutionRequest {
|
|
44
|
+
constructor(public request: PublicExecutionRequest, public counter: number) {}
|
|
45
|
+
|
|
46
|
+
isEmpty(): boolean {
|
|
47
|
+
return this.request.isEmpty() && !this.counter;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
/**
|
|
42
52
|
* The result of executing a private function.
|
|
43
53
|
*/
|
|
@@ -63,9 +73,9 @@ export interface ExecutionResult {
|
|
|
63
73
|
/** The nested executions. */
|
|
64
74
|
nestedExecutions: this[];
|
|
65
75
|
/** Enqueued public function execution requests to be picked up by the sequencer. */
|
|
66
|
-
enqueuedPublicFunctionCalls:
|
|
76
|
+
enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[];
|
|
67
77
|
/** Public function execution requested for teardown */
|
|
68
|
-
publicTeardownFunctionCall:
|
|
78
|
+
publicTeardownFunctionCall: PublicExecutionRequest;
|
|
69
79
|
/**
|
|
70
80
|
* Encrypted note logs emitted during execution of this function call.
|
|
71
81
|
* Note: These are preimages to `noteEncryptedLogsHashes`.
|
|
@@ -161,21 +171,26 @@ export function collectSortedUnencryptedLogs(execResult: ExecutionResult): Unenc
|
|
|
161
171
|
return new UnencryptedFunctionL2Logs(sortedLogs.map(l => l.log));
|
|
162
172
|
}
|
|
163
173
|
|
|
174
|
+
function collectEnqueuedCountedPublicExecutionRequests(execResult: ExecutionResult): CountedPublicExecutionRequest[] {
|
|
175
|
+
return [
|
|
176
|
+
...execResult.enqueuedPublicFunctionCalls,
|
|
177
|
+
...execResult.nestedExecutions.flatMap(collectEnqueuedCountedPublicExecutionRequests),
|
|
178
|
+
];
|
|
179
|
+
}
|
|
180
|
+
|
|
164
181
|
/**
|
|
165
182
|
* Collect all enqueued public function calls across all nested executions.
|
|
166
183
|
* @param execResult - The topmost execution result.
|
|
167
184
|
* @returns All enqueued public function calls.
|
|
168
185
|
*/
|
|
169
|
-
export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult):
|
|
186
|
+
export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult): PublicExecutionRequest[] {
|
|
187
|
+
const countedRequests = collectEnqueuedCountedPublicExecutionRequests(execResult);
|
|
170
188
|
// without the reverse sort, the logs will be in a queue like fashion which is wrong
|
|
171
189
|
// as the kernel processes it like a stack, popping items off and pushing them to output
|
|
172
|
-
return
|
|
173
|
-
...execResult.enqueuedPublicFunctionCalls,
|
|
174
|
-
...execResult.nestedExecutions.flatMap(collectEnqueuedPublicFunctionCalls),
|
|
175
|
-
].sort((a, b) => b.sideEffectCounter - a.sideEffectCounter);
|
|
190
|
+
return sortByCounter(countedRequests, false).map(r => r.request);
|
|
176
191
|
}
|
|
177
192
|
|
|
178
|
-
export function collectPublicTeardownFunctionCall(execResult: ExecutionResult):
|
|
193
|
+
export function collectPublicTeardownFunctionCall(execResult: ExecutionResult): PublicExecutionRequest {
|
|
179
194
|
const teardownCalls = [
|
|
180
195
|
execResult.publicTeardownFunctionCall,
|
|
181
196
|
...execResult.nestedExecutions.flatMap(collectPublicTeardownFunctionCall),
|
|
@@ -189,5 +204,5 @@ export function collectPublicTeardownFunctionCall(execResult: ExecutionResult):
|
|
|
189
204
|
throw new Error('Multiple public teardown calls detected');
|
|
190
205
|
}
|
|
191
206
|
|
|
192
|
-
return
|
|
207
|
+
return PublicExecutionRequest.empty();
|
|
193
208
|
}
|
package/src/mocks/fixtures.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type FunctionCall,
|
|
3
|
+
PublicExecutionRequest,
|
|
4
|
+
type SimulationError,
|
|
5
|
+
UnencryptedFunctionL2Logs,
|
|
6
|
+
} from '@aztec/circuit-types';
|
|
2
7
|
import {
|
|
3
8
|
ARGS_LENGTH,
|
|
4
9
|
AvmExecutionHints,
|
|
@@ -8,13 +13,12 @@ import {
|
|
|
8
13
|
type ContractStorageUpdateRequest,
|
|
9
14
|
Fr,
|
|
10
15
|
Gas,
|
|
11
|
-
type PublicCallRequest,
|
|
12
16
|
} from '@aztec/circuits.js';
|
|
13
17
|
import { makeAztecAddress, makeSelector } from '@aztec/circuits.js/testing';
|
|
14
18
|
import { FunctionType } from '@aztec/foundation/abi';
|
|
15
19
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
16
20
|
|
|
17
|
-
import { type
|
|
21
|
+
import { type PublicExecutionResult, resultToPublicCallRequest } from '../public/execution.js';
|
|
18
22
|
|
|
19
23
|
export class PublicExecutionResultBuilder {
|
|
20
24
|
private _executionRequest: PublicExecutionRequest;
|
|
@@ -29,7 +33,7 @@ export class PublicExecutionResultBuilder {
|
|
|
29
33
|
this._executionRequest = executionRequest;
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
static
|
|
36
|
+
static fromPublicExecutionRequest({
|
|
33
37
|
request,
|
|
34
38
|
returnValues = [new Fr(1n)],
|
|
35
39
|
nestedExecutions = [],
|
|
@@ -37,7 +41,7 @@ export class PublicExecutionResultBuilder {
|
|
|
37
41
|
contractStorageReads = [],
|
|
38
42
|
revertReason = undefined,
|
|
39
43
|
}: {
|
|
40
|
-
request:
|
|
44
|
+
request: PublicExecutionRequest;
|
|
41
45
|
returnValues?: Fr[];
|
|
42
46
|
nestedExecutions?: PublicExecutionResult[];
|
|
43
47
|
contractStorageUpdateRequests?: ContractStorageUpdateRequest[];
|
|
@@ -74,12 +78,9 @@ export class PublicExecutionResultBuilder {
|
|
|
74
78
|
contractStorageReads?: ContractStorageRead[];
|
|
75
79
|
revertReason?: SimulationError;
|
|
76
80
|
}) {
|
|
77
|
-
const builder = new PublicExecutionResultBuilder(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
functionSelector: tx.selector,
|
|
81
|
-
args: tx.args,
|
|
82
|
-
});
|
|
81
|
+
const builder = new PublicExecutionResultBuilder(
|
|
82
|
+
new PublicExecutionRequest(tx.to, new CallContext(from, tx.to, tx.selector, false, false), tx.args),
|
|
83
|
+
);
|
|
83
84
|
|
|
84
85
|
builder.withNestedExecutions(...nestedExecutions);
|
|
85
86
|
builder.withContractStorageUpdateRequest(...contractStorageUpdateRequests);
|
|
@@ -122,6 +123,7 @@ export class PublicExecutionResultBuilder {
|
|
|
122
123
|
return {
|
|
123
124
|
executionRequest: this._executionRequest,
|
|
124
125
|
nestedExecutions: this._nestedExecutions,
|
|
126
|
+
publicCallRequests: this._nestedExecutions.map(resultToPublicCallRequest),
|
|
125
127
|
noteHashReadRequests: [],
|
|
126
128
|
nullifierReadRequests: [],
|
|
127
129
|
nullifierNonExistentReadRequests: [],
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
2
|
+
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
|
|
5
|
+
import { NativeACVMSimulator } from './acvm_native.js';
|
|
6
|
+
import { WASMSimulator } from './acvm_wasm.js';
|
|
7
|
+
import { type SimulationProvider } from './simulation_provider.js';
|
|
8
|
+
|
|
9
|
+
export type SimulationProviderConfig = {
|
|
10
|
+
acvmBinaryPath?: string;
|
|
11
|
+
acvmWorkingDirectory?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function getSimulationProviderConfigFromEnv() {
|
|
15
|
+
const { ACVM_BINARY_PATH, ACVM_WORKING_DIRECTORY } = process.env;
|
|
16
|
+
return {
|
|
17
|
+
acvmWorkingDirectory: ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : undefined,
|
|
18
|
+
acvmBinaryPath: ACVM_BINARY_PATH ? ACVM_BINARY_PATH : undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function createSimulationProvider(
|
|
23
|
+
config: SimulationProviderConfig,
|
|
24
|
+
logger: DebugLogger = createDebugLogger('aztec:simulator'),
|
|
25
|
+
): Promise<SimulationProvider> {
|
|
26
|
+
if (config.acvmBinaryPath && config.acvmWorkingDirectory) {
|
|
27
|
+
try {
|
|
28
|
+
await fs.access(config.acvmBinaryPath, fs.constants.R_OK);
|
|
29
|
+
await fs.mkdir(config.acvmWorkingDirectory, { recursive: true });
|
|
30
|
+
logger.info(`Using native ACVM at ${config.acvmBinaryPath} and working directory ${config.acvmWorkingDirectory}`);
|
|
31
|
+
return new NativeACVMSimulator(config.acvmWorkingDirectory, config.acvmBinaryPath);
|
|
32
|
+
} catch {
|
|
33
|
+
logger.warn(`Failed to access ACVM at ${config.acvmBinaryPath}, falling back to WASM`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
logger.info('Using WASM ACVM simulation');
|
|
37
|
+
return new WASMSimulator();
|
|
38
|
+
}
|
package/src/providers/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type AvmProvingRequest,
|
|
4
4
|
MerkleTreeId,
|
|
5
5
|
type NestedProcessReturnValues,
|
|
6
|
+
type PublicExecutionRequest,
|
|
6
7
|
type PublicKernelNonTailRequest,
|
|
7
8
|
PublicKernelType,
|
|
8
9
|
type PublicProvingRequest,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
import {
|
|
14
15
|
type AvmExecutionHints,
|
|
15
16
|
AztecAddress,
|
|
16
|
-
CallRequest,
|
|
17
17
|
ClientIvcProof,
|
|
18
18
|
ContractStorageRead,
|
|
19
19
|
ContractStorageUpdateRequest,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
NoteHash,
|
|
41
41
|
Nullifier,
|
|
42
42
|
PublicCallData,
|
|
43
|
-
|
|
43
|
+
PublicCallRequest,
|
|
44
44
|
PublicCallStackItem,
|
|
45
45
|
PublicCircuitPublicInputs,
|
|
46
46
|
PublicKernelCircuitPrivateInputs,
|
|
@@ -62,7 +62,6 @@ import {
|
|
|
62
62
|
getVKSiblingPath,
|
|
63
63
|
} from '@aztec/noir-protocol-circuits-types';
|
|
64
64
|
import {
|
|
65
|
-
type PublicExecutionRequest,
|
|
66
65
|
type PublicExecutionResult,
|
|
67
66
|
type PublicExecutor,
|
|
68
67
|
accumulateReturnValues,
|
|
@@ -165,76 +164,18 @@ export abstract class AbstractPhaseManager {
|
|
|
165
164
|
previousKernelArtifact: ProtocolArtifact,
|
|
166
165
|
): Promise<PhaseResult>;
|
|
167
166
|
|
|
168
|
-
public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelType,
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
const publicCallsStack = tx.enqueuedPublicFunctionCalls.slice().reverse();
|
|
180
|
-
const nonRevertibleCallStack = data.endNonRevertibleData.publicCallStack.filter(i => !i.isEmpty());
|
|
181
|
-
const revertibleCallStack = data.end.publicCallStack.filter(i => !i.isEmpty());
|
|
182
|
-
|
|
183
|
-
const callRequestsStack = publicCallsStack
|
|
184
|
-
.map(call => call.toCallRequest())
|
|
185
|
-
.filter(
|
|
186
|
-
// filter out enqueued calls that are not in the public call stack
|
|
187
|
-
// TODO mitch left a question about whether this is only needed when unit testing
|
|
188
|
-
// with mock data
|
|
189
|
-
call => revertibleCallStack.find(p => p.equals(call)) || nonRevertibleCallStack.find(p => p.equals(call)),
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
const teardownCallStack = tx.publicTeardownFunctionCall.isEmpty() ? [] : [tx.publicTeardownFunctionCall];
|
|
193
|
-
|
|
194
|
-
if (callRequestsStack.length === 0) {
|
|
195
|
-
return {
|
|
196
|
-
[PublicKernelType.NON_PUBLIC]: [],
|
|
197
|
-
[PublicKernelType.SETUP]: [],
|
|
198
|
-
[PublicKernelType.APP_LOGIC]: [],
|
|
199
|
-
[PublicKernelType.TEARDOWN]: teardownCallStack,
|
|
200
|
-
[PublicKernelType.TAIL]: [],
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// find the first call that is revertible
|
|
205
|
-
const firstRevertibleCallIndex = callRequestsStack.findIndex(
|
|
206
|
-
c => revertibleCallStack.findIndex(p => p.equals(c)) !== -1,
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
if (firstRevertibleCallIndex === 0) {
|
|
210
|
-
return {
|
|
211
|
-
[PublicKernelType.NON_PUBLIC]: [],
|
|
212
|
-
[PublicKernelType.SETUP]: [],
|
|
213
|
-
[PublicKernelType.APP_LOGIC]: publicCallsStack,
|
|
214
|
-
[PublicKernelType.TEARDOWN]: teardownCallStack,
|
|
215
|
-
[PublicKernelType.TAIL]: [],
|
|
216
|
-
};
|
|
217
|
-
} else if (firstRevertibleCallIndex === -1) {
|
|
218
|
-
// there's no app logic, split the functions between setup (many) and teardown (just one function call)
|
|
219
|
-
return {
|
|
220
|
-
[PublicKernelType.NON_PUBLIC]: [],
|
|
221
|
-
[PublicKernelType.SETUP]: publicCallsStack,
|
|
222
|
-
[PublicKernelType.APP_LOGIC]: [],
|
|
223
|
-
[PublicKernelType.TEARDOWN]: teardownCallStack,
|
|
224
|
-
[PublicKernelType.TAIL]: [],
|
|
225
|
-
};
|
|
226
|
-
} else {
|
|
227
|
-
return {
|
|
228
|
-
[PublicKernelType.NON_PUBLIC]: [],
|
|
229
|
-
[PublicKernelType.SETUP]: publicCallsStack.slice(0, firstRevertibleCallIndex),
|
|
230
|
-
[PublicKernelType.APP_LOGIC]: publicCallsStack.slice(firstRevertibleCallIndex),
|
|
231
|
-
[PublicKernelType.TEARDOWN]: teardownCallStack,
|
|
232
|
-
[PublicKernelType.TAIL]: [],
|
|
233
|
-
};
|
|
234
|
-
}
|
|
167
|
+
public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelType, PublicExecutionRequest[]> {
|
|
168
|
+
const teardownRequest = tx.getPublicTeardownExecutionRequest();
|
|
169
|
+
return {
|
|
170
|
+
[PublicKernelType.NON_PUBLIC]: [],
|
|
171
|
+
[PublicKernelType.SETUP]: tx.getNonRevertiblePublicExecutionRequests(),
|
|
172
|
+
[PublicKernelType.APP_LOGIC]: tx.getRevertiblePublicExecutionRequests(),
|
|
173
|
+
[PublicKernelType.TEARDOWN]: teardownRequest ? [teardownRequest] : [],
|
|
174
|
+
[PublicKernelType.TAIL]: [],
|
|
175
|
+
};
|
|
235
176
|
}
|
|
236
177
|
|
|
237
|
-
protected extractEnqueuedPublicCalls(tx: Tx):
|
|
178
|
+
protected extractEnqueuedPublicCalls(tx: Tx): PublicExecutionRequest[] {
|
|
238
179
|
const calls = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx)[this.phase];
|
|
239
180
|
|
|
240
181
|
return calls;
|
|
@@ -245,7 +186,7 @@ export abstract class AbstractPhaseManager {
|
|
|
245
186
|
previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
|
|
246
187
|
previousKernelArtifact: ProtocolArtifact,
|
|
247
188
|
): Promise<TxPublicCallsResult> {
|
|
248
|
-
const enqueuedCalls = this.extractEnqueuedPublicCalls(tx);
|
|
189
|
+
const enqueuedCalls = [...this.extractEnqueuedPublicCalls(tx)].reverse();
|
|
249
190
|
|
|
250
191
|
if (!enqueuedCalls || !enqueuedCalls.length) {
|
|
251
192
|
return {
|
|
@@ -299,7 +240,7 @@ export abstract class AbstractPhaseManager {
|
|
|
299
240
|
|
|
300
241
|
// Sanity check for a current upstream assumption.
|
|
301
242
|
// Consumers of the result seem to expect "reverted <=> revertReason !== undefined".
|
|
302
|
-
const functionSelector = result.executionRequest.functionSelector.toString();
|
|
243
|
+
const functionSelector = result.executionRequest.callContext.functionSelector.toString();
|
|
303
244
|
if (result.reverted && !result.revertReason) {
|
|
304
245
|
throw new Error(
|
|
305
246
|
`Simulation of ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${
|
|
@@ -460,13 +401,6 @@ export abstract class AbstractPhaseManager {
|
|
|
460
401
|
const publicDataTreeInfo = await this.db.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE);
|
|
461
402
|
this.historicalHeader.state.partial.publicDataTree.root = Fr.fromBuffer(publicDataTreeInfo.root);
|
|
462
403
|
|
|
463
|
-
const callStackPreimages = await this.getPublicCallStackPreimages(result);
|
|
464
|
-
const publicCallStackHashes = padArrayEnd(
|
|
465
|
-
callStackPreimages.map(c => c.getCompressed().hash()),
|
|
466
|
-
Fr.ZERO,
|
|
467
|
-
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
|
|
468
|
-
);
|
|
469
|
-
|
|
470
404
|
const publicCircuitPublicInputs = PublicCircuitPublicInputs.from({
|
|
471
405
|
callContext: result.executionRequest.callContext,
|
|
472
406
|
proverAddress: AztecAddress.ZERO,
|
|
@@ -507,7 +441,11 @@ export abstract class AbstractPhaseManager {
|
|
|
507
441
|
ContractStorageUpdateRequest.empty(),
|
|
508
442
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
|
|
509
443
|
),
|
|
510
|
-
|
|
444
|
+
publicCallRequests: padArrayEnd(
|
|
445
|
+
result.publicCallRequests,
|
|
446
|
+
PublicCallRequest.empty(),
|
|
447
|
+
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
|
|
448
|
+
),
|
|
511
449
|
unencryptedLogsHashes: padArrayEnd(result.unencryptedLogsHashes, LogHash.empty(), MAX_UNENCRYPTED_LOGS_PER_CALL),
|
|
512
450
|
historicalHeader: this.historicalHeader,
|
|
513
451
|
globalVariables: this.globalVariables,
|
|
@@ -520,23 +458,12 @@ export abstract class AbstractPhaseManager {
|
|
|
520
458
|
|
|
521
459
|
return new PublicCallStackItem(
|
|
522
460
|
result.executionRequest.contractAddress,
|
|
523
|
-
new FunctionData(result.executionRequest.functionSelector, false),
|
|
461
|
+
new FunctionData(result.executionRequest.callContext.functionSelector, false),
|
|
524
462
|
publicCircuitPublicInputs,
|
|
525
463
|
isExecutionRequest,
|
|
526
464
|
);
|
|
527
465
|
}
|
|
528
466
|
|
|
529
|
-
protected async getPublicCallStackPreimages(result: PublicExecutionResult): Promise<PublicCallStackItem[]> {
|
|
530
|
-
const nested = result.nestedExecutions;
|
|
531
|
-
if (nested.length > MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) {
|
|
532
|
-
throw new Error(
|
|
533
|
-
`Public call stack size exceeded (max ${MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL}, got ${nested.length})`,
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
return await Promise.all(nested.map(n => this.getPublicCallStackItem(n)));
|
|
538
|
-
}
|
|
539
|
-
|
|
540
467
|
/**
|
|
541
468
|
* Looks at the side effects of a transaction and returns the highest counter
|
|
542
469
|
* @param tx - A transaction
|
|
@@ -562,10 +489,7 @@ export abstract class AbstractPhaseManager {
|
|
|
562
489
|
|
|
563
490
|
let max = 0;
|
|
564
491
|
for (const sideEffect of sideEffectCounters) {
|
|
565
|
-
if ('
|
|
566
|
-
// look at both start and end counters because for enqueued public calls start > 0 while end === 0
|
|
567
|
-
max = Math.max(max, sideEffect.startSideEffectCounter.toNumber(), sideEffect.endSideEffectCounter.toNumber());
|
|
568
|
-
} else if ('counter' in sideEffect) {
|
|
492
|
+
if ('counter' in sideEffect) {
|
|
569
493
|
max = Math.max(max, sideEffect.counter);
|
|
570
494
|
} else {
|
|
571
495
|
throw new Error('Unknown side effect type');
|
|
@@ -593,10 +517,6 @@ export abstract class AbstractPhaseManager {
|
|
|
593
517
|
protected async getPublicCallData(result: PublicExecutionResult, isExecutionRequest = false) {
|
|
594
518
|
const bytecodeHash = await this.getBytecodeHash(result);
|
|
595
519
|
const callStackItem = await this.getPublicCallStackItem(result, isExecutionRequest);
|
|
596
|
-
|
|
597
|
-
c.toCallRequest(callStackItem.publicInputs.callContext),
|
|
598
|
-
);
|
|
599
|
-
const publicCallStack = padArrayEnd(publicCallRequests, CallRequest.empty(), MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL);
|
|
600
|
-
return new PublicCallData(callStackItem, publicCallStack, makeEmptyProof(), bytecodeHash);
|
|
520
|
+
return new PublicCallData(callStackItem, makeEmptyProof(), bytecodeHash);
|
|
601
521
|
}
|
|
602
522
|
}
|