Skip to content

Commit c7eb450

Browse files
committed
Fix Mina account FFI
1 parent 4fe4a2f commit c7eb450

File tree

6 files changed

+110
-120
lines changed

6 files changed

+110
-120
lines changed

operator/mina/lib/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn inner_verify_mina_state_ffi(
7070
let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) };
7171

7272
let pub_input_bytes =
73-
unsafe { std::slice::from_raw_parts(pub_input_bytes, proof_len as usize) };
73+
unsafe { std::slice::from_raw_parts(pub_input_bytes, pub_input_len as usize) };
7474

7575
verify_mina_state(proof_bytes, pub_input_bytes)
7676
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <stdbool.h>
2+
#include <stdint.h>
23

3-
bool verify_account_inclusion_ffi(unsigned char *proof_buffer,
4-
unsigned int proof_len,
5-
unsigned char *public_input_buffer,
6-
unsigned int public_input_len);
4+
int32_t verify_account_inclusion_ffi(unsigned char *proof_buffer,
5+
uint32_t proof_len,
6+
unsigned char *public_input_buffer,
7+
uint32_t public_input_len);

operator/mina_account/lib/src/lib.rs

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,25 @@ mod merkle_verifier;
1212
#[no_mangle]
1313
pub extern "C" fn verify_account_inclusion_ffi(
1414
proof_bytes: *const u8,
15-
proof_len: usize,
15+
proof_len: u32,
1616
pub_input_bytes: *const u8,
17-
pub_input_len: usize,
17+
pub_input_len: u32,
18+
) -> i32 {
19+
let result = std::panic::catch_unwind(|| {
20+
inner_verify_account_inclusion_ffi(proof_bytes, proof_len, pub_input_bytes, pub_input_len)
21+
});
22+
23+
match result {
24+
Ok(v) => v as i32,
25+
Err(_) => -1,
26+
}
27+
}
28+
29+
fn inner_verify_account_inclusion_ffi(
30+
proof_bytes: *const u8,
31+
proof_len: u32,
32+
pub_input_bytes: *const u8,
33+
pub_input_len: u32,
1834
) -> bool {
1935
if proof_bytes.is_null() || pub_input_bytes.is_null() {
2036
error!("Input buffer null");
@@ -29,7 +45,7 @@ pub extern "C" fn verify_account_inclusion_ffi(
2945
let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) };
3046

3147
let pub_input_bytes =
32-
unsafe { std::slice::from_raw_parts(pub_input_bytes, proof_len as usize) };
48+
unsafe { std::slice::from_raw_parts(pub_input_bytes, pub_input_len as usize) };
3349

3450
verify_account_inclusion(proof_bytes, pub_input_bytes)
3551
}
@@ -45,6 +61,7 @@ pub fn verify_account_inclusion(proof_bytes: &[u8], pub_input_bytes: &[u8]) -> b
4561
return false;
4662
}
4763
};
64+
error!("pub input len: {}", pub_input_bytes.len());
4865
let MinaAccountPubInputs {
4966
ledger_hash,
5067
encoded_account,
@@ -94,80 +111,50 @@ mod test {
94111

95112
#[test]
96113
fn valid_account_state_proof_verifies() {
97-
let result = verify_account_inclusion(PROOF_BYTES, PUB_INPUT_BYTES);
98-
assert!(result);
99-
}
100-
101-
#[test]
102-
fn empty_account_state_proof_does_not_verify() {
103-
let proof_buffer = [0u8; PROOF_BYTES.len()];
104-
let proof_size = PROOF_BYTES.len();
105-
106-
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
107-
let pub_input_size = PUB_INPUT_BYTES.len();
108-
assert!(pub_input_size <= pub_input_buffer.len());
109-
pub_input_buffer[..pub_input_size].clone_from_slice(PUB_INPUT_BYTES);
110-
111-
let result = verify_account_inclusion(&proof_buffer, &pub_input_buffer, pub_input_size);
112-
assert!(!result);
113-
}
114-
115-
#[test]
116-
fn valid_account_state_proof_with_empty_pub_input_does_not_verify() {
117114
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
118115
let proof_size = PROOF_BYTES.len();
119116
assert!(proof_size <= proof_buffer.len());
120117
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
121118

122-
let pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
119+
let mut pub_input_buffer = [0u8; PUB_INPUT_BYTES.len()];
123120
let pub_input_size = PUB_INPUT_BYTES.len();
121+
assert!(pub_input_size <= pub_input_buffer.len());
122+
pub_input_buffer[..pub_input_size].clone_from_slice(PUB_INPUT_BYTES);
124123

125124
let result = verify_account_inclusion_ffi(
126-
&proof_buffer,
127-
proof_size,
128-
&pub_input_buffer,
129-
pub_input_size,
125+
proof_buffer.as_ptr(),
126+
proof_size as u32,
127+
pub_input_buffer.as_ptr(),
128+
pub_input_size as u32,
130129
);
131-
assert!(!result);
130+
assert_eq!(result, 1);
132131
}
133132

134133
#[test]
135-
fn valid_account_state_proof_with_greater_proof_size_does_not_verify() {
136-
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
137-
let wrong_proof_size = MAX_PROOF_SIZE + 1;
138-
proof_buffer[..PROOF_BYTES.len()].clone_from_slice(PROOF_BYTES);
139-
140-
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
141-
let pub_input_size = PUB_INPUT_BYTES.len();
142-
assert!(pub_input_size <= pub_input_buffer.len());
143-
pub_input_buffer[..pub_input_size].clone_from_slice(PUB_INPUT_BYTES);
134+
fn empty_account_state_proof_does_not_verify() {
135+
const PROOF_SIZE: usize = PROOF_BYTES.len();
136+
let proof_buffer = [0u8; PROOF_SIZE];
144137

145138
let result = verify_account_inclusion_ffi(
146-
&proof_buffer,
147-
wrong_proof_size,
148-
&pub_input_buffer,
149-
pub_input_size,
139+
proof_buffer.as_ptr(),
140+
PROOF_SIZE as u32,
141+
PUB_INPUT_BYTES.as_ptr(),
142+
PUB_INPUT_BYTES.len() as u32,
150143
);
151-
assert!(!result);
144+
assert_eq!(result, 0);
152145
}
153146

154147
#[test]
155-
fn valid_account_state_proof_with_greater_pub_input_size_does_not_verify() {
156-
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
157-
let proof_size = PROOF_BYTES.len();
158-
assert!(proof_size <= proof_buffer.len());
159-
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
160-
161-
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
162-
let wrong_pub_input_size = MAX_PUB_INPUT_SIZE + 1;
163-
pub_input_buffer[..PUB_INPUT_BYTES.len()].clone_from_slice(PUB_INPUT_BYTES);
148+
fn valid_account_state_proof_with_empty_pub_input_does_not_verify() {
149+
const PUB_INPUT_SIZE: usize = PUB_INPUT_BYTES.len();
150+
let pub_input_buffer = [0u8; PUB_INPUT_SIZE];
164151

165152
let result = verify_account_inclusion_ffi(
166-
&proof_buffer,
167-
proof_size,
168-
&pub_input_buffer,
169-
wrong_pub_input_size,
153+
PROOF_BYTES.as_ptr(),
154+
PROOF_BYTES.len() as u32,
155+
pub_input_buffer.as_ptr(),
156+
PUB_INPUT_SIZE as u32,
170157
);
171-
assert!(!result);
158+
assert_eq!(result, 0);
172159
}
173160
}

operator/mina_account/mina_account.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,35 @@ package mina_account
99
import "C"
1010
import (
1111
"fmt"
12-
"time"
1312
"unsafe"
1413
)
1514

16-
func timer() func() {
17-
start := time.Now()
18-
return func() {
19-
fmt.Printf("Mina account verification took %v\n", time.Since(start))
15+
func VerifyAccountInclusion(proofBuffer []byte, pubInputBuffer []byte) (isVerified bool, err error) {
16+
// Here we define the return value on failure
17+
isVerified = false
18+
err = nil
19+
if len(proofBuffer) == 0 || len(pubInputBuffer) == 0 {
20+
return isVerified, err
2021
}
21-
}
2222

23-
func VerifyAccountInclusion(proofBuffer []byte, proofLen uint, pubInputBuffer []byte, pubInputLen uint) bool {
24-
defer timer()()
23+
// This will catch any go panic
24+
defer func() {
25+
rec := recover()
26+
if rec != nil {
27+
err = fmt.Errorf("Panic was caught while verifying sp1 proof: %s", rec)
28+
}
29+
}()
30+
2531
proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0]))
2632
pubInputPtr := (*C.uchar)(unsafe.Pointer(&pubInputBuffer[0]))
27-
return (bool)(C.verify_account_inclusion_ffi(proofPtr, (C.uint)(proofLen), pubInputPtr, (C.uint)(pubInputLen)))
33+
r := (C.int32_t)(C.verify_account_inclusion_ffi(proofPtr, (C.uint32_t)(len(proofBuffer)), pubInputPtr, (C.uint32_t)(len(pubInputBuffer))))
34+
35+
if r == -1 {
36+
err = fmt.Errorf("Panic happened on FFI while verifying Mina account proof")
37+
return isVerified, err
38+
}
39+
40+
isVerified = (r == 1)
41+
42+
return isVerified, err
2843
}
Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,71 @@
11
package mina_account_test
22

33
import (
4-
"fmt"
54
"os"
65
"testing"
76

87
"github.com/yetanotherco/aligned_layer/operator/mina_account"
98
)
109

10+
const ProofFilePath = "../../scripts/test_files/mina_account/mina_account.proof"
11+
12+
const PubInputFilePath = "../../scripts/test_files/mina_account/mina_account.pub"
13+
1114
func TestMinaStateProofVerifies(t *testing.T) {
12-
fmt.Println(os.Getwd())
13-
proofFile, err := os.Open("../../scripts/test_files/mina_account/mina_account.proof")
15+
proofBytes, err := os.ReadFile(ProofFilePath)
1416
if err != nil {
1517
t.Errorf("could not open mina account proof file")
1618
}
1719

18-
proofBuffer := make([]byte, mina_account.MAX_PROOF_SIZE)
19-
proofLen, err := proofFile.Read(proofBuffer)
20-
if err != nil {
21-
t.Errorf("could not read bytes from mina account proof file")
22-
}
23-
24-
pubInputFile, err := os.Open("../../scripts/test_files/mina_account/mina_account.pub")
25-
if err != nil {
26-
t.Errorf("could not open mina account pub inputs file")
27-
}
28-
pubInputBuffer := make([]byte, mina_account.MAX_PUB_INPUT_SIZE)
29-
pubInputLen, err := pubInputFile.Read(pubInputBuffer)
20+
pubInputBytes, err := os.ReadFile(PubInputFilePath)
3021
if err != nil {
31-
t.Errorf("could not read bytes from mina account pub inputs hash")
22+
t.Errorf("could not open mina account pub input file")
3223
}
3324

34-
if !mina_account.VerifyAccountInclusion(([mina_account.MAX_PROOF_SIZE]byte)(proofBuffer), uint(proofLen), ([mina_account.MAX_PUB_INPUT_SIZE]byte)(pubInputBuffer), uint(pubInputLen)) {
25+
verified, err := mina_account.VerifyAccountInclusion(proofBytes, pubInputBytes)
26+
if err != nil || !verified {
3527
t.Errorf("proof did not verify")
3628
}
3729
}
3830

3931
func TestEmptyMinaStateProofDoesNotVerify(t *testing.T) {
40-
fmt.Println(os.Getwd())
41-
proofBuffer := make([]byte, mina_account.MAX_PROOF_SIZE)
42-
43-
pubInputFile, err := os.Open("../../scripts/test_files/mina_account/mina_account.pub")
32+
proofBytes, err := os.ReadFile(ProofFilePath)
4433
if err != nil {
45-
t.Errorf("could not open mina account pub inputs file")
34+
t.Errorf("could not open mina state proof file")
4635
}
47-
pubInputBuffer := make([]byte, mina_account.MAX_PUB_INPUT_SIZE)
48-
pubInputLen, err := pubInputFile.Read(pubInputBuffer)
36+
emptyProofBuffer := make([]byte, len(proofBytes))
37+
38+
pubInputBytes, err := os.ReadFile(PubInputFilePath)
4939
if err != nil {
50-
t.Errorf("could not read bytes from mina account pub inputs hash")
40+
t.Errorf("could not open mina state pub input file")
5141
}
5242

53-
if mina_account.VerifyAccountInclusion(([mina_account.MAX_PROOF_SIZE]byte)(proofBuffer), mina_account.MAX_PROOF_SIZE, ([mina_account.MAX_PUB_INPUT_SIZE]byte)(pubInputBuffer), uint(pubInputLen)) {
54-
t.Errorf("Empty proof should not verify but it did")
43+
verified, err := mina_account.VerifyAccountInclusion(emptyProofBuffer, pubInputBytes)
44+
if err != nil {
45+
t.Errorf("verification failed with error")
46+
}
47+
if verified {
48+
t.Errorf("proof should not verify")
5549
}
5650
}
5751

5852
func TestMinaStateProofWithEmptyPubInputDoesNotVerify(t *testing.T) {
59-
fmt.Println(os.Getwd())
60-
proofFile, err := os.Open("../../scripts/test_files/mina_account/mina_account.proof")
53+
proofBytes, err := os.ReadFile(ProofFilePath)
6154
if err != nil {
62-
t.Errorf("could not open mina account proof file")
55+
t.Errorf("could not open mina state proof file")
6356
}
6457

65-
proofBuffer := make([]byte, mina_account.MAX_PROOF_SIZE)
66-
proofLen, err := proofFile.Read(proofBuffer)
58+
pubInputBytes, err := os.ReadFile(PubInputFilePath)
6759
if err != nil {
68-
t.Errorf("could not read bytes from mina account proof file")
60+
t.Errorf("could not open mina state pub input file")
6961
}
62+
emptyPubInputBuffer := make([]byte, len(pubInputBytes))
7063

71-
pubInputBuffer := make([]byte, mina_account.MAX_PUB_INPUT_SIZE)
72-
73-
if mina_account.VerifyAccountInclusion(([mina_account.MAX_PROOF_SIZE]byte)(proofBuffer), uint(proofLen), ([mina_account.MAX_PUB_INPUT_SIZE]byte)(pubInputBuffer), mina_account.MAX_PUB_INPUT_SIZE) {
74-
t.Errorf("proof with empty public input should not verify but id did")
64+
verified, err := mina_account.VerifyAccountInclusion(proofBytes, emptyPubInputBuffer)
65+
if err != nil {
66+
t.Errorf("verification failed with error")
67+
}
68+
if verified {
69+
t.Errorf("proof should not verify")
7570
}
7671
}

operator/pkg/operator.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -531,21 +531,13 @@ func (o *Operator) verify(verificationData VerificationData, disabledVerifiersBi
531531
o.handleVerificationResult(results, verificationResult, err, "Risc0 proof verification")
532532
results <- verificationResult
533533
case common.Mina:
534-
proofLen := (uint)(len(verificationData.Proof))
535-
pubInputLen := (uint)(len(verificationData.PubInput))
536-
537-
verificationResult := mina.VerifyMinaState(verificationData.Proof, proofLen, verificationData.PubInput, (uint)(pubInputLen))
534+
verificationResult, err := mina.VerifyMinaState(verificationData.Proof, verificationData.PubInput)
538535
o.Logger.Infof("Mina state proof verification result: %t", verificationResult)
539-
// TODO: Remove the nil value passed as err argument
540-
o.handleVerificationResult(results, verificationResult, nil, "Mina state proof verification")
536+
o.handleVerificationResult(results, verificationResult, err, "Mina state proof verification")
541537
case common.MinaAccount:
542-
proofLen := (uint)(len(verificationData.Proof))
543-
pubInputLen := (uint)(len(verificationData.PubInput))
544-
545-
verificationResult := mina_account.VerifyAccountInclusion(verificationData.Proof, proofLen, verificationData.PubInput, (uint)(pubInputLen))
538+
verificationResult, err := mina_account.VerifyAccountInclusion(verificationData.Proof, verificationData.PubInput)
546539
o.Logger.Infof("Mina account inclusion proof verification result: %t", verificationResult)
547-
// TODO: Remove the nil value passed as err argument
548-
o.handleVerificationResult(results, verificationResult, nil, "Mina account state proof verification")
540+
o.handleVerificationResult(results, verificationResult, err, "Mina account state proof verification")
549541
default:
550542
o.Logger.Error("Unrecognized proving system ID")
551543
results <- false

0 commit comments

Comments
 (0)