Skip to content

Commit

Permalink
Merge branch 'master' into tf/improve-noir-wasm
Browse files Browse the repository at this point in the history
* master:
  feat(wasm)!: update wasm artifacts to match cli artifacts (#2973)
  chore: Update ACIR artifacts (#2971)
  chore: refactor LSP code for readability and dev ex (#2969)
  • Loading branch information
TomAFrench committed Oct 3, 2023
2 parents 22e91cb + ce16c0b commit 77674a4
Show file tree
Hide file tree
Showing 32 changed files with 446 additions and 383 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,16 @@ test_cases.forEach((testInfo) => {

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

let compile_output;
let noir_program;
try {
compile_output = await getCircuit(noir_source);
noir_program = await getCircuit(noir_source);

expect(await compile_output, 'Compile output ').to.be.an('object');
expect(await noir_program, 'Compile output ').to.be.an('object');
} catch (e) {
expect(e, 'Compilation Step').to.not.be.an('error');
throw e;
}

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

Expand Down
6 changes: 2 additions & 4 deletions compiler/integration-tests/test/browser/recursion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ describe('It compiles noir program code, receiving circuit bytes and abi object.
});

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

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

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

logger.debug('recursion_inputs', recursion_inputs);

const { circuit: recursion_circuit, abi: recursion_abi } = await getCircuit(circuit_recursion_source);
const recursion_program = { bytecode: recursion_circuit, abi: recursion_abi };
const recursion_program = await getCircuit(circuit_recursion_source);

const recursion_backend = new BarretenbergBackend(recursion_program);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ test_cases.forEach((testInfo) => {

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

const compile_output = compile(noir_source_path);
const noir_program = compile(noir_source_path);

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

Expand Down
45 changes: 43 additions & 2 deletions compiler/wasm/src/compile.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use fm::FileManager;
use gloo_utils::format::JsValueSerdeExt;
use js_sys::Array;
use nargo::artifacts::{
contract::{PreprocessedContract, PreprocessedContractFunction},
program::PreprocessedProgram,
};
use noirc_driver::{
add_dep, compile_contract, compile_main, prepare_crate, prepare_dependency, CompileOptions,
CompiledContract, CompiledProgram,
};
use noirc_frontend::{graph::CrateGraph, hir::Context};
use std::path::Path;
use wasm_bindgen::prelude::*;

use crate::errors::JsCompileError;

const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg";

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(extends = Array, js_name = "StringArray", typescript_type = "string[]")]
Expand Down Expand Up @@ -56,7 +63,9 @@ pub fn compile(
nargo::ops::optimize_contract(compiled_contract, np_language, &is_opcode_supported)
.expect("Contract optimization failed");

Ok(<JsValue as JsValueSerdeExt>::from_serde(&optimized_contract).unwrap())
let preprocessed_contract = preprocess_contract(optimized_contract);

Ok(<JsValue as JsValueSerdeExt>::from_serde(&preprocessed_contract).unwrap())
} else {
let compiled_program = compile_main(&mut context, crate_id, &compile_options, None, true)
.map_err(|_| JsCompileError::new("Failed to compile program".to_string()))?
Expand All @@ -66,7 +75,9 @@ pub fn compile(
nargo::ops::optimize_program(compiled_program, np_language, &is_opcode_supported)
.expect("Program optimization failed");

Ok(<JsValue as JsValueSerdeExt>::from_serde(&optimized_program).unwrap())
let preprocessed_program = preprocess_program(optimized_program);

Ok(<JsValue as JsValueSerdeExt>::from_serde(&preprocessed_program).unwrap())
}
}

Expand Down Expand Up @@ -98,6 +109,36 @@ fn add_noir_lib(context: &mut Context, library_name: &str) {
}
}

fn preprocess_program(program: CompiledProgram) -> PreprocessedProgram {
PreprocessedProgram {
hash: program.hash,
backend: String::from(BACKEND_IDENTIFIER),
abi: program.abi,
bytecode: program.circuit,
}
}

fn preprocess_contract(contract: CompiledContract) -> PreprocessedContract {
let preprocessed_functions = contract
.functions
.into_iter()
.map(|func| PreprocessedContractFunction {
name: func.name,
function_type: func.function_type,
is_internal: func.is_internal,
abi: func.abi,
bytecode: func.bytecode,
})
.collect();

PreprocessedContract {
name: contract.name,
backend: String::from(BACKEND_IDENTIFIER),
functions: preprocessed_functions,
events: contract.events,
}
}

cfg_if::cfg_if! {
if #[cfg(target_os = "wasi")] {

Check warning on line 143 in compiler/wasm/src/compile.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (wasi)
fn get_non_stdlib_asset(path_to_file: &Path) -> std::io::Result<String> {
Expand Down
14 changes: 9 additions & 5 deletions compiler/wasm/test/browser/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@ async function getSource(): Promise<string> {
return getFileContent(noirSourcePath);
}

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

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

const wasmCircuitBase64 = await compileNoirSource(source);
const wasmCircuit = await compileNoirSource(source);

const cliCircuitBase64 = await getPrecompiledSource();
const cliCircuit = await getPrecompiledSource();

expect(wasmCircuitBase64).to.equal(cliCircuitBase64);
// We don't expect the hashes to match due to how `noir_wasm` handles dependencies
expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode);
expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi);
expect(wasmCircuit.backend).to.eq(cliCircuit.backend);
}).timeout(20e3); // 20 seconds
});
20 changes: 9 additions & 11 deletions compiler/wasm/test/node/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,23 @@ async function getSource(): Promise<string> {
return getFileContent(noirSourcePath);
}

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

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

const wasmCircuitBase64 = await compileNoirSource(source);
const wasmCircuit = await compileNoirSource(source);

const cliCircuitBase64 = await getPrecompiledSource();
const cliCircuit = await getPrecompiledSource();

console.log('wasm', wasmCircuitBase64);

console.log('cli', cliCircuitBase64);

console.log('Compilation is a match? ', wasmCircuitBase64 === cliCircuitBase64);

expect(wasmCircuitBase64).to.equal(cliCircuitBase64);
// We don't expect the hashes to match due to how `noir_wasm` handles dependencies
expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode);
expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi);
expect(wasmCircuit.backend).to.eq(cliCircuit.backend);
}).timeout(10e3);
});
5 changes: 3 additions & 2 deletions compiler/wasm/test/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { compile } from '@noir-lang/noir_wasm';
export const noirSourcePath = '../../noir-script/src/main.nr';
export const nargoArtifactPath = '../../noir-script/target/noir_wasm_testing.json';

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

initializeResolver((id: string) => {
Expand All @@ -26,7 +27,7 @@ export async function compileNoirSource(noir_source: string): Promise<unknown> {

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

return compiled_noir.circuit;
return compiled_noir;
} catch (e) {
console.log('Error while compiling:', e);
}
Expand Down
Loading

0 comments on commit 77674a4

Please sign in to comment.