Skip to content

Commit 4782d90

Browse files
committed
chore: remove unwraps for errors
1 parent ed66b62 commit 4782d90

File tree

2 files changed

+161
-103
lines changed

2 files changed

+161
-103
lines changed

bindings/java/rust_code/src/errors.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#[derive(Debug)]
2+
pub enum Error {
3+
Jni(jni::errors::Error),
4+
ProverError(eip7594::prover::ProverError),
5+
VerifierError(eip7594::verifier::VerifierError),
6+
}
7+
8+
impl From<jni::errors::Error> for Error {
9+
fn from(err: jni::errors::Error) -> Self {
10+
Error::Jni(err)
11+
}
12+
}
13+
14+
impl From<eip7594::prover::ProverError> for Error {
15+
fn from(err: eip7594::prover::ProverError) -> Self {
16+
Error::ProverError(err)
17+
}
18+
}

bindings/java/rust_code/src/lib.rs

+143-103
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ use jni::objects::{JByteArray, JClass, JLongArray, JObject, JValue};
55
use jni::sys::{jboolean, jlong};
66
use jni::JNIEnv;
77

8-
// TODO: Convert the unwraps into Exceptions
9-
// TODO: The java code solely uses `java/lang/IllegalArgumentException`
10-
// TODO: swap for custom exception or use a more specific exception
8+
mod errors;
9+
use errors::Error;
1110

1211
#[no_mangle]
1312
pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_peerDASContextNew(
@@ -36,18 +35,22 @@ pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_computeCe
3635
blob: JByteArray<'local>,
3736
) -> JObject<'local> {
3837
let ctx = &*(ctx_ptr as *const PeerDASContext);
39-
let blob = env.convert_byte_array(blob).unwrap();
40-
41-
let (cells, proofs) = match ctx.prover_ctx().compute_cells_and_kzg_proofs(&blob) {
38+
match compute_cells_and_kzg_proofs(&mut env, ctx, blob) {
4239
Ok(cells_and_proofs) => cells_and_proofs,
4340
Err(err) => {
44-
env.throw_new("java/lang/IllegalArgumentException", format!("{:?}", err))
45-
.expect("Failed to throw exception for `compute_cells_and_kzg_proofs`");
41+
throw_on_error(&mut env, err, "computeCellsAndKZGProofs");
4642
return JObject::default();
4743
}
48-
};
49-
50-
return cells_and_proofs_to_jobject(&mut env, &cells, &proofs).unwrap();
44+
}
45+
}
46+
fn compute_cells_and_kzg_proofs<'local>(
47+
env: &mut JNIEnv<'local>,
48+
ctx: &PeerDASContext,
49+
blob: JByteArray<'local>,
50+
) -> Result<JObject<'local>, Error> {
51+
let blob = env.convert_byte_array(blob)?;
52+
let (cells, proofs) = ctx.prover_ctx().compute_cells_and_kzg_proofs(&blob)?;
53+
cells_and_proofs_to_jobject(env, &cells, &proofs).map_err(Error::from)
5154
}
5255

5356
#[no_mangle]
@@ -60,18 +63,22 @@ pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_blobToKZG
6063
blob: JByteArray<'local>,
6164
) -> JByteArray<'local> {
6265
let ctx = &*(ctx_ptr as *const PeerDASContext);
63-
let blob = env.convert_byte_array(blob).unwrap();
64-
65-
let commitment = match ctx.prover_ctx().blob_to_kzg_commitment(&blob) {
66+
match blob_to_kzg_commitment(&mut env, ctx, blob) {
6667
Ok(commitment) => commitment,
6768
Err(err) => {
68-
env.throw_new("java/lang/IllegalArgumentException", format!("{:?}", err))
69-
.expect("Failed to throw exception for `blob_to_kzg_commitment`");
69+
throw_on_error(&mut env, err, "blobToKZGCommitment");
7070
return JByteArray::default();
7171
}
72-
};
73-
74-
return env.byte_array_from_slice(&commitment).unwrap();
72+
}
73+
}
74+
fn blob_to_kzg_commitment<'local>(
75+
env: &mut JNIEnv<'local>,
76+
ctx: &PeerDASContext,
77+
blob: JByteArray<'local>,
78+
) -> Result<JByteArray<'local>, Error> {
79+
let blob = env.convert_byte_array(blob)?;
80+
let commitment = ctx.prover_ctx().blob_to_kzg_commitment(&blob)?;
81+
env.byte_array_from_slice(&commitment).map_err(Error::from)
7582
}
7683

7784
#[no_mangle]
@@ -88,24 +95,34 @@ pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_verifyCel
8895
) -> jboolean {
8996
let ctx = &*(ctx_ptr as *const PeerDASContext);
9097

91-
let commitment_bytes = env.convert_byte_array(&commitment_bytes).unwrap();
98+
match verify_cell_kzg_proof(&mut env, ctx, commitment_bytes, cell_id, cell, proof_bytes) {
99+
Ok(result) => result,
100+
Err(err) => {
101+
throw_on_error(&mut env, err, "verifyCellKZGProof");
102+
return jboolean::default();
103+
}
104+
}
105+
}
106+
fn verify_cell_kzg_proof(
107+
env: &mut JNIEnv,
108+
ctx: &PeerDASContext,
109+
commitment_bytes: JByteArray,
110+
cell_id: jlong,
111+
cell: JByteArray,
112+
proof_bytes: JByteArray,
113+
) -> Result<jboolean, Error> {
114+
let commitment_bytes = env.convert_byte_array(commitment_bytes)?;
92115
let cell_id = cell_id as u64;
93-
let cell = env.convert_byte_array(&cell).unwrap();
94-
let proof_bytes = env.convert_byte_array(&proof_bytes).unwrap();
116+
let cell = env.convert_byte_array(cell)?;
117+
let proof_bytes = env.convert_byte_array(proof_bytes)?;
95118

96119
match ctx
97120
.verifier_ctx()
98121
.verify_cell_kzg_proof(&commitment_bytes, cell_id, &cell, &proof_bytes)
99122
{
100-
Ok(_) => return jboolean::from(true),
101-
Err(VerifierError::InvalidProof) => {
102-
return jboolean::from(false);
103-
}
104-
Err(err) => {
105-
env.throw_new("java/lang/IllegalArgumentException", format!("{:?}", err))
106-
.expect("Failed to throw exception for `verify_cell_kzg_proof`");
107-
return jboolean::default();
108-
}
123+
Ok(_) => Ok(jboolean::from(true)),
124+
Err(VerifierError::InvalidProof) => Ok(jboolean::from(false)),
125+
Err(err) => Err(Error::VerifierError(err)),
109126
}
110127
}
111128

@@ -124,30 +141,49 @@ pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_verifyCel
124141
) -> jboolean {
125142
let ctx = &*(ctx_ptr as *const PeerDASContext);
126143

127-
let commitment_bytes = jobject_array_to_2d_byte_array(&mut env, commitment_bytes).unwrap();
128-
let row_indices = jlongarray_to_vec_u64(&env, row_indices);
129-
let column_indices = jlongarray_to_vec_u64(&env, column_indices);
130-
let cells = jobject_array_to_2d_byte_array(&mut env, cells).unwrap();
131-
let proofs = jobject_array_to_2d_byte_array(&mut env, proofs).unwrap();
132-
133-
match ctx.verifier_ctx().verify_cell_kzg_proof_batch(
144+
match verify_cell_kzg_proof_batch(
145+
&mut env,
146+
ctx,
134147
commitment_bytes,
135148
row_indices,
136149
column_indices,
137-
cells.iter().map(|cell| cell.as_slice()).collect(),
150+
cells,
138151
proofs,
139152
) {
140-
Ok(_) => return jboolean::from(true),
141-
Err(VerifierError::InvalidProof) => {
142-
return jboolean::from(false);
143-
}
153+
Ok(result) => result,
144154
Err(err) => {
145-
env.throw_new("java/lang/IllegalArgumentException", format!("{:?}", err))
146-
.expect("Failed to throw exception for `verify_cell_kzg_proof_batch`");
155+
throw_on_error(&mut env, err, "verifyCellKZGProofBatch");
147156
return jboolean::default();
148157
}
149158
}
150159
}
160+
fn verify_cell_kzg_proof_batch<'local>(
161+
env: &mut JNIEnv,
162+
ctx: &PeerDASContext,
163+
commitment_bytes: JObjectArray<'local>,
164+
row_indices: JLongArray,
165+
column_indices: JLongArray,
166+
cells: JObjectArray<'local>,
167+
proofs: JObjectArray<'local>,
168+
) -> Result<jboolean, Error> {
169+
let commitment_bytes = jobject_array_to_2d_byte_array(env, commitment_bytes)?;
170+
let row_indices = jlongarray_to_vec_u64(env, row_indices)?;
171+
let column_indices = jlongarray_to_vec_u64(env, column_indices)?;
172+
let cells = jobject_array_to_2d_byte_array(env, cells)?;
173+
let proofs = jobject_array_to_2d_byte_array(env, proofs)?;
174+
175+
match ctx.verifier_ctx().verify_cell_kzg_proof_batch(
176+
commitment_bytes,
177+
row_indices,
178+
column_indices,
179+
cells.iter().map(|cell| cell.as_slice()).collect(),
180+
proofs,
181+
) {
182+
Ok(_) => Ok(jboolean::from(true)),
183+
Err(VerifierError::InvalidProof) => Ok(jboolean::from(false)),
184+
Err(err) => Err(Error::VerifierError(err)),
185+
}
186+
}
151187

152188
#[no_mangle]
153189
pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_recoverCellsAndProof<
@@ -161,54 +197,52 @@ pub unsafe extern "system" fn Java_ethereum_cryptography_LibPeerDASKZG_recoverCe
161197
) -> JObject<'local> {
162198
let ctx = &*(ctx_ptr as *const PeerDASContext);
163199

164-
let cell_ids = jlongarray_to_vec_u64(&env, cell_ids);
165-
166-
let cells = match jobject_array_to_2d_byte_array(&mut env, cells) {
167-
Ok(cells) => cells,
200+
match recover_cells_and_kzg_proofs(&mut env, ctx, cell_ids, cells) {
201+
Ok(cells_and_proofs) => cells_and_proofs,
168202
Err(err) => {
169-
env.throw_new("java/lang/IllegalArgumentException", &err.to_string())
170-
.expect("Failed to throw exception for `recover_all_cells`");
203+
throw_on_error(&mut env, err, "recoverCellsAndProof");
171204
return JObject::default();
172205
}
173-
};
206+
}
207+
}
208+
fn recover_cells_and_kzg_proofs<'local>(
209+
env: &mut JNIEnv<'local>,
210+
ctx: &PeerDASContext,
211+
cell_ids: JLongArray,
212+
cells: JObjectArray<'local>,
213+
) -> Result<JObject<'local>, Error> {
214+
let cell_ids = jlongarray_to_vec_u64(env, cell_ids)?;
215+
let cells = jobject_array_to_2d_byte_array(env, cells)?;
174216

175-
let (recovered_cells, recovered_proofs) = match ctx.prover_ctx().recover_cells_and_proofs(
217+
let (recovered_cells, recovered_proofs) = ctx.prover_ctx().recover_cells_and_proofs(
176218
cell_ids,
177219
cells.iter().map(|x| x.as_slice()).collect(),
178220
vec![],
179-
) {
180-
Ok(recovered_cells_and_proofs) => recovered_cells_and_proofs,
181-
Err(err) => {
182-
env.throw_new("java/lang/IllegalArgumentException", format!("{:?}", err))
183-
.expect("Failed to throw exception for `recover_all_cells`");
184-
return JObject::default();
185-
}
186-
};
221+
)?;
187222

188-
return cells_and_proofs_to_jobject(&mut env, &recovered_cells, &recovered_proofs).unwrap();
223+
cells_and_proofs_to_jobject(env, &recovered_cells, &recovered_proofs).map_err(Error::from)
189224
}
190225

191-
fn jlongarray_to_vec_u64(env: &JNIEnv, array: JLongArray) -> Vec<u64> {
226+
/// Converts a JLongArray to a Vec<u64>
227+
fn jlongarray_to_vec_u64(env: &JNIEnv, array: JLongArray) -> Result<Vec<u64>, Error> {
192228
// Step 1: Get the length of the JLongArray
193-
let array_length = env
194-
.get_array_length(&array)
195-
.expect("Unable to get array length");
229+
let array_length = env.get_array_length(&array)?;
196230

197231
// Step 2: Create a buffer to hold the jlong elements (these are i64s)
198232
let mut buffer: Vec<i64> = vec![0; array_length as usize];
199233

200234
// Step 3: Get the elements from the JLongArray
201-
env.get_long_array_region(array, 0, &mut buffer)
202-
.expect("Unable to get array region");
235+
env.get_long_array_region(array, 0, &mut buffer)?;
203236

204237
// Step 4: Convert the Vec<i64> to Vec<u64>
205-
buffer.into_iter().map(|x| x as u64).collect()
238+
Ok(buffer.into_iter().map(|x| x as u64).collect())
206239
}
207240

241+
/// Converts a JObjectArray to a Vec<Vec<u8>>
208242
fn jobject_array_to_2d_byte_array(
209243
env: &mut JNIEnv,
210244
array: JObjectArray,
211-
) -> Result<Vec<Vec<u8>>, jni::errors::Error> {
245+
) -> Result<Vec<Vec<u8>>, Error> {
212246
// Get the length of the outer array
213247
let outer_len = env.get_array_length(&array)?;
214248

@@ -235,57 +269,63 @@ fn jobject_array_to_2d_byte_array(
235269
Ok(result)
236270
}
237271

272+
/// Converts a Vec<Vec<u8>> to a JObject that represents a CellsAndProofs object in Java
238273
fn cells_and_proofs_to_jobject<'local>(
239274
env: &mut JNIEnv<'local>,
240275
cells: &[impl AsRef<[u8]>],
241276
proofs: &[impl AsRef<[u8]>],
242-
) -> Result<JObject<'local>, jni::errors::Error> {
277+
) -> Result<JObject<'local>, Error> {
243278
// Create a new instance of the CellsAndProofs class in Java
244-
let cells_and_proofs_class = env
245-
.find_class("ethereum/cryptography/CellsAndProofs")
246-
.unwrap();
279+
let cells_and_proofs_class = env.find_class("ethereum/cryptography/CellsAndProofs")?;
247280

248-
let cell_byte_array_class = env.find_class("[B").unwrap();
249-
let proof_byte_array_class = env.find_class("[B").unwrap();
281+
let cell_byte_array_class = env.find_class("[B")?;
282+
let proof_byte_array_class = env.find_class("[B")?;
250283

251284
// Create 2D array for cells
252-
let cells_array = env
253-
.new_object_array(
254-
cells.len() as i32,
255-
cell_byte_array_class,
256-
env.new_byte_array(0).unwrap(),
257-
)
258-
.unwrap();
285+
let cells_array = env.new_object_array(
286+
cells.len() as i32,
287+
cell_byte_array_class,
288+
env.new_byte_array(0)?,
289+
)?;
259290

260291
for (i, cell) in cells.into_iter().enumerate() {
261-
let cell_array = env.byte_array_from_slice(cell.as_ref()).unwrap();
262-
env.set_object_array_element(&cells_array, i as i32, cell_array)
263-
.unwrap();
292+
let cell_array = env.byte_array_from_slice(cell.as_ref())?;
293+
env.set_object_array_element(&cells_array, i as i32, cell_array)?;
264294
}
265295

266296
// Create 2D array for proofs
267-
let proofs_array = env
268-
.new_object_array(
269-
proofs.len() as i32,
270-
proof_byte_array_class,
271-
env.new_byte_array(0).unwrap(),
272-
)
273-
.unwrap();
297+
let proofs_array = env.new_object_array(
298+
proofs.len() as i32,
299+
proof_byte_array_class,
300+
env.new_byte_array(0)?,
301+
)?;
274302

275303
for (i, proof) in proofs.into_iter().enumerate() {
276-
let proof_array = env.byte_array_from_slice(proof.as_ref()).unwrap();
277-
env.set_object_array_element(&proofs_array, i as i32, proof_array)
278-
.unwrap();
304+
let proof_array = env.byte_array_from_slice(proof.as_ref())?;
305+
env.set_object_array_element(&proofs_array, i as i32, proof_array)?;
279306
}
280307

281308
// Create the CellsAndProofs object
282-
let cells_and_proofs_obj = env
283-
.new_object(
284-
cells_and_proofs_class,
285-
"([[B[[B)V",
286-
&[JValue::Object(&cells_array), JValue::Object(&proofs_array)],
287-
)
288-
.unwrap();
309+
let cells_and_proofs_obj = env.new_object(
310+
cells_and_proofs_class,
311+
"([[B[[B)V",
312+
&[JValue::Object(&cells_array), JValue::Object(&proofs_array)],
313+
)?;
289314

290315
Ok(cells_and_proofs_obj)
291316
}
317+
318+
/// Throws an exception in Java
319+
fn throw_on_error(env: &mut JNIEnv, err: Error, func_name: &'static str) {
320+
let reason = match err {
321+
Error::Jni(err) => format!("{:?}", err),
322+
Error::ProverError(err) => format!("{:?}", err),
323+
Error::VerifierError(err) => format!("{:?}", err),
324+
};
325+
let msg = format!(
326+
"function {} has thrown an exception, with reason: {}",
327+
func_name, reason
328+
);
329+
env.throw_new("java/lang/IllegalArgumentException", msg)
330+
.expect("Failed to throw exception");
331+
}

0 commit comments

Comments
 (0)