use crate::Field;
use crate::{rlc::circuit::builder::RlcCircuitBuilder, utils::build_utils::dummy::DummyFrom};
use getset::Getters;
use halo2_base::{
halo2_proofs::{circuit::Layouter, plonk::ConstraintSystem},
AssignedValue,
};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use super::{
promise_collector::{
PromiseCaller, PromiseCallsGetter, PromiseCommitSetter, PromiseResultsGetter,
},
promise_loader::comp_loader::SingleComponentLoaderParams,
types::FixLenLogical,
ComponentType, ComponentTypeId, FlattenVirtualTable, LogicalResult,
};
mod comp_circuit_impl;
pub use comp_circuit_impl::ComponentCircuitImpl;
pub trait ComponentBuilder<F: Field> {
type Config: Clone = ();
type Params: Clone + Default = ();
fn new(params: Self::Params) -> Self;
fn get_params(&self) -> Self::Params;
fn clear_witnesses(&mut self) {}
fn configure_with_params(meta: &mut ConstraintSystem<F>, params: Self::Params) -> Self::Config;
fn calculate_params(&mut self) -> Self::Params;
}
pub trait CoreBuilderParams {
fn get_output_params(&self) -> CoreBuilderOutputParams;
}
#[derive(Clone, Default, Getters)]
pub struct CoreBuilderOutputParams {
#[getset(get = "pub")]
cap_per_shard: Vec<usize>,
}
impl CoreBuilderOutputParams {
pub fn new(cap_per_shard: Vec<usize>) -> Self {
assert!(cap_per_shard.is_empty() || cap_per_shard.len().is_power_of_two());
Self { cap_per_shard }
}
}
impl CoreBuilderParams for CoreBuilderOutputParams {
fn get_output_params(&self) -> CoreBuilderOutputParams {
self.clone()
}
}
pub trait CoreBuilderInput<F: Field> = Serialize + DeserializeOwned + Clone + 'static;
pub struct CoreBuilderOutput<F: Field, T: ComponentType<F>> {
pub public_instances: Vec<AssignedValue<F>>,
pub virtual_table: FlattenVirtualTable<AssignedValue<F>>,
pub logical_results: Vec<LogicalResult<F, T>>,
}
pub trait CoreBuilder<F: Field>: ComponentBuilder<F, Params: CoreBuilderParams> {
type CompType: ComponentType<F>;
type PublicInstanceValue: FixLenLogical<F>;
type PublicInstanceWitness: FixLenLogical<AssignedValue<F>>;
type CoreInput: CoreBuilderInput<F> + DummyFrom<Self::Params>;
fn feed_input(&mut self, input: Self::CoreInput) -> anyhow::Result<()>;
fn virtual_assign_phase0(
&mut self,
builder: &mut RlcCircuitBuilder<F>,
promise_caller: PromiseCaller<F>,
) -> CoreBuilderOutput<F, Self::CompType>;
#[allow(unused_variables)]
fn raw_synthesize_phase0(&mut self, config: &Self::Config, layouter: &mut impl Layouter<F>) {}
#[allow(unused_variables)]
fn virtual_assign_phase1(&mut self, builder: &mut RlcCircuitBuilder<F>) {}
#[allow(unused_variables)]
fn raw_synthesize_phase1(&mut self, config: &Self::Config, layouter: &mut impl Layouter<F>) {}
}
#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
pub struct LoaderParamsPerComponentType {
pub component_type_id: ComponentTypeId,
pub loader_params: SingleComponentLoaderParams,
}
pub trait PromiseBuilder<F: Field>: ComponentBuilder<F> {
fn get_component_type_dependencies() -> Vec<ComponentTypeId>;
fn extract_loader_params_per_component_type(
params: &Self::Params,
) -> Vec<LoaderParamsPerComponentType>;
fn fulfill_promise_results(&mut self, promise_results_getter: &impl PromiseResultsGetter<F>);
fn virtual_assign_phase0(
&mut self,
builder: &mut RlcCircuitBuilder<F>,
promise_commit_setter: &mut impl PromiseCommitSetter<F>,
);
fn raw_synthesize_phase0(&mut self, config: &Self::Config, layouter: &mut impl Layouter<F>);
fn virtual_assign_phase1(
&mut self,
builder: &mut RlcCircuitBuilder<F>,
promise_calls_getter: &mut impl PromiseCallsGetter<F>,
);
fn raw_synthesize_phase1(&mut self, config: &Self::Config, layouter: &mut impl Layouter<F>);
}