Skip to content

Commit c987d70

Browse files
committed
feat: post sp1 proof ep
1 parent fcb5426 commit c987d70

File tree

4 files changed

+128
-23
lines changed

4 files changed

+128
-23
lines changed

aggregation_mode/batcher/src/db.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,51 @@ impl Db {
4343
.await
4444
.map(|res| res.flatten())
4545
}
46+
47+
pub async fn insert_proof(
48+
&self,
49+
address: &str,
50+
proving_system_id: i32,
51+
proof: &[u8],
52+
program_commitment: &[u8],
53+
merkle_path: Option<&[u8]>,
54+
task_id: Option<Uuid>,
55+
) -> Result<Uuid, sqlx::Error> {
56+
sqlx::query_scalar::<_, Uuid>(
57+
"INSERT INTO proofs (
58+
address,
59+
proving_system_id,
60+
proof,
61+
program_commitment,
62+
merkle_path,
63+
task_id
64+
) VALUES ($1, $2, $3, $4, $5, $6)
65+
RETURNING proof_id",
66+
)
67+
.bind(address)
68+
.bind(proving_system_id)
69+
.bind(proof)
70+
.bind(program_commitment)
71+
.bind(merkle_path)
72+
.bind(task_id)
73+
.fetch_one(&self.pool)
74+
.await
75+
}
76+
77+
pub async fn has_active_payment_event(
78+
&self,
79+
address: &str,
80+
now_ts: i64,
81+
) -> Result<bool, sqlx::Error> {
82+
sqlx::query_scalar::<_, bool>(
83+
"SELECT EXISTS(
84+
SELECT 1 FROM payment_events
85+
WHERE address = $1 AND started_at < $2 AND $2 < valid_until
86+
)",
87+
)
88+
.bind(address)
89+
.bind(now_ts)
90+
.fetch_one(&self.pool)
91+
.await
92+
}
4693
}

aggregation_mode/batcher/src/server/http.rs

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
use std::time::{SystemTime, UNIX_EPOCH};
2+
13
use actix_web::{
4+
http::StatusCode,
25
web::{self, Data},
36
App, HttpRequest, HttpResponse, HttpServer, Responder,
47
};
@@ -9,7 +12,13 @@ use super::{
912
types::{AppResponse, ProofMerkleQuery},
1013
};
1114

12-
use crate::{config::Config, db::Db, server::types::SubmitProofRequest};
15+
use crate::{
16+
config::Config,
17+
db::Db,
18+
server::types::{
19+
SubmitProofRequest, SubmitProofRequestMessageRisc0, SubmitProofRequestMessageSP1,
20+
},
21+
};
1322

1423
#[derive(Clone, Debug)]
1524
pub struct BatcherServer {
@@ -60,23 +69,20 @@ impl BatcherServer {
6069
"nonce": count
6170
}
6271
))),
63-
Err(err) => {
64-
tracing::error!(error = ?err, "failed to count proofs");
65-
HttpResponse::InternalServerError()
66-
.json(AppResponse::new_unsucessfull("Internal server error", 500))
67-
}
72+
Err(_) => HttpResponse::InternalServerError()
73+
.json(AppResponse::new_unsucessfull("Internal server error", 500)),
6874
}
6975
}
7076

7177
// TODO: receive the proof and 1. decode it, 2. verify it, 3. add to the db
7278
async fn post_proof_sp1(
7379
req: HttpRequest,
74-
body: web::Json<SubmitProofRequest>,
80+
body: web::Json<SubmitProofRequest<SubmitProofRequestMessageSP1>>,
7581
) -> impl Responder {
7682
let data = body.into_inner();
7783

7884
// TODO: validate signature
79-
let recovered_address = "";
85+
let recovered_address = "0x0000000000000000000000000000000000000000";
8086

8187
let Some(state) = req.app_data::<Data<BatcherServer>>() else {
8288
return HttpResponse::InternalServerError()
@@ -85,16 +91,68 @@ impl BatcherServer {
8591
let state = state.get_ref();
8692

8793
let Ok(count) = state.db.count_proofs_by_address(recovered_address).await else {
88-
return HttpResponse::InternalServerError().finish();
94+
return HttpResponse::InternalServerError()
95+
.json(AppResponse::new_unsucessfull("Internal server error", 500));
8996
};
9097

91-
HttpResponse::Ok().json(AppResponse::new_sucessfull(serde_json::json!({})))
98+
if data.nonce != (count as u64) {
99+
return HttpResponse::BadRequest().json(AppResponse::new_unsucessfull(
100+
&format!("Invalid nonce, expected nonce = {count}"),
101+
400,
102+
));
103+
}
104+
105+
let now_ts = match SystemTime::now().duration_since(UNIX_EPOCH) {
106+
Ok(duration) => duration.as_secs() as i64,
107+
Err(_) => {
108+
return HttpResponse::InternalServerError()
109+
.json(AppResponse::new_unsucessfull("Internal server error", 500));
110+
}
111+
};
112+
113+
let has_payment = match state
114+
.db
115+
.has_active_payment_event(recovered_address, now_ts)
116+
.await
117+
{
118+
Ok(result) => result,
119+
Err(_) => {
120+
return HttpResponse::InternalServerError()
121+
.json(AppResponse::new_unsucessfull("Internal server error", 500));
122+
}
123+
};
124+
125+
if !has_payment {
126+
return HttpResponse::BadRequest().json(AppResponse::new_unsucessfull(
127+
"You have to pay before submitting a proof",
128+
400,
129+
));
130+
}
131+
132+
match state
133+
.db
134+
.insert_proof(
135+
recovered_address,
136+
AggregationModeProvingSystem::SP1.as_u16() as i32,
137+
&data.message.proof,
138+
&data.message.program_vk_commitment,
139+
None,
140+
None,
141+
)
142+
.await
143+
{
144+
Ok(proof_id) => HttpResponse::Ok().json(AppResponse::new_sucessfull(
145+
serde_json::json!({ "proof_id": proof_id.to_string() }),
146+
)),
147+
Err(_) => HttpResponse::InternalServerError()
148+
.json(AppResponse::new_unsucessfull("Internal server error", 500)),
149+
}
92150
}
93151

94152
/// TODO: complete for risc0 (see `post_proof_sp1`)
95153
async fn post_proof_risc0(
96154
_req: HttpRequest,
97-
_body: web::Json<SubmitProofRequest>,
155+
_body: web::Json<SubmitProofRequest<SubmitProofRequestMessageRisc0>>,
98156
) -> impl Responder {
99157
HttpResponse::Ok().json(AppResponse::new_sucessfull(serde_json::json!({})))
100158
}

aggregation_mode/batcher/src/server/types.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,26 @@ impl AppResponse {
2727
}
2828
}
2929

30-
// TODO: move this to the sdk once ready
31-
3230
#[derive(Deserialize, Clone)]
3331
pub(super) struct ProofMerkleQuery {
3432
pub id: Option<String>,
3533
}
3634

3735
#[derive(Serialize, Deserialize, Clone, Debug)]
38-
pub(super) struct SubmitProofRequest {
39-
pub message: SubmitProofRequestMessage,
36+
pub(super) struct SubmitProofRequest<T> {
37+
pub nonce: u64,
38+
pub message: T,
4039
pub signature: String,
4140
}
41+
#[derive(Serialize, Deserialize, Clone, Debug)]
42+
pub(super) struct SubmitProofRequestMessageSP1 {
43+
pub proof: Vec<u8>,
44+
pub program_vk_commitment: Vec<u8>,
45+
}
4246

4347
#[derive(Serialize, Deserialize, Clone, Debug)]
44-
pub(super) struct SubmitProofRequestMessage {
45-
pub nonce: u64,
46-
pub proving_system_id: AggregationModeProvingSystem,
48+
pub(super) struct SubmitProofRequestMessageRisc0 {
4749
pub proof: Vec<u8>,
48-
pub public_inputs: Option<Vec<u8>>,
49-
pub program_id: Vec<u8>,
50+
pub program_image_id: Vec<u8>,
51+
pub public_inputs: Vec<u8>,
5052
}

aggregation_mode/db/migrations/001_init.sql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@ CREATE TABLE proofs (
99
proof_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
1010
address CHAR(42),
1111
proving_system_id INT,
12-
vm_program_code BYTEA,
1312
proof BYTEA,
14-
public_inputs BYTEA,
15-
proof_commitment BYTEA,
13+
program_commitment BYTEA,
1614
merkle_path BYTEA,
1715
task_id UUID REFERENCES tasks(task_id)
1816
);

0 commit comments

Comments
 (0)