@aztec/simulator 0.59.0 → 0.61.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 (190) hide show
  1. package/dest/acvm/acvm.d.ts +1 -0
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.d.ts +5 -3
  4. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  5. package/dest/acvm/oracle/oracle.js +15 -7
  6. package/dest/acvm/oracle/typed_oracle.d.ts +7 -4
  7. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  8. package/dest/acvm/oracle/typed_oracle.js +10 -4
  9. package/dest/acvm/serialize.d.ts +1 -0
  10. package/dest/acvm/serialize.d.ts.map +1 -1
  11. package/dest/avm/avm_context.d.ts +1 -1
  12. package/dest/avm/avm_context.js +1 -1
  13. package/dest/avm/avm_execution_environment.d.ts +2 -5
  14. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  15. package/dest/avm/avm_execution_environment.js +7 -15
  16. package/dest/avm/avm_gas.d.ts.map +1 -1
  17. package/dest/avm/avm_gas.js +6 -10
  18. package/dest/avm/avm_machine_state.d.ts +2 -0
  19. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  20. package/dest/avm/avm_machine_state.js +3 -1
  21. package/dest/avm/avm_memory_types.d.ts +1 -0
  22. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  23. package/dest/avm/avm_simulator.d.ts +16 -0
  24. package/dest/avm/avm_simulator.d.ts.map +1 -1
  25. package/dest/avm/avm_simulator.js +45 -4
  26. package/dest/avm/bytecode_utils.d.ts +1 -0
  27. package/dest/avm/bytecode_utils.d.ts.map +1 -1
  28. package/dest/avm/fixtures/index.d.ts +3 -0
  29. package/dest/avm/fixtures/index.d.ts.map +1 -1
  30. package/dest/avm/fixtures/index.js +8 -2
  31. package/dest/avm/journal/journal.d.ts +19 -19
  32. package/dest/avm/journal/journal.d.ts.map +1 -1
  33. package/dest/avm/journal/journal.js +73 -48
  34. package/dest/avm/journal/nullifiers.d.ts +9 -9
  35. package/dest/avm/journal/nullifiers.d.ts.map +1 -1
  36. package/dest/avm/journal/nullifiers.js +24 -24
  37. package/dest/avm/journal/public_storage.d.ts +10 -10
  38. package/dest/avm/journal/public_storage.d.ts.map +1 -1
  39. package/dest/avm/journal/public_storage.js +21 -21
  40. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  41. package/dest/avm/opcodes/accrued_substate.js +5 -5
  42. package/dest/avm/opcodes/contract.d.ts +8 -1
  43. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  44. package/dest/avm/opcodes/contract.js +41 -21
  45. package/dest/avm/opcodes/conversion.d.ts +1 -1
  46. package/dest/avm/opcodes/conversion.d.ts.map +1 -1
  47. package/dest/avm/opcodes/conversion.js +12 -9
  48. package/dest/avm/opcodes/environment_getters.d.ts +13 -14
  49. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  50. package/dest/avm/opcodes/environment_getters.js +17 -16
  51. package/dest/avm/opcodes/external_calls.d.ts +3 -6
  52. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  53. package/dest/avm/opcodes/external_calls.js +23 -43
  54. package/dest/avm/opcodes/hashing.d.ts +2 -26
  55. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  56. package/dest/avm/opcodes/hashing.js +11 -95
  57. package/dest/avm/opcodes/index.d.ts +0 -1
  58. package/dest/avm/opcodes/index.d.ts.map +1 -1
  59. package/dest/avm/opcodes/index.js +1 -2
  60. package/dest/avm/opcodes/instruction.d.ts +1 -0
  61. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  62. package/dest/avm/opcodes/memory.d.ts +20 -0
  63. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  64. package/dest/avm/opcodes/memory.js +59 -3
  65. package/dest/avm/opcodes/storage.js +3 -3
  66. package/dest/avm/serialization/buffer_cursor.d.ts +1 -0
  67. package/dest/avm/serialization/buffer_cursor.d.ts.map +1 -1
  68. package/dest/avm/serialization/bytecode_serialization.d.ts +1 -0
  69. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  70. package/dest/avm/serialization/bytecode_serialization.js +5 -7
  71. package/dest/avm/serialization/instruction_serialization.d.ts +34 -35
  72. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  73. package/dest/avm/serialization/instruction_serialization.js +34 -36
  74. package/dest/avm/test_utils.d.ts +3 -1
  75. package/dest/avm/test_utils.d.ts.map +1 -1
  76. package/dest/avm/test_utils.js +4 -1
  77. package/dest/client/client_execution_context.d.ts +9 -18
  78. package/dest/client/client_execution_context.d.ts.map +1 -1
  79. package/dest/client/client_execution_context.js +30 -50
  80. package/dest/client/db_oracle.d.ts +17 -1
  81. package/dest/client/db_oracle.d.ts.map +1 -1
  82. package/dest/client/db_oracle.js +1 -1
  83. package/dest/client/private_execution.d.ts.map +1 -1
  84. package/dest/client/private_execution.js +3 -4
  85. package/dest/client/simulator.d.ts.map +1 -1
  86. package/dest/client/simulator.js +3 -3
  87. package/dest/client/view_data_oracle.d.ts +17 -1
  88. package/dest/client/view_data_oracle.d.ts.map +1 -1
  89. package/dest/client/view_data_oracle.js +21 -1
  90. package/dest/common/index.d.ts +0 -1
  91. package/dest/common/index.d.ts.map +1 -1
  92. package/dest/common/index.js +1 -2
  93. package/dest/mocks/fixtures.js +2 -2
  94. package/dest/providers/acvm_native.d.ts +1 -0
  95. package/dest/providers/acvm_native.d.ts.map +1 -1
  96. package/dest/public/db_interfaces.d.ts +1 -0
  97. package/dest/public/db_interfaces.d.ts.map +1 -1
  98. package/dest/public/dual_side_effect_trace.d.ts +10 -11
  99. package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
  100. package/dest/public/dual_side_effect_trace.js +26 -22
  101. package/dest/public/enqueued_call_side_effect_trace.d.ts +11 -12
  102. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
  103. package/dest/public/enqueued_call_side_effect_trace.js +33 -23
  104. package/dest/public/enqueued_call_simulator.d.ts +3 -3
  105. package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
  106. package/dest/public/enqueued_call_simulator.js +30 -39
  107. package/dest/public/enqueued_calls_processor.d.ts +2 -3
  108. package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
  109. package/dest/public/enqueued_calls_processor.js +19 -26
  110. package/dest/public/execution.d.ts +1 -0
  111. package/dest/public/execution.d.ts.map +1 -1
  112. package/dest/public/execution.js +2 -2
  113. package/dest/public/executor.d.ts.map +1 -1
  114. package/dest/public/executor.js +6 -5
  115. package/dest/public/public_db_sources.d.ts +1 -0
  116. package/dest/public/public_db_sources.d.ts.map +1 -1
  117. package/dest/public/public_kernel.d.ts +0 -1
  118. package/dest/public/public_kernel.d.ts.map +1 -1
  119. package/dest/public/public_kernel.js +5 -8
  120. package/dest/public/public_kernel_tail_simulator.d.ts +1 -5
  121. package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
  122. package/dest/public/public_kernel_tail_simulator.js +6 -12
  123. package/dest/public/public_processor.js +4 -4
  124. package/dest/public/side_effect_trace.d.ts +11 -9
  125. package/dest/public/side_effect_trace.d.ts.map +1 -1
  126. package/dest/public/side_effect_trace.js +40 -30
  127. package/dest/public/side_effect_trace_interface.d.ts +10 -9
  128. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  129. package/package.json +9 -9
  130. package/src/acvm/oracle/oracle.ts +13 -6
  131. package/src/acvm/oracle/typed_oracle.ts +9 -3
  132. package/src/avm/avm_context.ts +1 -1
  133. package/src/avm/avm_execution_environment.ts +0 -15
  134. package/src/avm/avm_gas.ts +5 -9
  135. package/src/avm/avm_machine_state.ts +2 -0
  136. package/src/avm/avm_simulator.ts +69 -6
  137. package/src/avm/fixtures/index.ts +7 -2
  138. package/src/avm/journal/journal.ts +93 -50
  139. package/src/avm/journal/nullifiers.ts +23 -23
  140. package/src/avm/journal/public_storage.ts +20 -20
  141. package/src/avm/opcodes/accrued_substate.ts +4 -8
  142. package/src/avm/opcodes/contract.ts +45 -21
  143. package/src/avm/opcodes/conversion.ts +9 -6
  144. package/src/avm/opcodes/environment_getters.ts +7 -5
  145. package/src/avm/opcodes/external_calls.ts +21 -45
  146. package/src/avm/opcodes/hashing.ts +9 -122
  147. package/src/avm/opcodes/index.ts +0 -1
  148. package/src/avm/opcodes/memory.ts +69 -2
  149. package/src/avm/opcodes/storage.ts +2 -2
  150. package/src/avm/serialization/bytecode_serialization.ts +6 -9
  151. package/src/avm/serialization/instruction_serialization.ts +3 -5
  152. package/src/avm/test_utils.ts +5 -1
  153. package/src/client/client_execution_context.ts +21 -71
  154. package/src/client/db_oracle.ts +26 -0
  155. package/src/client/private_execution.ts +1 -9
  156. package/src/client/simulator.ts +0 -2
  157. package/src/client/view_data_oracle.ts +31 -1
  158. package/src/common/index.ts +0 -1
  159. package/src/mocks/fixtures.ts +1 -1
  160. package/src/public/dual_side_effect_trace.ts +38 -24
  161. package/src/public/enqueued_call_side_effect_trace.ts +60 -28
  162. package/src/public/enqueued_call_simulator.ts +52 -49
  163. package/src/public/enqueued_calls_processor.ts +27 -41
  164. package/src/public/execution.ts +1 -1
  165. package/src/public/executor.ts +11 -5
  166. package/src/public/public_kernel.ts +9 -12
  167. package/src/public/public_kernel_tail_simulator.ts +6 -15
  168. package/src/public/public_processor.ts +3 -3
  169. package/src/public/side_effect_trace.ts +73 -29
  170. package/src/public/side_effect_trace_interface.ts +15 -10
  171. package/dest/avm/opcodes/commitment.d.ts +0 -16
  172. package/dest/avm/opcodes/commitment.d.ts.map +0 -1
  173. package/dest/avm/opcodes/commitment.js +0 -51
  174. package/dest/client/test_utils.d.ts +0 -9
  175. package/dest/client/test_utils.d.ts.map +0 -1
  176. package/dest/client/test_utils.js +0 -27
  177. package/dest/common/side_effect_counter.d.ts +0 -10
  178. package/dest/common/side_effect_counter.d.ts.map +0 -1
  179. package/dest/common/side_effect_counter.js +0 -18
  180. package/dest/rollup/index.d.ts +0 -2
  181. package/dest/rollup/index.d.ts.map +0 -1
  182. package/dest/rollup/index.js +0 -2
  183. package/dest/rollup/rollup.d.ts +0 -101
  184. package/dest/rollup/rollup.d.ts.map +0 -1
  185. package/dest/rollup/rollup.js +0 -100
  186. package/src/avm/opcodes/commitment.ts +0 -65
  187. package/src/client/test_utils.ts +0 -57
  188. package/src/common/side_effect_counter.ts +0 -17
  189. package/src/rollup/index.ts +0 -1
  190. package/src/rollup/rollup.ts +0 -228
@@ -39,11 +39,7 @@ export class NoteHashExists extends Instruction {
39
39
  const noteHash = memory.get(noteHashOffset).toFr();
40
40
  const leafIndex = memory.get(leafIndexOffset).toFr();
41
41
 
42
- const exists = await context.persistableState.checkNoteHashExists(
43
- context.environment.storageAddress,
44
- noteHash,
45
- leafIndex,
46
- );
42
+ const exists = await context.persistableState.checkNoteHashExists(context.environment.address, noteHash, leafIndex);
47
43
  memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
48
44
 
49
45
  memory.assert({ reads: 2, writes: 1, addressing });
@@ -75,7 +71,7 @@ export class EmitNoteHash extends Instruction {
75
71
  }
76
72
 
77
73
  const noteHash = memory.get(noteHashOffset).toFr();
78
- context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
74
+ context.persistableState.writeNoteHash(context.environment.address, noteHash);
79
75
 
80
76
  memory.assert({ reads: 1, addressing });
81
77
  context.machineState.incrementPc();
@@ -148,12 +144,12 @@ export class EmitNullifier extends Instruction {
148
144
 
149
145
  const nullifier = memory.get(nullifierOffset).toFr();
150
146
  try {
151
- await context.persistableState.writeNullifier(context.environment.storageAddress, nullifier);
147
+ await context.persistableState.writeNullifier(context.environment.address, nullifier);
152
148
  } catch (e) {
153
149
  if (e instanceof NullifierCollisionError) {
154
150
  // Error is known/expected, raise as InstructionExecutionError that the will lead the simulator to revert this call
155
151
  throw new InstructionExecutionError(
156
- `Attempted to emit duplicate nullifier ${nullifier} (storage address: ${context.environment.storageAddress}).`,
152
+ `Attempted to emit duplicate nullifier ${nullifier} (contract address: ${context.environment.address}).`,
157
153
  );
158
154
  } else {
159
155
  throw e;
@@ -1,23 +1,36 @@
1
- import { Fr } from '@aztec/circuits.js';
2
-
3
1
  import type { AvmContext } from '../avm_context.js';
4
- import { Field, TypeTag } from '../avm_memory_types.js';
2
+ import { Field, TypeTag, Uint1 } from '../avm_memory_types.js';
3
+ import { InstructionExecutionError } from '../errors.js';
5
4
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
5
  import { Addressing } from './addressing_mode.js';
7
6
  import { Instruction } from './instruction.js';
8
7
 
8
+ export enum ContractInstanceMember {
9
+ DEPLOYER,
10
+ CLASS_ID,
11
+ INIT_HASH,
12
+ }
13
+
9
14
  export class GetContractInstance extends Instruction {
10
15
  static readonly type: string = 'GETCONTRACTINSTANCE';
11
16
  static readonly opcode: Opcode = Opcode.GETCONTRACTINSTANCE;
12
17
  // Informs (de)serialization. See Instruction.deserialize.
13
18
  static readonly wireFormat: OperandType[] = [
14
- OperandType.UINT8,
15
- OperandType.UINT8,
16
- OperandType.UINT32,
17
- OperandType.UINT32,
19
+ OperandType.UINT8, // opcode
20
+ OperandType.UINT8, // indirect bits
21
+ OperandType.UINT8, // member enum (immediate)
22
+ OperandType.UINT16, // addressOffset
23
+ OperandType.UINT16, // dstOffset
24
+ OperandType.UINT16, // existsOfsset
18
25
  ];
19
26
 
20
- constructor(private indirect: number, private addressOffset: number, private dstOffset: number) {
27
+ constructor(
28
+ private indirect: number,
29
+ private memberEnum: number,
30
+ private addressOffset: number,
31
+ private dstOffset: number,
32
+ private existsOffset: number,
33
+ ) {
21
34
  super();
22
35
  }
23
36
 
@@ -25,27 +38,38 @@ export class GetContractInstance extends Instruction {
25
38
  const memory = context.machineState.memory.track(this.type);
26
39
  context.machineState.consumeGas(this.gasCost());
27
40
 
28
- const operands = [this.addressOffset, this.dstOffset];
41
+ if (!(this.memberEnum in ContractInstanceMember)) {
42
+ throw new InstructionExecutionError(`Invalid GETCONSTRACTINSTANCE member enum ${this.memberEnum}`);
43
+ }
44
+
45
+ const operands = [this.addressOffset, this.dstOffset, this.existsOffset];
29
46
  const addressing = Addressing.fromWire(this.indirect, operands.length);
30
- const [addressOffset, dstOffset] = addressing.resolve(operands, memory);
47
+ const [addressOffset, dstOffset, existsOffset] = addressing.resolve(operands, memory);
31
48
  memory.checkTag(TypeTag.FIELD, addressOffset);
32
49
 
33
50
  const address = memory.get(addressOffset).toFr();
34
51
  const instance = await context.persistableState.getContractInstance(address);
52
+ const exists = instance !== undefined;
35
53
 
36
- const data = [
37
- new Fr(instance.exists),
38
- instance.salt,
39
- instance.deployer.toField(),
40
- instance.contractClassId,
41
- instance.initializationHash,
42
- // This this okay ?
43
- ...instance.publicKeys.toFields(),
44
- ].map(f => new Field(f));
54
+ let memberValue = new Field(0);
55
+ if (exists) {
56
+ switch (this.memberEnum as ContractInstanceMember) {
57
+ case ContractInstanceMember.DEPLOYER:
58
+ memberValue = new Field(instance.deployer.toField());
59
+ break;
60
+ case ContractInstanceMember.CLASS_ID:
61
+ memberValue = new Field(instance.contractClassId.toField());
62
+ break;
63
+ case ContractInstanceMember.INIT_HASH:
64
+ memberValue = new Field(instance.initializationHash);
65
+ break;
66
+ }
67
+ }
45
68
 
46
- memory.setSlice(dstOffset, data);
69
+ memory.set(existsOffset, new Uint1(exists ? 1 : 0));
70
+ memory.set(dstOffset, memberValue);
47
71
 
48
- memory.assert({ reads: 1, writes: 17, addressing });
72
+ memory.assert({ reads: 1, writes: 2, addressing });
49
73
  context.machineState.incrementPc();
50
74
  }
51
75
  }
@@ -5,9 +5,9 @@ import { Opcode, OperandType } from '../serialization/instruction_serialization.
5
5
  import { Addressing } from './addressing_mode.js';
6
6
  import { Instruction } from './instruction.js';
7
7
 
8
- export class ToRadixLE extends Instruction {
8
+ export class ToRadixBE extends Instruction {
9
9
  static type: string = 'TORADIXLE';
10
- static readonly opcode: Opcode = Opcode.TORADIXLE;
10
+ static readonly opcode: Opcode = Opcode.TORADIXBE;
11
11
 
12
12
  // Informs (de)serialization. See Instruction.deserialize.
13
13
  static readonly wireFormat: OperandType[] = [
@@ -44,15 +44,18 @@ export class ToRadixLE extends Instruction {
44
44
 
45
45
  let value: bigint = memory.get(srcOffset).toBigInt();
46
46
  const radix: bigint = memory.get(radixOffset).toBigInt();
47
+ if (this.numLimbs < 1) {
48
+ throw new InstructionExecutionError(`ToRadixBE instruction's numLimbs should be > 0 (was ${this.numLimbs})`);
49
+ }
47
50
  if (radix > 256) {
48
- throw new InstructionExecutionError(`ToRadixLE instruction's radix should be <= 256 (was ${radix})`);
51
+ throw new InstructionExecutionError(`ToRadixBE instruction's radix should be <= 256 (was ${radix})`);
49
52
  }
50
53
  const radixBN: bigint = BigInt(radix);
51
- const limbArray = [];
54
+ const limbArray = new Array(this.numLimbs);
52
55
 
53
- for (let i = 0; i < this.numLimbs; i++) {
56
+ for (let i = this.numLimbs - 1; i >= 0; i--) {
54
57
  const limb = value % radixBN;
55
- limbArray.push(limb);
58
+ limbArray[i] = limb;
56
59
  value /= radixBN;
57
60
  }
58
61
 
@@ -1,12 +1,12 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
2
  import { Field, Uint32, Uint64 } from '../avm_memory_types.js';
3
+ import { InstructionExecutionError } from '../errors.js';
3
4
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
4
5
  import { Addressing } from './addressing_mode.js';
5
6
  import { Instruction } from './instruction.js';
6
7
 
7
8
  export enum EnvironmentVariable {
8
9
  ADDRESS,
9
- STORAGEADDRESS,
10
10
  SENDER,
11
11
  FUNCTIONSELECTOR,
12
12
  TRANSACTIONFEE,
@@ -25,8 +25,6 @@ function getValue(e: EnvironmentVariable, ctx: AvmContext) {
25
25
  switch (e) {
26
26
  case EnvironmentVariable.ADDRESS:
27
27
  return new Field(ctx.environment.address.toField());
28
- case EnvironmentVariable.STORAGEADDRESS:
29
- return new Field(ctx.environment.storageAddress.toField());
30
28
  case EnvironmentVariable.SENDER:
31
29
  return new Field(ctx.environment.sender.toField());
32
30
  case EnvironmentVariable.FUNCTIONSELECTOR:
@@ -66,7 +64,7 @@ export class GetEnvVar extends Instruction {
66
64
  OperandType.UINT16, // dstOffset
67
65
  ];
68
66
 
69
- constructor(private indirect: number, private varEnum: EnvironmentVariable, private dstOffset: number) {
67
+ constructor(private indirect: number, private varEnum: number, private dstOffset: number) {
70
68
  super();
71
69
  }
72
70
 
@@ -74,11 +72,15 @@ export class GetEnvVar extends Instruction {
74
72
  const memory = context.machineState.memory.track(this.type);
75
73
  context.machineState.consumeGas(this.gasCost());
76
74
 
75
+ if (!(this.varEnum in EnvironmentVariable)) {
76
+ throw new InstructionExecutionError(`Invalid GETENVVAR var enum ${this.varEnum}`);
77
+ }
78
+
77
79
  const operands = [this.dstOffset];
78
80
  const addressing = Addressing.fromWire(this.indirect, operands.length);
79
81
  const [dstOffset] = addressing.resolve(operands, memory);
80
82
 
81
- memory.set(dstOffset, getValue(this.varEnum, context));
83
+ memory.set(dstOffset, getValue(this.varEnum as EnvironmentVariable, context));
82
84
 
83
85
  memory.assert({ writes: 1, addressing });
84
86
  context.machineState.incrementPc();
@@ -1,10 +1,9 @@
1
- import { FunctionSelector, Gas } from '@aztec/circuits.js';
2
- import { padArrayEnd } from '@aztec/foundation/collection';
1
+ import { Fr, FunctionSelector, Gas, PUBLIC_DISPATCH_SELECTOR } from '@aztec/circuits.js';
3
2
 
4
3
  import type { AvmContext } from '../avm_context.js';
5
4
  import { type AvmContractCallResult } from '../avm_contract_call_result.js';
6
5
  import { gasLeftToGas } from '../avm_gas.js';
7
- import { Field, TypeTag, Uint8 } from '../avm_memory_types.js';
6
+ import { type Field, TypeTag, Uint1 } from '../avm_memory_types.js';
8
7
  import { AvmSimulator } from '../avm_simulator.js';
9
8
  import { RethrownError } from '../errors.js';
10
9
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
@@ -21,58 +20,39 @@ abstract class ExternalCall extends Instruction {
21
20
  OperandType.UINT16,
22
21
  OperandType.UINT16,
23
22
  OperandType.UINT16,
24
- OperandType.UINT16,
25
- OperandType.UINT16,
26
- OperandType.UINT16,
27
23
  ];
28
24
 
29
25
  constructor(
30
26
  private indirect: number,
31
- private gasOffset: number /* Unused due to no formal gas implementation at this moment */,
27
+ private gasOffset: number,
32
28
  private addrOffset: number,
33
29
  private argsOffset: number,
34
30
  private argsSizeOffset: number,
35
- private retOffset: number,
36
- private retSize: number,
37
31
  private successOffset: number,
38
- // NOTE: Function selector is likely temporary since eventually public contract bytecode will be one
39
- // blob containing all functions, and function selector will become an application-level mechanism
40
- // (e.g. first few bytes of calldata + compiler-generated jump table)
41
- private functionSelectorOffset: number,
42
32
  ) {
43
33
  super();
44
34
  }
45
35
 
46
36
  public async execute(context: AvmContext) {
47
37
  const memory = context.machineState.memory.track(this.type);
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
- ];
38
+ const operands = [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.successOffset];
57
39
  const addressing = Addressing.fromWire(this.indirect, operands.length);
58
- const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset, functionSelectorOffset] =
59
- addressing.resolve(operands, memory);
40
+ const [gasOffset, addrOffset, argsOffset, argsSizeOffset, successOffset] = addressing.resolve(operands, memory);
60
41
  memory.checkTags(TypeTag.FIELD, gasOffset, gasOffset + 1);
61
42
  memory.checkTag(TypeTag.FIELD, addrOffset);
62
43
  memory.checkTag(TypeTag.UINT32, argsSizeOffset);
63
- memory.checkTag(TypeTag.FIELD, functionSelectorOffset);
64
44
 
65
45
  const calldataSize = memory.get(argsSizeOffset).toNumber();
66
46
  memory.checkTagsRange(TypeTag.FIELD, argsOffset, calldataSize);
67
47
 
68
48
  const callAddress = memory.getAs<Field>(addrOffset);
69
49
  const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
70
- const functionSelector = memory.getAs<Field>(functionSelectorOffset).toFr();
50
+ const functionSelector = new Fr(PUBLIC_DISPATCH_SELECTOR);
71
51
  // If we are already in a static call, we propagate the environment.
72
52
  const callType = context.environment.isStaticCall ? 'STATICCALL' : this.type;
73
53
 
74
54
  // First we consume the gas for this operation.
75
- context.machineState.consumeGas(this.gasCost(calldataSize + this.retSize));
55
+ context.machineState.consumeGas(this.gasCost(calldataSize));
76
56
  // Then we consume the gas allocated for the nested call. The excess will be refunded later.
77
57
  // Gas allocation is capped by the amount of gas left in the current context.
78
58
  // We have to do some dancing here because the gas allocation is a field,
@@ -106,18 +86,12 @@ abstract class ExternalCall extends Instruction {
106
86
  throw new RethrownError(nestedCallResults.revertReason.message, nestedCallResults.revertReason);
107
87
  }
108
88
 
109
- // We only take as much data as was specified in the return size and pad with zeroes if the return data is smaller
110
- // than the specified size in order to prevent that memory to be left with garbage
111
- const returnData = nestedCallResults.output.slice(0, this.retSize);
112
- const convertedReturnData = padArrayEnd(
113
- returnData.map(f => new Field(f)),
114
- new Field(0),
115
- this.retSize,
116
- );
89
+ // Save return/revert data for later.
90
+ const fullReturnData = nestedCallResults.output;
91
+ context.machineState.nestedReturndata = fullReturnData;
117
92
 
118
- // Write our return data into memory
119
- memory.set(successOffset, new Uint8(success ? 1 : 0));
120
- memory.setSlice(retOffset, convertedReturnData);
93
+ // Write our success flag into memory.
94
+ memory.set(successOffset, new Uint1(success ? 1 : 0));
121
95
 
122
96
  // Refund unused gas
123
97
  context.machineState.refundGas(gasLeftToGas(nestedContext.machineState));
@@ -132,7 +106,7 @@ abstract class ExternalCall extends Instruction {
132
106
  /*avmCallResults=*/ nestedCallResults,
133
107
  );
134
108
 
135
- memory.assert({ reads: calldataSize + 5, writes: 1 + this.retSize, addressing });
109
+ memory.assert({ reads: calldataSize + 4, writes: 1, addressing });
136
110
  context.machineState.incrementPc();
137
111
  }
138
112
 
@@ -204,22 +178,24 @@ export class Revert extends Instruction {
204
178
  OperandType.UINT16,
205
179
  ];
206
180
 
207
- constructor(private indirect: number, private returnOffset: number, private retSize: number) {
181
+ constructor(private indirect: number, private returnOffset: number, private retSizeOffset: number) {
208
182
  super();
209
183
  }
210
184
 
211
185
  public async execute(context: AvmContext): Promise<void> {
212
186
  const memory = context.machineState.memory.track(this.type);
213
- context.machineState.consumeGas(this.gasCost(this.retSize));
214
187
 
215
- const operands = [this.returnOffset];
188
+ const operands = [this.returnOffset, this.retSizeOffset];
216
189
  const addressing = Addressing.fromWire(this.indirect, operands.length);
217
- const [returnOffset] = addressing.resolve(operands, memory);
190
+ const [returnOffset, retSizeOffset] = addressing.resolve(operands, memory);
218
191
 
219
- const output = memory.getSlice(returnOffset, this.retSize).map(word => word.toFr());
192
+ memory.checkTag(TypeTag.UINT32, retSizeOffset);
193
+ const retSize = memory.get(retSizeOffset).toNumber();
194
+ context.machineState.consumeGas(this.gasCost(retSize));
195
+ const output = memory.getSlice(returnOffset, retSize).map(word => word.toFr());
220
196
 
221
197
  context.machineState.revert(output);
222
- memory.assert({ reads: this.retSize, addressing });
198
+ memory.assert({ reads: retSize + 1, addressing });
223
199
  }
224
200
  }
225
201
 
@@ -1,15 +1,7 @@
1
- import {
2
- keccak256,
3
- keccakf1600,
4
- pedersenHash,
5
- poseidon2Permutation,
6
- sha256Compression,
7
- } from '@aztec/foundation/crypto';
8
-
9
- import { strict as assert } from 'assert';
1
+ import { keccakf1600, poseidon2Permutation, sha256Compression } from '@aztec/foundation/crypto';
10
2
 
11
3
  import { type AvmContext } from '../avm_context.js';
12
- import { Field, TypeTag, Uint8, Uint32, Uint64 } from '../avm_memory_types.js';
4
+ import { Field, TypeTag, Uint32, Uint64 } from '../avm_memory_types.js';
13
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
14
6
  import { Addressing } from './addressing_mode.js';
15
7
  import { Instruction } from './instruction.js';
@@ -52,52 +44,6 @@ export class Poseidon2 extends Instruction {
52
44
  }
53
45
  }
54
46
 
55
- export class Keccak extends Instruction {
56
- static type: string = 'KECCAK';
57
- static readonly opcode: Opcode = Opcode.KECCAK;
58
-
59
- // Informs (de)serialization. See Instruction.deserialize.
60
- static readonly wireFormat: OperandType[] = [
61
- OperandType.UINT8,
62
- OperandType.UINT8,
63
- OperandType.UINT32,
64
- OperandType.UINT32,
65
- OperandType.UINT32,
66
- ];
67
-
68
- constructor(
69
- private indirect: number,
70
- private dstOffset: number,
71
- private messageOffset: number,
72
- private messageSizeOffset: number,
73
- ) {
74
- super();
75
- }
76
-
77
- // pub fn keccak256(input: [u8], message_size: u32) -> [u8; 32]
78
- public async execute(context: AvmContext): Promise<void> {
79
- const memory = context.machineState.memory.track(this.type);
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);
83
- memory.checkTag(TypeTag.UINT32, messageSizeOffset);
84
- const messageSize = memory.get(messageSizeOffset).toNumber();
85
- context.machineState.consumeGas(this.gasCost(messageSize));
86
-
87
- memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize);
88
-
89
- const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
90
- const hashBuffer = keccak256(messageData);
91
-
92
- // We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
93
- const res = [...hashBuffer].map(byte => new Uint8(byte));
94
- memory.setSlice(dstOffset, res);
95
-
96
- memory.assert({ reads: messageSize + 1, writes: 32, addressing });
97
- context.machineState.incrementPc();
98
- }
99
- }
100
-
101
47
  export class KeccakF1600 extends Instruction {
102
48
  static type: string = 'KECCAKF1600';
103
49
  static readonly opcode: Opcode = Opcode.KECCAKF1600;
@@ -108,39 +54,30 @@ export class KeccakF1600 extends Instruction {
108
54
  OperandType.UINT8,
109
55
  OperandType.UINT16,
110
56
  OperandType.UINT16,
111
- OperandType.UINT16,
112
57
  ];
113
58
 
114
- constructor(
115
- private indirect: number,
116
- private dstOffset: number,
117
- private stateOffset: number,
118
- // This is here for compatibility with the CPP side. Should be removed in both.
119
- private stateSizeOffset: number,
120
- ) {
59
+ constructor(private indirect: number, private dstOffset: number, private inputOffset: number) {
121
60
  super();
122
61
  }
123
62
 
124
63
  // pub fn keccakf1600(input: [u64; 25]) -> [u64; 25]
125
64
  public async execute(context: AvmContext): Promise<void> {
65
+ const inputSize = 25;
126
66
  const memory = context.machineState.memory.track(this.type);
127
- const operands = [this.dstOffset, this.stateOffset, this.stateSizeOffset];
67
+ const operands = [this.dstOffset, this.inputOffset];
128
68
  const addressing = Addressing.fromWire(this.indirect, operands.length);
129
- const [dstOffset, stateOffset, stateSizeOffset] = addressing.resolve(operands, memory);
130
- memory.checkTag(TypeTag.UINT32, stateSizeOffset);
131
- const stateSize = memory.get(stateSizeOffset).toNumber();
132
- assert(stateSize === 25, 'Invalid state size for keccakf1600');
69
+ const [dstOffset, inputOffset] = addressing.resolve(operands, memory);
133
70
  context.machineState.consumeGas(this.gasCost());
134
71
 
135
- memory.checkTagsRange(TypeTag.UINT64, stateOffset, stateSize);
72
+ memory.checkTagsRange(TypeTag.UINT64, inputOffset, inputSize);
136
73
 
137
- const stateData = memory.getSlice(stateOffset, stateSize).map(word => word.toBigInt());
74
+ const stateData = memory.getSlice(inputOffset, inputSize).map(word => word.toBigInt());
138
75
  const updatedState = keccakf1600(stateData);
139
76
 
140
77
  const res = updatedState.map(word => new Uint64(word));
141
78
  memory.setSlice(dstOffset, res);
142
79
 
143
- memory.assert({ reads: stateSize + 1, writes: 25, addressing });
80
+ memory.assert({ reads: inputSize, writes: inputSize, addressing });
144
81
  context.machineState.incrementPc();
145
82
  }
146
83
  }
@@ -193,53 +130,3 @@ export class Sha256Compression extends Instruction {
193
130
  context.machineState.incrementPc();
194
131
  }
195
132
  }
196
-
197
- export class Pedersen extends Instruction {
198
- static type: string = 'PEDERSEN';
199
- static readonly opcode: Opcode = Opcode.PEDERSEN;
200
-
201
- // Informs (de)serialization. See Instruction.deserialize.
202
- static readonly wireFormat: OperandType[] = [
203
- OperandType.UINT8,
204
- OperandType.UINT8,
205
- OperandType.UINT32,
206
- OperandType.UINT32,
207
- OperandType.UINT32,
208
- OperandType.UINT32,
209
- ];
210
-
211
- constructor(
212
- private indirect: number,
213
- private genIndexOffset: number,
214
- private dstOffset: number,
215
- private messageOffset: number,
216
- private messageSizeOffset: number,
217
- ) {
218
- super();
219
- }
220
-
221
- public async execute(context: AvmContext): Promise<void> {
222
- const memory = context.machineState.memory.track(this.type);
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);
226
-
227
- // We hash a set of field elements
228
- const genIndex = Number(memory.get(genIndexOffset).toBigInt());
229
- memory.checkTag(TypeTag.UINT32, genIndexOffset);
230
- const messageSize = Number(memory.get(messageSizeOffset).toBigInt());
231
- memory.checkTag(TypeTag.UINT32, messageSizeOffset);
232
- const hashData = memory.getSlice(messageOffset, messageSize);
233
-
234
- context.machineState.consumeGas(this.gasCost(messageSize));
235
-
236
- memory.checkTagsRange(TypeTag.FIELD, messageOffset, messageSize);
237
-
238
- // No domain sep for now
239
- const hash = pedersenHash(hashData, genIndex);
240
- memory.set(dstOffset, new Field(hash));
241
-
242
- memory.assert({ reads: messageSize + 2, writes: 1, addressing });
243
- context.machineState.incrementPc();
244
- }
245
- }
@@ -13,4 +13,3 @@ export * from './environment_getters.js';
13
13
  export * from './accrued_substate.js';
14
14
  export * from './hashing.js';
15
15
  export * from './ec_add.js';
16
- export * from './commitment.js';
@@ -1,5 +1,5 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
- import { Field, TaggedMemory } from '../avm_memory_types.js';
2
+ import { Field, TaggedMemory, TypeTag, Uint32 } from '../avm_memory_types.js';
3
3
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
4
4
  import { Addressing } from './addressing_mode.js';
5
5
  import { Instruction } from './instruction.js';
@@ -179,11 +179,11 @@ export class CalldataCopy extends Instruction {
179
179
 
180
180
  public async execute(context: AvmContext): Promise<void> {
181
181
  const memory = context.machineState.memory.track(this.type);
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.
183
182
  const operands = [this.cdStartOffset, this.copySizeOffset, this.dstOffset];
184
183
  const addressing = Addressing.fromWire(this.indirect, operands.length);
185
184
  const [cdStartOffset, copySizeOffset, dstOffset] = addressing.resolve(operands, memory);
186
185
 
186
+ memory.checkTags(TypeTag.UINT32, cdStartOffset, copySizeOffset);
187
187
  const cdStart = memory.get(cdStartOffset).toNumber();
188
188
  const copySize = memory.get(copySizeOffset).toNumber();
189
189
  context.machineState.consumeGas(this.gasCost(copySize));
@@ -196,3 +196,70 @@ export class CalldataCopy extends Instruction {
196
196
  context.machineState.incrementPc();
197
197
  }
198
198
  }
199
+
200
+ export class ReturndataSize extends Instruction {
201
+ static readonly type: string = 'RETURNDATASIZE';
202
+ static readonly opcode: Opcode = Opcode.RETURNDATASIZE;
203
+ // Informs (de)serialization. See Instruction.deserialize.
204
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
205
+
206
+ constructor(private indirect: number, private dstOffset: number) {
207
+ super();
208
+ }
209
+
210
+ public async execute(context: AvmContext): Promise<void> {
211
+ const memory = context.machineState.memory.track(this.type);
212
+ const operands = [this.dstOffset];
213
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
214
+ const [dstOffset] = addressing.resolve(operands, memory);
215
+ context.machineState.consumeGas(this.gasCost());
216
+
217
+ memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
218
+
219
+ memory.assert({ writes: 1, addressing });
220
+ context.machineState.incrementPc();
221
+ }
222
+ }
223
+
224
+ export class ReturndataCopy extends Instruction {
225
+ static readonly type: string = 'RETURNDATACOPY';
226
+ static readonly opcode: Opcode = Opcode.RETURNDATACOPY;
227
+ // Informs (de)serialization. See Instruction.deserialize.
228
+ static readonly wireFormat: OperandType[] = [
229
+ OperandType.UINT8,
230
+ OperandType.UINT8,
231
+ OperandType.UINT16,
232
+ OperandType.UINT16,
233
+ OperandType.UINT16,
234
+ ];
235
+
236
+ constructor(
237
+ private indirect: number,
238
+ private rdStartOffset: number,
239
+ private copySizeOffset: number,
240
+ private dstOffset: number,
241
+ ) {
242
+ super();
243
+ }
244
+
245
+ public async execute(context: AvmContext): Promise<void> {
246
+ const memory = context.machineState.memory.track(this.type);
247
+ const operands = [this.rdStartOffset, this.copySizeOffset, this.dstOffset];
248
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
249
+ const [rdStartOffset, copySizeOffset, dstOffset] = addressing.resolve(operands, memory);
250
+
251
+ memory.checkTags(TypeTag.UINT32, rdStartOffset, copySizeOffset);
252
+ const rdStart = memory.get(rdStartOffset).toNumber();
253
+ const copySize = memory.get(copySizeOffset).toNumber();
254
+ context.machineState.consumeGas(this.gasCost(copySize));
255
+
256
+ const transformedData = context.machineState.nestedReturndata
257
+ .slice(rdStart, rdStart + copySize)
258
+ .map(f => new Field(f));
259
+
260
+ memory.setSlice(dstOffset, transformedData);
261
+
262
+ memory.assert({ reads: 2, writes: copySize, addressing });
263
+ context.machineState.incrementPc();
264
+ }
265
+ }
@@ -43,7 +43,7 @@ export class SStore extends BaseStorageInstruction {
43
43
 
44
44
  const slot = memory.get(slotOffset).toFr();
45
45
  const value = memory.get(srcOffset).toFr();
46
- context.persistableState.writeStorage(context.environment.storageAddress, slot, value);
46
+ context.persistableState.writeStorage(context.environment.address, slot, value);
47
47
 
48
48
  memory.assert({ reads: 2, addressing });
49
49
  context.machineState.incrementPc();
@@ -68,7 +68,7 @@ export class SLoad extends BaseStorageInstruction {
68
68
  memory.checkTag(TypeTag.FIELD, slotOffset);
69
69
 
70
70
  const slot = memory.get(slotOffset).toFr();
71
- const value = await context.persistableState.readStorage(context.environment.storageAddress, slot);
71
+ const value = await context.persistableState.readStorage(context.environment.address, slot);
72
72
  memory.set(dstOffset, new Field(value));
73
73
 
74
74
  context.machineState.incrementPc();