From 33bf54f51b4917faafede7bf03e561627e8f5e19 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 13 Jan 2020 23:35:37 +0100 Subject: [PATCH] refactor zokrates_js lib --- zokrates_js/src/lib.rs | 97 ++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/zokrates_js/src/lib.rs b/zokrates_js/src/lib.rs index a8af3ea3..17dbac8e 100644 --- a/zokrates_js/src/lib.rs +++ b/zokrates_js/src/lib.rs @@ -1,12 +1,14 @@ +use bincode::{deserialize, serialize}; use serde::{Deserialize, Serialize}; +use serde_json::to_string_pretty; use wasm_bindgen::prelude::*; use zokrates_abi::{parse_strict, Encode, Inputs}; -use zokrates_core::compile::{compile as compile_core, CompileErrors, CompilationArtifacts}; +use zokrates_core::compile::{compile as core_compile, CompilationArtifacts}; use zokrates_core::imports::Error; use zokrates_core::ir; +use zokrates_core::proof_system::{self, ProofSystem}; use zokrates_core::typed_absy::abi::Abi; use zokrates_core::typed_absy::Type; -use zokrates_core::proof_system::{self, ProofSystem}; use zokrates_field::field::FieldPrime; #[derive(Serialize, Deserialize)] @@ -21,82 +23,88 @@ pub struct CompilationResult { abi: String, } +impl ResolverResult { + fn to_tuple(&self) -> (String, String) { + (self.source.clone(), self.location.clone()) + } +} + +#[inline] fn deserialize_program(value: &Vec) -> Result, JsValue> { - bincode::deserialize(&value) + deserialize(&value) .map_err(|err| JsValue::from_str(&format!("Could not deserialize program: {}", err))) } +#[inline] +fn serialize_program(program: &ir::Prog) -> Result, JsValue> { + serialize(program) + .map_err(|err| JsValue::from_str(&format!("Could not serialize program: {}", err))) +} + #[wasm_bindgen] pub fn compile( source: JsValue, location: JsValue, - resolve: &js_sys::Function) -> Result { + resolve: &js_sys::Function, +) -> Result { + let closure = |l: String, p: String| { + let value = resolve + .call2(&JsValue::UNDEFINED, &l.into(), &p.clone().into()) + .map_err(|_| { + Error::new(format!( + "Error thrown in callback: Could not resolve `{}`", + p + )) + })?; - let closure = |l: String, p: String| match resolve.call2( - &JsValue::UNDEFINED, - &l.into(), - &p.clone().into(), - ) { - Ok(value) => { - if value.is_null() || value.is_undefined() { - Err(Error::new(format!("Could not resolve `{}`", p))) - } else { - let result: ResolverResult = value - .into_serde() - .map_err(|_| Error::new(format!("Invalid resolve object format")))?; - Ok((result.source, result.location)) - } + if value.is_null() || value.is_undefined() { + Err(Error::new(format!("Could not resolve `{}`", p))) + } else { + let result: ResolverResult = value.into_serde().unwrap(); + Ok(result.to_tuple()) } - Err(_) => Err(Error::new(format!( - "Error thrown in resolve callback; could not resolve `{}`", - p - ))), }; - let result: Result, CompileErrors> = compile_core( + let artifacts: CompilationArtifacts = core_compile( source.as_string().unwrap(), location.as_string().unwrap(), Some(&closure), - ); + ) + .map_err(|ce| JsValue::from_str(&format!("{}", ce)))?; - match result { - Ok(artifacts) => { - let program: Vec = bincode::serialize(artifacts.prog()).unwrap(); - let abi: String = serde_json::to_string_pretty(artifacts.abi()).unwrap(); + let result = CompilationResult { + program: serialize_program(artifacts.prog())?, + abi: to_string_pretty(artifacts.abi()).unwrap(), + }; - let output: CompilationResult = CompilationResult { program, abi }; - Ok(JsValue::from_serde(&output).unwrap()) - } - Err(ce) => Err(JsValue::from_str(&format!("{}", ce))), - } + Ok(JsValue::from_serde(&result).unwrap()) } #[wasm_bindgen] pub fn compute_witness(artifacts: JsValue, args: JsValue) -> Result { let result: CompilationResult = artifacts.into_serde().unwrap(); - let program_flattened: ir::Prog = deserialize_program(&result.program)?; + let program_flattened = deserialize_program(&result.program)?; let abi: Abi = serde_json::from_str(result.abi.as_str()) .map_err(|err| JsValue::from_str(&format!("Could not deserialize abi: {}", err)))?; - let input: String = args.as_string().unwrap(); + let input = args.as_string().unwrap(); let input_types: Vec = abi.inputs.iter().map(|i| i.ty.clone()).collect(); let inputs = parse_strict(&input, input_types) .map(|parsed| Inputs::Abi(parsed)) .map_err(|why| JsValue::from_str(&format!("{}", why.to_string())))?; - let witness = program_flattened.execute(&inputs.encode()); - match witness { - Ok(witness) => Ok(JsValue::from_str(&format!("{}", witness))), - Err(error) => Err(JsValue::from_str(&format!("Execution failed: {}", error))), - } + program_flattened + .execute(&inputs.encode()) + .map(|witness| JsValue::from_str(&format!("{}", witness))) + .map_err(|err| JsValue::from_str(&format!("Execution failed: {}", err))) } #[wasm_bindgen] pub fn setup(program: JsValue) -> Result { let input: Vec = program.into_serde().unwrap(); - let program_flattened: ir::Prog = deserialize_program(&input)?; + let program_flattened = deserialize_program(&input)?; let keypair = proof_system::G16 {}.setup(program_flattened); Ok(JsValue::from_serde(&keypair).unwrap()) } @@ -111,15 +119,14 @@ pub fn export_solidity_verifier(vk: JsValue, is_abiv2: JsValue) -> JsValue { #[wasm_bindgen] pub fn generate_proof(program: JsValue, witness: JsValue, pk: JsValue) -> Result { let input: Vec = program.into_serde().unwrap(); - let program_flattened: ir::Prog = deserialize_program(&input)?; + let program_flattened = deserialize_program(&input)?; - let str_witness: String = witness.as_string().unwrap(); + let str_witness = witness.as_string().unwrap(); let ir_witness: ir::Witness = ir::Witness::read(str_witness.as_bytes()) .map_err(|err| JsValue::from_str(&format!("Could not read witness: {}", err)))?; let proving_key: Vec = pk.into_serde().unwrap(); - let proof: String = - proof_system::G16 {}.generate_proof(program_flattened, ir_witness, proving_key); + let proof = proof_system::G16 {}.generate_proof(program_flattened, ir_witness, proving_key); Ok(JsValue::from_str(proof.as_str())) }