@aztec/simulator 0.77.0-testnet-ignition.26 → 0.77.0-testnet-ignition.28

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 (198) hide show
  1. package/dest/private/index.js +2 -2
  2. package/dest/private/private_execution.js +18 -16
  3. package/dest/private/{client_execution_context.js → private_execution_oracle.js} +24 -19
  4. package/dest/private/simulator.js +12 -14
  5. package/dest/private/{view_data_oracle.js → unconstrained_execution_oracle.js} +32 -34
  6. package/dest/public/public_tx_simulator/public_tx_simulator.js +21 -12
  7. package/package.json +14 -14
  8. package/src/private/{db_oracle.ts → execution_data_provider.ts} +28 -2
  9. package/src/private/index.ts +6 -2
  10. package/src/private/private_execution.ts +21 -20
  11. package/src/private/{client_execution_context.ts → private_execution_oracle.ts} +41 -26
  12. package/src/private/simulator.ts +20 -24
  13. package/src/private/unconstrained_execution.ts +2 -2
  14. package/src/private/{view_data_oracle.ts → unconstrained_execution_oracle.ts} +42 -35
  15. package/src/public/public_tx_simulator/public_tx_simulator.ts +29 -16
  16. package/dest/client.d.ts +0 -5
  17. package/dest/client.d.ts.map +0 -1
  18. package/dest/common/db_interfaces.d.ts +0 -80
  19. package/dest/common/db_interfaces.d.ts.map +0 -1
  20. package/dest/common/debug_fn_name.d.ts +0 -5
  21. package/dest/common/debug_fn_name.d.ts.map +0 -1
  22. package/dest/common/errors.d.ts +0 -54
  23. package/dest/common/errors.d.ts.map +0 -1
  24. package/dest/common/index.d.ts +0 -4
  25. package/dest/common/index.d.ts.map +0 -1
  26. package/dest/common/message_load_oracle_inputs.d.ts +0 -15
  27. package/dest/common/message_load_oracle_inputs.d.ts.map +0 -1
  28. package/dest/common/stats/index.d.ts +0 -2
  29. package/dest/common/stats/index.d.ts.map +0 -1
  30. package/dest/common/stats/stats.d.ts +0 -4
  31. package/dest/common/stats/stats.d.ts.map +0 -1
  32. package/dest/private/acvm/acvm.d.ts +0 -35
  33. package/dest/private/acvm/acvm.d.ts.map +0 -1
  34. package/dest/private/acvm/acvm_types.d.ts +0 -10
  35. package/dest/private/acvm/acvm_types.d.ts.map +0 -1
  36. package/dest/private/acvm/deserialize.d.ts +0 -36
  37. package/dest/private/acvm/deserialize.d.ts.map +0 -1
  38. package/dest/private/acvm/index.d.ts +0 -6
  39. package/dest/private/acvm/index.d.ts.map +0 -1
  40. package/dest/private/acvm/oracle/index.d.ts +0 -14
  41. package/dest/private/acvm/oracle/index.d.ts.map +0 -1
  42. package/dest/private/acvm/oracle/oracle.d.ts +0 -49
  43. package/dest/private/acvm/oracle/oracle.d.ts.map +0 -1
  44. package/dest/private/acvm/oracle/typed_oracle.d.ts +0 -83
  45. package/dest/private/acvm/oracle/typed_oracle.d.ts.map +0 -1
  46. package/dest/private/acvm/serialize.d.ts +0 -24
  47. package/dest/private/acvm/serialize.d.ts.map +0 -1
  48. package/dest/private/client_execution_context.d.ts +0 -217
  49. package/dest/private/client_execution_context.d.ts.map +0 -1
  50. package/dest/private/db_oracle.d.ts +0 -238
  51. package/dest/private/db_oracle.d.ts.map +0 -1
  52. package/dest/private/execution_note_cache.d.ts +0 -93
  53. package/dest/private/execution_note_cache.d.ts.map +0 -1
  54. package/dest/private/hashed_values_cache.d.ts +0 -28
  55. package/dest/private/hashed_values_cache.d.ts.map +0 -1
  56. package/dest/private/index.d.ts +0 -13
  57. package/dest/private/index.d.ts.map +0 -1
  58. package/dest/private/pick_notes.d.ts +0 -85
  59. package/dest/private/pick_notes.d.ts.map +0 -1
  60. package/dest/private/private_execution.d.ts +0 -24
  61. package/dest/private/private_execution.d.ts.map +0 -1
  62. package/dest/private/providers/acvm_native.d.ts +0 -40
  63. package/dest/private/providers/acvm_native.d.ts.map +0 -1
  64. package/dest/private/providers/acvm_wasm.d.ts +0 -15
  65. package/dest/private/providers/acvm_wasm.d.ts.map +0 -1
  66. package/dest/private/providers/acvm_wasm_with_blobs.d.ts +0 -19
  67. package/dest/private/providers/acvm_wasm_with_blobs.d.ts.map +0 -1
  68. package/dest/private/providers/factory.d.ts +0 -12
  69. package/dest/private/providers/factory.d.ts.map +0 -1
  70. package/dest/private/providers/simulation_provider.d.ts +0 -19
  71. package/dest/private/providers/simulation_provider.d.ts.map +0 -1
  72. package/dest/private/simulator.d.ts +0 -36
  73. package/dest/private/simulator.d.ts.map +0 -1
  74. package/dest/private/unconstrained_execution.d.ts +0 -10
  75. package/dest/private/unconstrained_execution.d.ts.map +0 -1
  76. package/dest/private/view_data_oracle.d.ts +0 -164
  77. package/dest/private/view_data_oracle.d.ts.map +0 -1
  78. package/dest/public/avm/avm_context.d.ts +0 -41
  79. package/dest/public/avm/avm_context.d.ts.map +0 -1
  80. package/dest/public/avm/avm_contract_call_result.d.ts +0 -30
  81. package/dest/public/avm/avm_contract_call_result.d.ts.map +0 -1
  82. package/dest/public/avm/avm_execution_environment.d.ts +0 -21
  83. package/dest/public/avm/avm_execution_environment.d.ts.map +0 -1
  84. package/dest/public/avm/avm_gas.d.ts +0 -60
  85. package/dest/public/avm/avm_gas.d.ts.map +0 -1
  86. package/dest/public/avm/avm_machine_state.d.ts +0 -93
  87. package/dest/public/avm/avm_machine_state.d.ts.map +0 -1
  88. package/dest/public/avm/avm_memory_types.d.ts +0 -264
  89. package/dest/public/avm/avm_memory_types.d.ts.map +0 -1
  90. package/dest/public/avm/avm_simulator.d.ts +0 -40
  91. package/dest/public/avm/avm_simulator.d.ts.map +0 -1
  92. package/dest/public/avm/bytecode_utils.d.ts +0 -5
  93. package/dest/public/avm/bytecode_utils.d.ts.map +0 -1
  94. package/dest/public/avm/errors.d.ts +0 -122
  95. package/dest/public/avm/errors.d.ts.map +0 -1
  96. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +0 -21
  97. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +0 -1
  98. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +0 -36
  99. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +0 -1
  100. package/dest/public/avm/fixtures/index.d.ts +0 -84
  101. package/dest/public/avm/fixtures/index.d.ts.map +0 -1
  102. package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +0 -35
  103. package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +0 -1
  104. package/dest/public/avm/index.d.ts +0 -4
  105. package/dest/public/avm/index.d.ts.map +0 -1
  106. package/dest/public/avm/journal/index.d.ts +0 -2
  107. package/dest/public/avm/journal/index.d.ts.map +0 -1
  108. package/dest/public/avm/journal/journal.d.ts +0 -209
  109. package/dest/public/avm/journal/journal.d.ts.map +0 -1
  110. package/dest/public/avm/journal/nullifiers.d.ts +0 -64
  111. package/dest/public/avm/journal/nullifiers.d.ts.map +0 -1
  112. package/dest/public/avm/journal/public_storage.d.ts +0 -66
  113. package/dest/public/avm/journal/public_storage.d.ts.map +0 -1
  114. package/dest/public/avm/opcodes/accrued_substate.d.ts +0 -75
  115. package/dest/public/avm/opcodes/accrued_substate.d.ts.map +0 -1
  116. package/dest/public/avm/opcodes/addressing_mode.d.ts +0 -27
  117. package/dest/public/avm/opcodes/addressing_mode.d.ts.map +0 -1
  118. package/dest/public/avm/opcodes/arithmetic.d.ts +0 -37
  119. package/dest/public/avm/opcodes/arithmetic.d.ts.map +0 -1
  120. package/dest/public/avm/opcodes/bitwise.d.ts +0 -50
  121. package/dest/public/avm/opcodes/bitwise.d.ts.map +0 -1
  122. package/dest/public/avm/opcodes/comparators.d.ts +0 -25
  123. package/dest/public/avm/opcodes/comparators.d.ts.map +0 -1
  124. package/dest/public/avm/opcodes/contract.d.ts +0 -21
  125. package/dest/public/avm/opcodes/contract.d.ts.map +0 -1
  126. package/dest/public/avm/opcodes/control_flow.d.ts +0 -41
  127. package/dest/public/avm/opcodes/control_flow.d.ts.map +0 -1
  128. package/dest/public/avm/opcodes/conversion.d.ts +0 -17
  129. package/dest/public/avm/opcodes/conversion.d.ts.map +0 -1
  130. package/dest/public/avm/opcodes/ec_add.d.ts +0 -19
  131. package/dest/public/avm/opcodes/ec_add.d.ts.map +0 -1
  132. package/dest/public/avm/opcodes/environment_getters.d.ts +0 -28
  133. package/dest/public/avm/opcodes/environment_getters.d.ts.map +0 -1
  134. package/dest/public/avm/opcodes/external_calls.d.ts +0 -50
  135. package/dest/public/avm/opcodes/external_calls.d.ts.map +0 -1
  136. package/dest/public/avm/opcodes/hashing.d.ts +0 -36
  137. package/dest/public/avm/opcodes/hashing.d.ts.map +0 -1
  138. package/dest/public/avm/opcodes/index.d.ts +0 -16
  139. package/dest/public/avm/opcodes/index.d.ts.map +0 -1
  140. package/dest/public/avm/opcodes/instruction.d.ts +0 -70
  141. package/dest/public/avm/opcodes/instruction.d.ts.map +0 -1
  142. package/dest/public/avm/opcodes/instruction_impl.d.ts +0 -19
  143. package/dest/public/avm/opcodes/instruction_impl.d.ts.map +0 -1
  144. package/dest/public/avm/opcodes/memory.d.ts +0 -74
  145. package/dest/public/avm/opcodes/memory.d.ts.map +0 -1
  146. package/dest/public/avm/opcodes/misc.d.ts +0 -17
  147. package/dest/public/avm/opcodes/misc.d.ts.map +0 -1
  148. package/dest/public/avm/opcodes/storage.d.ts +0 -24
  149. package/dest/public/avm/opcodes/storage.d.ts.map +0 -1
  150. package/dest/public/avm/serialization/buffer_cursor.d.ts +0 -28
  151. package/dest/public/avm/serialization/buffer_cursor.d.ts.map +0 -1
  152. package/dest/public/avm/serialization/bytecode_serialization.d.ts +0 -21
  153. package/dest/public/avm/serialization/bytecode_serialization.d.ts.map +0 -1
  154. package/dest/public/avm/serialization/instruction_serialization.d.ts +0 -104
  155. package/dest/public/avm/serialization/instruction_serialization.d.ts.map +0 -1
  156. package/dest/public/avm/test_utils.d.ts +0 -18
  157. package/dest/public/avm/test_utils.d.ts.map +0 -1
  158. package/dest/public/bytecode_errors.d.ts +0 -4
  159. package/dest/public/bytecode_errors.d.ts.map +0 -1
  160. package/dest/public/execution.d.ts +0 -108
  161. package/dest/public/execution.d.ts.map +0 -1
  162. package/dest/public/executor_metrics.d.ts +0 -13
  163. package/dest/public/executor_metrics.d.ts.map +0 -1
  164. package/dest/public/fixtures/index.d.ts +0 -3
  165. package/dest/public/fixtures/index.d.ts.map +0 -1
  166. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +0 -32
  167. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +0 -1
  168. package/dest/public/fixtures/utils.d.ts +0 -13
  169. package/dest/public/fixtures/utils.d.ts.map +0 -1
  170. package/dest/public/index.d.ts +0 -10
  171. package/dest/public/index.d.ts.map +0 -1
  172. package/dest/public/public_db_sources.d.ts +0 -129
  173. package/dest/public/public_db_sources.d.ts.map +0 -1
  174. package/dest/public/public_processor/public_processor.d.ts +0 -74
  175. package/dest/public/public_processor/public_processor.d.ts.map +0 -1
  176. package/dest/public/public_processor/public_processor_metrics.d.ts +0 -27
  177. package/dest/public/public_processor/public_processor_metrics.d.ts.map +0 -1
  178. package/dest/public/public_tx_simulator/public_tx_context.d.ts +0 -137
  179. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +0 -1
  180. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +0 -102
  181. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +0 -1
  182. package/dest/public/side_effect_errors.d.ts +0 -4
  183. package/dest/public/side_effect_errors.d.ts.map +0 -1
  184. package/dest/public/side_effect_trace.d.ts +0 -132
  185. package/dest/public/side_effect_trace.d.ts.map +0 -1
  186. package/dest/public/side_effect_trace_interface.d.ts +0 -34
  187. package/dest/public/side_effect_trace_interface.d.ts.map +0 -1
  188. package/dest/public/tx_contract_cache.d.ts +0 -41
  189. package/dest/public/tx_contract_cache.d.ts.map +0 -1
  190. package/dest/public/unique_class_ids.d.ts +0 -37
  191. package/dest/public/unique_class_ids.d.ts.map +0 -1
  192. package/dest/public/utils.d.ts +0 -5
  193. package/dest/public/utils.d.ts.map +0 -1
  194. package/dest/server.d.ts +0 -6
  195. package/dest/server.d.ts.map +0 -1
  196. package/dest/test/utils.d.ts +0 -13
  197. package/dest/test/utils.d.ts.map +0 -1
  198. /package/dest/private/{db_oracle.js → execution_data_provider.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  export { AcirSimulator } from './simulator.js';
2
- export { ViewDataOracle } from './view_data_oracle.js';
3
- export { ContractClassNotFoundError, ContractNotFoundError } from './db_oracle.js';
2
+ export { UnconstrainedExecutionOracle } from './unconstrained_execution_oracle.js';
3
+ export { ContractClassNotFoundError, ContractNotFoundError } from './execution_data_provider.js';
4
4
  export * from './pick_notes.js';
5
5
  export { ExecutionNoteCache } from './execution_note_cache.js';
6
6
  export { extractPrivateCircuitPublicInputs, readCurrentClassId } from './private_execution.js';
@@ -12,14 +12,14 @@ import { fromACVMField, witnessMapToFields } from './acvm/deserialize.js';
12
12
  import { Oracle, extractCallStack } from './acvm/index.js';
13
13
  /**
14
14
  * Execute a private function and return the execution result.
15
- */ export async function executePrivateFunction(simulator, context, artifact, contractAddress, functionSelector, log = createLogger('simulator:private_execution')) {
16
- const functionName = await context.getDebugFunctionName();
15
+ */ export async function executePrivateFunction(simulator, privateExecutionOracle, artifact, contractAddress, functionSelector, log = createLogger('simulator:private_execution')) {
16
+ const functionName = await privateExecutionOracle.getDebugFunctionName();
17
17
  log.verbose(`Executing private function ${functionName}`, {
18
18
  contract: contractAddress
19
19
  });
20
20
  const acir = artifact.bytecode;
21
- const initialWitness = context.getInitialWitness(artifact);
22
- const acvmCallback = new Oracle(context);
21
+ const initialWitness = privateExecutionOracle.getInitialWitness(artifact);
22
+ const acvmCallback = new Oracle(privateExecutionOracle);
23
23
  const timer = new Timer();
24
24
  const acirExecutionResult = await simulator.executeUserCircuit(acir, initialWitness, acvmCallback).catch((err)=>{
25
25
  err.message = resolveAssertionMessageFromError(err, artifact);
@@ -43,14 +43,14 @@ import { Oracle, extractCallStack } from './acvm/index.js';
43
43
  outputSize: publicInputs.toBuffer().length,
44
44
  appCircuitName: functionName
45
45
  });
46
- const contractClassLogs = context.getContractClassLogs();
47
- const rawReturnValues = await context.loadFromExecutionCache(publicInputs.returnsHash);
48
- const noteHashLeafIndexMap = context.getNoteHashLeafIndexMap();
49
- const newNotes = context.getNewNotes();
50
- const noteHashNullifierCounterMap = context.getNoteHashNullifierCounterMap();
51
- const nestedExecutions = context.getNestedExecutions();
52
- const enqueuedPublicFunctionCalls = context.getEnqueuedPublicFunctionCalls();
53
- const publicTeardownFunctionCall = context.getPublicTeardownFunctionCall();
46
+ const contractClassLogs = privateExecutionOracle.getContractClassLogs();
47
+ const rawReturnValues = await privateExecutionOracle.loadFromExecutionCache(publicInputs.returnsHash);
48
+ const noteHashLeafIndexMap = privateExecutionOracle.getNoteHashLeafIndexMap();
49
+ const newNotes = privateExecutionOracle.getNewNotes();
50
+ const noteHashNullifierCounterMap = privateExecutionOracle.getNoteHashNullifierCounterMap();
51
+ const nestedExecutions = privateExecutionOracle.getNestedExecutions();
52
+ const enqueuedPublicFunctionCalls = privateExecutionOracle.getEnqueuedPublicFunctionCalls();
53
+ const publicTeardownFunctionCall = privateExecutionOracle.getPublicTeardownFunctionCall();
54
54
  log.debug(`Returning from call to ${contractAddress.toString()}:${functionSelector}`);
55
55
  return new PrivateCallExecutionResult(acir, Buffer.from(artifact.verificationKey, 'base64'), partialWitness, publicInputs, noteHashLeafIndexMap, newNotes, noteHashNullifierCounterMap, rawReturnValues, nestedExecutions, enqueuedPublicFunctionCalls, publicTeardownFunctionCall, contractClassLogs);
56
56
  }
@@ -73,17 +73,19 @@ import { Oracle, extractCallStack } from './acvm/index.js';
73
73
  }
74
74
  return PrivateCircuitPublicInputs.fromFields(returnData);
75
75
  }
76
- export async function readCurrentClassId(contractAddress, instance, node, blockNumber) {
76
+ export async function readCurrentClassId(contractAddress, instance, executionDataProvider, blockNumber) {
77
77
  const { sharedMutableSlot } = await SharedMutableValuesWithHash.getContractUpdateSlots(contractAddress);
78
- const sharedMutableValues = await SharedMutableValues.readFromTree(sharedMutableSlot, (slot)=>node.getPublicStorageAt(ProtocolContractAddress.ContractInstanceDeployer, slot, blockNumber));
78
+ const sharedMutableValues = await SharedMutableValues.readFromTree(sharedMutableSlot, (slot)=>executionDataProvider.getPublicStorageAt(blockNumber, ProtocolContractAddress.ContractInstanceDeployer, slot));
79
79
  let currentClassId = sharedMutableValues.svc.getCurrentAt(blockNumber)[0];
80
80
  if (currentClassId.isZero()) {
81
81
  currentClassId = instance.originalContractClassId;
82
82
  }
83
83
  return currentClassId;
84
84
  }
85
- export async function verifyCurrentClassId(contractAddress, instance, node, blockNumber) {
86
- const currentClassId = await readCurrentClassId(contractAddress, instance, node, blockNumber);
85
+ export async function verifyCurrentClassId(contractAddress, executionDataProvider, blockNumber) {
86
+ const instance = await executionDataProvider.getContractInstance(contractAddress);
87
+ blockNumber = blockNumber ?? await executionDataProvider.getBlockNumber();
88
+ const currentClassId = await readCurrentClassId(contractAddress, instance, executionDataProvider, blockNumber);
87
89
  if (!instance.currentContractClassId.equals(currentClassId)) {
88
90
  throw new Error(`Contract ${contractAddress} is outdated, current class id is ${currentClassId}, local class id is ${instance.currentContractClassId}`);
89
91
  }
@@ -1,4 +1,4 @@
1
- import { PRIVATE_CONTEXT_INPUTS_LENGTH, PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
1
+ import { MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS, PRIVATE_CONTEXT_INPUTS_LENGTH, PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import { FunctionSelector, countArgumentsSize } from '@aztec/stdlib/abi';
@@ -10,18 +10,18 @@ import { CallContext, CountedContractClassLog, CountedPublicExecutionRequest, No
10
10
  import { toACVMWitness } from './acvm/index.js';
11
11
  import { pickNotes } from './pick_notes.js';
12
12
  import { executePrivateFunction, verifyCurrentClassId } from './private_execution.js';
13
- import { ViewDataOracle } from './view_data_oracle.js';
13
+ import { UnconstrainedExecutionOracle } from './unconstrained_execution_oracle.js';
14
14
  /**
15
- * The execution context for a client tx simulation.
16
- */ export class ClientExecutionContext extends ViewDataOracle {
15
+ * The execution oracle for the private part of a transaction.
16
+ */ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
17
17
  argsHash;
18
18
  txContext;
19
19
  callContext;
20
20
  historicalHeader;
21
21
  executionCache;
22
22
  noteCache;
23
- node;
24
23
  provider;
24
+ totalPublicArgsCount;
25
25
  sideEffectCounter;
26
26
  /**
27
27
  * New notes created during this execution.
@@ -44,8 +44,8 @@ import { ViewDataOracle } from './view_data_oracle.js';
44
44
  nestedExecutions;
45
45
  enqueuedPublicFunctionCalls;
46
46
  publicTeardownFunctionCall;
47
- constructor(argsHash, txContext, callContext, /** Header of a block whose state is used during private execution (not the block the transaction is included in). */ historicalHeader, /** List of transient auth witnesses to be used during this simulation */ authWitnesses, capsules, executionCache, noteCache, db, node, provider, sideEffectCounter = 0, log = createLogger('simulator:client_execution_context'), scopes){
48
- super(callContext.contractAddress, authWitnesses, capsules, db, node, log, scopes), this.argsHash = argsHash, this.txContext = txContext, this.callContext = callContext, this.historicalHeader = historicalHeader, this.executionCache = executionCache, this.noteCache = noteCache, this.node = node, this.provider = provider, this.sideEffectCounter = sideEffectCounter, this.newNotes = [], this.noteHashLeafIndexMap = new Map(), this.noteHashNullifierCounterMap = new Map(), this.contractClassLogs = [], this.nestedExecutions = [], this.enqueuedPublicFunctionCalls = [], this.publicTeardownFunctionCall = PublicExecutionRequest.empty();
47
+ constructor(argsHash, txContext, callContext, /** Header of a block whose state is used during private execution (not the block the transaction is included in). */ historicalHeader, /** List of transient auth witnesses to be used during this simulation */ authWitnesses, capsules, executionCache, noteCache, executionDataProvider, provider, totalPublicArgsCount, sideEffectCounter = 0, log = createLogger('simulator:client_execution_context'), scopes){
48
+ super(callContext.contractAddress, authWitnesses, capsules, executionDataProvider, log, scopes), this.argsHash = argsHash, this.txContext = txContext, this.callContext = callContext, this.historicalHeader = historicalHeader, this.executionCache = executionCache, this.noteCache = noteCache, this.provider = provider, this.totalPublicArgsCount = totalPublicArgsCount, this.sideEffectCounter = sideEffectCounter, this.newNotes = [], this.noteHashLeafIndexMap = new Map(), this.noteHashNullifierCounterMap = new Map(), this.contractClassLogs = [], this.nestedExecutions = [], this.enqueuedPublicFunctionCalls = [], this.publicTeardownFunctionCall = PublicExecutionRequest.empty();
49
49
  }
50
50
  // We still need this function until we can get user-defined ordering of structs for fn arguments
51
51
  // TODO When that is sorted out on noir side, we can use instead the utilities in serialize.ts
@@ -141,7 +141,7 @@ import { ViewDataOracle } from './view_data_oracle.js';
141
141
  // Nullified pending notes are already removed from the list.
142
142
  const pendingNotes = this.noteCache.getNotes(this.callContext.contractAddress, storageSlot);
143
143
  const pendingNullifiers = this.noteCache.getNullifiers(this.callContext.contractAddress);
144
- const dbNotes = await this.db.getNotes(this.callContext.contractAddress, storageSlot, status, this.scopes);
144
+ const dbNotes = await this.executionDataProvider.getNotes(this.callContext.contractAddress, storageSlot, status, this.scopes);
145
145
  const dbNotesFiltered = dbNotes.filter((n)=>!pendingNullifiers.has(n.siloedNullifier.value));
146
146
  const notes = pickNotes([
147
147
  ...dbNotesFiltered,
@@ -257,11 +257,11 @@ import { ViewDataOracle } from './view_data_oracle.js';
257
257
  */ async callPrivateFunction(targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall) {
258
258
  this.log.debug(`Calling private function ${targetContractAddress}:${functionSelector} from ${this.callContext.contractAddress}`);
259
259
  isStaticCall = isStaticCall || this.callContext.isStaticCall;
260
- await verifyCurrentClassId(targetContractAddress, await this.db.getContractInstance(targetContractAddress), this.node, this.historicalHeader.globalVariables.blockNumber.toNumber());
261
- const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector);
260
+ await verifyCurrentClassId(targetContractAddress, this.executionDataProvider, this.historicalHeader.globalVariables.blockNumber.toNumber());
261
+ const targetArtifact = await this.executionDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
262
262
  const derivedTxContext = this.txContext.clone();
263
263
  const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall);
264
- const context = new ClientExecutionContext(argsHash, derivedTxContext, derivedCallContext, this.historicalHeader, this.authWitnesses, this.capsules, this.executionCache, this.noteCache, this.db, this.node, this.provider, sideEffectCounter, this.log, this.scopes);
264
+ const context = new PrivateExecutionOracle(argsHash, derivedTxContext, derivedCallContext, this.historicalHeader, this.authWitnesses, this.capsules, this.executionCache, this.noteCache, this.executionDataProvider, this.provider, this.totalPublicArgsCount, sideEffectCounter, this.log, this.scopes);
265
265
  const childExecutionResult = await executePrivateFunction(this.provider, context, targetArtifact, targetContractAddress, functionSelector);
266
266
  if (isStaticCall) {
267
267
  this.#checkValidStaticCall(childExecutionResult);
@@ -282,7 +282,7 @@ import { ViewDataOracle } from './view_data_oracle.js';
282
282
  * @param isStaticCall - Whether the call is a static call.
283
283
  * @returns The public call stack item with the request information.
284
284
  */ async createPublicExecutionRequest(callType, targetContractAddress, functionSelector, argsHash, sideEffectCounter, isStaticCall) {
285
- const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector);
285
+ const targetArtifact = await this.executionDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
286
286
  const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall);
287
287
  const args = this.executionCache.getPreimage(argsHash);
288
288
  this.log.verbose(`Created ${callType} public execution request to ${targetArtifact.name}@${targetContractAddress}`, {
@@ -319,11 +319,16 @@ import { ViewDataOracle } from './view_data_oracle.js';
319
319
  // new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
320
320
  // We don't validate or compute it in the circuit because a) it's harder to do with slices, and
321
321
  // b) this is only temporary.
322
- const newArgsHash = await this.executionCache.store([
322
+ const newArgs = [
323
323
  functionSelector.toField(),
324
324
  ...this.executionCache.getPreimage(argsHash)
325
- ]);
325
+ ];
326
+ const newArgsHash = await this.executionCache.store(newArgs);
326
327
  await this.createPublicExecutionRequest('enqueued', targetContractAddress, FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), newArgsHash, sideEffectCounter, isStaticCall);
328
+ this.totalPublicArgsCount += newArgs.length;
329
+ if (this.totalPublicArgsCount > MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS) {
330
+ throw new Error(`Too many total args to all enqueued public calls! (> ${MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS})`);
331
+ }
327
332
  return newArgsHash;
328
333
  }
329
334
  /**
@@ -363,16 +368,16 @@ import { ViewDataOracle } from './view_data_oracle.js';
363
368
  return new CallContext(this.contractAddress, targetContractAddress, await FunctionSelector.fromNameAndParameters(targetArtifact.name, targetArtifact.parameters), isStaticCall);
364
369
  }
365
370
  getDebugFunctionName() {
366
- return this.db.getDebugFunctionName(this.contractAddress, this.callContext.functionSelector);
371
+ return this.executionDataProvider.getDebugFunctionName(this.contractAddress, this.callContext.functionSelector);
367
372
  }
368
373
  async incrementAppTaggingSecretIndexAsSender(sender, recipient) {
369
- await this.db.incrementAppTaggingSecretIndexAsSender(this.contractAddress, sender, recipient);
374
+ await this.executionDataProvider.incrementAppTaggingSecretIndexAsSender(this.contractAddress, sender, recipient);
370
375
  }
371
376
  async syncNotes() {
372
- const taggedLogsByRecipient = await this.db.syncTaggedLogs(this.contractAddress, this.historicalHeader.globalVariables.blockNumber.toNumber(), this.scopes);
377
+ const taggedLogsByRecipient = await this.executionDataProvider.syncTaggedLogs(this.contractAddress, this.historicalHeader.globalVariables.blockNumber.toNumber(), this.scopes);
373
378
  for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries()){
374
- await this.db.processTaggedLogs(taggedLogs, AztecAddress.fromString(recipient));
379
+ await this.executionDataProvider.processTaggedLogs(taggedLogs, AztecAddress.fromString(recipient));
375
380
  }
376
- await this.db.removeNullifiedNotes(this.contractAddress);
381
+ await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
377
382
  }
378
383
  }
@@ -4,22 +4,20 @@ import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
4
4
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
5
5
  import { CallContext, PrivateExecutionResult } from '@aztec/stdlib/tx';
6
6
  import { createSimulationError } from '../common/errors.js';
7
- import { ClientExecutionContext } from './client_execution_context.js';
8
7
  import { ExecutionNoteCache } from './execution_note_cache.js';
9
8
  import { HashedValuesCache } from './hashed_values_cache.js';
10
9
  import { executePrivateFunction, verifyCurrentClassId } from './private_execution.js';
10
+ import { PrivateExecutionOracle } from './private_execution_oracle.js';
11
11
  import { executeUnconstrainedFunction } from './unconstrained_execution.js';
12
- import { ViewDataOracle } from './view_data_oracle.js';
12
+ import { UnconstrainedExecutionOracle } from './unconstrained_execution_oracle.js';
13
13
  /**
14
14
  * The ACIR simulator.
15
15
  */ export class AcirSimulator {
16
- db;
17
- node;
16
+ executionDataProvider;
18
17
  simulationProvider;
19
18
  log;
20
- constructor(db, node, simulationProvider){
21
- this.db = db;
22
- this.node = node;
19
+ constructor(executionDataProvider, simulationProvider){
20
+ this.executionDataProvider = executionDataProvider;
23
21
  this.simulationProvider = simulationProvider;
24
22
  this.log = createLogger('simulator');
25
23
  }
@@ -32,9 +30,9 @@ import { ViewDataOracle } from './view_data_oracle.js';
32
30
  * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
33
31
  * @returns The result of the execution.
34
32
  */ async run(request, contractAddress, selector, msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE), scopes) {
35
- const header = await this.db.getBlockHeader();
36
- await verifyCurrentClassId(contractAddress, await this.db.getContractInstance(contractAddress), this.node, header.globalVariables.blockNumber.toNumber());
37
- const entryPointArtifact = await this.db.getFunctionArtifact(contractAddress, selector);
33
+ const header = await this.executionDataProvider.getBlockHeader();
34
+ await verifyCurrentClassId(contractAddress, this.executionDataProvider);
35
+ const entryPointArtifact = await this.executionDataProvider.getFunctionArtifact(contractAddress, selector);
38
36
  if (entryPointArtifact.functionType !== FunctionType.PRIVATE) {
39
37
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as private`);
40
38
  }
@@ -46,7 +44,7 @@ import { ViewDataOracle } from './view_data_oracle.js';
46
44
  const callContext = new CallContext(msgSender, contractAddress, await FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters), entryPointArtifact.isStatic);
47
45
  const txRequestHash = await request.toTxRequest().hash();
48
46
  const noteCache = new ExecutionNoteCache(txRequestHash);
49
- const context = new ClientExecutionContext(request.firstCallArgsHash, request.txContext, callContext, header, request.authWitnesses, request.capsules, HashedValuesCache.create(request.argsOfCalls), noteCache, this.db, this.node, this.simulationProvider, startSideEffectCounter, undefined, scopes);
47
+ const context = new PrivateExecutionOracle(request.firstCallArgsHash, request.txContext, callContext, header, request.authWitnesses, request.capsules, HashedValuesCache.create(request.argsOfCalls), noteCache, this.executionDataProvider, this.simulationProvider, /*totalPublicArgsCount=*/ 0, startSideEffectCounter, undefined, scopes);
50
48
  try {
51
49
  const executionResult = await executePrivateFunction(this.simulationProvider, context, entryPointArtifact, contractAddress, request.functionSelector);
52
50
  const { usedTxRequestHashForNonces } = noteCache.finish();
@@ -63,12 +61,12 @@ import { ViewDataOracle } from './view_data_oracle.js';
63
61
  * @param contractAddress - The address of the contract.
64
62
  * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
65
63
  */ async runUnconstrained(request, contractAddress, selector, scopes) {
66
- await verifyCurrentClassId(contractAddress, await this.db.getContractInstance(contractAddress), this.node, await this.node.getBlockNumber());
67
- const entryPointArtifact = await this.db.getFunctionArtifact(contractAddress, selector);
64
+ await verifyCurrentClassId(contractAddress, this.executionDataProvider);
65
+ const entryPointArtifact = await this.executionDataProvider.getFunctionArtifact(contractAddress, selector);
68
66
  if (entryPointArtifact.functionType !== FunctionType.UNCONSTRAINED) {
69
67
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as unconstrained`);
70
68
  }
71
- const context = new ViewDataOracle(contractAddress, [], [], this.db, this.node, undefined, scopes);
69
+ const context = new UnconstrainedExecutionOracle(contractAddress, [], [], this.executionDataProvider, undefined, scopes);
72
70
  try {
73
71
  return await executeUnconstrainedFunction(this.simulationProvider, context, entryPointArtifact, contractAddress, request.selector, request.args);
74
72
  } catch (err) {
@@ -6,30 +6,28 @@ import { siloNullifier } from '@aztec/stdlib/hash';
6
6
  import { TypedOracle } from './acvm/index.js';
7
7
  import { pickNotes } from './pick_notes.js';
8
8
  /**
9
- * The execution context for a client view tx simulation.
10
- * It only reads data from data sources. Nothing will be updated or created during this simulation.
11
- */ export class ViewDataOracle extends TypedOracle {
9
+ * The oracle for an unconstrained function execution.
10
+ */ export class UnconstrainedExecutionOracle extends TypedOracle {
12
11
  contractAddress;
13
12
  authWitnesses;
14
13
  capsules;
15
- db;
16
- aztecNode;
14
+ executionDataProvider;
17
15
  log;
18
16
  scopes;
19
- constructor(contractAddress, /** List of transient auth witnesses to be used during this simulation */ authWitnesses, capsules, db, aztecNode, log = createLogger('simulator:client_view_context'), scopes){
20
- super(), this.contractAddress = contractAddress, this.authWitnesses = authWitnesses, this.capsules = capsules, this.db = db, this.aztecNode = aztecNode, this.log = log, this.scopes = scopes;
17
+ constructor(contractAddress, /** List of transient auth witnesses to be used during this simulation */ authWitnesses, capsules, executionDataProvider, log = createLogger('simulator:client_view_context'), scopes){
18
+ super(), this.contractAddress = contractAddress, this.authWitnesses = authWitnesses, this.capsules = capsules, this.executionDataProvider = executionDataProvider, this.log = log, this.scopes = scopes;
21
19
  }
22
20
  getBlockNumber() {
23
- return this.aztecNode.getBlockNumber();
21
+ return this.executionDataProvider.getBlockNumber();
24
22
  }
25
23
  getContractAddress() {
26
24
  return Promise.resolve(this.contractAddress);
27
25
  }
28
26
  getChainId() {
29
- return Promise.resolve(this.aztecNode.getChainId().then((id)=>new Fr(id)));
27
+ return Promise.resolve(this.executionDataProvider.getChainId().then((id)=>new Fr(id)));
30
28
  }
31
29
  getVersion() {
32
- return Promise.resolve(this.aztecNode.getVersion().then((v)=>new Fr(v)));
30
+ return Promise.resolve(this.executionDataProvider.getVersion().then((v)=>new Fr(v)));
33
31
  }
34
32
  /**
35
33
  * Retrieve keys associated with a specific master public key and app address.
@@ -37,7 +35,7 @@ import { pickNotes } from './pick_notes.js';
37
35
  * @returns A Promise that resolves to nullifier keys.
38
36
  * @throws If the keys are not registered in the key store.
39
37
  */ getKeyValidationRequest(pkMHash) {
40
- return this.db.getKeyValidationRequest(pkMHash, this.contractAddress);
38
+ return this.executionDataProvider.getKeyValidationRequest(pkMHash, this.contractAddress);
41
39
  }
42
40
  /**
43
41
  * Fetches the index and sibling path of a leaf at a given block from a given tree.
@@ -46,7 +44,7 @@ import { pickNotes } from './pick_notes.js';
46
44
  * @param leafValue - The leaf value
47
45
  * @returns The index and sibling path concatenated [index, sibling_path]
48
46
  */ getMembershipWitness(blockNumber, treeId, leafValue) {
49
- return this.db.getMembershipWitness(blockNumber, treeId, leafValue);
47
+ return this.executionDataProvider.getMembershipWitness(blockNumber, treeId, leafValue);
50
48
  }
51
49
  /**
52
50
  * Returns a nullifier membership witness for a given nullifier at a given block.
@@ -54,7 +52,7 @@ import { pickNotes } from './pick_notes.js';
54
52
  * @param nullifier - Nullifier we try to find witness for.
55
53
  * @returns The nullifier membership witness (if found).
56
54
  */ async getNullifierMembershipWitness(blockNumber, nullifier) {
57
- return await this.db.getNullifierMembershipWitness(blockNumber, nullifier);
55
+ return await this.executionDataProvider.getNullifierMembershipWitness(blockNumber, nullifier);
58
56
  }
59
57
  /**
60
58
  * Returns a low nullifier membership witness for a given nullifier at a given block.
@@ -65,7 +63,7 @@ import { pickNotes } from './pick_notes.js';
65
63
  * list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
66
64
  * we are trying to prove non-inclusion for.
67
65
  */ async getLowNullifierMembershipWitness(blockNumber, nullifier) {
68
- return await this.db.getLowNullifierMembershipWitness(blockNumber, nullifier);
66
+ return await this.executionDataProvider.getLowNullifierMembershipWitness(blockNumber, nullifier);
69
67
  }
70
68
  /**
71
69
  * Returns a public data tree witness for a given leaf slot at a given block.
@@ -73,14 +71,14 @@ import { pickNotes } from './pick_notes.js';
73
71
  * @param leafSlot - The slot of the public data tree to get the witness for.
74
72
  * @returns - The witness
75
73
  */ async getPublicDataTreeWitness(blockNumber, leafSlot) {
76
- return await this.db.getPublicDataTreeWitness(blockNumber, leafSlot);
74
+ return await this.executionDataProvider.getPublicDataTreeWitness(blockNumber, leafSlot);
77
75
  }
78
76
  /**
79
77
  * Fetches a block header of a given block.
80
78
  * @param blockNumber - The number of a block of which to get the block header.
81
79
  * @returns Block extracted from a block with block number `blockNumber`.
82
80
  */ async getBlockHeader(blockNumber) {
83
- const block = await this.db.getBlock(blockNumber);
81
+ const block = await this.executionDataProvider.getBlock(blockNumber);
84
82
  if (!block) {
85
83
  return undefined;
86
84
  }
@@ -92,14 +90,14 @@ import { pickNotes } from './pick_notes.js';
92
90
  * @returns A complete address associated with the input address.
93
91
  * @throws An error if the account is not registered in the database.
94
92
  */ getCompleteAddress(account) {
95
- return this.db.getCompleteAddress(account);
93
+ return this.executionDataProvider.getCompleteAddress(account);
96
94
  }
97
95
  /**
98
96
  * Returns a contract instance associated with an address or throws if not found.
99
97
  * @param address - Address.
100
98
  * @returns A contract instance.
101
99
  */ getContractInstance(address) {
102
- return this.db.getContractInstance(address);
100
+ return this.executionDataProvider.getContractInstance(address);
103
101
  }
104
102
  /**
105
103
  * Returns an auth witness for the given message hash. Checks on the list of transient witnesses
@@ -107,7 +105,7 @@ import { pickNotes } from './pick_notes.js';
107
105
  * @param messageHash - Hash of the message to authenticate.
108
106
  * @returns Authentication witness for the requested message hash.
109
107
  */ getAuthWitness(messageHash) {
110
- return Promise.resolve(this.authWitnesses.find((w)=>w.requestHash.equals(messageHash))?.witness ?? this.db.getAuthWitness(messageHash));
108
+ return Promise.resolve(this.authWitnesses.find((w)=>w.requestHash.equals(messageHash))?.witness ?? this.executionDataProvider.getAuthWitness(messageHash));
111
109
  }
112
110
  /**
113
111
  * Gets some notes for a contract address and storage slot.
@@ -130,7 +128,7 @@ import { pickNotes } from './pick_notes.js';
130
128
  * @param status - The status of notes to fetch.
131
129
  * @returns Array of note data.
132
130
  */ async getNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status) {
133
- const dbNotes = await this.db.getNotes(this.contractAddress, storageSlot, status, this.scopes);
131
+ const dbNotes = await this.executionDataProvider.getNotes(this.contractAddress, storageSlot, status, this.scopes);
134
132
  return pickNotes(dbNotes, {
135
133
  selects: selectByIndexes.slice(0, numSelects).map((index, i)=>({
136
134
  selector: {
@@ -159,18 +157,18 @@ import { pickNotes } from './pick_notes.js';
159
157
  * @returns A boolean indicating whether the nullifier exists in the tree or not.
160
158
  */ async checkNullifierExists(innerNullifier) {
161
159
  const nullifier = await siloNullifier(this.contractAddress, innerNullifier);
162
- const index = await this.db.getNullifierIndex(nullifier);
160
+ const index = await this.executionDataProvider.getNullifierIndex(nullifier);
163
161
  return index !== undefined;
164
162
  }
165
163
  /**
166
- * Fetches a message from the db, given its key.
164
+ * Fetches a message from the executionDataProvider, given its key.
167
165
  * @param contractAddress - Address of a contract by which the message was emitted.
168
166
  * @param messageHash - Hash of the message.
169
167
  * @param secret - Secret used to compute a nullifier.
170
168
  * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages
171
169
  * @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
172
170
  */ async getL1ToL2MembershipWitness(contractAddress, messageHash, secret) {
173
- return await this.db.getL1ToL2MembershipWitness(contractAddress, messageHash, secret);
171
+ return await this.executionDataProvider.getL1ToL2MembershipWitness(contractAddress, messageHash, secret);
174
172
  }
175
173
  /**
176
174
  * Read the public storage data.
@@ -182,7 +180,7 @@ import { pickNotes } from './pick_notes.js';
182
180
  const values = [];
183
181
  for(let i = 0n; i < numberOfElements; i++){
184
182
  const storageSlot = new Fr(startStorageSlot.value + i);
185
- const value = await this.aztecNode.getPublicStorageAt(contractAddress, storageSlot, blockNumber);
183
+ const value = await this.executionDataProvider.getPublicStorageAt(blockNumber, contractAddress, storageSlot);
186
184
  this.log.debug(`Oracle storage read: slot=${storageSlot.toString()} address-${contractAddress.toString()} value=${value}`);
187
185
  values.push(value);
188
186
  }
@@ -205,52 +203,52 @@ import { pickNotes } from './pick_notes.js';
205
203
  * @param recipient - The address receiving the note
206
204
  * @returns A tagging secret that can be used to tag notes.
207
205
  */ async getIndexedTaggingSecretAsSender(sender, recipient) {
208
- return await this.db.getIndexedTaggingSecretAsSender(this.contractAddress, sender, recipient);
206
+ return await this.executionDataProvider.getIndexedTaggingSecretAsSender(this.contractAddress, sender, recipient);
209
207
  }
210
208
  async syncNotes() {
211
- const taggedLogsByRecipient = await this.db.syncTaggedLogs(this.contractAddress, await this.aztecNode.getBlockNumber(), this.scopes);
209
+ const taggedLogsByRecipient = await this.executionDataProvider.syncTaggedLogs(this.contractAddress, await this.executionDataProvider.getBlockNumber(), this.scopes);
212
210
  for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries()){
213
- await this.db.processTaggedLogs(taggedLogs, AztecAddress.fromString(recipient));
211
+ await this.executionDataProvider.processTaggedLogs(taggedLogs, AztecAddress.fromString(recipient));
214
212
  }
215
- await this.db.removeNullifiedNotes(this.contractAddress);
213
+ await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
216
214
  }
217
215
  async deliverNote(contractAddress, storageSlot, nonce, content, noteHash, nullifier, txHash, recipient) {
218
216
  // TODO(#10727): allow other contracts to deliver notes
219
217
  if (!this.contractAddress.equals(contractAddress)) {
220
218
  throw new Error(`Got a note delivery request from ${contractAddress}, expected ${this.contractAddress}`);
221
219
  }
222
- await this.db.deliverNote(contractAddress, storageSlot, nonce, content, noteHash, nullifier, txHash, recipient);
220
+ await this.executionDataProvider.deliverNote(contractAddress, storageSlot, nonce, content, noteHash, nullifier, txHash, recipient);
223
221
  }
224
222
  getLogByTag(tag) {
225
- return this.db.getLogByTag(tag);
223
+ return this.executionDataProvider.getLogByTag(tag);
226
224
  }
227
225
  storeCapsule(contractAddress, slot, capsule) {
228
226
  if (!contractAddress.equals(this.contractAddress)) {
229
227
  // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
230
228
  throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
231
229
  }
232
- return this.db.storeCapsule(this.contractAddress, slot, capsule);
230
+ return this.executionDataProvider.storeCapsule(this.contractAddress, slot, capsule);
233
231
  }
234
232
  async loadCapsule(contractAddress, slot) {
235
233
  if (!contractAddress.equals(this.contractAddress)) {
236
234
  // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
237
235
  throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
238
236
  }
239
- return this.capsules.find((c)=>c.contractAddress.equals(contractAddress) && c.storageSlot.equals(slot))?.data ?? await this.db.loadCapsule(this.contractAddress, slot);
237
+ return this.capsules.find((c)=>c.contractAddress.equals(contractAddress) && c.storageSlot.equals(slot))?.data ?? await this.executionDataProvider.loadCapsule(this.contractAddress, slot);
240
238
  }
241
239
  deleteCapsule(contractAddress, slot) {
242
240
  if (!contractAddress.equals(this.contractAddress)) {
243
241
  // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
244
242
  throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
245
243
  }
246
- return this.db.deleteCapsule(this.contractAddress, slot);
244
+ return this.executionDataProvider.deleteCapsule(this.contractAddress, slot);
247
245
  }
248
246
  copyCapsule(contractAddress, srcSlot, dstSlot, numEntries) {
249
247
  if (!contractAddress.equals(this.contractAddress)) {
250
248
  // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
251
249
  throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
252
250
  }
253
- return this.db.copyCapsule(this.contractAddress, srcSlot, dstSlot, numEntries);
251
+ return this.executionDataProvider.copyCapsule(this.contractAddress, srcSlot, dstSlot, numEntries);
254
252
  }
255
253
  // TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption.
256
254
  aes128Decrypt(ciphertext, iv, symKey) {
@@ -8,6 +8,7 @@ import { createLogger } from '@aztec/foundation/log';
8
8
  import { Timer } from '@aztec/foundation/timer';
9
9
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
10
10
  import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
11
+ import { SimulationError } from '@aztec/stdlib/errors';
11
12
  import { NestedProcessReturnValues, TxExecutionPhase } from '@aztec/stdlib/tx';
12
13
  import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
13
14
  import { strict as assert } from 'assert';
@@ -61,15 +62,19 @@ export class PublicTxSimulator {
61
62
  processedPhases.push(setupResult);
62
63
  }
63
64
  const revertStart = process.hrtime.bigint();
64
- // FIXME(#12375): TX shouldn't die if revertible insertions fail. Should just revert to snapshot.
65
- await this.insertRevertiblesFromPrivate(context);
66
- // add new contracts to the contracts db so that their functions may be found and called
67
- await this.worldStateDB.addNewRevertibleContracts(tx);
68
- const revertEnd = process.hrtime.bigint();
69
- this.metrics.recordPrivateEffectsInsertion(Number(revertEnd - revertStart) / 1_000, 'revertible');
70
- if (context.hasPhase(TxExecutionPhase.APP_LOGIC)) {
71
- const appLogicResult = await this.simulateAppLogicPhase(context);
72
- processedPhases.push(appLogicResult);
65
+ const success = await this.insertRevertiblesFromPrivate(context);
66
+ if (success) {
67
+ // add new contracts to the contracts db so that their functions may be found and called
68
+ await this.worldStateDB.addNewRevertibleContracts(tx);
69
+ const revertEnd = process.hrtime.bigint();
70
+ this.metrics.recordPrivateEffectsInsertion(Number(revertEnd - revertStart) / 1_000, 'revertible');
71
+ // Only proceed with app logic if there was no revert during revertible insertion
72
+ if (context.hasPhase(TxExecutionPhase.APP_LOGIC)) {
73
+ const appLogicResult = await this.simulateAppLogicPhase(context);
74
+ processedPhases.push(appLogicResult);
75
+ }
76
+ } else {
77
+ this.log.debug(`Revertible insertions failed. Skipping app logic.`);
73
78
  }
74
79
  if (context.hasPhase(TxExecutionPhase.TEARDOWN)) {
75
80
  const teardownResult = await this.simulateTeardownPhase(context);
@@ -255,7 +260,7 @@ export class PublicTxSimulator {
255
260
  await stateManager.writeSiloedNullifiersFromPrivate(context.nonRevertibleAccumulatedDataFromPrivate.nullifiers);
256
261
  } catch (e) {
257
262
  if (e instanceof NullifierCollisionError) {
258
- throw new NullifierCollisionError(`Nullifier collision encountered when inserting non-revertible nullifiers from private.\nDetails: ${e.message}\n.Stack:${e.stack}`);
263
+ throw new NullifierCollisionError(`Nullifier collision encountered when inserting non-revertible nullifiers from private.\nDetails: ${e.message}\nStack:${e.stack}`);
259
264
  }
260
265
  }
261
266
  for (const noteHash of context.nonRevertibleAccumulatedDataFromPrivate.noteHashes){
@@ -275,8 +280,11 @@ export class PublicTxSimulator {
275
280
  await stateManager.writeSiloedNullifiersFromPrivate(context.revertibleAccumulatedDataFromPrivate.nullifiers);
276
281
  } catch (e) {
277
282
  if (e instanceof NullifierCollisionError) {
278
- // FIXME(#12375): simulator should be able to recover from this and just revert to snapshot.
279
- throw new NullifierCollisionError(`Nullifier collision encountered when inserting revertible nullifiers from private. Details:\n${e.message}\n.Stack:${e.stack}`);
283
+ // Instead of throwing, revert the app_logic phase
284
+ context.revert(TxExecutionPhase.APP_LOGIC, new SimulationError(`Nullifier collision encountered when inserting revertible nullifiers from private\nDetails: ${e.message}\nError stack: ${e.stack}`, []), /*culprit=*/ 'insertRevertiblesFromPrivate');
285
+ return /*success=*/ false;
286
+ } else {
287
+ throw e;
280
288
  }
281
289
  }
282
290
  for (const noteHash of context.revertibleAccumulatedDataFromPrivate.noteHashes){
@@ -285,6 +293,7 @@ export class PublicTxSimulator {
285
293
  await stateManager.writeSiloedNoteHash(noteHash);
286
294
  }
287
295
  }
296
+ return /*success=*/ true;
288
297
  }
289
298
  async payFee(context) {
290
299
  const txFee = context.getTransactionFee(TxExecutionPhase.TEARDOWN);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "0.77.0-testnet-ignition.26",
3
+ "version": "0.77.0-testnet-ignition.28",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/server.js",
@@ -59,26 +59,26 @@
59
59
  ]
60
60
  },
61
61
  "dependencies": {
62
- "@aztec/constants": "0.77.0-testnet-ignition.26",
63
- "@aztec/foundation": "0.77.0-testnet-ignition.26",
64
- "@aztec/noir-protocol-circuits-types": "0.77.0-testnet-ignition.26",
65
- "@aztec/protocol-contracts": "0.77.0-testnet-ignition.26",
66
- "@aztec/stdlib": "0.77.0-testnet-ignition.26",
67
- "@aztec/telemetry-client": "0.77.0-testnet-ignition.26",
68
- "@aztec/world-state": "0.77.0-testnet-ignition.26",
62
+ "@aztec/constants": "0.77.0-testnet-ignition.28",
63
+ "@aztec/foundation": "0.77.0-testnet-ignition.28",
64
+ "@aztec/noir-protocol-circuits-types": "0.77.0-testnet-ignition.28",
65
+ "@aztec/protocol-contracts": "0.77.0-testnet-ignition.28",
66
+ "@aztec/stdlib": "0.77.0-testnet-ignition.28",
67
+ "@aztec/telemetry-client": "0.77.0-testnet-ignition.28",
68
+ "@aztec/world-state": "0.77.0-testnet-ignition.28",
69
69
  "levelup": "^5.1.1",
70
70
  "lodash.clonedeep": "^4.5.0",
71
71
  "lodash.merge": "^4.6.2",
72
72
  "memdown": "^6.1.1",
73
73
  "tslib": "^2.4.0",
74
- "@aztec/noir-acvm_js": "0.77.0-testnet-ignition.26",
75
- "@aztec/noir-noirc_abi": "0.77.0-testnet-ignition.26",
76
- "@aztec/noir-types": "0.77.0-testnet-ignition.26"
74
+ "@aztec/noir-acvm_js": "0.77.0-testnet-ignition.28",
75
+ "@aztec/noir-noirc_abi": "0.77.0-testnet-ignition.28",
76
+ "@aztec/noir-types": "0.77.0-testnet-ignition.28"
77
77
  },
78
78
  "devDependencies": {
79
- "@aztec/kv-store": "0.77.0-testnet-ignition.26",
80
- "@aztec/merkle-tree": "0.77.0-testnet-ignition.26",
81
- "@aztec/noir-contracts.js": "0.77.0-testnet-ignition.26",
79
+ "@aztec/kv-store": "0.77.0-testnet-ignition.28",
80
+ "@aztec/merkle-tree": "0.77.0-testnet-ignition.28",
81
+ "@aztec/noir-contracts.js": "0.77.0-testnet-ignition.28",
82
82
  "@jest/globals": "^29.5.0",
83
83
  "@types/jest": "^29.5.0",
84
84
  "@types/levelup": "^5.1.3",