Skip to content

Commit

Permalink
feat: add SyncCompute API skeleton in executor
Browse files Browse the repository at this point in the history
Put common definitions in the common.proto file.

Some rework of key hanlding that will be used in the executor.
  • Loading branch information
dartdart26 committed Aug 26, 2024
1 parent bed330f commit 29430b7
Show file tree
Hide file tree
Showing 21 changed files with 378 additions and 97 deletions.
12 changes: 10 additions & 2 deletions fhevm-engine/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion fhevm-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ resolver = "2"
members = ["coprocessor", "executor", "fhevm-engine-common"]

[workspace.dependencies]
tfhe = { version = "0.8.0-alpha.2", features = ["boolean", "shortint", "integer", "aarch64-unix", "zk-pok"] }
tfhe = { version = "0.8.0-alpha.2", features = ["boolean", "shortint", "integer", "aarch64-unix", "zk-pok", "experimental-force_fft_algo_dif4"] }
clap = { version = "4.5", features = ["derive"] }
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
prost = "0.13"
tonic = { version = "0.12", features = ["server"] }
6 changes: 3 additions & 3 deletions fhevm-engine/coprocessor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ edition = "2021"

[dependencies]
# Common dependencies
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
prost = "0.13"
tonic = { version = "0.12", features = ["server"] }
tokio.workspace = true
prost.workspace = true
tonic.workspace = true
# Optional dependencies
tonic-web = "0.12"
tonic-health = "0.12"
Expand Down
16 changes: 4 additions & 12 deletions fhevm-engine/coprocessor/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use fhevm_engine_common::generate_fhe_keys;
use fhevm_engine_common::keys::{FhevmKeys, SerializedFhevmKeys};
use tokio::task::JoinSet;

mod cli;
Expand Down Expand Up @@ -82,15 +82,7 @@ async fn async_main(
}

fn generate_dump_fhe_keys() {
let output_dir = "fhevm-keys";
println!("Generating keys...");
let keys = generate_fhe_keys();
println!("Creating directory {output_dir}");
std::fs::create_dir_all(output_dir).unwrap();
println!("Creating file {output_dir}/cks");
std::fs::write(format!("{output_dir}/cks"), keys.client_key).unwrap();
println!("Creating file {output_dir}/pks");
std::fs::write(format!("{output_dir}/pks"), keys.compact_public_key).unwrap();
println!("Creating file {output_dir}/sks");
std::fs::write(format!("{output_dir}/sks"), keys.server_key).unwrap();
let keys = FhevmKeys::new();
let ser_keys: SerializedFhevmKeys = keys.into();
ser_keys.save_to_disk();
}
6 changes: 5 additions & 1 deletion fhevm-engine/coprocessor/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ use coprocessor::{DebugDecryptResponse, DebugDecryptResponseSingle, InputCiphert
use sqlx::{query, Acquire};
use tonic::transport::Server;

pub mod common {
tonic::include_proto!("fhevm.common");
}

pub mod coprocessor {
tonic::include_proto!("coprocessor");
tonic::include_proto!("fhevm.coprocessor");
}

pub struct CoprocessorService {
Expand Down
3 changes: 2 additions & 1 deletion fhevm-engine/coprocessor/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use crate::server::coprocessor::async_computation_input::Input;
use crate::server::coprocessor::fhevm_coprocessor_client::FhevmCoprocessorClient;
use crate::server::coprocessor::{
AsyncComputation, AsyncComputationInput, AsyncComputeRequest, DebugDecryptRequest,
DebugEncryptRequest, DebugEncryptRequestSingle, FheOperation,
DebugEncryptRequest, DebugEncryptRequestSingle,
};
use crate::server::common::FheOperation;
use tonic::metadata::MetadataValue;
use utils::{default_api_key, wait_until_all_ciphertexts_computed};

Expand Down
3 changes: 2 additions & 1 deletion fhevm-engine/coprocessor/src/tests/operators.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::server::coprocessor::fhevm_coprocessor_client::FhevmCoprocessorClient;
use crate::server::coprocessor::{
AsyncComputation, AsyncComputeRequest, DebugDecryptRequest, DebugEncryptRequest,
DebugEncryptRequestSingle, FheOperation,
DebugEncryptRequestSingle,
};
use crate::server::common::FheOperation;
use crate::tests::utils::wait_until_all_ciphertexts_computed;
use crate::{
server::coprocessor::{async_computation_input::Input, AsyncComputationInput},
Expand Down
8 changes: 8 additions & 0 deletions fhevm-engine/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ version = "0.1.0"
edition = "2021"

[dependencies]
clap.workspace = true
tokio.workspace = true
prost.workspace = true
tonic.workspace = true
fhevm-engine-common = { path = "../fhevm-engine-common" }

[build-dependencies]
tonic-build = "0.12"
9 changes: 9 additions & 0 deletions fhevm-engine/executor/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::{env, path::PathBuf};

fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
tonic_build::configure()
.file_descriptor_set_path(out_dir.join("executor_descriptor.bin"))
.compile(&["../../proto/executor.proto"], &["../../proto"])
.unwrap();
}
18 changes: 18 additions & 0 deletions fhevm-engine/executor/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use clap::Parser;

#[derive(Parser, Debug, Clone)]
#[command(version, about, long_about = None)]
pub struct Args {
#[arg(long, default_value_t = 4)]
pub tokio_threads: usize,

#[arg(long, default_value_t = 8)]
pub fhe_compute_threads: usize,

#[arg(long, default_value = "127.0.0.1:50051")]
pub server_addr: String,
}

pub fn parse_args() -> Args {
Args::parse()
}
2 changes: 2 additions & 0 deletions fhevm-engine/executor/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod cli;
pub mod server;
11 changes: 9 additions & 2 deletions fhevm-engine/executor/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
fn main() {
println!("Hello, world!");
use std::error::Error;

mod cli;
mod server;

fn main() -> Result<(), Box<dyn Error>> {
let args = cli::parse_args();
server::start(&args)?;
Ok(())
}
48 changes: 48 additions & 0 deletions fhevm-engine/executor/src/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::error::Error;

use executor::{
fhevm_executor_server::{FhevmExecutor, FhevmExecutorServer},
SyncComputeRequest, SyncComputeResponse,
};
use tonic::{transport::Server, Request, Response};

mod common {
tonic::include_proto!("fhevm.common");
}

pub mod executor {
tonic::include_proto!("fhevm.executor");
}

pub fn start(args: &crate::cli::Args) -> Result<(), Box<dyn Error>> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.worker_threads(args.tokio_threads)
.max_blocking_threads(args.fhe_compute_threads)
.enable_all()
.build()?;

let executor = FhevmExecutorService::default();
let addr = args.server_addr.parse().expect("server address");

runtime.block_on(async {
Server::builder()
.add_service(FhevmExecutorServer::new(executor))
.serve(addr)
.await?;
Ok::<(), Box<dyn Error>>(())
})?;
Ok(())
}

#[derive(Default)]
pub struct FhevmExecutorService {}

#[tonic::async_trait]
impl FhevmExecutor for FhevmExecutorService {
async fn sync_compute(
&self,
req: Request<SyncComputeRequest>,
) -> Result<Response<SyncComputeResponse>, tonic::Status> {
Ok(Response::new(SyncComputeResponse::default()))
}
}
12 changes: 12 additions & 0 deletions fhevm-engine/executor/tests/sync_compute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use executor::server::executor::{fhevm_executor_client::FhevmExecutorClient, SyncComputeRequest};
use utils::TestInstance;

mod utils;

#[tokio::test]
async fn compute_on_ciphertexts() -> Result<(), Box<dyn std::error::Error>> {
let test_instance = TestInstance::new();
let mut client = FhevmExecutorClient::connect(test_instance.server_addr).await?;
let resp = client.sync_compute(SyncComputeRequest::default()).await?;
Ok(())
}
27 changes: 27 additions & 0 deletions fhevm-engine/executor/tests/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use clap::Parser;
use executor::{cli::Args, server};
use fhevm_engine_common::keys::{FhevmKeys, SerializedFhevmKeys};

pub struct TestInstance {
pub keys: FhevmKeys,
pub server_addr: String,
}

impl TestInstance {
pub fn new() -> Self {
// Get defaults by parsing a cmd line without any arguments.
let args = Args::parse_from(&["test"]);

let instance = TestInstance {
keys: SerializedFhevmKeys::load_from_disk().into(),
server_addr: format!("http://{}", args.server_addr),
};

std::thread::spawn(move || server::start(&args).expect("start server"));

// TODO: a hacky way to wait for the server to start
std::thread::sleep(std::time::Duration::from_millis(150));

instance
}
}
16 changes: 4 additions & 12 deletions fhevm-engine/fhevm-engine-common/src/bin/generate_keys.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
use fhevm_engine_common::generate_fhe_keys;
use fhevm_engine_common::keys::{FhevmKeys, SerializedFhevmKeys};

fn main() {
let output_dir = "fhevm-keys";
println!("Generating keys...");
let keys = generate_fhe_keys();
println!("Creating directory {output_dir}");
std::fs::create_dir_all(output_dir).unwrap();
println!("Creating file {output_dir}/cks");
std::fs::write(format!("{output_dir}/cks"), keys.client_key).unwrap();
println!("Creating file {output_dir}/pks");
std::fs::write(format!("{output_dir}/pks"), keys.compact_public_key).unwrap();
println!("Creating file {output_dir}/sks");
std::fs::write(format!("{output_dir}/sks"), keys.server_key).unwrap();
let keys = FhevmKeys::new();
let ser_keys: SerializedFhevmKeys = keys.into();
ser_keys.save_to_disk();
}
104 changes: 104 additions & 0 deletions fhevm-engine/fhevm-engine-common/src/keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use std::fs::read;

use tfhe::{
generate_keys,
shortint::parameters::{
list_compression::COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
},
ClientKey, CompactPublicKey, ConfigBuilder, ServerKey,
};

pub struct FhevmKeys {
pub server_key: ServerKey,
pub client_key: Option<ClientKey>,
pub compact_public_key: Option<CompactPublicKey>,
}

pub struct SerializedFhevmKeys {
pub server_key: Vec<u8>,
pub client_key: Option<Vec<u8>>,
pub compact_public_key: Option<Vec<u8>>,
}

impl FhevmKeys {
pub fn new() -> Self {
println!("Generating keys...");
let config =
ConfigBuilder::with_custom_parameters(PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64)
.enable_compression(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64)
.build();
let (client_key, server_key) = generate_keys(config);
let compact_public_key = CompactPublicKey::new(&client_key);
FhevmKeys {
server_key,
client_key: Some(client_key),
compact_public_key: Some(compact_public_key),
}
}
}

impl SerializedFhevmKeys {
const DIRECTORY: &'static str = "fhevm-keys";
const SKS: &'static str = "fhevm-keys/sks";
const CKS: &'static str = "fhevm-keys/cks";
const PKS: &'static str = "fhevm-keys/pks";

pub fn save_to_disk(self) {
println!("Creating directory {}", Self::DIRECTORY);
std::fs::create_dir_all(Self::DIRECTORY).expect("create keys directory");

println!("Creating file {}", Self::SKS);
std::fs::write(format!("{}", Self::SKS), self.server_key).expect("write sks");

if self.client_key.is_some() {
println!("Creating file {}", Self::CKS);
std::fs::write(format!("{}", Self::CKS), self.client_key.unwrap()).expect("write cks");
}

if self.compact_public_key.is_some() {
println!("Creating file {}", Self::PKS);
std::fs::write(format!("{}", Self::PKS), self.compact_public_key.unwrap())
.expect("write pks");
}
}

pub fn load_from_disk() -> Self {
let server_key = read(Self::SKS).expect("read server key");
let client_key = read(Self::CKS);
let compact_public_key = read(Self::PKS);
SerializedFhevmKeys {
server_key,
client_key: client_key.ok(),
compact_public_key: compact_public_key.ok(),
}
}
}

impl From<FhevmKeys> for SerializedFhevmKeys {
fn from(f: FhevmKeys) -> Self {
SerializedFhevmKeys {
server_key: bincode::serialize(&f.server_key).expect("serialize server key"),
client_key: f
.client_key
.map(|c| bincode::serialize(&c).expect("serialize client key")),
compact_public_key: f
.compact_public_key
.map(|p| bincode::serialize(&p).expect("serialize compact public key")),
}
}
}

impl From<SerializedFhevmKeys> for FhevmKeys {
fn from(f: SerializedFhevmKeys) -> Self {
FhevmKeys {
server_key: bincode::deserialize(&f.server_key).expect("deserialize server key"),
client_key: f
.client_key
.map(|c| bincode::deserialize(&c).expect("deserialize client key")),
compact_public_key: f
.compact_public_key
.map(|p| bincode::deserialize(&p).expect("deserialize compact public key")),
}
}
}
Loading

0 comments on commit 29430b7

Please sign in to comment.