@aztec/simulator 0.30.0 → 0.31.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 (88) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +1 -1
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +3 -3
  4. package/dest/acvm/oracle/typed_oracle.d.ts +1 -1
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +2 -2
  7. package/dest/avm/avm_execution_environment.d.ts +7 -0
  8. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  9. package/dest/avm/avm_execution_environment.js +16 -1
  10. package/dest/avm/avm_gas_cost.d.ts +18 -0
  11. package/dest/avm/avm_gas_cost.d.ts.map +1 -0
  12. package/dest/avm/avm_gas_cost.js +84 -0
  13. package/dest/avm/avm_machine_state.d.ts +12 -1
  14. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  15. package/dest/avm/avm_machine_state.js +31 -2
  16. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  17. package/dest/avm/avm_memory_types.js +2 -1
  18. package/dest/avm/avm_simulator.d.ts.map +1 -1
  19. package/dest/avm/avm_simulator.js +2 -2
  20. package/dest/avm/errors.d.ts +4 -0
  21. package/dest/avm/errors.d.ts.map +1 -1
  22. package/dest/avm/errors.js +8 -1
  23. package/dest/avm/fixtures/index.d.ts +7 -1
  24. package/dest/avm/fixtures/index.d.ts.map +1 -1
  25. package/dest/avm/fixtures/index.js +20 -6
  26. package/dest/avm/journal/journal.d.ts.map +1 -1
  27. package/dest/avm/journal/journal.js +7 -2
  28. package/dest/avm/opcodes/hashing.d.ts +12 -12
  29. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  30. package/dest/avm/opcodes/hashing.js +24 -23
  31. package/dest/avm/opcodes/instruction.d.ts +24 -2
  32. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  33. package/dest/avm/opcodes/instruction.js +41 -2
  34. package/dest/client/private_execution.d.ts.map +1 -1
  35. package/dest/client/private_execution.js +4 -5
  36. package/dest/client/unconstrained_execution.js +2 -2
  37. package/dest/client/view_data_oracle.d.ts +8 -5
  38. package/dest/client/view_data_oracle.d.ts.map +1 -1
  39. package/dest/client/view_data_oracle.js +9 -6
  40. package/dest/index.d.ts +1 -0
  41. package/dest/index.d.ts.map +1 -1
  42. package/dest/index.js +2 -1
  43. package/dest/public/db.d.ts +7 -5
  44. package/dest/public/db.d.ts.map +1 -1
  45. package/dest/public/executor.d.ts.map +1 -1
  46. package/dest/public/executor.js +4 -2
  47. package/dest/public/public_execution_context.d.ts +7 -4
  48. package/dest/public/public_execution_context.d.ts.map +1 -1
  49. package/dest/public/public_execution_context.js +9 -6
  50. package/dest/simulator/acvm_native.d.ts +20 -0
  51. package/dest/simulator/acvm_native.d.ts.map +1 -0
  52. package/dest/simulator/acvm_native.js +96 -0
  53. package/dest/simulator/acvm_wasm.d.ts +7 -0
  54. package/dest/simulator/acvm_wasm.d.ts.map +1 -0
  55. package/dest/simulator/acvm_wasm.js +23 -0
  56. package/dest/simulator/index.d.ts +4 -0
  57. package/dest/simulator/index.d.ts.map +1 -0
  58. package/dest/simulator/index.js +4 -0
  59. package/dest/simulator/simulation_provider.d.ts +9 -0
  60. package/dest/simulator/simulation_provider.d.ts.map +1 -0
  61. package/dest/simulator/simulation_provider.js +2 -0
  62. package/dest/test/utils.d.ts.map +1 -1
  63. package/dest/test/utils.js +4 -4
  64. package/package.json +6 -5
  65. package/src/acvm/oracle/oracle.ts +10 -2
  66. package/src/acvm/oracle/typed_oracle.ts +5 -1
  67. package/src/avm/avm_execution_environment.ts +20 -1
  68. package/src/avm/avm_gas_cost.ts +94 -0
  69. package/src/avm/avm_machine_state.ts +34 -1
  70. package/src/avm/avm_memory_types.ts +1 -0
  71. package/src/avm/avm_simulator.ts +1 -2
  72. package/src/avm/errors.ts +8 -0
  73. package/src/avm/fixtures/index.ts +21 -5
  74. package/src/avm/journal/journal.ts +10 -1
  75. package/src/avm/opcodes/hashing.ts +27 -20
  76. package/src/avm/opcodes/instruction.ts +45 -2
  77. package/src/client/private_execution.ts +3 -4
  78. package/src/client/unconstrained_execution.ts +1 -1
  79. package/src/client/view_data_oracle.ts +8 -5
  80. package/src/index.ts +1 -0
  81. package/src/public/db.ts +11 -5
  82. package/src/public/executor.ts +3 -1
  83. package/src/public/public_execution_context.ts +8 -5
  84. package/src/simulator/acvm_native.ts +112 -0
  85. package/src/simulator/acvm_wasm.ts +31 -0
  86. package/src/simulator/index.ts +3 -0
  87. package/src/simulator/simulation_provider.ts +10 -0
  88. package/src/test/utils.ts +2 -3
@@ -92,12 +92,15 @@ export class PublicExecutionContext extends TypedOracle {
92
92
  }
93
93
 
94
94
  /**
95
- * Fetches the a message from the db, given its key.
96
- * @param entryKey - A buffer representing the entry key.
97
- * @returns The l1 to l2 message data
95
+ * Fetches a message from the db, given its key.
96
+ * @param contractAddress - Address of a contract by which the message was emitted.
97
+ * @param messageHash - Hash of the message.
98
+ * @param secret - Secret used to compute a nullifier.
99
+ * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages
100
+ * @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
98
101
  */
99
- public async getL1ToL2MembershipWitness(entryKey: Fr) {
100
- return await this.commitmentsDb.getL1ToL2MembershipWitness(entryKey);
102
+ public async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) {
103
+ return await this.commitmentsDb.getL1ToL2MembershipWitness(contractAddress, messageHash, secret);
101
104
  }
102
105
 
103
106
  /**
@@ -0,0 +1,112 @@
1
+ import { randomBytes } from '@aztec/foundation/crypto';
2
+ import { NoirCompiledCircuit } from '@aztec/types/noir';
3
+
4
+ import { WitnessMap } from '@noir-lang/types';
5
+ import * as proc from 'child_process';
6
+ import fs from 'fs/promises';
7
+
8
+ import { SimulationProvider } from './simulation_provider.js';
9
+
10
+ /**
11
+ * Parses a TOML format witness map string into a Map structure
12
+ * @param outputString - The witness map in TOML format
13
+ * @returns The parsed witness map
14
+ */
15
+ function parseIntoWitnessMap(outputString: string) {
16
+ const lines = outputString.split('\n');
17
+ return new Map<number, string>(
18
+ lines
19
+ .filter((line: string) => line.length)
20
+ .map((line: string) => {
21
+ const pair = line.replaceAll(' ', '').split('=');
22
+ return [Number(pair[0]), pair[1].replaceAll('"', '')];
23
+ }),
24
+ );
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @param inputWitness - The circuit's input witness
30
+ * @param bytecode - The circuit bytecode
31
+ * @param workingDirectory - A directory to use for temporary files by the ACVM
32
+ * @param pathToAcvm - The path to the ACVm binary
33
+ * @returns The completed partial witness outputted from the circuit
34
+ */
35
+ export async function executeNativeCircuit(
36
+ inputWitness: WitnessMap,
37
+ bytecode: Buffer,
38
+ workingDirectory: string,
39
+ pathToAcvm: string,
40
+ ) {
41
+ const bytecodeFilename = 'bytecode';
42
+ const witnessFilename = 'input_witness.toml';
43
+
44
+ // convert the witness map to TOML format
45
+ let witnessMap = '';
46
+ inputWitness.forEach((value: string, key: number) => {
47
+ witnessMap = witnessMap.concat(`${key} = '${value}'\n`);
48
+ });
49
+
50
+ // In case the directory is still around from some time previously, remove it
51
+ await fs.rm(workingDirectory, { recursive: true, force: true });
52
+ // Create the new working directory
53
+ await fs.mkdir(workingDirectory, { recursive: true });
54
+ // Write the bytecode and input witness to the working directory
55
+ await fs.writeFile(`${workingDirectory}/${bytecodeFilename}`, bytecode);
56
+ await fs.writeFile(`${workingDirectory}/${witnessFilename}`, witnessMap);
57
+
58
+ // Execute the ACVM using the given args
59
+ const args = [
60
+ `execute`,
61
+ `--working-directory`,
62
+ `${workingDirectory}`,
63
+ `--bytecode`,
64
+ `${bytecodeFilename}`,
65
+ `--input-witness`,
66
+ `${witnessFilename}`,
67
+ `--print`,
68
+ ];
69
+ const processPromise = new Promise<string>((resolve, reject) => {
70
+ let outputWitness = Buffer.alloc(0);
71
+ let errorBuffer = Buffer.alloc(0);
72
+ const acvm = proc.spawn(pathToAcvm, args);
73
+ acvm.stdout.on('data', data => {
74
+ outputWitness = Buffer.concat([outputWitness, data]);
75
+ });
76
+ acvm.stderr.on('data', data => {
77
+ errorBuffer = Buffer.concat([errorBuffer, data]);
78
+ });
79
+ acvm.on('close', code => {
80
+ if (code === 0) {
81
+ resolve(outputWitness.toString('utf-8'));
82
+ } else {
83
+ reject(errorBuffer.toString('utf-8'));
84
+ }
85
+ });
86
+ });
87
+
88
+ try {
89
+ const output = await processPromise;
90
+ return parseIntoWitnessMap(output);
91
+ } finally {
92
+ // Clean up the working directory before we leave
93
+ await fs.rm(workingDirectory, { recursive: true, force: true });
94
+ }
95
+ }
96
+
97
+ export class NativeACVMSimulator implements SimulationProvider {
98
+ constructor(private workingDirectory: string, private pathToAcvm: string) {}
99
+ async simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise<WitnessMap> {
100
+ // Execute the circuit on those initial witness values
101
+
102
+ // Decode the bytecode from base64 since the acvm does not know about base64 encoding
103
+ const decodedBytecode = Buffer.from(compiledCircuit.bytecode, 'base64');
104
+
105
+ // Provide a unique working directory so we don't get clashes with parallel executions
106
+ const directory = `${this.workingDirectory}/${randomBytes(32).toString('hex')}`;
107
+ // Execute the circuit
108
+ const _witnessMap = await executeNativeCircuit(input, decodedBytecode, directory, this.pathToAcvm);
109
+
110
+ return _witnessMap;
111
+ }
112
+ }
@@ -0,0 +1,31 @@
1
+ import { NoirCompiledCircuit } from '@aztec/types/noir';
2
+
3
+ import { WasmBlackBoxFunctionSolver, createBlackBoxSolver, executeCircuitWithBlackBoxSolver } from '@noir-lang/acvm_js';
4
+ import { WitnessMap } from '@noir-lang/types';
5
+
6
+ import { SimulationProvider } from './simulation_provider.js';
7
+
8
+ let solver: Promise<WasmBlackBoxFunctionSolver>;
9
+
10
+ const getSolver = (): Promise<WasmBlackBoxFunctionSolver> => {
11
+ if (!solver) {
12
+ solver = createBlackBoxSolver();
13
+ }
14
+ return solver;
15
+ };
16
+
17
+ export class WASMSimulator implements SimulationProvider {
18
+ async simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise<WitnessMap> {
19
+ // Execute the circuit on those initial witness values
20
+ //
21
+ // Decode the bytecode from base64 since the acvm does not know about base64 encoding
22
+ const decodedBytecode = Buffer.from(compiledCircuit.bytecode, 'base64');
23
+ //
24
+ // Execute the circuit
25
+ const _witnessMap = await executeCircuitWithBlackBoxSolver(await getSolver(), decodedBytecode, input, () => {
26
+ throw Error('unexpected oracle during execution');
27
+ });
28
+
29
+ return _witnessMap;
30
+ }
31
+ }
@@ -0,0 +1,3 @@
1
+ export * from './acvm_native.js';
2
+ export * from './acvm_wasm.js';
3
+ export * from './simulation_provider.js';
@@ -0,0 +1,10 @@
1
+ import { NoirCompiledCircuit } from '@aztec/types/noir';
2
+
3
+ import { WitnessMap } from '@noir-lang/types';
4
+
5
+ /**
6
+ * Low level simulation interface
7
+ */
8
+ export interface SimulationProvider {
9
+ simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise<WitnessMap>;
10
+ }
package/src/test/utils.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/circuit-types';
2
2
  import { AztecAddress, EthAddress, Fr } from '@aztec/circuits.js';
3
3
  import { computeMessageSecretHash } from '@aztec/circuits.js/hash';
4
- import { sha256 } from '@aztec/foundation/crypto';
4
+ import { sha256ToField } from '@aztec/foundation/crypto';
5
5
 
6
6
  /**
7
7
  * Test utility function to craft an L1 to L2 message.
@@ -21,8 +21,7 @@ export const buildL1ToL2Message = (
21
21
  const selectorBuf = Buffer.from(selector, 'hex');
22
22
 
23
23
  const contentBuf = Buffer.concat([selectorBuf, ...contentPreimage.map(field => field.toBuffer())]);
24
- const content = Fr.fromBufferReduce(sha256(contentBuf));
25
-
24
+ const content = sha256ToField(contentBuf);
26
25
  const secretHash = computeMessageSecretHash(secret);
27
26
 
28
27
  // Eventually the kernel will need to prove the kernel portal pair exists within the contract tree,