1use std::sync::Arc;
2
3use eyre::Result;
4use openvm_circuit::arch::{
5 instructions::{
6 exe::VmExe, instruction::Instruction, program::Program, LocalOpcode, SystemOpcode,
7 },
8 SystemConfig,
9};
10use openvm_continuations::{prover::engine_device_ctx, RootSC};
11use openvm_sdk_config::SdkVmBuilder;
12use openvm_stark_backend::{
13 keygen::types::MultiStarkProvingKey, prover::ProvingContext, StarkEngine, SystemParams,
14};
15use openvm_stark_sdk::config::{app_params_with_100_bits_security, MAX_APP_LOG_STACKED_HEIGHT};
16#[cfg(feature = "evm-prove")]
17use {
18 crate::{
19 prover::{vm::types::VmProvingKey, EvmProver, RootProver},
20 SC,
21 },
22 openvm_circuit::arch::{
23 Executor, MeteredExecutor, PreflightExecutor, VmBuilder, VmExecutionConfig,
24 },
25 openvm_stark_backend::{p3_field::PrimeField32, proof::Proof, Val},
26};
27
28use crate::{
29 config::{AggregationConfig, AggregationSystemParams, AggregationTreeConfig, AppConfig},
30 keygen::AppProvingKey,
31 prover::{AggProver, StarkProver},
32 DeferralSetup, StdIn, F,
33};
34
35type CpuRootE =
36 openvm_stark_sdk::config::baby_bear_bn254_poseidon2::BabyBearBn254Poseidon2CpuEngine;
37
38cfg_if::cfg_if! {
39 if #[cfg(feature = "cuda")] {
40 type ChildE = openvm_cuda_backend::BabyBearPoseidon2GpuEngine;
41 } else {
42 type ChildE = openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2CpuEngine;
43 }
44}
45
46fn dummy_terminate_exe() -> Arc<VmExe<F>> {
47 let dummy_program = Program::<F>::from_instructions(&[Instruction::from_isize(
48 SystemOpcode::TERMINATE.global_opcode(),
49 0,
50 0,
51 0,
52 0,
53 0,
54 )]);
55 Arc::new(VmExe::new(dummy_program))
56}
57
58pub(crate) fn compute_root_proof_heights(
59 system_config: SystemConfig,
60 agg_params: AggregationSystemParams,
61 agg_tree_config: AggregationTreeConfig,
62 root_params: SystemParams,
63 deferral_setup: DeferralSetup,
64) -> Result<(Vec<usize>, Arc<MultiStarkProvingKey<RootSC>>)> {
65 let dummy_exe = dummy_terminate_exe();
66
67 let memory_dimensions = system_config.memory_config.memory_dimensions();
68 let num_user_pvs = system_config.num_public_values;
69
70 let mut app_config = AppConfig::riscv32(app_params_with_100_bits_security(
71 MAX_APP_LOG_STACKED_HEIGHT,
72 ));
73 app_config.app_vm_config.system.config = system_config;
74
75 let def_hook_cached_commit = deferral_setup.hook_cached_commit();
76 let def_hook_commit = deferral_setup.hook_commit().map(Into::into);
77
78 let app_pk = AppProvingKey::keygen(app_config)?;
79
80 let agg_prover = Arc::new(AggProver::new(
81 Arc::new(app_pk.app_vm_pk.vm_pk.get_vk()),
82 AggregationConfig { params: agg_params },
83 agg_tree_config,
84 def_hook_cached_commit,
85 ));
86
87 let mut stark_prover = StarkProver::<ChildE, SdkVmBuilder>::new(
88 Default::default(),
89 &app_pk.app_vm_pk,
90 dummy_exe,
91 agg_prover.clone(),
92 deferral_setup,
93 )?;
94 stark_prover.set_program_name("root_keygen");
95 let (agg_proof, _) = stark_prover.prove(StdIn::default(), &[])?;
96
97 let root_prover = openvm_continuations::prover::RootCpuProver::new::<CpuRootE>(
98 agg_prover.internal_recursive_prover.get_vk(),
99 agg_prover
100 .internal_recursive_prover
101 .get_self_vk_pcs_data()
102 .unwrap()
103 .commitment
104 .into(),
105 root_params,
106 memory_dimensions,
107 num_user_pvs,
108 def_hook_commit,
109 None,
110 );
111 let engine = root_prover.create_engine::<CpuRootE>();
112 let root_proving_ctx: ProvingContext<<CpuRootE as StarkEngine>::PB> = root_prover
113 .generate_proving_ctx(
114 agg_proof.inner,
115 &agg_proof.user_pvs_proof,
116 agg_proof.deferral_merkle_proofs.as_ref(),
117 engine_device_ctx(&engine),
118 )
119 .unwrap();
120
121 let trace_heights = root_proving_ctx
122 .into_iter()
123 .map(|(_, air_ctx)| air_ctx.height())
124 .collect();
125 Ok((trace_heights, root_prover.get_pk()))
126}
127
128#[cfg(feature = "evm-prove")]
133pub fn generate_dummy_root_proof<E, VB>(
134 vm_builder: VB,
135 app_vm_pk: &VmProvingKey<VB::VmConfig>,
136 agg_prover: Arc<AggProver>,
137 deferral_setup: DeferralSetup,
138 root_prover: Arc<RootProver>,
139) -> Proof<RootSC>
140where
141 E: StarkEngine<SC = SC>,
142 VB: VmBuilder<E> + Clone,
143 Val<SC>: PrimeField32,
144 <VB::VmConfig as VmExecutionConfig<F>>::Executor:
145 Executor<F> + MeteredExecutor<F> + PreflightExecutor<F, VB::RecordArena>,
146{
147 let dummy_exe = dummy_terminate_exe();
148
149 let mut evm_prover = EvmProver::<E, _>::new(
150 vm_builder,
151 app_vm_pk,
152 dummy_exe,
153 agg_prover,
154 deferral_setup,
155 root_prover,
156 None,
157 )
158 .expect("Failed to create dummy EVM prover");
159 evm_prover.stark_prover.set_program_name("halo2_keygen");
160
161 evm_prover
162 .prove_root(StdIn::default(), &[])
163 .expect("Failed to generate dummy root proof")
164}