@aztec/simulator 0.56.0 → 0.58.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 (205) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +2 -5
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +7 -38
  4. package/dest/acvm/oracle/typed_oracle.d.ts +4 -8
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +1 -10
  7. package/dest/avm/avm_execution_environment.d.ts +2 -3
  8. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  9. package/dest/avm/avm_execution_environment.js +3 -4
  10. package/dest/avm/avm_gas.d.ts.map +1 -1
  11. package/dest/avm/avm_gas.js +2 -3
  12. package/dest/avm/avm_memory_types.d.ts +10 -5
  13. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  14. package/dest/avm/avm_memory_types.js +31 -16
  15. package/dest/avm/avm_simulator.d.ts.map +1 -1
  16. package/dest/avm/avm_simulator.js +5 -2
  17. package/dest/avm/errors.d.ts +1 -1
  18. package/dest/avm/errors.d.ts.map +1 -1
  19. package/dest/avm/errors.js +12 -3
  20. package/dest/avm/fixtures/index.d.ts.map +1 -1
  21. package/dest/avm/fixtures/index.js +4 -4
  22. package/dest/avm/journal/journal.d.ts +2 -1
  23. package/dest/avm/journal/journal.d.ts.map +1 -1
  24. package/dest/avm/journal/journal.js +8 -8
  25. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  26. package/dest/avm/opcodes/accrued_substate.js +54 -47
  27. package/dest/avm/opcodes/addressing_mode.d.ts +3 -2
  28. package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -1
  29. package/dest/avm/opcodes/addressing_mode.js +25 -21
  30. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  31. package/dest/avm/opcodes/arithmetic.js +7 -6
  32. package/dest/avm/opcodes/bitwise.d.ts +3 -3
  33. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  34. package/dest/avm/opcodes/bitwise.js +19 -16
  35. package/dest/avm/opcodes/commitment.d.ts.map +1 -1
  36. package/dest/avm/opcodes/commitment.js +6 -5
  37. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  38. package/dest/avm/opcodes/comparators.js +7 -6
  39. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  40. package/dest/avm/opcodes/contract.js +8 -6
  41. package/dest/avm/opcodes/control_flow.js +7 -7
  42. package/dest/avm/opcodes/conversion.d.ts.map +1 -1
  43. package/dest/avm/opcodes/conversion.js +11 -10
  44. package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
  45. package/dest/avm/opcodes/ec_add.js +25 -15
  46. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  47. package/dest/avm/opcodes/environment_getters.js +6 -5
  48. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  49. package/dest/avm/opcodes/external_calls.js +37 -26
  50. package/dest/avm/opcodes/hashing.d.ts +1 -3
  51. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  52. package/dest/avm/opcodes/hashing.js +39 -48
  53. package/dest/avm/opcodes/instruction.d.ts +2 -6
  54. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  55. package/dest/avm/opcodes/instruction.js +3 -9
  56. package/dest/avm/opcodes/instruction_impl.d.ts +1 -2
  57. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  58. package/dest/avm/opcodes/instruction_impl.js +2 -5
  59. package/dest/avm/opcodes/memory.d.ts +0 -12
  60. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  61. package/dest/avm/opcodes/memory.js +24 -54
  62. package/dest/avm/opcodes/misc.d.ts.map +1 -1
  63. package/dest/avm/opcodes/misc.js +10 -9
  64. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
  65. package/dest/avm/opcodes/multi_scalar_mul.js +35 -20
  66. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  67. package/dest/avm/opcodes/storage.js +13 -11
  68. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  69. package/dest/avm/serialization/bytecode_serialization.js +2 -3
  70. package/dest/avm/serialization/instruction_serialization.d.ts +32 -34
  71. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  72. package/dest/avm/serialization/instruction_serialization.js +34 -37
  73. package/dest/avm/test_utils.d.ts +1 -2
  74. package/dest/avm/test_utils.d.ts.map +1 -1
  75. package/dest/avm/test_utils.js +1 -1
  76. package/dest/client/client_execution_context.d.ts +6 -30
  77. package/dest/client/client_execution_context.d.ts.map +1 -1
  78. package/dest/client/client_execution_context.js +36 -54
  79. package/dest/client/db_oracle.d.ts +1 -2
  80. package/dest/client/db_oracle.d.ts.map +1 -1
  81. package/dest/client/db_oracle.js +1 -1
  82. package/dest/client/index.d.ts +1 -1
  83. package/dest/client/index.d.ts.map +1 -1
  84. package/dest/client/index.js +2 -2
  85. package/dest/client/private_execution.d.ts +12 -3
  86. package/dest/client/private_execution.d.ts.map +1 -1
  87. package/dest/client/private_execution.js +29 -23
  88. package/dest/client/simulator.d.ts +2 -3
  89. package/dest/client/simulator.d.ts.map +1 -1
  90. package/dest/client/simulator.js +1 -1
  91. package/dest/client/view_data_oracle.d.ts +1 -2
  92. package/dest/client/view_data_oracle.d.ts.map +1 -1
  93. package/dest/client/view_data_oracle.js +1 -1
  94. package/dest/common/debug_fn_name.d.ts +4 -0
  95. package/dest/common/debug_fn_name.d.ts.map +1 -0
  96. package/dest/common/debug_fn_name.js +15 -0
  97. package/dest/common/index.d.ts +0 -1
  98. package/dest/common/index.d.ts.map +1 -1
  99. package/dest/common/index.js +1 -2
  100. package/dest/public/db_interfaces.d.ts +1 -2
  101. package/dest/public/db_interfaces.d.ts.map +1 -1
  102. package/dest/public/dual_side_effect_trace.d.ts +76 -0
  103. package/dest/public/dual_side_effect_trace.d.ts.map +1 -0
  104. package/dest/public/dual_side_effect_trace.js +109 -0
  105. package/dest/public/enqueued_call_side_effect_trace.d.ts +114 -0
  106. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -0
  107. package/dest/public/enqueued_call_side_effect_trace.js +314 -0
  108. package/dest/public/enqueued_call_simulator.d.ts +2 -2
  109. package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
  110. package/dest/public/enqueued_call_simulator.js +20 -10
  111. package/dest/public/enqueued_calls_processor.d.ts +2 -2
  112. package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
  113. package/dest/public/enqueued_calls_processor.js +3 -5
  114. package/dest/public/execution.d.ts +11 -5
  115. package/dest/public/execution.d.ts.map +1 -1
  116. package/dest/public/execution.js +13 -1
  117. package/dest/public/executor.d.ts +7 -6
  118. package/dest/public/executor.d.ts.map +1 -1
  119. package/dest/public/executor.js +24 -15
  120. package/dest/public/fee_payment.d.ts +1 -1
  121. package/dest/public/fee_payment.d.ts.map +1 -1
  122. package/dest/public/fee_payment.js +4 -7
  123. package/dest/public/hints_builder.d.ts +2 -2
  124. package/dest/public/hints_builder.d.ts.map +1 -1
  125. package/dest/public/hints_builder.js +2 -2
  126. package/dest/public/public_db_sources.d.ts +4 -5
  127. package/dest/public/public_db_sources.d.ts.map +1 -1
  128. package/dest/public/public_db_sources.js +15 -11
  129. package/dest/public/public_kernel_tail_simulator.d.ts +3 -3
  130. package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
  131. package/dest/public/public_kernel_tail_simulator.js +1 -1
  132. package/dest/public/public_processor.d.ts +7 -10
  133. package/dest/public/public_processor.d.ts.map +1 -1
  134. package/dest/public/public_processor.js +9 -10
  135. package/dest/public/side_effect_errors.d.ts +4 -0
  136. package/dest/public/side_effect_errors.d.ts.map +1 -0
  137. package/dest/public/side_effect_errors.js +7 -0
  138. package/dest/public/side_effect_trace.d.ts +3 -4
  139. package/dest/public/side_effect_trace.d.ts.map +1 -1
  140. package/dest/public/side_effect_trace.js +54 -29
  141. package/dest/public/side_effect_trace_interface.d.ts +1 -1
  142. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  143. package/package.json +12 -9
  144. package/src/acvm/oracle/oracle.ts +8 -86
  145. package/src/acvm/oracle/typed_oracle.ts +8 -33
  146. package/src/avm/avm_execution_environment.ts +1 -3
  147. package/src/avm/avm_gas.ts +1 -2
  148. package/src/avm/avm_memory_types.ts +38 -16
  149. package/src/avm/avm_simulator.ts +7 -1
  150. package/src/avm/errors.ts +11 -3
  151. package/src/avm/fixtures/index.ts +2 -3
  152. package/src/avm/journal/journal.ts +14 -10
  153. package/src/avm/opcodes/accrued_substate.ts +53 -61
  154. package/src/avm/opcodes/addressing_mode.ts +27 -24
  155. package/src/avm/opcodes/arithmetic.ts +6 -8
  156. package/src/avm/opcodes/bitwise.ts +18 -18
  157. package/src/avm/opcodes/commitment.ts +6 -7
  158. package/src/avm/opcodes/comparators.ts +6 -8
  159. package/src/avm/opcodes/contract.ts +7 -8
  160. package/src/avm/opcodes/control_flow.ts +6 -6
  161. package/src/avm/opcodes/conversion.ts +10 -12
  162. package/src/avm/opcodes/ec_add.ts +29 -24
  163. package/src/avm/opcodes/environment_getters.ts +5 -4
  164. package/src/avm/opcodes/external_calls.ts +37 -30
  165. package/src/avm/opcodes/hashing.ts +38 -63
  166. package/src/avm/opcodes/instruction.ts +3 -10
  167. package/src/avm/opcodes/instruction_impl.ts +0 -3
  168. package/src/avm/opcodes/memory.ts +23 -67
  169. package/src/avm/opcodes/misc.ts +9 -11
  170. package/src/avm/opcodes/multi_scalar_mul.ts +31 -26
  171. package/src/avm/opcodes/storage.ts +12 -10
  172. package/src/avm/serialization/bytecode_serialization.ts +0 -2
  173. package/src/avm/serialization/instruction_serialization.ts +1 -4
  174. package/src/avm/test_utils.ts +1 -2
  175. package/src/client/client_execution_context.ts +46 -97
  176. package/src/client/db_oracle.ts +6 -2
  177. package/src/client/index.ts +1 -1
  178. package/src/client/private_execution.ts +45 -15
  179. package/src/client/simulator.ts +2 -3
  180. package/src/client/view_data_oracle.ts +1 -2
  181. package/src/common/debug_fn_name.ts +22 -0
  182. package/src/common/index.ts +0 -1
  183. package/src/public/db_interfaces.ts +5 -2
  184. package/src/public/dual_side_effect_trace.ts +173 -0
  185. package/src/public/enqueued_call_side_effect_trace.ts +552 -0
  186. package/src/public/enqueued_call_simulator.ts +35 -14
  187. package/src/public/enqueued_calls_processor.ts +4 -6
  188. package/src/public/execution.ts +15 -6
  189. package/src/public/executor.ts +42 -19
  190. package/src/public/fee_payment.ts +4 -6
  191. package/src/public/hints_builder.ts +9 -11
  192. package/src/public/public_db_sources.ts +31 -22
  193. package/src/public/public_kernel_tail_simulator.ts +3 -3
  194. package/src/public/public_processor.ts +17 -13
  195. package/src/public/side_effect_errors.ts +6 -0
  196. package/src/public/side_effect_trace.ts +74 -29
  197. package/src/public/side_effect_trace_interface.ts +2 -2
  198. package/dest/client/execution_result.d.ts +0 -104
  199. package/dest/client/execution_result.d.ts.map +0 -1
  200. package/dest/client/execution_result.js +0 -136
  201. package/dest/common/return_values.d.ts +0 -11
  202. package/dest/common/return_values.d.ts.map +0 -1
  203. package/dest/common/return_values.js +0 -13
  204. package/src/client/execution_result.ts +0 -228
  205. package/src/common/return_values.ts +0 -18
@@ -14,14 +14,14 @@ export class EcAdd extends Instruction {
14
14
  // Informs (de)serialization. See Instruction.deserialize.
15
15
  static readonly wireFormat: OperandType[] = [
16
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
17
+ OperandType.UINT16, // indirect
18
+ OperandType.UINT16, // p1X
19
+ OperandType.UINT16, // p1Y
20
+ OperandType.UINT16, // p1IsInfinite
21
+ OperandType.UINT16, // p2X
22
+ OperandType.UINT16, // p2Y
23
+ OperandType.UINT16, // p2IsInfinite
24
+ OperandType.UINT16, // dst
25
25
  ];
26
26
 
27
27
  constructor(
@@ -38,23 +38,21 @@ export class EcAdd extends Instruction {
38
38
  }
39
39
 
40
40
  public async execute(context: AvmContext): Promise<void> {
41
- const memoryOperations = { reads: 6, writes: 3, indirect: this.indirect };
42
41
  const memory = context.machineState.memory.track(this.type);
43
- context.machineState.consumeGas(this.gasCost(memoryOperations));
42
+ context.machineState.consumeGas(this.gasCost());
44
43
 
44
+ const operands = [
45
+ this.p1XOffset,
46
+ this.p1YOffset,
47
+ this.p1IsInfiniteOffset,
48
+ this.p2XOffset,
49
+ this.p2YOffset,
50
+ this.p2IsInfiniteOffset,
51
+ this.dstOffset,
52
+ ];
53
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
45
54
  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
- );
55
+ addressing.resolve(operands, memory);
58
56
 
59
57
  const p1X = memory.get(p1XOffset);
60
58
  const p1Y = memory.get(p1YOffset);
@@ -74,7 +72,14 @@ export class EcAdd extends Instruction {
74
72
  }
75
73
 
76
74
  const grumpkin = new Grumpkin();
77
- let dest = grumpkin.add(p1, p2);
75
+ let dest;
76
+ if (p1IsInfinite) {
77
+ dest = p2;
78
+ } else if (p2IsInfinite) {
79
+ dest = p1;
80
+ } else {
81
+ dest = grumpkin.add(p1, p2);
82
+ }
78
83
  // Temporary,
79
84
  if (p1IsInfinite) {
80
85
  dest = p2;
@@ -86,7 +91,7 @@ export class EcAdd extends Instruction {
86
91
  // Check representation of infinity for grumpkin
87
92
  memory.set(dstOffset + 2, new Field(dest.equals(Point.ZERO) ? 1 : 0));
88
93
 
89
- memory.assert(memoryOperations);
94
+ memory.assert({ reads: 6, writes: 3, addressing });
90
95
  context.machineState.incrementPc();
91
96
  }
92
97
  }
@@ -71,15 +71,16 @@ export class GetEnvVar extends Instruction {
71
71
  }
72
72
 
73
73
  public async execute(context: AvmContext): Promise<void> {
74
- const memoryOperations = { writes: 1, indirect: this.indirect };
75
74
  const memory = context.machineState.memory.track(this.type);
76
- context.machineState.consumeGas(this.gasCost(memoryOperations));
75
+ context.machineState.consumeGas(this.gasCost());
77
76
 
78
- const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], memory);
77
+ const operands = [this.dstOffset];
78
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
79
+ const [dstOffset] = addressing.resolve(operands, memory);
79
80
 
80
81
  memory.set(dstOffset, getValue(this.varEnum, context));
81
82
 
82
- memory.assert(memoryOperations);
83
+ memory.assert({ writes: 1, addressing });
83
84
  context.machineState.incrementPc();
84
85
  }
85
86
  }
@@ -15,15 +15,15 @@ abstract class ExternalCall extends Instruction {
15
15
  // Informs (de)serialization. See Instruction.deserialize.
16
16
  static readonly wireFormat: OperandType[] = [
17
17
  OperandType.UINT8,
18
- OperandType.UINT8,
19
- OperandType.UINT32,
20
- OperandType.UINT32,
21
- OperandType.UINT32,
22
- OperandType.UINT32,
23
- OperandType.UINT32,
24
- OperandType.UINT32,
25
- OperandType.UINT32,
26
- OperandType.UINT32,
18
+ OperandType.UINT16, // Indirect
19
+ OperandType.UINT16,
20
+ OperandType.UINT16,
21
+ OperandType.UINT16,
22
+ OperandType.UINT16,
23
+ OperandType.UINT16,
24
+ OperandType.UINT16,
25
+ OperandType.UINT16,
26
+ OperandType.UINT16,
27
27
  ];
28
28
 
29
29
  constructor(
@@ -45,29 +45,34 @@ abstract class ExternalCall extends Instruction {
45
45
 
46
46
  public async execute(context: AvmContext) {
47
47
  const memory = context.machineState.memory.track(this.type);
48
- const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset] = Addressing.fromWire(
49
- this.indirect,
50
- ).resolve(
51
- [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.retOffset, this.successOffset],
52
- memory,
53
- );
48
+ const operands = [
49
+ this.gasOffset,
50
+ this.addrOffset,
51
+ this.argsOffset,
52
+ this.argsSizeOffset,
53
+ this.retOffset,
54
+ this.successOffset,
55
+ this.functionSelectorOffset,
56
+ ];
57
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
58
+ const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset, functionSelectorOffset] =
59
+ addressing.resolve(operands, memory);
54
60
  memory.checkTags(TypeTag.FIELD, gasOffset, gasOffset + 1);
55
61
  memory.checkTag(TypeTag.FIELD, addrOffset);
56
62
  memory.checkTag(TypeTag.UINT32, argsSizeOffset);
57
- memory.checkTag(TypeTag.FIELD, this.functionSelectorOffset);
63
+ memory.checkTag(TypeTag.FIELD, functionSelectorOffset);
58
64
 
59
65
  const calldataSize = memory.get(argsSizeOffset).toNumber();
60
66
  memory.checkTagsRange(TypeTag.FIELD, argsOffset, calldataSize);
61
67
 
62
68
  const callAddress = memory.getAs<Field>(addrOffset);
63
69
  const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
64
- const functionSelector = memory.getAs<Field>(this.functionSelectorOffset).toFr();
70
+ const functionSelector = memory.getAs<Field>(functionSelectorOffset).toFr();
65
71
  // If we are already in a static call, we propagate the environment.
66
72
  const callType = context.environment.isStaticCall ? 'STATICCALL' : this.type;
67
73
 
68
74
  // First we consume the gas for this operation.
69
- const memoryOperations = { reads: calldataSize + 5, writes: 1 + this.retSize, indirect: this.indirect };
70
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: calldataSize + this.retSize }));
75
+ context.machineState.consumeGas(this.gasCost(calldataSize + this.retSize));
71
76
  // Then we consume the gas allocated for the nested call. The excess will be refunded later.
72
77
  // Gas allocation is capped by the amount of gas left in the current context.
73
78
  // We have to do some dancing here because the gas allocation is a field,
@@ -127,7 +132,7 @@ abstract class ExternalCall extends Instruction {
127
132
  /*avmCallResults=*/ nestedCallResults,
128
133
  );
129
134
 
130
- memory.assert(memoryOperations);
135
+ memory.assert({ reads: calldataSize + 5, writes: 1 + this.retSize, addressing });
131
136
  context.machineState.incrementPc();
132
137
  }
133
138
 
@@ -159,8 +164,8 @@ export class Return extends Instruction {
159
164
  static readonly wireFormat: OperandType[] = [
160
165
  OperandType.UINT8,
161
166
  OperandType.UINT8,
162
- OperandType.UINT32,
163
- OperandType.UINT32,
167
+ OperandType.UINT16,
168
+ OperandType.UINT16,
164
169
  ];
165
170
 
166
171
  constructor(private indirect: number, private returnOffset: number, private copySize: number) {
@@ -168,16 +173,17 @@ export class Return extends Instruction {
168
173
  }
169
174
 
170
175
  public async execute(context: AvmContext): Promise<void> {
171
- const memoryOperations = { reads: this.copySize, indirect: this.indirect };
172
176
  const memory = context.machineState.memory.track(this.type);
173
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.copySize }));
177
+ context.machineState.consumeGas(this.gasCost(this.copySize));
174
178
 
175
- const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory);
179
+ const operands = [this.returnOffset];
180
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
181
+ const [returnOffset] = addressing.resolve(operands, memory);
176
182
 
177
183
  const output = memory.getSlice(returnOffset, this.copySize).map(word => word.toFr());
178
184
 
179
185
  context.machineState.return(output);
180
- memory.assert(memoryOperations);
186
+ memory.assert({ reads: this.copySize, addressing });
181
187
  }
182
188
  }
183
189
 
@@ -203,16 +209,17 @@ export class Revert extends Instruction {
203
209
  }
204
210
 
205
211
  public async execute(context: AvmContext): Promise<void> {
206
- const memoryOperations = { reads: this.retSize, indirect: this.indirect };
207
212
  const memory = context.machineState.memory.track(this.type);
208
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.retSize }));
213
+ context.machineState.consumeGas(this.gasCost(this.retSize));
209
214
 
210
- const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory);
215
+ const operands = [this.returnOffset];
216
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
217
+ const [returnOffset] = addressing.resolve(operands, memory);
211
218
 
212
219
  const output = memory.getSlice(returnOffset, this.retSize).map(word => word.toFr());
213
220
 
214
221
  context.machineState.revert(output);
215
- memory.assert(memoryOperations);
222
+ memory.assert({ reads: this.retSize, addressing });
216
223
  }
217
224
  }
218
225
 
@@ -10,7 +10,6 @@ import { strict as assert } from 'assert';
10
10
 
11
11
  import { type AvmContext } from '../avm_context.js';
12
12
  import { Field, TypeTag, Uint8, Uint32, Uint64 } from '../avm_memory_types.js';
13
- import { InstructionExecutionError } from '../errors.js';
14
13
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
15
14
  import { Addressing } from './addressing_mode.js';
16
15
  import { Instruction } from './instruction.js';
@@ -24,8 +23,8 @@ export class Poseidon2 extends Instruction {
24
23
  static readonly wireFormat: OperandType[] = [
25
24
  OperandType.UINT8,
26
25
  OperandType.UINT8,
27
- OperandType.UINT32,
28
- OperandType.UINT32,
26
+ OperandType.UINT16,
27
+ OperandType.UINT16,
29
28
  ];
30
29
 
31
30
  constructor(private indirect: number, private inputStateOffset: number, private outputStateOffset: number) {
@@ -33,14 +32,12 @@ export class Poseidon2 extends Instruction {
33
32
  }
34
33
 
35
34
  public async execute(context: AvmContext): Promise<void> {
36
- const memoryOperations = { reads: Poseidon2.stateSize, writes: Poseidon2.stateSize, indirect: this.indirect };
37
35
  const memory = context.machineState.memory.track(this.type);
38
- context.machineState.consumeGas(this.gasCost(memoryOperations));
36
+ context.machineState.consumeGas(this.gasCost());
39
37
 
40
- const [inputOffset, outputOffset] = Addressing.fromWire(this.indirect).resolve(
41
- [this.inputStateOffset, this.outputStateOffset],
42
- memory,
43
- );
38
+ const operands = [this.inputStateOffset, this.outputStateOffset];
39
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
40
+ const [inputOffset, outputOffset] = addressing.resolve(operands, memory);
44
41
  memory.checkTagsRange(TypeTag.FIELD, inputOffset, Poseidon2.stateSize);
45
42
 
46
43
  const inputState = memory.getSlice(inputOffset, Poseidon2.stateSize);
@@ -50,7 +47,7 @@ export class Poseidon2 extends Instruction {
50
47
  outputState.map(word => new Field(word)),
51
48
  );
52
49
 
53
- memory.assert(memoryOperations);
50
+ memory.assert({ reads: Poseidon2.stateSize, writes: Poseidon2.stateSize, addressing });
54
51
  context.machineState.incrementPc();
55
52
  }
56
53
  }
@@ -80,14 +77,12 @@ export class Keccak extends Instruction {
80
77
  // pub fn keccak256(input: [u8], message_size: u32) -> [u8; 32]
81
78
  public async execute(context: AvmContext): Promise<void> {
82
79
  const memory = context.machineState.memory.track(this.type);
83
- const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
84
- [this.dstOffset, this.messageOffset, this.messageSizeOffset],
85
- memory,
86
- );
80
+ const operands = [this.dstOffset, this.messageOffset, this.messageSizeOffset];
81
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
82
+ const [dstOffset, messageOffset, messageSizeOffset] = addressing.resolve(operands, memory);
87
83
  memory.checkTag(TypeTag.UINT32, messageSizeOffset);
88
84
  const messageSize = memory.get(messageSizeOffset).toNumber();
89
- const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
90
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: messageSize }));
85
+ context.machineState.consumeGas(this.gasCost(messageSize));
91
86
 
92
87
  memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize);
93
88
 
@@ -98,7 +93,7 @@ export class Keccak extends Instruction {
98
93
  const res = [...hashBuffer].map(byte => new Uint8(byte));
99
94
  memory.setSlice(dstOffset, res);
100
95
 
101
- memory.assert(memoryOperations);
96
+ memory.assert({ reads: messageSize + 1, writes: 32, addressing });
102
97
  context.machineState.incrementPc();
103
98
  }
104
99
  }
@@ -111,9 +106,9 @@ export class KeccakF1600 extends Instruction {
111
106
  static readonly wireFormat: OperandType[] = [
112
107
  OperandType.UINT8,
113
108
  OperandType.UINT8,
114
- OperandType.UINT32,
115
- OperandType.UINT32,
116
- OperandType.UINT32,
109
+ OperandType.UINT16,
110
+ OperandType.UINT16,
111
+ OperandType.UINT16,
117
112
  ];
118
113
 
119
114
  constructor(
@@ -129,15 +124,13 @@ export class KeccakF1600 extends Instruction {
129
124
  // pub fn keccakf1600(input: [u64; 25]) -> [u64; 25]
130
125
  public async execute(context: AvmContext): Promise<void> {
131
126
  const memory = context.machineState.memory.track(this.type);
132
- const [dstOffset, stateOffset, stateSizeOffset] = Addressing.fromWire(this.indirect).resolve(
133
- [this.dstOffset, this.stateOffset, this.stateSizeOffset],
134
- memory,
135
- );
127
+ const operands = [this.dstOffset, this.stateOffset, this.stateSizeOffset];
128
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
129
+ const [dstOffset, stateOffset, stateSizeOffset] = addressing.resolve(operands, memory);
136
130
  memory.checkTag(TypeTag.UINT32, stateSizeOffset);
137
131
  const stateSize = memory.get(stateSizeOffset).toNumber();
138
132
  assert(stateSize === 25, 'Invalid state size for keccakf1600');
139
- const memoryOperations = { reads: stateSize + 1, writes: 25, indirect: this.indirect };
140
- context.machineState.consumeGas(this.gasCost(memoryOperations));
133
+ context.machineState.consumeGas(this.gasCost());
141
134
 
142
135
  memory.checkTagsRange(TypeTag.UINT64, stateOffset, stateSize);
143
136
 
@@ -147,7 +140,7 @@ export class KeccakF1600 extends Instruction {
147
140
  const res = updatedState.map(word => new Uint64(word));
148
141
  memory.setSlice(dstOffset, res);
149
142
 
150
- memory.assert(memoryOperations);
143
+ memory.assert({ reads: stateSize + 1, writes: 25, addressing });
151
144
  context.machineState.incrementPc();
152
145
  }
153
146
  }
@@ -160,20 +153,16 @@ export class Sha256Compression extends Instruction {
160
153
  static readonly wireFormat: OperandType[] = [
161
154
  OperandType.UINT8,
162
155
  OperandType.UINT8,
163
- OperandType.UINT32,
164
- OperandType.UINT32,
165
- OperandType.UINT32,
166
- OperandType.UINT32,
167
- OperandType.UINT32,
156
+ OperandType.UINT16,
157
+ OperandType.UINT16,
158
+ OperandType.UINT16,
168
159
  ];
169
160
 
170
161
  constructor(
171
162
  private indirect: number,
172
163
  private outputOffset: number,
173
164
  private stateOffset: number,
174
- private stateSizeOffset: number,
175
165
  private inputsOffset: number,
176
- private inputsSizeOffset: number,
177
166
  ) {
178
167
  super();
179
168
  }
@@ -183,36 +172,24 @@ export class Sha256Compression extends Instruction {
183
172
  const INPUTS_SIZE = 16;
184
173
 
185
174
  const memory = context.machineState.memory.track(this.type);
186
- const [outputOffset, stateOffset, stateSizeOffset, inputsOffset, inputsSizeOffset] = Addressing.fromWire(
187
- this.indirect,
188
- ).resolve(
189
- [this.outputOffset, this.stateOffset, this.stateSizeOffset, this.inputsOffset, this.inputsSizeOffset],
190
- memory,
191
- );
192
- const stateSize = memory.get(stateSizeOffset).toNumber();
193
- const inputsSize = memory.get(inputsSizeOffset).toNumber();
194
- if (stateSize !== STATE_SIZE) {
195
- throw new InstructionExecutionError('`state` argument to SHA256 compression must be of length 8');
196
- }
197
- if (inputsSize !== INPUTS_SIZE) {
198
- throw new InstructionExecutionError('`inputs` argument to SHA256 compression must be of length 16');
199
- }
200
- // +2 to account for both size offsets (stateSizeOffset and inputsSizeOffset)
175
+ const operands = [this.outputOffset, this.stateOffset, this.inputsOffset];
176
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
177
+ const [outputOffset, stateOffset, inputsOffset] = addressing.resolve(operands, memory);
178
+
201
179
  // Note: size of output is same as size of state
202
- const memoryOperations = { reads: stateSize + inputsSize + 2, writes: stateSize, indirect: this.indirect };
203
- context.machineState.consumeGas(this.gasCost(memoryOperations));
204
- memory.checkTagsRange(TypeTag.UINT32, inputsOffset, inputsSize);
205
- memory.checkTagsRange(TypeTag.UINT32, stateOffset, stateSize);
180
+ context.machineState.consumeGas(this.gasCost());
181
+ memory.checkTagsRange(TypeTag.UINT32, inputsOffset, INPUTS_SIZE);
182
+ memory.checkTagsRange(TypeTag.UINT32, stateOffset, STATE_SIZE);
206
183
 
207
- const state = Uint32Array.from(memory.getSlice(stateOffset, stateSize).map(word => word.toNumber()));
208
- const inputs = Uint32Array.from(memory.getSlice(inputsOffset, inputsSize).map(word => word.toNumber()));
184
+ const state = Uint32Array.from(memory.getSlice(stateOffset, STATE_SIZE).map(word => word.toNumber()));
185
+ const inputs = Uint32Array.from(memory.getSlice(inputsOffset, INPUTS_SIZE).map(word => word.toNumber()));
209
186
  const output = sha256Compression(state, inputs);
210
187
 
211
188
  // Conversion required from Uint32Array to Uint32[] (can't map directly, need `...`)
212
189
  const res = [...output].map(word => new Uint32(word));
213
190
  memory.setSlice(outputOffset, res);
214
191
 
215
- memory.assert(memoryOperations);
192
+ memory.assert({ reads: STATE_SIZE + INPUTS_SIZE, writes: STATE_SIZE, addressing });
216
193
  context.machineState.incrementPc();
217
194
  }
218
195
  }
@@ -243,10 +220,9 @@ export class Pedersen extends Instruction {
243
220
 
244
221
  public async execute(context: AvmContext): Promise<void> {
245
222
  const memory = context.machineState.memory.track(this.type);
246
- const [genIndexOffset, dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
247
- [this.genIndexOffset, this.dstOffset, this.messageOffset, this.messageSizeOffset],
248
- memory,
249
- );
223
+ const operands = [this.genIndexOffset, this.dstOffset, this.messageOffset, this.messageSizeOffset];
224
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
225
+ const [genIndexOffset, dstOffset, messageOffset, messageSizeOffset] = addressing.resolve(operands, memory);
250
226
 
251
227
  // We hash a set of field elements
252
228
  const genIndex = Number(memory.get(genIndexOffset).toBigInt());
@@ -255,8 +231,7 @@ export class Pedersen extends Instruction {
255
231
  memory.checkTag(TypeTag.UINT32, messageSizeOffset);
256
232
  const hashData = memory.getSlice(messageOffset, messageSize);
257
233
 
258
- const memoryOperations = { reads: messageSize + 2, writes: 1, indirect: this.indirect };
259
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: messageSize }));
234
+ context.machineState.consumeGas(this.gasCost(messageSize));
260
235
 
261
236
  memory.checkTagsRange(TypeTag.FIELD, messageOffset, messageSize);
262
237
 
@@ -264,7 +239,7 @@ export class Pedersen extends Instruction {
264
239
  const hash = pedersenHash(hashData, genIndex);
265
240
  memory.set(dstOffset, new Field(hash));
266
241
 
267
- memory.assert(memoryOperations);
242
+ memory.assert({ reads: messageSize + 2, writes: 1, addressing });
268
243
  context.machineState.incrementPc();
269
244
  }
270
245
  }
@@ -1,8 +1,7 @@
1
1
  import { strict as assert } from 'assert';
2
2
 
3
3
  import type { AvmContext } from '../avm_context.js';
4
- import { getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js';
5
- import { type MemoryOperations } from '../avm_memory_types.js';
4
+ import { type Gas, getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js';
6
5
  import { type BufferCursor } from '../serialization/buffer_cursor.js';
7
6
  import { type Serializable } from '../serialization/bytecode_serialization.js';
8
7
  import { Opcode, type OperandType, deserialize, serializeAs } from '../serialization/instruction_serialization.js';
@@ -86,17 +85,11 @@ export abstract class Instruction {
86
85
 
87
86
  /**
88
87
  * Computes gas cost for the instruction based on its base cost and memory operations.
89
- * @param memoryOps Memory operations performed by the instruction.
90
88
  * @returns Gas cost.
91
89
  */
92
- protected gasCost(ops: Partial<MemoryOperations & { indirect: number; dynMultiplier: number }> = {}) {
90
+ protected gasCost(dynMultiplier: number = 0): Gas {
93
91
  const baseGasCost = getBaseGasCost(this.opcode);
94
- // TODO: We are using a simplified gas model to reduce complexity in the circuit.
95
- // Memory accounting will probably be removed.
96
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6861): reconsider.
97
- // const memoryGasCost = getMemoryGasCost(memoryOps);
98
- // const memoryGasCost = { l2Gas: 0, daGas: 0 };
99
- const dynGasCost = mulGas(getDynamicGasCost(this.opcode), ops.dynMultiplier ?? 0);
92
+ const dynGasCost = mulGas(getDynamicGasCost(this.opcode), dynMultiplier);
100
93
  return sumGas(baseGasCost, dynGasCost);
101
94
  }
102
95
 
@@ -8,10 +8,8 @@ export const ThreeOperandWireFormat8 = [
8
8
  OperandType.UINT8,
9
9
  OperandType.UINT8,
10
10
  OperandType.UINT8,
11
- OperandType.UINT8,
12
11
  ];
13
12
  export const ThreeOperandWireFormat16 = [
14
- OperandType.UINT8,
15
13
  OperandType.UINT8,
16
14
  OperandType.UINT8,
17
15
  OperandType.UINT16,
@@ -29,7 +27,6 @@ export abstract class ThreeOperandInstruction extends Instruction {
29
27
 
30
28
  constructor(
31
29
  protected indirect: number,
32
- protected inTag: number,
33
30
  protected aOffset: number,
34
31
  protected bOffset: number,
35
32
  protected dstOffset: number,
@@ -62,60 +62,16 @@ export class Set extends Instruction {
62
62
  }
63
63
 
64
64
  public async execute(context: AvmContext): Promise<void> {
65
- const memoryOperations = { writes: 1, indirect: this.indirect };
66
65
  const memory = context.machineState.memory.track(this.type);
67
- context.machineState.consumeGas(this.gasCost(memoryOperations));
66
+ context.machineState.consumeGas(this.gasCost());
68
67
 
69
- const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], memory);
68
+ const operands = [this.dstOffset];
69
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
70
+ const [dstOffset] = addressing.resolve(operands, memory);
70
71
  const res = TaggedMemory.buildFromTagTruncating(this.value, this.inTag);
71
72
  memory.set(dstOffset, res);
72
73
 
73
- memory.assert(memoryOperations);
74
- context.machineState.incrementPc();
75
- }
76
- }
77
-
78
- export class CMov extends Instruction {
79
- static readonly type: string = 'CMOV';
80
- static readonly opcode: Opcode = Opcode.CMOV;
81
- // Informs (de)serialization. See Instruction.deserialize.
82
- static readonly wireFormat: OperandType[] = [
83
- OperandType.UINT8,
84
- OperandType.UINT8,
85
- OperandType.UINT32,
86
- OperandType.UINT32,
87
- OperandType.UINT32,
88
- OperandType.UINT32,
89
- ];
90
-
91
- constructor(
92
- private indirect: number,
93
- private aOffset: number,
94
- private bOffset: number,
95
- private condOffset: number,
96
- private dstOffset: number,
97
- ) {
98
- super();
99
- }
100
-
101
- public async execute(context: AvmContext): Promise<void> {
102
- const memoryOperations = { reads: 3, writes: 1, indirect: this.indirect };
103
- const memory = context.machineState.memory.track(this.type);
104
- context.machineState.consumeGas(this.gasCost(memoryOperations));
105
-
106
- const [aOffset, bOffset, condOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
107
- [this.aOffset, this.bOffset, this.condOffset, this.dstOffset],
108
- memory,
109
- );
110
-
111
- const a = memory.get(aOffset);
112
- const b = memory.get(bOffset);
113
- const cond = memory.get(condOffset);
114
-
115
- // TODO: reconsider toBigInt() here
116
- memory.set(dstOffset, cond.toBigInt() > 0 ? a : b);
117
-
118
- memory.assert(memoryOperations);
74
+ memory.assert({ writes: 1, addressing });
119
75
  context.machineState.incrementPc();
120
76
  }
121
77
  }
@@ -144,18 +100,19 @@ export class Cast extends Instruction {
144
100
  }
145
101
 
146
102
  public async execute(context: AvmContext): Promise<void> {
147
- const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
148
103
  const memory = context.machineState.memory.track(this.type);
149
- context.machineState.consumeGas(this.gasCost(memoryOperations));
104
+ context.machineState.consumeGas(this.gasCost());
150
105
 
151
- const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory);
106
+ const operands = [this.srcOffset, this.dstOffset];
107
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
108
+ const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
152
109
 
153
110
  const a = memory.get(srcOffset);
154
111
  const casted = TaggedMemory.buildFromTagTruncating(a.toBigInt(), this.dstTag);
155
112
 
156
113
  memory.set(dstOffset, casted);
157
114
 
158
- memory.assert(memoryOperations);
115
+ memory.assert({ reads: 1, writes: 1, addressing });
159
116
  context.machineState.incrementPc();
160
117
  }
161
118
  }
@@ -183,17 +140,18 @@ export class Mov extends Instruction {
183
140
  }
184
141
 
185
142
  public async execute(context: AvmContext): Promise<void> {
186
- const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
187
143
  const memory = context.machineState.memory.track(this.type);
188
- context.machineState.consumeGas(this.gasCost(memoryOperations));
144
+ context.machineState.consumeGas(this.gasCost());
189
145
 
190
- const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory);
146
+ const operands = [this.srcOffset, this.dstOffset];
147
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
148
+ const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
191
149
 
192
150
  const a = memory.get(srcOffset);
193
151
 
194
152
  memory.set(dstOffset, a);
195
153
 
196
- memory.assert(memoryOperations);
154
+ memory.assert({ reads: 1, writes: 1, addressing });
197
155
  context.machineState.incrementPc();
198
156
  }
199
157
  }
@@ -205,9 +163,9 @@ export class CalldataCopy extends Instruction {
205
163
  static readonly wireFormat: OperandType[] = [
206
164
  OperandType.UINT8,
207
165
  OperandType.UINT8,
208
- OperandType.UINT32,
209
- OperandType.UINT32,
210
- OperandType.UINT32,
166
+ OperandType.UINT16,
167
+ OperandType.UINT16,
168
+ OperandType.UINT16,
211
169
  ];
212
170
 
213
171
  constructor(
@@ -222,21 +180,19 @@ export class CalldataCopy extends Instruction {
222
180
  public async execute(context: AvmContext): Promise<void> {
223
181
  const memory = context.machineState.memory.track(this.type);
224
182
  // We don't need to check tags here because: (1) the calldata is NOT in memory, and (2) we are the ones writing to destination.
225
- const [cdStartOffset, copySizeOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
226
- [this.cdStartOffset, this.copySizeOffset, this.dstOffset],
227
- memory,
228
- );
183
+ const operands = [this.cdStartOffset, this.copySizeOffset, this.dstOffset];
184
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
185
+ const [cdStartOffset, copySizeOffset, dstOffset] = addressing.resolve(operands, memory);
229
186
 
230
187
  const cdStart = memory.get(cdStartOffset).toNumber();
231
188
  const copySize = memory.get(copySizeOffset).toNumber();
232
- const memoryOperations = { reads: 2, writes: copySize, indirect: this.indirect };
233
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: copySize }));
189
+ context.machineState.consumeGas(this.gasCost(copySize));
234
190
 
235
191
  const transformedData = context.environment.calldata.slice(cdStart, cdStart + copySize).map(f => new Field(f));
236
192
 
237
193
  memory.setSlice(dstOffset, transformedData);
238
194
 
239
- memory.assert(memoryOperations);
195
+ memory.assert({ reads: 2, writes: copySize, addressing });
240
196
  context.machineState.incrementPc();
241
197
  }
242
198
  }