@aztec/simulator 0.40.0 → 0.41.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.
Files changed (124) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +4 -2
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +21 -18
  4. package/dest/acvm/oracle/typed_oracle.d.ts +6 -11
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +11 -5
  7. package/dest/avm/avm_execution_environment.d.ts +4 -3
  8. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  9. package/dest/avm/avm_execution_environment.js +7 -5
  10. package/dest/avm/avm_simulator.d.ts.map +1 -1
  11. package/dest/avm/avm_simulator.js +5 -4
  12. package/dest/avm/errors.d.ts +6 -0
  13. package/dest/avm/errors.d.ts.map +1 -1
  14. package/dest/avm/errors.js +10 -1
  15. package/dest/avm/fixtures/index.js +3 -3
  16. package/dest/avm/journal/journal.d.ts +2 -3
  17. package/dest/avm/journal/journal.d.ts.map +1 -1
  18. package/dest/avm/journal/journal.js +9 -14
  19. package/dest/avm/journal/nullifiers.d.ts +17 -5
  20. package/dest/avm/journal/nullifiers.d.ts.map +1 -1
  21. package/dest/avm/journal/nullifiers.js +27 -10
  22. package/dest/avm/journal/public_storage.d.ts +19 -6
  23. package/dest/avm/journal/public_storage.d.ts.map +1 -1
  24. package/dest/avm/journal/public_storage.js +30 -12
  25. package/dest/avm/journal/trace.js +9 -9
  26. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  27. package/dest/avm/opcodes/accrued_substate.js +6 -7
  28. package/dest/avm/opcodes/external_calls.d.ts +2 -2
  29. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  30. package/dest/avm/opcodes/external_calls.js +22 -11
  31. package/dest/avm/opcodes/storage.d.ts +0 -7
  32. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  33. package/dest/avm/opcodes/storage.js +3 -12
  34. package/dest/client/client_execution_context.d.ts +35 -17
  35. package/dest/client/client_execution_context.d.ts.map +1 -1
  36. package/dest/client/client_execution_context.js +70 -33
  37. package/dest/client/db_oracle.d.ts +10 -11
  38. package/dest/client/db_oracle.d.ts.map +1 -1
  39. package/dest/client/execution_note_cache.d.ts +17 -0
  40. package/dest/client/execution_note_cache.d.ts.map +1 -1
  41. package/dest/client/execution_note_cache.js +25 -2
  42. package/dest/client/execution_result.d.ts +11 -0
  43. package/dest/client/execution_result.d.ts.map +1 -1
  44. package/dest/client/execution_result.js +21 -3
  45. package/dest/client/private_execution.d.ts.map +1 -1
  46. package/dest/client/private_execution.js +4 -1
  47. package/dest/client/simulator.d.ts.map +1 -1
  48. package/dest/client/simulator.js +6 -6
  49. package/dest/client/view_data_oracle.d.ts +11 -10
  50. package/dest/client/view_data_oracle.d.ts.map +1 -1
  51. package/dest/client/view_data_oracle.js +16 -12
  52. package/dest/common/index.d.ts +1 -0
  53. package/dest/common/index.d.ts.map +1 -1
  54. package/dest/common/index.js +2 -1
  55. package/dest/common/return_values.d.ts +11 -0
  56. package/dest/common/return_values.d.ts.map +1 -0
  57. package/dest/common/return_values.js +13 -0
  58. package/dest/mocks/fixtures.d.ts +2 -1
  59. package/dest/mocks/fixtures.d.ts.map +1 -1
  60. package/dest/mocks/fixtures.js +2 -3
  61. package/dest/public/abstract_phase_manager.d.ts +3 -3
  62. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  63. package/dest/public/abstract_phase_manager.js +17 -10
  64. package/dest/public/app_logic_phase_manager.d.ts +1 -1
  65. package/dest/public/execution.d.ts +2 -6
  66. package/dest/public/execution.d.ts.map +1 -1
  67. package/dest/public/execution.js +1 -1
  68. package/dest/public/executor.d.ts.map +1 -1
  69. package/dest/public/executor.js +11 -8
  70. package/dest/public/hints_builder.d.ts +2 -2
  71. package/dest/public/hints_builder.d.ts.map +1 -1
  72. package/dest/public/hints_builder.js +4 -4
  73. package/dest/public/public_processor.d.ts +2 -2
  74. package/dest/public/public_processor.d.ts.map +1 -1
  75. package/dest/public/public_processor.js +5 -5
  76. package/dest/public/setup_phase_manager.d.ts +1 -1
  77. package/dest/public/setup_phase_manager.js +2 -2
  78. package/dest/public/tail_phase_manager.d.ts +1 -1
  79. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  80. package/dest/public/tail_phase_manager.js +4 -4
  81. package/dest/public/teardown_phase_manager.d.ts +1 -1
  82. package/dest/public/teardown_phase_manager.js +2 -2
  83. package/dest/public/transitional_adaptors.d.ts +2 -1
  84. package/dest/public/transitional_adaptors.d.ts.map +1 -1
  85. package/dest/public/transitional_adaptors.js +17 -3
  86. package/dest/public/utils.js +3 -3
  87. package/package.json +8 -8
  88. package/src/acvm/oracle/oracle.ts +26 -23
  89. package/src/acvm/oracle/typed_oracle.ts +15 -15
  90. package/src/avm/avm_execution_environment.ts +9 -5
  91. package/src/avm/avm_simulator.ts +5 -3
  92. package/src/avm/errors.ts +10 -0
  93. package/src/avm/fixtures/index.ts +2 -2
  94. package/src/avm/journal/journal.ts +14 -18
  95. package/src/avm/journal/nullifiers.ts +27 -14
  96. package/src/avm/journal/public_storage.ts +30 -16
  97. package/src/avm/journal/trace.ts +8 -8
  98. package/src/avm/opcodes/accrued_substate.ts +5 -6
  99. package/src/avm/opcodes/external_calls.ts +23 -9
  100. package/src/avm/opcodes/storage.ts +2 -12
  101. package/src/client/client_execution_context.ts +75 -37
  102. package/src/client/db_oracle.ts +10 -11
  103. package/src/client/execution_note_cache.ts +29 -1
  104. package/src/client/execution_result.ts +26 -2
  105. package/src/client/private_execution.ts +3 -0
  106. package/src/client/simulator.ts +4 -5
  107. package/src/client/view_data_oracle.ts +18 -13
  108. package/src/common/index.ts +1 -0
  109. package/src/common/return_values.ts +18 -0
  110. package/src/mocks/fixtures.ts +2 -2
  111. package/src/public/abstract_phase_manager.ts +21 -15
  112. package/src/public/execution.ts +2 -6
  113. package/src/public/executor.ts +14 -7
  114. package/src/public/hints_builder.ts +11 -3
  115. package/src/public/public_processor.ts +7 -7
  116. package/src/public/setup_phase_manager.ts +1 -1
  117. package/src/public/tail_phase_manager.ts +5 -7
  118. package/src/public/teardown_phase_manager.ts +1 -1
  119. package/src/public/transitional_adaptors.ts +17 -2
  120. package/src/public/utils.ts +2 -2
  121. package/dest/client/logs_cache.d.ts +0 -33
  122. package/dest/client/logs_cache.d.ts.map +0 -1
  123. package/dest/client/logs_cache.js +0 -59
  124. package/src/client/logs_cache.ts +0 -65
@@ -5,13 +5,13 @@ import {
5
5
  type NullifierMembershipWitness,
6
6
  type PublicDataWitness,
7
7
  } from '@aztec/circuit-types';
8
- import { type CompleteAddress, type Header } from '@aztec/circuits.js';
8
+ import { type CompleteAddress, type Header, type KeyValidationRequest } 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
11
  import { type Fr } from '@aztec/foundation/fields';
12
12
  import { type ContractInstance } from '@aztec/types/contracts';
13
13
 
14
- import { type NoteData, type NullifierKeys } from '../acvm/index.js';
14
+ import { type NoteData } from '../acvm/index.js';
15
15
  import { type CommitmentsDB } from '../public/db.js';
16
16
 
17
17
  /**
@@ -45,10 +45,11 @@ export interface DBOracle extends CommitmentsDB {
45
45
 
46
46
  /**
47
47
  * Retrieve the complete address associated to a given address.
48
- * @param address - Address to fetch the pubkey for.
48
+ * @param account - The account address.
49
49
  * @returns A complete address associated with the input address.
50
+ * @throws An error if the account is not registered in the database.
50
51
  */
51
- getCompleteAddress(address: AztecAddress): Promise<CompleteAddress>;
52
+ getCompleteAddress(account: AztecAddress): Promise<CompleteAddress>;
52
53
 
53
54
  /**
54
55
  * Retrieve the auth witness for a given message hash.
@@ -65,14 +66,12 @@ export interface DBOracle extends CommitmentsDB {
65
66
  popCapsule(): Promise<Fr[]>;
66
67
 
67
68
  /**
68
- * Retrieve nullifier keys associated with a specific account and app/contract address.
69
- *
70
- * @param accountAddress - The account address.
71
- * @param contractAddress - The contract address.
72
- * @returns A Promise that resolves to nullifier keys of a requested account and contract.
73
- * @throws An error if the account is not registered in the database.
69
+ * Retrieve keys associated with a specific master public key and app address.
70
+ * @param pkMHash - The master public key hash.
71
+ * @returns A Promise that resolves to nullifier keys.
72
+ * @throws If the keys are not registered in the key store.
74
73
  */
75
- getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise<NullifierKeys>;
74
+ getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest>;
76
75
 
77
76
  /**
78
77
  * Retrieves a set of notes stored in the database for a given contract address and storage slot.
@@ -1,8 +1,10 @@
1
+ import { type EncryptedL2Log } from '@aztec/circuit-types';
1
2
  import { siloNullifier } from '@aztec/circuits.js/hash';
2
3
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
3
4
  import { Fr } from '@aztec/foundation/fields';
4
5
 
5
6
  import { type NoteData } from '../acvm/index.js';
7
+ import { type CountedLog } from './execution_result.js';
6
8
 
7
9
  export interface PendingNote {
8
10
  note: NoteData;
@@ -27,6 +29,13 @@ export class ExecutionNoteCache {
27
29
  */
28
30
  private nullifiers: Map<bigint, Set<bigint>> = new Map();
29
31
 
32
+ /**
33
+ * The list of encrypted logs linked to note hashes created in this transaction.
34
+ * This mapping maps from inner note hash to log(s) emitted for that note hash.
35
+ * Note that their value (bigint representation) is used because Frs cannot be looked up in Sets.
36
+ */
37
+ private logs: Map<bigint, CountedLog<EncryptedL2Log>[]> = new Map();
38
+
30
39
  /**
31
40
  * Add a new note to cache.
32
41
  * @param note - New note created during execution.
@@ -37,6 +46,16 @@ export class ExecutionNoteCache {
37
46
  this.newNotes.set(note.contractAddress.toBigInt(), notes);
38
47
  }
39
48
 
49
+ /**
50
+ * Add a new note to cache.
51
+ * @param note - New note created during execution.
52
+ */
53
+ public addNewLog(log: CountedLog<EncryptedL2Log>, innerNoteHash: Fr) {
54
+ const logs = this.logs.get(innerNoteHash.toBigInt()) ?? [];
55
+ logs.push(log);
56
+ this.logs.set(innerNoteHash.toBigInt(), logs);
57
+ }
58
+
40
59
  /**
41
60
  * Add a nullifier to cache. It could be for a db note or a new note created during execution.
42
61
  * @param contractAddress - Contract address of the note.
@@ -52,7 +71,7 @@ export class ExecutionNoteCache {
52
71
  this.nullifiers.set(contractAddress.toBigInt(), nullifiers);
53
72
 
54
73
  let nullifiedNoteHashCounter: number | undefined = undefined;
55
- // Find and remove the matching new note if the emitted innerNoteHash is not empty.
74
+ // Find and remove the matching new note and log(s) if the emitted innerNoteHash is not empty.
56
75
  if (!innerNoteHash.equals(Fr.ZERO)) {
57
76
  const notes = this.newNotes.get(contractAddress.toBigInt()) ?? [];
58
77
  const noteIndexToRemove = notes.findIndex(n => n.note.innerNoteHash.equals(innerNoteHash));
@@ -62,6 +81,8 @@ export class ExecutionNoteCache {
62
81
  const note = notes.splice(noteIndexToRemove, 1)[0];
63
82
  nullifiedNoteHashCounter = note.counter;
64
83
  this.newNotes.set(contractAddress.toBigInt(), notes);
84
+ // If a log linked to the note hash does not exist, this method just does nothing
85
+ this.logs.delete(innerNoteHash.toBigInt());
65
86
  }
66
87
 
67
88
  return nullifiedNoteHashCounter;
@@ -96,4 +117,11 @@ export class ExecutionNoteCache {
96
117
  public getNullifiers(contractAddress: AztecAddress): Set<bigint> {
97
118
  return this.nullifiers.get(contractAddress.toBigInt()) ?? new Set();
98
119
  }
120
+
121
+ /**
122
+ * Return all note logs emitted from a contract.
123
+ */
124
+ public getLogs(): CountedLog<EncryptedL2Log>[] {
125
+ return Array.from(this.logs.values()).flat();
126
+ }
99
127
  }
@@ -58,6 +58,11 @@ export interface ExecutionResult {
58
58
  enqueuedPublicFunctionCalls: PublicCallRequest[];
59
59
  /** Public function execution requested for teardown */
60
60
  publicTeardownFunctionCall: PublicCallRequest;
61
+ /**
62
+ * Encrypted note logs emitted during execution of this function call.
63
+ * Note: These are preimages to `noteEncryptedLogsHashes`.
64
+ */
65
+ noteEncryptedLogs: CountedLog<EncryptedL2Log>[];
61
66
  /**
62
67
  * Encrypted logs emitted during execution of this function call.
63
68
  * Note: These are preimages to `encryptedLogsHashes`.
@@ -82,13 +87,32 @@ export function collectNullifiedNoteHashCounters(execResult: ExecutionResult, ac
82
87
  return accum;
83
88
  }
84
89
 
90
+ /**
91
+ * Collect all encrypted logs across all nested executions.
92
+ * @param execResult - The topmost execution result.
93
+ * @returns All encrypted logs.
94
+ */
95
+ function collectNoteEncryptedLogs(execResult: ExecutionResult): CountedLog<EncryptedL2Log>[] {
96
+ return [execResult.noteEncryptedLogs, ...execResult.nestedExecutions.flatMap(collectNoteEncryptedLogs)].flat();
97
+ }
98
+
99
+ /**
100
+ * Collect all encrypted logs across all nested executions and sorts by counter.
101
+ * @param execResult - The topmost execution result.
102
+ * @returns All encrypted logs.
103
+ */
104
+ export function collectSortedNoteEncryptedLogs(execResult: ExecutionResult): EncryptedFunctionL2Logs {
105
+ const allLogs = collectNoteEncryptedLogs(execResult);
106
+ const sortedLogs = sortByCounter(allLogs);
107
+ return new EncryptedFunctionL2Logs(sortedLogs.map(l => l.log));
108
+ }
85
109
  /**
86
110
  * Collect all encrypted logs across all nested executions.
87
111
  * @param execResult - The topmost execution result.
88
112
  * @returns All encrypted logs.
89
113
  */
90
114
  function collectEncryptedLogs(execResult: ExecutionResult): CountedLog<EncryptedL2Log>[] {
91
- return [execResult.encryptedLogs, ...[...execResult.nestedExecutions].flatMap(collectEncryptedLogs)].flat();
115
+ return [execResult.encryptedLogs, ...execResult.nestedExecutions.flatMap(collectEncryptedLogs)].flat();
92
116
  }
93
117
 
94
118
  /**
@@ -108,7 +132,7 @@ export function collectSortedEncryptedLogs(execResult: ExecutionResult): Encrypt
108
132
  * @returns All unencrypted logs.
109
133
  */
110
134
  function collectUnencryptedLogs(execResult: ExecutionResult): CountedLog<UnencryptedL2Log>[] {
111
- return [execResult.unencryptedLogs, ...[...execResult.nestedExecutions].flatMap(collectUnencryptedLogs)].flat();
135
+ return [execResult.unencryptedLogs, ...execResult.nestedExecutions.flatMap(collectUnencryptedLogs)].flat();
112
136
  }
113
137
 
114
138
  /**
@@ -42,6 +42,8 @@ export async function executePrivateFunction(
42
42
  const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
43
43
  const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness);
44
44
 
45
+ context.chopNoteEncryptedLogs();
46
+ const noteEncryptedLogs = context.getNoteEncryptedLogs();
45
47
  const encryptedLogs = context.getEncryptedLogs();
46
48
  const unencryptedLogs = context.getUnencryptedLogs();
47
49
 
@@ -69,6 +71,7 @@ export async function executePrivateFunction(
69
71
  vk: Buffer.from(artifact.verificationKey!, 'hex'),
70
72
  nestedExecutions,
71
73
  enqueuedPublicFunctionCalls,
74
+ noteEncryptedLogs,
72
75
  publicTeardownFunctionCall,
73
76
  encryptedLogs,
74
77
  unencryptedLogs,
@@ -19,7 +19,6 @@ import { ClientExecutionContext } from './client_execution_context.js';
19
19
  import { type DBOracle } from './db_oracle.js';
20
20
  import { ExecutionNoteCache } from './execution_note_cache.js';
21
21
  import { type ExecutionResult } from './execution_result.js';
22
- import { LogsCache } from './logs_cache.js';
23
22
  import { executePrivateFunction } from './private_execution.js';
24
23
  import { executeUnconstrainedFunction } from './unconstrained_execution.js';
25
24
  import { ViewDataOracle } from './view_data_oracle.js';
@@ -69,8 +68,8 @@ export class AcirSimulator {
69
68
  contractAddress: AztecAddress,
70
69
  msgSender = AztecAddress.ZERO,
71
70
  ): Promise<ExecutionResult> {
72
- if (entryPointArtifact.functionType !== FunctionType.SECRET) {
73
- throw new Error(`Cannot run ${entryPointArtifact.functionType} function as secret`);
71
+ if (entryPointArtifact.functionType !== FunctionType.PRIVATE) {
72
+ throw new Error(`Cannot run ${entryPointArtifact.functionType} function as private`);
74
73
  }
75
74
 
76
75
  if (request.origin !== contractAddress) {
@@ -89,7 +88,7 @@ export class AcirSimulator {
89
88
  contractAddress,
90
89
  FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters),
91
90
  false,
92
- false,
91
+ entryPointArtifact.isStatic,
93
92
  startSideEffectCounter,
94
93
  );
95
94
  const context = new ClientExecutionContext(
@@ -101,7 +100,6 @@ export class AcirSimulator {
101
100
  request.authWitnesses,
102
101
  PackedValuesCache.create(request.argsOfCalls),
103
102
  new ExecutionNoteCache(),
104
- new LogsCache(),
105
103
  this.db,
106
104
  this.node,
107
105
  startSideEffectCounter,
@@ -197,6 +195,7 @@ export class AcirSimulator {
197
195
  const execRequest: FunctionCall = {
198
196
  to: contractAddress,
199
197
  functionData: FunctionData.empty(),
198
+ isStatic: artifact.isStatic,
200
199
  args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, noteTypeId, extendedNoteItems]),
201
200
  };
202
201
 
@@ -7,14 +7,14 @@ import {
7
7
  type NullifierMembershipWitness,
8
8
  type PublicDataWitness,
9
9
  } from '@aztec/circuit-types';
10
- import { type Header } from '@aztec/circuits.js';
10
+ import { type Header, type KeyValidationRequest } from '@aztec/circuits.js';
11
11
  import { siloNullifier } from '@aztec/circuits.js/hash';
12
12
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
13
13
  import { Fr } from '@aztec/foundation/fields';
14
- import { createDebugLogger } from '@aztec/foundation/log';
14
+ import { applyStringFormatting, createDebugLogger } from '@aztec/foundation/log';
15
15
  import { type ContractInstance } from '@aztec/types/contracts';
16
16
 
17
- import { type NoteData, type NullifierKeys, TypedOracle } from '../acvm/index.js';
17
+ import { type NoteData, TypedOracle } from '../acvm/index.js';
18
18
  import { type DBOracle } from './db_oracle.js';
19
19
  import { pickNotes } from './pick_notes.js';
20
20
 
@@ -35,14 +35,13 @@ export class ViewDataOracle extends TypedOracle {
35
35
  }
36
36
 
37
37
  /**
38
- * Retrieve nullifier keys associated with a specific account and app/contract address.
39
- *
40
- * @param accountAddress - The account address.
41
- * @returns A Promise that resolves to nullifier keys of a requested account and contract.
42
- * @throws An error if the account is not registered in the database.
38
+ * Retrieve keys associated with a specific master public key and app address.
39
+ * @param pkMHash - The master public key hash.
40
+ * @returns A Promise that resolves to nullifier keys.
41
+ * @throws If the keys are not registered in the key store.
43
42
  */
44
- public override getNullifierKeys(account: AztecAddress): Promise<NullifierKeys> {
45
- return this.db.getNullifierKeys(account, this.contractAddress);
43
+ public override getKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
44
+ return this.db.getKeyValidationRequest(pkMHash, this.contractAddress);
46
45
  }
47
46
 
48
47
  /**
@@ -129,11 +128,12 @@ export class ViewDataOracle extends TypedOracle {
129
128
 
130
129
  /**
131
130
  * Retrieve the complete address associated to a given address.
132
- * @param address - Address to fetch the complete address for.
131
+ * @param account - The account address.
133
132
  * @returns A complete address associated with the input address.
133
+ * @throws An error if the account is not registered in the database.
134
134
  */
135
- public override getCompleteAddress(address: AztecAddress): Promise<CompleteAddress> {
136
- return this.db.getCompleteAddress(address);
135
+ public override getCompleteAddress(account: AztecAddress): Promise<CompleteAddress> {
136
+ return this.db.getCompleteAddress(account);
137
137
  }
138
138
 
139
139
  /**
@@ -258,4 +258,9 @@ export class ViewDataOracle extends TypedOracle {
258
258
  }
259
259
  return values;
260
260
  }
261
+
262
+ public override debugLog(message: string, fields: Fr[]): void {
263
+ const formattedStr = applyStringFormatting(message, fields);
264
+ this.log.verbose(`debug_log ${formattedStr}`);
265
+ }
261
266
  }
@@ -1,3 +1,4 @@
1
1
  export * from './packed_values_cache.js';
2
2
  export * from './errors.js';
3
3
  export * from './side_effect_counter.js';
4
+ export * from './return_values.js';
@@ -0,0 +1,18 @@
1
+ import { NestedProcessReturnValues } from '@aztec/circuit-types';
2
+
3
+ import type { ExecutionResult } from '../client/execution_result.js';
4
+ import type { PublicExecutionResult } from '../public/execution.js';
5
+
6
+ /**
7
+ * Recursively accummulate the return values of a call result and its nested executions,
8
+ * so they can be retrieved in order.
9
+ * @param executionResult
10
+ * @returns
11
+ */
12
+ export function accumulateReturnValues(
13
+ executionResult: PublicExecutionResult | ExecutionResult,
14
+ ): NestedProcessReturnValues {
15
+ const acc = new NestedProcessReturnValues(executionResult.returnValues);
16
+ acc.nested = executionResult.nestedExecutions.map(nestedExecution => accumulateReturnValues(nestedExecution));
17
+ return acc;
18
+ }
@@ -116,7 +116,6 @@ export class PublicExecutionResultBuilder {
116
116
  contractStorageReads: [],
117
117
  unencryptedLogsHashes: [],
118
118
  unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
119
- unencryptedLogPreimagesLength: new Fr(4n), // empty logs have len 4
120
119
  allUnencryptedLogs: UnencryptedFunctionL2Logs.empty(),
121
120
  startSideEffectCounter: Fr.ZERO,
122
121
  endSideEffectCounter: Fr.ZERO,
@@ -134,7 +133,8 @@ export const makeFunctionCall = (
134
133
  to = makeAztecAddress(30),
135
134
  selector = makeSelector(5),
136
135
  args = new Array(ARGS_LENGTH).fill(Fr.ZERO),
137
- ) => ({ to, functionData: new FunctionData(selector, false), args });
136
+ isStatic = false,
137
+ ) => ({ to, functionData: new FunctionData(selector, /*isPrivate=*/ false), args, isStatic });
138
138
 
139
139
  export function addKernelPublicCallStack(
140
140
  kernelOutput: PrivateKernelTailCircuitPublicInputs,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MerkleTreeId,
3
- type ProcessReturnValues,
3
+ type NestedProcessReturnValues,
4
4
  type PublicKernelRequest,
5
5
  PublicKernelType,
6
6
  type SimulationError,
@@ -18,6 +18,7 @@ import {
18
18
  type Header,
19
19
  type KernelCircuitPublicInputs,
20
20
  L2ToL1Message,
21
+ LogHash,
21
22
  MAX_NEW_L2_TO_L1_MSGS_PER_CALL,
22
23
  MAX_NEW_NOTE_HASHES_PER_CALL,
23
24
  MAX_NEW_NULLIFIERS_PER_CALL,
@@ -44,7 +45,6 @@ import {
44
45
  PublicKernelData,
45
46
  ReadRequest,
46
47
  RevertCode,
47
- SideEffect,
48
48
  VK_TREE_HEIGHT,
49
49
  VerificationKey,
50
50
  makeEmptyProof,
@@ -57,6 +57,7 @@ import {
57
57
  type PublicExecution,
58
58
  type PublicExecutionResult,
59
59
  type PublicExecutor,
60
+ accumulateReturnValues,
60
61
  collectPublicDataReads,
61
62
  collectPublicDataUpdateRequests,
62
63
  isPublicExecutionResult,
@@ -140,7 +141,7 @@ export abstract class AbstractPhaseManager {
140
141
  * revert reason, if any
141
142
  */
142
143
  revertReason: SimulationError | undefined;
143
- returnValues: ProcessReturnValues;
144
+ returnValues: NestedProcessReturnValues[];
144
145
  /** Gas used during the execution this particular phase. */
145
146
  gasUsed: Gas | undefined;
146
147
  }>;
@@ -227,7 +228,7 @@ export abstract class AbstractPhaseManager {
227
228
  Proof,
228
229
  UnencryptedFunctionL2Logs[],
229
230
  SimulationError | undefined,
230
- ProcessReturnValues,
231
+ NestedProcessReturnValues[],
231
232
  Gas,
232
233
  ]
233
234
  > {
@@ -238,7 +239,7 @@ export abstract class AbstractPhaseManager {
238
239
  const enqueuedCalls = this.extractEnqueuedPublicCalls(tx);
239
240
 
240
241
  if (!enqueuedCalls || !enqueuedCalls.length) {
241
- return [[], kernelOutput, kernelProof, [], undefined, undefined, Gas.empty()];
242
+ return [[], kernelOutput, kernelProof, [], undefined, [], Gas.empty()];
242
243
  }
243
244
 
244
245
  const newUnencryptedFunctionLogs: UnencryptedFunctionL2Logs[] = [];
@@ -250,9 +251,10 @@ export abstract class AbstractPhaseManager {
250
251
  // separate public callstacks to be proven by separate public kernel sequences
251
252
  // and submitted separately to the base rollup?
252
253
 
253
- let returns: ProcessReturnValues = undefined;
254
254
  let gasUsed = Gas.empty();
255
255
 
256
+ const enqueuedCallResults = [];
257
+
256
258
  for (const enqueuedCall of enqueuedCalls) {
257
259
  const executionStack: (PublicExecution | PublicExecutionResult)[] = [enqueuedCall];
258
260
 
@@ -334,13 +336,14 @@ export abstract class AbstractPhaseManager {
334
336
  }`,
335
337
  );
336
338
  // 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];
339
+ return [[], kernelOutput, kernelProof, [], result.revertReason, [], gasUsed];
338
340
  }
339
341
 
340
342
  if (!enqueuedExecutionResult) {
341
343
  enqueuedExecutionResult = result;
342
- returns = result.returnValues;
343
344
  }
345
+
346
+ enqueuedCallResults.push(accumulateReturnValues(enqueuedExecutionResult));
344
347
  }
345
348
  // HACK(#1622): Manually patches the ordering of public state actions
346
349
  // TODO(#757): Enforce proper ordering of public state actions
@@ -350,7 +353,15 @@ export abstract class AbstractPhaseManager {
350
353
  // TODO(#3675): This should be done in a public kernel circuit
351
354
  removeRedundantPublicDataWrites(kernelOutput, this.phase);
352
355
 
353
- return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns, gasUsed];
356
+ return [
357
+ publicKernelInputs,
358
+ kernelOutput,
359
+ kernelProof,
360
+ newUnencryptedFunctionLogs,
361
+ undefined,
362
+ enqueuedCallResults,
363
+ gasUsed,
364
+ ];
354
365
  }
355
366
 
356
367
  /** Returns all pending private and public nullifiers. */
@@ -451,12 +462,7 @@ export abstract class AbstractPhaseManager {
451
462
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
452
463
  ),
453
464
  publicCallStackHashes,
454
- unencryptedLogsHashes: padArrayEnd(
455
- result.unencryptedLogsHashes,
456
- SideEffect.empty(),
457
- MAX_UNENCRYPTED_LOGS_PER_CALL,
458
- ),
459
- unencryptedLogPreimagesLength: result.unencryptedLogPreimagesLength,
465
+ unencryptedLogsHashes: padArrayEnd(result.unencryptedLogsHashes, LogHash.empty(), MAX_UNENCRYPTED_LOGS_PER_CALL),
460
466
  historicalHeader: this.historicalHeader,
461
467
  globalVariables: this.globalVariables,
462
468
  startGasLeft: Gas.from(result.startGasLeft),
@@ -4,13 +4,13 @@ import {
4
4
  type ContractStorageUpdateRequest,
5
5
  type Fr,
6
6
  type L2ToL1Message,
7
+ type LogHash,
7
8
  type NoteHash,
8
9
  type Nullifier,
9
10
  type PublicCallRequest,
10
11
  PublicDataRead,
11
12
  PublicDataUpdateRequest,
12
13
  type ReadRequest,
13
- type SideEffect,
14
14
  } from '@aztec/circuits.js';
15
15
  import { computePublicDataTreeLeafSlot, computePublicDataTreeValue } from '@aztec/circuits.js/hash';
16
16
 
@@ -48,16 +48,12 @@ export interface PublicExecutionResult {
48
48
  * The hashed logs with side effect counter.
49
49
  * Note: required as we don't track the counter anywhere else.
50
50
  */
51
- unencryptedLogsHashes: SideEffect[];
51
+ unencryptedLogsHashes: LogHash[];
52
52
  /**
53
53
  * Unencrypted logs emitted during execution of this function call.
54
54
  * Note: These are preimages to `unencryptedLogsHashes`.
55
55
  */
56
56
  unencryptedLogs: UnencryptedFunctionL2Logs;
57
- /**
58
- * Length of the unencrypted log preimages emitted in this function call.
59
- */
60
- unencryptedLogPreimagesLength: Fr;
61
57
  /**
62
58
  * Unencrypted logs emitted during this call AND any nested calls.
63
59
  * Useful for maintaining correct ordering in ts.
@@ -11,6 +11,7 @@ import {
11
11
  import { createDebugLogger } from '@aztec/foundation/log';
12
12
 
13
13
  import { spawn } from 'child_process';
14
+ import { assert } from 'console';
14
15
  import fs from 'fs/promises';
15
16
  import path from 'path';
16
17
 
@@ -27,7 +28,12 @@ import { PackedValuesCache } from '../common/packed_values_cache.js';
27
28
  import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db.js';
28
29
  import { type PublicExecution, type PublicExecutionResult, checkValidStaticCall } from './execution.js';
29
30
  import { PublicExecutionContext } from './public_execution_context.js';
30
- import { convertAvmResultsToPxResult, createAvmExecutionEnvironment, isAvmBytecode } from './transitional_adaptors.js';
31
+ import {
32
+ convertAvmResultsToPxResult,
33
+ createAvmExecutionEnvironment,
34
+ decompressBytecodeIfCompressed,
35
+ isAvmBytecode,
36
+ } from './transitional_adaptors.js';
31
37
 
32
38
  /**
33
39
  * Execute a public function and return the execution result.
@@ -46,7 +52,7 @@ export async function executePublicFunction(
46
52
  );
47
53
  }
48
54
 
49
- if (isAvmBytecode(bytecode)) {
55
+ if (await isAvmBytecode(bytecode)) {
50
56
  return await executeTopLevelPublicFunctionAvm(context, bytecode);
51
57
  } else {
52
58
  return await executePublicFunctionAcvm(context, bytecode, nested);
@@ -82,7 +88,8 @@ async function executeTopLevelPublicFunctionAvm(
82
88
  for (const nullifier of executionContext.pendingNullifiers) {
83
89
  worldStateJournal.nullifiers.cache.appendSiloed(nullifier.value);
84
90
  }
85
- worldStateJournal.trace.accessCounter = startSideEffectCounter;
91
+ // All the subsequent side effects will have a counter larger than the call's start counter.
92
+ worldStateJournal.trace.accessCounter = startSideEffectCounter + 1;
86
93
 
87
94
  const executionEnv = createAvmExecutionEnvironment(
88
95
  executionContext.execution,
@@ -184,7 +191,6 @@ async function executePublicFunctionAcvm(
184
191
  nestedExecutions: [],
185
192
  unencryptedLogsHashes: [],
186
193
  unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
187
- unencryptedLogPreimagesLength: new Fr(4n), // empty logs have len 4
188
194
  allUnencryptedLogs: UnencryptedFunctionL2Logs.empty(),
189
195
  reverted,
190
196
  revertReason,
@@ -209,7 +215,6 @@ async function executePublicFunctionAcvm(
209
215
  startSideEffectCounter,
210
216
  endSideEffectCounter,
211
217
  unencryptedLogsHashes: unencryptedLogsHashesPadded,
212
- unencryptedLogPreimagesLength,
213
218
  } = PublicCircuitPublicInputs.fromFields(returnWitness);
214
219
  const returnValues = await context.unpackReturns(returnsHash);
215
220
 
@@ -256,7 +261,6 @@ async function executePublicFunctionAcvm(
256
261
  nestedExecutions,
257
262
  unencryptedLogsHashes,
258
263
  unencryptedLogs,
259
- unencryptedLogPreimagesLength,
260
264
  allUnencryptedLogs,
261
265
  reverted: false,
262
266
  revertReason: undefined,
@@ -354,7 +358,10 @@ export class PublicExecutor {
354
358
  const proofPath = path.join(artifactsPath, 'proof');
355
359
 
356
360
  const { args, functionData, contractAddress } = avmExecution;
357
- const bytecode = await this.contractsDb.getBytecode(contractAddress, functionData.selector);
361
+ let bytecode = await this.contractsDb.getBytecode(contractAddress, functionData.selector);
362
+ assert(!!bytecode, `Bytecode not found for ${contractAddress}:${functionData.selector}`);
363
+ // This should be removed once we do bytecode validation.
364
+ bytecode = await decompressBytecodeIfCompressed(bytecode!);
358
365
  // Write call data and bytecode to files.
359
366
  await fs.writeFile(
360
367
  calldataPath,
@@ -3,7 +3,7 @@ import {
3
3
  type Fr,
4
4
  type MAX_NEW_NULLIFIERS_PER_TX,
5
5
  type MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
6
- type MAX_NULLIFIER_READ_REQUESTS_PER_TX,
6
+ MAX_NULLIFIER_READ_REQUESTS_PER_TX,
7
7
  type MAX_PUBLIC_DATA_HINTS,
8
8
  type MAX_PUBLIC_DATA_READS_PER_TX,
9
9
  type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
@@ -27,11 +27,19 @@ import { type IndexedTreeId, type MerkleTreeOperations } from '@aztec/world-stat
27
27
  export class HintsBuilder {
28
28
  constructor(private db: MerkleTreeOperations) {}
29
29
 
30
- getNullifierReadRequestHints(
30
+ async getNullifierReadRequestHints(
31
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 buildSiloedNullifierReadRequestHints(this, nullifierReadRequests, pendingNullifiers);
34
+ return (
35
+ await buildSiloedNullifierReadRequestHints(
36
+ this,
37
+ nullifierReadRequests,
38
+ pendingNullifiers,
39
+ MAX_NULLIFIER_READ_REQUESTS_PER_TX,
40
+ MAX_NULLIFIER_READ_REQUESTS_PER_TX,
41
+ )
42
+ ).hints;
35
43
  }
36
44
 
37
45
  getNullifierNonExistentReadRequestHints(
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  type BlockProver,
3
3
  type FailedTx,
4
- type ProcessReturnValues,
4
+ NestedProcessReturnValues,
5
5
  type ProcessedTx,
6
6
  type PublicKernelRequest,
7
7
  type SimulationError,
@@ -96,12 +96,12 @@ export class PublicProcessor {
96
96
  maxTransactions = txs.length,
97
97
  blockProver?: BlockProver,
98
98
  txValidator?: TxValidator<ProcessedTx>,
99
- ): Promise<[ProcessedTx[], FailedTx[], ProcessReturnValues[]]> {
99
+ ): Promise<[ProcessedTx[], FailedTx[], NestedProcessReturnValues[]]> {
100
100
  // The processor modifies the tx objects in place, so we need to clone them.
101
101
  txs = txs.map(tx => Tx.clone(tx));
102
102
  const result: ProcessedTx[] = [];
103
103
  const failed: FailedTx[] = [];
104
- const returns: ProcessReturnValues[] = [];
104
+ const returns: NestedProcessReturnValues[] = [];
105
105
 
106
106
  for (const tx of txs) {
107
107
  // only process up to the limit of the block
@@ -129,7 +129,7 @@ export class PublicProcessor {
129
129
  await blockProver.addNewTx(processedTx);
130
130
  }
131
131
  result.push(processedTx);
132
- returns.push(returnValues);
132
+ returns.push(returnValues?.[0] ?? new NestedProcessReturnValues([]));
133
133
  } catch (err: any) {
134
134
  const errorMessage = err instanceof Error ? err.message : 'Unknown error';
135
135
  this.log.warn(`Failed to process tx ${tx.getTxHash()}: ${errorMessage}`);
@@ -138,7 +138,7 @@ export class PublicProcessor {
138
138
  tx,
139
139
  error: err instanceof Error ? err : new Error(errorMessage),
140
140
  });
141
- returns.push([]);
141
+ returns.push(new NestedProcessReturnValues([]));
142
142
  }
143
143
  }
144
144
 
@@ -154,8 +154,8 @@ export class PublicProcessor {
154
154
  return makeEmptyProcessedTx(this.historicalHeader.clone(), chainId, version);
155
155
  }
156
156
 
157
- private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, ProcessReturnValues | undefined]> {
158
- let returnValues: ProcessReturnValues = undefined;
157
+ private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, NestedProcessReturnValues[]]> {
158
+ let returnValues: NestedProcessReturnValues[] = [];
159
159
  const publicRequests: PublicKernelRequest[] = [];
160
160
  let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx(
161
161
  tx,
@@ -67,7 +67,7 @@ export class SetupPhaseManager extends AbstractPhaseManager {
67
67
  publicKernelOutput,
68
68
  publicKernelProof,
69
69
  revertReason,
70
- returnValues: undefined,
70
+ returnValues: [],
71
71
  gasUsed,
72
72
  };
73
73
  }