mirror of https://github.com/vacp2p/zerokit.git
Macro to call functions with an error message with output (#141)
Another variation of our call, this time when output is used
This commit is contained in:
parent
6ff4eeb237
commit
39bea35a6d
|
@ -3,6 +3,8 @@
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
extern crate web_sys;
|
extern crate web_sys;
|
||||||
|
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
use js_sys::{BigInt as JsBigInt, Object, Uint8Array};
|
use js_sys::{BigInt as JsBigInt, Object, Uint8Array};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use rln::public::RLN;
|
use rln::public::RLN;
|
||||||
|
@ -20,6 +22,45 @@ pub struct RLNWrapper {
|
||||||
instance: RLN<'static>,
|
instance: RLN<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Macro to call methods with arbitrary amount of arguments,
|
||||||
|
// which have the last argument is output buffer pointer
|
||||||
|
// First argument to the macro is context,
|
||||||
|
// second is the actual method on `RLN`
|
||||||
|
// third is the aforementioned output buffer argument
|
||||||
|
// rest are all other arguments to the method
|
||||||
|
macro_rules! call_with_output_and_error_msg {
|
||||||
|
// this variant is needed for the case when
|
||||||
|
// there are zero other arguments
|
||||||
|
($instance:expr, $method:ident, $error_msg:expr) => {
|
||||||
|
{
|
||||||
|
let mut output_data: Vec<u8> = Vec::new();
|
||||||
|
let new_instance = $instance.process();
|
||||||
|
if let Err(err) = new_instance.instance.$method(&mut output_data) {
|
||||||
|
std::mem::forget(output_data);
|
||||||
|
Err(format!("Msg: {:#?}, Error: {:#?}", $error_msg, err))
|
||||||
|
} else {
|
||||||
|
let result = Uint8Array::from(&output_data[..]);
|
||||||
|
std::mem::forget(output_data);
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($instance:expr, $method:ident, $error_msg:expr, $( $arg:expr ),* ) => {
|
||||||
|
{
|
||||||
|
let mut output_data: Vec<u8> = Vec::new();
|
||||||
|
let new_instance = $instance.process();
|
||||||
|
if let Err(err) = new_instance.instance.$method($($arg.process()),*, &mut output_data) {
|
||||||
|
std::mem::forget(output_data);
|
||||||
|
Err(format!("Msg: {:#?}, Error: {:#?}", $error_msg, err))
|
||||||
|
} else {
|
||||||
|
let result = Uint8Array::from(&output_data[..]);
|
||||||
|
std::mem::forget(output_data);
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Macro to call_with_error_msg methods with arbitrary amount of arguments,
|
// Macro to call_with_error_msg methods with arbitrary amount of arguments,
|
||||||
// First argument to the macro is context,
|
// First argument to the macro is context,
|
||||||
// second is the actual method on `RLNWrapper`
|
// second is the actual method on `RLNWrapper`
|
||||||
|
@ -50,6 +91,13 @@ impl ProcessArg for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> ProcessArg for Vec<T> {
|
||||||
|
type ReturnType = Vec<T>;
|
||||||
|
fn process(self) -> Self::ReturnType {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ProcessArg for *const RLN<'a> {
|
impl<'a> ProcessArg for *const RLN<'a> {
|
||||||
type ReturnType = &'a RLN<'a>;
|
type ReturnType = &'a RLN<'a>;
|
||||||
fn process(self) -> Self::ReturnType {
|
fn process(self) -> Self::ReturnType {
|
||||||
|
@ -57,20 +105,21 @@ impl<'a> ProcessArg for *const RLN<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ProcessArgRef {
|
impl ProcessArg for *const RLNWrapper {
|
||||||
type ReturnType;
|
type ReturnType = &'static RLNWrapper;
|
||||||
fn process(self) -> Self::ReturnType;
|
fn process(self) -> Self::ReturnType {
|
||||||
|
unsafe { &*self }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessArgRef for *mut RLNWrapper {
|
impl ProcessArg for *mut RLNWrapper {
|
||||||
type ReturnType = &'static mut RLNWrapper;
|
type ReturnType = &'static mut RLNWrapper;
|
||||||
|
|
||||||
fn process(self) -> Self::ReturnType {
|
fn process(self) -> Self::ReturnType {
|
||||||
unsafe { &mut *self }
|
unsafe { &mut *self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ProcessArgRef for &'a [u8] {
|
impl<'a> ProcessArg for &'a [u8] {
|
||||||
type ReturnType = &'a [u8];
|
type ReturnType = &'a [u8];
|
||||||
|
|
||||||
fn process(self) -> Self::ReturnType {
|
fn process(self) -> Self::ReturnType {
|
||||||
|
@ -167,8 +216,6 @@ pub fn generate_rln_proof_with_witness(
|
||||||
calculated_witness: Vec<JsBigInt>,
|
calculated_witness: Vec<JsBigInt>,
|
||||||
serialized_witness: Uint8Array,
|
serialized_witness: Uint8Array,
|
||||||
) -> Result<Uint8Array, String> {
|
) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &mut *ctx };
|
|
||||||
|
|
||||||
let mut witness_vec: Vec<BigInt> = vec![];
|
let mut witness_vec: Vec<BigInt> = vec![];
|
||||||
|
|
||||||
for v in calculated_witness {
|
for v in calculated_witness {
|
||||||
|
@ -182,69 +229,36 @@ pub fn generate_rln_proof_with_witness(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
call_with_output_and_error_msg!(
|
||||||
|
ctx,
|
||||||
if wrapper
|
generate_rln_proof_with_witness,
|
||||||
.instance
|
"could not generate proof",
|
||||||
.generate_rln_proof_with_witness(witness_vec, serialized_witness.to_vec(), &mut output_data)
|
witness_vec,
|
||||||
.is_ok()
|
serialized_witness.to_vec()
|
||||||
{
|
)
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not generate proof".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[wasm_bindgen(js_name = generateMembershipKey)]
|
#[wasm_bindgen(js_name = generateMembershipKey)]
|
||||||
pub fn wasm_key_gen(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
pub fn wasm_key_gen(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(ctx, key_gen, "could not generate membership keys")
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
if wrapper.instance.key_gen(&mut output_data).is_ok() {
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not generate membership keys".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[wasm_bindgen(js_name = generateExtendedMembershipKey)]
|
#[wasm_bindgen(js_name = generateExtendedMembershipKey)]
|
||||||
pub fn wasm_extended_key_gen(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
pub fn wasm_extended_key_gen(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(ctx, extended_key_gen, "could not generate membership keys")
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
if wrapper.instance.extended_key_gen(&mut output_data).is_ok() {
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not generate membership keys".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[wasm_bindgen(js_name = generateSeededMembershipKey)]
|
#[wasm_bindgen(js_name = generateSeededMembershipKey)]
|
||||||
pub fn wasm_seeded_key_gen(ctx: *const RLNWrapper, seed: Uint8Array) -> Result<Uint8Array, String> {
|
pub fn wasm_seeded_key_gen(ctx: *const RLNWrapper, seed: Uint8Array) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
ctx,
|
||||||
if wrapper
|
seeded_key_gen,
|
||||||
.instance
|
"could not generate membership key",
|
||||||
.seeded_key_gen(&seed.to_vec()[..], &mut output_data)
|
&seed.to_vec()[..]
|
||||||
.is_ok()
|
)
|
||||||
{
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not generate membership key".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
@ -253,20 +267,12 @@ pub fn wasm_seeded_extended_key_gen(
|
||||||
ctx: *const RLNWrapper,
|
ctx: *const RLNWrapper,
|
||||||
seed: Uint8Array,
|
seed: Uint8Array,
|
||||||
) -> Result<Uint8Array, String> {
|
) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
ctx,
|
||||||
if wrapper
|
seeded_extended_key_gen,
|
||||||
.instance
|
"could not generate membership key",
|
||||||
.seeded_extended_key_gen(&seed.to_vec()[..], &mut output_data)
|
&seed.to_vec()[..]
|
||||||
.is_ok()
|
)
|
||||||
{
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not generate membership key".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
@ -276,24 +282,13 @@ pub fn wasm_recover_id_secret(
|
||||||
input_proof_data_1: Uint8Array,
|
input_proof_data_1: Uint8Array,
|
||||||
input_proof_data_2: Uint8Array,
|
input_proof_data_2: Uint8Array,
|
||||||
) -> Result<Uint8Array, String> {
|
) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
ctx,
|
||||||
if wrapper
|
recover_id_secret,
|
||||||
.instance
|
"could not recover id secret",
|
||||||
.recover_id_secret(
|
&input_proof_data_1.to_vec()[..],
|
||||||
&input_proof_data_1.to_vec()[..],
|
&input_proof_data_2.to_vec()[..]
|
||||||
&input_proof_data_2.to_vec()[..],
|
)
|
||||||
&mut output_data,
|
|
||||||
)
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not recover id secret".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
@ -334,14 +329,5 @@ pub fn wasm_verify_with_roots(
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[wasm_bindgen(js_name = getRoot)]
|
#[wasm_bindgen(js_name = getRoot)]
|
||||||
pub fn wasm_get_root(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
pub fn wasm_get_root(ctx: *const RLNWrapper) -> Result<Uint8Array, String> {
|
||||||
let wrapper = unsafe { &*ctx };
|
call_with_output_and_error_msg!(ctx, get_root, "could not obtain root")
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
if wrapper.instance.get_root(&mut output_data).is_ok() {
|
|
||||||
let result = Uint8Array::from(&output_data[..]);
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
Err("could not obtain root".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue