use std::{cmp::Reverse, sync::Arc};
use derivative::Derivative;
use crate::{
keygen::types::{
LinearConstraint, MultiStarkVerifyingKey, MultiStarkVerifyingKey0, StarkVerifyingKey,
},
proof::TraceVData,
prover::{MatrixDimensions, ProverBackend},
StarkProtocolConfig, SystemParams,
};
#[derive(Derivative)]
#[derivative(Clone(bound = "PB::Matrix: Clone"))]
pub struct CommittedTraceData<PB: ProverBackend> {
pub commitment: PB::Commitment,
pub trace: PB::Matrix,
pub data: Arc<PB::PcsData>,
}
#[derive(derive_new::new)]
pub struct DeviceMultiStarkProvingKey<PB: ProverBackend> {
pub per_air: Vec<DeviceStarkProvingKey<PB>>,
pub trace_height_constraints: Vec<LinearConstraint>,
pub max_constraint_degree: usize,
pub params: SystemParams,
pub vk_pre_hash: PB::Commitment,
}
pub struct DeviceStarkProvingKey<PB: ProverBackend> {
pub air_name: String,
pub vk: StarkVerifyingKey<PB::Val, PB::Commitment>,
pub preprocessed_data: Option<CommittedTraceData<PB>>,
pub other_data: PB::OtherAirData,
}
#[derive(derive_new::new)]
pub struct ProvingContext<PB: ProverBackend> {
pub per_trace: Vec<(usize, AirProvingContext<PB>)>,
}
#[derive(derive_new::new)]
pub struct AirProvingContext<PB: ProverBackend> {
pub cached_mains: Vec<CommittedTraceData<PB>>,
pub common_main: PB::Matrix,
pub public_values: Vec<PB::Val>,
}
pub struct HostProof<SC: StarkProtocolConfig, PB: ProverBackend, ConstraintsProof, OpeningProof> {
pub common_main_commit: PB::Commitment,
pub trace_vdata: Vec<Option<TraceVData<SC>>>,
pub public_values: Vec<Vec<PB::Val>>,
pub constraints_proof: ConstraintsProof,
pub opening_proof: OpeningProof,
}
impl<PB: ProverBackend> CommittedTraceData<PB> {
#[inline(always)]
pub fn height(&self) -> usize {
self.trace.height()
}
}
impl<PB: ProverBackend> DeviceMultiStarkProvingKey<PB> {
pub fn get_vk<SC>(&self) -> MultiStarkVerifyingKey<SC>
where
SC: StarkProtocolConfig<F = PB::Val, Digest = PB::Commitment>,
{
let per_air = self.per_air.iter().map(|pk| pk.vk.clone()).collect();
let inner = MultiStarkVerifyingKey0 {
params: self.params.clone(),
per_air,
trace_height_constraints: self.trace_height_constraints.clone(),
};
MultiStarkVerifyingKey {
inner,
pre_hash: self.vk_pre_hash.clone(),
}
}
}
impl<PB: ProverBackend> IntoIterator for ProvingContext<PB> {
type Item = (usize, AirProvingContext<PB>);
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.per_trace.into_iter()
}
}
impl<PB: ProverBackend> ProvingContext<PB> {
pub fn common_main_traces(&self) -> impl Iterator<Item = (usize, &PB::Matrix)> {
self.per_trace
.iter()
.map(|(air_idx, trace_ctx)| (*air_idx, &trace_ctx.common_main))
}
pub fn into_sorted(mut self) -> Self {
self.sort_for_stacking();
self
}
pub fn sort_for_stacking(&mut self) {
self.per_trace.sort_by_key(|(air_idx, trace_ctx)| {
(Reverse(trace_ctx.common_main.height()), *air_idx)
});
}
}
impl<PB: ProverBackend> AirProvingContext<PB> {
pub fn simple(common_main_trace: PB::Matrix, public_values: Vec<PB::Val>) -> Self {
Self::new(vec![], common_main_trace, public_values)
}
pub fn simple_no_pis(common_main_trace: PB::Matrix) -> Self {
Self::simple(common_main_trace, vec![])
}
pub fn height(&self) -> usize {
self.common_main.height()
}
}