-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: gRPC server and client (#4)
Implemented a gRPC server to call the Stone prover from a remote client. This server provides a single endpoint at the moment, `Prove`, which returns the proof. The protocol uses server-side streaming to communicate the proof to the client once it is computed. This server is still limited, the following points need to be discussed: * Efficiency: the protocol passes JSON data (public input, prover config and parameters) as raw strings. These strings are then deserialized on server-side to validate them, but end up being serialized again for use by the prover process. This is clearly inefficient. * Even if the client process cancels the request, the prover will keep on running until the proof is generated.
- Loading branch information
1 parent
57347e7
commit 54aca74
Showing
13 changed files
with
372 additions
and
24 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
[workspace] | ||
resolver = "2" | ||
|
||
members = ["stone-prover"] | ||
members = ["madara-prover-rpc-client", "madara-prover-rpc-server", "stone-prover"] | ||
|
||
[workspace.dependencies] | ||
prost = "0.12.1" | ||
serde = { version = "1.0.192", features = ["derive"] } | ||
serde_json = "1.0.108" | ||
tokio = { version = "1.34.0", features = ["macros", "process", "rt-multi-thread"] } | ||
tonic = "0.10.2" | ||
tonic-build = "0.10.2" |
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,15 @@ | ||
[package] | ||
name = "madara-prover-rpc-client" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
prost = { workspace = true } | ||
serde_json = { workspace = true } | ||
tokio = { workspace = true } | ||
tonic = { workspace = true } | ||
|
||
[build-dependencies] | ||
tonic-build = { workspace = true } |
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,4 @@ | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
tonic_build::compile_protos("../protocols/prover.proto")?; | ||
Ok(()) | ||
} |
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,28 @@ | ||
use tonic::codegen::tokio_stream::StreamExt; | ||
use tonic::Status; | ||
|
||
use crate::prover::prover_client::ProverClient; | ||
use crate::prover::{ProverRequest, ProverResponse}; | ||
|
||
pub async fn call_prover( | ||
client: &mut ProverClient<tonic::transport::Channel>, | ||
public_input: String, | ||
memory: Vec<u8>, | ||
trace: Vec<u8>, | ||
prover_config: String, | ||
prover_parameters: String, | ||
) -> Result<ProverResponse, Status> { | ||
let request = tonic::Request::new(ProverRequest { | ||
public_input, | ||
memory, | ||
trace, | ||
prover_config, | ||
prover_parameters, | ||
}); | ||
let prover_stream = client.prove(request).await?.into_inner(); | ||
if let Some(prover_result) = prover_stream.take(1).next().await { | ||
return prover_result; | ||
} | ||
|
||
Err(Status::cancelled("Server-side stream was dropped")) | ||
} |
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,33 @@ | ||
use crate::client::call_prover; | ||
use prover::prover_client::ProverClient; | ||
use std::path::Path; | ||
|
||
pub mod client; | ||
mod prover; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let mut client = ProverClient::connect("http://[::1]:8080").await?; | ||
|
||
let fixtures_dir = Path::new("../stone-prover/tests/fixtures/fibonacci"); | ||
let public_input = | ||
std::fs::read_to_string(fixtures_dir.join("fibonacci_public_input.json")).unwrap(); | ||
let memory = std::fs::read(fixtures_dir.join("fibonacci_memory.bin")).unwrap(); | ||
let trace = std::fs::read(fixtures_dir.join("fibonacci_trace.bin")).unwrap(); | ||
let prover_config = | ||
std::fs::read_to_string(fixtures_dir.join("cpu_air_prover_config.json")).unwrap(); | ||
let prover_parameters = | ||
std::fs::read_to_string(fixtures_dir.join("cpu_air_params.json")).unwrap(); | ||
|
||
let response = call_prover( | ||
&mut client, | ||
public_input, | ||
memory, | ||
trace, | ||
prover_config, | ||
prover_parameters, | ||
) | ||
.await?; | ||
println!("Got: '{}' from service", response.proof_hex); | ||
Ok(()) | ||
} |
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 @@ | ||
tonic::include_proto!("prover"); |
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,18 @@ | ||
[package] | ||
name = "madara-prover-rpc-server" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
prost = { workspace = true } | ||
stone-prover = { path = "../stone-prover" } | ||
tokio = { workspace = true } | ||
tonic = { workspace = true } | ||
serde_json = { workspace = true } | ||
tokio-stream = "0.1.14" | ||
|
||
[build-dependencies] | ||
tonic-build = { workspace = true } | ||
|
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,4 @@ | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
tonic_build::compile_protos("../protocols/prover.proto")?; | ||
Ok(()) | ||
} |
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,70 @@ | ||
use tokio_stream::wrappers::ReceiverStream; | ||
use tonic::{transport::Server, Request, Response, Status}; | ||
|
||
use prover::ProverRequest; | ||
use stone_prover::error::ProverError; | ||
use stone_prover::models::{Proof, ProverConfig, ProverParameters, PublicInput}; | ||
use stone_prover::prover::run_prover_async; | ||
|
||
use crate::prover::prover_server::{Prover, ProverServer}; | ||
use crate::prover::ProverResponse; | ||
|
||
pub mod prover { | ||
tonic::include_proto!("prover"); | ||
} | ||
|
||
async fn call_prover(prover_request: &ProverRequest) -> Result<Proof, ProverError> { | ||
let public_input: PublicInput = serde_json::from_str(&prover_request.public_input)?; | ||
let prover_config: ProverConfig = serde_json::from_str(&prover_request.prover_config)?; | ||
let prover_parameters: ProverParameters = | ||
serde_json::from_str(&prover_request.prover_parameters)?; | ||
|
||
run_prover_async( | ||
&public_input, | ||
&prover_request.memory, | ||
&prover_request.trace, | ||
&prover_config, | ||
&prover_parameters, | ||
) | ||
.await | ||
} | ||
|
||
#[derive(Debug, Default)] | ||
pub struct ProverService {} | ||
|
||
#[tonic::async_trait] | ||
impl Prover for ProverService { | ||
type ProveStream = ReceiverStream<Result<ProverResponse, Status>>; | ||
|
||
async fn prove( | ||
&self, | ||
request: Request<ProverRequest>, | ||
) -> Result<Response<Self::ProveStream>, Status> { | ||
let r = request.into_inner(); | ||
let (tx, rx) = tokio::sync::mpsc::channel(1); | ||
|
||
tokio::spawn(async move { | ||
let prover_result = call_prover(&r) | ||
.await | ||
.map(|proof| ProverResponse { | ||
proof_hex: proof.proof_hex, | ||
}) | ||
.map_err(|e| Status::invalid_argument(format!("Prover run failed: {e}"))); | ||
let _ = tx.send(prover_result).await; | ||
}); | ||
|
||
Ok(Response::new(ReceiverStream::new(rx))) | ||
} | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let address = "[::1]:8080".parse().unwrap(); | ||
let prover_service = ProverService::default(); | ||
|
||
Server::builder() | ||
.add_service(ProverServer::new(prover_service)) | ||
.serve(address) | ||
.await?; | ||
Ok(()) | ||
} |
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,19 @@ | ||
syntax = "proto3"; | ||
package prover; | ||
|
||
service Prover { | ||
rpc Prove (ProverRequest) returns (stream ProverResponse); | ||
} | ||
|
||
message ProverRequest { | ||
|
||
string public_input = 1; | ||
bytes memory = 2; | ||
bytes trace = 3; | ||
string prover_config = 4; | ||
string prover_parameters = 5; | ||
} | ||
|
||
message ProverResponse { | ||
string proof_hex = 1; | ||
} |
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
Oops, something went wrong.