Skip to content

Commit e825166

Browse files
feat(aggregation-mode): add endpoint for submitted proofs count and time left
1 parent b6e50e4 commit e825166

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

aggregation_mode/batcher/src/server/helpers.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::time::{SystemTime, UNIX_EPOCH};
2+
13
pub(super) fn format_merkle_path(bytes: &[u8]) -> Result<Vec<String>, String> {
24
if bytes.is_empty() {
35
return Ok(vec![]);
@@ -12,3 +14,17 @@ pub(super) fn format_merkle_path(bytes: &[u8]) -> Result<Vec<String>, String> {
1214
.map(|chunk| format!("0x{}", hex::encode(chunk)))
1315
.collect())
1416
}
17+
18+
pub(crate) fn get_time_left_day_formatted() -> String {
19+
let now = SystemTime::now()
20+
.duration_since(UNIX_EPOCH)
21+
.expect("Error al obtener el tiempo");
22+
23+
let seconds_remaining = 86400 - (now.as_secs() % 86400);
24+
25+
let hours = seconds_remaining / 3600;
26+
let minutes = (seconds_remaining % 3600) / 60;
27+
let seconds = seconds_remaining % 60;
28+
29+
format!("{hours}:{minutes}:{seconds}")
30+
}

aggregation_mode/batcher/src/server/http.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ use super::{
2020
use crate::{
2121
config::Config,
2222
db::Db,
23-
server::types::{GetReceiptsResponse, SubmitProofRequestRisc0, SubmitProofRequestSP1},
23+
server::{
24+
helpers::get_time_left_day_formatted,
25+
types::{GetReceiptsResponse, SubmitProofRequestRisc0, SubmitProofRequestSP1},
26+
},
2427
verifiers::{verify_sp1_proof, VerificationError},
2528
};
2629

@@ -48,6 +51,7 @@ impl BatcherServer {
4851
.route("/receipts", web::get().to(Self::get_receipts))
4952
.route("/proof/sp1", web::post().to(Self::post_proof_sp1))
5053
.route("/proof/risc0", web::post().to(Self::post_proof_risc0))
54+
.route("/quotas/{address}", web::get().to(Self::get_quotas))
5155
})
5256
.bind(("127.0.0.1", port))
5357
.expect("To bind socket correctly")
@@ -298,4 +302,41 @@ impl BatcherServer {
298302
.json(AppResponse::new_unsucessfull("Internal server error", 500)),
299303
}
300304
}
305+
306+
async fn get_quotas(req: HttpRequest) -> impl Responder {
307+
let Some(state) = req.app_data::<Data<BatcherServer>>() else {
308+
return HttpResponse::InternalServerError().json(AppResponse::new_unsucessfull(
309+
"Internal server error: Failed to get app data",
310+
500,
311+
));
312+
};
313+
314+
let state = state.get_ref();
315+
316+
let Some(address_raw) = req.match_info().get("address") else {
317+
return HttpResponse::BadRequest()
318+
.json(AppResponse::new_unsucessfull("Missing address", 400));
319+
};
320+
321+
// Check that the address is a valid ethereum address
322+
if alloy::primitives::Address::from_str(address_raw.trim()).is_err() {
323+
return HttpResponse::BadRequest()
324+
.json(AppResponse::new_unsucessfull("Invalid address", 400));
325+
}
326+
327+
let address = address_raw.to_lowercase();
328+
329+
let Ok(daily_tasks_by_address) = state.db.get_daily_tasks_by_address(&address).await else {
330+
return HttpResponse::InternalServerError()
331+
.json(AppResponse::new_unsucessfull("Internal server error", 500));
332+
};
333+
334+
let formatted_time_left = get_time_left_day_formatted();
335+
336+
HttpResponse::Ok().json(AppResponse::new_sucessfull(serde_json::json!({
337+
"amount-submitted": daily_tasks_by_address,
338+
"amount-left": (state.config.max_daily_proofs_per_user - daily_tasks_by_address),
339+
"time-left": formatted_time_left.as_str()
340+
})))
341+
}
301342
}

0 commit comments

Comments
 (0)