@@ -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,9 +20,8 @@ use super::{
1820use crate :: {
1921 config:: Config ,
2022 db:: Db ,
21- server:: types:: {
22- SubmitProofRequest , SubmitProofRequestMessageRisc0 , SubmitProofRequestMessageSP1 ,
23- } ,
23+ server:: types:: { SubmitProofRequestRisc0 , SubmitProofRequestSP1 } ,
24+ verifiers:: { verify_sp1_proof, VerificationError } ,
2425} ;
2526
2627#[ derive( Clone , Debug ) ]
@@ -62,7 +63,6 @@ impl BatcherServer {
6263 } ;
6364
6465 // TODO: validate valid ethereum address
65-
6666 let Some ( state) = req. app_data :: < Data < BatcherServer > > ( ) else {
6767 return HttpResponse :: InternalServerError ( )
6868 . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
@@ -82,11 +82,8 @@ impl BatcherServer {
8282
8383 async fn post_proof_sp1 (
8484 req : HttpRequest ,
85- body : web :: Json < SubmitProofRequest < SubmitProofRequestMessageSP1 > > ,
85+ MultipartForm ( data ) : MultipartForm < SubmitProofRequestSP1 > ,
8686 ) -> impl Responder {
87- let data = body. into_inner ( ) ;
88-
89- // TODO: validate signature
9087 let recovered_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" . to_lowercase ( ) ;
9188
9289 let Some ( state) = req. app_data :: < Data < BatcherServer > > ( ) else {
@@ -100,7 +97,7 @@ impl BatcherServer {
10097 . json ( AppResponse :: new_unsucessfull ( "Internal server error" , 500 ) ) ;
10198 } ;
10299
103- if data. nonce != ( count as u64 ) {
100+ if data. nonce . 0 != ( count as u64 ) {
104101 return HttpResponse :: BadRequest ( ) . json ( AppResponse :: new_unsucessfull (
105102 & format ! ( "Invalid nonce, expected nonce = {count}" ) ,
106103 400 ,
@@ -138,15 +135,42 @@ impl BatcherServer {
138135 ) ) ;
139136 }
140137
141- // 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+ } ;
142166
143167 match state
144168 . db
145169 . insert_task (
146170 & recovered_address,
147171 AggregationModeProvingSystem :: SP1 . as_u16 ( ) as i32 ,
148- & data . message . proof ,
149- & data . message . program_vk_commitment ,
172+ & proof_content ,
173+ & vk_content ,
150174 None ,
151175 )
152176 . await
@@ -162,7 +186,7 @@ impl BatcherServer {
162186 /// TODO: complete for risc0 (see `post_proof_sp1`)
163187 async fn post_proof_risc0 (
164188 _req : HttpRequest ,
165- _body : web :: Json < SubmitProofRequest < SubmitProofRequestMessageRisc0 > > ,
189+ MultipartForm ( _ ) : MultipartForm < SubmitProofRequestRisc0 > ,
166190 ) -> impl Responder {
167191 HttpResponse :: Ok ( ) . json ( AppResponse :: new_sucessfull ( serde_json:: json!( { } ) ) )
168192 }
0 commit comments