@@ -3,11 +3,13 @@ use std::{
33 time:: { SystemTime , UNIX_EPOCH } ,
44} ;
55
6+ use actix_multipart:: form:: MultipartForm ;
67use actix_web:: {
78 web:: { self , Data } ,
89 App , HttpRequest , HttpResponse , HttpServer , Responder ,
910} ;
1011use aligned_sdk:: aggregation_layer:: AggregationModeProvingSystem ;
12+ use sp1_sdk:: { SP1ProofWithPublicValues , SP1VerifyingKey } ;
1113use sqlx:: types:: BigDecimal ;
1214
1315use super :: {
@@ -18,7 +20,8 @@ use super::{
1820use crate :: {
1921 config:: Config ,
2022 db:: Db ,
21- types:: { SubmitProofRequest , SubmitProofRequestMessageRisc0 , SubmitProofRequestMessageSP1 } ,
23+ types:: { SubmitProofRequestRisc0 , SubmitProofRequestSP1 } ,
24+ verifiers:: { verify_sp1_proof, VerificationError } ,
2225} ;
2326
2427#[ derive( Clone , Debug ) ]
@@ -60,7 +63,6 @@ impl BatcherServer {
6063 } ;
6164
6265 // TODO: validate valid ethereum address
63-
6466 let Some ( state) = req. app_data :: < Data < BatcherServer > > ( ) else {
6567 return HttpResponse :: InternalServerError ( )
6668 . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
@@ -80,11 +82,8 @@ impl BatcherServer {
8082
8183 async fn post_proof_sp1 (
8284 req : HttpRequest ,
83- body : web :: Json < SubmitProofRequest < SubmitProofRequestMessageSP1 > > ,
85+ MultipartForm ( data ) : MultipartForm < SubmitProofRequestSP1 > ,
8486 ) -> impl Responder {
85- let data = body. into_inner ( ) ;
86-
87- // TODO: validate signature
8887 let recovered_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" . to_lowercase ( ) ;
8988
9089 let Some ( state) = req. app_data :: < Data < BatcherServer > > ( ) else {
@@ -98,7 +97,7 @@ impl BatcherServer {
9897 . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
9998 } ;
10099
101- if data. nonce != ( count as u64 ) {
100+ if data. nonce . 0 != ( count as u64 ) {
102101 return HttpResponse :: BadRequest ( ) . json ( AppResponse :: new_unsucessfull (
103102 & format ! ( "Invalid nonce, expected nonce = {count}" ) ,
104103 400 ,
@@ -136,15 +135,42 @@ impl BatcherServer {
136135 ) ) ;
137136 }
138137
139- // TODO: decode proof and validate it
138+ let Ok ( proof_content) = tokio:: fs:: read ( data. proof . file . path ( ) ) . await else {
139+ return HttpResponse :: InternalServerError ( )
140+ . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
141+ } ;
142+
143+ let Ok ( proof) = bincode:: deserialize :: < SP1ProofWithPublicValues > ( & proof_content) else {
144+ return HttpResponse :: BadRequest ( )
145+ . json ( AppResponse :: new_unsucessfull ( "Invalid SP1 proof" , 400 ) ) ;
146+ } ;
147+
148+ let Ok ( vk_content) = tokio:: fs:: read ( data. program_vk . file . path ( ) ) . await else {
149+ return HttpResponse :: InternalServerError ( )
150+ . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
151+ } ;
152+
153+ let Ok ( vk) = bincode:: deserialize :: < SP1VerifyingKey > ( & vk_content) else {
154+ return HttpResponse :: BadRequest ( )
155+ . json ( AppResponse :: new_unsucessfull ( "Invalid vk" , 400 ) ) ;
156+ } ;
157+
158+ if let Err ( e) = verify_sp1_proof ( & proof, & vk) {
159+ let message = match e {
160+ VerificationError :: InvalidProof => "Proof verification failed" ,
161+ VerificationError :: UnsupportedProof => "Unsupported proof" ,
162+ } ;
163+
164+ return HttpResponse :: BadRequest ( ) . json ( AppResponse :: new_unsucessfull ( message, 400 ) ) ;
165+ } ;
140166
141167 match state
142168 . db
143169 . insert_task (
144170 & recovered_address,
145171 AggregationModeProvingSystem :: SP1 . as_u16 ( ) as i32 ,
146- & data . message . proof ,
147- & data . message . program_vk_commitment ,
172+ & proof_content ,
173+ & vk_content ,
148174 None ,
149175 )
150176 . await
@@ -160,7 +186,7 @@ impl BatcherServer {
160186 /// TODO: complete for risc0 (see `post_proof_sp1`)
161187 async fn post_proof_risc0 (
162188 _req : HttpRequest ,
163- _body : web :: Json < SubmitProofRequest < SubmitProofRequestMessageRisc0 > > ,
189+ MultipartForm ( _ ) : MultipartForm < SubmitProofRequestRisc0 > ,
164190 ) -> impl Responder {
165191 HttpResponse :: Ok ( ) . json ( AppResponse :: new_sucessfull ( serde_json:: json!( { } ) ) )
166192 }
0 commit comments