@aztec/simulator 0.57.0 → 0.59.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 (135) hide show
  1. package/dest/acvm/oracle/oracle.js +2 -2
  2. package/dest/acvm/oracle/typed_oracle.d.ts +1 -2
  3. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  4. package/dest/acvm/oracle/typed_oracle.js +1 -1
  5. package/dest/avm/avm_gas.js +2 -2
  6. package/dest/avm/avm_memory_types.d.ts +7 -3
  7. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  8. package/dest/avm/avm_memory_types.js +29 -14
  9. package/dest/avm/avm_simulator.d.ts.map +1 -1
  10. package/dest/avm/avm_simulator.js +5 -2
  11. package/dest/avm/fixtures/index.d.ts.map +1 -1
  12. package/dest/avm/fixtures/index.js +3 -3
  13. package/dest/avm/journal/journal.d.ts.map +1 -1
  14. package/dest/avm/journal/journal.js +2 -3
  15. package/dest/avm/opcodes/accrued_substate.js +17 -17
  16. package/dest/avm/opcodes/arithmetic.js +2 -2
  17. package/dest/avm/opcodes/bitwise.d.ts +3 -3
  18. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  19. package/dest/avm/opcodes/bitwise.js +9 -8
  20. package/dest/avm/opcodes/comparators.js +2 -2
  21. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  22. package/dest/avm/opcodes/contract.js +4 -3
  23. package/dest/avm/opcodes/control_flow.js +1 -1
  24. package/dest/avm/opcodes/conversion.js +4 -4
  25. package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
  26. package/dest/avm/opcodes/ec_add.js +18 -9
  27. package/dest/avm/opcodes/external_calls.js +10 -10
  28. package/dest/avm/opcodes/hashing.js +8 -8
  29. package/dest/avm/opcodes/instruction_impl.d.ts +1 -2
  30. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  31. package/dest/avm/opcodes/instruction_impl.js +2 -5
  32. package/dest/avm/opcodes/memory.js +3 -3
  33. package/dest/avm/opcodes/misc.js +4 -4
  34. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
  35. package/dest/avm/opcodes/multi_scalar_mul.js +24 -9
  36. package/dest/avm/opcodes/storage.js +2 -2
  37. package/dest/avm/serialization/instruction_serialization.js +2 -2
  38. package/dest/avm/test_utils.d.ts +1 -2
  39. package/dest/avm/test_utils.d.ts.map +1 -1
  40. package/dest/avm/test_utils.js +1 -1
  41. package/dest/client/client_execution_context.d.ts.map +1 -1
  42. package/dest/client/client_execution_context.js +7 -3
  43. package/dest/client/db_oracle.d.ts +1 -2
  44. package/dest/client/db_oracle.d.ts.map +1 -1
  45. package/dest/client/db_oracle.js +1 -1
  46. package/dest/client/index.d.ts +1 -0
  47. package/dest/client/index.d.ts.map +1 -1
  48. package/dest/client/index.js +2 -1
  49. package/dest/client/private_execution.d.ts +10 -1
  50. package/dest/client/private_execution.d.ts.map +1 -1
  51. package/dest/client/private_execution.js +25 -5
  52. package/dest/client/view_data_oracle.d.ts +1 -2
  53. package/dest/client/view_data_oracle.d.ts.map +1 -1
  54. package/dest/client/view_data_oracle.js +1 -1
  55. package/dest/public/db_interfaces.d.ts +1 -2
  56. package/dest/public/db_interfaces.d.ts.map +1 -1
  57. package/dest/public/dual_side_effect_trace.d.ts +76 -0
  58. package/dest/public/dual_side_effect_trace.d.ts.map +1 -0
  59. package/dest/public/dual_side_effect_trace.js +109 -0
  60. package/dest/public/enqueued_call_side_effect_trace.d.ts +114 -0
  61. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -0
  62. package/dest/public/enqueued_call_side_effect_trace.js +314 -0
  63. package/dest/public/enqueued_call_simulator.d.ts +2 -2
  64. package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
  65. package/dest/public/enqueued_call_simulator.js +18 -7
  66. package/dest/public/enqueued_calls_processor.d.ts +2 -2
  67. package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
  68. package/dest/public/enqueued_calls_processor.js +3 -5
  69. package/dest/public/execution.d.ts +3 -4
  70. package/dest/public/execution.d.ts.map +1 -1
  71. package/dest/public/execution.js +1 -1
  72. package/dest/public/executor.d.ts +6 -4
  73. package/dest/public/executor.d.ts.map +1 -1
  74. package/dest/public/executor.js +18 -9
  75. package/dest/public/fee_payment.d.ts +1 -1
  76. package/dest/public/fee_payment.d.ts.map +1 -1
  77. package/dest/public/fee_payment.js +4 -7
  78. package/dest/public/hints_builder.d.ts +2 -2
  79. package/dest/public/hints_builder.d.ts.map +1 -1
  80. package/dest/public/hints_builder.js +1 -1
  81. package/dest/public/public_db_sources.d.ts +4 -5
  82. package/dest/public/public_db_sources.d.ts.map +1 -1
  83. package/dest/public/public_db_sources.js +15 -11
  84. package/dest/public/public_kernel_tail_simulator.d.ts +3 -3
  85. package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
  86. package/dest/public/public_kernel_tail_simulator.js +1 -1
  87. package/dest/public/public_processor.d.ts +7 -11
  88. package/dest/public/public_processor.d.ts.map +1 -1
  89. package/dest/public/public_processor.js +8 -12
  90. package/dest/public/side_effect_trace.d.ts +1 -2
  91. package/dest/public/side_effect_trace.d.ts.map +1 -1
  92. package/dest/public/side_effect_trace.js +2 -2
  93. package/package.json +9 -9
  94. package/src/acvm/oracle/oracle.ts +1 -1
  95. package/src/acvm/oracle/typed_oracle.ts +6 -2
  96. package/src/avm/avm_gas.ts +1 -1
  97. package/src/avm/avm_memory_types.ts +28 -11
  98. package/src/avm/avm_simulator.ts +7 -1
  99. package/src/avm/fixtures/index.ts +2 -2
  100. package/src/avm/journal/journal.ts +3 -4
  101. package/src/avm/opcodes/accrued_substate.ts +17 -17
  102. package/src/avm/opcodes/arithmetic.ts +1 -1
  103. package/src/avm/opcodes/bitwise.ts +8 -7
  104. package/src/avm/opcodes/comparators.ts +1 -1
  105. package/src/avm/opcodes/contract.ts +3 -2
  106. package/src/avm/opcodes/control_flow.ts +1 -1
  107. package/src/avm/opcodes/conversion.ts +4 -4
  108. package/src/avm/opcodes/ec_add.ts +15 -8
  109. package/src/avm/opcodes/external_calls.ts +10 -10
  110. package/src/avm/opcodes/hashing.ts +8 -8
  111. package/src/avm/opcodes/instruction_impl.ts +0 -3
  112. package/src/avm/opcodes/memory.ts +3 -3
  113. package/src/avm/opcodes/misc.ts +4 -4
  114. package/src/avm/opcodes/multi_scalar_mul.ts +20 -12
  115. package/src/avm/opcodes/storage.ts +2 -2
  116. package/src/avm/serialization/instruction_serialization.ts +1 -1
  117. package/src/avm/test_utils.ts +1 -2
  118. package/src/client/client_execution_context.ts +6 -1
  119. package/src/client/db_oracle.ts +6 -2
  120. package/src/client/index.ts +1 -0
  121. package/src/client/private_execution.ts +36 -6
  122. package/src/client/view_data_oracle.ts +1 -2
  123. package/src/public/db_interfaces.ts +5 -2
  124. package/src/public/dual_side_effect_trace.ts +173 -0
  125. package/src/public/enqueued_call_side_effect_trace.ts +552 -0
  126. package/src/public/enqueued_call_simulator.ts +33 -11
  127. package/src/public/enqueued_calls_processor.ts +4 -6
  128. package/src/public/execution.ts +2 -4
  129. package/src/public/executor.ts +38 -9
  130. package/src/public/fee_payment.ts +4 -6
  131. package/src/public/hints_builder.ts +2 -2
  132. package/src/public/public_db_sources.ts +31 -22
  133. package/src/public/public_kernel_tail_simulator.ts +3 -3
  134. package/src/public/public_processor.ts +16 -16
  135. package/src/public/side_effect_trace.ts +2 -2
@@ -12,7 +12,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
12
12
  const operands = [this.aOffset, this.bOffset, this.dstOffset];
13
13
  const addressing = Addressing.fromWire(this.indirect, operands.length);
14
14
  const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
15
- memory.checkTags(this.inTag, aOffset, bOffset);
15
+ memory.checkTagsAreSame(aOffset, bOffset);
16
16
 
17
17
  const a = memory.get(aOffset);
18
18
  const b = memory.get(bOffset);
@@ -39,12 +39,13 @@ export class GetContractInstance extends Instruction {
39
39
  instance.deployer.toField(),
40
40
  instance.contractClassId,
41
41
  instance.initializationHash,
42
- instance.publicKeysHash,
42
+ // This this okay ?
43
+ ...instance.publicKeys.toFields(),
43
44
  ].map(f => new Field(f));
44
45
 
45
46
  memory.setSlice(dstOffset, data);
46
47
 
47
- memory.assert({ reads: 1, writes: 6, addressing });
48
+ memory.assert({ reads: 1, writes: 17, addressing });
48
49
  context.machineState.incrementPc();
49
50
  }
50
51
  }
@@ -63,7 +63,7 @@ export class InternalCall extends Instruction {
63
63
  static readonly type: string = 'INTERNALCALL';
64
64
  static readonly opcode: Opcode = Opcode.INTERNALCALL;
65
65
  // Informs (de)serialization. See Instruction.deserialize.
66
- static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT32];
66
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT16];
67
67
 
68
68
  constructor(private loc: number) {
69
69
  super();
@@ -13,10 +13,10 @@ export class ToRadixLE extends Instruction {
13
13
  static readonly wireFormat: OperandType[] = [
14
14
  OperandType.UINT8, // Opcode
15
15
  OperandType.UINT8, // Indirect
16
- OperandType.UINT32, // src memory address
17
- OperandType.UINT32, // dst memory address
18
- OperandType.UINT32, // radix memory address
19
- OperandType.UINT32, // number of limbs (Immediate)
16
+ OperandType.UINT16, // src memory address
17
+ OperandType.UINT16, // dst memory address
18
+ OperandType.UINT16, // radix memory address
19
+ OperandType.UINT16, // number of limbs (Immediate)
20
20
  OperandType.UINT8, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte)
21
21
  ];
22
22
 
@@ -15,13 +15,13 @@ export class EcAdd extends Instruction {
15
15
  static readonly wireFormat: OperandType[] = [
16
16
  OperandType.UINT8, // reserved
17
17
  OperandType.UINT16, // 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
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(
@@ -72,7 +72,14 @@ export class EcAdd extends Instruction {
72
72
  }
73
73
 
74
74
  const grumpkin = new Grumpkin();
75
- 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
+ }
76
83
  // Temporary,
77
84
  if (p1IsInfinite) {
78
85
  dest = p2;
@@ -16,14 +16,14 @@ abstract class ExternalCall extends Instruction {
16
16
  static readonly wireFormat: OperandType[] = [
17
17
  OperandType.UINT8,
18
18
  OperandType.UINT16, // Indirect
19
- OperandType.UINT32,
20
- OperandType.UINT32,
21
- OperandType.UINT32,
22
- OperandType.UINT32,
23
- OperandType.UINT32,
24
- OperandType.UINT32,
25
- OperandType.UINT32,
26
- OperandType.UINT32,
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(
@@ -164,8 +164,8 @@ export class Return extends Instruction {
164
164
  static readonly wireFormat: OperandType[] = [
165
165
  OperandType.UINT8,
166
166
  OperandType.UINT8,
167
- OperandType.UINT32,
168
- OperandType.UINT32,
167
+ OperandType.UINT16,
168
+ OperandType.UINT16,
169
169
  ];
170
170
 
171
171
  constructor(private indirect: number, private returnOffset: number, private copySize: number) {
@@ -23,8 +23,8 @@ export class Poseidon2 extends Instruction {
23
23
  static readonly wireFormat: OperandType[] = [
24
24
  OperandType.UINT8,
25
25
  OperandType.UINT8,
26
- OperandType.UINT32,
27
- OperandType.UINT32,
26
+ OperandType.UINT16,
27
+ OperandType.UINT16,
28
28
  ];
29
29
 
30
30
  constructor(private indirect: number, private inputStateOffset: number, private outputStateOffset: number) {
@@ -106,9 +106,9 @@ export class KeccakF1600 extends Instruction {
106
106
  static readonly wireFormat: OperandType[] = [
107
107
  OperandType.UINT8,
108
108
  OperandType.UINT8,
109
- OperandType.UINT32,
110
- OperandType.UINT32,
111
- OperandType.UINT32,
109
+ OperandType.UINT16,
110
+ OperandType.UINT16,
111
+ OperandType.UINT16,
112
112
  ];
113
113
 
114
114
  constructor(
@@ -153,9 +153,9 @@ export class Sha256Compression extends Instruction {
153
153
  static readonly wireFormat: OperandType[] = [
154
154
  OperandType.UINT8,
155
155
  OperandType.UINT8,
156
- OperandType.UINT32,
157
- OperandType.UINT32,
158
- OperandType.UINT32,
156
+ OperandType.UINT16,
157
+ OperandType.UINT16,
158
+ OperandType.UINT16,
159
159
  ];
160
160
 
161
161
  constructor(
@@ -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,
@@ -163,9 +163,9 @@ export class CalldataCopy extends Instruction {
163
163
  static readonly wireFormat: OperandType[] = [
164
164
  OperandType.UINT8,
165
165
  OperandType.UINT8,
166
- OperandType.UINT32,
167
- OperandType.UINT32,
168
- OperandType.UINT32,
166
+ OperandType.UINT16,
167
+ OperandType.UINT16,
168
+ OperandType.UINT16,
169
169
  ];
170
170
 
171
171
  constructor(
@@ -15,10 +15,10 @@ export class DebugLog extends Instruction {
15
15
  static readonly wireFormat: OperandType[] = [
16
16
  OperandType.UINT8, // Opcode
17
17
  OperandType.UINT8, // Indirect
18
- OperandType.UINT32, // message memory address
19
- OperandType.UINT32, // message size
20
- OperandType.UINT32, // fields memory address
21
- OperandType.UINT32, // fields size address
18
+ OperandType.UINT16, // message memory address
19
+ OperandType.UINT16, // message size
20
+ OperandType.UINT16, // fields memory address
21
+ OperandType.UINT16, // fields size address
22
22
  ];
23
23
 
24
24
  constructor(
@@ -16,10 +16,10 @@ export class MultiScalarMul extends Instruction {
16
16
  static readonly wireFormat: OperandType[] = [
17
17
  OperandType.UINT8 /* opcode */,
18
18
  OperandType.UINT8 /* indirect */,
19
- OperandType.UINT32 /* points vector offset */,
20
- OperandType.UINT32 /* scalars vector offset */,
21
- OperandType.UINT32 /* output offset (fixed triplet) */,
22
- OperandType.UINT32 /* points length offset */,
19
+ OperandType.UINT16 /* points vector offset */,
20
+ OperandType.UINT16 /* scalars vector offset */,
21
+ OperandType.UINT16 /* output offset (fixed triplet) */,
22
+ OperandType.UINT16 /* points length offset */,
23
23
  ];
24
24
 
25
25
  constructor(
@@ -69,10 +69,8 @@ export class MultiScalarMul extends Instruction {
69
69
  // Now we need to reconstruct the points and scalars into something we can operate on.
70
70
  const grumpkinPoints: Point[] = [];
71
71
  for (let i = 0; i < numPoints; i++) {
72
- const p: Point = new Point(pointsVector[3 * i].toFr(), pointsVector[3 * i + 1].toFr(), false);
73
- // Include this later when we have a standard for representing infinity
74
- // const isInf = pointsVector[i + 2].toBoolean();
75
-
72
+ const isInf = pointsVector[3 * i + 2].toNumber() === 1;
73
+ const p: Point = new Point(pointsVector[3 * i].toFr(), pointsVector[3 * i + 1].toFr(), isInf);
76
74
  if (!p.isOnGrumpkin()) {
77
75
  throw new InstructionExecutionError(`Point ${p.toString()} is not on the curve.`);
78
76
  }
@@ -93,10 +91,20 @@ export class MultiScalarMul extends Instruction {
93
91
  const [firstBaseScalarPair, ...rest]: Array<[Point, Fq]> = grumpkinPoints.map((p, idx) => [p, scalarFqVector[idx]]);
94
92
  // Fold the points and scalars into a single point
95
93
  // We have to ensure get the first point, since the identity element (point at infinity) isn't quite working in ts
96
- const outputPoint = rest.reduce(
97
- (acc, curr) => grumpkin.add(acc, grumpkin.mul(curr[0], curr[1])),
98
- grumpkin.mul(firstBaseScalarPair[0], firstBaseScalarPair[1]),
99
- );
94
+ const outputPoint = rest.reduce((acc, curr) => {
95
+ if (curr[1] === Fq.ZERO) {
96
+ // If we multiply by 0, the result will the point at infinity - so we ignore it
97
+ return acc;
98
+ } else if (curr[0].inf) {
99
+ // If we multiply the point at infinity by a scalar, it's still the point at infinity
100
+ return acc;
101
+ } else if (acc.inf) {
102
+ // If we accumulator is the point at infinity, we can just return the current point
103
+ return curr[0];
104
+ } else {
105
+ return grumpkin.add(acc, grumpkin.mul(curr[0], curr[1]));
106
+ }
107
+ }, grumpkin.mul(firstBaseScalarPair[0], firstBaseScalarPair[1]));
100
108
  const output = outputPoint.toFields().map(f => new Field(f));
101
109
 
102
110
  memory.setSlice(outputOffset, output);
@@ -10,8 +10,8 @@ abstract class BaseStorageInstruction extends Instruction {
10
10
  public static readonly wireFormat: OperandType[] = [
11
11
  OperandType.UINT8,
12
12
  OperandType.UINT8,
13
- OperandType.UINT32,
14
- OperandType.UINT32,
13
+ OperandType.UINT16,
14
+ OperandType.UINT16,
15
15
  ];
16
16
 
17
17
  constructor(protected indirect: number, protected aOffset: number, protected bOffset: number) {
@@ -158,7 +158,7 @@ function writeBigInt128BE(this: Buffer, value: bigint): void {
158
158
  */
159
159
  export function deserialize(cursor: BufferCursor | Buffer, operands: OperandType[]): (number | bigint)[] {
160
160
  const argValues = [];
161
- if (cursor instanceof Buffer) {
161
+ if (Buffer.isBuffer(cursor)) {
162
162
  cursor = new BufferCursor(cursor);
163
163
  }
164
164
 
@@ -1,5 +1,4 @@
1
- import { Fr } from '@aztec/circuits.js';
2
- import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
1
+ import { type ContractInstanceWithAddress, Fr } from '@aztec/circuits.js';
3
2
 
4
3
  import { type jest } from '@jest/globals';
5
4
  import { mock } from 'jest-mock-extended';
@@ -17,6 +17,7 @@ import {
17
17
  CallContext,
18
18
  FunctionSelector,
19
19
  type Header,
20
+ PRIVATE_CONTEXT_INPUTS_LENGTH,
20
21
  PUBLIC_DISPATCH_SELECTOR,
21
22
  PrivateContextInputs,
22
23
  type TxContext,
@@ -108,8 +109,12 @@ export class ClientExecutionContext extends ViewDataOracle {
108
109
  this.txContext,
109
110
  this.sideEffectCounter,
110
111
  );
112
+ const privateContextInputsAsFields = privateContextInputs.toFields();
113
+ if (privateContextInputsAsFields.length !== PRIVATE_CONTEXT_INPUTS_LENGTH) {
114
+ throw new Error('Invalid private context inputs size');
115
+ }
111
116
 
112
- const fields = [...privateContextInputs.toFields(), ...args];
117
+ const fields = [...privateContextInputsAsFields, ...args];
113
118
  return toACVMWitness(0, fields);
114
119
  }
115
120
 
@@ -5,11 +5,15 @@ import {
5
5
  type NullifierMembershipWitness,
6
6
  type PublicDataWitness,
7
7
  } from '@aztec/circuit-types';
8
- import { type CompleteAddress, type Header, type KeyValidationRequest } from '@aztec/circuits.js';
8
+ import {
9
+ type CompleteAddress,
10
+ type ContractInstance,
11
+ type Header,
12
+ type KeyValidationRequest,
13
+ } from '@aztec/circuits.js';
9
14
  import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi';
10
15
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
11
16
  import { type Fr } from '@aztec/foundation/fields';
12
- import { type ContractInstance } from '@aztec/types/contracts';
13
17
 
14
18
  import { type NoteData } from '../acvm/index.js';
15
19
  import { type CommitmentsDB } from '../public/db_interfaces.js';
@@ -2,3 +2,4 @@ export * from './simulator.js';
2
2
  export * from './db_oracle.js';
3
3
  export * from './pick_notes.js';
4
4
  export * from './execution_note_cache.js';
5
+ export { extractPrivateCircuitPublicInputs } from './private_execution.js';
@@ -1,13 +1,20 @@
1
1
  import { PrivateExecutionResult } from '@aztec/circuit-types';
2
2
  import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
3
- import { Fr, FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js';
4
- import type { FunctionArtifact, FunctionSelector } from '@aztec/foundation/abi';
3
+ import {
4
+ Fr,
5
+ FunctionData,
6
+ PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,
7
+ PRIVATE_CONTEXT_INPUTS_LENGTH,
8
+ PrivateCallStackItem,
9
+ PrivateCircuitPublicInputs,
10
+ } from '@aztec/circuits.js';
11
+ import { type FunctionArtifact, type FunctionSelector, countArgumentsSize } from '@aztec/foundation/abi';
5
12
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
6
13
  import { createDebugLogger } from '@aztec/foundation/log';
7
14
  import { Timer } from '@aztec/foundation/timer';
8
15
 
9
- import { witnessMapToFields } from '../acvm/deserialize.js';
10
- import { Oracle, acvm, extractCallStack } from '../acvm/index.js';
16
+ import { fromACVMField, witnessMapToFields } from '../acvm/deserialize.js';
17
+ import { type ACVMWitness, Oracle, acvm, extractCallStack } from '../acvm/index.js';
11
18
  import { ExecutionError } from '../common/errors.js';
12
19
  import { type ClientExecutionContext } from './client_execution_context.js';
13
20
 
@@ -40,8 +47,7 @@ export async function executePrivateFunction(
40
47
  });
41
48
  const duration = timer.ms();
42
49
  const partialWitness = acirExecutionResult.partialWitness;
43
- const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
44
- const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness);
50
+ const publicInputs = extractPrivateCircuitPublicInputs(artifact, partialWitness);
45
51
 
46
52
  // TODO (alexg) estimate this size
47
53
  const initialWitnessSize = witnessMapToFields(initialWitness).length * Fr.SIZE_IN_BYTES;
@@ -92,3 +98,27 @@ export async function executePrivateFunction(
92
98
  unencryptedLogs,
93
99
  );
94
100
  }
101
+
102
+ /**
103
+ * Get the private circuit public inputs from the partial witness.
104
+ * @param artifact - The function artifact
105
+ * @param partialWitness - The partial witness, result of simulating the function.
106
+ * @returns - The public inputs.
107
+ */
108
+ export function extractPrivateCircuitPublicInputs(
109
+ artifact: FunctionArtifact,
110
+ partialWitness: ACVMWitness,
111
+ ): PrivateCircuitPublicInputs {
112
+ const parametersSize = countArgumentsSize(artifact) + PRIVATE_CONTEXT_INPUTS_LENGTH;
113
+ const returnsSize = PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH;
114
+ const returnData = [];
115
+ // Return values always appear in the witness after arguments.
116
+ for (let i = parametersSize; i < parametersSize + returnsSize; i++) {
117
+ const returnedField = partialWitness.get(i);
118
+ if (returnedField === undefined) {
119
+ throw new Error(`Missing return value for index ${i}`);
120
+ }
121
+ returnData.push(fromACVMField(returnedField));
122
+ }
123
+ return PrivateCircuitPublicInputs.fromFields(returnData);
124
+ }
@@ -7,12 +7,11 @@ import {
7
7
  type NullifierMembershipWitness,
8
8
  type PublicDataWitness,
9
9
  } from '@aztec/circuit-types';
10
- import { type Header, type KeyValidationRequest } from '@aztec/circuits.js';
10
+ import { type ContractInstance, type Header, type KeyValidationRequest } from '@aztec/circuits.js';
11
11
  import { siloNullifier } from '@aztec/circuits.js/hash';
12
12
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
13
13
  import { Fr } from '@aztec/foundation/fields';
14
14
  import { applyStringFormatting, createDebugLogger } from '@aztec/foundation/log';
15
- import { type ContractInstance } from '@aztec/types/contracts';
16
15
 
17
16
  import { type NoteData, TypedOracle } from '../acvm/index.js';
18
17
  import { type DBOracle } from './db_oracle.js';
@@ -1,8 +1,11 @@
1
1
  import { type NullifierMembershipWitness } from '@aztec/circuit-types';
2
- import { type FunctionSelector, type L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/circuits.js';
2
+ import {
3
+ type ContractInstanceWithAddress,
4
+ type FunctionSelector,
5
+ type L1_TO_L2_MSG_TREE_HEIGHT,
6
+ } from '@aztec/circuits.js';
3
7
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
4
8
  import { type Fr } from '@aztec/foundation/fields';
5
- import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
6
9
 
7
10
  import { type MessageLoadOracleInputs } from '../acvm/index.js';
8
11
 
@@ -0,0 +1,173 @@
1
+ import {
2
+ type CombinedConstantData,
3
+ type ContractInstanceWithAddress,
4
+ type Gas,
5
+ type VMCircuitPublicInputs,
6
+ } from '@aztec/circuits.js';
7
+ import { type Fr } from '@aztec/foundation/fields';
8
+
9
+ import { assert } from 'console';
10
+
11
+ import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js';
12
+ import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
13
+ import { type PublicEnqueuedCallSideEffectTrace } from './enqueued_call_side_effect_trace.js';
14
+ import { type PublicExecutionResult } from './execution.js';
15
+ import { type PublicSideEffectTrace } from './side_effect_trace.js';
16
+ import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
17
+
18
+ export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
19
+
20
+ export class DualSideEffectTrace implements PublicSideEffectTraceInterface {
21
+ constructor(
22
+ public readonly innerCallTrace: PublicSideEffectTrace,
23
+ public readonly enqueuedCallTrace: PublicEnqueuedCallSideEffectTrace,
24
+ ) {}
25
+
26
+ public fork() {
27
+ return new DualSideEffectTrace(this.innerCallTrace.fork(), this.enqueuedCallTrace.fork());
28
+ }
29
+
30
+ public getCounter() {
31
+ assert(this.innerCallTrace.getCounter() == this.enqueuedCallTrace.getCounter());
32
+ return this.innerCallTrace.getCounter();
33
+ }
34
+
35
+ public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean) {
36
+ this.innerCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
37
+ this.enqueuedCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
38
+ }
39
+
40
+ public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) {
41
+ this.innerCallTrace.tracePublicStorageWrite(storageAddress, slot, value);
42
+ this.enqueuedCallTrace.tracePublicStorageWrite(storageAddress, slot, value);
43
+ }
44
+
45
+ // TODO(8287): _exists can be removed once we have the vm properly handling the equality check
46
+ public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) {
47
+ this.innerCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists);
48
+ this.enqueuedCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists);
49
+ }
50
+
51
+ public traceNewNoteHash(_storageAddress: Fr, noteHash: Fr) {
52
+ this.innerCallTrace.traceNewNoteHash(_storageAddress, noteHash);
53
+ this.enqueuedCallTrace.traceNewNoteHash(_storageAddress, noteHash);
54
+ }
55
+
56
+ public traceNullifierCheck(storageAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean) {
57
+ this.innerCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending);
58
+ this.enqueuedCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending);
59
+ }
60
+
61
+ public traceNewNullifier(storageAddress: Fr, nullifier: Fr) {
62
+ this.innerCallTrace.traceNewNullifier(storageAddress, nullifier);
63
+ this.enqueuedCallTrace.traceNewNullifier(storageAddress, nullifier);
64
+ }
65
+
66
+ public traceL1ToL2MessageCheck(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean) {
67
+ this.innerCallTrace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists);
68
+ this.enqueuedCallTrace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists);
69
+ }
70
+
71
+ public traceNewL2ToL1Message(contractAddress: Fr, recipient: Fr, content: Fr) {
72
+ this.innerCallTrace.traceNewL2ToL1Message(contractAddress, recipient, content);
73
+ this.enqueuedCallTrace.traceNewL2ToL1Message(contractAddress, recipient, content);
74
+ }
75
+
76
+ public traceUnencryptedLog(contractAddress: Fr, log: Fr[]) {
77
+ this.innerCallTrace.traceUnencryptedLog(contractAddress, log);
78
+ this.enqueuedCallTrace.traceUnencryptedLog(contractAddress, log);
79
+ }
80
+
81
+ public traceGetContractInstance(instance: TracedContractInstance) {
82
+ this.innerCallTrace.traceGetContractInstance(instance);
83
+ this.enqueuedCallTrace.traceGetContractInstance(instance);
84
+ }
85
+
86
+ /**
87
+ * Trace a nested call.
88
+ * Accept some results from a finished nested call's trace into this one.
89
+ */
90
+ public traceNestedCall(
91
+ /** The trace of the nested call. */
92
+ nestedCallTrace: this,
93
+ /** The execution environment of the nested call. */
94
+ nestedEnvironment: AvmExecutionEnvironment,
95
+ /** How much gas was available for this public execution. */
96
+ startGasLeft: Gas,
97
+ /** How much gas was left after this public execution. */
98
+ endGasLeft: Gas,
99
+ /** Bytecode used for this execution. */
100
+ bytecode: Buffer,
101
+ /** The call's results */
102
+ avmCallResults: AvmContractCallResult,
103
+ /** Function name for logging */
104
+ functionName: string = 'unknown',
105
+ ) {
106
+ this.innerCallTrace.traceNestedCall(
107
+ nestedCallTrace.innerCallTrace,
108
+ nestedEnvironment,
109
+ startGasLeft,
110
+ endGasLeft,
111
+ bytecode,
112
+ avmCallResults,
113
+ functionName,
114
+ );
115
+ this.enqueuedCallTrace.traceNestedCall(
116
+ nestedCallTrace.enqueuedCallTrace,
117
+ nestedEnvironment,
118
+ startGasLeft,
119
+ endGasLeft,
120
+ bytecode,
121
+ avmCallResults,
122
+ functionName,
123
+ );
124
+ }
125
+
126
+ /**
127
+ * Convert this trace to a PublicExecutionResult for use externally to the simulator.
128
+ */
129
+ public toPublicExecutionResult(
130
+ /** The execution environment of the nested call. */
131
+ avmEnvironment: AvmExecutionEnvironment,
132
+ /** How much gas was available for this public execution. */
133
+ startGasLeft: Gas,
134
+ /** How much gas was left after this public execution. */
135
+ endGasLeft: Gas,
136
+ /** Bytecode used for this execution. */
137
+ bytecode: Buffer,
138
+ /** The call's results */
139
+ avmCallResults: AvmContractCallResult,
140
+ /** Function name for logging */
141
+ functionName: string = 'unknown',
142
+ ): PublicExecutionResult {
143
+ return this.innerCallTrace.toPublicExecutionResult(
144
+ avmEnvironment,
145
+ startGasLeft,
146
+ endGasLeft,
147
+ bytecode,
148
+ avmCallResults,
149
+ functionName,
150
+ );
151
+ }
152
+
153
+ public toVMCircuitPublicInputs(
154
+ /** Constants */
155
+ constants: CombinedConstantData,
156
+ /** The execution environment of the nested call. */
157
+ avmEnvironment: AvmExecutionEnvironment,
158
+ /** How much gas was available for this public execution. */
159
+ startGasLeft: Gas,
160
+ /** How much gas was left after this public execution. */
161
+ endGasLeft: Gas,
162
+ /** The call's results */
163
+ avmCallResults: AvmContractCallResult,
164
+ ): VMCircuitPublicInputs {
165
+ return this.enqueuedCallTrace.toVMCircuitPublicInputs(
166
+ constants,
167
+ avmEnvironment,
168
+ startGasLeft,
169
+ endGasLeft,
170
+ avmCallResults,
171
+ );
172
+ }
173
+ }