Skip to content

Commit 83e21b6

Browse files
committed
create http server which serves bindings functions
1 parent f0c512d commit 83e21b6

23 files changed

+497
-10
lines changed

Cargo.lock

+44-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ axum = { version = "0.7.7" }
2929
byteorder = { version = "1.4.3" }
3030
chacha20poly1305 = { version = "0.10.1", default-features = false }
3131
clap = { version = "4.5.8" }
32+
ctor = { version = "0.2.9" }
3233
getrandom = { version = "0.2" }
3334
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v0.3.0", default-features = false }
3435
halo2curves = { version = "0.6.0", default-features = false }
@@ -38,7 +39,10 @@ itertools = { version = "0.13.0" }
3839
metrics = { version = "0.24.1", default-features = false }
3940
metrics-exporter-prometheus = { version = "0.16.0", default-features = false }
4041
num-bigint = { version = "0.4.3" }
42+
once_cell = { version = "1.20.2" }
4143
openssl = { version = "0.10.59" }
44+
quote = { version = "1.0.38" }
45+
proc-macro2 = { version = "1.0.93" }
4246
rand = { version = "0.8.5" }
4347
rayon = { version = "1.8" }
4448
reqwest = { version = "0.12.5" }
@@ -67,9 +71,12 @@ wasm-bindgen-rayon = { version = "1.2.1" }
6771
content-encryption = { path = "crates/content-encryption", default-features = false }
6872
evm-utils = { path = "crates/evm-utils" }
6973
halo2_solidity_verifier = { path = "crates/halo2-verifier" }
74+
macros-core = { path = "crates/macros-core" }
75+
macros = { path = "crates/macros" }
7076
powers-of-tau = { path = "crates/powers-of-tau" }
7177
shielder-account = { path = "crates/shielder-account" }
7278
shielder-contract = { path = "crates/shielder-contract" }
7379
shielder-relayer = { path = "crates/shielder-relayer" }
7480
shielder-setup = { path = "crates/shielder-setup" }
7581
type-conversions = { path = "crates/type-conversions" }
82+
shielder_bindings = { path = "crates/shielder_bindings" }

crates/macros-core/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "macros-core"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
once_cell = { workspace = true }
8+
serde_json = { workspace = true }

crates/macros-core/src/lib.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::sync::Mutex;
2+
3+
use once_cell::sync::Lazy;
4+
use serde_json::Value;
5+
6+
pub type JsonFnPointer = fn(Value) -> Value;
7+
8+
/// A simple struct to hold info about an "exported" function.
9+
#[derive(Debug, Clone)]
10+
pub struct JsonizedFunction {
11+
/// The function name as a string.
12+
pub name: &'static str,
13+
// You could store more metadata here (e.g., param types, function pointer, etc.).
14+
pub func: JsonFnPointer,
15+
}
16+
17+
/// A global registry of exported functions.
18+
///
19+
/// By using `Lazy<Mutex<...>>`, we can push to this vector at compile time
20+
/// (technically, it's “init-time” for each static), and read it later.
21+
pub static EXPORTED_FUNCTIONS: Lazy<Mutex<Vec<JsonizedFunction>>> =
22+
Lazy::new(|| Mutex::new(Vec::new()));

crates/macros/Cargo.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "macros"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
proc-macro = true
8+
9+
[dependencies]
10+
ctor = { workspace = true }
11+
macros-core = { workspace = true }
12+
once_cell = { workspace = true }
13+
proc-macro2 = { workspace = true }
14+
quote = { workspace = true }
15+
syn = { version = "1", features = ["full"] }

crates/macros/src/args.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use proc_macro2::Ident;
2+
use quote::{format_ident, quote};
3+
use syn::{FnArg, Pat, Type};
4+
5+
/// Helper struct to store parsed argument information
6+
pub struct ArgumentInfo {
7+
pub name: Ident,
8+
pub ty: Box<Type>,
9+
}
10+
11+
/// Parse function arguments into a vector of ArgumentInfo
12+
pub fn parse_arguments(
13+
inputs: &syn::punctuated::Punctuated<FnArg, syn::token::Comma>,
14+
) -> Vec<ArgumentInfo> {
15+
let mut args = Vec::new();
16+
17+
for (i, arg) in inputs.iter().enumerate() {
18+
if let FnArg::Typed(pat_type) = arg {
19+
let arg_name = match &*pat_type.pat {
20+
Pat::Ident(ident) => ident.ident.clone(),
21+
_ => format_ident!("arg{}", i),
22+
};
23+
args.push(ArgumentInfo {
24+
name: arg_name,
25+
ty: pat_type.ty.clone(),
26+
});
27+
}
28+
}
29+
30+
args
31+
}
32+
33+
/// Generate Deserealizable struct definition for function arguments
34+
pub fn generate_args_struct(
35+
struct_name: &Ident,
36+
args: &[ArgumentInfo],
37+
) -> proc_macro2::TokenStream {
38+
let fields = args.iter().map(|arg| {
39+
let name = &arg.name;
40+
let ty = &arg.ty;
41+
quote! { pub #name: #ty }
42+
});
43+
let fields_ts = quote! {
44+
#(#fields),*
45+
};
46+
47+
quote! {
48+
#[allow(non_camel_case_types)]
49+
#[derive(::serde::Deserialize)]
50+
struct #struct_name {
51+
#fields_ts
52+
}
53+
}
54+
}

crates/macros/src/bridging.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use proc_macro2::Ident;
2+
use quote::quote;
3+
4+
use crate::args::ArgumentInfo;
5+
6+
/// Generate bridging function that converts between JSON and native types
7+
/// JSON is parsed into a Deserealizable struct, then the function is called
8+
/// with the struct fields as arguments. The result is then serialized back
9+
/// into JSON.
10+
pub fn generate_bridging_fn(
11+
fn_name: &Ident,
12+
struct_name: &Ident,
13+
args: &[ArgumentInfo],
14+
ret_type: &proc_macro2::TokenStream,
15+
call_path: proc_macro2::TokenStream,
16+
) -> (proc_macro2::TokenStream, Ident) {
17+
let arg_names: Vec<_> = args.iter().map(|arg| &arg.name).collect();
18+
let bridging_name = quote::format_ident!("{}_json", fn_name);
19+
20+
(
21+
quote! {
22+
#[allow(non_snake_case)]
23+
fn #bridging_name(input: ::serde_json::Value) -> ::serde_json::Value {
24+
let args: #struct_name = match ::serde_json::from_value(input) {
25+
Ok(val) => val,
26+
Err(e) => {
27+
return ::serde_json::json!({
28+
"error": format!("Invalid input JSON: {}", e)
29+
});
30+
}
31+
};
32+
33+
let result: #ret_type = #call_path(#( args.#arg_names ),*);
34+
::serde_json::json!(result)
35+
}
36+
},
37+
bridging_name,
38+
)
39+
}

0 commit comments

Comments
 (0)