@aztec/simulator 0.47.0 → 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.
Files changed (62) hide show
  1. package/dest/acvm/acvm.d.ts +1 -1
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.d.ts +2 -2
  4. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  5. package/dest/acvm/oracle/oracle.js +6 -8
  6. package/dest/acvm/oracle/typed_oracle.d.ts +7 -4
  7. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  8. package/dest/acvm/oracle/typed_oracle.js +1 -1
  9. package/dest/acvm/serialize.d.ts +0 -11
  10. package/dest/acvm/serialize.d.ts.map +1 -1
  11. package/dest/acvm/serialize.js +1 -26
  12. package/dest/avm/avm_gas.d.ts.map +1 -1
  13. package/dest/avm/avm_gas.js +2 -1
  14. package/dest/avm/opcodes/commitment.d.ts +16 -0
  15. package/dest/avm/opcodes/commitment.d.ts.map +1 -0
  16. package/dest/avm/opcodes/commitment.js +50 -0
  17. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  18. package/dest/avm/serialization/bytecode_serialization.js +3 -1
  19. package/dest/avm/serialization/instruction_serialization.d.ts +4 -3
  20. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  21. package/dest/avm/serialization/instruction_serialization.js +5 -4
  22. package/dest/client/client_execution_context.d.ts +12 -9
  23. package/dest/client/client_execution_context.d.ts.map +1 -1
  24. package/dest/client/client_execution_context.js +21 -23
  25. package/dest/client/execution_result.d.ts +12 -6
  26. package/dest/client/execution_result.d.ts.map +1 -1
  27. package/dest/client/execution_result.js +21 -8
  28. package/dest/mocks/fixtures.d.ts +5 -5
  29. package/dest/mocks/fixtures.d.ts.map +1 -1
  30. package/dest/mocks/fixtures.js +6 -9
  31. package/dest/public/abstract_phase_manager.d.ts +4 -5
  32. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  33. package/dest/public/abstract_phase_manager.js +16 -83
  34. package/dest/public/execution.d.ts +8 -10
  35. package/dest/public/execution.d.ts.map +1 -1
  36. package/dest/public/execution.js +10 -1
  37. package/dest/public/executor.d.ts +2 -1
  38. package/dest/public/executor.d.ts.map +1 -1
  39. package/dest/public/executor.js +3 -3
  40. package/dest/public/index.d.ts +1 -1
  41. package/dest/public/index.d.ts.map +1 -1
  42. package/dest/public/index.js +1 -1
  43. package/dest/public/side_effect_trace.d.ts +1 -0
  44. package/dest/public/side_effect_trace.d.ts.map +1 -1
  45. package/dest/public/side_effect_trace.js +9 -9
  46. package/package.json +9 -9
  47. package/src/acvm/acvm.ts +1 -1
  48. package/src/acvm/oracle/oracle.ts +5 -7
  49. package/src/acvm/oracle/typed_oracle.ts +4 -10
  50. package/src/acvm/serialize.ts +0 -29
  51. package/src/avm/avm_gas.ts +1 -0
  52. package/src/avm/opcodes/commitment.ts +66 -0
  53. package/src/avm/serialization/bytecode_serialization.ts +2 -0
  54. package/src/avm/serialization/instruction_serialization.ts +1 -0
  55. package/src/client/client_execution_context.ts +29 -30
  56. package/src/client/execution_result.ts +25 -10
  57. package/src/mocks/fixtures.ts +13 -11
  58. package/src/public/abstract_phase_manager.ts +22 -102
  59. package/src/public/execution.ts +30 -14
  60. package/src/public/executor.ts +4 -3
  61. package/src/public/index.ts +1 -1
  62. package/src/public/side_effect_trace.ts +13 -7
@@ -6,7 +6,7 @@ import { Fr, Point } from '@aztec/foundation/fields';
6
6
 
7
7
  import { type ACVMField } from '../acvm_types.js';
8
8
  import { frToBoolean, frToNumber, fromACVMField } from '../deserialize.js';
9
- import { toACVMField, toAcvmEnqueuePublicFunctionResult } from '../serialize.js';
9
+ import { toACVMField } from '../serialize.js';
10
10
  import { type TypedOracle } from './typed_oracle.js';
11
11
 
12
12
  /**
@@ -429,7 +429,7 @@ export class Oracle {
429
429
  [isStaticCall]: ACVMField[],
430
430
  [isDelegateCall]: ACVMField[],
431
431
  ): Promise<ACVMField[]> {
432
- const callStackItem = await this.typedOracle.callPrivateFunction(
432
+ const { endSideEffectCounter, returnsHash } = await this.typedOracle.callPrivateFunction(
433
433
  AztecAddress.fromField(fromACVMField(contractAddress)),
434
434
  FunctionSelector.fromField(fromACVMField(functionSelector)),
435
435
  fromACVMField(argsHash),
@@ -437,7 +437,7 @@ export class Oracle {
437
437
  frToBoolean(fromACVMField(isStaticCall)),
438
438
  frToBoolean(fromACVMField(isDelegateCall)),
439
439
  );
440
- return callStackItem.toFields().map(toACVMField);
440
+ return [endSideEffectCounter, returnsHash].map(toACVMField);
441
441
  }
442
442
 
443
443
  async callPublicFunction(
@@ -467,7 +467,7 @@ export class Oracle {
467
467
  [isStaticCall]: ACVMField[],
468
468
  [isDelegateCall]: ACVMField[],
469
469
  ) {
470
- const enqueuedRequest = await this.typedOracle.enqueuePublicFunctionCall(
470
+ await this.typedOracle.enqueuePublicFunctionCall(
471
471
  AztecAddress.fromString(contractAddress),
472
472
  FunctionSelector.fromField(fromACVMField(functionSelector)),
473
473
  fromACVMField(argsHash),
@@ -475,7 +475,6 @@ export class Oracle {
475
475
  frToBoolean(fromACVMField(isStaticCall)),
476
476
  frToBoolean(fromACVMField(isDelegateCall)),
477
477
  );
478
- return toAcvmEnqueuePublicFunctionResult(enqueuedRequest);
479
478
  }
480
479
 
481
480
  async setPublicTeardownFunctionCall(
@@ -486,7 +485,7 @@ export class Oracle {
486
485
  [isStaticCall]: ACVMField[],
487
486
  [isDelegateCall]: ACVMField[],
488
487
  ) {
489
- const teardownRequest = await this.typedOracle.setPublicTeardownFunctionCall(
488
+ await this.typedOracle.setPublicTeardownFunctionCall(
490
489
  AztecAddress.fromString(contractAddress),
491
490
  FunctionSelector.fromField(fromACVMField(functionSelector)),
492
491
  fromACVMField(argsHash),
@@ -494,7 +493,6 @@ export class Oracle {
494
493
  frToBoolean(fromACVMField(isStaticCall)),
495
494
  frToBoolean(fromACVMField(isDelegateCall)),
496
495
  );
497
- return toAcvmEnqueuePublicFunctionResult(teardownRequest);
498
496
  }
499
497
 
500
498
  aes128Encrypt(input: ACVMField[], initializationVector: ACVMField[], key: ACVMField[]): ACVMField[] {
@@ -9,13 +9,7 @@ import {
9
9
  type SiblingPath,
10
10
  type UnencryptedL2Log,
11
11
  } from '@aztec/circuit-types';
12
- import {
13
- type Header,
14
- type KeyValidationRequest,
15
- type L1_TO_L2_MSG_TREE_HEIGHT,
16
- type PrivateCallStackItem,
17
- type PublicCallRequest,
18
- } from '@aztec/circuits.js';
12
+ import { type Header, type KeyValidationRequest, type L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/circuits.js';
19
13
  import { type FunctionSelector, type NoteSelector } from '@aztec/foundation/abi';
20
14
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
21
15
  import { Fr } from '@aztec/foundation/fields';
@@ -255,7 +249,7 @@ export abstract class TypedOracle {
255
249
  _sideEffectCounter: number,
256
250
  _isStaticCall: boolean,
257
251
  _isDelegateCall: boolean,
258
- ): Promise<PrivateCallStackItem> {
252
+ ): Promise<{ endSideEffectCounter: Fr; returnsHash: Fr }> {
259
253
  throw new OracleMethodNotAvailableError('callPrivateFunction');
260
254
  }
261
255
 
@@ -277,7 +271,7 @@ export abstract class TypedOracle {
277
271
  _sideEffectCounter: number,
278
272
  _isStaticCall: boolean,
279
273
  _isDelegateCall: boolean,
280
- ): Promise<PublicCallRequest> {
274
+ ): Promise<void> {
281
275
  throw new OracleMethodNotAvailableError('enqueuePublicFunctionCall');
282
276
  }
283
277
 
@@ -288,7 +282,7 @@ export abstract class TypedOracle {
288
282
  _sideEffectCounter: number,
289
283
  _isStaticCall: boolean,
290
284
  _isDelegateCall: boolean,
291
- ): Promise<PublicCallRequest> {
285
+ ): Promise<void> {
292
286
  throw new OracleMethodNotAvailableError('setPublicTeardownFunctionCall');
293
287
  }
294
288
 
@@ -1,4 +1,3 @@
1
- import { ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH, type PublicCallRequest } from '@aztec/circuits.js';
2
1
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
3
2
  import { type EthAddress } from '@aztec/foundation/eth-address';
4
3
  import { Fr } from '@aztec/foundation/fields';
@@ -40,34 +39,6 @@ export function toACVMField(
40
39
  return `0x${adaptBufferSize(buffer).toString('hex')}`;
41
40
  }
42
41
 
43
- // Utilities to write TS classes to ACVM Field arrays
44
- // In the order that the ACVM expects them
45
-
46
- /**
47
- * Converts a public call stack item with the request for executing a public function to
48
- * a set of ACVM fields accepted by the enqueue_public_function_call_oracle Aztec.nr function.
49
- * Note that only the fields related to the request are serialized: those related to the result
50
- * are empty since this is just an execution request, so we don't send them to the circuit.
51
- * @param item - The public call stack item to serialize to be passed onto Noir.
52
- * @returns The fields expected by the enqueue_public_function_call_oracle Aztec.nr function.
53
- * TODO(#4380): Nuke this and replace it with PublicCallRequest.toFields()
54
- */
55
- export function toAcvmEnqueuePublicFunctionResult(item: PublicCallRequest): ACVMField[] {
56
- const fields = [
57
- item.contractAddress.toField(),
58
- item.functionSelector.toField(),
59
- ...item.callContext.toFields(),
60
- item.sideEffectCounter,
61
- item.getArgsHash(),
62
- ];
63
- if (fields.length !== ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH) {
64
- throw new Error(
65
- `Invalid length for EnqueuePublicFunctionResult (got ${fields.length} expected ${ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH})`,
66
- );
67
- }
68
- return fields.map(toACVMField);
69
- }
70
-
71
42
  /**
72
43
  * Inserts a list of ACVM fields to a witness.
73
44
  * @param witnessStartIndex - The index where to start inserting the fields.
@@ -124,6 +124,7 @@ const BaseGasCosts: Record<Opcode, Gas> = {
124
124
  [Opcode.PEDERSEN]: DefaultBaseGasCost,
125
125
  [Opcode.ECADD]: DefaultBaseGasCost,
126
126
  [Opcode.MSM]: DefaultBaseGasCost,
127
+ [Opcode.PEDERSENCOMMITMENT]: DefaultBaseGasCost,
127
128
  // Conversions
128
129
  [Opcode.TORADIXLE]: DefaultBaseGasCost,
129
130
  // Other
@@ -0,0 +1,66 @@
1
+ import { pedersenCommit } from '@aztec/foundation/crypto';
2
+
3
+ import { type AvmContext } from '../avm_context.js';
4
+ import { Field, TypeTag, Uint8 } from '../avm_memory_types.js';
5
+ import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
+ import { Addressing } from './addressing_mode.js';
7
+ import { Instruction } from './instruction.js';
8
+
9
+ export class PedersenCommitment extends Instruction {
10
+ static type: string = 'PEDERSENCOMMITMENT';
11
+ static readonly opcode: Opcode = Opcode.PEDERSENCOMMITMENT;
12
+
13
+ // Informs (de)serialization. See Instruction.deserialize.
14
+ static readonly wireFormat: OperandType[] = [
15
+ OperandType.UINT8 /* Opcode */,
16
+ OperandType.UINT8 /* Indirect */,
17
+ OperandType.UINT32 /* Input Offset*/,
18
+ OperandType.UINT32 /* Dst Offset */,
19
+ OperandType.UINT32 /* Input Size Offset */,
20
+ OperandType.UINT32 /* Generator Index Offset */,
21
+ ];
22
+
23
+ constructor(
24
+ private indirect: number,
25
+ private inputOffset: number,
26
+ private outputOffset: number,
27
+ private inputSizeOffset: number,
28
+ private genIndexOffset: number,
29
+ ) {
30
+ super();
31
+ }
32
+
33
+ public async execute(context: AvmContext): Promise<void> {
34
+ const memory = context.machineState.memory.track(this.type);
35
+ const [inputOffset, outputOffset, inputSizeOffset, genIndexOffset] = Addressing.fromWire(this.indirect).resolve(
36
+ [this.inputOffset, this.outputOffset, this.inputSizeOffset, this.genIndexOffset],
37
+ memory,
38
+ );
39
+
40
+ const inputSize = memory.get(inputSizeOffset).toNumber();
41
+ memory.checkTag(TypeTag.UINT32, inputSizeOffset);
42
+
43
+ const inputs = memory.getSlice(inputOffset, inputSize);
44
+ memory.checkTagsRange(TypeTag.FIELD, inputOffset, inputSize);
45
+
46
+ // Generator index not used for now since we dont utilise it in the pedersenCommit function
47
+ memory.checkTag(TypeTag.UINT32, genIndexOffset);
48
+
49
+ const memoryOperations = { reads: inputSize + 1, writes: 3, indirect: this.indirect };
50
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
51
+
52
+ const inputBuffer: Buffer[] = inputs.map(input => input.toBuffer());
53
+ // TODO: Add the generate index to the pedersenCommit function
54
+ const commitment = pedersenCommit(inputBuffer).map(f => new Field(f));
55
+ // The function doesnt include a flag if the output point is infinity, come back to this
56
+ // for now we just check if theyre zero - until we know how bb encodes them
57
+ const isInfinity = commitment[0].equals(new Field(0)) && commitment[1].equals(new Field(0));
58
+
59
+ memory.set(outputOffset, commitment[0]); // Field typed
60
+ memory.set(outputOffset + 1, commitment[1]); // Field typed
61
+ memory.set(outputOffset + 2, new Uint8(isInfinity ? 1 : 0)); // U8 typed
62
+
63
+ memory.assert(memoryOperations);
64
+ context.machineState.incrementPc();
65
+ }
66
+ }
@@ -1,3 +1,4 @@
1
+ import { PedersenCommitment } from '../opcodes/commitment.js';
1
2
  import { DAGasLeft, L2GasLeft } from '../opcodes/context_getters.js';
2
3
  import { EcAdd } from '../opcodes/ec_add.js';
3
4
  import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js';
@@ -146,6 +147,7 @@ const INSTRUCTION_SET = () =>
146
147
  [Sha256.opcode, Sha256],
147
148
  [Pedersen.opcode, Pedersen],
148
149
  [MultiScalarMul.opcode, MultiScalarMul],
150
+ [PedersenCommitment.opcode, PedersenCommitment],
149
151
  // Conversions
150
152
  [ToRadixLE.opcode, ToRadixLE],
151
153
  // Future Gadgets -- pending changes in noir
@@ -78,6 +78,7 @@ export enum Opcode {
78
78
  PEDERSEN, // temp - may be removed, but alot of contracts rely on it
79
79
  ECADD,
80
80
  MSM,
81
+ PEDERSENCOMMITMENT,
81
82
  // Conversion
82
83
  TORADIXLE,
83
84
  // Future Gadgets -- pending changes in noir
@@ -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';
@@ -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 { CountedLog, CountedNoteLog, type ExecutionResult, type NoteAndSlot } from './execution_result.js';
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: PublicCallRequest[] = [];
74
- private publicTeardownFunctionCall: PublicCallRequest = PublicCallRequest.empty();
79
+ private enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[] = [];
80
+ private publicTeardownFunctionCall: PublicExecutionRequest = PublicExecutionRequest.empty();
75
81
 
76
82
  constructor(
77
83
  contractAddress: AztecAddress,
@@ -528,7 +534,11 @@ export class ClientExecutionContext extends ViewDataOracle {
528
534
 
529
535
  this.nestedExecutions.push(childExecutionResult);
530
536
 
531
- return childExecutionResult.callStackItem;
537
+ const publicInputs = childExecutionResult.callStackItem.publicInputs;
538
+ return {
539
+ endSideEffectCounter: publicInputs.endSideEffectCounter,
540
+ returnsHash: publicInputs.returnsHash,
541
+ };
532
542
  }
533
543
 
534
544
  /**
@@ -540,7 +550,7 @@ export class ClientExecutionContext extends ViewDataOracle {
540
550
  * @param isStaticCall - Whether the call is a static call.
541
551
  * @returns The public call stack item with the request information.
542
552
  */
543
- protected async createPublicCallRequest(
553
+ protected async createPublicExecutionRequest(
544
554
  callType: 'enqueued' | 'teardown',
545
555
  targetContractAddress: AztecAddress,
546
556
  functionSelector: FunctionSelector,
@@ -548,9 +558,7 @@ export class ClientExecutionContext extends ViewDataOracle {
548
558
  sideEffectCounter: number,
549
559
  isStaticCall: boolean,
550
560
  isDelegateCall: boolean,
551
- ): Promise<PublicCallRequest> {
552
- isStaticCall = isStaticCall || this.callContext.isStaticCall;
553
-
561
+ ) {
554
562
  const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector);
555
563
  const derivedCallContext = this.deriveCallContext(
556
564
  targetContractAddress,
@@ -560,22 +568,21 @@ export class ClientExecutionContext extends ViewDataOracle {
560
568
  );
561
569
  const args = this.packedValuesCache.unpack(argsHash);
562
570
 
563
- // TODO($846): if enqueued public calls are associated with global
564
- // side-effect counter, that will leak info about how many other private
565
- // side-effects occurred in the TX. Ultimately the private kernel should
566
- // just output everything in the proper order without any counters.
567
571
  this.log.verbose(
568
- `Created PublicCallRequest of type [${callType}], side-effect counter [${sideEffectCounter}] to ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
572
+ `Created PublicExecutionRequest of type [${callType}], side-effect counter [${sideEffectCounter}] to ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
569
573
  );
570
574
 
571
- return PublicCallRequest.from({
575
+ const request = PublicExecutionRequest.from({
572
576
  args,
573
577
  callContext: derivedCallContext,
574
- parentCallContext: this.callContext,
575
- functionSelector,
576
578
  contractAddress: targetContractAddress,
577
- sideEffectCounter,
578
579
  });
580
+
581
+ if (callType === 'enqueued') {
582
+ this.enqueuedPublicFunctionCalls.push(new CountedPublicExecutionRequest(request, sideEffectCounter));
583
+ } else {
584
+ this.publicTeardownFunctionCall = request;
585
+ }
579
586
  }
580
587
 
581
588
  /**
@@ -596,8 +603,8 @@ export class ClientExecutionContext extends ViewDataOracle {
596
603
  sideEffectCounter: number,
597
604
  isStaticCall: boolean,
598
605
  isDelegateCall: boolean,
599
- ): Promise<PublicCallRequest> {
600
- const enqueuedRequest = await this.createPublicCallRequest(
606
+ ) {
607
+ await this.createPublicExecutionRequest(
601
608
  'enqueued',
602
609
  targetContractAddress,
603
610
  functionSelector,
@@ -606,10 +613,6 @@ export class ClientExecutionContext extends ViewDataOracle {
606
613
  isStaticCall,
607
614
  isDelegateCall,
608
615
  );
609
-
610
- this.enqueuedPublicFunctionCalls.push(enqueuedRequest);
611
-
612
- return enqueuedRequest;
613
616
  }
614
617
 
615
618
  /**
@@ -630,8 +633,8 @@ export class ClientExecutionContext extends ViewDataOracle {
630
633
  sideEffectCounter: number,
631
634
  isStaticCall: boolean,
632
635
  isDelegateCall: boolean,
633
- ): Promise<PublicCallRequest> {
634
- const publicTeardownFunctionCall = await this.createPublicCallRequest(
636
+ ) {
637
+ await this.createPublicExecutionRequest(
635
638
  'teardown',
636
639
  targetContractAddress,
637
640
  functionSelector,
@@ -640,10 +643,6 @@ export class ClientExecutionContext extends ViewDataOracle {
640
643
  isStaticCall,
641
644
  isDelegateCall,
642
645
  );
643
-
644
- this.publicTeardownFunctionCall = publicTeardownFunctionCall;
645
-
646
- return publicTeardownFunctionCall;
647
646
  }
648
647
 
649
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, PublicCallRequest, sortByCounter } from '@aztec/circuits.js';
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: PublicCallRequest[];
76
+ enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[];
67
77
  /** Public function execution requested for teardown */
68
- publicTeardownFunctionCall: PublicCallRequest;
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): PublicCallRequest[] {
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): PublicCallRequest {
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 PublicCallRequest.empty();
207
+ return PublicExecutionRequest.empty();
193
208
  }
@@ -1,4 +1,9 @@
1
- import { type FunctionCall, type SimulationError, UnencryptedFunctionL2Logs } from '@aztec/circuit-types';
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 PublicExecutionRequest, type PublicExecutionResult } from '../public/execution.js';
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 fromPublicCallRequest({
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: PublicCallRequest;
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
- callContext: new CallContext(from, tx.to, tx.selector, false, false),
79
- contractAddress: tx.to,
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: [],