diff --git a/lightclient-circuits/src/aggregation_circuit.rs b/lightclient-circuits/src/aggregation_circuit.rs index 8a17bab..9d191a3 100644 --- a/lightclient-circuits/src/aggregation_circuit.rs +++ b/lightclient-circuits/src/aggregation_circuit.rs @@ -7,7 +7,7 @@ use halo2_base::{ gates::{circuit::CircuitBuilderStage, flex_gate::MultiPhaseThreadBreakPoints}, halo2_proofs::{ halo2curves::bn256::{Bn256, Fr}, - plonk::Error, + plonk::{Circuit, Error}, poly::{commitment::Params, kzg::commitment::ParamsKZG}, }, }; @@ -16,11 +16,7 @@ use snark_verifier_sdk::{ halo2::aggregation::{AggregationCircuit, AggregationConfigParams}, Snark, SHPLONK, }; -use std::{ - env::{set_var, var}, - fs::File, - path::Path, -}; +use std::{fs::File, path::Path}; /// Configuration for the aggregation circuit. #[derive(Clone, Debug, Default, Serialize, Deserialize)] @@ -43,39 +39,28 @@ impl AggregationConfigPinning { } impl Halo2ConfigPinning for AggregationConfigPinning { + type CircuitParams = AggregationConfigParams; type BreakPoints = MultiPhaseThreadBreakPoints; + fn new(params: Self::CircuitParams, break_points: Self::BreakPoints) -> Self { + Self { + params, + break_points, + } + } + fn from_path>(path: P) -> Self { - let pinning: Self = serde_json::from_reader( + serde_json::from_reader( File::open(&path) .unwrap_or_else(|e| panic!("{:?} does not exist: {e:?}", path.as_ref())), ) - .unwrap(); - pinning.set_var(); - pinning - } - - fn set_var(&self) { - set_var( - "AGG_CONFIG_PARAMS", - serde_json::to_string(&self.params).unwrap(), - ); - set_var("LOOKUP_BITS", (self.params.degree - 1).to_string()); + .unwrap() } fn break_points(self) -> MultiPhaseThreadBreakPoints { self.break_points } - fn from_var(break_points: MultiPhaseThreadBreakPoints) -> Self { - let params: AggregationConfigParams = - serde_json::from_str(&var("AGG_CONFIG_PARAMS").unwrap()).unwrap(); - Self { - params, - break_points, - } - } - fn degree(&self) -> u32 { self.params.degree } @@ -84,8 +69,8 @@ impl Halo2ConfigPinning for AggregationConfigPinning { impl PinnableCircuit for AggregationCircuit { type Pinning = AggregationConfigPinning; - fn break_points(&self) -> MultiPhaseThreadBreakPoints { - AggregationCircuit::break_points(self) + fn pinning(&self) -> Self::Pinning { + ::new(self.params(), self.break_points()) } } @@ -119,17 +104,9 @@ impl AppCircuit for AggregationCircuit { // We assume that `AggregationCircuit` will only be used for a single aggregation/compression layer. circuit.expose_previous_instances(false); - match stage { - CircuitBuilderStage::Prover => { - circuit.set_params(circuit_params); - circuit.set_break_points(pinning.map_or(vec![], |p| p.break_points)); - } - _ => { - set_var( - "AGG_CONFIG_PARAMS", - serde_json::to_string(&circuit.calculate_params(Some(10))).unwrap(), - ); - } + if matches!(stage, CircuitBuilderStage::Prover) { + circuit.set_params(circuit_params); + circuit.set_break_points(pinning.map_or(vec![], |p| p.break_points)); }; Ok(circuit) diff --git a/lightclient-circuits/src/gadget/crypto/builder.rs b/lightclient-circuits/src/gadget/crypto/builder.rs index c257c2c..09d52f7 100644 --- a/lightclient-circuits/src/gadget/crypto/builder.rs +++ b/lightclient-circuits/src/gadget/crypto/builder.rs @@ -2,9 +2,7 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only -use std::env::set_var; - -use crate::util::{CommonGateManager, Eth2ConfigPinning, GateBuilderConfig, PinnableCircuit}; +use crate::util::{CommonGateManager, Eth2ConfigPinning, GateBuilderConfig, Halo2ConfigPinning, PinnableCircuit}; use eth_types::Field; use getset::Getters; use halo2_base::{ @@ -168,12 +166,7 @@ impl> ShaCircuitBuilder) -> BaseCircuitParams { - let params = self.base.calculate_params(minimum_rows); - set_var( - "GATE_CONFIG_PARAMS", - serde_json::to_string(¶ms).unwrap(), - ); - params + self.base.calculate_params(minimum_rows) } pub fn sha_contexts_pair(&mut self) -> (&mut Context, GateManager::CustomContext<'_>) { @@ -280,7 +273,7 @@ where { type Pinning = Eth2ConfigPinning; - fn break_points(&self) -> MultiPhaseThreadBreakPoints { - self.base.break_points() + fn pinning(&self) -> Self::Pinning { + Eth2ConfigPinning::new(self.params(), self.base.break_points()) } } diff --git a/lightclient-circuits/src/util/circuit.rs b/lightclient-circuits/src/util/circuit.rs index 030cea3..1811442 100644 --- a/lightclient-circuits/src/util/circuit.rs +++ b/lightclient-circuits/src/util/circuit.rs @@ -2,7 +2,6 @@ // Code: https://github.com/ChainSafe/Spectre // SPDX-License-Identifier: LGPL-3.0-only -use std::env::{set_var, var}; use std::fs; use std::{fs::File, path::Path}; @@ -24,18 +23,32 @@ use snark_verifier_sdk::{gen_pk, halo2::gen_snark_shplonk, read_pk}; use snark_verifier_sdk::{CircuitExt, Snark}; /// Halo2 circuit configuration parameters. -pub trait Halo2ConfigPinning: Serialize { +pub trait Halo2ConfigPinning: Serialize + Sized + for<'de> Deserialize<'de> { + type CircuitParams; + type BreakPoints; - /// Loads configuration parameters from a file and sets environmental variables. - fn from_path>(path: P) -> Self; - /// Loads configuration parameters into environment variables. - fn set_var(&self); + + fn new(params: Self::CircuitParams, break_points: Self::BreakPoints) -> Self; /// Returns break points fn break_points(self) -> Self::BreakPoints; - /// Constructs `Self` from environmental variables and break points - fn from_var(break_points: Self::BreakPoints) -> Self; + /// Degree of the circuit, log_2(number of rows) fn degree(&self) -> u32; + + /// Loads configuration parameters from a file and sets environmental variables. + fn from_path>(path: P) -> Self { + serde_json::from_reader( + File::open(&path) + .unwrap_or_else(|e| panic!("{:?} does not exist: {e:?}", path.as_ref())), + ) + .unwrap() + } + + /// Writes to file + fn write>(&self, path: P) { + serde_json::to_writer_pretty(File::create(path).unwrap(), self) + .expect("failed to serialize to file"); + } } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -45,39 +58,20 @@ pub struct Eth2ConfigPinning { } impl Halo2ConfigPinning for Eth2ConfigPinning { + type CircuitParams = BaseCircuitParams; type BreakPoints = MultiPhaseThreadBreakPoints; - fn from_path>(path: P) -> Self { - let pinning: Self = serde_json::from_reader( - File::open(&path) - .unwrap_or_else(|e| panic!("{:?} does not exist: {e:?}", path.as_ref())), - ) - .unwrap(); - pinning.set_var(); - pinning - } - - fn set_var(&self) { - set_var( - "GATE_CONFIG_PARAMS", - serde_json::to_string(&self.params).unwrap(), - ); - set_var("LOOKUP_BITS", (self.params.k - 1).to_string()); - } - - fn break_points(self) -> MultiPhaseThreadBreakPoints { - self.break_points - } - - fn from_var(break_points: MultiPhaseThreadBreakPoints) -> Self { - let params: BaseCircuitParams = - serde_json::from_str(&var("GATE_CONFIG_PARAMS").unwrap()).unwrap(); + fn new(params: Self::CircuitParams, break_points: Self::BreakPoints) -> Self { Self { params, break_points, } } + fn break_points(self) -> MultiPhaseThreadBreakPoints { + self.break_points + } + fn degree(&self) -> u32 { self.params.k as u32 } @@ -86,13 +80,7 @@ impl Halo2ConfigPinning for Eth2ConfigPinning { pub trait PinnableCircuit: CircuitExt { type Pinning: Halo2ConfigPinning; - fn break_points(&self) -> ::BreakPoints; - - fn write_pinning(&self, path: impl AsRef) { - let break_points = self.break_points(); - let pinning: Self::Pinning = Halo2ConfigPinning::from_var(break_points); - serde_json::to_writer_pretty(File::create(path).unwrap(), &pinning).unwrap(); - } + fn pinning(&self) -> Self::Pinning; } pub trait AppCircuit { @@ -143,7 +131,7 @@ pub trait AppCircuit { let pk = gen_pk(params, &circuit, Some(pk_path.as_ref())); if !pk_exists { // should only write pinning data if we created a new pkey - circuit.write_pinning(pinning_path); + circuit.pinning().write(pinning_path); } pk }