use std::sync::{atomic::AtomicBool, Arc};
use evm_arithmetization::{AllStark, GenerationInputs, StarkConfig};
use plonky2::{
gates::noop::NoopGate,
iop::witness::PartialWitness,
plonk::{circuit_builder::CircuitBuilder, circuit_data::CircuitConfig},
util::timing::TimingTree,
};
use crate::{
proof_types::{
AggregatableBlockProof, AggregatableProof, GeneratedAggBlockProof, GeneratedAggProof,
GeneratedBlockProof, GeneratedTxnProof,
},
prover_state::ProverState,
types::{Config, Field, PlonkyProofIntern, EXTENSION_DEGREE},
};
pub type ProofGenResult<T> = Result<T, ProofGenError>;
#[derive(Debug)]
pub struct ProofGenError(pub String);
impl std::fmt::Display for ProofGenError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:#?}", self.0)
}
}
impl std::error::Error for ProofGenError {}
impl From<String> for ProofGenError {
fn from(v: String) -> Self {
Self(v)
}
}
pub fn generate_txn_proof(
p_state: &ProverState,
gen_inputs: GenerationInputs,
abort_signal: Option<Arc<AtomicBool>>,
) -> ProofGenResult<GeneratedTxnProof> {
let (intern, p_vals) = p_state
.state
.prove_root(
&AllStark::default(),
&StarkConfig::standard_fast_config(),
gen_inputs,
&mut TimingTree::default(),
abort_signal,
)
.map_err(|err| err.to_string())?;
Ok(GeneratedTxnProof { p_vals, intern })
}
pub fn generate_agg_proof(
p_state: &ProverState,
lhs_child: &AggregatableProof,
rhs_child: &AggregatableProof,
) -> ProofGenResult<GeneratedAggProof> {
let (intern, p_vals) = p_state
.state
.prove_aggregation(
lhs_child.is_agg(),
lhs_child.intern(),
lhs_child.public_values(),
rhs_child.is_agg(),
rhs_child.intern(),
rhs_child.public_values(),
)
.map_err(|err| err.to_string())?;
Ok(GeneratedAggProof { p_vals, intern })
}
pub fn generate_block_proof(
p_state: &ProverState,
prev_opt_parent_b_proof: Option<&GeneratedBlockProof>,
curr_block_agg_proof: &GeneratedAggProof,
) -> ProofGenResult<GeneratedBlockProof> {
let b_height = curr_block_agg_proof
.p_vals
.block_metadata
.block_number
.low_u64();
let parent_intern = prev_opt_parent_b_proof.map(|p| &p.intern);
let (b_proof_intern, _) = p_state
.state
.prove_block(
parent_intern,
&curr_block_agg_proof.intern,
curr_block_agg_proof.p_vals.clone(),
)
.map_err(|err| err.to_string())?;
Ok(GeneratedBlockProof {
b_height,
intern: b_proof_intern,
})
}
pub fn generate_agg_block_proof(
p_state: &ProverState,
lhs_child: &AggregatableBlockProof,
rhs_child: &AggregatableBlockProof,
) -> ProofGenResult<GeneratedAggBlockProof> {
let intern = p_state
.state
.prove_two_to_one_block(
lhs_child.intern(),
lhs_child.is_agg(),
rhs_child.intern(),
rhs_child.is_agg(),
)
.map_err(|err| err.to_string())?;
Ok(GeneratedAggBlockProof { intern })
}
pub fn dummy_proof() -> ProofGenResult<PlonkyProofIntern> {
let mut builder = CircuitBuilder::<Field, EXTENSION_DEGREE>::new(CircuitConfig::default());
builder.add_gate(NoopGate, vec![]);
let circuit_data = builder.build::<_>();
let inputs = PartialWitness::new();
plonky2::plonk::prover::prove::<Field, Config, EXTENSION_DEGREE>(
&circuit_data.prover_only,
&circuit_data.common,
inputs,
&mut TimingTree::default(),
)
.map_err(|e| ProofGenError(e.to_string()))
}