Skip to content

Commit 24c2cf3

Browse files
feat(sdk)!: configurable aggregation tree shape in SDK (#1570)
Introduce `AggregationTreeConfig` struct for simple configuration of aggregation tree. These were already in the provers, but not exposed to be changeable. Breaking API changes in SDK: - `AggStarkProver::new` - `ContinuationProver::new` - `Sdk` now internally contains `AggregationTreeConfig`, although `Sdk::new()` is unchanged and just sets a default Towards INT-3302
1 parent e827799 commit 24c2cf3

File tree

10 files changed

+93
-30
lines changed

10 files changed

+93
-30
lines changed

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/prove/src/bin/fib_e2e.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ async fn main() -> Result<()> {
6363
app_pk,
6464
app_committed_exe,
6565
full_agg_pk,
66+
args.agg_tree_config,
6667
);
6768
e2e_prover.set_program_name("fib_e2e");
6869
let _proof = e2e_prover.generate_proof_for_evm(stdin);

benchmarks/prove/src/bin/kitchen_sink.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ fn main() -> Result<()> {
8585
app_pk,
8686
app_committed_exe,
8787
full_agg_pk,
88+
args.agg_tree_config,
8889
);
8990
prover.set_program_name("kitchen_sink");
9091
let stdin = StdIn::default();

benchmarks/prove/src/util.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ use openvm_native_compiler::conversion::CompilerOptions;
99
use openvm_sdk::{
1010
commit::commit_app_exe,
1111
config::{
12-
AggConfig, AggStarkConfig, AppConfig, Halo2Config, DEFAULT_APP_LOG_BLOWUP,
13-
DEFAULT_INTERNAL_LOG_BLOWUP, DEFAULT_LEAF_LOG_BLOWUP, DEFAULT_ROOT_LOG_BLOWUP,
12+
AggConfig, AggStarkConfig, AggregationTreeConfig, AppConfig, Halo2Config,
13+
DEFAULT_APP_LOG_BLOWUP, DEFAULT_INTERNAL_LOG_BLOWUP, DEFAULT_LEAF_LOG_BLOWUP,
14+
DEFAULT_ROOT_LOG_BLOWUP,
1415
},
1516
keygen::{leaf_keygen, AppProvingKey},
16-
prover::{
17-
vm::local::VmLocalProver, AppProver, LeafProvingController, DEFAULT_NUM_CHILDREN_LEAF,
18-
},
17+
prover::{vm::local::VmLocalProver, AppProver, LeafProvingController},
1918
Sdk, StdIn,
2019
};
2120
use openvm_stark_backend::utils::metrics_span;
@@ -66,6 +65,10 @@ pub struct BenchmarkCli {
6665
#[arg(short, long, alias = "max_segment_length")]
6766
pub max_segment_length: Option<usize>,
6867

68+
/// Controls the arity (num_children) of the aggregation tree
69+
#[command(flatten)]
70+
pub agg_tree_config: AggregationTreeConfig,
71+
6972
/// Whether to execute with additional profiling metric collection
7073
#[arg(long)]
7174
pub profiling: bool,
@@ -219,7 +222,7 @@ where
219222
let leaf_prover =
220223
VmLocalProver::<SC, NativeConfig, E>::new(leaf_vm_pk, app_pk.leaf_committed_exe);
221224
let leaf_controller = LeafProvingController {
222-
num_children: DEFAULT_NUM_CHILDREN_LEAF,
225+
num_children: AggregationTreeConfig::default().num_children_leaf,
223226
};
224227
leaf_controller.generate_proof(&leaf_prover, &app_proof);
225228
}

crates/cli/src/commands/prove.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use eyre::Result;
55
use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
66
use openvm_sdk::{
77
commit::AppExecutionCommit,
8-
config::SdkVmConfig,
8+
config::{AggregationTreeConfig, SdkVmConfig},
99
fs::{
1010
read_agg_pk_from_file, read_app_pk_from_file, read_exe_from_file, write_app_proof_to_file,
1111
write_evm_proof_to_file,
@@ -56,12 +56,15 @@ enum ProveSubCommand {
5656

5757
#[arg(long, action, help = "Path to output proof", default_value = DEFAULT_EVM_PROOF_PATH)]
5858
output: PathBuf,
59+
60+
#[command(flatten)]
61+
agg_tree_config: AggregationTreeConfig,
5962
},
6063
}
6164

6265
impl ProveCmd {
6366
pub fn run(&self) -> Result<()> {
64-
let sdk = Sdk::new();
67+
let mut sdk = Sdk::new();
6568
match &self.command {
6669
ProveSubCommand::App {
6770
app_pk,
@@ -79,7 +82,9 @@ impl ProveCmd {
7982
exe,
8083
input,
8184
output,
85+
agg_tree_config,
8286
} => {
87+
sdk.set_agg_tree_config(*agg_tree_config);
8388
let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
8489
let (app_pk, committed_exe, input) =
8590
Self::prepare_execution(&sdk, app_pk, exe, input)?;

crates/sdk/src/config/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use clap::Args;
12
use openvm_circuit::arch::instructions::program::DEFAULT_MAX_NUM_PUBLIC_VALUES;
23
use openvm_continuations::verifier::{
34
common::types::VmVerifierPvs, internal::types::InternalVmVerifierPvs,
@@ -15,6 +16,11 @@ pub const DEFAULT_LEAF_LOG_BLOWUP: usize = 1;
1516
pub const DEFAULT_INTERNAL_LOG_BLOWUP: usize = 2;
1617
pub const DEFAULT_ROOT_LOG_BLOWUP: usize = 3;
1718

19+
// Aggregation Tree Defaults
20+
const DEFAULT_NUM_CHILDREN_LEAF: usize = 1;
21+
const DEFAULT_NUM_CHILDREN_INTERNAL: usize = 4;
22+
const DEFAULT_MAX_INTERNAL_WRAPPER_LAYERS: usize = 4;
23+
1824
#[derive(Clone, Debug, Serialize, Deserialize)]
1925
pub struct AppConfig<VC> {
2026
#[serde(default)]
@@ -59,6 +65,23 @@ pub struct Halo2Config {
5965
pub profiling: bool,
6066
}
6167

68+
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Args)]
69+
pub struct AggregationTreeConfig {
70+
/// Each leaf verifier circuit will aggregate this many App VM proofs.
71+
#[arg(long, default_value_t = DEFAULT_NUM_CHILDREN_LEAF)]
72+
pub num_children_leaf: usize,
73+
/// Each internal verifier circuit will aggregate this many proofs,
74+
/// where each proof may be of either leaf or internal verifier (self) circuit.
75+
#[arg(long, default_value_t = DEFAULT_NUM_CHILDREN_INTERNAL)]
76+
pub num_children_internal: usize,
77+
/// Safety threshold: how many times to do 1-to-1 aggregation of the "last" internal
78+
/// verifier proof before it is small enough for the root verifier circuit.
79+
/// Note: almost always no wrapping is needed.
80+
#[arg(long, default_value_t = DEFAULT_MAX_INTERNAL_WRAPPER_LAYERS)]
81+
pub max_internal_wrapper_layers: usize,
82+
// root currently always has 1 child for now
83+
}
84+
6285
impl<VC> AppConfig<VC> {
6386
pub fn new(app_fri_params: FriParameters, app_vm_config: VC) -> Self {
6487
Self {
@@ -187,3 +210,13 @@ impl AggStarkConfig {
187210
config
188211
}
189212
}
213+
214+
impl Default for AggregationTreeConfig {
215+
fn default() -> Self {
216+
Self {
217+
num_children_leaf: DEFAULT_NUM_CHILDREN_LEAF,
218+
num_children_internal: DEFAULT_NUM_CHILDREN_INTERNAL,
219+
max_internal_wrapper_layers: DEFAULT_MAX_INTERNAL_WRAPPER_LAYERS,
220+
}
221+
}
222+
}

crates/sdk/src/lib.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::{
1010
use alloy_primitives::{Bytes, FixedBytes};
1111
use alloy_sol_types::{sol, SolCall, SolValue};
1212
use commit::commit_app_exe;
13-
use config::AppConfig;
13+
use config::{AggregationTreeConfig, AppConfig};
1414
use eyre::{Context, Result};
1515
use keygen::{AppProvingKey, AppVerifyingKey};
1616
use openvm_build::{
@@ -101,12 +101,14 @@ pub struct VerifiedContinuationVmPayload {
101101
}
102102

103103
pub struct GenericSdk<E: StarkFriEngine<SC>> {
104+
agg_tree_config: AggregationTreeConfig,
104105
_phantom: PhantomData<E>,
105106
}
106107

107108
impl<E: StarkFriEngine<SC>> Default for GenericSdk<E> {
108109
fn default() -> Self {
109110
Self {
111+
agg_tree_config: AggregationTreeConfig::default(),
110112
_phantom: PhantomData,
111113
}
112114
}
@@ -119,6 +121,14 @@ impl<E: StarkFriEngine<SC>> GenericSdk<E> {
119121
Self::default()
120122
}
121123

124+
pub fn agg_tree_config(&self) -> &AggregationTreeConfig {
125+
&self.agg_tree_config
126+
}
127+
128+
pub fn set_agg_tree_config(&mut self, agg_tree_config: AggregationTreeConfig) {
129+
self.agg_tree_config = agg_tree_config;
130+
}
131+
122132
pub fn build<P: AsRef<Path>>(
123133
&self,
124134
guest_opts: GuestOptions,
@@ -264,7 +274,8 @@ impl<E: StarkFriEngine<SC>> GenericSdk<E> {
264274
VC::Executor: Chip<SC>,
265275
VC::Periphery: Chip<SC>,
266276
{
267-
let stark_prover = StarkProver::<VC, E>::new(app_pk, app_exe, agg_stark_pk);
277+
let stark_prover =
278+
StarkProver::<VC, E>::new(app_pk, app_exe, agg_stark_pk, self.agg_tree_config);
268279
let proof = stark_prover.generate_root_verifier_input(inputs);
269280
Ok(proof)
270281
}
@@ -281,7 +292,8 @@ impl<E: StarkFriEngine<SC>> GenericSdk<E> {
281292
VC::Executor: Chip<SC>,
282293
VC::Periphery: Chip<SC>,
283294
{
284-
let e2e_prover = ContinuationProver::<VC, E>::new(reader, app_pk, app_exe, agg_pk);
295+
let e2e_prover =
296+
ContinuationProver::<VC, E>::new(reader, app_pk, app_exe, agg_pk, self.agg_tree_config);
285297
let proof = e2e_prover.generate_proof_for_evm(inputs);
286298
Ok(proof)
287299
}

crates/sdk/src/prover/agg.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use openvm_stark_sdk::{engine::StarkFriEngine, openvm_stark_backend::proof::Proo
1111
use tracing::info_span;
1212

1313
use crate::{
14+
config::AggregationTreeConfig,
1415
keygen::AggStarkProvingKey,
1516
prover::{
1617
vm::{local::VmLocalProver, SingleSegmentVmProver},
@@ -19,10 +20,6 @@ use crate::{
1920
NonRootCommittedExe, RootSC, F, SC,
2021
};
2122

22-
pub const DEFAULT_NUM_CHILDREN_LEAF: usize = 1;
23-
const DEFAULT_NUM_CHILDREN_INTERNAL: usize = 2;
24-
const DEFAULT_MAX_INTERNAL_WRAPPER_LAYERS: usize = 4;
25-
2623
pub struct AggStarkProver<E: StarkFriEngine<SC>> {
2724
leaf_prover: VmLocalProver<SC, NativeConfig, E>,
2825
leaf_controller: LeafProvingController,
@@ -43,11 +40,12 @@ impl<E: StarkFriEngine<SC>> AggStarkProver<E> {
4340
pub fn new(
4441
agg_stark_pk: AggStarkProvingKey,
4542
leaf_committed_exe: Arc<NonRootCommittedExe>,
43+
tree_config: AggregationTreeConfig,
4644
) -> Self {
4745
let leaf_prover =
4846
VmLocalProver::<SC, NativeConfig, E>::new(agg_stark_pk.leaf_vm_pk, leaf_committed_exe);
4947
let leaf_controller = LeafProvingController {
50-
num_children: DEFAULT_NUM_CHILDREN_LEAF,
48+
num_children: tree_config.num_children_leaf,
5149
};
5250
let internal_prover = VmLocalProver::<SC, NativeConfig, E>::new(
5351
agg_stark_pk.internal_vm_pk,
@@ -59,8 +57,8 @@ impl<E: StarkFriEngine<SC>> AggStarkProver<E> {
5957
leaf_controller,
6058
internal_prover,
6159
root_prover,
62-
num_children_internal: DEFAULT_NUM_CHILDREN_INTERNAL,
63-
max_internal_wrapper_layers: DEFAULT_MAX_INTERNAL_WRAPPER_LAYERS,
60+
num_children_internal: tree_config.num_children_internal,
61+
max_internal_wrapper_layers: tree_config.max_internal_wrapper_layers,
6462
}
6563
}
6664

crates/sdk/src/prover/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::sync::Arc;
33
use openvm_circuit::arch::VmConfig;
44
use openvm_stark_sdk::{engine::StarkFriEngine, openvm_stark_backend::Chip};
55

6-
use crate::{keygen::AppProvingKey, stdin::StdIn, NonRootCommittedExe, F, SC};
6+
use crate::{
7+
config::AggregationTreeConfig, keygen::AppProvingKey, stdin::StdIn, NonRootCommittedExe, F, SC,
8+
};
79

810
mod agg;
911
pub use agg::*;
@@ -25,8 +27,8 @@ pub use stark::*;
2527
use crate::{keygen::AggProvingKey, prover::halo2::Halo2Prover, types::EvmProof};
2628

2729
pub struct ContinuationProver<VC, E: StarkFriEngine<SC>> {
28-
stark_prover: StarkProver<VC, E>,
29-
halo2_prover: Halo2Prover,
30+
pub stark_prover: StarkProver<VC, E>,
31+
pub halo2_prover: Halo2Prover,
3032
}
3133

3234
impl<VC, E: StarkFriEngine<SC>> ContinuationProver<VC, E> {
@@ -35,6 +37,7 @@ impl<VC, E: StarkFriEngine<SC>> ContinuationProver<VC, E> {
3537
app_pk: Arc<AppProvingKey<VC>>,
3638
app_committed_exe: Arc<NonRootCommittedExe>,
3739
agg_pk: AggProvingKey,
40+
agg_tree_config: AggregationTreeConfig,
3841
) -> Self
3942
where
4043
VC: VmConfig<F>,
@@ -43,7 +46,8 @@ impl<VC, E: StarkFriEngine<SC>> ContinuationProver<VC, E> {
4346
agg_stark_pk,
4447
halo2_pk,
4548
} = agg_pk;
46-
let stark_prover = StarkProver::new(app_pk, app_committed_exe, agg_stark_pk);
49+
let stark_prover =
50+
StarkProver::new(app_pk, app_committed_exe, agg_stark_pk, agg_tree_config);
4751
Self {
4852
stark_prover,
4953
halo2_prover: Halo2Prover::new(reader, halo2_pk),

crates/sdk/src/prover/stark.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,22 @@ use openvm_stark_backend::{proof::Proof, Chip};
66
use openvm_stark_sdk::engine::StarkFriEngine;
77

88
use crate::{
9+
config::AggregationTreeConfig,
910
keygen::{AggStarkProvingKey, AppProvingKey},
1011
prover::{agg::AggStarkProver, app::AppProver},
1112
NonRootCommittedExe, RootSC, StdIn, F, SC,
1213
};
1314

1415
pub struct StarkProver<VC, E: StarkFriEngine<SC>> {
15-
app_prover: AppProver<VC, E>,
16-
agg_prover: AggStarkProver<E>,
16+
pub app_prover: AppProver<VC, E>,
17+
pub agg_prover: AggStarkProver<E>,
1718
}
1819
impl<VC, E: StarkFriEngine<SC>> StarkProver<VC, E> {
1920
pub fn new(
2021
app_pk: Arc<AppProvingKey<VC>>,
2122
app_committed_exe: Arc<NonRootCommittedExe>,
2223
agg_stark_pk: AggStarkProvingKey,
24+
agg_tree_config: AggregationTreeConfig,
2325
) -> Self
2426
where
2527
VC: VmConfig<F>,
@@ -36,7 +38,11 @@ impl<VC, E: StarkFriEngine<SC>> StarkProver<VC, E> {
3638

3739
Self {
3840
app_prover: AppProver::new(app_pk.app_vm_pk.clone(), app_committed_exe),
39-
agg_prover: AggStarkProver::new(agg_stark_pk, app_pk.leaf_committed_exe.clone()),
41+
agg_prover: AggStarkProver::new(
42+
agg_stark_pk,
43+
app_pk.leaf_committed_exe.clone(),
44+
agg_tree_config,
45+
),
4046
}
4147
}
4248
pub fn set_program_name(&mut self, program_name: impl AsRef<str>) -> &mut Self {

0 commit comments

Comments
 (0)