@aztec/simulator 0.41.0 → 0.43.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 (243) hide show
  1. package/dest/acvm/acvm.d.ts +2 -2
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/acvm.js +3 -3
  4. package/dest/acvm/oracle/oracle.d.ts +7 -4
  5. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/oracle.js +32 -12
  7. package/dest/acvm/oracle/typed_oracle.d.ts +6 -3
  8. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  9. package/dest/acvm/oracle/typed_oracle.js +15 -6
  10. package/dest/acvm/serialize.js +2 -2
  11. package/dest/avm/avm_gas.d.ts +1 -5
  12. package/dest/avm/avm_gas.d.ts.map +1 -1
  13. package/dest/avm/avm_gas.js +69 -73
  14. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  15. package/dest/avm/avm_memory_types.js +2 -4
  16. package/dest/avm/avm_simulator.d.ts +5 -0
  17. package/dest/avm/avm_simulator.d.ts.map +1 -1
  18. package/dest/avm/avm_simulator.js +8 -1
  19. package/dest/avm/fixtures/index.d.ts +6 -0
  20. package/dest/avm/fixtures/index.d.ts.map +1 -1
  21. package/dest/avm/fixtures/index.js +18 -1
  22. package/dest/avm/index.d.ts +2 -0
  23. package/dest/avm/index.d.ts.map +1 -0
  24. package/dest/avm/index.js +2 -0
  25. package/dest/avm/journal/host_storage.d.ts +1 -1
  26. package/dest/avm/journal/host_storage.d.ts.map +1 -1
  27. package/dest/avm/journal/journal.d.ts +5 -3
  28. package/dest/avm/journal/journal.d.ts.map +1 -1
  29. package/dest/avm/journal/journal.js +23 -14
  30. package/dest/avm/journal/trace.d.ts +3 -1
  31. package/dest/avm/journal/trace.d.ts.map +1 -1
  32. package/dest/avm/journal/trace.js +8 -1
  33. package/dest/avm/journal/trace_types.d.ts +5 -0
  34. package/dest/avm/journal/trace_types.d.ts.map +1 -1
  35. package/dest/avm/journal/trace_types.js +1 -5
  36. package/dest/avm/opcodes/accrued_substate.d.ts +2 -2
  37. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  38. package/dest/avm/opcodes/accrued_substate.js +36 -21
  39. package/dest/avm/opcodes/arithmetic.d.ts +1 -7
  40. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  41. package/dest/avm/opcodes/arithmetic.js +12 -20
  42. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  43. package/dest/avm/opcodes/bitwise.js +11 -8
  44. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  45. package/dest/avm/opcodes/comparators.js +7 -5
  46. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  47. package/dest/avm/opcodes/contract.js +20 -24
  48. package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
  49. package/dest/avm/opcodes/control_flow.js +4 -2
  50. package/dest/avm/opcodes/conversion.js +2 -2
  51. package/dest/avm/opcodes/ec_add.d.ts +19 -0
  52. package/dest/avm/opcodes/ec_add.d.ts.map +1 -0
  53. package/dest/avm/opcodes/ec_add.js +78 -0
  54. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  55. package/dest/avm/opcodes/external_calls.js +11 -5
  56. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  57. package/dest/avm/opcodes/hashing.js +10 -2
  58. package/dest/avm/opcodes/instruction.d.ts +1 -1
  59. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  60. package/dest/avm/opcodes/instruction.js +6 -4
  61. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  62. package/dest/avm/opcodes/instruction_impl.js +4 -2
  63. package/dest/avm/opcodes/memory.d.ts +1 -5
  64. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  65. package/dest/avm/opcodes/memory.js +14 -18
  66. package/dest/avm/opcodes/multi_scalar_mul.d.ts +16 -0
  67. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -0
  68. package/dest/avm/opcodes/multi_scalar_mul.js +95 -0
  69. package/dest/avm/opcodes/storage.d.ts +1 -6
  70. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  71. package/dest/avm/opcodes/storage.js +11 -14
  72. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  73. package/dest/avm/serialization/bytecode_serialization.js +6 -2
  74. package/dest/avm/serialization/instruction_serialization.d.ts +3 -1
  75. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  76. package/dest/avm/serialization/instruction_serialization.js +4 -2
  77. package/dest/client/client_execution_context.d.ts +24 -20
  78. package/dest/client/client_execution_context.d.ts.map +1 -1
  79. package/dest/client/client_execution_context.js +52 -55
  80. package/dest/client/db_oracle.d.ts +7 -1
  81. package/dest/client/db_oracle.d.ts.map +1 -1
  82. package/dest/client/execution_note_cache.d.ts +0 -17
  83. package/dest/client/execution_note_cache.d.ts.map +1 -1
  84. package/dest/client/execution_note_cache.js +1 -24
  85. package/dest/client/execution_result.d.ts +8 -4
  86. package/dest/client/execution_result.d.ts.map +1 -1
  87. package/dest/client/execution_result.js +16 -6
  88. package/dest/client/private_execution.d.ts +2 -3
  89. package/dest/client/private_execution.d.ts.map +1 -1
  90. package/dest/client/private_execution.js +20 -9
  91. package/dest/client/simulator.d.ts +2 -17
  92. package/dest/client/simulator.d.ts.map +1 -1
  93. package/dest/client/simulator.js +24 -33
  94. package/dest/client/unconstrained_execution.d.ts +2 -3
  95. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  96. package/dest/client/unconstrained_execution.js +5 -7
  97. package/dest/client/view_data_oracle.d.ts +2 -0
  98. package/dest/client/view_data_oracle.d.ts.map +1 -1
  99. package/dest/client/view_data_oracle.js +7 -1
  100. package/dest/index.d.ts +3 -1
  101. package/dest/index.d.ts.map +1 -1
  102. package/dest/index.js +4 -2
  103. package/dest/mocks/fixtures.d.ts +14 -10
  104. package/dest/mocks/fixtures.d.ts.map +1 -1
  105. package/dest/mocks/fixtures.js +22 -16
  106. package/dest/{simulator → providers}/acvm_native.d.ts.map +1 -1
  107. package/dest/{simulator → providers}/acvm_native.js +13 -14
  108. package/dest/providers/acvm_wasm.d.ts.map +1 -0
  109. package/dest/providers/acvm_wasm.js +15 -0
  110. package/dest/providers/index.d.ts.map +1 -0
  111. package/dest/{simulator → providers}/index.js +1 -1
  112. package/dest/{simulator → providers}/simulation_provider.d.ts.map +1 -1
  113. package/dest/{simulator → providers}/simulation_provider.js +1 -1
  114. package/dest/public/abstract_phase_manager.d.ts +53 -53
  115. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  116. package/dest/public/abstract_phase_manager.js +146 -153
  117. package/dest/public/app_logic_phase_manager.d.ts +8 -9
  118. package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
  119. package/dest/public/app_logic_phase_manager.js +15 -15
  120. package/dest/public/{db.d.ts → db_interfaces.d.ts} +4 -3
  121. package/dest/public/db_interfaces.d.ts.map +1 -0
  122. package/dest/public/db_interfaces.js +2 -0
  123. package/dest/public/execution.d.ts +16 -23
  124. package/dest/public/execution.d.ts.map +1 -1
  125. package/dest/public/execution.js +1 -51
  126. package/dest/public/executor.d.ts +4 -31
  127. package/dest/public/executor.d.ts.map +1 -1
  128. package/dest/public/executor.js +40 -283
  129. package/dest/public/fee_payment.d.ts +11 -0
  130. package/dest/public/fee_payment.d.ts.map +1 -0
  131. package/dest/public/fee_payment.js +24 -0
  132. package/dest/public/hints_builder.d.ts +2 -1
  133. package/dest/public/hints_builder.d.ts.map +1 -1
  134. package/dest/public/hints_builder.js +6 -2
  135. package/dest/public/index.d.ts +8 -6
  136. package/dest/public/index.d.ts.map +1 -1
  137. package/dest/public/index.js +9 -7
  138. package/dest/public/phase_manager_factory.d.ts +4 -4
  139. package/dest/public/phase_manager_factory.d.ts.map +1 -1
  140. package/dest/public/phase_manager_factory.js +5 -5
  141. package/dest/public/{public_executor.d.ts → public_db_sources.d.ts} +6 -3
  142. package/dest/public/public_db_sources.d.ts.map +1 -0
  143. package/dest/public/public_db_sources.js +244 -0
  144. package/dest/public/public_kernel.js +14 -14
  145. package/dest/public/public_processor.d.ts +6 -4
  146. package/dest/public/public_processor.d.ts.map +1 -1
  147. package/dest/public/public_processor.js +48 -30
  148. package/dest/public/setup_phase_manager.d.ts +8 -10
  149. package/dest/public/setup_phase_manager.d.ts.map +1 -1
  150. package/dest/public/setup_phase_manager.js +12 -21
  151. package/dest/public/tail_phase_manager.d.ts +7 -13
  152. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  153. package/dest/public/tail_phase_manager.js +17 -37
  154. package/dest/public/teardown_phase_manager.d.ts +8 -10
  155. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  156. package/dest/public/teardown_phase_manager.js +16 -22
  157. package/dest/public/transitional_adaptors.d.ts +2 -2
  158. package/dest/public/transitional_adaptors.d.ts.map +1 -1
  159. package/dest/public/transitional_adaptors.js +14 -6
  160. package/package.json +12 -9
  161. package/src/acvm/acvm.ts +0 -3
  162. package/src/acvm/oracle/oracle.ts +68 -16
  163. package/src/acvm/oracle/typed_oracle.ts +31 -6
  164. package/src/acvm/serialize.ts +1 -1
  165. package/src/avm/avm_gas.ts +68 -73
  166. package/src/avm/avm_memory_types.ts +1 -3
  167. package/src/avm/avm_simulator.ts +9 -0
  168. package/src/avm/fixtures/index.ts +24 -0
  169. package/src/avm/index.ts +1 -0
  170. package/src/avm/journal/host_storage.ts +1 -1
  171. package/src/avm/journal/journal.ts +32 -22
  172. package/src/avm/journal/trace.ts +9 -0
  173. package/src/avm/journal/trace_types.ts +4 -0
  174. package/src/avm/opcodes/accrued_substate.ts +53 -20
  175. package/src/avm/opcodes/arithmetic.ts +18 -22
  176. package/src/avm/opcodes/bitwise.ts +13 -8
  177. package/src/avm/opcodes/comparators.ts +9 -4
  178. package/src/avm/opcodes/contract.ts +22 -26
  179. package/src/avm/opcodes/control_flow.ts +3 -1
  180. package/src/avm/opcodes/conversion.ts +1 -1
  181. package/src/avm/opcodes/ec_add.ts +92 -0
  182. package/src/avm/opcodes/external_calls.ts +11 -3
  183. package/src/avm/opcodes/hashing.ts +11 -1
  184. package/src/avm/opcodes/instruction.ts +5 -3
  185. package/src/avm/opcodes/instruction_impl.ts +4 -1
  186. package/src/avm/opcodes/memory.ts +19 -19
  187. package/src/avm/opcodes/multi_scalar_mul.ts +114 -0
  188. package/src/avm/opcodes/storage.ts +10 -17
  189. package/src/avm/serialization/bytecode_serialization.ts +5 -1
  190. package/src/avm/serialization/instruction_serialization.ts +2 -0
  191. package/src/client/client_execution_context.ts +76 -60
  192. package/src/client/db_oracle.ts +8 -1
  193. package/src/client/execution_note_cache.ts +0 -28
  194. package/src/client/execution_result.ts +21 -7
  195. package/src/client/private_execution.ts +36 -21
  196. package/src/client/simulator.ts +25 -35
  197. package/src/client/unconstrained_execution.ts +9 -12
  198. package/src/client/view_data_oracle.ts +8 -0
  199. package/src/index.ts +3 -1
  200. package/src/mocks/fixtures.ts +30 -32
  201. package/src/{simulator → providers}/acvm_native.ts +21 -19
  202. package/src/{simulator → providers}/acvm_wasm.ts +2 -16
  203. package/src/public/abstract_phase_manager.ts +209 -258
  204. package/src/public/app_logic_phase_manager.ts +24 -40
  205. package/src/public/{db.ts → db_interfaces.ts} +4 -2
  206. package/src/public/execution.ts +15 -77
  207. package/src/public/executor.ts +61 -399
  208. package/src/public/fee_payment.ts +26 -0
  209. package/src/public/hints_builder.ts +6 -0
  210. package/src/public/index.ts +8 -12
  211. package/src/public/phase_manager_factory.ts +7 -7
  212. package/src/public/{public_executor.ts → public_db_sources.ts} +65 -9
  213. package/src/public/public_kernel.ts +24 -24
  214. package/src/public/public_processor.ts +81 -40
  215. package/src/public/setup_phase_manager.ts +21 -46
  216. package/src/public/tail_phase_manager.ts +19 -67
  217. package/src/public/teardown_phase_manager.ts +23 -42
  218. package/src/public/transitional_adaptors.ts +41 -5
  219. package/dest/public/db.d.ts.map +0 -1
  220. package/dest/public/db.js +0 -2
  221. package/dest/public/public_execution_context.d.ts +0 -121
  222. package/dest/public/public_execution_context.d.ts.map +0 -1
  223. package/dest/public/public_execution_context.js +0 -214
  224. package/dest/public/public_executor.d.ts.map +0 -1
  225. package/dest/public/public_executor.js +0 -197
  226. package/dest/public/state_actions.d.ts +0 -39
  227. package/dest/public/state_actions.d.ts.map +0 -1
  228. package/dest/public/state_actions.js +0 -80
  229. package/dest/public/utils.d.ts +0 -8
  230. package/dest/public/utils.d.ts.map +0 -1
  231. package/dest/public/utils.js +0 -31
  232. package/dest/simulator/acvm_wasm.d.ts.map +0 -1
  233. package/dest/simulator/acvm_wasm.js +0 -22
  234. package/dest/simulator/index.d.ts.map +0 -1
  235. package/src/public/public_execution_context.ts +0 -289
  236. package/src/public/state_actions.ts +0 -102
  237. package/src/public/utils.ts +0 -33
  238. /package/dest/{simulator → providers}/acvm_native.d.ts +0 -0
  239. /package/dest/{simulator → providers}/acvm_wasm.d.ts +0 -0
  240. /package/dest/{simulator → providers}/index.d.ts +0 -0
  241. /package/dest/{simulator → providers}/simulation_provider.d.ts +0 -0
  242. /package/src/{simulator → providers}/index.ts +0 -0
  243. /package/src/{simulator → providers}/simulation_provider.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
- import { Uint8 } from '../avm_memory_types.js';
2
+ import { TypeTag, Uint8 } from '../avm_memory_types.js';
3
3
  import { InstructionExecutionError, StaticCallAlterationError } from '../errors.js';
4
4
  import { NullifierCollisionError } from '../journal/nullifiers.js';
5
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
@@ -31,17 +31,22 @@ export class NoteHashExists extends Instruction {
31
31
  const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
32
32
  const memory = context.machineState.memory.track(this.type);
33
33
  context.machineState.consumeGas(this.gasCost(memoryOperations));
34
+ const [noteHashOffset, leafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
35
+ [this.noteHashOffset, this.leafIndexOffset, this.existsOffset],
36
+ memory,
37
+ );
38
+ memory.checkTags(TypeTag.FIELD, noteHashOffset, leafIndexOffset);
34
39
 
35
40
  // Note that this instruction accepts any type in memory, and converts to Field.
36
- const noteHash = memory.get(this.noteHashOffset).toFr();
37
- const leafIndex = memory.get(this.leafIndexOffset).toFr();
41
+ const noteHash = memory.get(noteHashOffset).toFr();
42
+ const leafIndex = memory.get(leafIndexOffset).toFr();
38
43
 
39
44
  const exists = await context.persistableState.checkNoteHashExists(
40
45
  context.environment.storageAddress,
41
46
  noteHash,
42
47
  leafIndex,
43
48
  );
44
- memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
49
+ memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
45
50
 
46
51
  memory.assert(memoryOperations);
47
52
  context.machineState.incrementPc();
@@ -63,11 +68,14 @@ export class EmitNoteHash extends Instruction {
63
68
  const memory = context.machineState.memory.track(this.type);
64
69
  context.machineState.consumeGas(this.gasCost(memoryOperations));
65
70
 
71
+ const [noteHashOffset] = Addressing.fromWire(this.indirect).resolve([this.noteHashOffset], memory);
72
+ memory.checkTag(TypeTag.FIELD, noteHashOffset);
73
+
66
74
  if (context.environment.isStaticCall) {
67
75
  throw new StaticCallAlterationError();
68
76
  }
69
77
 
70
- const noteHash = memory.get(this.noteHashOffset).toFr();
78
+ const noteHash = memory.get(noteHashOffset).toFr();
71
79
  context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
72
80
 
73
81
  memory.assert(memoryOperations);
@@ -101,11 +109,17 @@ export class NullifierExists extends Instruction {
101
109
  const memory = context.machineState.memory.track(this.type);
102
110
  context.machineState.consumeGas(this.gasCost(memoryOperations));
103
111
 
104
- const nullifier = memory.get(this.nullifierOffset).toFr();
105
- const address = memory.get(this.addressOffset).toFr();
112
+ const [nullifierOffset, addressOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
113
+ [this.nullifierOffset, this.addressOffset, this.existsOffset],
114
+ memory,
115
+ );
116
+ memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
117
+
118
+ const nullifier = memory.get(nullifierOffset).toFr();
119
+ const address = memory.get(addressOffset).toFr();
106
120
  const exists = await context.persistableState.checkNullifierExists(address, nullifier);
107
121
 
108
- memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
122
+ memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
109
123
 
110
124
  memory.assert(memoryOperations);
111
125
  context.machineState.incrementPc();
@@ -131,7 +145,10 @@ export class EmitNullifier extends Instruction {
131
145
  const memory = context.machineState.memory.track(this.type);
132
146
  context.machineState.consumeGas(this.gasCost(memoryOperations));
133
147
 
134
- const nullifier = memory.get(this.nullifierOffset).toFr();
148
+ const [nullifierOffset] = Addressing.fromWire(this.indirect).resolve([this.nullifierOffset], memory);
149
+ memory.checkTag(TypeTag.FIELD, nullifierOffset);
150
+
151
+ const nullifier = memory.get(nullifierOffset).toFr();
135
152
  try {
136
153
  await context.persistableState.writeNullifier(context.environment.storageAddress, nullifier);
137
154
  } catch (e) {
@@ -176,10 +193,16 @@ export class L1ToL2MessageExists extends Instruction {
176
193
  const memory = context.machineState.memory.track(this.type);
177
194
  context.machineState.consumeGas(this.gasCost(memoryOperations));
178
195
 
179
- const msgHash = memory.get(this.msgHashOffset).toFr();
180
- const msgLeafIndex = memory.get(this.msgLeafIndexOffset).toFr();
196
+ const [msgHashOffset, msgLeafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
197
+ [this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset],
198
+ memory,
199
+ );
200
+ memory.checkTags(TypeTag.FIELD, msgHashOffset, msgLeafIndexOffset);
201
+
202
+ const msgHash = memory.get(msgHashOffset).toFr();
203
+ const msgLeafIndex = memory.get(msgLeafIndexOffset).toFr();
181
204
  const exists = await context.persistableState.checkL1ToL2MessageExists(msgHash, msgLeafIndex);
182
- memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
205
+ memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
183
206
 
184
207
  memory.assert(memoryOperations);
185
208
  context.machineState.incrementPc();
@@ -202,7 +225,7 @@ export class EmitUnencryptedLog extends Instruction {
202
225
  private indirect: number,
203
226
  private eventSelectorOffset: number,
204
227
  private logOffset: number,
205
- private logSize: number,
228
+ private logSizeOffset: number,
206
229
  ) {
207
230
  super();
208
231
  }
@@ -212,18 +235,23 @@ export class EmitUnencryptedLog extends Instruction {
212
235
  throw new StaticCallAlterationError();
213
236
  }
214
237
 
215
- const memoryOperations = { reads: 1 + this.logSize, indirect: this.indirect };
216
238
  const memory = context.machineState.memory.track(this.type);
217
- context.machineState.consumeGas(this.gasCost(memoryOperations));
218
239
 
219
- const [eventSelectorOffset, logOffset] = Addressing.fromWire(this.indirect).resolve(
220
- [this.eventSelectorOffset, this.logOffset],
240
+ const [eventSelectorOffset, logOffset, logSizeOffset] = Addressing.fromWire(this.indirect).resolve(
241
+ [this.eventSelectorOffset, this.logOffset, this.logSizeOffset],
221
242
  memory,
222
243
  );
244
+ memory.checkTag(TypeTag.FIELD, eventSelectorOffset);
245
+ memory.checkTag(TypeTag.UINT32, logSizeOffset);
246
+ const logSize = memory.get(logSizeOffset).toNumber();
247
+ memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
223
248
 
224
249
  const contractAddress = context.environment.address;
225
250
  const event = memory.get(eventSelectorOffset).toFr();
226
- const log = memory.getSlice(logOffset, this.logSize).map(f => f.toFr());
251
+
252
+ const memoryOperations = { reads: 2 + logSize, indirect: this.indirect };
253
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
254
+ const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
227
255
  context.persistableState.writeLog(contractAddress, event, log);
228
256
 
229
257
  memory.assert(memoryOperations);
@@ -250,8 +278,13 @@ export class SendL2ToL1Message extends Instruction {
250
278
  const memory = context.machineState.memory.track(this.type);
251
279
  context.machineState.consumeGas(this.gasCost(memoryOperations));
252
280
 
253
- const recipient = memory.get(this.recipientOffset).toFr();
254
- const content = memory.get(this.contentOffset).toFr();
281
+ const [recipientOffset, contentOffset] = Addressing.fromWire(this.indirect).resolve(
282
+ [this.recipientOffset, this.contentOffset],
283
+ memory,
284
+ );
285
+
286
+ const recipient = memory.get(recipientOffset).toFr();
287
+ const content = memory.get(contentOffset).toFr();
255
288
  context.persistableState.writeL1Message(recipient, content);
256
289
 
257
290
  memory.assert(memoryOperations);
@@ -1,7 +1,7 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
- import { getBaseGasCost, getGasCostForTypeTag, getMemoryGasCost, sumGas } from '../avm_gas.js';
3
- import { type Field, type MemoryOperations, type MemoryValue, TypeTag } from '../avm_memory_types.js';
2
+ import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js';
4
3
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
4
+ import { Addressing } from './addressing_mode.js';
5
5
  import { Instruction } from './instruction.js';
6
6
  import { ThreeOperandInstruction } from './instruction_impl.js';
7
7
 
@@ -11,24 +11,22 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
11
11
  const memory = context.machineState.memory.track(this.type);
12
12
  context.machineState.consumeGas(this.gasCost(memoryOperations));
13
13
 
14
- memory.checkTags(this.inTag, this.aOffset, this.bOffset);
14
+ const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
15
+ [this.aOffset, this.bOffset, this.dstOffset],
16
+ memory,
17
+ );
18
+ memory.checkTags(this.inTag, aOffset, bOffset);
15
19
 
16
- const a = memory.get(this.aOffset);
17
- const b = memory.get(this.bOffset);
20
+ const a = memory.get(aOffset);
21
+ const b = memory.get(bOffset);
18
22
 
19
23
  const dest = this.compute(a, b);
20
- memory.set(this.dstOffset, dest);
24
+ memory.set(dstOffset, dest);
21
25
 
22
26
  memory.assert(memoryOperations);
23
27
  context.machineState.incrementPc();
24
28
  }
25
29
 
26
- protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
27
- const baseGasCost = getGasCostForTypeTag(this.inTag, getBaseGasCost(this.opcode));
28
- const memoryGasCost = getMemoryGasCost(memoryOps);
29
- return sumGas(baseGasCost, memoryGasCost);
30
- }
31
-
32
30
  protected abstract compute(a: MemoryValue, b: MemoryValue): MemoryValue;
33
31
  }
34
32
 
@@ -90,21 +88,19 @@ export class FieldDiv extends Instruction {
90
88
  const memory = context.machineState.memory.track(this.type);
91
89
  context.machineState.consumeGas(this.gasCost(memoryOperations));
92
90
 
93
- memory.checkTags(TypeTag.FIELD, this.aOffset, this.bOffset);
91
+ const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
92
+ [this.aOffset, this.bOffset, this.dstOffset],
93
+ memory,
94
+ );
95
+ memory.checkTags(TypeTag.FIELD, aOffset, bOffset);
94
96
 
95
- const a = memory.getAs<Field>(this.aOffset);
96
- const b = memory.getAs<Field>(this.bOffset);
97
+ const a = memory.getAs<Field>(aOffset);
98
+ const b = memory.getAs<Field>(bOffset);
97
99
 
98
100
  const dest = a.fdiv(b);
99
- memory.set(this.dstOffset, dest);
101
+ memory.set(dstOffset, dest);
100
102
 
101
103
  memory.assert(memoryOperations);
102
104
  context.machineState.incrementPc();
103
105
  }
104
-
105
- protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
106
- const baseGasCost = getGasCostForTypeTag(TypeTag.FIELD, getBaseGasCost(this.opcode));
107
- const memoryGasCost = getMemoryGasCost(memoryOps);
108
- return sumGas(baseGasCost, memoryGasCost);
109
- }
110
106
  }
@@ -1,6 +1,7 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
2
  import { type IntegralValue, type TaggedMemoryInterface, TypeTag } from '../avm_memory_types.js';
3
3
  import { Opcode } from '../serialization/instruction_serialization.js';
4
+ import { Addressing } from './addressing_mode.js';
4
5
  import { ThreeOperandInstruction, TwoOperandInstruction } from './instruction_impl.js';
5
6
 
6
7
  abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
@@ -9,13 +10,17 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
9
10
  const memory = context.machineState.memory.track(this.type);
10
11
  context.machineState.consumeGas(this.gasCost(memoryOperations));
11
12
 
12
- this.checkTags(memory, this.inTag, this.aOffset, this.bOffset);
13
+ const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
14
+ [this.aOffset, this.bOffset, this.dstOffset],
15
+ memory,
16
+ );
17
+ this.checkTags(memory, this.inTag, aOffset, bOffset);
13
18
 
14
- const a = memory.getAs<IntegralValue>(this.aOffset);
15
- const b = memory.getAs<IntegralValue>(this.bOffset);
19
+ const a = memory.getAs<IntegralValue>(aOffset);
20
+ const b = memory.getAs<IntegralValue>(bOffset);
16
21
 
17
22
  const res = this.compute(a, b);
18
- memory.set(this.dstOffset, res);
23
+ memory.set(dstOffset, res);
19
24
 
20
25
  memory.assert(memoryOperations);
21
26
  context.machineState.incrementPc();
@@ -93,12 +98,12 @@ export class Not extends TwoOperandInstruction {
93
98
  const memory = context.machineState.memory.track(this.type);
94
99
  context.machineState.consumeGas(this.gasCost(memoryOperations));
95
100
 
96
- memory.checkTags(this.inTag, this.aOffset);
97
-
98
- const a = memory.getAs<IntegralValue>(this.aOffset);
101
+ const [aOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.dstOffset], memory);
102
+ memory.checkTags(this.inTag, aOffset);
103
+ const a = memory.getAs<IntegralValue>(aOffset);
99
104
 
100
105
  const res = a.not();
101
- memory.set(this.dstOffset, res);
106
+ memory.set(dstOffset, res);
102
107
 
103
108
  memory.assert(memoryOperations);
104
109
  context.machineState.incrementPc();
@@ -1,6 +1,7 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
2
  import { type MemoryValue, Uint8 } from '../avm_memory_types.js';
3
3
  import { Opcode } from '../serialization/instruction_serialization.js';
4
+ import { Addressing } from './addressing_mode.js';
4
5
  import { ThreeOperandInstruction } from './instruction_impl.js';
5
6
 
6
7
  abstract class ComparatorInstruction extends ThreeOperandInstruction {
@@ -9,13 +10,17 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
9
10
  const memory = context.machineState.memory.track(this.type);
10
11
  context.machineState.consumeGas(this.gasCost(memoryOperations));
11
12
 
12
- memory.checkTags(this.inTag, this.aOffset, this.bOffset);
13
+ const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
14
+ [this.aOffset, this.bOffset, this.dstOffset],
15
+ memory,
16
+ );
17
+ memory.checkTags(this.inTag, aOffset, bOffset);
13
18
 
14
- const a = memory.get(this.aOffset);
15
- const b = memory.get(this.bOffset);
19
+ const a = memory.get(aOffset);
20
+ const b = memory.get(bOffset);
16
21
 
17
22
  const dest = new Uint8(this.compare(a, b) ? 1 : 0);
18
- memory.set(this.dstOffset, dest);
23
+ memory.set(dstOffset, dest);
19
24
 
20
25
  memory.assert(memoryOperations);
21
26
  context.machineState.incrementPc();
@@ -1,7 +1,7 @@
1
- import { AztecAddress, Fr } from '@aztec/circuits.js';
1
+ import { Fr } from '@aztec/circuits.js';
2
2
 
3
3
  import type { AvmContext } from '../avm_context.js';
4
- import { Field } from '../avm_memory_types.js';
4
+ import { Field, TypeTag } from '../avm_memory_types.js';
5
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
6
  import { Addressing } from './addressing_mode.js';
7
7
  import { Instruction } from './instruction.js';
@@ -22,35 +22,31 @@ export class GetContractInstance extends Instruction {
22
22
  }
23
23
 
24
24
  async execute(context: AvmContext): Promise<void> {
25
+ const memoryOperations = { reads: 1, writes: 6, indirect: this.indirect };
26
+ const memory = context.machineState.memory.track(this.type);
27
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
28
+
25
29
  const [addressOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
26
30
  [this.addressOffset, this.dstOffset],
27
- context.machineState.memory,
31
+ memory,
28
32
  );
33
+ memory.checkTag(TypeTag.FIELD, addressOffset);
34
+
35
+ const address = memory.get(addressOffset).toFr();
36
+ const instance = await context.persistableState.getContractInstance(address);
37
+
38
+ const data = [
39
+ new Fr(instance.exists),
40
+ instance.salt,
41
+ instance.deployer.toField(),
42
+ instance.contractClassId,
43
+ instance.initializationHash,
44
+ instance.publicKeysHash,
45
+ ].map(f => new Field(f));
29
46
 
30
- const address = AztecAddress.fromField(context.machineState.memory.get(addressOffset).toFr());
31
- const instance = await context.persistableState.hostStorage.contractsDb.getContractInstance(address);
32
-
33
- const data =
34
- instance === undefined
35
- ? [
36
- new Field(0), // not found
37
- new Field(0),
38
- new Field(0),
39
- new Field(0),
40
- new Field(0),
41
- new Field(0),
42
- ]
43
- : [
44
- new Fr(1), // found
45
- instance.salt,
46
- instance.deployer.toField(),
47
- instance.contractClassId,
48
- instance.initializationHash,
49
- instance.publicKeysHash,
50
- ].map(f => new Field(f));
51
-
52
- context.machineState.memory.setSlice(dstOffset, data);
47
+ memory.setSlice(dstOffset, data);
53
48
 
49
+ memory.assert(memoryOperations);
54
50
  context.machineState.incrementPc();
55
51
  }
56
52
  }
@@ -2,6 +2,7 @@ import type { AvmContext } from '../avm_context.js';
2
2
  import { type IntegralValue } from '../avm_memory_types.js';
3
3
  import { InstructionExecutionError } from '../errors.js';
4
4
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
5
+ import { Addressing } from './addressing_mode.js';
5
6
  import { Instruction } from './instruction.js';
6
7
 
7
8
  export class Jump extends Instruction {
@@ -44,7 +45,8 @@ export class JumpI extends Instruction {
44
45
  const memory = context.machineState.memory.track(this.type);
45
46
  context.machineState.consumeGas(this.gasCost(memoryOperations));
46
47
 
47
- const condition = memory.getAs<IntegralValue>(this.condOffset);
48
+ const [condOffset] = Addressing.fromWire(this.indirect).resolve([this.condOffset], memory);
49
+ const condition = memory.getAs<IntegralValue>(condOffset);
48
50
 
49
51
  // TODO: reconsider this casting
50
52
  if (condition.toBigInt() == 0n) {
@@ -50,7 +50,7 @@ export class ToRadixLE extends Instruction {
50
50
  value /= radixBN;
51
51
  }
52
52
 
53
- const res = [...limbArray].map(byte => new Uint8(byte));
53
+ const res = limbArray.map(byte => new Uint8(byte));
54
54
  memory.setSlice(dstOffset, res);
55
55
 
56
56
  memory.assert(memoryOperations);
@@ -0,0 +1,92 @@
1
+ import { Grumpkin } from '@aztec/circuits.js/barretenberg';
2
+ import { Point } from '@aztec/foundation/fields';
3
+
4
+ import { type AvmContext } from '../avm_context.js';
5
+ import { Field } from '../avm_memory_types.js';
6
+ import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
7
+ import { Addressing } from './addressing_mode.js';
8
+ import { Instruction } from './instruction.js';
9
+
10
+ export class EcAdd extends Instruction {
11
+ static type: string = 'ECADD';
12
+ static readonly opcode = Opcode.ECADD;
13
+
14
+ // Informs (de)serialization. See Instruction.deserialize.
15
+ static readonly wireFormat: OperandType[] = [
16
+ OperandType.UINT8, // reserved
17
+ OperandType.UINT8, // indirect
18
+ OperandType.UINT32, // p1X
19
+ OperandType.UINT32, // p1Y
20
+ OperandType.UINT32, // p1IsInfinite
21
+ OperandType.UINT32, // p2X
22
+ OperandType.UINT32, // p2Y
23
+ OperandType.UINT32, // p2IsInfinite
24
+ OperandType.UINT32, // dst
25
+ ];
26
+
27
+ constructor(
28
+ private indirect: number,
29
+ private p1XOffset: number,
30
+ private p1YOffset: number,
31
+ private p1IsInfiniteOffset: number,
32
+ private p2XOffset: number,
33
+ private p2YOffset: number,
34
+ private p2IsInfiniteOffset: number,
35
+ private dstOffset: number,
36
+ ) {
37
+ super();
38
+ }
39
+
40
+ public async execute(context: AvmContext): Promise<void> {
41
+ const memoryOperations = { reads: 6, writes: 3, indirect: this.indirect };
42
+ const memory = context.machineState.memory.track(this.type);
43
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
44
+
45
+ const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] =
46
+ Addressing.fromWire(this.indirect).resolve(
47
+ [
48
+ this.p1XOffset,
49
+ this.p1YOffset,
50
+ this.p1IsInfiniteOffset,
51
+ this.p2XOffset,
52
+ this.p2YOffset,
53
+ this.p2IsInfiniteOffset,
54
+ this.dstOffset,
55
+ ],
56
+ memory,
57
+ );
58
+
59
+ const p1X = memory.get(p1XOffset);
60
+ const p1Y = memory.get(p1YOffset);
61
+ const p1IsInfinite = memory.get(p1IsInfiniteOffset).toNumber() === 1;
62
+ const p1 = new Point(p1X.toFr(), p1Y.toFr());
63
+ if (!p1.isOnGrumpkin()) {
64
+ throw new Error(`Point1 is not on the curve`);
65
+ }
66
+
67
+ const p2X = memory.get(p2XOffset);
68
+ const p2Y = memory.get(p2YOffset);
69
+ // unused. Point doesn't store this information
70
+ const p2IsInfinite = memory.get(p2IsInfiniteOffset).toNumber() === 1;
71
+ const p2 = new Point(p2X.toFr(), p2Y.toFr());
72
+ if (!p2.isOnGrumpkin()) {
73
+ throw new Error(`Point1 is not on the curve`);
74
+ }
75
+
76
+ const grumpkin = new Grumpkin();
77
+ let dest = grumpkin.add(p1, p2);
78
+ // Temporary,
79
+ if (p1IsInfinite) {
80
+ dest = p2;
81
+ } else if (p2IsInfinite) {
82
+ dest = p1;
83
+ }
84
+ memory.set(dstOffset, new Field(dest.x));
85
+ memory.set(dstOffset + 1, new Field(dest.y));
86
+ // Check representation of infinity for grumpkin
87
+ memory.set(dstOffset + 2, new Field(dest.equals(Point.ZERO) ? 1 : 0));
88
+
89
+ memory.assert(memoryOperations);
90
+ context.machineState.incrementPc();
91
+ }
92
+ }
@@ -4,7 +4,7 @@ import { padArrayEnd } from '@aztec/foundation/collection';
4
4
  import { convertAvmResultsToPxResult, createPublicExecution } from '../../public/transitional_adaptors.js';
5
5
  import type { AvmContext } from '../avm_context.js';
6
6
  import { gasLeftToGas } from '../avm_gas.js';
7
- import { Field, Uint8 } from '../avm_memory_types.js';
7
+ import { Field, TypeTag, Uint8 } from '../avm_memory_types.js';
8
8
  import { type AvmContractCallResults } from '../avm_message_call_result.js';
9
9
  import { AvmSimulator } from '../avm_simulator.js';
10
10
  import { RethrownError } from '../errors.js';
@@ -53,9 +53,15 @@ abstract class ExternalCall extends Instruction {
53
53
  [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.retOffset, this.successOffset],
54
54
  memory,
55
55
  );
56
+ memory.checkTags(TypeTag.FIELD, gasOffset, gasOffset + 1);
57
+ memory.checkTag(TypeTag.FIELD, addrOffset);
58
+ memory.checkTag(TypeTag.UINT32, argsSizeOffset);
59
+ memory.checkTag(TypeTag.FIELD, this.functionSelectorOffset);
56
60
 
57
- const callAddress = memory.getAs<Field>(addrOffset);
58
61
  const calldataSize = memory.get(argsSizeOffset).toNumber();
62
+ memory.checkTagsRange(TypeTag.FIELD, argsOffset, calldataSize);
63
+
64
+ const callAddress = memory.getAs<Field>(addrOffset);
59
65
  const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
60
66
  const functionSelector = memory.getAs<Field>(this.functionSelectorOffset).toFr();
61
67
  // If we are already in a static call, we propagate the environment.
@@ -86,13 +92,15 @@ abstract class ExternalCall extends Instruction {
86
92
  const startSideEffectCounter = nestedContext.persistableState.trace.accessCounter;
87
93
 
88
94
  const oldStyleExecution = createPublicExecution(startSideEffectCounter, nestedContext.environment, calldata);
89
- const nestedCallResults: AvmContractCallResults = await new AvmSimulator(nestedContext).execute();
95
+ const simulator = new AvmSimulator(nestedContext);
96
+ const nestedCallResults: AvmContractCallResults = await simulator.execute();
90
97
  const pxResults = convertAvmResultsToPxResult(
91
98
  nestedCallResults,
92
99
  startSideEffectCounter,
93
100
  oldStyleExecution,
94
101
  Gas.from(allocatedGas),
95
102
  nestedContext,
103
+ simulator.getBytecode(),
96
104
  );
97
105
  // store the old PublicExecutionResult object to maintain a recursive data structure for the old kernel
98
106
  context.persistableState.transitionalExecutionResult.nestedExecutions.push(pxResults);
@@ -1,7 +1,7 @@
1
1
  import { keccak256, pedersenHash, poseidon2Permutation, sha256 } from '@aztec/foundation/crypto';
2
2
 
3
3
  import { type AvmContext } from '../avm_context.js';
4
- import { Field, Uint8 } from '../avm_memory_types.js';
4
+ import { Field, TypeTag, Uint8 } from '../avm_memory_types.js';
5
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
6
  import { Addressing } from './addressing_mode.js';
7
7
  import { Instruction } from './instruction.js';
@@ -32,6 +32,7 @@ export class Poseidon2 extends Instruction {
32
32
  [this.inputStateOffset, this.outputStateOffset],
33
33
  memory,
34
34
  );
35
+ memory.checkTagsRange(TypeTag.FIELD, inputOffset, Poseidon2.stateSize);
35
36
 
36
37
  const inputState = memory.getSlice(inputOffset, Poseidon2.stateSize);
37
38
  const outputState = poseidon2Permutation(inputState);
@@ -74,10 +75,13 @@ export class Keccak extends Instruction {
74
75
  [this.dstOffset, this.messageOffset, this.messageSizeOffset],
75
76
  memory,
76
77
  );
78
+ memory.checkTag(TypeTag.UINT32, messageSizeOffset);
77
79
  const messageSize = memory.get(messageSizeOffset).toNumber();
78
80
  const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
79
81
  context.machineState.consumeGas(this.gasCost(memoryOperations));
80
82
 
83
+ memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize);
84
+
81
85
  const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
82
86
  const hashBuffer = keccak256(messageData);
83
87
 
@@ -119,9 +123,11 @@ export class Sha256 extends Instruction {
119
123
  [this.dstOffset, this.messageOffset, this.messageSizeOffset],
120
124
  memory,
121
125
  );
126
+ memory.checkTag(TypeTag.UINT32, messageSizeOffset);
122
127
  const messageSize = memory.get(messageSizeOffset).toNumber();
123
128
  const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
124
129
  context.machineState.consumeGas(this.gasCost(memoryOperations));
130
+ memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize);
125
131
 
126
132
  const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
127
133
  const hashBuffer = sha256(messageData);
@@ -168,12 +174,16 @@ export class Pedersen extends Instruction {
168
174
 
169
175
  // We hash a set of field elements
170
176
  const genIndex = Number(memory.get(genIndexOffset).toBigInt());
177
+ memory.checkTag(TypeTag.UINT32, genIndexOffset);
171
178
  const messageSize = Number(memory.get(messageSizeOffset).toBigInt());
179
+ memory.checkTag(TypeTag.UINT32, messageSizeOffset);
172
180
  const hashData = memory.getSlice(messageOffset, messageSize);
173
181
 
174
182
  const memoryOperations = { reads: messageSize + 2, writes: 1, indirect: this.indirect };
175
183
  context.machineState.consumeGas(this.gasCost(memoryOperations));
176
184
 
185
+ memory.checkTagsRange(TypeTag.FIELD, messageOffset, messageSize);
186
+
177
187
  // No domain sep for now
178
188
  const hash = pedersenHash(hashData, genIndex);
179
189
  memory.set(dstOffset, new Field(hash));
@@ -1,7 +1,7 @@
1
1
  import { strict as assert } from 'assert';
2
2
 
3
3
  import type { AvmContext } from '../avm_context.js';
4
- import { getBaseGasCost, getMemoryGasCost, sumGas } from '../avm_gas.js';
4
+ import { getBaseGasCost, sumGas } from '../avm_gas.js';
5
5
  import { type MemoryOperations } from '../avm_memory_types.js';
6
6
  import { type BufferCursor } from '../serialization/buffer_cursor.js';
7
7
  import { Opcode, type OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
@@ -67,9 +67,11 @@ export abstract class Instruction {
67
67
  * @param memoryOps Memory operations performed by the instruction.
68
68
  * @returns Gas cost.
69
69
  */
70
- protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
70
+ protected gasCost(_memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
71
71
  const baseGasCost = getBaseGasCost(this.opcode);
72
- const memoryGasCost = getMemoryGasCost(memoryOps);
72
+ // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6861): reconsider.
73
+ // const memoryGasCost = getMemoryGasCost(memoryOps);
74
+ const memoryGasCost = { l2Gas: 0, daGas: 0 };
73
75
  return sumGas(baseGasCost, memoryGasCost);
74
76
  }
75
77
 
@@ -1,6 +1,7 @@
1
1
  import { type AvmContext } from '../avm_context.js';
2
2
  import { type MemoryValue } from '../avm_memory_types.js';
3
3
  import { OperandType } from '../serialization/instruction_serialization.js';
4
+ import { Addressing } from './addressing_mode.js';
4
5
  import { Instruction } from './instruction.js';
5
6
 
6
7
  /** Wire format that informs deserialization for instructions with two operands. */
@@ -72,7 +73,9 @@ export abstract class GetterInstruction extends Instruction {
72
73
  const memory = context.machineState.memory.track(this.type);
73
74
  context.machineState.consumeGas(this.gasCost(memoryOperations));
74
75
 
75
- memory.set(this.dstOffset, this.getValue(context));
76
+ const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], memory);
77
+
78
+ memory.set(dstOffset, this.getValue(context));
76
79
 
77
80
  memory.assert(memoryOperations);
78
81
  context.machineState.incrementPc();