Skip to content

Commit ce16c0b

Browse files
authored
feat(wasm)!: update wasm artifacts to match cli artifacts (#2973)
1 parent 4f86031 commit ce16c0b

7 files changed

Lines changed: 72 additions & 32 deletions

File tree

compiler/integration-tests/test/browser/compile_prove_verify.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,16 @@ test_cases.forEach((testInfo) => {
4949

5050
const noir_source = await getFile(`${base_relative_path}/${test_case}/src/main.nr`);
5151

52-
let compile_output;
52+
let noir_program;
5353
try {
54-
compile_output = await getCircuit(noir_source);
54+
noir_program = await getCircuit(noir_source);
5555

56-
expect(await compile_output, 'Compile output ').to.be.an('object');
56+
expect(await noir_program, 'Compile output ').to.be.an('object');
5757
} catch (e) {
5858
expect(e, 'Compilation Step').to.not.be.an('error');
5959
throw e;
6060
}
6161

62-
const noir_program = { bytecode: compile_output.circuit, abi: compile_output.abi };
6362
const backend = new BarretenbergBackend(noir_program);
6463
const program = new Noir(noir_program, backend);
6564

compiler/integration-tests/test/browser/recursion.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ describe('It compiles noir program code, receiving circuit bytes and abi object.
4848
});
4949

5050
it('Should generate valid inner proof for correct input, then verify proof within a proof', async () => {
51-
const { circuit: main_circuit, abi: main_abi } = await getCircuit(circuit_main_source);
51+
const main_program = await getCircuit(circuit_main_source);
5252
const main_inputs = TOML.parse(circuit_main_toml);
5353

54-
const main_program = { bytecode: main_circuit, abi: main_abi };
5554
const main_backend = new BarretenbergBackend(main_program);
5655

5756
const main_witnessUint8Array = await generateWitness(main_program, main_inputs);
@@ -79,8 +78,7 @@ describe('It compiles noir program code, receiving circuit bytes and abi object.
7978

8079
logger.debug('recursion_inputs', recursion_inputs);
8180

82-
const { circuit: recursion_circuit, abi: recursion_abi } = await getCircuit(circuit_recursion_source);
83-
const recursion_program = { bytecode: recursion_circuit, abi: recursion_abi };
81+
const recursion_program = await getCircuit(circuit_recursion_source);
8482

8583
const recursion_backend = new BarretenbergBackend(recursion_program);
8684

compiler/integration-tests/test/node/smart_contract_verifier.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,16 @@ test_cases.forEach((testInfo) => {
3838

3939
const noir_source_path = resolve(`${base_relative_path}/${test_case}/src/main.nr`);
4040

41-
let compile_output;
41+
let noir_program;
4242
try {
43-
compile_output = await getCircuit(noir_source_path);
43+
noir_program = await getCircuit(noir_source_path);
4444

45-
expect(await compile_output, 'Compile output ').to.be.an('object');
45+
expect(await noir_program, 'Compile output ').to.be.an('object');
4646
} catch (e) {
4747
expect(e, 'Compilation Step').to.not.be.an('error');
4848
throw e;
4949
}
5050

51-
const noir_program = { bytecode: compile_output.circuit, abi: compile_output.abi };
5251
const backend = new BarretenbergBackend(noir_program);
5352
const program = new Noir(noir_program, backend);
5453

compiler/wasm/src/compile.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
use fm::FileManager;
22
use gloo_utils::format::JsValueSerdeExt;
33
use log::debug;
4+
use nargo::artifacts::{
5+
contract::{PreprocessedContract, PreprocessedContractFunction},
6+
program::PreprocessedProgram,
7+
};
48
use noirc_driver::{
59
add_dep, compile_contract, compile_main, prepare_crate, prepare_dependency, CompileOptions,
10+
CompiledContract, CompiledProgram,
611
};
712
use noirc_frontend::{graph::CrateGraph, hir::Context};
813
use serde::{Deserialize, Serialize};
914
use std::path::Path;
1015
use wasm_bindgen::prelude::*;
1116

17+
const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg";
18+
1219
#[derive(Debug, Serialize, Deserialize)]
1320
pub struct WASMCompileOptions {
1421
#[serde(default = "default_entry_point")]
@@ -123,7 +130,9 @@ pub fn compile(args: JsValue) -> JsValue {
123130
nargo::ops::optimize_contract(compiled_contract, np_language, &is_opcode_supported)
124131
.expect("Contract optimization failed");
125132

126-
<JsValue as JsValueSerdeExt>::from_serde(&optimized_contract).unwrap()
133+
let preprocessed_contract = preprocess_contract(optimized_contract);
134+
135+
<JsValue as JsValueSerdeExt>::from_serde(&preprocessed_contract).unwrap()
127136
} else {
128137
let compiled_program =
129138
compile_main(&mut context, crate_id, &options.compile_options, None, true)
@@ -134,7 +143,39 @@ pub fn compile(args: JsValue) -> JsValue {
134143
nargo::ops::optimize_program(compiled_program, np_language, &is_opcode_supported)
135144
.expect("Program optimization failed");
136145

137-
<JsValue as JsValueSerdeExt>::from_serde(&optimized_program).unwrap()
146+
let preprocessed_program = preprocess_program(optimized_program);
147+
148+
<JsValue as JsValueSerdeExt>::from_serde(&preprocessed_program).unwrap()
149+
}
150+
}
151+
152+
fn preprocess_program(program: CompiledProgram) -> PreprocessedProgram {
153+
PreprocessedProgram {
154+
hash: program.hash,
155+
backend: String::from(BACKEND_IDENTIFIER),
156+
abi: program.abi,
157+
bytecode: program.circuit,
158+
}
159+
}
160+
161+
fn preprocess_contract(contract: CompiledContract) -> PreprocessedContract {
162+
let preprocessed_functions = contract
163+
.functions
164+
.into_iter()
165+
.map(|func| PreprocessedContractFunction {
166+
name: func.name,
167+
function_type: func.function_type,
168+
is_internal: func.is_internal,
169+
abi: func.abi,
170+
bytecode: func.bytecode,
171+
})
172+
.collect();
173+
174+
PreprocessedContract {
175+
name: contract.name,
176+
backend: String::from(BACKEND_IDENTIFIER),
177+
functions: preprocessed_functions,
178+
events: contract.events,
138179
}
139180
}
140181

compiler/wasm/test/browser/index.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@ async function getSource(): Promise<string> {
1616
return getFileContent(noirSourcePath);
1717
}
1818

19-
async function getPrecompiledSource(): Promise<string> {
19+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20+
async function getPrecompiledSource(): Promise<any> {
2021
const compiledData = await getFileContent(nargoArtifactPath);
21-
return JSON.parse(compiledData).bytecode;
22+
return JSON.parse(compiledData);
2223
}
2324

2425
describe('noir wasm compilation', () => {
2526
it('matches nargos compilation', async () => {
2627
const source = await getSource();
2728

28-
const wasmCircuitBase64 = await compileNoirSource(source);
29+
const wasmCircuit = await compileNoirSource(source);
2930

30-
const cliCircuitBase64 = await getPrecompiledSource();
31+
const cliCircuit = await getPrecompiledSource();
3132

32-
expect(wasmCircuitBase64).to.equal(cliCircuitBase64);
33+
// We don't expect the hashes to match due to how `noir_wasm` handles dependencies
34+
expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode);
35+
expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi);
36+
expect(wasmCircuit.backend).to.eq(cliCircuit.backend);
3337
}).timeout(20e3); // 20 seconds
3438
});

compiler/wasm/test/node/index.test.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,23 @@ async function getSource(): Promise<string> {
1111
return getFileContent(noirSourcePath);
1212
}
1313

14-
async function getPrecompiledSource(): Promise<string> {
14+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15+
async function getPrecompiledSource(): Promise<any> {
1516
const compiledData = await getFileContent(nargoArtifactPath);
16-
return JSON.parse(compiledData).bytecode;
17+
return JSON.parse(compiledData);
1718
}
1819

1920
describe('noir wasm compilation', () => {
2021
it('matches nargos compilation', async () => {
2122
const source = await getSource();
2223

23-
const wasmCircuitBase64 = await compileNoirSource(source);
24+
const wasmCircuit = await compileNoirSource(source);
2425

25-
const cliCircuitBase64 = await getPrecompiledSource();
26+
const cliCircuit = await getPrecompiledSource();
2627

27-
console.log('wasm', wasmCircuitBase64);
28-
29-
console.log('cli', cliCircuitBase64);
30-
31-
console.log('Compilation is a match? ', wasmCircuitBase64 === cliCircuitBase64);
32-
33-
expect(wasmCircuitBase64).to.equal(cliCircuitBase64);
28+
// We don't expect the hashes to match due to how `noir_wasm` handles dependencies
29+
expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode);
30+
expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi);
31+
expect(wasmCircuit.backend).to.eq(cliCircuit.backend);
3432
}).timeout(10e3);
3533
});

compiler/wasm/test/shared.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { compile } from '@noir-lang/noir_wasm';
44
export const noirSourcePath = '../../noir-script/src/main.nr';
55
export const nargoArtifactPath = '../../noir-script/target/noir_wasm_testing.json';
66

7-
export async function compileNoirSource(noir_source: string): Promise<unknown> {
7+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8+
export async function compileNoirSource(noir_source: string): Promise<any> {
89
console.log('Compiling Noir source...');
910

1011
initializeResolver((id: string) => {
@@ -24,7 +25,7 @@ export async function compileNoirSource(noir_source: string): Promise<unknown> {
2425

2526
console.log('Noir source compilation done.');
2627

27-
return compiled_noir.circuit;
28+
return compiled_noir;
2829
} catch (e) {
2930
console.log('Error while compiling:', e);
3031
}

0 commit comments

Comments
 (0)