-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core,host): initial aggregation API
- Loading branch information
1 parent
8e86975
commit 83d538b
Showing
7 changed files
with
498 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ use crate::{ | |
ProverState, | ||
}; | ||
|
||
mod proof; | ||
pub mod proof; | ||
|
||
#[derive(OpenApi)] | ||
#[openapi( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
use axum::{response::IntoResponse, Json, Router}; | ||
use raiko_lib::prover::Proof; | ||
use raiko_tasks::TaskStatus; | ||
use serde::{Deserialize, Serialize}; | ||
use utoipa::{OpenApi, ToSchema}; | ||
use utoipa_scalar::{Scalar, Servable}; | ||
use utoipa_swagger_ui::SwaggerUi; | ||
|
||
use crate::{ | ||
server::api::v1::{self, GuestOutputDoc}, | ||
ProverState, | ||
}; | ||
|
||
mod proof; | ||
|
||
#[derive(OpenApi)] | ||
#[openapi( | ||
info( | ||
title = "Raiko Proverd Server API", | ||
version = "3.0", | ||
description = "Raiko Proverd Server API", | ||
contact( | ||
name = "API Support", | ||
url = "https://community.taiko.xyz", | ||
email = "[email protected]", | ||
), | ||
license( | ||
name = "MIT", | ||
url = "https://github.com/taikoxyz/raiko/blob/main/LICENSE" | ||
), | ||
), | ||
components( | ||
schemas( | ||
raiko_core::interfaces::ProofRequestOpt, | ||
raiko_core::interfaces::ProverSpecificOpts, | ||
crate::interfaces::HostError, | ||
GuestOutputDoc, | ||
ProofResponse, | ||
TaskStatus, | ||
CancelStatus, | ||
PruneStatus, | ||
Proof, | ||
Status, | ||
) | ||
), | ||
tags( | ||
(name = "Proving", description = "Routes that handle proving requests"), | ||
(name = "Health", description = "Routes that report the server health status"), | ||
(name = "Metrics", description = "Routes that give detailed insight into the server") | ||
) | ||
)] | ||
/// The root API struct which is generated from the `OpenApi` derive macro. | ||
pub struct Docs; | ||
|
||
#[derive(Debug, Deserialize, Serialize, ToSchema)] | ||
#[serde(untagged)] | ||
pub enum ProofResponse { | ||
Status { | ||
/// The status of the submitted task. | ||
status: TaskStatus, | ||
}, | ||
Proof { | ||
/// The proof. | ||
proof: Proof, | ||
}, | ||
} | ||
|
||
#[derive(Debug, Deserialize, Serialize, ToSchema)] | ||
#[serde(tag = "status", rename_all = "lowercase")] | ||
pub enum Status { | ||
Ok { data: ProofResponse }, | ||
Error { error: String, message: String }, | ||
} | ||
|
||
impl From<Vec<u8>> for Status { | ||
fn from(proof: Vec<u8>) -> Self { | ||
Self::Ok { | ||
data: ProofResponse::Proof { | ||
proof: serde_json::from_slice(&proof).unwrap_or_default(), | ||
}, | ||
} | ||
} | ||
} | ||
|
||
impl From<Proof> for Status { | ||
fn from(proof: Proof) -> Self { | ||
Self::Ok { | ||
data: ProofResponse::Proof { proof }, | ||
} | ||
} | ||
} | ||
|
||
impl From<TaskStatus> for Status { | ||
fn from(status: TaskStatus) -> Self { | ||
Self::Ok { | ||
data: ProofResponse::Status { status }, | ||
} | ||
} | ||
} | ||
|
||
impl IntoResponse for Status { | ||
fn into_response(self) -> axum::response::Response { | ||
Json(serde_json::to_value(self).unwrap()).into_response() | ||
} | ||
} | ||
|
||
#[derive(Debug, Deserialize, Serialize, ToSchema)] | ||
#[serde(tag = "status", rename_all = "lowercase")] | ||
/// Status of cancellation request. | ||
/// Can be `ok` for a successful cancellation or `error` with message and error type for errors. | ||
pub enum CancelStatus { | ||
/// Cancellation was successful. | ||
Ok, | ||
/// Cancellation failed. | ||
Error { error: String, message: String }, | ||
} | ||
|
||
impl IntoResponse for CancelStatus { | ||
fn into_response(self) -> axum::response::Response { | ||
Json(serde_json::to_value(self).unwrap()).into_response() | ||
} | ||
} | ||
|
||
#[derive(Debug, Serialize, ToSchema, Deserialize)] | ||
#[serde(tag = "status", rename_all = "lowercase")] | ||
/// Status of prune request. | ||
/// Can be `ok` for a successful prune or `error` with message and error type for errors. | ||
pub enum PruneStatus { | ||
/// Prune was successful. | ||
Ok, | ||
/// Prune failed. | ||
Error { error: String, message: String }, | ||
} | ||
|
||
impl IntoResponse for PruneStatus { | ||
fn into_response(self) -> axum::response::Response { | ||
Json(serde_json::to_value(self).unwrap()).into_response() | ||
} | ||
} | ||
|
||
#[must_use] | ||
pub fn create_docs() -> utoipa::openapi::OpenApi { | ||
[ | ||
v1::health::create_docs(), | ||
v1::metrics::create_docs(), | ||
proof::create_docs(), | ||
] | ||
.into_iter() | ||
.fold(Docs::openapi(), |mut doc, sub_doc| { | ||
doc.merge(sub_doc); | ||
doc | ||
}) | ||
} | ||
|
||
pub fn create_router() -> Router<ProverState> { | ||
let docs = create_docs(); | ||
|
||
Router::new() | ||
// Only add the concurrency limit to the proof route. We want to still be able to call | ||
// healthchecks and metrics to have insight into the system. | ||
.nest("/proof", proof::create_router()) | ||
.nest("/health", v1::health::create_router()) | ||
.nest("/metrics", v1::metrics::create_router()) | ||
.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", docs.clone())) | ||
.merge(Scalar::with_url("/scalar", docs)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use axum::{debug_handler, extract::State, routing::post, Json, Router}; | ||
use raiko_core::{ | ||
interfaces::{AggregationRequest, ProofRequest, ProofRequestOpt}, | ||
provider::get_task_data, | ||
}; | ||
use raiko_tasks::{TaskDescriptor, TaskManager, TaskStatus}; | ||
use serde_json::Value; | ||
use utoipa::OpenApi; | ||
|
||
use crate::{interfaces::HostResult, server::api::v2::CancelStatus, Message, ProverState}; | ||
|
||
#[utoipa::path(post, path = "/proof/cancel", | ||
tag = "Proving", | ||
request_body = ProofRequestOpt, | ||
responses ( | ||
(status = 200, description = "Successfully cancelled proof task", body = CancelStatus) | ||
) | ||
)] | ||
#[debug_handler(state = ProverState)] | ||
/// Cancel a proof task with requested config. | ||
/// | ||
/// Accepts a proof request and cancels a proving task with the specified guest prover. | ||
/// The guest provers currently available are: | ||
/// - native - constructs a block and checks for equality | ||
/// - sgx - uses the sgx environment to construct a block and produce proof of execution | ||
/// - sp1 - uses the sp1 prover | ||
/// - risc0 - uses the risc0 prover | ||
async fn cancel_handler( | ||
State(prover_state): State<ProverState>, | ||
Json(aggregation_request): Json<AggregationRequest>, | ||
) -> HostResult<CancelStatus> { | ||
// Override the existing proof request config from the config file and command line | ||
// options with the request from the client. | ||
aggregation_request.merge(&prover_state.request_config()); | ||
|
||
let proof_request_opts: Vec<ProofRequestOpt> = aggregation_request.into(); | ||
|
||
for opt in proof_request_opts { | ||
let proof_request = ProofRequest::try_from(opt)?; | ||
|
||
let (chain_id, block_hash) = get_task_data( | ||
&proof_request.network, | ||
proof_request.block_number, | ||
&prover_state.chain_specs, | ||
) | ||
.await?; | ||
|
||
let key = TaskDescriptor::from(( | ||
chain_id, | ||
block_hash, | ||
proof_request.proof_type, | ||
proof_request.prover.clone().to_string(), | ||
)); | ||
|
||
prover_state.task_channel.try_send(Message::from(&key))?; | ||
|
||
let mut manager = prover_state.task_manager(); | ||
|
||
manager | ||
.update_task_progress(key, TaskStatus::Cancelled, None) | ||
.await?; | ||
} | ||
|
||
Ok(CancelStatus::Ok) | ||
} | ||
|
||
#[derive(OpenApi)] | ||
#[openapi(paths(cancel_handler))] | ||
struct Docs; | ||
|
||
pub fn create_docs() -> utoipa::openapi::OpenApi { | ||
Docs::openapi() | ||
} | ||
|
||
pub fn create_router() -> Router<ProverState> { | ||
Router::new().route("/", post(cancel_handler)) | ||
} |
Oops, something went wrong.