@aztec/simulator 0.34.0 → 0.35.1

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 (168) hide show
  1. package/dest/acvm/acvm.d.ts +4 -1
  2. package/dest/acvm/acvm.d.ts.map +1 -1
  3. package/dest/acvm/acvm.js +5 -5
  4. package/dest/acvm/deserialize.d.ts +3 -5
  5. package/dest/acvm/deserialize.d.ts.map +1 -1
  6. package/dest/acvm/deserialize.js +6 -9
  7. package/dest/acvm/oracle/oracle.d.ts +2 -0
  8. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  9. package/dest/acvm/oracle/oracle.js +12 -4
  10. package/dest/acvm/oracle/typed_oracle.d.ts +2 -0
  11. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  12. package/dest/acvm/oracle/typed_oracle.js +7 -1
  13. package/dest/avm/avm_execution_environment.d.ts +4 -2
  14. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  15. package/dest/avm/avm_execution_environment.js +7 -5
  16. package/dest/avm/avm_gas.js +2 -2
  17. package/dest/avm/avm_machine_state.d.ts +2 -0
  18. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  19. package/dest/avm/avm_machine_state.js +24 -6
  20. package/dest/avm/avm_memory_types.js +2 -2
  21. package/dest/avm/avm_simulator.js +2 -2
  22. package/dest/avm/fixtures/index.d.ts +3 -0
  23. package/dest/avm/fixtures/index.d.ts.map +1 -1
  24. package/dest/avm/fixtures/index.js +11 -4
  25. package/dest/avm/journal/journal.d.ts +1 -0
  26. package/dest/avm/journal/journal.d.ts.map +1 -1
  27. package/dest/avm/journal/journal.js +12 -1
  28. package/dest/avm/opcodes/accrued_substate.d.ts +2 -1
  29. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  30. package/dest/avm/opcodes/accrued_substate.js +13 -5
  31. package/dest/avm/opcodes/context_getters.js +2 -2
  32. package/dest/avm/opcodes/external_calls.d.ts +2 -2
  33. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  34. package/dest/avm/opcodes/external_calls.js +7 -6
  35. package/dest/avm/opcodes/hashing.d.ts +8 -8
  36. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  37. package/dest/avm/opcodes/hashing.js +35 -43
  38. package/dest/avm/serialization/instruction_serialization.d.ts +1 -1
  39. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  40. package/dest/avm/serialization/instruction_serialization.js +2 -2
  41. package/dest/client/client_execution_context.d.ts +13 -3
  42. package/dest/client/client_execution_context.d.ts.map +1 -1
  43. package/dest/client/client_execution_context.js +23 -8
  44. package/dest/client/private_execution.d.ts.map +1 -1
  45. package/dest/client/private_execution.js +8 -6
  46. package/dest/client/simulator.d.ts.map +1 -1
  47. package/dest/client/simulator.js +6 -5
  48. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  49. package/dest/client/unconstrained_execution.js +5 -4
  50. package/dest/common/index.d.ts +1 -1
  51. package/dest/common/index.d.ts.map +1 -1
  52. package/dest/common/index.js +2 -2
  53. package/dest/common/packed_values_cache.d.ts +28 -0
  54. package/dest/common/packed_values_cache.d.ts.map +1 -0
  55. package/dest/common/packed_values_cache.js +50 -0
  56. package/dest/index.d.ts +1 -0
  57. package/dest/index.d.ts.map +1 -1
  58. package/dest/index.js +2 -1
  59. package/dest/mocks/fixtures.d.ts +42 -0
  60. package/dest/mocks/fixtures.d.ts.map +1 -0
  61. package/dest/mocks/fixtures.js +84 -0
  62. package/dest/mocks/index.d.ts +2 -0
  63. package/dest/mocks/index.d.ts.map +1 -0
  64. package/dest/mocks/index.js +2 -0
  65. package/dest/public/abstract_phase_manager.d.ts +82 -0
  66. package/dest/public/abstract_phase_manager.d.ts.map +1 -0
  67. package/dest/public/abstract_phase_manager.js +320 -0
  68. package/dest/public/app_logic_phase_manager.d.ts +29 -0
  69. package/dest/public/app_logic_phase_manager.d.ts.map +1 -0
  70. package/dest/public/app_logic_phase_manager.js +50 -0
  71. package/dest/public/execution.d.ts +3 -0
  72. package/dest/public/execution.d.ts.map +1 -1
  73. package/dest/public/execution.js +1 -1
  74. package/dest/public/executor.d.ts.map +1 -1
  75. package/dest/public/executor.js +17 -13
  76. package/dest/public/hints_builder.d.ts +23 -0
  77. package/dest/public/hints_builder.d.ts.map +1 -0
  78. package/dest/public/hints_builder.js +62 -0
  79. package/dest/public/index.d.ts +5 -0
  80. package/dest/public/index.d.ts.map +1 -1
  81. package/dest/public/index.js +6 -1
  82. package/dest/public/phase_manager_factory.d.ts +18 -0
  83. package/dest/public/phase_manager_factory.d.ts.map +1 -0
  84. package/dest/public/phase_manager_factory.js +56 -0
  85. package/dest/public/public_execution_context.d.ts +15 -5
  86. package/dest/public/public_execution_context.d.ts.map +1 -1
  87. package/dest/public/public_execution_context.js +28 -12
  88. package/dest/public/public_executor.d.ts +79 -0
  89. package/dest/public/public_executor.d.ts.map +1 -0
  90. package/dest/public/public_executor.js +198 -0
  91. package/dest/public/public_kernel.d.ts +37 -0
  92. package/dest/public/public_kernel.d.ts.map +1 -0
  93. package/dest/public/public_kernel.js +97 -0
  94. package/dest/public/public_kernel_circuit_simulator.d.ts +31 -0
  95. package/dest/public/public_kernel_circuit_simulator.d.ts.map +1 -0
  96. package/dest/public/public_kernel_circuit_simulator.js +2 -0
  97. package/dest/public/public_processor.d.ts +53 -0
  98. package/dest/public/public_processor.d.ts.map +1 -0
  99. package/dest/public/public_processor.js +144 -0
  100. package/dest/public/setup_phase_manager.d.ts +30 -0
  101. package/dest/public/setup_phase_manager.d.ts.map +1 -0
  102. package/dest/public/setup_phase_manager.js +46 -0
  103. package/dest/public/tail_phase_manager.d.ts +30 -0
  104. package/dest/public/tail_phase_manager.d.ts.map +1 -0
  105. package/dest/public/tail_phase_manager.js +60 -0
  106. package/dest/public/teardown_phase_manager.d.ts +30 -0
  107. package/dest/public/teardown_phase_manager.d.ts.map +1 -0
  108. package/dest/public/teardown_phase_manager.js +46 -0
  109. package/dest/public/transitional_adaptors.d.ts +2 -1
  110. package/dest/public/transitional_adaptors.d.ts.map +1 -1
  111. package/dest/public/transitional_adaptors.js +11 -10
  112. package/dest/public/utils.d.ts +8 -0
  113. package/dest/public/utils.d.ts.map +1 -0
  114. package/dest/public/utils.js +29 -0
  115. package/dest/simulator/acvm_native.d.ts +19 -3
  116. package/dest/simulator/acvm_native.d.ts.map +1 -1
  117. package/dest/simulator/acvm_native.js +75 -48
  118. package/dest/simulator/acvm_wasm.d.ts.map +1 -1
  119. package/dest/simulator/acvm_wasm.js +3 -4
  120. package/package.json +8 -5
  121. package/src/acvm/acvm.ts +8 -5
  122. package/src/acvm/deserialize.ts +5 -9
  123. package/src/acvm/oracle/oracle.ts +13 -3
  124. package/src/acvm/oracle/typed_oracle.ts +8 -0
  125. package/src/avm/avm_execution_environment.ts +9 -1
  126. package/src/avm/avm_gas.ts +1 -1
  127. package/src/avm/avm_machine_state.ts +26 -5
  128. package/src/avm/avm_memory_types.ts +1 -1
  129. package/src/avm/avm_simulator.ts +1 -1
  130. package/src/avm/fixtures/index.ts +13 -1
  131. package/src/avm/journal/journal.ts +13 -0
  132. package/src/avm/opcodes/accrued_substate.ts +16 -4
  133. package/src/avm/opcodes/context_getters.ts +1 -1
  134. package/src/avm/opcodes/external_calls.ts +8 -5
  135. package/src/avm/opcodes/hashing.ts +38 -54
  136. package/src/avm/serialization/instruction_serialization.ts +1 -1
  137. package/src/client/client_execution_context.ts +25 -6
  138. package/src/client/private_execution.ts +7 -6
  139. package/src/client/simulator.ts +7 -3
  140. package/src/client/unconstrained_execution.ts +4 -3
  141. package/src/common/index.ts +1 -1
  142. package/src/common/packed_values_cache.ts +55 -0
  143. package/src/index.ts +1 -0
  144. package/src/mocks/fixtures.ts +169 -0
  145. package/src/mocks/index.ts +1 -0
  146. package/src/public/abstract_phase_manager.ts +571 -0
  147. package/src/public/app_logic_phase_manager.ts +76 -0
  148. package/src/public/execution.ts +4 -0
  149. package/src/public/executor.ts +18 -13
  150. package/src/public/hints_builder.ts +119 -0
  151. package/src/public/index.ts +5 -0
  152. package/src/public/phase_manager_factory.ts +126 -0
  153. package/src/public/public_execution_context.ts +29 -18
  154. package/src/public/public_executor.ts +267 -0
  155. package/src/public/public_kernel.ts +139 -0
  156. package/src/public/public_kernel_circuit_simulator.ts +36 -0
  157. package/src/public/public_processor.ts +212 -0
  158. package/src/public/setup_phase_manager.ts +66 -0
  159. package/src/public/tail_phase_manager.ts +120 -0
  160. package/src/public/teardown_phase_manager.ts +66 -0
  161. package/src/public/transitional_adaptors.ts +14 -5
  162. package/src/public/utils.ts +31 -0
  163. package/src/simulator/acvm_native.ts +94 -47
  164. package/src/simulator/acvm_wasm.ts +7 -3
  165. package/dest/common/packed_args_cache.d.ts +0 -28
  166. package/dest/common/packed_args_cache.d.ts.map +0 -1
  167. package/dest/common/packed_args_cache.js +0 -50
  168. package/src/common/packed_args_cache.ts +0 -55
@@ -80,19 +80,31 @@ export class NullifierExists extends Instruction {
80
80
  static type: string = 'NULLIFIEREXISTS';
81
81
  static readonly opcode: Opcode = Opcode.NULLIFIEREXISTS;
82
82
  // Informs (de)serialization. See Instruction.deserialize.
83
- static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32];
83
+ static readonly wireFormat = [
84
+ OperandType.UINT8,
85
+ OperandType.UINT8,
86
+ OperandType.UINT32,
87
+ OperandType.UINT32,
88
+ OperandType.UINT32,
89
+ ];
84
90
 
85
- constructor(private indirect: number, private nullifierOffset: number, private existsOffset: number) {
91
+ constructor(
92
+ private indirect: number,
93
+ private nullifierOffset: number,
94
+ private addressOffset: number,
95
+ private existsOffset: number,
96
+ ) {
86
97
  super();
87
98
  }
88
99
 
89
100
  public async execute(context: AvmContext): Promise<void> {
90
- const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
101
+ const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
91
102
  const memory = context.machineState.memory.track(this.type);
92
103
  context.machineState.consumeGas(this.gasCost(memoryOperations));
93
104
 
94
105
  const nullifier = memory.get(this.nullifierOffset).toFr();
95
- const exists = await context.persistableState.checkNullifierExists(context.environment.storageAddress, nullifier);
106
+ const address = memory.get(this.addressOffset).toFr();
107
+ const exists = await context.persistableState.checkNullifierExists(address, nullifier);
96
108
 
97
109
  memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
98
110
 
@@ -7,7 +7,7 @@ export class L2GasLeft extends GetterInstruction {
7
7
  static type: string = 'L2GASLEFT';
8
8
  static readonly opcode: Opcode = Opcode.L2GASLEFT;
9
9
 
10
- // TODO(@spalladino) Yellow paper specifies that the value should be an Uint32, not a Field.
10
+ // TODO(@spalladino) Protocol specs specifies that the value should be an Uint32, not a Field.
11
11
  protected getValue(context: AvmContext): MemoryValue {
12
12
  return new Field(context.machineState.l2GasLeft);
13
13
  }
@@ -36,7 +36,7 @@ abstract class ExternalCall extends Instruction {
36
36
  private gasOffset: number /* Unused due to no formal gas implementation at this moment */,
37
37
  private addrOffset: number,
38
38
  private argsOffset: number,
39
- private argsSize: number,
39
+ private argsSizeOffset: number,
40
40
  private retOffset: number,
41
41
  private retSize: number,
42
42
  private successOffset: number,
@@ -50,20 +50,23 @@ abstract class ExternalCall extends Instruction {
50
50
 
51
51
  public async execute(context: AvmContext) {
52
52
  const memory = context.machineState.memory.track(this.type);
53
- const [gasOffset, addrOffset, argsOffset, retOffset, successOffset] = Addressing.fromWire(this.indirect).resolve(
54
- [this.gasOffset, this.addrOffset, this.argsOffset, this.retOffset, this.successOffset],
53
+ const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset] = Addressing.fromWire(
54
+ this.indirect,
55
+ ).resolve(
56
+ [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.retOffset, this.successOffset],
55
57
  memory,
56
58
  );
57
59
 
58
60
  const callAddress = memory.getAs<Field>(addrOffset);
59
- const calldata = memory.getSlice(argsOffset, this.argsSize).map(f => f.toFr());
61
+ const calldataSize = memory.get(argsSizeOffset).toNumber();
62
+ const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
60
63
  const l1Gas = memory.get(gasOffset).toNumber();
61
64
  const l2Gas = memory.getAs<Field>(gasOffset + 1).toNumber();
62
65
  const daGas = memory.getAs<Field>(gasOffset + 2).toNumber();
63
66
  const functionSelector = memory.getAs<Field>(this.temporaryFunctionSelectorOffset).toFr();
64
67
 
65
68
  const allocatedGas = { l1Gas, l2Gas, daGas };
66
- const memoryOperations = { reads: this.argsSize + 5, writes: 1 + this.retSize, indirect: this.indirect };
69
+ const memoryOperations = { reads: calldataSize + 6, writes: 1 + this.retSize, indirect: this.indirect };
67
70
  const totalGas = sumGas(this.gasCost(memoryOperations), allocatedGas);
68
71
  context.machineState.consumeGas(totalGas);
69
72
 
@@ -1,15 +1,15 @@
1
- import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
2
- import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/crypto';
1
+ import { keccak256, pedersenHash, poseidon2Permutation, sha256 } from '@aztec/foundation/crypto';
3
2
 
4
3
  import { type AvmContext } from '../avm_context.js';
5
- import { Field } from '../avm_memory_types.js';
4
+ import { Field, Uint8 } from '../avm_memory_types.js';
6
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
7
6
  import { Addressing } from './addressing_mode.js';
8
7
  import { Instruction } from './instruction.js';
9
8
 
10
9
  export class Poseidon2 extends Instruction {
11
10
  static type: string = 'POSEIDON2';
12
- static readonly opcode: Opcode = Opcode.POSEIDON;
11
+ static readonly opcode: Opcode = Opcode.POSEIDON2;
12
+ static readonly stateSize = 4;
13
13
 
14
14
  // Informs (de)serialization. See Instruction.deserialize.
15
15
  static readonly wireFormat: OperandType[] = [
@@ -17,34 +17,28 @@ export class Poseidon2 extends Instruction {
17
17
  OperandType.UINT8,
18
18
  OperandType.UINT32,
19
19
  OperandType.UINT32,
20
- OperandType.UINT32,
21
20
  ];
22
21
 
23
- constructor(
24
- private indirect: number,
25
- private dstOffset: number,
26
- private messageOffset: number,
27
- private messageSize: number,
28
- ) {
22
+ constructor(private indirect: number, private inputStateOffset: number, private outputStateOffset: number) {
29
23
  super();
30
24
  }
31
25
 
32
26
  public async execute(context: AvmContext): Promise<void> {
33
- const memoryOperations = { reads: this.messageSize, writes: 1, indirect: this.indirect };
27
+ const memoryOperations = { reads: Poseidon2.stateSize, writes: Poseidon2.stateSize, indirect: this.indirect };
34
28
  const memory = context.machineState.memory.track(this.type);
35
29
  context.machineState.consumeGas(this.gasCost(memoryOperations));
36
30
 
37
- // We hash a set of field elements
38
- const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
39
- [this.dstOffset, this.messageOffset],
31
+ const [inputOffset, outputOffset] = Addressing.fromWire(this.indirect).resolve(
32
+ [this.inputStateOffset, this.outputStateOffset],
40
33
  memory,
41
34
  );
42
35
 
43
- // Memory pointer will be indirect
44
- const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
45
-
46
- const hash = poseidonHash(hashData);
47
- memory.set(dstOffset, new Field(hash));
36
+ const inputState = memory.getSlice(inputOffset, Poseidon2.stateSize);
37
+ const outputState = poseidon2Permutation(inputState);
38
+ memory.setSlice(
39
+ outputOffset,
40
+ outputState.map(word => new Field(word)),
41
+ );
48
42
 
49
43
  memory.assert(memoryOperations);
50
44
  context.machineState.incrementPc();
@@ -68,33 +62,28 @@ export class Keccak extends Instruction {
68
62
  private indirect: number,
69
63
  private dstOffset: number,
70
64
  private messageOffset: number,
71
- private messageSize: number,
65
+ private messageSizeOffset: number,
72
66
  ) {
73
67
  super();
74
68
  }
75
69
 
76
- // Note hash output is 32 bytes, so takes up two fields
70
+ // pub fn keccak256(input: [u8], message_size: u32) -> [u8; 32]
77
71
  public async execute(context: AvmContext): Promise<void> {
78
- const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
79
72
  const memory = context.machineState.memory.track(this.type);
80
- context.machineState.consumeGas(this.gasCost(memoryOperations));
81
-
82
- // We hash a set of field elements
83
- const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
84
- [this.dstOffset, this.messageOffset],
73
+ const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
74
+ [this.dstOffset, this.messageOffset, this.messageSizeOffset],
85
75
  memory,
86
76
  );
77
+ const messageSize = memory.get(messageSizeOffset).toNumber();
78
+ const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
79
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
87
80
 
88
- const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
89
-
90
- const hash = keccak(Buffer.concat(hashData));
91
-
92
- // Split output into two fields
93
- const high = new Field(toBigIntBE(hash.subarray(0, 16)));
94
- const low = new Field(toBigIntBE(hash.subarray(16, 32)));
81
+ const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
82
+ const hashBuffer = keccak256(messageData);
95
83
 
96
- memory.set(dstOffset, high);
97
- memory.set(dstOffset + 1, low);
84
+ // We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
85
+ const res = [...hashBuffer].map(byte => new Uint8(byte));
86
+ memory.setSlice(dstOffset, res);
98
87
 
99
88
  memory.assert(memoryOperations);
100
89
  context.machineState.incrementPc();
@@ -118,33 +107,28 @@ export class Sha256 extends Instruction {
118
107
  private indirect: number,
119
108
  private dstOffset: number,
120
109
  private messageOffset: number,
121
- private messageSize: number,
110
+ private messageSizeOffset: number,
122
111
  ) {
123
112
  super();
124
113
  }
125
114
 
126
- // Note hash output is 32 bytes, so takes up two fields
115
+ // pub fn sha256_slice(input: [u8]) -> [u8; 32]
127
116
  public async execute(context: AvmContext): Promise<void> {
128
- const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
129
117
  const memory = context.machineState.memory.track(this.type);
130
- context.machineState.consumeGas(this.gasCost(memoryOperations));
131
-
132
- const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
133
- [this.dstOffset, this.messageOffset],
118
+ const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
119
+ [this.dstOffset, this.messageOffset, this.messageSizeOffset],
134
120
  memory,
135
121
  );
122
+ const messageSize = memory.get(messageSizeOffset).toNumber();
123
+ const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
124
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
136
125
 
137
- // We hash a set of field elements
138
- const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
139
-
140
- const hash = sha256(Buffer.concat(hashData));
141
-
142
- // Split output into two fields
143
- const high = new Field(toBigIntBE(hash.subarray(0, 16)));
144
- const low = new Field(toBigIntBE(hash.subarray(16, 32)));
126
+ const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
127
+ const hashBuffer = sha256(messageData);
145
128
 
146
- memory.set(dstOffset, high);
147
- memory.set(dstOffset + 1, low);
129
+ // We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
130
+ const res = [...hashBuffer].map(byte => new Uint8(byte));
131
+ memory.setSlice(dstOffset, res);
148
132
 
149
133
  memory.assert(memoryOperations);
150
134
  context.machineState.incrementPc();
@@ -75,7 +75,7 @@ export enum Opcode {
75
75
  REVERT,
76
76
  // Gadgets
77
77
  KECCAK,
78
- POSEIDON,
78
+ POSEIDON2,
79
79
  SHA256, // temp - may be removed, but alot of contracts rely on it
80
80
  PEDERSEN, // temp - may be removed, but alot of contracts rely on it
81
81
  }
@@ -28,7 +28,7 @@ import { Fr, type Point } from '@aztec/foundation/fields';
28
28
  import { createDebugLogger } from '@aztec/foundation/log';
29
29
 
30
30
  import { type NoteData, toACVMWitness } from '../acvm/index.js';
31
- import { type PackedArgsCache } from '../common/packed_args_cache.js';
31
+ import { type PackedValuesCache } from '../common/packed_values_cache.js';
32
32
  import { type DBOracle } from './db_oracle.js';
33
33
  import { type ExecutionNoteCache } from './execution_note_cache.js';
34
34
  import { type ExecutionResult, type NoteAndSlot } from './execution_result.js';
@@ -72,7 +72,7 @@ export class ClientExecutionContext extends ViewDataOracle {
72
72
  protected readonly historicalHeader: Header,
73
73
  /** List of transient auth witnesses to be used during this simulation */
74
74
  protected readonly authWitnesses: AuthWitness[],
75
- private readonly packedArgsCache: PackedArgsCache,
75
+ private readonly packedValuesCache: PackedValuesCache,
76
76
  private readonly noteCache: ExecutionNoteCache,
77
77
  protected readonly db: DBOracle,
78
78
  private readonly curve: Grumpkin,
@@ -93,7 +93,7 @@ export class ClientExecutionContext extends ViewDataOracle {
93
93
  public getInitialWitness(abi: FunctionAbi) {
94
94
  const argumentsSize = countArgumentsSize(abi);
95
95
 
96
- const args = this.packedArgsCache.unpack(this.argsHash);
96
+ const args = this.packedValuesCache.unpack(this.argsHash);
97
97
 
98
98
  if (args.length !== argumentsSize) {
99
99
  throw new Error('Invalid arguments size');
@@ -175,7 +175,23 @@ export class ClientExecutionContext extends ViewDataOracle {
175
175
  * @param args - Arguments to pack
176
176
  */
177
177
  public packArguments(args: Fr[]): Promise<Fr> {
178
- return Promise.resolve(this.packedArgsCache.pack(args));
178
+ return Promise.resolve(this.packedValuesCache.pack(args));
179
+ }
180
+
181
+ /**
182
+ * Pack the given returns.
183
+ * @param returns - Returns to pack
184
+ */
185
+ public packReturns(returns: Fr[]): Promise<Fr> {
186
+ return Promise.resolve(this.packedValuesCache.pack(returns));
187
+ }
188
+
189
+ /**
190
+ * Unpack the given returns.
191
+ * @param returnsHash - Returns hash to unpack
192
+ */
193
+ public unpackReturns(returnsHash: Fr): Promise<Fr[]> {
194
+ return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
179
195
  }
180
196
 
181
197
  /**
@@ -375,7 +391,7 @@ export class ClientExecutionContext extends ViewDataOracle {
375
391
  derivedCallContext,
376
392
  this.historicalHeader,
377
393
  this.authWitnesses,
378
- this.packedArgsCache,
394
+ this.packedValuesCache,
379
395
  this.noteCache,
380
396
  this.db,
381
397
  this.curve,
@@ -428,7 +444,7 @@ export class ClientExecutionContext extends ViewDataOracle {
428
444
  isDelegateCall,
429
445
  isStaticCall,
430
446
  );
431
- const args = this.packedArgsCache.unpack(argsHash);
447
+ const args = this.packedValuesCache.unpack(argsHash);
432
448
  const enqueuedRequest = PublicCallRequest.from({
433
449
  args,
434
450
  callContext: derivedCallContext,
@@ -472,9 +488,12 @@ export class ClientExecutionContext extends ViewDataOracle {
472
488
  isDelegateCall ? this.contractAddress : targetContractAddress,
473
489
  portalContractAddress,
474
490
  FunctionSelector.fromNameAndParameters(targetArtifact.name, targetArtifact.parameters),
491
+ this.callContext.gasLeft, // TODO(palla/gas): We should deduct DA and L1 gas used for the derived context
475
492
  isDelegateCall,
476
493
  isStaticCall,
477
494
  startSideEffectCounter,
495
+ this.callContext.gasSettings,
496
+ this.callContext.transactionFee,
478
497
  );
479
498
  }
480
499
 
@@ -4,7 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address';
4
4
  import { Fr } from '@aztec/foundation/fields';
5
5
  import { createDebugLogger } from '@aztec/foundation/log';
6
6
 
7
- import { extractReturnWitness } from '../acvm/deserialize.js';
7
+ import { witnessMapToFields } from '../acvm/deserialize.js';
8
8
  import { Oracle, acvm, extractCallStack } from '../acvm/index.js';
9
9
  import { ExecutionError } from '../common/errors.js';
10
10
  import { type ClientExecutionContext } from './client_execution_context.js';
@@ -26,7 +26,7 @@ export async function executePrivateFunction(
26
26
  const acir = artifact.bytecode;
27
27
  const initialWitness = context.getInitialWitness(artifact);
28
28
  const acvmCallback = new Oracle(context);
29
- const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch(
29
+ const acirExecutionResult = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch(
30
30
  (err: Error) => {
31
31
  throw new ExecutionError(
32
32
  err.message,
@@ -39,8 +39,8 @@ export async function executePrivateFunction(
39
39
  );
40
40
  },
41
41
  );
42
-
43
- const returnWitness = extractReturnWitness(acir, partialWitness);
42
+ const partialWitness = acirExecutionResult.partialWitness;
43
+ const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
44
44
  const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness);
45
45
 
46
46
  const encryptedLogs = context.getEncryptedLogs();
@@ -55,9 +55,10 @@ export async function executePrivateFunction(
55
55
 
56
56
  // Mocking the return type to be an array of 4 fields
57
57
  // TODO: @LHerskind must be updated as we are progressing with the macros to get the information
58
- const returnTypes: AbiType[] = [{ kind: 'array', length: 4, type: { kind: 'field' } }];
58
+ const rawReturnValues = await context.unpackReturns(publicInputs.returnsHash);
59
+ const returnTypes: AbiType[] = [{ kind: 'array', length: rawReturnValues.length, type: { kind: 'field' } }];
59
60
  const mockArtifact = { ...artifact, returnTypes };
60
- const returnValues = decodeReturnValues(mockArtifact, publicInputs.returnValues);
61
+ const returnValues = decodeReturnValues(mockArtifact, rawReturnValues);
61
62
 
62
63
  const noteHashReadRequestPartialWitnesses = context.getNoteHashReadRequestPartialWitnesses(
63
64
  publicInputs.noteHashReadRequests,
@@ -16,7 +16,7 @@ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
16
16
  import { type WasmBlackBoxFunctionSolver, createBlackBoxSolver } from '@noir-lang/acvm_js';
17
17
 
18
18
  import { createSimulationError } from '../common/errors.js';
19
- import { PackedArgsCache } from '../common/packed_args_cache.js';
19
+ import { PackedValuesCache } from '../common/packed_values_cache.js';
20
20
  import { ClientExecutionContext } from './client_execution_context.js';
21
21
  import { type DBOracle } from './db_oracle.js';
22
22
  import { ExecutionNoteCache } from './execution_note_cache.js';
@@ -89,14 +89,18 @@ export class AcirSimulator {
89
89
  // reserve the first side effect for the tx hash (inserted by the private kernel)
90
90
  const startSideEffectCounter = 1;
91
91
 
92
+ const transactionFee = Fr.ZERO;
92
93
  const callContext = new CallContext(
93
94
  msgSender,
94
95
  contractAddress,
95
96
  portalContractAddress,
96
97
  FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters),
98
+ request.gasSettings.getInitialAvailable(),
97
99
  false,
98
100
  false,
99
101
  startSideEffectCounter,
102
+ request.gasSettings,
103
+ transactionFee,
100
104
  );
101
105
  const context = new ClientExecutionContext(
102
106
  contractAddress,
@@ -105,7 +109,7 @@ export class AcirSimulator {
105
109
  callContext,
106
110
  header,
107
111
  request.authWitnesses,
108
- PackedArgsCache.create(request.packedArguments),
112
+ PackedValuesCache.create(request.packedArguments),
109
113
  new ExecutionNoteCache(),
110
114
  this.db,
111
115
  curve,
@@ -194,7 +198,7 @@ export class AcirSimulator {
194
198
  const maxNoteFields = (artifact.parameters[artifact.parameters.length - 1].type as ArrayType).length;
195
199
  if (maxNoteFields < note.items.length) {
196
200
  throw new Error(
197
- `The note being processed has ${note.items.length} fields, while "compute_note_hash_and_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please consider increasing the allowed field size to accommodate all notes generated from the contract.`,
201
+ `The note being processed has ${note.items.length} fields, while "compute_note_hash_and_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please reduce the number of fields in your note.`,
198
202
  );
199
203
  }
200
204
 
@@ -4,7 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address';
4
4
  import { type Fr } from '@aztec/foundation/fields';
5
5
  import { createDebugLogger } from '@aztec/foundation/log';
6
6
 
7
- import { extractReturnWitness } from '../acvm/deserialize.js';
7
+ import { witnessMapToFields } from '../acvm/deserialize.js';
8
8
  import { Oracle, acvm, extractCallStack, toACVMWitness } from '../acvm/index.js';
9
9
  import { ExecutionError } from '../common/errors.js';
10
10
  import { AcirSimulator } from './simulator.js';
@@ -27,7 +27,7 @@ export async function executeUnconstrainedFunction(
27
27
 
28
28
  const acir = artifact.bytecode;
29
29
  const initialWitness = toACVMWitness(0, args);
30
- const { partialWitness } = await acvm(
30
+ const acirExecutionResult = await acvm(
31
31
  await AcirSimulator.getSolver(),
32
32
  acir,
33
33
  initialWitness,
@@ -44,6 +44,7 @@ export async function executeUnconstrainedFunction(
44
44
  );
45
45
  });
46
46
 
47
- return decodeReturnValues(artifact, extractReturnWitness(acir, partialWitness));
47
+ const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
48
+ return decodeReturnValues(artifact, returnWitness);
48
49
  }
49
50
  // docs:end:execute_unconstrained_function
@@ -1,3 +1,3 @@
1
- export * from './packed_args_cache.js';
1
+ export * from './packed_values_cache.js';
2
2
  export * from './errors.js';
3
3
  export * from './side_effect_counter.js';
@@ -0,0 +1,55 @@
1
+ import { PackedValues } from '@aztec/circuit-types';
2
+ import { Fr } from '@aztec/circuits.js';
3
+
4
+ /**
5
+ * A cache for packed values (arguments, returns) during transaction execution.
6
+ */
7
+ export class PackedValuesCache {
8
+ private cache: Map<bigint, Fr[]>;
9
+
10
+ constructor(initialArguments: PackedValues[] = []) {
11
+ this.cache = new Map();
12
+ for (const initialArg of initialArguments) {
13
+ this.cache.set(initialArg.hash.toBigInt(), initialArg.values);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Creates a new packed values cache.
19
+ * @param initialArguments - The initial arguments to add to the cache.
20
+ * @returns The new packed values cache.
21
+ */
22
+ public static create(initialArguments: PackedValues[] = []) {
23
+ return new PackedValuesCache(initialArguments);
24
+ }
25
+
26
+ /**
27
+ * Unpacks packed values.
28
+ * @param hash - The hash of the packed values.
29
+ * @returns The unpacked values.
30
+ */
31
+ public unpack(hash: Fr): Fr[] {
32
+ if (hash.equals(Fr.ZERO)) {
33
+ return [];
34
+ }
35
+ const packedValues = this.cache.get(hash.value);
36
+ if (!packedValues) {
37
+ throw new Error(`Packed values for hash ${hash.toString()} not found in cache`);
38
+ }
39
+ return packedValues;
40
+ }
41
+
42
+ /**
43
+ * Packs values.
44
+ * @param values - The values to pack.
45
+ * @returns The hash of the packed values.
46
+ */
47
+ public pack(values: Fr[]) {
48
+ if (values.length === 0) {
49
+ return Fr.ZERO;
50
+ }
51
+ const packedValues = PackedValues.fromValues(values);
52
+ this.cache.set(packedValues.hash.value, packedValues.values);
53
+ return packedValues.hash;
54
+ }
55
+ }
package/src/index.ts CHANGED
@@ -3,3 +3,4 @@ export * from './client/index.js';
3
3
  export * from './common/index.js';
4
4
  export * from './public/index.js';
5
5
  export * from './simulator/index.js';
6
+ export * from './mocks/index.js';