Skip to content

Commit ea66645

Browse files
authored
Merge pull request #2 from Sindri-Labs/klm-introduce-blocking-methods
Introduce blocking circuit create & prove
2 parents 3af55af + 5a6571a commit ea66645

File tree

4 files changed

+121
-11
lines changed

4 files changed

+121
-11
lines changed

sindri-rs/src/client.rs

+41-5
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl SindriClient {
213213
///
214214
/// # Examples
215215
///
216-
/// ```
216+
/// ```ignore
217217
/// use sindri_rs::client::SindriClient;
218218
///
219219
/// let client = SindriClient::new(None, None);
@@ -298,6 +298,20 @@ impl SindriClient {
298298
Ok(circuit_info)
299299
}
300300

301+
/// Blocking version of `create_circuit`.
302+
///
303+
/// This method provides the same functionality as `create_circuit` but can be used
304+
/// in synchronous contexts. It internally creates a runtime to execute the async operation.
305+
pub fn create_circuit_blocking(
306+
&self,
307+
project: String,
308+
tags: Option<Vec<String>>,
309+
meta: Option<HashMap<String, String>>,
310+
) -> Result<CircuitInfoResponse, Box<dyn std::error::Error>> {
311+
let runtime = tokio::runtime::Runtime::new()?;
312+
runtime.block_on(self.create_circuit(project, tags, meta))
313+
}
314+
301315
/// Deletes a circuit by ID.
302316
///
303317
/// # Arguments
@@ -333,7 +347,7 @@ impl SindriClient {
333347
///
334348
/// # Examples
335349
///
336-
/// ```
350+
/// ```ignore
337351
/// use sindri_rs::client::SindriClient;
338352
///
339353
/// let client = SindriClient::new(None, None);
@@ -395,7 +409,7 @@ impl SindriClient {
395409
///
396410
/// # Examples
397411
///
398-
/// ```
412+
/// ```ignore
399413
/// use sindri_rs::client::SindriClient;
400414
///
401415
/// let client = SindriClient::new(None, None);
@@ -437,7 +451,7 @@ impl SindriClient {
437451
///
438452
/// # Examples
439453
///
440-
/// ```
454+
/// ```ignore
441455
/// use sindri_rs::client::SindriClient;
442456
///
443457
/// let client = SindriClient::new(None, None);
@@ -496,6 +510,28 @@ impl SindriClient {
496510
Ok(proof_info)
497511
}
498512

513+
/// Blocking version of `prove_circuit`.
514+
///
515+
/// This method provides the same functionality as `prove_circuit` but can be used
516+
/// in synchronous contexts. It internally creates a runtime to execute the async operation.
517+
pub fn prove_circuit_blocking(
518+
&self,
519+
circuit_id: &str,
520+
proof_input: impl Into<ProofInput>,
521+
meta: Option<HashMap<String, String>>,
522+
verify: Option<bool>,
523+
prover_implementation: Option<String>,
524+
) -> Result<ProofInfoResponse, Box<dyn std::error::Error>> {
525+
let runtime = tokio::runtime::Runtime::new()?;
526+
runtime.block_on(self.prove_circuit(
527+
circuit_id,
528+
proof_input,
529+
meta,
530+
verify,
531+
prover_implementation,
532+
))
533+
}
534+
499535
/// Deletes a proof by ID.
500536
///
501537
/// # Arguments
@@ -533,7 +569,7 @@ impl SindriClient {
533569
///
534570
/// # Examples
535571
///
536-
/// ```
572+
/// ```ignore
537573
/// use sindri_rs::client::SindriClient;
538574
///
539575
/// let client = SindriClient::new(None, None);

sindri-rs/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//!
1313
//! Generate your first zero-knowledge proof in just a few lines of code:
1414
//!
15-
//! ```rust
15+
//! ```ignore
1616
//! use sindri_rs::client::SindriClient;
1717
//!
1818
//! let client = SindriClient::new(None, None);

sindri-rs/tests/projects.rs

+43-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::{
2-
collections::{HashMap, HashSet},
3-
fs,
4-
io::Cursor,
5-
};
1+
use std::collections::{HashMap, HashSet};
2+
#[cfg(not(any(feature = "record", feature = "replay")))]
3+
use std::{fs, io::Cursor};
64

5+
#[cfg(not(any(feature = "record", feature = "replay")))]
76
use flate2::read::GzDecoder;
7+
#[cfg(not(any(feature = "record", feature = "replay")))]
88
use tar::Archive;
99
use tempfile::TempDir;
1010

@@ -51,6 +51,44 @@ async fn test_create_circuit() {
5151
assert_eq!(circom_info.num_outputs, Some(1));
5252
}
5353

54+
#[test]
55+
fn test_create_circuit_blocking() {
56+
let (_temp_dir, dir_path) = factory::baby_circuit();
57+
58+
let client = SindriClient::new(None, None);
59+
60+
let test_tags = vec!["tag1".to_string(), "tag2".to_string()];
61+
let test_meta = HashMap::from([
62+
("key1".to_string(), "value1".to_string()),
63+
("key2".to_string(), "value2".to_string()),
64+
]);
65+
66+
let result = client
67+
.create_circuit_blocking(
68+
dir_path.to_string_lossy().to_string(),
69+
Some(test_tags.clone()),
70+
Some(test_meta.clone()),
71+
);
72+
73+
assert!(result.is_ok());
74+
let circuit = result.unwrap();
75+
76+
assert_eq!(*circuit.status(), JobStatus::Ready);
77+
assert_eq!(circuit.meta(), &test_meta);
78+
assert_eq!(
79+
circuit.tags().iter().collect::<HashSet<_>>(),
80+
test_tags.iter().collect::<HashSet<_>>()
81+
);
82+
83+
let circom_info = match circuit {
84+
CircuitInfoResponse::Circom(circom_info) => circom_info,
85+
_ => panic!("Circuit is not of Circom type"),
86+
};
87+
88+
assert_eq!(circom_info.proving_scheme, "groth16");
89+
assert_eq!(circom_info.num_outputs, Some(1));
90+
}
91+
5492
#[tokio::test]
5593
async fn test_delete_circuit() {
5694
let (_temp_dir, dir_path) = factory::baby_circuit();

sindri-rs/tests/proofs.rs

+36
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,42 @@ async fn test_create_proof_basic() {
4848
assert_eq!(proof.meta, test_meta);
4949
}
5050

51+
#[test]
52+
fn test_create_proof_basic_blocking() {
53+
let (_temp_dir, dir_path) = factory::baby_circuit();
54+
55+
let client = SindriClient::new(None, None);
56+
57+
// Create circuit first (using blocking version for consistency)
58+
let circuit = client
59+
.create_circuit_blocking(
60+
dir_path.to_string_lossy().to_string(),
61+
Some(vec!["prove_basic_blocking".to_string()]),
62+
None,
63+
)
64+
.unwrap();
65+
let circuit_identifier = circuit.id();
66+
67+
let input = r#"{"a": 1, "b": 2}"#;
68+
let test_meta = HashMap::from([
69+
("key1".to_string(), "value1".to_string()),
70+
("key2".to_string(), "value2".to_string()),
71+
]);
72+
let result = client.prove_circuit_blocking(
73+
circuit_identifier,
74+
input,
75+
Some(test_meta.clone()),
76+
None,
77+
None,
78+
);
79+
80+
assert!(result.is_ok());
81+
let proof = result.unwrap();
82+
83+
assert!(!proof.proof_id.is_empty());
84+
assert_eq!(proof.meta, test_meta);
85+
}
86+
5187
#[tokio::test]
5288
async fn test_create_proof_input_modes() {
5389
let (_temp_dir, dir_path) = factory::baby_circuit();

0 commit comments

Comments
 (0)