Skip to content

Commit

Permalink
Add merkle tree batch verification panic catch
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Ventura committed Oct 8, 2024
1 parent d0881ae commit 5dff8f7
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 11 deletions.
3 changes: 2 additions & 1 deletion operator/merkle_tree/lib/merkle_tree.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdbool.h>
#include <stdint.h>

bool verify_merkle_tree_batch_ffi(unsigned char *batch_bytes, unsigned int batch_len, unsigned char *merkle_root);
int32_t verify_merkle_tree_batch_ffi(unsigned char *batch_bytes, unsigned int batch_len, unsigned char *merkle_root);
24 changes: 20 additions & 4 deletions operator/merkle_tree/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use lambdaworks_crypto::merkle_tree::merkle::MerkleTree;
use log::error;

#[no_mangle]
pub extern "C" fn verify_merkle_tree_batch_ffi(
pub extern "C" fn inner_verify_merkle_tree_batch_ffi(
batch_ptr: *const u8,
batch_len: usize,
merkle_root: &[u8; 32],
Expand Down Expand Up @@ -53,6 +53,22 @@ pub extern "C" fn verify_merkle_tree_batch_ffi(
computed_batch_merkle_tree.root == *merkle_root
}

#[no_mangle]
pub extern "C" fn verify_merkle_tree_batch_ffi(
batch_ptr: *const u8,
batch_len: usize,
merkle_root: &[u8; 32],
) -> i32 {
let result = std::panic::catch_unwind(|| {
inner_verify_merkle_tree_batch_ffi(batch_ptr, batch_len, merkle_root)
});

match result {
Ok(v) => v as i32,
Err(_) => -1,
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -75,7 +91,7 @@ mod tests {
let result =
verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root);

assert_eq!(result, true);
assert_eq!(result, 1);
}

#[test]
Expand All @@ -92,7 +108,7 @@ mod tests {
let result =
verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root);

assert_eq!(result, false);
assert_eq!(result, 0);
}

#[test]
Expand All @@ -109,6 +125,6 @@ mod tests {
let result =
verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root);

assert_eq!(result, false);
assert_eq!(result, 0);
}
}
28 changes: 25 additions & 3 deletions operator/merkle_tree/merkle_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,35 @@ package merkle_tree
*/
import "C"
import "unsafe"
import "fmt"

func VerifyMerkleTreeBatch(batchBuffer []byte, merkleRootBuffer [32]byte) bool {
func VerifyMerkleTreeBatch(batchBuffer []byte, merkleRootBuffer [32]byte) (isVerified bool, err error) {
// Here we define the return value on failure
isVerified = false
err = nil
if len(batchBuffer) == 0 {
return false
return isVerified, err
}

// This will catch any go panic
defer func() {
rec := recover()
if rec != nil {
err = fmt.Errorf("Panic was caught while verifying merkle tree batch: %s", rec)
}
}()

batchPtr := (*C.uchar)(unsafe.Pointer(&batchBuffer[0]))
merkleRootPtr := (*C.uchar)(unsafe.Pointer(&merkleRootBuffer[0]))
return (bool)(C.verify_merkle_tree_batch_ffi(batchPtr, (C.uint)(len(batchBuffer)), merkleRootPtr))

r := (C.int32_t)(C.verify_merkle_tree_batch_ffi(batchPtr, (C.uint)(len(batchBuffer)), merkleRootPtr))

if r == -1 {
err = fmt.Errorf("Panic happened on FFI while verifying merkle tree batch")
return isVerified, err
}

isVerified = (r == 1)

return isVerified, err
}
3 changes: 2 additions & 1 deletion operator/merkle_tree/merkle_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ func TestVerifyMerkleTreeBatch(t *testing.T) {
var merkleRoot [32]byte
copy(merkleRoot[:], merkle_root)

if !VerifyMerkleTreeBatch(batchByteValue, merkleRoot) {
verified, err := VerifyMerkleTreeBatch(batchByteValue, merkleRoot)
if err != nil || !verified {
t.Errorf("Batch did not verify Merkle Root")
}

Expand Down
7 changes: 5 additions & 2 deletions operator/pkg/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ func (o *Operator) getBatchFromDataService(ctx context.Context, batchURL string,

// Checks if downloaded merkle root is the same as the expected one
o.Logger.Infof("Verifying batch merkle tree...")
merkle_root_check := merkle_tree.VerifyMerkleTreeBatch(batchBytes, expectedMerkleRoot)
if !merkle_root_check {
merkle_root_check, err := merkle_tree.VerifyMerkleTreeBatch(batchBytes, expectedMerkleRoot)
if err != nil {
o.Logger.Errorf("Error while verifying merkle tree batch")
}
if err != nil || !merkle_root_check {
// try old merkle tree
o.Logger.Infof("Batch merkle tree verification failed. Trying old merkle tree...")
merkle_root_check = merkle_tree_old.VerifyMerkleTreeBatchOld(batchBytes, expectedMerkleRoot)
Expand Down

0 comments on commit 5dff8f7

Please sign in to comment.