@aztec/simulator 0.69.1 → 0.71.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 (148) hide show
  1. package/dest/acvm/acvm.d.ts +1 -2
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/acvm.js +12 -2
  4. package/dest/acvm/deserialize.d.ts +9 -0
  5. package/dest/acvm/deserialize.d.ts.map +1 -1
  6. package/dest/acvm/deserialize.js +12 -1
  7. package/dest/acvm/index.d.ts +1 -1
  8. package/dest/acvm/index.d.ts.map +1 -1
  9. package/dest/acvm/index.js +2 -2
  10. package/dest/acvm/oracle/oracle.d.ts +9 -5
  11. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  12. package/dest/acvm/oracle/oracle.js +44 -22
  13. package/dest/acvm/oracle/typed_oracle.d.ts +11 -17
  14. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  15. package/dest/acvm/oracle/typed_oracle.js +25 -23
  16. package/dest/avm/avm_simulator.d.ts.map +1 -1
  17. package/dest/avm/avm_simulator.js +7 -1
  18. package/dest/avm/fixtures/index.d.ts +2 -3
  19. package/dest/avm/fixtures/index.d.ts.map +1 -1
  20. package/dest/avm/fixtures/index.js +4 -4
  21. package/dest/avm/journal/journal.d.ts +3 -4
  22. package/dest/avm/journal/journal.d.ts.map +1 -1
  23. package/dest/avm/journal/journal.js +11 -10
  24. package/dest/avm/journal/nullifiers.d.ts +1 -1
  25. package/dest/avm/journal/nullifiers.d.ts.map +1 -1
  26. package/dest/avm/journal/public_storage.d.ts +1 -1
  27. package/dest/avm/journal/public_storage.d.ts.map +1 -1
  28. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  29. package/dest/avm/opcodes/memory.js +9 -5
  30. package/dest/client/client_execution_context.d.ts +29 -18
  31. package/dest/client/client_execution_context.d.ts.map +1 -1
  32. package/dest/client/client_execution_context.js +42 -29
  33. package/dest/client/db_oracle.d.ts +55 -16
  34. package/dest/client/db_oracle.d.ts.map +1 -1
  35. package/dest/client/db_oracle.js +1 -1
  36. package/dest/client/execution_note_cache.d.ts +27 -4
  37. package/dest/client/execution_note_cache.d.ts.map +1 -1
  38. package/dest/client/execution_note_cache.js +62 -12
  39. package/dest/client/index.d.ts +11 -3
  40. package/dest/client/index.d.ts.map +1 -1
  41. package/dest/client/index.js +11 -4
  42. package/dest/client/private_execution.d.ts +3 -2
  43. package/dest/client/private_execution.d.ts.map +1 -1
  44. package/dest/client/private_execution.js +10 -8
  45. package/dest/client/simulator.d.ts +4 -2
  46. package/dest/client/simulator.d.ts.map +1 -1
  47. package/dest/client/simulator.js +14 -9
  48. package/dest/client/unconstrained_execution.d.ts +2 -1
  49. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  50. package/dest/client/unconstrained_execution.js +10 -5
  51. package/dest/client/view_data_oracle.d.ts +7 -10
  52. package/dest/client/view_data_oracle.d.ts.map +1 -1
  53. package/dest/client/view_data_oracle.js +38 -19
  54. package/dest/common/hashed_values_cache.d.ts +28 -0
  55. package/dest/common/hashed_values_cache.d.ts.map +1 -0
  56. package/dest/common/{packed_values_cache.js → hashed_values_cache.js} +22 -22
  57. package/dest/common/index.d.ts +1 -1
  58. package/dest/common/index.js +1 -1
  59. package/dest/common/message_load_oracle_inputs.d.ts +15 -0
  60. package/dest/common/message_load_oracle_inputs.d.ts.map +1 -0
  61. package/dest/common/message_load_oracle_inputs.js +15 -0
  62. package/dest/common/simulation_provider.d.ts +19 -0
  63. package/dest/common/simulation_provider.d.ts.map +1 -0
  64. package/dest/common/simulation_provider.js +27 -0
  65. package/dest/common.d.ts +2 -0
  66. package/dest/common.d.ts.map +1 -0
  67. package/dest/common.js +2 -0
  68. package/dest/providers/acvm_native.d.ts +5 -2
  69. package/dest/providers/acvm_native.d.ts.map +1 -1
  70. package/dest/providers/acvm_native.js +5 -2
  71. package/dest/providers/acvm_wasm.d.ts +8 -2
  72. package/dest/providers/acvm_wasm.d.ts.map +1 -1
  73. package/dest/providers/acvm_wasm.js +31 -5
  74. package/dest/providers/acvm_wasm_with_blobs.d.ts +14 -2
  75. package/dest/providers/acvm_wasm_with_blobs.d.ts.map +1 -1
  76. package/dest/providers/acvm_wasm_with_blobs.js +25 -5
  77. package/dest/providers/factory.d.ts +1 -1
  78. package/dest/providers/factory.d.ts.map +1 -1
  79. package/dest/providers/factory.js +1 -1
  80. package/dest/providers/index.d.ts +1 -1
  81. package/dest/providers/index.d.ts.map +1 -1
  82. package/dest/providers/index.js +2 -2
  83. package/dest/public/db_interfaces.d.ts +1 -1
  84. package/dest/public/db_interfaces.d.ts.map +1 -1
  85. package/dest/public/fixtures/index.d.ts +3 -3
  86. package/dest/public/fixtures/index.d.ts.map +1 -1
  87. package/dest/public/fixtures/index.js +52 -23
  88. package/dest/public/public_db_sources.d.ts +2 -1
  89. package/dest/public/public_db_sources.d.ts.map +1 -1
  90. package/dest/public/public_db_sources.js +2 -2
  91. package/dest/public/public_processor.d.ts +3 -3
  92. package/dest/public/public_processor.d.ts.map +1 -1
  93. package/dest/public/public_processor.js +9 -9
  94. package/dest/public/public_tx_context.d.ts +3 -7
  95. package/dest/public/public_tx_context.d.ts.map +1 -1
  96. package/dest/public/public_tx_context.js +7 -20
  97. package/dest/public/public_tx_simulator.d.ts +1 -1
  98. package/dest/public/public_tx_simulator.d.ts.map +1 -1
  99. package/dest/public/public_tx_simulator.js +7 -7
  100. package/{src/index.ts → dest/server.d.ts} +1 -2
  101. package/dest/server.d.ts.map +1 -0
  102. package/dest/server.js +6 -0
  103. package/package.json +11 -12
  104. package/src/acvm/acvm.ts +20 -3
  105. package/src/acvm/deserialize.ts +12 -0
  106. package/src/acvm/index.ts +1 -1
  107. package/src/acvm/oracle/oracle.ts +90 -28
  108. package/src/acvm/oracle/typed_oracle.ts +41 -24
  109. package/src/avm/avm_simulator.ts +6 -0
  110. package/src/avm/fixtures/index.ts +5 -4
  111. package/src/avm/journal/journal.ts +9 -9
  112. package/src/avm/journal/nullifiers.ts +1 -1
  113. package/src/avm/journal/public_storage.ts +1 -1
  114. package/src/avm/opcodes/memory.ts +8 -4
  115. package/src/client/client_execution_context.ts +47 -30
  116. package/src/client/db_oracle.ts +68 -17
  117. package/src/client/execution_note_cache.ts +67 -14
  118. package/src/client/index.ts +11 -3
  119. package/src/client/private_execution.ts +22 -18
  120. package/src/client/simulator.ts +21 -8
  121. package/src/client/unconstrained_execution.ts +21 -14
  122. package/src/client/view_data_oracle.ts +53 -19
  123. package/src/common/hashed_values_cache.ts +55 -0
  124. package/src/common/index.ts +1 -1
  125. package/src/common/message_load_oracle_inputs.ts +15 -0
  126. package/src/common/simulation_provider.ts +45 -0
  127. package/src/common.ts +1 -0
  128. package/src/providers/acvm_native.ts +12 -2
  129. package/src/providers/acvm_wasm.ts +36 -9
  130. package/src/providers/acvm_wasm_with_blobs.ts +35 -10
  131. package/src/providers/factory.ts +1 -1
  132. package/src/providers/index.ts +1 -1
  133. package/src/public/db_interfaces.ts +1 -1
  134. package/src/public/fixtures/index.ts +66 -36
  135. package/src/public/public_db_sources.ts +3 -6
  136. package/src/public/public_processor.ts +14 -7
  137. package/src/public/public_tx_context.ts +6 -19
  138. package/src/public/public_tx_simulator.ts +6 -6
  139. package/{dest/index.d.ts → src/server.ts} +0 -3
  140. package/dest/common/packed_values_cache.d.ts +0 -28
  141. package/dest/common/packed_values_cache.d.ts.map +0 -1
  142. package/dest/index.d.ts.map +0 -1
  143. package/dest/index.js +0 -8
  144. package/dest/providers/simulation_provider.d.ts +0 -9
  145. package/dest/providers/simulation_provider.d.ts.map +0 -1
  146. package/dest/providers/simulation_provider.js +0 -2
  147. package/src/common/packed_values_cache.ts +0 -55
  148. package/src/providers/simulation_provider.ts +0 -10
@@ -5,7 +5,6 @@ import {
5
5
  type NoteStatus,
6
6
  type NullifierMembershipWitness,
7
7
  type PublicDataWitness,
8
- type SiblingPath,
9
8
  type UnencryptedL2Log,
10
9
  } from '@aztec/circuit-types';
11
10
  import {
@@ -19,6 +18,8 @@ import { type FunctionSelector, type NoteSelector } from '@aztec/foundation/abi'
19
18
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
20
19
  import { Fr } from '@aztec/foundation/fields';
21
20
 
21
+ import { type MessageLoadOracleInputs } from '../../common/message_load_oracle_inputs.js';
22
+
22
23
  /**
23
24
  * Information about a note needed during execution.
24
25
  */
@@ -39,19 +40,6 @@ export interface NoteData {
39
40
  index?: bigint;
40
41
  }
41
42
 
42
- export class MessageLoadOracleInputs<N extends number> {
43
- constructor(
44
- /** The index of the message commitment in the merkle tree. */
45
- public index: bigint,
46
- /** The path in the merkle tree to the message. */
47
- public siblingPath: SiblingPath<N>,
48
- ) {}
49
-
50
- toFields(): Fr[] {
51
- return [new Fr(this.index), ...this.siblingPath.toFields()];
52
- }
53
- }
54
-
55
43
  class OracleMethodNotAvailableError extends Error {
56
44
  constructor(methodName: string) {
57
45
  super(`Oracle method ${methodName} is not available.`);
@@ -68,16 +56,16 @@ export abstract class TypedOracle {
68
56
  return Fr.random();
69
57
  }
70
58
 
71
- packArgumentsArray(_args: Fr[]): Promise<Fr> {
72
- throw new OracleMethodNotAvailableError('packArgumentsArray');
59
+ storeArrayInExecutionCache(_args: Fr[]): Promise<Fr> {
60
+ throw new OracleMethodNotAvailableError('storeArrayInExecutionCache');
73
61
  }
74
62
 
75
- packReturns(_returns: Fr[]): Promise<Fr> {
76
- throw new OracleMethodNotAvailableError('packReturns');
63
+ storeInExecutionCache(_values: Fr[]): Promise<Fr> {
64
+ throw new OracleMethodNotAvailableError('storeInExecutionCache');
77
65
  }
78
66
 
79
- unpackReturns(_returnsHash: Fr): Promise<Fr[]> {
80
- throw new OracleMethodNotAvailableError('unpackReturns');
67
+ loadFromExecutionCache(_hash: Fr): Promise<Fr[]> {
68
+ throw new OracleMethodNotAvailableError('loadFromExecutionCache');
81
69
  }
82
70
 
83
71
  getBlockNumber(): Promise<number> {
@@ -108,10 +96,6 @@ export abstract class TypedOracle {
108
96
  throw new OracleMethodNotAvailableError('getMembershipWitness');
109
97
  }
110
98
 
111
- getSiblingPath(_blockNumber: number, _treeId: MerkleTreeId, _leafIndex: Fr): Promise<Fr[]> {
112
- throw new OracleMethodNotAvailableError('getSiblingPath');
113
- }
114
-
115
99
  getNullifierMembershipWitness(_blockNumber: number, _nullifier: Fr): Promise<NullifierMembershipWitness | undefined> {
116
100
  throw new OracleMethodNotAvailableError('getNullifierMembershipWitness');
117
101
  }
@@ -170,6 +154,10 @@ export abstract class TypedOracle {
170
154
  throw new OracleMethodNotAvailableError('notifyNullifiedNote');
171
155
  }
172
156
 
157
+ notifyCreatedNullifier(_innerNullifier: Fr): Promise<void> {
158
+ throw new OracleMethodNotAvailableError('notifyCreatedNullifier');
159
+ }
160
+
173
161
  checkNullifierExists(_innerNullifier: Fr): Promise<boolean> {
174
162
  throw new OracleMethodNotAvailableError('checkNullifierExists');
175
163
  }
@@ -248,4 +236,33 @@ export abstract class TypedOracle {
248
236
  syncNotes(): Promise<void> {
249
237
  throw new OracleMethodNotAvailableError('syncNotes');
250
238
  }
239
+
240
+ deliverNote(
241
+ _contractAddress: AztecAddress,
242
+ _storageSlot: Fr,
243
+ _nonce: Fr,
244
+ _content: Fr[],
245
+ _noteHash: Fr,
246
+ _nullifier: Fr,
247
+ _txHash: Fr,
248
+ _recipient: AztecAddress,
249
+ ): Promise<void> {
250
+ throw new OracleMethodNotAvailableError('deliverNote');
251
+ }
252
+
253
+ dbStore(_contractAddress: AztecAddress, _key: Fr, _values: Fr[]): Promise<void> {
254
+ throw new OracleMethodNotAvailableError('dbStore');
255
+ }
256
+
257
+ dbLoad(_contractAddress: AztecAddress, _key: Fr): Promise<Fr[] | null> {
258
+ throw new OracleMethodNotAvailableError('dbLoad');
259
+ }
260
+
261
+ dbDelete(_contractAddress: AztecAddress, _key: Fr): Promise<void> {
262
+ throw new OracleMethodNotAvailableError('dbDelete');
263
+ }
264
+
265
+ dbCopy(_contractAddress: AztecAddress, _srcKey: Fr, _dstKey: Fr, _numEntries: number): Promise<void> {
266
+ throw new OracleMethodNotAvailableError('dbCopy');
267
+ }
251
268
  }
@@ -137,6 +137,7 @@ export class AvmSimulator {
137
137
  this.bytecode = bytecode;
138
138
 
139
139
  const { machineState } = this.context;
140
+ const callStartGas = machineState.gasLeft; // Save gas before executing instruction (for profiling)
140
141
  try {
141
142
  // Execute instruction pointed to by the current program counter
142
143
  // continuing until the machine state signifies a halt
@@ -180,6 +181,11 @@ export class AvmSimulator {
180
181
  const revertReason = reverted ? await revertReasonFromExplicitRevert(output, this.context) : undefined;
181
182
  const results = new AvmContractCallResult(reverted, output, machineState.gasLeft, revertReason);
182
183
  this.log.debug(`Context execution results: ${results.toString()}`);
184
+ const totalGasUsed: Gas = {
185
+ l2Gas: callStartGas.l2Gas - machineState.l2GasLeft,
186
+ daGas: callStartGas.daGas - machineState.daGasLeft,
187
+ };
188
+ this.log.debug(`Executed ${instrCounter} instructions and consumed ${totalGasUsed.l2Gas} L2 Gas`);
183
189
 
184
190
  this.tallyPrintFunction();
185
191
  // Return results for processing by calling context
@@ -1,4 +1,4 @@
1
- import { TxHash, isNoirCallStackUnresolved } from '@aztec/circuit-types';
1
+ import { isNoirCallStackUnresolved } from '@aztec/circuit-types';
2
2
  import { GasFees, GlobalVariables, MAX_L2_GAS_PER_TX_PUBLIC_PORTION } from '@aztec/circuits.js';
3
3
  import { type FunctionArtifact, FunctionSelector } from '@aztec/foundation/abi';
4
4
  import { AztecAddress } from '@aztec/foundation/aztec-address';
@@ -10,8 +10,9 @@ import { strict as assert } from 'assert';
10
10
  import { mock } from 'jest-mock-extended';
11
11
  import merge from 'lodash.merge';
12
12
 
13
- import { type WorldStateDB, resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../index.js';
13
+ import { resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../common.js';
14
14
  import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js';
15
+ import { type WorldStateDB } from '../../server.js';
15
16
  import { AvmContext } from '../avm_context.js';
16
17
  import { AvmExecutionEnvironment } from '../avm_execution_environment.js';
17
18
  import { AvmMachineState } from '../avm_machine_state.js';
@@ -45,7 +46,7 @@ export function initPersistableStateManager(overrides?: {
45
46
  nullifiers?: NullifierManager;
46
47
  doMerkleOperations?: boolean;
47
48
  merkleTrees?: AvmEphemeralForest;
48
- txHash?: TxHash;
49
+ firstNullifier?: Fr;
49
50
  }): AvmPersistableStateManager {
50
51
  const worldStateDB = overrides?.worldStateDB || mock<WorldStateDB>();
51
52
  return new AvmPersistableStateManager(
@@ -55,7 +56,7 @@ export function initPersistableStateManager(overrides?: {
55
56
  overrides?.nullifiers || new NullifierManager(worldStateDB),
56
57
  overrides?.doMerkleOperations || false,
57
58
  overrides?.merkleTrees || mock<AvmEphemeralForest>(),
58
- overrides?.txHash || new TxHash(new Fr(27)),
59
+ overrides?.firstNullifier || new Fr(27),
59
60
  );
60
61
  }
61
62
 
@@ -1,4 +1,4 @@
1
- import { MerkleTreeId, type TxHash } from '@aztec/circuit-types';
1
+ import { MerkleTreeId } from '@aztec/circuit-types';
2
2
  import {
3
3
  AztecAddress,
4
4
  CANONICAL_AUTH_REGISTRY_ADDRESS,
@@ -61,7 +61,7 @@ export class AvmPersistableStateManager {
61
61
  private readonly doMerkleOperations: boolean = false,
62
62
  /** Ephmeral forest for merkle tree operations */
63
63
  public merkleTrees: AvmEphemeralForest,
64
- public readonly txHash: TxHash,
64
+ public readonly firstNullifier: Fr,
65
65
  ) {}
66
66
 
67
67
  /**
@@ -71,7 +71,7 @@ export class AvmPersistableStateManager {
71
71
  worldStateDB: WorldStateDB,
72
72
  trace: PublicSideEffectTraceInterface,
73
73
  doMerkleOperations: boolean = false,
74
- txHash: TxHash,
74
+ firstNullifier: Fr,
75
75
  ) {
76
76
  const ephemeralForest = await AvmEphemeralForest.create(worldStateDB.getMerkleInterface());
77
77
  return new AvmPersistableStateManager(
@@ -81,7 +81,7 @@ export class AvmPersistableStateManager {
81
81
  /*nullifiers=*/ new NullifierManager(worldStateDB),
82
82
  /*doMerkleOperations=*/ doMerkleOperations,
83
83
  ephemeralForest,
84
- txHash,
84
+ firstNullifier,
85
85
  );
86
86
  }
87
87
 
@@ -96,7 +96,7 @@ export class AvmPersistableStateManager {
96
96
  this.nullifiers.fork(),
97
97
  this.doMerkleOperations,
98
98
  this.merkleTrees.fork(),
99
- this.txHash,
99
+ this.firstNullifier,
100
100
  );
101
101
  }
102
102
 
@@ -124,13 +124,14 @@ export class AvmPersistableStateManager {
124
124
  this.publicStorage.acceptAndMerge(forkedState.publicStorage);
125
125
  this.nullifiers.acceptAndMerge(forkedState.nullifiers);
126
126
  this.trace.merge(forkedState.trace, reverted);
127
- if (!reverted) {
128
- this.merkleTrees = forkedState.merkleTrees;
127
+ if (reverted) {
129
128
  if (this.doMerkleOperations) {
130
129
  this.log.debug(
131
130
  `Rolled back nullifier tree to root ${this.merkleTrees.treeMap.get(MerkleTreeId.NULLIFIER_TREE)!.getRoot()}`,
132
131
  );
133
132
  }
133
+ } else {
134
+ this.merkleTrees = forkedState.merkleTrees;
134
135
  }
135
136
  }
136
137
 
@@ -293,8 +294,7 @@ export class AvmPersistableStateManager {
293
294
  * @param noteHash - the non unique note hash to write
294
295
  */
295
296
  public writeSiloedNoteHash(noteHash: Fr): void {
296
- const txHash = Fr.fromBuffer(this.txHash.toBuffer());
297
- const nonce = computeNoteHashNonce(txHash, this.trace.getNoteHashCount());
297
+ const nonce = computeNoteHashNonce(this.firstNullifier, this.trace.getNoteHashCount());
298
298
  const uniqueNoteHash = computeUniqueNoteHash(nonce, noteHash);
299
299
 
300
300
  this.writeUniqueNoteHash(uniqueNoteHash);
@@ -1,6 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
 
3
- import type { CommitmentsDB } from '../../index.js';
3
+ import type { CommitmentsDB } from '../../server.js';
4
4
 
5
5
  /**
6
6
  * A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
@@ -1,7 +1,7 @@
1
1
  import { type AztecAddress } from '@aztec/circuits.js';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
 
4
- import type { PublicStateDB } from '../../index.js';
4
+ import type { PublicStateDB } from '../../server.js';
5
5
 
6
6
  type PublicStorageReadResult = {
7
7
  value: Fr;
@@ -190,7 +190,10 @@ export class CalldataCopy extends Instruction {
190
190
  const copySize = memory.get(copySizeOffset).toNumber();
191
191
  context.machineState.consumeGas(this.gasCost(copySize));
192
192
 
193
- const transformedData = context.environment.calldata.slice(cdStart, cdStart + copySize).map(f => new Field(f));
193
+ // Values which are out-of-range of the calldata array will be set with Field(0);
194
+ const slice = context.environment.calldata.slice(cdStart, cdStart + copySize).map(f => new Field(f));
195
+ // slice has size = MIN(copySize, calldata.length - cdStart) as TS truncates out-of-range portion
196
+ const transformedData = [...slice, ...Array(copySize - slice.length).fill(new Field(0))];
194
197
 
195
198
  memory.setSlice(dstOffset, transformedData);
196
199
 
@@ -253,9 +256,10 @@ export class ReturndataCopy extends Instruction {
253
256
  const copySize = memory.get(copySizeOffset).toNumber();
254
257
  context.machineState.consumeGas(this.gasCost(copySize));
255
258
 
256
- const transformedData = context.machineState.nestedReturndata
257
- .slice(rdStart, rdStart + copySize)
258
- .map(f => new Field(f));
259
+ // Values which are out-of-range of the returndata array will be set with Field(0);
260
+ const slice = context.machineState.nestedReturndata.slice(rdStart, rdStart + copySize).map(f => new Field(f));
261
+ // slice has size = MIN(copySize, returndata.length - rdStart) as TS truncates out-of-range portion
262
+ const transformedData = [...slice, ...Array(copySize - slice.length).fill(new Field(0))];
259
263
 
260
264
  memory.setSlice(dstOffset, transformedData);
261
265
 
@@ -6,7 +6,7 @@ import {
6
6
  Note,
7
7
  NoteAndSlot,
8
8
  type NoteStatus,
9
- type PrivateExecutionResult,
9
+ type PrivateCallExecutionResult,
10
10
  PublicExecutionRequest,
11
11
  type UnencryptedL2Log,
12
12
  } from '@aztec/circuit-types';
@@ -26,7 +26,8 @@ import { Fr } from '@aztec/foundation/fields';
26
26
  import { createLogger } from '@aztec/foundation/log';
27
27
 
28
28
  import { type NoteData, toACVMWitness } from '../acvm/index.js';
29
- import { type PackedValuesCache } from '../common/packed_values_cache.js';
29
+ import { type HashedValuesCache } from '../common/hashed_values_cache.js';
30
+ import { type SimulationProvider } from '../server.js';
30
31
  import { type DBOracle } from './db_oracle.js';
31
32
  import { type ExecutionNoteCache } from './execution_note_cache.js';
32
33
  import { pickNotes } from './pick_notes.js';
@@ -57,7 +58,7 @@ export class ClientExecutionContext extends ViewDataOracle {
57
58
  private noteHashLeafIndexMap: Map<bigint, bigint> = new Map();
58
59
  private noteHashNullifierCounterMap: Map<number, number> = new Map();
59
60
  private contractClassLogs: CountedContractClassLog[] = [];
60
- private nestedExecutions: PrivateExecutionResult[] = [];
61
+ private nestedExecutions: PrivateCallExecutionResult[] = [];
61
62
  private enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[] = [];
62
63
  private publicTeardownFunctionCall: PublicExecutionRequest = PublicExecutionRequest.empty();
63
64
 
@@ -69,10 +70,11 @@ export class ClientExecutionContext extends ViewDataOracle {
69
70
  protected readonly historicalHeader: BlockHeader,
70
71
  /** List of transient auth witnesses to be used during this simulation */
71
72
  authWitnesses: AuthWitness[],
72
- private readonly packedValuesCache: PackedValuesCache,
73
+ private readonly executionCache: HashedValuesCache,
73
74
  private readonly noteCache: ExecutionNoteCache,
74
75
  db: DBOracle,
75
76
  private node: AztecNode,
77
+ private provider: SimulationProvider,
76
78
  protected sideEffectCounter: number = 0,
77
79
  log = createLogger('simulator:client_execution_context'),
78
80
  scopes?: AztecAddress[],
@@ -90,7 +92,7 @@ export class ClientExecutionContext extends ViewDataOracle {
90
92
  public getInitialWitness(abi: FunctionAbi) {
91
93
  const argumentsSize = countArgumentsSize(abi);
92
94
 
93
- const args = this.packedValuesCache.unpack(this.argsHash);
95
+ const args = this.executionCache.getPreimage(this.argsHash);
94
96
 
95
97
  if (args.length !== argumentsSize) {
96
98
  throw new Error('Invalid arguments size');
@@ -159,27 +161,29 @@ export class ClientExecutionContext extends ViewDataOracle {
159
161
  }
160
162
 
161
163
  /**
162
- * Pack the given array of arguments.
163
- * @param args - Arguments to pack
164
+ * Store values in the execution cache.
165
+ * @param values - Values to store.
164
166
  */
165
- public override packArgumentsArray(args: Fr[]): Promise<Fr> {
166
- return Promise.resolve(this.packedValuesCache.pack(args));
167
+ public override storeArrayInExecutionCache(args: Fr[]): Promise<Fr> {
168
+ return Promise.resolve(this.executionCache.store(args));
167
169
  }
168
170
 
169
171
  /**
170
- * Pack the given returns.
171
- * @param returns - Returns to pack
172
+ * Store values in the execution cache.
173
+ * @param values - Values to store.
174
+ * @returns The hash of the values.
172
175
  */
173
- public override packReturns(returns: Fr[]): Promise<Fr> {
174
- return Promise.resolve(this.packedValuesCache.pack(returns));
176
+ public override storeInExecutionCache(values: Fr[]): Promise<Fr> {
177
+ return Promise.resolve(this.executionCache.store(values));
175
178
  }
176
179
 
177
180
  /**
178
- * Unpack the given returns.
179
- * @param returnsHash - Returns hash to unpack
181
+ * Gets values from the execution cache.
182
+ * @param hash - Hash of the values.
183
+ * @returns The values.
180
184
  */
181
- public override unpackReturns(returnsHash: Fr): Promise<Fr[]> {
182
- return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
185
+ public override loadFromExecutionCache(hash: Fr): Promise<Fr[]> {
186
+ return Promise.resolve(this.executionCache.getPreimage(hash));
183
187
  }
184
188
 
185
189
  /**
@@ -307,6 +311,17 @@ export class ClientExecutionContext extends ViewDataOracle {
307
311
  return Promise.resolve();
308
312
  }
309
313
 
314
+ /**
315
+ * Adding a siloed nullifier into the current set of all pending nullifiers created
316
+ * within the current transaction/execution.
317
+ * @param innerNullifier - The pending nullifier to add in the list (not yet siloed by contract address).
318
+ * @param noteHash - A hash of the new note.
319
+ */
320
+ public override notifyCreatedNullifier(innerNullifier: Fr) {
321
+ this.noteCache.nullifierCreated(this.callContext.contractAddress, innerNullifier);
322
+ return Promise.resolve();
323
+ }
324
+
310
325
  /**
311
326
  * Emit a contract class unencrypted log.
312
327
  * This fn exists because sha hashing the preimage
@@ -323,7 +338,7 @@ export class ClientExecutionContext extends ViewDataOracle {
323
338
  return Fr.fromBuffer(log.hash());
324
339
  }
325
340
 
326
- #checkValidStaticCall(childExecutionResult: PrivateExecutionResult) {
341
+ #checkValidStaticCall(childExecutionResult: PrivateCallExecutionResult) {
327
342
  if (
328
343
  childExecutionResult.publicInputs.noteHashes.some(item => !item.isEmpty()) ||
329
344
  childExecutionResult.publicInputs.nullifiers.some(item => !item.isEmpty()) ||
@@ -339,7 +354,7 @@ export class ClientExecutionContext extends ViewDataOracle {
339
354
  * Calls a private function as a nested execution.
340
355
  * @param targetContractAddress - The address of the contract to call.
341
356
  * @param functionSelector - The function selector of the function to call.
342
- * @param argsHash - The packed arguments to pass to the function.
357
+ * @param argsHash - The arguments hash to pass to the function.
343
358
  * @param sideEffectCounter - The side effect counter at the start of the call.
344
359
  * @param isStaticCall - Whether the call is a static call.
345
360
  * @returns The execution result.
@@ -369,16 +384,18 @@ export class ClientExecutionContext extends ViewDataOracle {
369
384
  derivedCallContext,
370
385
  this.historicalHeader,
371
386
  this.authWitnesses,
372
- this.packedValuesCache,
387
+ this.executionCache,
373
388
  this.noteCache,
374
389
  this.db,
375
390
  this.node,
391
+ this.provider,
376
392
  sideEffectCounter,
377
393
  this.log,
378
394
  this.scopes,
379
395
  );
380
396
 
381
397
  const childExecutionResult = await executePrivateFunction(
398
+ this.provider,
382
399
  context,
383
400
  targetArtifact,
384
401
  targetContractAddress,
@@ -402,7 +419,7 @@ export class ClientExecutionContext extends ViewDataOracle {
402
419
  * Creates a PublicExecutionRequest object representing the request to call a public function.
403
420
  * @param targetContractAddress - The address of the contract to call.
404
421
  * @param functionSelector - The function selector of the function to call.
405
- * @param argsHash - The packed arguments to pass to the function.
422
+ * @param argsHash - The arguments hash to pass to the function.
406
423
  * @param sideEffectCounter - The side effect counter at the start of the call.
407
424
  * @param isStaticCall - Whether the call is a static call.
408
425
  * @returns The public call stack item with the request information.
@@ -417,7 +434,7 @@ export class ClientExecutionContext extends ViewDataOracle {
417
434
  ) {
418
435
  const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector);
419
436
  const derivedCallContext = this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall);
420
- const args = this.packedValuesCache.unpack(argsHash);
437
+ const args = this.executionCache.getPreimage(argsHash);
421
438
 
422
439
  this.log.verbose(
423
440
  `Created ${callType} public execution request to ${targetArtifact.name}@${targetContractAddress}`,
@@ -448,7 +465,7 @@ export class ClientExecutionContext extends ViewDataOracle {
448
465
  * of the execution are empty.
449
466
  * @param targetContractAddress - The address of the contract to call.
450
467
  * @param functionSelector - The function selector of the function to call.
451
- * @param argsHash - The packed arguments to pass to the function.
468
+ * @param argsHash - The arguments hash to pass to the function.
452
469
  * @param sideEffectCounter - The side effect counter at the start of the call.
453
470
  * @param isStaticCall - Whether the call is a static call.
454
471
  * @returns The public call stack item with the request information.
@@ -462,13 +479,13 @@ export class ClientExecutionContext extends ViewDataOracle {
462
479
  ): Promise<Fr> {
463
480
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
464
481
  // WARNING: This is insecure and should be temporary!
465
- // The oracle repacks the arguments and returns a new args_hash.
482
+ // The oracle re-hashes the arguments and returns a new args_hash.
466
483
  // new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
467
484
  // We don't validate or compute it in the circuit because a) it's harder to do with slices, and
468
485
  // b) this is only temporary.
469
- const newArgsHash = this.packedValuesCache.pack([
486
+ const newArgsHash = this.executionCache.store([
470
487
  functionSelector.toField(),
471
- ...this.packedValuesCache.unpack(argsHash),
488
+ ...this.executionCache.getPreimage(argsHash),
472
489
  ]);
473
490
  await this.createPublicExecutionRequest(
474
491
  'enqueued',
@@ -487,7 +504,7 @@ export class ClientExecutionContext extends ViewDataOracle {
487
504
  * of the execution are empty.
488
505
  * @param targetContractAddress - The address of the contract to call.
489
506
  * @param functionSelector - The function selector of the function to call.
490
- * @param argsHash - The packed arguments to pass to the function.
507
+ * @param argsHash - The arguments hash to pass to the function.
491
508
  * @param sideEffectCounter - The side effect counter at the start of the call.
492
509
  * @param isStaticCall - Whether the call is a static call.
493
510
  * @returns The public call stack item with the request information.
@@ -501,13 +518,13 @@ export class ClientExecutionContext extends ViewDataOracle {
501
518
  ): Promise<Fr> {
502
519
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
503
520
  // WARNING: This is insecure and should be temporary!
504
- // The oracle repacks the arguments and returns a new args_hash.
521
+ // The oracle rehashes the arguments and returns a new args_hash.
505
522
  // new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
506
523
  // We don't validate or compute it in the circuit because a) it's harder to do with slices, and
507
524
  // b) this is only temporary.
508
- const newArgsHash = this.packedValuesCache.pack([
525
+ const newArgsHash = this.executionCache.store([
509
526
  functionSelector.toField(),
510
- ...this.packedValuesCache.unpack(argsHash),
527
+ ...this.executionCache.getPreimage(argsHash),
511
528
  ]);
512
529
  await this.createPublicExecutionRequest(
513
530
  'teardown',
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  type L2Block,
3
- type L2BlockNumber,
4
3
  type MerkleTreeId,
5
4
  type NoteStatus,
6
5
  type NullifierMembershipWitness,
@@ -141,22 +140,13 @@ export interface DBOracle extends CommitmentsDB {
141
140
  getBlockHeader(): Promise<BlockHeader>;
142
141
 
143
142
  /**
144
- * Fetch the index of the leaf in the respective tree
145
- * @param blockNumber - The block number at which to get the leaf index.
146
- * @param treeId - The id of the tree to search.
147
- * @param leafValue - The leaf value buffer.
148
- * @returns - The index of the leaf. Undefined if it does not exist in the tree.
143
+ * Fetches the index and sibling path of a leaf at a given block from a given tree.
144
+ * @param blockNumber - The block number at which to get the membership witness.
145
+ * @param treeId - Id of the tree to get the sibling path from.
146
+ * @param leafValue - The leaf value
147
+ * @returns The index and sibling path concatenated [index, sibling_path]
149
148
  */
150
- findLeafIndex(blockNumber: L2BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined>;
151
-
152
- /**
153
- * Fetch the sibling path of the leaf in the respective tree
154
- * @param blockNumber - The block number at which to get the sibling path.
155
- * @param treeId - The id of the tree to search.
156
- * @param leafIndex - The index of the leaf.
157
- * @returns - The sibling path of the leaf.
158
- */
159
- getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: bigint): Promise<Fr[]>;
149
+ getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]>;
160
150
 
161
151
  /**
162
152
  * Returns a nullifier membership witness for a given nullifier at a given block.
@@ -224,7 +214,7 @@ export interface DBOracle extends CommitmentsDB {
224
214
  ): Promise<void>;
225
215
 
226
216
  /**
227
- * Synchronizes the logs tagged with the recipient's address and all the senders in the addressbook.
217
+ * Synchronizes the logs tagged with the recipient's address and all the senders in the address book.
228
218
  * Returns the unsynched logs and updates the indexes of the secrets used to tag them until there are no more logs to sync.
229
219
  * @param contractAddress - The address of the contract that the logs are tagged for
230
220
  * @param recipient - The address of the recipient
@@ -243,8 +233,69 @@ export interface DBOracle extends CommitmentsDB {
243
233
  */
244
234
  processTaggedLogs(logs: TxScopedL2Log[], recipient: AztecAddress): Promise<void>;
245
235
 
236
+ /**
237
+ * Delivers the preimage and metadata of a committed note so that it can be later requested via the `getNotes`
238
+ * oracle.
239
+ *
240
+ * @param contractAddress - The address of the contract that created the note (i.e. the siloing contract)
241
+ * @param storageSlot - The storage slot of the note - used for indexing in `getNotes`
242
+ * @param nonce - The nonce of the note used by the kernel to compute the unique note hash
243
+ * @param content - The note's content: this is the primary item to return in `getNotes`
244
+ * @param noteHash - The non-unique non-siloed note hash
245
+ * @param nullifier - The inner (non-siloed) note nullifier
246
+ * @param txHash - The transaction in which the note was added to the note hash tree
247
+ * @param recipient - The account that discovered the note
248
+ */
249
+ deliverNote(
250
+ contractAddress: AztecAddress,
251
+ storageSlot: Fr,
252
+ nonce: Fr,
253
+ content: Fr[],
254
+ noteHash: Fr,
255
+ nullifier: Fr,
256
+ txHash: Fr,
257
+ recipient: AztecAddress,
258
+ ): Promise<void>;
259
+
246
260
  /**
247
261
  * Removes all of a contract's notes that have been nullified from the note database.
248
262
  */
249
263
  removeNullifiedNotes(contractAddress: AztecAddress): Promise<void>;
264
+
265
+ /**
266
+ * Stores arbitrary information in a per-contract non-volatile database, which can later be retrieved with `dbLoad`.
267
+ * * If data was already stored at this slot, it is overwrriten.
268
+ * @param contractAddress - The contract address to scope the data under.
269
+ * @param slot - The slot in the database in which to store the value. Slots need not be contiguous.
270
+ * @param values - The data to store.
271
+ */
272
+ dbStore(contractAddress: AztecAddress, slot: Fr, values: Fr[]): Promise<void>;
273
+
274
+ /**
275
+ * Returns data previously stored via `dbStore` in the per-contract non-volatile database.
276
+ * @param contractAddress - The contract address under which the data is scoped.
277
+ * @param slot - The slot in the database to read.
278
+ * @returns The stored data or `null` if no data is stored under the slot.
279
+ */
280
+ dbLoad(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null>;
281
+
282
+ /**
283
+ * Deletes data in the per-contract non-volatile database. Does nothing if no data was present.
284
+ * @param contractAddress - The contract address under which the data is scoped.
285
+ * @param slot - The slot in the database to delete.
286
+ */
287
+ dbDelete(contractAddress: AztecAddress, slot: Fr): Promise<void>;
288
+
289
+ /**
290
+ * Copies a number of contiguous entries in the per-contract non-volatile database. This allows for efficient data
291
+ * structures by avoiding repeated calls to `dbLoad` and `dbStore`.
292
+ * Supports overlapping source and destination regions (which will result in the overlapped source values being
293
+ * overwritten). All copied slots must exist in the database (i.e. have been stored and not deleted)
294
+ *
295
+ * @param contractAddress - The contract address under which the data is scoped.
296
+ * @param srcSlot - The first slot to copy from.
297
+ * @param dstSlot - The first slot to copy to.
298
+ * @param numEntries - The number of entries to copy.
299
+ */
300
+ dbCopy(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
250
301
  }