@aztec/simulator 0.32.1 → 0.34.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 (160) hide show
  1. package/README.md +5 -3
  2. package/dest/acvm/acvm.js +2 -2
  3. package/dest/acvm/oracle/index.d.ts +0 -1
  4. package/dest/acvm/oracle/index.d.ts.map +1 -1
  5. package/dest/acvm/oracle/index.js +1 -2
  6. package/dest/acvm/oracle/oracle.d.ts +1 -1
  7. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  8. package/dest/acvm/oracle/oracle.js +4 -5
  9. package/dest/avm/avm_context.d.ts +4 -14
  10. package/dest/avm/avm_context.d.ts.map +1 -1
  11. package/dest/avm/avm_context.js +10 -22
  12. package/dest/avm/avm_execution_environment.d.ts +4 -3
  13. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  14. package/dest/avm/avm_execution_environment.js +8 -7
  15. package/dest/avm/avm_gas.d.ts +71 -0
  16. package/dest/avm/avm_gas.d.ts.map +1 -0
  17. package/dest/avm/avm_gas.js +161 -0
  18. package/dest/avm/avm_machine_state.d.ts +4 -2
  19. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  20. package/dest/avm/avm_machine_state.js +8 -2
  21. package/dest/avm/avm_memory_types.d.ts +53 -1
  22. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  23. package/dest/avm/avm_memory_types.js +99 -6
  24. package/dest/avm/avm_simulator.d.ts.map +1 -1
  25. package/dest/avm/avm_simulator.js +15 -13
  26. package/dest/avm/fixtures/index.d.ts.map +1 -1
  27. package/dest/avm/fixtures/index.js +3 -3
  28. package/dest/avm/journal/journal.d.ts +14 -13
  29. package/dest/avm/journal/journal.d.ts.map +1 -1
  30. package/dest/avm/journal/journal.js +5 -5
  31. package/dest/avm/journal/trace.d.ts +8 -19
  32. package/dest/avm/journal/trace.d.ts.map +1 -1
  33. package/dest/avm/journal/trace.js +48 -116
  34. package/dest/avm/journal/trace_types.d.ts +23 -4
  35. package/dest/avm/journal/trace_types.d.ts.map +1 -1
  36. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  37. package/dest/avm/opcodes/accrued_substate.js +45 -17
  38. package/dest/avm/opcodes/addressing_mode.d.ts +5 -3
  39. package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -1
  40. package/dest/avm/opcodes/addressing_mode.js +5 -1
  41. package/dest/avm/opcodes/arithmetic.d.ts +7 -3
  42. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  43. package/dest/avm/opcodes/arithmetic.js +27 -16
  44. package/dest/avm/opcodes/bitwise.d.ts +21 -20
  45. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  46. package/dest/avm/opcodes/bitwise.js +43 -65
  47. package/dest/avm/opcodes/comparators.d.ts +12 -9
  48. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  49. package/dest/avm/opcodes/comparators.js +22 -32
  50. package/dest/avm/opcodes/context_getters.d.ts +20 -0
  51. package/dest/avm/opcodes/context_getters.d.ts.map +1 -0
  52. package/dest/avm/opcodes/context_getters.js +26 -0
  53. package/dest/avm/opcodes/contract.d.ts +14 -0
  54. package/dest/avm/opcodes/contract.d.ts.map +1 -0
  55. package/dest/avm/opcodes/contract.js +49 -0
  56. package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
  57. package/dest/avm/opcodes/control_flow.js +12 -2
  58. package/dest/avm/opcodes/environment_getters.d.ts +30 -33
  59. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  60. package/dest/avm/opcodes/environment_getters.js +34 -43
  61. package/dest/avm/opcodes/external_calls.d.ts +13 -19
  62. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  63. package/dest/avm/opcodes/external_calls.js +69 -72
  64. package/dest/avm/opcodes/hashing.d.ts +2 -1
  65. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  66. package/dest/avm/opcodes/hashing.js +37 -18
  67. package/dest/avm/opcodes/index.d.ts +1 -0
  68. package/dest/avm/opcodes/index.d.ts.map +1 -1
  69. package/dest/avm/opcodes/index.js +2 -1
  70. package/dest/avm/opcodes/instruction.d.ts +10 -15
  71. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  72. package/dest/avm/opcodes/instruction.js +12 -22
  73. package/dest/avm/opcodes/instruction_impl.d.ts +14 -0
  74. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  75. package/dest/avm/opcodes/instruction_impl.js +37 -16
  76. package/dest/avm/opcodes/memory.d.ts +4 -3
  77. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  78. package/dest/avm/opcodes/memory.js +38 -19
  79. package/dest/avm/opcodes/storage.d.ts +5 -0
  80. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  81. package/dest/avm/opcodes/storage.js +21 -7
  82. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  83. package/dest/avm/serialization/bytecode_serialization.js +7 -5
  84. package/dest/avm/serialization/instruction_serialization.d.ts +12 -11
  85. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  86. package/dest/avm/serialization/instruction_serialization.js +13 -12
  87. package/dest/client/client_execution_context.d.ts +2 -2
  88. package/dest/client/client_execution_context.d.ts.map +1 -1
  89. package/dest/client/client_execution_context.js +6 -6
  90. package/dest/client/private_execution.d.ts +1 -1
  91. package/dest/client/private_execution.d.ts.map +1 -1
  92. package/dest/client/private_execution.js +8 -4
  93. package/dest/client/unconstrained_execution.d.ts +1 -1
  94. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  95. package/dest/client/unconstrained_execution.js +2 -2
  96. package/dest/client/view_data_oracle.d.ts +2 -2
  97. package/dest/client/view_data_oracle.d.ts.map +1 -1
  98. package/dest/client/view_data_oracle.js +2 -2
  99. package/dest/public/executor.d.ts +2 -8
  100. package/dest/public/executor.d.ts.map +1 -1
  101. package/dest/public/executor.js +101 -69
  102. package/dest/public/index.d.ts +1 -1
  103. package/dest/public/index.d.ts.map +1 -1
  104. package/dest/public/public_execution_context.d.ts +6 -6
  105. package/dest/public/public_execution_context.d.ts.map +1 -1
  106. package/dest/public/public_execution_context.js +8 -12
  107. package/dest/public/transitional_adaptors.d.ts +32 -0
  108. package/dest/public/transitional_adaptors.d.ts.map +1 -0
  109. package/dest/public/transitional_adaptors.js +161 -0
  110. package/package.json +15 -9
  111. package/src/acvm/acvm.ts +1 -1
  112. package/src/acvm/oracle/index.ts +0 -1
  113. package/src/acvm/oracle/oracle.ts +3 -4
  114. package/src/avm/avm_context.ts +11 -33
  115. package/src/avm/avm_execution_environment.ts +9 -17
  116. package/src/avm/{avm_gas_cost.ts → avm_gas.ts} +75 -21
  117. package/src/avm/avm_machine_state.ts +9 -2
  118. package/src/avm/avm_memory_types.ts +134 -6
  119. package/src/avm/avm_simulator.ts +14 -12
  120. package/src/avm/fixtures/index.ts +2 -1
  121. package/src/avm/journal/journal.ts +24 -17
  122. package/src/avm/journal/trace.ts +59 -121
  123. package/src/avm/journal/trace_types.ts +39 -39
  124. package/src/avm/opcodes/accrued_substate.ts +58 -23
  125. package/src/avm/opcodes/addressing_mode.ts +8 -3
  126. package/src/avm/opcodes/arithmetic.ts +32 -22
  127. package/src/avm/opcodes/bitwise.ts +49 -83
  128. package/src/avm/opcodes/comparators.ts +28 -43
  129. package/src/avm/opcodes/context_getters.ts +32 -0
  130. package/src/avm/opcodes/contract.ts +58 -0
  131. package/src/avm/opcodes/control_flow.ts +23 -5
  132. package/src/avm/opcodes/environment_getters.ts +35 -44
  133. package/src/avm/opcodes/external_calls.ts +90 -89
  134. package/src/avm/opcodes/hashing.ts +45 -22
  135. package/src/avm/opcodes/index.ts +1 -0
  136. package/src/avm/opcodes/instruction.ts +14 -26
  137. package/src/avm/opcodes/instruction_impl.ts +45 -15
  138. package/src/avm/opcodes/memory.ts +48 -28
  139. package/src/avm/opcodes/storage.ts +26 -12
  140. package/src/avm/serialization/bytecode_serialization.ts +6 -3
  141. package/src/avm/serialization/instruction_serialization.ts +1 -0
  142. package/src/client/client_execution_context.ts +5 -5
  143. package/src/client/private_execution.ts +10 -4
  144. package/src/client/unconstrained_execution.ts +1 -1
  145. package/src/client/view_data_oracle.ts +1 -1
  146. package/src/public/executor.ts +123 -75
  147. package/src/public/index.ts +2 -2
  148. package/src/public/public_execution_context.ts +14 -19
  149. package/src/public/transitional_adaptors.ts +240 -0
  150. package/dest/acvm/oracle/debug.d.ts +0 -19
  151. package/dest/acvm/oracle/debug.d.ts.map +0 -1
  152. package/dest/acvm/oracle/debug.js +0 -95
  153. package/dest/avm/avm_gas_cost.d.ts +0 -322
  154. package/dest/avm/avm_gas_cost.d.ts.map +0 -1
  155. package/dest/avm/avm_gas_cost.js +0 -118
  156. package/dest/avm/temporary_executor_migration.d.ts +0 -25
  157. package/dest/avm/temporary_executor_migration.d.ts.map +0 -1
  158. package/dest/avm/temporary_executor_migration.js +0 -83
  159. package/src/acvm/oracle/debug.ts +0 -109
  160. package/src/avm/temporary_executor_migration.ts +0 -122
@@ -0,0 +1,161 @@
1
+ // All code in this file needs to die once the public executor is phased out in favor of the AVM.
2
+ import { UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types';
3
+ import { CallContext, ContractStorageRead, ContractStorageUpdateRequest, FunctionData, L2ToL1Message, ReadRequest, SideEffect, SideEffectLinkedToNoteHash, } from '@aztec/circuits.js';
4
+ import { Fr } from '@aztec/foundation/fields';
5
+ import { AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
6
+ import { AvmContractCallResults } from '../avm/avm_message_call_result.js';
7
+ import { Mov } from '../avm/opcodes/memory.js';
8
+ import { createSimulationError } from '../common/errors.js';
9
+ import { PackedArgsCache, SideEffectCounter } from '../index.js';
10
+ import { PublicExecutionContext } from './public_execution_context.js';
11
+ /**
12
+ * Convert a PublicExecution(Environment) object to an AvmExecutionEnvironment
13
+ *
14
+ * @param current
15
+ * @param globalVariables
16
+ * @returns
17
+ */
18
+ export function createAvmExecutionEnvironment(current, header, globalVariables) {
19
+ return new AvmExecutionEnvironment(current.contractAddress, current.callContext.storageContractAddress, current.callContext.msgSender, // TODO: origin is not available
20
+ current.callContext.msgSender, current.callContext.portalContractAddress,
21
+ /*feePerL1Gas=*/ Fr.zero(),
22
+ /*feePerL2Gas=*/ Fr.zero(),
23
+ /*feePerDaGas=*/ Fr.zero(),
24
+ /*contractCallDepth=*/ Fr.zero(), header, globalVariables, current.callContext.isStaticCall, current.callContext.isDelegateCall, current.args, current.functionData.selector);
25
+ }
26
+ export function createPublicExecutionContext(avmContext, calldata) {
27
+ const sideEffectCounter = avmContext.persistableState.trace.accessCounter;
28
+ const callContext = CallContext.from({
29
+ msgSender: avmContext.environment.sender,
30
+ storageContractAddress: avmContext.environment.storageAddress,
31
+ portalContractAddress: avmContext.environment.portal,
32
+ functionSelector: avmContext.environment.temporaryFunctionSelector,
33
+ isDelegateCall: avmContext.environment.isDelegateCall,
34
+ isStaticCall: avmContext.environment.isStaticCall,
35
+ sideEffectCounter: sideEffectCounter,
36
+ });
37
+ const functionData = new FunctionData(avmContext.environment.temporaryFunctionSelector, /*isPrivate=*/ false);
38
+ const execution = {
39
+ contractAddress: avmContext.environment.address,
40
+ callContext,
41
+ args: calldata,
42
+ functionData,
43
+ };
44
+ const packedArgs = PackedArgsCache.create([]);
45
+ const context = new PublicExecutionContext(execution, avmContext.environment.header, avmContext.environment.globals, packedArgs, new SideEffectCounter(sideEffectCounter), avmContext.persistableState.hostStorage.publicStateDb, avmContext.persistableState.hostStorage.contractsDb, avmContext.persistableState.hostStorage.commitmentsDb);
46
+ return context;
47
+ }
48
+ /**
49
+ * Convert the result of an AVM contract call to a PublicExecutionResult for the public kernel
50
+ *
51
+ * @param execution
52
+ * @param newWorldState
53
+ * @param result
54
+ * @returns
55
+ */
56
+ export async function convertAvmResults(executionContext, newWorldState, result) {
57
+ const execution = executionContext.execution;
58
+ const contractStorageReads = newWorldState.storageReads.map(read => new ContractStorageRead(read.slot, read.value, read.counter.toNumber()));
59
+ const contractStorageUpdateRequests = newWorldState.storageWrites.map(write => new ContractStorageUpdateRequest(write.slot, write.value, write.counter.toNumber()));
60
+ // We need to write the storage updates to the DB, because that's what the ACVM expects.
61
+ // Assumes the updates are in the right order.
62
+ for (const write of newWorldState.storageWrites) {
63
+ await executionContext.stateDb.storageWrite(write.storageAddress, write.slot, write.value);
64
+ }
65
+ const newNoteHashes = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash.noteHash, noteHash.counter));
66
+ const nullifierReadRequests = newWorldState.nullifierChecks
67
+ .filter(nullifierCheck => nullifierCheck.exists)
68
+ .map(nullifierCheck => new ReadRequest(nullifierCheck.nullifier, nullifierCheck.counter.toNumber()));
69
+ const nullifierNonExistentReadRequests = newWorldState.nullifierChecks
70
+ .filter(nullifierCheck => !nullifierCheck.exists)
71
+ .map(nullifierCheck => new ReadRequest(nullifierCheck.nullifier, nullifierCheck.counter.toNumber()));
72
+ const newNullifiers = newWorldState.newNullifiers.map(tracedNullifier => new SideEffectLinkedToNoteHash(
73
+ /*value=*/ tracedNullifier.nullifier,
74
+ /*noteHash=*/ Fr.ZERO, // NEEDED?
75
+ tracedNullifier.counter));
76
+ const unencryptedLogs = new UnencryptedFunctionL2Logs(newWorldState.newLogs.map(log => new UnencryptedL2Log(log.contractAddress, log.selector, log.data)));
77
+ const newL2ToL1Messages = newWorldState.newL1Messages.map(m => new L2ToL1Message(m.recipient, m.content));
78
+ const returnValues = result.output;
79
+ // TODO: Support nested executions.
80
+ const nestedExecutions = [];
81
+ // TODO keep track of side effect counters
82
+ const startSideEffectCounter = Fr.ZERO;
83
+ const endSideEffectCounter = Fr.ZERO;
84
+ return {
85
+ execution,
86
+ nullifierReadRequests,
87
+ nullifierNonExistentReadRequests,
88
+ newNoteHashes,
89
+ newL2ToL1Messages,
90
+ startSideEffectCounter,
91
+ endSideEffectCounter,
92
+ newNullifiers,
93
+ contractStorageReads,
94
+ contractStorageUpdateRequests,
95
+ returnValues,
96
+ nestedExecutions,
97
+ unencryptedLogs,
98
+ reverted: result.reverted,
99
+ revertReason: result.revertReason ? createSimulationError(result.revertReason) : undefined,
100
+ };
101
+ }
102
+ export function convertPublicExecutionResult(res) {
103
+ return new AvmContractCallResults(res.reverted, res.returnValues, res.revertReason);
104
+ }
105
+ export function updateAvmContextFromPublicExecutionResult(ctx, result) {
106
+ // We have to push these manually and not use the trace* functions
107
+ // so that we respect the side effect counters.
108
+ for (const readRequest of result.contractStorageReads) {
109
+ ctx.persistableState.trace.publicStorageReads.push({
110
+ storageAddress: ctx.environment.storageAddress,
111
+ exists: true, // FIXME
112
+ slot: readRequest.storageSlot,
113
+ value: readRequest.currentValue,
114
+ counter: new Fr(readRequest.sideEffectCounter ?? Fr.ZERO),
115
+ });
116
+ }
117
+ for (const updateRequest of result.contractStorageUpdateRequests) {
118
+ ctx.persistableState.trace.publicStorageWrites.push({
119
+ storageAddress: ctx.environment.storageAddress,
120
+ slot: updateRequest.storageSlot,
121
+ value: updateRequest.newValue,
122
+ counter: new Fr(updateRequest.sideEffectCounter ?? Fr.ZERO),
123
+ });
124
+ // We need to manually populate the cache.
125
+ ctx.persistableState.publicStorage.write(ctx.environment.storageAddress, updateRequest.storageSlot, updateRequest.newValue);
126
+ }
127
+ for (const nullifier of result.newNullifiers) {
128
+ ctx.persistableState.trace.newNullifiers.push({
129
+ storageAddress: ctx.environment.storageAddress,
130
+ nullifier: nullifier.value,
131
+ counter: nullifier.counter,
132
+ });
133
+ }
134
+ for (const noteHash of result.newNoteHashes) {
135
+ ctx.persistableState.trace.newNoteHashes.push({
136
+ storageAddress: ctx.environment.storageAddress,
137
+ noteHash: noteHash.value,
138
+ counter: noteHash.counter,
139
+ });
140
+ }
141
+ for (const message of result.newL2ToL1Messages) {
142
+ ctx.persistableState.newL1Messages.push(message);
143
+ }
144
+ for (const log of result.unencryptedLogs.logs) {
145
+ ctx.persistableState.newLogs.push(new UnencryptedL2Log(log.contractAddress, log.selector, log.data));
146
+ }
147
+ }
148
+ const AVM_MAGIC_SUFFIX = Buffer.from([
149
+ Mov.opcode, // opcode
150
+ 0x00, // indirect
151
+ ...Buffer.from('000018ca', 'hex'), // srcOffset
152
+ ...Buffer.from('000018ca', 'hex'), // dstOffset
153
+ ]);
154
+ export function markBytecodeAsAvm(bytecode) {
155
+ return Buffer.concat([bytecode, AVM_MAGIC_SUFFIX]);
156
+ }
157
+ export function isAvmBytecode(bytecode) {
158
+ const magicSize = AVM_MAGIC_SUFFIX.length;
159
+ return bytecode.subarray(-magicSize).equals(AVM_MAGIC_SUFFIX);
160
+ }
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNpdGlvbmFsX2FkYXB0b3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3B1YmxpYy90cmFuc2l0aW9uYWxfYWRhcHRvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUdBQWlHO0FBQ2pHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25GLE9BQU8sRUFDTCxXQUFXLEVBQ1gsbUJBQW1CLEVBQ25CLDRCQUE0QixFQUM1QixZQUFZLEVBR1osYUFBYSxFQUNiLFdBQVcsRUFDWCxVQUFVLEVBQ1YsMEJBQTBCLEdBQzNCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRzlDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRTNFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMvQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWpFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRXZFOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSw2QkFBNkIsQ0FDM0MsT0FBd0IsRUFDeEIsTUFBYyxFQUNkLGVBQWdDO0lBRWhDLE9BQU8sSUFBSSx1QkFBdUIsQ0FDaEMsT0FBTyxDQUFDLGVBQWUsRUFDdkIsT0FBTyxDQUFDLFdBQVcsQ0FBQyxzQkFBc0IsRUFDMUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsZ0NBQWdDO0lBQy9ELE9BQU8sQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUM3QixPQUFPLENBQUMsV0FBVyxDQUFDLHFCQUFxQjtJQUN6QyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO0lBQzFCLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7SUFDMUIsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtJQUMxQixzQkFBc0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQ2hDLE1BQU0sRUFDTixlQUFlLEVBQ2YsT0FBTyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQ2hDLE9BQU8sQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUNsQyxPQUFPLENBQUMsSUFBSSxFQUNaLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUM5QixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxVQUFzQixFQUFFLFFBQWM7SUFDakYsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztJQUMxRSxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDO1FBQ25DLFNBQVMsRUFBRSxVQUFVLENBQUMsV0FBVyxDQUFDLE1BQU07UUFDeEMsc0JBQXNCLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxjQUFjO1FBQzdELHFCQUFxQixFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTTtRQUNwRCxnQkFBZ0IsRUFBRSxVQUFVLENBQUMsV0FBVyxDQUFDLHlCQUF5QjtRQUNsRSxjQUFjLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxjQUFjO1FBQ3JELFlBQVksRUFBRSxVQUFVLENBQUMsV0FBVyxDQUFDLFlBQVk7UUFDakQsaUJBQWlCLEVBQUUsaUJBQWlCO0tBQ3JDLENBQUMsQ0FBQztJQUNILE1BQU0sWUFBWSxHQUFHLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMseUJBQXlCLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlHLE1BQU0sU0FBUyxHQUFvQjtRQUNqQyxlQUFlLEVBQUUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxPQUFPO1FBQy9DLFdBQVc7UUFDWCxJQUFJLEVBQUUsUUFBUTtRQUNkLFlBQVk7S0FDYixDQUFDO0lBQ0YsTUFBTSxVQUFVLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUU5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLHNCQUFzQixDQUN4QyxTQUFTLEVBQ1QsVUFBVSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQzdCLFVBQVUsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUM5QixVQUFVLEVBQ1YsSUFBSSxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxFQUN4QyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFDckQsVUFBVSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQ25ELFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUN0RCxDQUFDO0lBRUYsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGlCQUFpQixDQUNyQyxnQkFBd0MsRUFDeEMsYUFBMEIsRUFDMUIsTUFBOEI7SUFFOUIsTUFBTSxTQUFTLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDO0lBRTdDLE1BQU0sb0JBQW9CLEdBQTBCLGFBQWEsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUNoRixJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FDaEYsQ0FBQztJQUNGLE1BQU0sNkJBQTZCLEdBQW1DLGFBQWEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNuRyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksNEJBQTRCLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FDN0YsQ0FBQztJQUNGLHdGQUF3RjtJQUN4Riw4Q0FBOEM7SUFDOUMsS0FBSyxNQUFNLEtBQUssSUFBSSxhQUFhLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDaEQsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0YsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLGFBQWEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNuRCxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUNoRSxDQUFDO0lBQ0YsTUFBTSxxQkFBcUIsR0FBa0IsYUFBYSxDQUFDLGVBQWU7U0FDdkUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQztTQUMvQyxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLE1BQU0sZ0NBQWdDLEdBQWtCLGFBQWEsQ0FBQyxlQUFlO1NBQ2xGLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQztTQUNoRCxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLE1BQU0sYUFBYSxHQUFpQyxhQUFhLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDakYsZUFBZSxDQUFDLEVBQUUsQ0FDaEIsSUFBSSwwQkFBMEI7SUFDNUIsVUFBVSxDQUFDLGVBQWUsQ0FBQyxTQUFTO0lBQ3BDLGFBQWEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFVBQVU7SUFDakMsZUFBZSxDQUFDLE9BQU8sQ0FDeEIsQ0FDSixDQUFDO0lBQ0YsTUFBTSxlQUFlLEdBQThCLElBQUkseUJBQXlCLENBQzlFLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQ3BHLENBQUM7SUFDRixNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUUxRyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBRW5DLG1DQUFtQztJQUNuQyxNQUFNLGdCQUFnQixHQUE0QixFQUFFLENBQUM7SUFDckQsMENBQTBDO0lBQzFDLE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztJQUN2QyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7SUFFckMsT0FBTztRQUNMLFNBQVM7UUFDVCxxQkFBcUI7UUFDckIsZ0NBQWdDO1FBQ2hDLGFBQWE7UUFDYixpQkFBaUI7UUFDakIsc0JBQXNCO1FBQ3RCLG9CQUFvQjtRQUNwQixhQUFhO1FBQ2Isb0JBQW9CO1FBQ3BCLDZCQUE2QjtRQUM3QixZQUFZO1FBQ1osZ0JBQWdCO1FBQ2hCLGVBQWU7UUFDZixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7UUFDekIsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztLQUMzRixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxHQUEwQjtJQUNyRSxPQUFPLElBQUksc0JBQXNCLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN0RixDQUFDO0FBRUQsTUFBTSxVQUFVLHlDQUF5QyxDQUFDLEdBQWUsRUFBRSxNQUE2QjtJQUN0RyxrRUFBa0U7SUFDbEUsK0NBQStDO0lBQy9DLEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDdEQsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUM7WUFDakQsY0FBYyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsY0FBYztZQUM5QyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVE7WUFDdEIsSUFBSSxFQUFFLFdBQVcsQ0FBQyxXQUFXO1lBQzdCLEtBQUssRUFBRSxXQUFXLENBQUMsWUFBWTtZQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDLGlCQUFpQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUM7U0FDMUQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssTUFBTSxhQUFhLElBQUksTUFBTSxDQUFDLDZCQUE2QixFQUFFLENBQUM7UUFDakUsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7WUFDbEQsY0FBYyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsY0FBYztZQUM5QyxJQUFJLEVBQUUsYUFBYSxDQUFDLFdBQVc7WUFDL0IsS0FBSyxFQUFFLGFBQWEsQ0FBQyxRQUFRO1lBQzdCLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQztTQUM1RCxDQUFDLENBQUM7UUFFSCwwQ0FBMEM7UUFDMUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQ3RDLEdBQUcsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUM5QixhQUFhLENBQUMsV0FBVyxFQUN6QixhQUFhLENBQUMsUUFBUSxDQUN2QixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssTUFBTSxTQUFTLElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzdDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztZQUM1QyxjQUFjLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxjQUFjO1lBQzlDLFNBQVMsRUFBRSxTQUFTLENBQUMsS0FBSztZQUMxQixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87U0FDM0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssTUFBTSxRQUFRLElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzVDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztZQUM1QyxjQUFjLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxjQUFjO1lBQzlDLFFBQVEsRUFBRSxRQUFRLENBQUMsS0FBSztZQUN4QixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87U0FDMUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssTUFBTSxPQUFPLElBQUksTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDL0MsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5QyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN2RyxDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNuQyxHQUFHLENBQUMsTUFBTSxFQUFFLFNBQVM7SUFDckIsSUFBSSxFQUFFLFdBQVc7SUFDakIsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsRUFBRSxZQUFZO0lBQy9DLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUUsWUFBWTtDQUNoRCxDQUFDLENBQUM7QUFFSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsUUFBZ0I7SUFDaEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxRQUFnQjtJQUM1QyxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFDMUMsT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDaEUsQ0FBQyJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "0.32.1",
3
+ "version": "0.34.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -16,24 +16,31 @@
16
16
  "clean": "rm -rf ./dest .tsbuildinfo",
17
17
  "formatting": "run -T prettier --check ./src && run -T eslint ./src",
18
18
  "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
19
- "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests"
19
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests"
20
20
  },
21
21
  "inherits": [
22
22
  "../package.common.json"
23
23
  ],
24
24
  "jest": {
25
- "preset": "ts-jest/presets/default-esm",
26
25
  "moduleNameMapper": {
27
26
  "^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
28
27
  },
29
28
  "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
30
- "rootDir": "./src"
29
+ "rootDir": "./src",
30
+ "transform": {
31
+ "^.+\\.tsx?$": [
32
+ "@swc/jest"
33
+ ]
34
+ },
35
+ "extensionsToTreatAsEsm": [
36
+ ".ts"
37
+ ]
31
38
  },
32
39
  "dependencies": {
33
- "@aztec/circuit-types": "0.32.1",
34
- "@aztec/circuits.js": "0.32.1",
35
- "@aztec/foundation": "0.32.1",
36
- "@aztec/types": "0.32.1",
40
+ "@aztec/circuit-types": "0.34.0",
41
+ "@aztec/circuits.js": "0.34.0",
42
+ "@aztec/foundation": "0.34.0",
43
+ "@aztec/types": "0.34.0",
37
44
  "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js",
38
45
  "@noir-lang/types": "portal:../../noir/packages/types",
39
46
  "levelup": "^5.1.1",
@@ -53,7 +60,6 @@
53
60
  "jest": "^29.5.0",
54
61
  "jest-mock-extended": "^3.0.4",
55
62
  "lodash.merge": "^4.6.2",
56
- "ts-jest": "^29.1.0",
57
63
  "ts-node": "^10.9.1",
58
64
  "typescript": "^5.0.4",
59
65
  "viem": "^2.7.15"
package/src/acvm/acvm.ts CHANGED
@@ -95,7 +95,7 @@ export async function acvm(
95
95
  initialWitness,
96
96
  async (name: string, args: ForeignCallInput[]) => {
97
97
  try {
98
- logger(`Oracle callback ${name}`);
98
+ logger.verbose(`Oracle callback ${name}`);
99
99
  const oracleFunction = callback[name as ORACLE_NAMES];
100
100
  if (!oracleFunction) {
101
101
  throw new Error(`Oracle callback ${name} not found`);
@@ -1,6 +1,5 @@
1
1
  import { type Oracle } from './oracle.js';
2
2
 
3
- export * from './debug.js';
4
3
  export * from './oracle.js';
5
4
  export * from './typed_oracle.js';
6
5
 
@@ -1,5 +1,5 @@
1
1
  import { MerkleTreeId, UnencryptedL2Log } from '@aztec/circuit-types';
2
- import { RETURN_VALUES_LENGTH } from '@aztec/circuits.js';
2
+ import { RETURN_VALUES_LENGTH, acvmFieldMessageToString, oracleDebugCallToFormattedStr } from '@aztec/circuits.js';
3
3
  import { EventSelector, FunctionSelector } from '@aztec/foundation/abi';
4
4
  import { AztecAddress } from '@aztec/foundation/aztec-address';
5
5
  import { padArrayEnd } from '@aztec/foundation/collection';
@@ -9,7 +9,6 @@ import { createDebugLogger } from '@aztec/foundation/log';
9
9
  import { type ACVMField } from '../acvm_types.js';
10
10
  import { frToBoolean, frToNumber, fromACVMField } from '../deserialize.js';
11
11
  import { toACVMField, toAcvmEnqueuePublicFunctionResult } from '../serialize.js';
12
- import { acvmFieldMessageToString, oracleDebugCallToFormattedStr } from './debug.js';
13
12
  import { type TypedOracle } from './typed_oracle.js';
14
13
 
15
14
  /**
@@ -305,12 +304,12 @@ export class Oracle {
305
304
  }
306
305
 
307
306
  debugLog(...args: ACVMField[][]): ACVMField {
308
- this.log(oracleDebugCallToFormattedStr(args));
307
+ this.log.verbose(oracleDebugCallToFormattedStr(args));
309
308
  return toACVMField(0);
310
309
  }
311
310
 
312
311
  debugLogWithPrefix(arg0: ACVMField[], ...args: ACVMField[][]): ACVMField {
313
- this.log(`${acvmFieldMessageToString(arg0)}: ${oracleDebugCallToFormattedStr(args)}`);
312
+ this.log.verbose(`${acvmFieldMessageToString(arg0)}: ${oracleDebugCallToFormattedStr(args)}`);
314
313
  return toACVMField(0);
315
314
  }
316
315
 
@@ -2,6 +2,7 @@ import { type AztecAddress, FunctionSelector } from '@aztec/circuits.js';
2
2
  import { type Fr } from '@aztec/foundation/fields';
3
3
 
4
4
  import { type AvmExecutionEnvironment } from './avm_execution_environment.js';
5
+ import { type Gas, gasToGasLeft } from './avm_gas.js';
5
6
  import { AvmMachineState } from './avm_machine_state.js';
6
7
  import { type AvmPersistableStateManager } from './journal/journal.js';
7
8
 
@@ -33,47 +34,24 @@ export class AvmContext {
33
34
  *
34
35
  * @param address - The contract instance to initialize a context for
35
36
  * @param calldata - Data/arguments for nested call
37
+ * @param allocatedGas - Gas allocated for the nested call
38
+ * @param callType - Type of call (CALL or STATICCALL)
36
39
  * @returns new AvmContext instance
37
40
  */
38
41
  public createNestedContractCallContext(
39
42
  address: AztecAddress,
40
43
  calldata: Fr[],
44
+ allocatedGas: Gas,
45
+ callType: 'CALL' | 'STATICCALL',
41
46
  temporaryFunctionSelector: FunctionSelector = FunctionSelector.empty(),
42
47
  ): AvmContext {
43
- const newExecutionEnvironment = this.environment.deriveEnvironmentForNestedCall(
44
- address,
45
- calldata,
46
- temporaryFunctionSelector,
47
- );
48
+ const deriveFn =
49
+ callType === 'CALL'
50
+ ? this.environment.deriveEnvironmentForNestedCall
51
+ : this.environment.deriveEnvironmentForNestedStaticCall;
52
+ const newExecutionEnvironment = deriveFn.call(this.environment, address, calldata, temporaryFunctionSelector);
48
53
  const forkedWorldState = this.persistableState.fork();
49
- const machineState = AvmMachineState.fromState(this.machineState);
50
- return new AvmContext(forkedWorldState, newExecutionEnvironment, machineState);
51
- }
52
-
53
- /**
54
- * Prepare a new AVM context that will be ready for an external/nested static call
55
- * - Fork the world state journal
56
- * - Derive a machine state from the current state
57
- * - E.g., gas metering is preserved but pc is reset
58
- * - Derive an execution environment from the caller/parent
59
- * - Alter both address and storageAddress
60
- *
61
- * @param address - The contract instance to initialize a context for
62
- * @param calldata - Data/arguments for nested call
63
- * @returns new AvmContext instance
64
- */
65
- public createNestedContractStaticCallContext(
66
- address: AztecAddress,
67
- calldata: Fr[],
68
- temporaryFunctionSelector: FunctionSelector = FunctionSelector.empty(),
69
- ): AvmContext {
70
- const newExecutionEnvironment = this.environment.deriveEnvironmentForNestedStaticCall(
71
- address,
72
- calldata,
73
- temporaryFunctionSelector,
74
- );
75
- const forkedWorldState = this.persistableState.fork();
76
- const machineState = AvmMachineState.fromState(this.machineState);
54
+ const machineState = AvmMachineState.fromState(gasToGasLeft(allocatedGas));
77
55
  return new AvmContext(forkedWorldState, newExecutionEnvironment, machineState);
78
56
  }
79
57
  }
@@ -1,4 +1,4 @@
1
- import { FunctionSelector, type GlobalVariables } from '@aztec/circuits.js';
1
+ import { FunctionSelector, type GlobalVariables, type Header } from '@aztec/circuits.js';
2
2
  import { computeVarArgsHash } from '@aztec/circuits.js/hash';
3
3
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
4
4
  import { type EthAddress } from '@aztec/foundation/eth-address';
@@ -22,29 +22,18 @@ export class AvmContextInputs {
22
22
  export class AvmExecutionEnvironment {
23
23
  constructor(
24
24
  public readonly address: AztecAddress,
25
-
26
25
  public readonly storageAddress: AztecAddress,
27
-
28
26
  public readonly origin: AztecAddress,
29
-
30
27
  public readonly sender: AztecAddress,
31
-
32
28
  public readonly portal: EthAddress,
33
-
34
29
  public readonly feePerL1Gas: Fr,
35
-
36
30
  public readonly feePerL2Gas: Fr,
37
-
38
31
  public readonly feePerDaGas: Fr,
39
-
40
32
  public readonly contractCallDepth: Fr,
41
-
33
+ public readonly header: Header,
42
34
  public readonly globals: GlobalVariables,
43
-
44
35
  public readonly isStaticCall: boolean,
45
-
46
36
  public readonly isDelegateCall: boolean,
47
-
48
37
  public readonly calldata: Fr[],
49
38
 
50
39
  // Function selector is temporary since eventually public contract bytecode will be one blob
@@ -59,20 +48,21 @@ export class AvmExecutionEnvironment {
59
48
  }
60
49
 
61
50
  public deriveEnvironmentForNestedCall(
62
- address: AztecAddress,
51
+ targetAddress: AztecAddress,
63
52
  calldata: Fr[],
64
53
  temporaryFunctionSelector: FunctionSelector = FunctionSelector.empty(),
65
54
  ): AvmExecutionEnvironment {
66
55
  return new AvmExecutionEnvironment(
67
- address,
68
- /*storageAddress=*/ address,
56
+ targetAddress,
57
+ /*storageAddress=*/ targetAddress,
69
58
  this.origin,
70
- this.sender,
59
+ this.address,
71
60
  this.portal,
72
61
  this.feePerL1Gas,
73
62
  this.feePerL2Gas,
74
63
  this.feePerDaGas,
75
64
  this.contractCallDepth,
65
+ this.header,
76
66
  this.globals,
77
67
  this.isStaticCall,
78
68
  this.isDelegateCall,
@@ -96,6 +86,7 @@ export class AvmExecutionEnvironment {
96
86
  this.feePerL2Gas,
97
87
  this.feePerDaGas,
98
88
  this.contractCallDepth,
89
+ this.header,
99
90
  this.globals,
100
91
  /*isStaticCall=*/ true,
101
92
  this.isDelegateCall,
@@ -119,6 +110,7 @@ export class AvmExecutionEnvironment {
119
110
  this.feePerL2Gas,
120
111
  this.feePerDaGas,
121
112
  this.contractCallDepth,
113
+ this.header,
122
114
  this.globals,
123
115
  this.isStaticCall,
124
116
  /*isDelegateCall=*/ true,
@@ -1,20 +1,49 @@
1
1
  import { TypeTag } from './avm_memory_types.js';
2
+ import { InstructionExecutionError } from './errors.js';
3
+ import { Addressing, AddressingMode } from './opcodes/addressing_mode.js';
2
4
  import { Opcode } from './serialization/instruction_serialization.js';
3
5
 
4
- /** Gas cost in L1, L2, and DA for a given instruction. */
5
- export type GasCost = {
6
+ /** Gas counters in L1, L2, and DA. */
7
+ export type Gas = {
6
8
  l1Gas: number;
7
9
  l2Gas: number;
8
10
  daGas: number;
9
11
  };
10
12
 
13
+ /** Maps a Gas struct to gasLeft properties. */
14
+ export function gasToGasLeft(gas: Gas) {
15
+ return { l1GasLeft: gas.l1Gas, l2GasLeft: gas.l2Gas, daGasLeft: gas.daGas };
16
+ }
17
+
18
+ /** Maps gasLeft properties to a gas struct. */
19
+ export function gasLeftToGas(gasLeft: { l1GasLeft: number; l2GasLeft: number; daGasLeft: number }) {
20
+ return { l1Gas: gasLeft.l1GasLeft, l2Gas: gasLeft.l2GasLeft, daGas: gasLeft.daGasLeft };
21
+ }
22
+
11
23
  /** Creates a new instance with all values set to zero except the ones set. */
12
- export function makeGasCost(gasCost: Partial<GasCost>) {
13
- return { ...EmptyGasCost, ...gasCost };
24
+ export function makeGas(gasCost: Partial<Gas>) {
25
+ return { ...EmptyGas, ...gasCost };
26
+ }
27
+
28
+ /** Sums together multiple instances of Gas. */
29
+ export function sumGas(...gases: Partial<Gas>[]) {
30
+ return gases.reduce(
31
+ (acc: Gas, gas) => ({
32
+ l1Gas: acc.l1Gas + (gas.l1Gas ?? 0),
33
+ l2Gas: acc.l2Gas + (gas.l2Gas ?? 0),
34
+ daGas: acc.daGas + (gas.daGas ?? 0),
35
+ }),
36
+ EmptyGas,
37
+ );
38
+ }
39
+
40
+ /** Multiplies a gas instance by a scalar. */
41
+ export function mulGas(gas: Partial<Gas>, scalar: number) {
42
+ return { l1Gas: (gas.l1Gas ?? 0) * scalar, l2Gas: (gas.l2Gas ?? 0) * scalar, daGas: (gas.daGas ?? 0) * scalar };
14
43
  }
15
44
 
16
- /** Gas cost of zero across all gas dimensions. */
17
- export const EmptyGasCost = {
45
+ /** Zero gas across all gas dimensions. */
46
+ export const EmptyGas: Gas = {
18
47
  l1Gas: 0,
19
48
  l2Gas: 0,
20
49
  daGas: 0,
@@ -29,12 +58,12 @@ export const DynamicGasCost = Symbol('DynamicGasCost');
29
58
  /** Temporary default gas cost. We should eventually remove all usage of this variable in favor of actual gas for each opcode. */
30
59
  const TemporaryDefaultGasCost = { l1Gas: 0, l2Gas: 10, daGas: 0 };
31
60
 
32
- /** Gas costs for each instruction. */
33
- export const GasCosts = {
34
- [Opcode.ADD]: DynamicGasCost,
35
- [Opcode.SUB]: DynamicGasCost,
36
- [Opcode.MUL]: DynamicGasCost,
37
- [Opcode.DIV]: DynamicGasCost,
61
+ /** Base gas costs for each instruction. Additional gas cost may be added on top due to memory or storage accesses, etc. */
62
+ export const GasCosts: Record<Opcode, Gas | typeof DynamicGasCost> = {
63
+ [Opcode.ADD]: TemporaryDefaultGasCost,
64
+ [Opcode.SUB]: TemporaryDefaultGasCost,
65
+ [Opcode.MUL]: TemporaryDefaultGasCost,
66
+ [Opcode.DIV]: TemporaryDefaultGasCost,
38
67
  [Opcode.FDIV]: TemporaryDefaultGasCost,
39
68
  [Opcode.EQ]: TemporaryDefaultGasCost,
40
69
  [Opcode.LT]: TemporaryDefaultGasCost,
@@ -64,7 +93,7 @@ export const GasCosts = {
64
93
  [Opcode.BLOCKL1GASLIMIT]: TemporaryDefaultGasCost,
65
94
  [Opcode.BLOCKL2GASLIMIT]: TemporaryDefaultGasCost,
66
95
  [Opcode.BLOCKDAGASLIMIT]: TemporaryDefaultGasCost,
67
- [Opcode.CALLDATACOPY]: DynamicGasCost,
96
+ [Opcode.CALLDATACOPY]: TemporaryDefaultGasCost,
68
97
  // Gas
69
98
  [Opcode.L1GASLEFT]: TemporaryDefaultGasCost,
70
99
  [Opcode.L2GASLEFT]: TemporaryDefaultGasCost,
@@ -75,7 +104,7 @@ export const GasCosts = {
75
104
  [Opcode.INTERNALCALL]: TemporaryDefaultGasCost,
76
105
  [Opcode.INTERNALRETURN]: TemporaryDefaultGasCost,
77
106
  // Memory
78
- [Opcode.SET]: DynamicGasCost,
107
+ [Opcode.SET]: TemporaryDefaultGasCost,
79
108
  [Opcode.MOV]: TemporaryDefaultGasCost,
80
109
  [Opcode.CMOV]: TemporaryDefaultGasCost,
81
110
  // World state
@@ -89,6 +118,7 @@ export const GasCosts = {
89
118
  [Opcode.HEADERMEMBER]: TemporaryDefaultGasCost,
90
119
  [Opcode.EMITUNENCRYPTEDLOG]: TemporaryDefaultGasCost,
91
120
  [Opcode.SENDL2TOL1MSG]: TemporaryDefaultGasCost,
121
+ [Opcode.GETCONTRACTINSTANCE]: TemporaryDefaultGasCost,
92
122
  // External calls
93
123
  [Opcode.CALL]: TemporaryDefaultGasCost,
94
124
  [Opcode.STATICCALL]: TemporaryDefaultGasCost,
@@ -100,18 +130,42 @@ export const GasCosts = {
100
130
  [Opcode.POSEIDON]: TemporaryDefaultGasCost,
101
131
  [Opcode.SHA256]: TemporaryDefaultGasCost, // temp - may be removed, but alot of contracts rely on i: TemporaryDefaultGasCost,
102
132
  [Opcode.PEDERSEN]: TemporaryDefaultGasCost, // temp - may be removed, but alot of contracts rely on i: TemporaryDefaultGasCost,t
103
- } as const;
133
+ };
134
+
135
+ /** Returns the fixed base gas cost for a given opcode, or throws if set to dynamic. */
136
+ export function getBaseGasCost(opcode: Opcode): Gas {
137
+ const cost = GasCosts[opcode];
138
+ if (cost === DynamicGasCost) {
139
+ throw new Error(`Opcode ${Opcode[opcode]} has dynamic gas cost`);
140
+ }
141
+ return cost;
142
+ }
143
+
144
+ /** Returns the gas cost associated with the memory operations performed. */
145
+ export function getMemoryGasCost(args: { reads?: number; writes?: number; indirect?: number }) {
146
+ const { reads, writes, indirect } = args;
147
+ const indirectCount = Addressing.fromWire(indirect ?? 0).count(AddressingMode.INDIRECT);
148
+ const l2MemoryGasCost =
149
+ (reads ?? 0) * GasCostConstants.MEMORY_READ +
150
+ (writes ?? 0) * GasCostConstants.MEMORY_WRITE +
151
+ indirectCount * GasCostConstants.MEMORY_INDIRECT_READ_PENALTY;
152
+ return makeGas({ l2Gas: l2MemoryGasCost });
153
+ }
104
154
 
105
155
  /** Constants used in base cost calculations. */
106
156
  export const GasCostConstants = {
107
- SET_COST_PER_BYTE: 100,
108
- CALLDATACOPY_COST_PER_BYTE: 10,
109
- ARITHMETIC_COST_PER_BYTE: 10,
110
- ARITHMETIC_COST_PER_INDIRECT_ACCESS: 5,
157
+ MEMORY_READ: 10,
158
+ MEMORY_INDIRECT_READ_PENALTY: 10,
159
+ MEMORY_WRITE: 100,
111
160
  };
112
161
 
162
+ /** Returns gas cost for an operation on a given type tag based on the base cost per byte. */
163
+ export function getGasCostForTypeTag(tag: TypeTag, baseCost: Gas) {
164
+ return mulGas(baseCost, getGasCostMultiplierFromTypeTag(tag));
165
+ }
166
+
113
167
  /** Returns a multiplier based on the size of the type represented by the tag. Throws on uninitialized or invalid. */
114
- export function getGasCostMultiplierFromTypeTag(tag: TypeTag) {
168
+ function getGasCostMultiplierFromTypeTag(tag: TypeTag) {
115
169
  switch (tag) {
116
170
  case TypeTag.UINT8:
117
171
  return 1;
@@ -127,6 +181,6 @@ export function getGasCostMultiplierFromTypeTag(tag: TypeTag) {
127
181
  return 32;
128
182
  case TypeTag.INVALID:
129
183
  case TypeTag.UNINITIALIZED:
130
- throw new Error(`Invalid tag type for gas cost multiplier: ${TypeTag[tag]}`);
184
+ throw new InstructionExecutionError(`Invalid tag type for gas cost multiplier: ${TypeTag[tag]}`);
131
185
  }
132
186
  }
@@ -1,6 +1,6 @@
1
1
  import { type Fr } from '@aztec/circuits.js';
2
2
 
3
- import { type GasCost, GasDimensions } from './avm_gas_cost.js';
3
+ import { type Gas, GasDimensions } from './avm_gas.js';
4
4
  import { TaggedMemory } from './avm_memory_types.js';
5
5
  import { AvmContractCallResults } from './avm_message_call_result.js';
6
6
  import { OutOfGasError } from './errors.js';
@@ -59,7 +59,7 @@ export class AvmMachineState {
59
59
  * Should any of the gas dimensions get depleted, it sets all gas left to zero and triggers
60
60
  * an exceptional halt by throwing an OutOfGasError.
61
61
  */
62
- public consumeGas(gasCost: Partial<GasCost>) {
62
+ public consumeGas(gasCost: Partial<Gas>) {
63
63
  // Assert there is enough gas on every dimension.
64
64
  const outOfGasDimensions = GasDimensions.filter(
65
65
  dimension => this[`${dimension}Left`] - (gasCost[dimension] ?? 0) < 0,
@@ -76,6 +76,13 @@ export class AvmMachineState {
76
76
  }
77
77
  }
78
78
 
79
+ /** Increases the gas left by the amounts specified. */
80
+ public refundGas(gasRefund: Partial<Gas>) {
81
+ for (const dimension of GasDimensions) {
82
+ this[`${dimension}Left`] += gasRefund[dimension] ?? 0;
83
+ }
84
+ }
85
+
79
86
  /**
80
87
  * Most instructions just increment PC before they complete
81
88
  */