mirror of
https://github.com/eth-act/ere.git
synced 2026-04-03 03:00:17 -04:00
Refactor docs and make Input API more explicit (#235)
This commit is contained in:
@@ -34,16 +34,16 @@ ere-zisk = { workspace = true, features = ["zkvm"], optional = true }
|
||||
ere-zkvm-interface = { workspace = true, features = ["clap"] }
|
||||
|
||||
[dev-dependencies]
|
||||
prost-build.workspace = true
|
||||
tempfile.workspace = true
|
||||
twirp-build.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
prost-build.workspace = true
|
||||
twirp-build.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["client"]
|
||||
client = []
|
||||
server = ["dep:clap", "dep:tower-http", "dep:tracing", "dep:tracing-subscriber", "tokio/macros", "tokio/rt-multi-thread", "tokio/signal"]
|
||||
|
||||
# zkVM
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
prost_build::Config::new()
|
||||
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") // enable support for JSON encoding
|
||||
.service_generator(twirp_build::service_generator())
|
||||
.compile_protos(&["./proto/api.proto"], &["./proto"])
|
||||
.expect("error compiling protos");
|
||||
Ok(())
|
||||
}
|
||||
278
crates/dockerized/server/src/api.rs
Normal file
278
crates/dockerized/server/src/api.rs
Normal file
@@ -0,0 +1,278 @@
|
||||
// This file is @generated by prost-build.
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ExecuteRequest {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub input_stdin: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub input_proofs: ::core::option::Option<::prost::alloc::vec::Vec<u8>>,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ExecuteResponse {
|
||||
#[prost(oneof = "execute_response::Result", tags = "1, 2")]
|
||||
pub result: ::core::option::Option<execute_response::Result>,
|
||||
}
|
||||
/// Nested message and enum types in `ExecuteResponse`.
|
||||
pub mod execute_response {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||
pub enum Result {
|
||||
#[prost(message, tag = "1")]
|
||||
Ok(super::ExecuteOk),
|
||||
#[prost(string, tag = "2")]
|
||||
Err(::prost::alloc::string::String),
|
||||
}
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ExecuteOk {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub public_values: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub report: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ProveRequest {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub input_stdin: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub input_proofs: ::core::option::Option<::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(enumeration = "ProofKind", tag = "3")]
|
||||
pub proof_kind: i32,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ProveResponse {
|
||||
#[prost(oneof = "prove_response::Result", tags = "1, 2")]
|
||||
pub result: ::core::option::Option<prove_response::Result>,
|
||||
}
|
||||
/// Nested message and enum types in `ProveResponse`.
|
||||
pub mod prove_response {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||
pub enum Result {
|
||||
#[prost(message, tag = "1")]
|
||||
Ok(super::ProveOk),
|
||||
#[prost(string, tag = "2")]
|
||||
Err(::prost::alloc::string::String),
|
||||
}
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ProveOk {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub public_values: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub proof: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub report: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct VerifyRequest {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub proof: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(enumeration = "ProofKind", tag = "2")]
|
||||
pub proof_kind: i32,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct VerifyResponse {
|
||||
#[prost(oneof = "verify_response::Result", tags = "1, 2")]
|
||||
pub result: ::core::option::Option<verify_response::Result>,
|
||||
}
|
||||
/// Nested message and enum types in `VerifyResponse`.
|
||||
pub mod verify_response {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||
pub enum Result {
|
||||
#[prost(message, tag = "1")]
|
||||
Ok(super::VerifyOk),
|
||||
#[prost(string, tag = "2")]
|
||||
Err(::prost::alloc::string::String),
|
||||
}
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct VerifyOk {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub public_values: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum ProofKind {
|
||||
Compressed = 0,
|
||||
Groth16 = 1,
|
||||
}
|
||||
impl ProofKind {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Compressed => "Compressed",
|
||||
Self::Groth16 => "Groth16",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"Compressed" => Some(Self::Compressed),
|
||||
"Groth16" => Some(Self::Groth16),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use twirp;
|
||||
#[twirp::async_trait::async_trait]
|
||||
pub trait ZkvmService: Send + Sync {
|
||||
async fn execute(
|
||||
&self,
|
||||
req: twirp::Request<ExecuteRequest>,
|
||||
) -> twirp::Result<twirp::Response<ExecuteResponse>>;
|
||||
async fn prove(
|
||||
&self,
|
||||
req: twirp::Request<ProveRequest>,
|
||||
) -> twirp::Result<twirp::Response<ProveResponse>>;
|
||||
async fn verify(
|
||||
&self,
|
||||
req: twirp::Request<VerifyRequest>,
|
||||
) -> twirp::Result<twirp::Response<VerifyResponse>>;
|
||||
}
|
||||
#[twirp::async_trait::async_trait]
|
||||
impl<T> ZkvmService for std::sync::Arc<T>
|
||||
where
|
||||
T: ZkvmService + Sync + Send,
|
||||
{
|
||||
async fn execute(
|
||||
&self,
|
||||
req: twirp::Request<ExecuteRequest>,
|
||||
) -> twirp::Result<twirp::Response<ExecuteResponse>> {
|
||||
T::execute(&*self, req).await
|
||||
}
|
||||
async fn prove(
|
||||
&self,
|
||||
req: twirp::Request<ProveRequest>,
|
||||
) -> twirp::Result<twirp::Response<ProveResponse>> {
|
||||
T::prove(&*self, req).await
|
||||
}
|
||||
async fn verify(
|
||||
&self,
|
||||
req: twirp::Request<VerifyRequest>,
|
||||
) -> twirp::Result<twirp::Response<VerifyResponse>> {
|
||||
T::verify(&*self, req).await
|
||||
}
|
||||
}
|
||||
pub fn router<T>(api: T) -> twirp::Router
|
||||
where
|
||||
T: ZkvmService + Clone + Send + Sync + 'static,
|
||||
{
|
||||
twirp::details::TwirpRouterBuilder::new("/api.ZkvmService", api)
|
||||
.route(
|
||||
"/Execute",
|
||||
|api: T, req: twirp::Request<ExecuteRequest>| async move {
|
||||
api.execute(req).await
|
||||
},
|
||||
)
|
||||
.route(
|
||||
"/Prove",
|
||||
|api: T, req: twirp::Request<ProveRequest>| async move {
|
||||
api.prove(req).await
|
||||
},
|
||||
)
|
||||
.route(
|
||||
"/Verify",
|
||||
|api: T, req: twirp::Request<VerifyRequest>| async move {
|
||||
api.verify(req).await
|
||||
},
|
||||
)
|
||||
.build()
|
||||
}
|
||||
#[twirp::async_trait::async_trait]
|
||||
impl ZkvmService for twirp::client::Client {
|
||||
async fn execute(
|
||||
&self,
|
||||
req: twirp::Request<ExecuteRequest>,
|
||||
) -> twirp::Result<twirp::Response<ExecuteResponse>> {
|
||||
self.request("api.ZkvmService/Execute", req).await
|
||||
}
|
||||
async fn prove(
|
||||
&self,
|
||||
req: twirp::Request<ProveRequest>,
|
||||
) -> twirp::Result<twirp::Response<ProveResponse>> {
|
||||
self.request("api.ZkvmService/Prove", req).await
|
||||
}
|
||||
async fn verify(
|
||||
&self,
|
||||
req: twirp::Request<VerifyRequest>,
|
||||
) -> twirp::Result<twirp::Response<VerifyResponse>> {
|
||||
self.request("api.ZkvmService/Verify", req).await
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub mod handler {
|
||||
use super::*;
|
||||
pub struct ZkvmServiceHandler {
|
||||
inner: std::sync::Arc<dyn ZkvmService>,
|
||||
}
|
||||
impl ZkvmServiceHandler {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new<M: ZkvmService + 'static>(inner: M) -> Self {
|
||||
Self {
|
||||
inner: std::sync::Arc::new(inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[twirp::async_trait::async_trait]
|
||||
impl twirp::client::DirectHandler for ZkvmServiceHandler {
|
||||
fn service(&self) -> &str {
|
||||
"api.ZkvmService"
|
||||
}
|
||||
async fn handle(
|
||||
&self,
|
||||
method: &str,
|
||||
req: twirp::reqwest::Request,
|
||||
) -> twirp::Result<twirp::reqwest::Response> {
|
||||
match method {
|
||||
"Execute" => {
|
||||
twirp::details::encode_response(
|
||||
self
|
||||
.inner
|
||||
.execute(twirp::details::decode_request(req).await?)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
"Prove" => {
|
||||
twirp::details::encode_response(
|
||||
self
|
||||
.inner
|
||||
.prove(twirp::details::decode_request(req).await?)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
"Verify" => {
|
||||
twirp::details::encode_response(
|
||||
self
|
||||
.inner
|
||||
.verify(twirp::details::decode_request(req).await?)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
Err(
|
||||
twirp::bad_route(
|
||||
format!(
|
||||
"unknown rpc `{method}` for service `{}`, url: {:?}",
|
||||
"api.ZkvmService", req.url()
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
pub mod client;
|
||||
#[rustfmt::skip]
|
||||
pub mod api;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod api {
|
||||
include!(concat!(env!("OUT_DIR"), "/api.rs"));
|
||||
}
|
||||
#[cfg(feature = "client")]
|
||||
pub mod client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
28
crates/dockerized/server/src/test.rs
Normal file
28
crates/dockerized/server/src/test.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::{env, fs, path::PathBuf};
|
||||
|
||||
/// To sync generated `api.rs`, run:
|
||||
///
|
||||
/// ```
|
||||
/// cargo test --package ere-server --no-default-features --lib -- test::api_generation --exact
|
||||
/// ```
|
||||
#[test]
|
||||
fn api_generation() {
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
prost_build::Config::new()
|
||||
.out_dir(tempdir.path())
|
||||
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") // enable support for JSON encoding
|
||||
.service_generator(twirp_build::service_generator())
|
||||
.compile_protos(&[dir.join("proto").join("api.proto")], &[dir.join("proto")])
|
||||
.unwrap();
|
||||
|
||||
let latest = tempdir.path().join("api.rs");
|
||||
let current = dir.join("src").join("api.rs");
|
||||
|
||||
// If it's in CI env, don't overwrite but only check if it's up-to-date.
|
||||
if env::var_os("GITHUB_ACTIONS").is_none() {
|
||||
fs::copy(&latest, ¤t).unwrap();
|
||||
}
|
||||
assert_eq!(fs::read(&latest).unwrap(), fs::read(¤t).unwrap());
|
||||
}
|
||||
Reference in New Issue
Block a user