From 9bdd7b4d15c489c3fac548ed27d4dd34995b9cbc Mon Sep 17 00:00:00 2001 From: Timofey Luin Date: Thu, 4 Jan 2024 15:02:05 +0100 Subject: [PATCH 1/2] switch to per spec RPC server --- Cargo.toml | 4 +- eth-types/src/spec.rs | 4 + lightclient-circuits/tests/step.rs | 10 +- prover/Cargo.toml | 1 + prover/src/args.rs | 8 + prover/src/lib.rs | 2 + prover/src/main.rs | 26 +++- prover/src/prover.rs | 89 +++++++++++ prover/src/rpc.rs | 238 +++++++++++++---------------- prover/src/rpc_api.rs | 5 - prover/src/utils.rs | 2 +- 11 files changed, 245 insertions(+), 144 deletions(-) create mode 100644 prover/src/prover.rs diff --git a/Cargo.toml b/Cargo.toml index 022a6062..a192af4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,14 +77,16 @@ pasta_curves = "0.5.1" ff = "0.13" sha2 = { version = "0.9", features = ["compress"] } uint = "0.9.1" -ark-std = { version = "0.4.0", features = ["print-trace"] } # misc itertools = "0.12.0" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.78" +getset = "0.1.2" log = "0.4.14" hex = "0.4" +ark-std = { version = "0.4.0", features = ["print-trace"] } + [patch.crates-io] halo2curves = { git = "https://github.com/timoftime/halo2curves", package = "halo2curves-axiom", rev = "1bd39b8" } diff --git a/eth-types/src/spec.rs b/eth-types/src/spec.rs index e7a42e14..ba05992b 100644 --- a/eth-types/src/spec.rs +++ b/eth-types/src/spec.rs @@ -6,6 +6,7 @@ use core::fmt::Debug; /// Beacon chain specification. pub trait Spec: 'static + Sized + Copy + Default + Debug { + const NAME: &'static str; const SYNC_COMMITTEE_SIZE: usize; const SYNC_COMMITTEE_ROOT_INDEX: usize; const SYNC_COMMITTEE_DEPTH: usize; @@ -25,6 +26,7 @@ pub trait Spec: 'static + Sized + Copy + Default + Debug { pub struct Minimal; impl Spec for Minimal { + const NAME: &'static str = "minimal"; const SYNC_COMMITTEE_SIZE: usize = 32; const SYNC_COMMITTEE_DEPTH: usize = 5; const SYNC_COMMITTEE_ROOT_INDEX: usize = 55; @@ -45,6 +47,7 @@ impl Spec for Minimal { pub struct Testnet; impl Spec for Testnet { + const NAME: &'static str = "testnet"; const SYNC_COMMITTEE_SIZE: usize = 512; const SYNC_COMMITTEE_DEPTH: usize = 5; const SYNC_COMMITTEE_ROOT_INDEX: usize = 55; @@ -64,6 +67,7 @@ impl Spec for Testnet { pub struct Mainnet; impl Spec for Mainnet { + const NAME: &'static str = "mainnet"; const SYNC_COMMITTEE_SIZE: usize = 512; const SYNC_COMMITTEE_DEPTH: usize = 5; const SYNC_COMMITTEE_ROOT_INDEX: usize = 55; diff --git a/lightclient-circuits/tests/step.rs b/lightclient-circuits/tests/step.rs index 7d4308a9..e62279a5 100644 --- a/lightclient-circuits/tests/step.rs +++ b/lightclient-circuits/tests/step.rs @@ -92,13 +92,11 @@ fn run_test_eth2_spec_mock(path: PathB let rotation_circuit = mock_committee_update_circuit(&rotation_witness, K_ROTATION, None); + let rotation_instance = + CommitteeUpdateCircuit::::get_instances(&rotation_witness, LIMB_BITS); let timer = start_timer!(|| "committee_update mock prover run"); - let prover = MockProver::::run( - K_ROTATION, - &rotation_circuit, - CommitteeUpdateCircuit::::get_instances(&rotation_witness, LIMB_BITS), - ) - .unwrap(); + let prover = + MockProver::::run(K_ROTATION, &rotation_circuit, rotation_instance).unwrap(); prover.assert_satisfied_par(); end_timer!(timer); diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 82584bf5..151fcdf5 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -39,6 +39,7 @@ ark-std.workspace = true itertools.workspace = true serde.workspace = true serde_json.workspace = true +getset.workspace = true log.workspace = true url = "2" diff --git a/prover/src/args.rs b/prover/src/args.rs index 668c1cf8..738ed600 100644 --- a/prover/src/args.rs +++ b/prover/src/args.rs @@ -37,6 +37,14 @@ pub enum BaseCmd { /// Port for RPC server to listen on #[clap(long, short, default_value = "3000")] port: String, + + /// Network specification [mainnet, testnet] + #[clap(long, short, default_value = "mainnet")] + spec: Spec, + + /// Path to directory with circuit artifacts + #[clap(long, short, default_value = "./build")] + build_dir: PathBuf, }, /// Circuit related commands. Circuit { diff --git a/prover/src/lib.rs b/prover/src/lib.rs index aac547c6..2fcf6f3c 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -4,6 +4,8 @@ #![allow(incomplete_features)] #![feature(generic_const_exprs)] +pub mod prover; + pub mod rpc_api; pub mod rpc_client; diff --git a/prover/src/main.rs b/prover/src/main.rs index 291d2d71..808aacca 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -20,8 +20,30 @@ mod args; async fn app(options: Cli) -> eyre::Result<()> { match options.subcommand { - args::BaseCmd::Rpc { port } => { - run_rpc(port.parse().unwrap()).await?; + args::BaseCmd::Rpc { + port, + spec, + build_dir, + } => { + match spec { + args::Spec::Testnet => { + run_rpc::( + port.parse().unwrap(), + options.args.config_dir, + build_dir, + ) + .await + } + args::Spec::Mainnet => { + run_rpc::( + port.parse().unwrap(), + options.args.config_dir, + build_dir, + ) + .await + } + args::Spec::Minimal => Err(eyre::eyre!("Minimal spec is not supported for RPC")), + }?; log::info!("Stopped accepting RPC connections"); diff --git a/prover/src/prover.rs b/prover/src/prover.rs new file mode 100644 index 00000000..b338d7d9 --- /dev/null +++ b/prover/src/prover.rs @@ -0,0 +1,89 @@ +// The Licensed Work is (c) 2023 ChainSafe +// Code: https://github.com/ChainSafe/Spectre +// SPDX-License-Identifier: LGPL-3.0-only + +use eth_types::Spec; +use getset::Getters; +use lightclient_circuits::committee_update_circuit::CommitteeUpdateCircuit; +use lightclient_circuits::halo2_base::utils::fs::gen_srs; +use lightclient_circuits::halo2_proofs::{ + halo2curves::bn256::{Bn256, Fr, G1Affine}, + plonk::ProvingKey, + poly::kzg::commitment::ParamsKZG, +}; +use lightclient_circuits::sync_step_circuit::StepCircuit; +use lightclient_circuits::util::AppCircuit; +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; + +#[derive(Clone, Debug, Getters)] +pub struct CircuitContext { + #[getset(get = "pub")] + pub config_path: PathBuf, + #[getset(get = "pub")] + pub degree: u32, + #[getset(get = "pub")] + pub pk: ProvingKey, +} + +#[derive(Clone, Debug)] +pub struct ProverState { + // degree -> params (use BTreeMap to find proper degree for params downsize) + pub params: BTreeMap>, + pub step: CircuitContext, + pub step_verifier: CircuitContext, + pub committee_update: CircuitContext, + pub committee_update_verifier: CircuitContext, +} + +impl ProverState { + pub fn new(config_dir: &Path, build_dir: &Path) -> Self { + let mut params_map = BTreeMap::new(); + + fn load_ctx( + config_path: PathBuf, + pk_path: PathBuf, + params_map: &mut BTreeMap>, + ) -> CircuitContext + where + Circuit::Witness: Default, + { + let degree = Circuit::get_degree(&config_path); + let params = gen_srs(degree); + + let pk = Circuit::read_pk(¶ms, pk_path, &config_path, &Circuit::Witness::default()); + + params_map.insert(degree, params); + + CircuitContext { + config_path, + degree, + pk, + } + } + + Self { + step: load_ctx::>( + config_dir.join(format!("sync_step_{}.json", S::NAME)), + build_dir.join(format!("sync_step_{}.pkey", S::NAME)), + &mut params_map, + ), + step_verifier: load_ctx::>( + config_dir.join(format!("sync_step_verifier_{}.json", S::NAME)), + build_dir.join(format!("sync_step_verifier_{}.pkey", S::NAME)), + &mut params_map, + ), + committee_update: load_ctx::>( + config_dir.join(format!("committee_update_{}.json", S::NAME)), + build_dir.join(format!("committee_update_{}.pkey", S::NAME)), + &mut params_map, + ), + committee_update_verifier: load_ctx::>( + config_dir.join(format!("committee_update_verifier_{}.json", S::NAME)), + build_dir.join(format!("committee_update_verifier_{}.pkey", S::NAME)), + &mut params_map, + ), + params: params_map, + } + } +} diff --git a/prover/src/rpc.rs b/prover/src/rpc.rs index cacfbd9e..190f1980 100644 --- a/prover/src/rpc.rs +++ b/prover/src/rpc.rs @@ -2,22 +2,21 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only -use super::args::Spec; use axum::{http::StatusCode, response::IntoResponse, routing::post, Router}; use ethers::prelude::*; use itertools::Itertools; -use jsonrpc_v2::RequestObject as JsonRpcRequestObject; +use jsonrpc_v2::{Data, RequestObject as JsonRpcRequestObject}; use jsonrpc_v2::{Error as JsonRpcError, Params}; use jsonrpc_v2::{MapRouter as JsonRpcMapRouter, Server as JsonRpcServer}; -use lightclient_circuits::halo2_base::utils::fs::gen_srs; -use lightclient_circuits::halo2_proofs::halo2curves::bn256::Fr; -use lightclient_circuits::{ - committee_update_circuit::CommitteeUpdateCircuit, sync_step_circuit::StepCircuit, - util::AppCircuit, -}; +use lightclient_circuits::halo2_proofs::halo2curves::bn256::{Bn256, Fr, G1Affine}; +use lightclient_circuits::halo2_proofs::plonk::ProvingKey; +use lightclient_circuits::halo2_proofs::poly::kzg::commitment::ParamsKZG; +use lightclient_circuits::sync_step_circuit::StepCircuit; +use lightclient_circuits::{committee_update_circuit::CommitteeUpdateCircuit, util::AppCircuit}; use preprocessor::{rotation_args_from_update, step_args_from_finality_update}; use snark_verifier_sdk::{halo2::aggregation::AggregationCircuit, Snark}; -use std::path::PathBuf; +use spectre_prover::prover::ProverState; +use std::path::{Path, PathBuf}; use std::sync::Arc; pub type JsonRpcServerState = Arc>; @@ -28,77 +27,69 @@ use crate::rpc_api::{ RPC_EVM_PROOF_STEP_CIRCUIT_COMPRESSED, }; -pub(crate) fn jsonrpc_server() -> JsonRpcServer { +pub(crate) fn jsonrpc_server( + state: ProverState, +) -> JsonRpcServer +where + [(); S::SYNC_COMMITTEE_SIZE]:, + [(); S::FINALIZED_HEADER_DEPTH]:, + [(); S::BYTES_PER_LOGS_BLOOM]:, + [(); S::MAX_EXTRA_DATA_BYTES]:, + [(); S::SYNC_COMMITTEE_ROOT_INDEX]:, + [(); S::SYNC_COMMITTEE_DEPTH]:, + [(); S::FINALIZED_HEADER_INDEX]:, +{ JsonRpcServer::new() + .with_data(Data::new(state)) .with_method( RPC_EVM_PROOF_COMMITTEE_UPDATE_CIRCUIT_COMPRESSED, - gen_evm_proof_committee_update_handler, + gen_evm_proof_committee_update_handler::, ) .with_method( RPC_EVM_PROOF_STEP_CIRCUIT_COMPRESSED, - gen_evm_proof_sync_step_compressed_handler, + gen_evm_proof_sync_step_compressed_handler::, ) .finish_unwrapped() } - -pub(crate) async fn gen_evm_proof_committee_update_handler( +pub(crate) async fn gen_evm_proof_committee_update_handler( + Data(state): Data, Params(params): Params, -) -> Result { +) -> Result +where + [(); S::SYNC_COMMITTEE_SIZE]:, + [(); S::FINALIZED_HEADER_DEPTH]:, + [(); S::BYTES_PER_LOGS_BLOOM]:, + [(); S::MAX_EXTRA_DATA_BYTES]:, + [(); S::SYNC_COMMITTEE_ROOT_INDEX]:, + [(); S::SYNC_COMMITTEE_DEPTH]:, + [(); S::FINALIZED_HEADER_INDEX]:, +{ let GenProofCommitteeUpdateParams { - spec, light_client_update, } = params; - // TODO: use config/build paths from CLI flags - - let (snark, verifier_filename) = match spec { - Spec::Testnet => { - let mut update = ssz_rs::deserialize(&light_client_update)?; - let witness = rotation_args_from_update(&mut update).await?; - let snark = gen_uncompressed_snark::>( - PathBuf::from("./lightclient-circuits/config/committee_update_testnet.json"), - PathBuf::from("./build/committee_update_testnet.pkey"), - witness, - )?; - - (snark, "committee_update_verifier_testnet") - } - Spec::Mainnet => { - let mut update = ssz_rs::deserialize(&light_client_update)?; - let witness = rotation_args_from_update(&mut update).await?; - let snark = gen_uncompressed_snark::>( - PathBuf::from("./lightclient-circuits/config/committee_update_mainnet.json"), - PathBuf::from("./build/committee_update_mainnet.pkey"), - witness, - )?; - - (snark, "committee_update_verifier_mainnet") - } - Spec::Minimal => return Err(JsonRpcError::internal("Minimal spec not supported in RPC")), - }; - - let (proof, instances) = { - let pinning_path = format!("./lightclient-circuits/config/{verifier_filename}.json"); - - // Circuits of all specs have the same pinning type so we can just use Mainnet spec. - let agg_k = AggregationCircuit::get_degree(&pinning_path); - let params_agg = gen_srs(agg_k); - let pk_agg = AggregationCircuit::read_pk( - ¶ms_agg, - format!("./build/{verifier_filename}.pkey"), - &pinning_path, - &vec![snark.clone()], - ); - - AggregationCircuit::gen_evm_proof_shplonk( - ¶ms_agg, - &pk_agg, - pinning_path, - None, - &vec![snark.clone()], - ) - .map_err(JsonRpcError::internal)? - }; + let mut update = ssz_rs::deserialize(&light_client_update)?; + let witness = rotation_args_from_update(&mut update).await?; + let params = state.params.get(state.committee_update.degree()).unwrap(); + + let snark = gen_uncompressed_snark::>( + state.committee_update.config_path(), + params, + state.committee_update.pk(), + witness, + )?; + + let (proof, instances) = AggregationCircuit::gen_evm_proof_shplonk( + state + .params + .get(state.committee_update_verifier.degree()) + .unwrap(), + state.committee_update_verifier.pk(), + state.committee_update_verifier.config_path(), + None, + &vec![snark.clone()], + ) + .map_err(JsonRpcError::internal)?; // Should be of length 77 initially then 12 after removing the last 65 elements which is the accumulator. // 12 field elems pairing, 1 byte poseidon commitment, 32 bytes ssz commitment, 32 bytes finalized header root @@ -120,66 +111,42 @@ pub(crate) async fn gen_evm_proof_committee_update_handler( }) } -pub(crate) async fn gen_evm_proof_sync_step_compressed_handler( +pub(crate) async fn gen_evm_proof_sync_step_compressed_handler( + Data(state): Data, Params(params): Params, -) -> Result { +) -> Result +where + [(); S::SYNC_COMMITTEE_SIZE]:, + [(); S::FINALIZED_HEADER_DEPTH]:, + [(); S::BYTES_PER_LOGS_BLOOM]:, + [(); S::MAX_EXTRA_DATA_BYTES]:, +{ let GenProofStepParams { - spec, light_client_finality_update, domain, pubkeys, } = params; - let (snark, verifier_filename) = match spec { - Spec::Testnet => { - let update = ssz_rs::deserialize(&light_client_finality_update)?; - let pubkeys = ssz_rs::deserialize(&pubkeys)?; - let witness = step_args_from_finality_update(update, pubkeys, domain).await?; - let snark = gen_uncompressed_snark::>( - PathBuf::from("./lightclient-circuits/config/sync_step_testnet.json"), - PathBuf::from("./build/sync_step_testnet.pkey"), - witness, - )?; - - (snark, "sync_step_verifier_testnet") - } - Spec::Mainnet => { - let update = ssz_rs::deserialize(&light_client_finality_update)?; - let pubkeys = ssz_rs::deserialize(&pubkeys)?; - let witness = step_args_from_finality_update(update, pubkeys, domain).await?; - let snark = gen_uncompressed_snark::>( - PathBuf::from("./lightclient-circuits/config/sync_step_mainnet.json"), - PathBuf::from("./build/sync_step_mainnet.pkey"), - witness, - )?; - - (snark, "sync_step_verifier_mainnet") - } - Spec::Minimal => return Err(JsonRpcError::internal("Minimal spec not supported in RPC")), - }; - - let (proof, instances) = { - let pinning_path = format!("./lightclient-circuits/config/{verifier_filename}.json"); - - // Circuits of all specs have the same pinning type so we can just use Mainnet spec. - let agg_k = AggregationCircuit::get_degree(&pinning_path); - let params_agg = gen_srs(agg_k); - let pk_agg = AggregationCircuit::read_pk( - ¶ms_agg, - format!("./build/{verifier_filename}.pkey"), - &pinning_path, - &vec![snark.clone()], - ); - - AggregationCircuit::gen_evm_proof_shplonk( - ¶ms_agg, - &pk_agg, - pinning_path, - None, - &vec![snark.clone()], - ) - .map_err(JsonRpcError::internal)? - }; + let update = ssz_rs::deserialize(&light_client_finality_update)?; + let pubkeys = ssz_rs::deserialize(&pubkeys)?; + let witness = step_args_from_finality_update(update, pubkeys, domain).await?; + let params = state.params.get(state.step.degree()).unwrap(); + + let snark = gen_uncompressed_snark::>( + state.step.config_path(), + params, + state.step.pk(), + witness, + )?; + + let (proof, instances) = AggregationCircuit::gen_evm_proof_shplonk( + state.params.get(state.step_verifier.degree()).unwrap(), + state.step_verifier.pk(), + state.step_verifier.config_path(), + None, + &vec![snark.clone()], + ) + .map_err(JsonRpcError::internal)?; let mut instances = instances[0] .iter() @@ -197,29 +164,42 @@ pub(crate) async fn gen_evm_proof_sync_step_compressed_handler( } fn gen_uncompressed_snark( - config_path: PathBuf, - pk_path: PathBuf, + config_path: &Path, + params: &ParamsKZG, + pk: &ProvingKey, witness: Circuit::Witness, ) -> eyre::Result where Circuit::Witness: Default, { - let params = gen_srs(Circuit::get_degree(&config_path)); - - let app_pk = Circuit::read_pk(¶ms, pk_path, &config_path, &Circuit::Witness::default()); - Ok(Circuit::gen_snark_shplonk( - ¶ms, - &app_pk, + params, + pk, config_path, None::, &witness, )?) } -pub async fn run_rpc(port: usize) -> Result<(), eyre::Error> { +pub async fn run_rpc( + port: usize, + config_dir: impl AsRef, + build_dir: impl AsRef, +) -> Result<(), eyre::Error> +where + [(); S::SYNC_COMMITTEE_SIZE]:, + [(); S::FINALIZED_HEADER_DEPTH]:, + [(); S::BYTES_PER_LOGS_BLOOM]:, + [(); S::MAX_EXTRA_DATA_BYTES]:, + [(); S::SYNC_COMMITTEE_ROOT_INDEX]:, + [(); S::SYNC_COMMITTEE_DEPTH]:, + [(); S::FINALIZED_HEADER_INDEX]:, +{ let tcp_listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await?; - let rpc_server = Arc::new(jsonrpc_server()); + let rpc_server = Arc::new(jsonrpc_server::(ProverState::new::( + config_dir.as_ref(), + build_dir.as_ref(), + ))); let router = Router::new() .route("/rpc", post(handler)) diff --git a/prover/src/rpc_api.rs b/prover/src/rpc_api.rs index 3b927720..29ee7631 100644 --- a/prover/src/rpc_api.rs +++ b/prover/src/rpc_api.rs @@ -2,7 +2,6 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only -use crate::args; use primitive_types::U256; use serde::{Deserialize, Serialize}; @@ -12,8 +11,6 @@ pub const RPC_EVM_PROOF_COMMITTEE_UPDATE_CIRCUIT_COMPRESSED: &str = #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GenProofStepParams { - pub spec: args::Spec, - // Serializing as Vec so that we can differentiate between Mainnet, Testnet, Minimal at runtime pub light_client_finality_update: Vec, pub pubkeys: Vec, @@ -23,8 +20,6 @@ pub struct GenProofStepParams { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GenProofCommitteeUpdateParams { - pub spec: args::Spec, - // Serializing as Vec so that we can differentiate between Mainnet, Testnet, Minimal at runtime pub light_client_update: Vec, } diff --git a/prover/src/utils.rs b/prover/src/utils.rs index ba56ff59..9dabd3b2 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -2,7 +2,7 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only -use std::{env, ops::Deref, sync::Arc}; +use std::{ops::Deref, sync::Arc}; use beacon_api_client::{BlockId, VersionedValue}; use ethereum_consensus_types::LightClientBootstrap; From d089449ac158937e3820eda6d496e72bc1d44503 Mon Sep 17 00:00:00 2001 From: Timofey Luin Date: Fri, 5 Jan 2024 14:40:23 +0100 Subject: [PATCH 2/2] fix verifier circuits keys loading --- prover/src/prover.rs | 59 +++++++++++++++++++++++++++++++------------- prover/src/rpc.rs | 13 +++++----- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/prover/src/prover.rs b/prover/src/prover.rs index b338d7d9..03b016e6 100644 --- a/prover/src/prover.rs +++ b/prover/src/prover.rs @@ -13,6 +13,7 @@ use lightclient_circuits::halo2_proofs::{ }; use lightclient_circuits::sync_step_circuit::StepCircuit; use lightclient_circuits::util::AppCircuit; +use snark_verifier_sdk::halo2::aggregation::AggregationCircuit; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; @@ -44,14 +45,12 @@ impl ProverState { config_path: PathBuf, pk_path: PathBuf, params_map: &mut BTreeMap>, - ) -> CircuitContext - where - Circuit::Witness: Default, - { + default_witness: Circuit::Witness, + ) -> CircuitContext { let degree = Circuit::get_degree(&config_path); let params = gen_srs(degree); - let pk = Circuit::read_pk(¶ms, pk_path, &config_path, &Circuit::Witness::default()); + let pk = Circuit::read_pk(¶ms, pk_path, &config_path, &default_witness); params_map.insert(degree, params); @@ -62,26 +61,52 @@ impl ProverState { } } + let step = load_ctx::>( + config_dir.join(format!("sync_step_{}.json", S::NAME)), + build_dir.join(format!("sync_step_{}.pkey", S::NAME)), + &mut params_map, + Default::default(), + ); + + let step_snark = StepCircuit::::gen_snark_shplonk( + params_map.get(step.degree()).unwrap(), + step.pk(), + step.config_path(), + None::, + &Default::default(), + ) + .unwrap(); + + let committee_update = load_ctx::>( + config_dir.join(format!("committee_update_{}.json", S::NAME)), + build_dir.join(format!("committee_update_{}.pkey", S::NAME)), + &mut params_map, + Default::default(), + ); + + let committee_update_snark = CommitteeUpdateCircuit::::gen_snark_shplonk( + params_map.get(committee_update.degree()).unwrap(), + committee_update.pk(), + committee_update.config_path(), + None::, + &Default::default(), + ) + .unwrap(); + Self { - step: load_ctx::>( - config_dir.join(format!("sync_step_{}.json", S::NAME)), - build_dir.join(format!("sync_step_{}.pkey", S::NAME)), - &mut params_map, - ), - step_verifier: load_ctx::>( + step, + step_verifier: load_ctx::( config_dir.join(format!("sync_step_verifier_{}.json", S::NAME)), build_dir.join(format!("sync_step_verifier_{}.pkey", S::NAME)), &mut params_map, + vec![step_snark], ), - committee_update: load_ctx::>( - config_dir.join(format!("committee_update_{}.json", S::NAME)), - build_dir.join(format!("committee_update_{}.pkey", S::NAME)), - &mut params_map, - ), - committee_update_verifier: load_ctx::>( + committee_update, + committee_update_verifier: load_ctx::( config_dir.join(format!("committee_update_verifier_{}.json", S::NAME)), build_dir.join(format!("committee_update_verifier_{}.pkey", S::NAME)), &mut params_map, + vec![committee_update_snark], ), params: params_map, } diff --git a/prover/src/rpc.rs b/prover/src/rpc.rs index 190f1980..2ee8ae11 100644 --- a/prover/src/rpc.rs +++ b/prover/src/rpc.rs @@ -2,6 +2,7 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only +use ark_std::{end_timer, start_timer}; use axum::{http::StatusCode, response::IntoResponse, routing::post, Router}; use ethers::prelude::*; use itertools::Itertools; @@ -71,7 +72,7 @@ where let mut update = ssz_rs::deserialize(&light_client_update)?; let witness = rotation_args_from_update(&mut update).await?; let params = state.params.get(state.committee_update.degree()).unwrap(); - + let snark = gen_uncompressed_snark::>( state.committee_update.config_path(), params, @@ -131,7 +132,7 @@ where let pubkeys = ssz_rs::deserialize(&pubkeys)?; let witness = step_args_from_finality_update(update, pubkeys, domain).await?; let params = state.params.get(state.step.degree()).unwrap(); - + let snark = gen_uncompressed_snark::>( state.step.config_path(), params, @@ -196,10 +197,10 @@ where [(); S::FINALIZED_HEADER_INDEX]:, { let tcp_listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await?; - let rpc_server = Arc::new(jsonrpc_server::(ProverState::new::( - config_dir.as_ref(), - build_dir.as_ref(), - ))); + let timer = start_timer!(|| "Load proving keys"); + let state = ProverState::new::(config_dir.as_ref(), build_dir.as_ref()); + end_timer!(timer); + let rpc_server = Arc::new(jsonrpc_server::(state)); let router = Router::new() .route("/rpc", post(handler))