@aztec/simulator 0.33.0 → 0.35.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 (186) hide show
  1. package/dest/acvm/acvm.d.ts +4 -1
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/acvm.js +5 -5
  4. package/dest/acvm/deserialize.d.ts +3 -5
  5. package/dest/acvm/deserialize.d.ts.map +1 -1
  6. package/dest/acvm/deserialize.js +6 -9
  7. package/dest/acvm/oracle/oracle.d.ts +3 -1
  8. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  9. package/dest/acvm/oracle/oracle.js +14 -6
  10. package/dest/acvm/oracle/typed_oracle.d.ts +2 -0
  11. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  12. package/dest/acvm/oracle/typed_oracle.js +7 -1
  13. package/dest/avm/avm_execution_environment.d.ts +6 -3
  14. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  15. package/dest/avm/avm_execution_environment.js +12 -9
  16. package/dest/avm/avm_gas.js +2 -2
  17. package/dest/avm/avm_machine_state.d.ts +2 -0
  18. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  19. package/dest/avm/avm_machine_state.js +24 -6
  20. package/dest/avm/avm_memory_types.js +6 -6
  21. package/dest/avm/avm_simulator.js +7 -7
  22. package/dest/avm/fixtures/index.d.ts +3 -0
  23. package/dest/avm/fixtures/index.d.ts.map +1 -1
  24. package/dest/avm/fixtures/index.js +11 -4
  25. package/dest/avm/journal/journal.d.ts +15 -13
  26. package/dest/avm/journal/journal.d.ts.map +1 -1
  27. package/dest/avm/journal/journal.js +16 -5
  28. package/dest/avm/journal/trace.d.ts +8 -19
  29. package/dest/avm/journal/trace.d.ts.map +1 -1
  30. package/dest/avm/journal/trace.js +48 -116
  31. package/dest/avm/journal/trace_types.d.ts +23 -4
  32. package/dest/avm/journal/trace_types.d.ts.map +1 -1
  33. package/dest/avm/opcodes/accrued_substate.d.ts +2 -1
  34. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  35. package/dest/avm/opcodes/accrued_substate.js +14 -6
  36. package/dest/avm/opcodes/context_getters.js +2 -2
  37. package/dest/avm/opcodes/external_calls.d.ts +2 -2
  38. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  39. package/dest/avm/opcodes/external_calls.js +26 -10
  40. package/dest/avm/opcodes/hashing.d.ts +8 -8
  41. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  42. package/dest/avm/opcodes/hashing.js +35 -43
  43. package/dest/avm/serialization/instruction_serialization.d.ts +1 -1
  44. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  45. package/dest/avm/serialization/instruction_serialization.js +2 -2
  46. package/dest/client/client_execution_context.d.ts +14 -4
  47. package/dest/client/client_execution_context.d.ts.map +1 -1
  48. package/dest/client/client_execution_context.js +28 -13
  49. package/dest/client/private_execution.d.ts +1 -1
  50. package/dest/client/private_execution.d.ts.map +1 -1
  51. package/dest/client/private_execution.js +10 -8
  52. package/dest/client/simulator.d.ts.map +1 -1
  53. package/dest/client/simulator.js +6 -5
  54. package/dest/client/unconstrained_execution.d.ts +1 -1
  55. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  56. package/dest/client/unconstrained_execution.js +6 -5
  57. package/dest/client/view_data_oracle.d.ts +2 -2
  58. package/dest/client/view_data_oracle.d.ts.map +1 -1
  59. package/dest/client/view_data_oracle.js +2 -2
  60. package/dest/common/index.d.ts +1 -1
  61. package/dest/common/index.d.ts.map +1 -1
  62. package/dest/common/index.js +2 -2
  63. package/dest/common/packed_values_cache.d.ts +28 -0
  64. package/dest/common/packed_values_cache.d.ts.map +1 -0
  65. package/dest/common/packed_values_cache.js +50 -0
  66. package/dest/index.d.ts +1 -0
  67. package/dest/index.d.ts.map +1 -1
  68. package/dest/index.js +2 -1
  69. package/dest/mocks/fixtures.d.ts +42 -0
  70. package/dest/mocks/fixtures.d.ts.map +1 -0
  71. package/dest/mocks/fixtures.js +84 -0
  72. package/dest/mocks/index.d.ts +2 -0
  73. package/dest/mocks/index.d.ts.map +1 -0
  74. package/dest/mocks/index.js +2 -0
  75. package/dest/public/abstract_phase_manager.d.ts +82 -0
  76. package/dest/public/abstract_phase_manager.d.ts.map +1 -0
  77. package/dest/public/abstract_phase_manager.js +320 -0
  78. package/dest/public/app_logic_phase_manager.d.ts +29 -0
  79. package/dest/public/app_logic_phase_manager.d.ts.map +1 -0
  80. package/dest/public/app_logic_phase_manager.js +50 -0
  81. package/dest/public/execution.d.ts +3 -0
  82. package/dest/public/execution.d.ts.map +1 -1
  83. package/dest/public/execution.js +1 -1
  84. package/dest/public/executor.d.ts +1 -15
  85. package/dest/public/executor.d.ts.map +1 -1
  86. package/dest/public/executor.js +80 -83
  87. package/dest/public/hints_builder.d.ts +23 -0
  88. package/dest/public/hints_builder.d.ts.map +1 -0
  89. package/dest/public/hints_builder.js +62 -0
  90. package/dest/public/index.d.ts +5 -0
  91. package/dest/public/index.d.ts.map +1 -1
  92. package/dest/public/index.js +6 -1
  93. package/dest/public/phase_manager_factory.d.ts +18 -0
  94. package/dest/public/phase_manager_factory.d.ts.map +1 -0
  95. package/dest/public/phase_manager_factory.js +56 -0
  96. package/dest/public/public_execution_context.d.ts +20 -10
  97. package/dest/public/public_execution_context.d.ts.map +1 -1
  98. package/dest/public/public_execution_context.js +35 -23
  99. package/dest/public/public_executor.d.ts +79 -0
  100. package/dest/public/public_executor.d.ts.map +1 -0
  101. package/dest/public/public_executor.js +198 -0
  102. package/dest/public/public_kernel.d.ts +37 -0
  103. package/dest/public/public_kernel.d.ts.map +1 -0
  104. package/dest/public/public_kernel.js +97 -0
  105. package/dest/public/public_kernel_circuit_simulator.d.ts +31 -0
  106. package/dest/public/public_kernel_circuit_simulator.d.ts.map +1 -0
  107. package/dest/public/public_kernel_circuit_simulator.js +2 -0
  108. package/dest/public/public_processor.d.ts +53 -0
  109. package/dest/public/public_processor.d.ts.map +1 -0
  110. package/dest/public/public_processor.js +144 -0
  111. package/dest/public/setup_phase_manager.d.ts +30 -0
  112. package/dest/public/setup_phase_manager.d.ts.map +1 -0
  113. package/dest/public/setup_phase_manager.js +46 -0
  114. package/dest/public/tail_phase_manager.d.ts +30 -0
  115. package/dest/public/tail_phase_manager.d.ts.map +1 -0
  116. package/dest/public/tail_phase_manager.js +60 -0
  117. package/dest/public/teardown_phase_manager.d.ts +30 -0
  118. package/dest/public/teardown_phase_manager.d.ts.map +1 -0
  119. package/dest/public/teardown_phase_manager.js +46 -0
  120. package/dest/public/transitional_adaptors.d.ts +33 -0
  121. package/dest/public/transitional_adaptors.d.ts.map +1 -0
  122. package/dest/public/transitional_adaptors.js +162 -0
  123. package/dest/public/utils.d.ts +8 -0
  124. package/dest/public/utils.d.ts.map +1 -0
  125. package/dest/public/utils.js +29 -0
  126. package/dest/simulator/acvm_native.d.ts +19 -3
  127. package/dest/simulator/acvm_native.d.ts.map +1 -1
  128. package/dest/simulator/acvm_native.js +75 -48
  129. package/dest/simulator/acvm_wasm.d.ts.map +1 -1
  130. package/dest/simulator/acvm_wasm.js +3 -4
  131. package/package.json +8 -5
  132. package/src/acvm/acvm.ts +8 -5
  133. package/src/acvm/deserialize.ts +5 -9
  134. package/src/acvm/oracle/oracle.ts +15 -5
  135. package/src/acvm/oracle/typed_oracle.ts +8 -0
  136. package/src/avm/avm_execution_environment.ts +17 -17
  137. package/src/avm/avm_gas.ts +1 -1
  138. package/src/avm/avm_machine_state.ts +26 -5
  139. package/src/avm/avm_memory_types.ts +5 -5
  140. package/src/avm/avm_simulator.ts +6 -6
  141. package/src/avm/fixtures/index.ts +14 -1
  142. package/src/avm/journal/journal.ts +37 -17
  143. package/src/avm/journal/trace.ts +59 -121
  144. package/src/avm/journal/trace_types.ts +39 -39
  145. package/src/avm/opcodes/accrued_substate.ts +17 -5
  146. package/src/avm/opcodes/context_getters.ts +1 -1
  147. package/src/avm/opcodes/external_calls.ts +32 -9
  148. package/src/avm/opcodes/hashing.ts +38 -54
  149. package/src/avm/serialization/instruction_serialization.ts +1 -1
  150. package/src/client/client_execution_context.ts +30 -11
  151. package/src/client/private_execution.ts +9 -8
  152. package/src/client/simulator.ts +7 -3
  153. package/src/client/unconstrained_execution.ts +5 -4
  154. package/src/client/view_data_oracle.ts +1 -1
  155. package/src/common/index.ts +1 -1
  156. package/src/common/packed_values_cache.ts +55 -0
  157. package/src/index.ts +1 -0
  158. package/src/mocks/fixtures.ts +169 -0
  159. package/src/mocks/index.ts +1 -0
  160. package/src/public/abstract_phase_manager.ts +571 -0
  161. package/src/public/app_logic_phase_manager.ts +76 -0
  162. package/src/public/execution.ts +4 -0
  163. package/src/public/executor.ts +93 -93
  164. package/src/public/hints_builder.ts +119 -0
  165. package/src/public/index.ts +5 -0
  166. package/src/public/phase_manager_factory.ts +126 -0
  167. package/src/public/public_execution_context.ts +43 -37
  168. package/src/public/public_executor.ts +267 -0
  169. package/src/public/public_kernel.ts +139 -0
  170. package/src/public/public_kernel_circuit_simulator.ts +36 -0
  171. package/src/public/public_processor.ts +212 -0
  172. package/src/public/setup_phase_manager.ts +66 -0
  173. package/src/public/tail_phase_manager.ts +120 -0
  174. package/src/public/teardown_phase_manager.ts +66 -0
  175. package/src/public/transitional_adaptors.ts +249 -0
  176. package/src/public/utils.ts +31 -0
  177. package/src/simulator/acvm_native.ts +94 -47
  178. package/src/simulator/acvm_wasm.ts +7 -3
  179. package/dest/avm/temporary_executor_migration.d.ts +0 -27
  180. package/dest/avm/temporary_executor_migration.d.ts.map +0 -1
  181. package/dest/avm/temporary_executor_migration.js +0 -94
  182. package/dest/common/packed_args_cache.d.ts +0 -28
  183. package/dest/common/packed_args_cache.d.ts.map +0 -1
  184. package/dest/common/packed_args_cache.js +0 -50
  185. package/src/avm/temporary_executor_migration.ts +0 -136
  186. package/src/common/packed_args_cache.ts +0 -55
@@ -1,8 +1,4 @@
1
- import {
2
- type NullifierMembershipWitness,
3
- UnencryptedFunctionL2Logs,
4
- type UnencryptedL2Log,
5
- } from '@aztec/circuit-types';
1
+ import { UnencryptedFunctionL2Logs, type UnencryptedL2Log } from '@aztec/circuit-types';
6
2
  import {
7
3
  CallContext,
8
4
  FunctionData,
@@ -17,7 +13,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
17
13
  import { type ContractInstance } from '@aztec/types/contracts';
18
14
 
19
15
  import { TypedOracle, toACVMWitness } from '../acvm/index.js';
20
- import { type PackedArgsCache, type SideEffectCounter } from '../common/index.js';
16
+ import { type PackedValuesCache, type SideEffectCounter } from '../common/index.js';
21
17
  import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db.js';
22
18
  import { type PublicExecution, type PublicExecutionResult, checkValidStaticCall } from './execution.js';
23
19
  import { executePublicFunction } from './executor.js';
@@ -36,13 +32,13 @@ export class PublicExecutionContext extends TypedOracle {
36
32
  * Data for this execution.
37
33
  */
38
34
  public readonly execution: PublicExecution,
39
- private readonly header: Header,
40
- private readonly globalVariables: GlobalVariables,
41
- private readonly packedArgsCache: PackedArgsCache,
35
+ public readonly header: Header,
36
+ public readonly globalVariables: GlobalVariables,
37
+ private readonly packedValuesCache: PackedValuesCache,
42
38
  private readonly sideEffectCounter: SideEffectCounter,
43
- private readonly stateDb: PublicStateDB,
44
- private readonly contractsDb: PublicContractsDB,
45
- private readonly commitmentsDb: CommitmentsDB,
39
+ public readonly stateDb: PublicStateDB,
40
+ public readonly contractsDb: PublicContractsDB,
41
+ public readonly commitmentsDb: CommitmentsDB,
46
42
  private log = createDebugLogger('aztec:simulator:public_execution_context'),
47
43
  ) {
48
44
  super();
@@ -98,7 +94,23 @@ export class PublicExecutionContext extends TypedOracle {
98
94
  * @param args - Arguments to pack
99
95
  */
100
96
  public packArguments(args: Fr[]): Promise<Fr> {
101
- return Promise.resolve(this.packedArgsCache.pack(args));
97
+ return Promise.resolve(this.packedValuesCache.pack(args));
98
+ }
99
+
100
+ /**
101
+ * Pack the given returns.
102
+ * @param returns - Returns to pack
103
+ */
104
+ public packReturns(returns: Fr[]): Promise<Fr> {
105
+ return Promise.resolve(this.packedValuesCache.pack(returns));
106
+ }
107
+
108
+ /**
109
+ * Unpack the given returns.
110
+ * @param returnsHash - Returns hash to unpack
111
+ */
112
+ public unpackReturns(returnsHash: Fr): Promise<Fr[]> {
113
+ return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
102
114
  }
103
115
 
104
116
  /**
@@ -120,7 +132,7 @@ export class PublicExecutionContext extends TypedOracle {
120
132
  public emitUnencryptedLog(log: UnencryptedL2Log) {
121
133
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/885)
122
134
  this.unencryptedLogs.push(log);
123
- this.log(`Emitted unencrypted log: "${log.toHumanReadable()}"`);
135
+ this.log.verbose(`Emitted unencrypted log: "${log.toHumanReadable()}"`);
124
136
  }
125
137
 
126
138
  /**
@@ -144,7 +156,7 @@ export class PublicExecutionContext extends TypedOracle {
144
156
  const storageSlot = new Fr(startStorageSlot.value + BigInt(i));
145
157
  const sideEffectCounter = this.sideEffectCounter.count();
146
158
  const value = await this.storageActions.read(storageSlot, sideEffectCounter);
147
- this.log(`Oracle storage read: slot=${storageSlot.toString()} value=${value.toString()}`);
159
+ this.log.debug(`Oracle storage read: slot=${storageSlot.toString()} value=${value.toString()}`);
148
160
  values.push(value);
149
161
  }
150
162
  return values;
@@ -163,7 +175,7 @@ export class PublicExecutionContext extends TypedOracle {
163
175
  const sideEffectCounter = this.sideEffectCounter.count();
164
176
  this.storageActions.write(storageSlot, newValue, sideEffectCounter);
165
177
  await this.stateDb.storageWrite(this.execution.callContext.storageContractAddress, storageSlot, newValue);
166
- this.log(`Oracle storage write: slot=${storageSlot.toString()} value=${newValue.toString()}`);
178
+ this.log.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${newValue.toString()}`);
167
179
  newValues.push(newValue);
168
180
  }
169
181
  return newValues;
@@ -186,26 +198,25 @@ export class PublicExecutionContext extends TypedOracle {
186
198
  ) {
187
199
  isStaticCall = isStaticCall || this.execution.callContext.isStaticCall;
188
200
 
189
- const args = this.packedArgsCache.unpack(argsHash);
190
- this.log(`Public function call: addr=${targetContractAddress} selector=${functionSelector} args=${args.join(',')}`);
201
+ const args = this.packedValuesCache.unpack(argsHash);
202
+ this.log.verbose(
203
+ `Public function call: addr=${targetContractAddress} selector=${functionSelector} args=${args.join(',')}`,
204
+ );
191
205
 
192
206
  const portalAddress = (await this.contractsDb.getPortalContractAddress(targetContractAddress)) ?? EthAddress.ZERO;
193
-
194
- const acir = await this.contractsDb.getBytecode(targetContractAddress, functionSelector);
195
- if (!acir) {
196
- throw new Error(`Bytecode not found for ${targetContractAddress}:${functionSelector}`);
197
- }
198
-
199
- const functionData = new FunctionData(functionSelector, false);
200
-
207
+ const functionData = new FunctionData(functionSelector, /*isPrivate=*/ false);
208
+ const { transactionFee, gasSettings, gasLeft } = this.execution.callContext;
201
209
  const callContext = CallContext.from({
202
210
  msgSender: isDelegateCall ? this.execution.callContext.msgSender : this.execution.contractAddress,
203
211
  storageContractAddress: isDelegateCall ? this.execution.contractAddress : targetContractAddress,
204
212
  portalContractAddress: portalAddress,
205
213
  functionSelector,
214
+ gasLeft, // Propagate the same gas left as when we started since ACVM public functions don't have any metering
206
215
  isDelegateCall,
207
216
  isStaticCall,
208
217
  sideEffectCounter,
218
+ gasSettings,
219
+ transactionFee,
209
220
  });
210
221
 
211
222
  const nestedExecution: PublicExecution = {
@@ -219,7 +230,7 @@ export class PublicExecutionContext extends TypedOracle {
219
230
  nestedExecution,
220
231
  this.header,
221
232
  this.globalVariables,
222
- this.packedArgsCache,
233
+ this.packedValuesCache,
223
234
  this.sideEffectCounter,
224
235
  this.stateDb,
225
236
  this.contractsDb,
@@ -227,7 +238,7 @@ export class PublicExecutionContext extends TypedOracle {
227
238
  this.log,
228
239
  );
229
240
 
230
- const childExecutionResult = await executePublicFunction(context, acir, true /** nested */);
241
+ const childExecutionResult = await executePublicFunction(context, /*nested=*/ true);
231
242
 
232
243
  if (isStaticCall) {
233
244
  checkValidStaticCall(
@@ -240,19 +251,14 @@ export class PublicExecutionContext extends TypedOracle {
240
251
  }
241
252
 
242
253
  this.nestedExecutions.push(childExecutionResult);
243
- this.log(`Returning from nested call: ret=${childExecutionResult.returnValues.join(', ')}`);
254
+ this.log.debug(`Returning from nested call: ret=${childExecutionResult.returnValues.join(', ')}`);
244
255
 
245
256
  return childExecutionResult.returnValues;
246
257
  }
247
258
 
248
- public async getNullifierMembershipWitness(
249
- blockNumber: number,
250
- nullifier: Fr,
251
- ): Promise<NullifierMembershipWitness | undefined> {
252
- if (!this.header.globalVariables.blockNumber.equals(new Fr(blockNumber))) {
253
- throw new Error(`Public execution oracle can only access nullifier membership witnesses for the current block`);
254
- }
255
- return await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
259
+ public async checkNullifierExists(nullifier: Fr): Promise<boolean> {
260
+ const witness = await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
261
+ return !!witness;
256
262
  }
257
263
 
258
264
  public async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
@@ -0,0 +1,267 @@
1
+ import { MerkleTreeId, NullifierMembershipWitness, type Tx } from '@aztec/circuit-types';
2
+ import {
3
+ type AztecAddress,
4
+ ContractClassRegisteredEvent,
5
+ ContractInstanceDeployedEvent,
6
+ type EthAddress,
7
+ Fr,
8
+ type FunctionSelector,
9
+ type L1_TO_L2_MSG_TREE_HEIGHT,
10
+ type NULLIFIER_TREE_HEIGHT,
11
+ type NullifierLeafPreimage,
12
+ type PublicDataTreeLeafPreimage,
13
+ } from '@aztec/circuits.js';
14
+ import { computeL1ToL2MessageNullifier, computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
15
+ import { createDebugLogger } from '@aztec/foundation/log';
16
+ import { getCanonicalClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
17
+ import {
18
+ type CommitmentsDB,
19
+ MessageLoadOracleInputs,
20
+ type PublicContractsDB,
21
+ type PublicStateDB,
22
+ } from '@aztec/simulator';
23
+ import {
24
+ type ContractClassPublic,
25
+ type ContractDataSource,
26
+ type ContractInstanceWithAddress,
27
+ } from '@aztec/types/contracts';
28
+ import { type MerkleTreeOperations } from '@aztec/world-state';
29
+
30
+ /**
31
+ * Implements the PublicContractsDB using a ContractDataSource.
32
+ * Progressively records contracts in transaction as they are processed in a block.
33
+ */
34
+ export class ContractsDataSourcePublicDB implements PublicContractsDB {
35
+ private instanceCache = new Map<string, ContractInstanceWithAddress>();
36
+ private classCache = new Map<string, ContractClassPublic>();
37
+
38
+ private log = createDebugLogger('aztec:sequencer:contracts-data-source');
39
+
40
+ constructor(private db: ContractDataSource) {}
41
+
42
+ /**
43
+ * Add new contracts from a transaction
44
+ * @param tx - The transaction to add contracts from.
45
+ */
46
+ public addNewContracts(tx: Tx): Promise<void> {
47
+ // Extract contract class and instance data from logs and add to cache for this block
48
+ const logs = tx.unencryptedLogs.unrollLogs();
49
+ ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e => {
50
+ this.log.debug(`Adding class ${e.contractClassId.toString()} to public execution contract cache`);
51
+ this.classCache.set(e.contractClassId.toString(), e.toContractClassPublic());
52
+ });
53
+ ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => {
54
+ this.log.debug(
55
+ `Adding instance ${e.address.toString()} with class ${e.contractClassId.toString()} to public execution contract cache`,
56
+ );
57
+ this.instanceCache.set(e.address.toString(), e.toContractInstance());
58
+ });
59
+
60
+ return Promise.resolve();
61
+ }
62
+
63
+ /**
64
+ * Removes new contracts added from transactions
65
+ * @param tx - The tx's contracts to be removed
66
+ */
67
+ public removeNewContracts(tx: Tx): Promise<void> {
68
+ // TODO(@spalladino): Can this inadvertently delete a valid contract added by another tx?
69
+ // Let's say we have two txs adding the same contract on the same block. If the 2nd one reverts,
70
+ // wouldn't that accidentally remove the contract added on the first one?
71
+ const logs = tx.unencryptedLogs.unrollLogs();
72
+ ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e =>
73
+ this.classCache.delete(e.contractClassId.toString()),
74
+ );
75
+ ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => this.instanceCache.delete(e.address.toString()));
76
+ return Promise.resolve();
77
+ }
78
+
79
+ public async getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
80
+ return this.instanceCache.get(address.toString()) ?? (await this.db.getContract(address));
81
+ }
82
+
83
+ public async getContractClass(contractClassId: Fr): Promise<ContractClassPublic | undefined> {
84
+ return this.classCache.get(contractClassId.toString()) ?? (await this.db.getContractClass(contractClassId));
85
+ }
86
+
87
+ async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
88
+ const instance = await this.getContractInstance(address);
89
+ if (!instance) {
90
+ throw new Error(`Contract ${address.toString()} not found`);
91
+ }
92
+ const contractClass = await this.getContractClass(instance.contractClassId);
93
+ if (!contractClass) {
94
+ throw new Error(`Contract class ${instance.contractClassId.toString()} for ${address.toString()} not found`);
95
+ }
96
+ return contractClass.publicFunctions.find(f => f.selector.equals(selector))?.bytecode;
97
+ }
98
+
99
+ async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
100
+ const contract = await this.getContractInstance(address);
101
+ return contract?.portalContractAddress;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Implements the PublicStateDB using a world-state database.
107
+ */
108
+ export class WorldStatePublicDB implements PublicStateDB {
109
+ private committedWriteCache: Map<bigint, Fr> = new Map();
110
+ private checkpointedWriteCache: Map<bigint, Fr> = new Map();
111
+ private uncommittedWriteCache: Map<bigint, Fr> = new Map();
112
+
113
+ constructor(private db: MerkleTreeOperations) {}
114
+
115
+ /**
116
+ * Reads a value from public storage, returning zero if none.
117
+ * @param contract - Owner of the storage.
118
+ * @param slot - Slot to read in the contract storage.
119
+ * @returns The current value in the storage slot.
120
+ */
121
+ public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
122
+ const leafSlot = computePublicDataTreeLeafSlot(contract, slot).value;
123
+ const uncommitted = this.uncommittedWriteCache.get(leafSlot);
124
+ if (uncommitted !== undefined) {
125
+ return uncommitted;
126
+ }
127
+ const checkpointed = this.checkpointedWriteCache.get(leafSlot);
128
+ if (checkpointed !== undefined) {
129
+ return checkpointed;
130
+ }
131
+ const committed = this.committedWriteCache.get(leafSlot);
132
+ if (committed !== undefined) {
133
+ return committed;
134
+ }
135
+
136
+ const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
137
+ if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
138
+ return Fr.ZERO;
139
+ }
140
+
141
+ const preimage = (await this.db.getLeafPreimage(
142
+ MerkleTreeId.PUBLIC_DATA_TREE,
143
+ lowLeafResult.index,
144
+ )) as PublicDataTreeLeafPreimage;
145
+
146
+ return preimage.value;
147
+ }
148
+
149
+ /**
150
+ * Records a write to public storage.
151
+ * @param contract - Owner of the storage.
152
+ * @param slot - Slot to read in the contract storage.
153
+ * @param newValue - The new value to store.
154
+ */
155
+ public storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
156
+ const index = computePublicDataTreeLeafSlot(contract, slot).value;
157
+ this.uncommittedWriteCache.set(index, newValue);
158
+ return Promise.resolve();
159
+ }
160
+
161
+ /**
162
+ * Commit the pending changes to the DB.
163
+ * @returns Nothing.
164
+ */
165
+ commit(): Promise<void> {
166
+ for (const [k, v] of this.checkpointedWriteCache) {
167
+ this.committedWriteCache.set(k, v);
168
+ }
169
+ // uncommitted writes take precedence over checkpointed writes
170
+ // since they are the most recent
171
+ for (const [k, v] of this.uncommittedWriteCache) {
172
+ this.committedWriteCache.set(k, v);
173
+ }
174
+ return this.rollbackToCommit();
175
+ }
176
+
177
+ /**
178
+ * Rollback the pending changes.
179
+ * @returns Nothing.
180
+ */
181
+ async rollbackToCommit(): Promise<void> {
182
+ await this.rollbackToCheckpoint();
183
+ this.checkpointedWriteCache = new Map<bigint, Fr>();
184
+ return Promise.resolve();
185
+ }
186
+
187
+ checkpoint(): Promise<void> {
188
+ for (const [k, v] of this.uncommittedWriteCache) {
189
+ this.checkpointedWriteCache.set(k, v);
190
+ }
191
+ return this.rollbackToCheckpoint();
192
+ }
193
+
194
+ rollbackToCheckpoint(): Promise<void> {
195
+ this.uncommittedWriteCache = new Map<bigint, Fr>();
196
+ return Promise.resolve();
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Implements WorldState db using a world state database.
202
+ */
203
+ export class WorldStateDB implements CommitmentsDB {
204
+ constructor(private db: MerkleTreeOperations) {}
205
+
206
+ public async getNullifierMembershipWitnessAtLatestBlock(
207
+ nullifier: Fr,
208
+ ): Promise<NullifierMembershipWitness | undefined> {
209
+ const index = await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
210
+ if (!index) {
211
+ return undefined;
212
+ }
213
+
214
+ const leafPreimagePromise = this.db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
215
+ const siblingPathPromise = this.db.getSiblingPath<typeof NULLIFIER_TREE_HEIGHT>(
216
+ MerkleTreeId.NULLIFIER_TREE,
217
+ BigInt(index),
218
+ );
219
+
220
+ const [leafPreimage, siblingPath] = await Promise.all([leafPreimagePromise, siblingPathPromise]);
221
+
222
+ if (!leafPreimage) {
223
+ return undefined;
224
+ }
225
+
226
+ return new NullifierMembershipWitness(BigInt(index), leafPreimage as NullifierLeafPreimage, siblingPath);
227
+ }
228
+
229
+ public async getL1ToL2MembershipWitness(
230
+ contractAddress: AztecAddress,
231
+ messageHash: Fr,
232
+ secret: Fr,
233
+ ): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
234
+ let nullifierIndex: bigint | undefined;
235
+ let messageIndex: bigint | undefined;
236
+ let startIndex = 0n;
237
+
238
+ // We iterate over messages until we find one whose nullifier is not in the nullifier tree --> we need to check
239
+ // for nullifiers because messages can have duplicates.
240
+ do {
241
+ messageIndex = (await this.db.findLeafIndexAfter(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, messageHash, startIndex))!;
242
+ if (messageIndex === undefined) {
243
+ throw new Error(`No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}`);
244
+ }
245
+
246
+ const messageNullifier = computeL1ToL2MessageNullifier(contractAddress, messageHash, secret, messageIndex);
247
+ nullifierIndex = await this.getNullifierIndex(messageNullifier);
248
+
249
+ startIndex = messageIndex + 1n;
250
+ } while (nullifierIndex !== undefined);
251
+
252
+ const siblingPath = await this.db.getSiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>(
253
+ MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
254
+ messageIndex,
255
+ );
256
+
257
+ return new MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>(messageIndex, siblingPath);
258
+ }
259
+
260
+ public async getCommitmentIndex(commitment: Fr): Promise<bigint | undefined> {
261
+ return await this.db.findLeafIndex(MerkleTreeId.NOTE_HASH_TREE, commitment);
262
+ }
263
+
264
+ public async getNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
265
+ return await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
266
+ }
267
+ }
@@ -0,0 +1,139 @@
1
+ import { type CircuitSimulationStats } from '@aztec/circuit-types/stats';
2
+ import {
3
+ type KernelCircuitPublicInputs,
4
+ type PublicKernelCircuitPrivateInputs,
5
+ type PublicKernelCircuitPublicInputs,
6
+ type PublicKernelTailCircuitPrivateInputs,
7
+ } from '@aztec/circuits.js';
8
+ import { createDebugLogger } from '@aztec/foundation/log';
9
+ import { elapsed } from '@aztec/foundation/timer';
10
+ import {
11
+ PublicKernelAppLogicArtifact,
12
+ PublicKernelSetupArtifact,
13
+ PublicKernelTailArtifact,
14
+ PublicKernelTeardownArtifact,
15
+ convertPublicInnerRollupInputsToWitnessMap,
16
+ convertPublicInnerRollupOutputFromWitnessMap,
17
+ convertPublicSetupRollupInputsToWitnessMap,
18
+ convertPublicSetupRollupOutputFromWitnessMap,
19
+ convertPublicTailInputsToWitnessMap,
20
+ convertPublicTailOutputFromWitnessMap,
21
+ convertPublicTeardownRollupInputsToWitnessMap,
22
+ convertPublicTeardownRollupOutputFromWitnessMap,
23
+ } from '@aztec/noir-protocol-circuits-types';
24
+ import { type SimulationProvider, WASMSimulator } from '@aztec/simulator';
25
+
26
+ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
27
+
28
+ /**
29
+ * Implements the PublicKernelCircuitSimulator.
30
+ */
31
+ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimulator {
32
+ private log = createDebugLogger('aztec:public-kernel-simulator');
33
+
34
+ // Some circuits are so small it is faster to use WASM
35
+ private wasmSimulator: WASMSimulator = new WASMSimulator();
36
+
37
+ constructor(private simulator: SimulationProvider) {}
38
+
39
+ /**
40
+ * Simulates the public kernel setup circuit from its inputs.
41
+ * @param input - Inputs to the circuit.
42
+ * @returns The public inputs as outputs of the simulation.
43
+ */
44
+ public async publicKernelCircuitSetup(
45
+ input: PublicKernelCircuitPrivateInputs,
46
+ ): Promise<PublicKernelCircuitPublicInputs> {
47
+ if (!input.previousKernel.publicInputs.needsSetup) {
48
+ throw new Error(`Expected previous kernel inputs to need setup`);
49
+ }
50
+ const inputWitness = convertPublicSetupRollupInputsToWitnessMap(input);
51
+ const [duration, witness] = await elapsed(() =>
52
+ this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelSetupArtifact),
53
+ );
54
+ const result = convertPublicSetupRollupOutputFromWitnessMap(witness);
55
+ this.log.debug(`Simulated public kernel setup circuit`, {
56
+ eventName: 'circuit-simulation',
57
+ circuitName: 'public-kernel-setup',
58
+ duration,
59
+ inputSize: input.toBuffer().length,
60
+ outputSize: result.toBuffer().length,
61
+ } satisfies CircuitSimulationStats);
62
+ return result;
63
+ }
64
+
65
+ /**
66
+ * Simulates the public kernel app logic circuit from its inputs.
67
+ * @param input - Inputs to the circuit.
68
+ * @returns The public inputs as outputs of the simulation.
69
+ */
70
+ public async publicKernelCircuitAppLogic(
71
+ input: PublicKernelCircuitPrivateInputs,
72
+ ): Promise<PublicKernelCircuitPublicInputs> {
73
+ if (!input.previousKernel.publicInputs.needsAppLogic) {
74
+ throw new Error(`Expected previous kernel inputs to need app logic`);
75
+ }
76
+ const inputWitness = convertPublicInnerRollupInputsToWitnessMap(input);
77
+ const [duration, witness] = await elapsed(() =>
78
+ this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelAppLogicArtifact),
79
+ );
80
+ const result = convertPublicInnerRollupOutputFromWitnessMap(witness);
81
+ this.log.debug(`Simulated public kernel app logic circuit`, {
82
+ eventName: 'circuit-simulation',
83
+ circuitName: 'public-kernel-app-logic',
84
+ duration,
85
+ inputSize: input.toBuffer().length,
86
+ outputSize: result.toBuffer().length,
87
+ } satisfies CircuitSimulationStats);
88
+ return result;
89
+ }
90
+
91
+ /**
92
+ * Simulates the public kernel teardown circuit from its inputs.
93
+ * @param input - Inputs to the circuit.
94
+ * @returns The public inputs as outputs of the simulation.
95
+ */
96
+ public async publicKernelCircuitTeardown(
97
+ input: PublicKernelCircuitPrivateInputs,
98
+ ): Promise<PublicKernelCircuitPublicInputs> {
99
+ if (!input.previousKernel.publicInputs.needsTeardown) {
100
+ throw new Error(`Expected previous kernel inputs to need teardown`);
101
+ }
102
+ const inputWitness = convertPublicTeardownRollupInputsToWitnessMap(input);
103
+ const [duration, witness] = await elapsed(() =>
104
+ this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelTeardownArtifact),
105
+ );
106
+ const result = convertPublicTeardownRollupOutputFromWitnessMap(witness);
107
+ this.log.debug(`Simulated public kernel teardown circuit`, {
108
+ eventName: 'circuit-simulation',
109
+ circuitName: 'public-kernel-teardown',
110
+ duration,
111
+ inputSize: input.toBuffer().length,
112
+ outputSize: result.toBuffer().length,
113
+ } satisfies CircuitSimulationStats);
114
+ return result;
115
+ }
116
+
117
+ /**
118
+ * Simulates the public kernel tail circuit from its inputs.
119
+ * @param input - Inputs to the circuit.
120
+ * @returns The public inputs as outputs of the simulation.
121
+ */
122
+ public async publicKernelCircuitTail(
123
+ input: PublicKernelTailCircuitPrivateInputs,
124
+ ): Promise<KernelCircuitPublicInputs> {
125
+ const inputWitness = convertPublicTailInputsToWitnessMap(input);
126
+ const [duration, witness] = await elapsed(() =>
127
+ this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelTailArtifact),
128
+ );
129
+ const result = convertPublicTailOutputFromWitnessMap(witness);
130
+ this.log.debug(`Simulated public kernel tail circuit`, {
131
+ eventName: 'circuit-simulation',
132
+ circuitName: 'public-kernel-tail',
133
+ duration,
134
+ inputSize: input.toBuffer().length,
135
+ outputSize: result.toBuffer().length,
136
+ } satisfies CircuitSimulationStats);
137
+ return result;
138
+ }
139
+ }
@@ -0,0 +1,36 @@
1
+ import {
2
+ type KernelCircuitPublicInputs,
3
+ type PublicKernelCircuitPrivateInputs,
4
+ type PublicKernelCircuitPublicInputs,
5
+ type PublicKernelTailCircuitPrivateInputs,
6
+ } from '@aztec/circuits.js';
7
+
8
+ /**
9
+ * Circuit simulator for the public kernel circuits.
10
+ */
11
+ export interface PublicKernelCircuitSimulator {
12
+ /**
13
+ * Simulates the public kernel setup circuit from its inputs.
14
+ * @param inputs - Inputs to the circuit.
15
+ * @returns The public inputs as outputs of the simulation.
16
+ */
17
+ publicKernelCircuitSetup(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
18
+ /**
19
+ * Simulates the public kernel app logic circuit from its inputs.
20
+ * @param inputs - Inputs to the circuit.
21
+ * @returns The public inputs as outputs of the simulation.
22
+ */
23
+ publicKernelCircuitAppLogic(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
24
+ /**
25
+ * Simulates the public kernel teardown circuit from its inputs.
26
+ * @param inputs - Inputs to the circuit.
27
+ * @returns The public inputs as outputs of the simulation.
28
+ */
29
+ publicKernelCircuitTeardown(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
30
+ /**
31
+ * Simulates the public kernel tail circuit from its inputs.
32
+ * @param inputs - Inputs to the circuit.
33
+ * @returns The public inputs as outputs of the simulation.
34
+ */
35
+ publicKernelCircuitTail(inputs: PublicKernelTailCircuitPrivateInputs): Promise<KernelCircuitPublicInputs>;
36
+ }