-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add faster STARK configuration for testing purposes #739
Changes from 11 commits
552df72
7193a46
25f0269
6eb7c9c
42d3715
acb6eac
15db9c3
b150ade
398bf4d
d098b24
ba64f01
5ef571a
d6be107
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,6 @@ use hashbrown::HashMap; | |
use itertools::{zip_eq, Itertools}; | ||
use mpt_trie::partial_trie::{HashedPartialTrie, Node, PartialTrie}; | ||
use plonky2::field::extension::Extendable; | ||
use plonky2::fri::FriParams; | ||
use plonky2::gates::constant::ConstantGate; | ||
use plonky2::gates::noop::NoopGate; | ||
use plonky2::hash::hash_types::{MerkleCapTarget, RichField, NUM_HASH_OUT_ELTS}; | ||
|
@@ -57,6 +56,7 @@ use crate::recursive_verifier::{ | |
recursive_stark_circuit, set_final_public_value_targets, set_public_value_targets, | ||
PlonkWrapperCircuit, PublicInputs, StarkWrapperCircuit, | ||
}; | ||
use crate::testing_utils::TWO_TO_ONE_BLOCK_CIRCUIT_TEST_THRESHOLD_DEGREE_BITS; | ||
use crate::util::h256_limbs; | ||
use crate::verifier::initial_memory_merkle_cap; | ||
|
||
|
@@ -786,10 +786,19 @@ where | |
all_stark: &AllStark<F, D>, | ||
degree_bits_ranges: &[Range<usize>; NUM_TABLES], | ||
stark_config: &StarkConfig, | ||
shrinking_circuit_config: Option<&CircuitConfig>, | ||
recursion_circuit_config: Option<&CircuitConfig>, | ||
threshold_degree_bits: Option<usize>, | ||
) -> Self { | ||
// Sanity check on the provided config | ||
assert_eq!(DEFAULT_CAP_LEN, 1 << stark_config.fri_config.cap_height); | ||
|
||
let shrinking_config = shrinking_config(); | ||
let shrinking_circuit_config = shrinking_circuit_config.unwrap_or(&shrinking_config); | ||
let circuit_config = CircuitConfig::standard_recursion_config(); | ||
let recursion_circuit_config = recursion_circuit_config.unwrap_or(&circuit_config); | ||
let threshold_degree_bits = threshold_degree_bits.unwrap_or(THRESHOLD_DEGREE_BITS); | ||
|
||
macro_rules! create_recursive_circuit { | ||
($table_enum:expr, $stark_field:ident) => { | ||
RecursiveCircuitsForTable::new( | ||
|
@@ -798,6 +807,8 @@ where | |
degree_bits_ranges[*$table_enum].clone(), | ||
&all_stark.cross_table_lookups, | ||
stark_config, | ||
shrinking_circuit_config, | ||
threshold_degree_bits, | ||
) | ||
}; | ||
} | ||
|
@@ -829,7 +840,7 @@ where | |
poseidon, | ||
]; | ||
|
||
let root = Self::create_segment_circuit(&by_table, stark_config); | ||
let root = Self::create_segment_circuit(&by_table, stark_config, recursion_circuit_config); | ||
let segment_aggregation = Self::create_segment_aggregation_circuit(&root); | ||
let batch_aggregation = | ||
Self::create_batch_aggregation_circuit(&segment_aggregation, stark_config); | ||
|
@@ -897,11 +908,12 @@ where | |
fn create_segment_circuit( | ||
by_table: &[RecursiveCircuitsForTable<F, C, D>; NUM_TABLES], | ||
stark_config: &StarkConfig, | ||
circuit_config: &CircuitConfig, | ||
) -> RootCircuitData<F, C, D> { | ||
let inner_common_data: [_; NUM_TABLES] = | ||
core::array::from_fn(|i| &by_table[i].final_circuits()[0].common); | ||
|
||
let mut builder = CircuitBuilder::new(CircuitConfig::standard_recursion_config()); | ||
let mut builder = CircuitBuilder::new(circuit_config.clone()); | ||
|
||
let table_in_use: [BoolTarget; NUM_TABLES] = | ||
core::array::from_fn(|_| builder.add_virtual_bool_target_safe()); | ||
|
@@ -1481,18 +1493,9 @@ where | |
fn create_block_circuit( | ||
agg: &BatchAggregationCircuitData<F, C, D>, | ||
) -> BlockCircuitData<F, C, D> { | ||
// Here, we have two block proofs and we aggregate them together. | ||
// The block circuit is similar to the agg circuit; both verify two inner | ||
// proofs. | ||
let expected_common_data = CommonCircuitData { | ||
fri_params: FriParams { | ||
degree_bits: 14, | ||
..agg.circuit.common.fri_params.clone() | ||
}, | ||
..agg.circuit.common.clone() | ||
}; | ||
let expected_common_data = agg.circuit.common.clone(); | ||
|
||
let mut builder = CircuitBuilder::<F, D>::new(CircuitConfig::standard_recursion_config()); | ||
let mut builder = CircuitBuilder::<F, D>::new(agg.circuit.common.config.clone()); | ||
let public_values = add_virtual_public_values_public_input(&mut builder); | ||
let has_parent_block = builder.add_virtual_bool_target_safe(); | ||
let parent_block_proof = builder.add_virtual_proof_with_pis(&expected_common_data); | ||
|
@@ -1567,6 +1570,10 @@ where | |
let agg_verifier_data = builder.constant_verifier_data(&agg.circuit.verifier_only); | ||
builder.verify_proof::<C>(&agg_root_proof, &agg_verifier_data, &agg.circuit.common); | ||
|
||
while log2_ceil(builder.num_gates()) < agg.circuit.common.degree_bits() { | ||
builder.add_gate(NoopGate, vec![]); | ||
} | ||
|
||
let circuit = builder.build::<C>(); | ||
BlockCircuitData { | ||
circuit, | ||
|
@@ -1743,6 +1750,13 @@ where | |
builder.add_gate(NoopGate, vec![]); | ||
} | ||
|
||
// When using test configurations, the block circuit's degree is less than the | ||
// 2-to-1 circuit's degree. Therefore, we also need to ensure its size meets | ||
// the 2-to-1 circuit's recursion threshold degree bits. | ||
while log2_ceil(builder.num_gates()) < TWO_TO_ONE_BLOCK_CIRCUIT_TEST_THRESHOLD_DEGREE_BITS { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we want to test another circuit that doesn't require the same number of degree bits? I don't think Also, I'm actually surprised There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We need it in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But why does the common circuit data not contain a high enough degree then? Shouldn't the common data and the circuit we're building agree on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The previous check The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve completed the refactoring to keep only one |
||
builder.add_gate(NoopGate, vec![]); | ||
} | ||
|
||
let circuit = builder.build::<C>(); | ||
|
||
BlockWrapperCircuitData { | ||
|
@@ -1826,6 +1840,11 @@ where | |
|
||
builder.connect_hashes(mix_hash, mix_hash_virtual); | ||
|
||
// Pad to match the block circuit's degree. | ||
while log2_ceil(builder.num_gates()) < block_wrapper_circuit.circuit.common.degree_bits() { | ||
builder.add_gate(NoopGate, vec![]); | ||
} | ||
|
||
let circuit = builder.build::<C>(); | ||
TwoToOneBlockCircuitData { | ||
circuit, | ||
|
@@ -2900,6 +2919,8 @@ where | |
degree_bits_range: Range<usize>, | ||
all_ctls: &[CrossTableLookup<F>], | ||
stark_config: &StarkConfig, | ||
shrinking_circuit_config: &CircuitConfig, | ||
threshold_degree_bits: usize, | ||
) -> Self { | ||
let by_stark_size = degree_bits_range | ||
.map(|degree_bits| { | ||
|
@@ -2911,6 +2932,8 @@ where | |
degree_bits, | ||
all_ctls, | ||
stark_config, | ||
shrinking_circuit_config, | ||
threshold_degree_bits, | ||
), | ||
) | ||
}) | ||
|
@@ -3023,15 +3046,17 @@ where | |
degree_bits: usize, | ||
all_ctls: &[CrossTableLookup<F>], | ||
stark_config: &StarkConfig, | ||
shrinking_config: &CircuitConfig, | ||
threshold_degree_bits: usize, | ||
) -> Self { | ||
let initial_wrapper = recursive_stark_circuit( | ||
table, | ||
stark, | ||
degree_bits, | ||
all_ctls, | ||
stark_config, | ||
&shrinking_config(), | ||
THRESHOLD_DEGREE_BITS, | ||
shrinking_config, | ||
threshold_degree_bits, | ||
); | ||
let mut shrinking_wrappers = vec![]; | ||
|
||
|
@@ -3042,12 +3067,12 @@ where | |
.map(|wrapper: &PlonkWrapperCircuit<F, C, D>| &wrapper.circuit) | ||
.unwrap_or(&initial_wrapper.circuit); | ||
let last_degree_bits = last.common.degree_bits(); | ||
assert!(last_degree_bits >= THRESHOLD_DEGREE_BITS); | ||
if last_degree_bits == THRESHOLD_DEGREE_BITS { | ||
assert!(last_degree_bits >= threshold_degree_bits); | ||
if last_degree_bits == threshold_degree_bits { | ||
break; | ||
} | ||
|
||
let mut builder = CircuitBuilder::new(shrinking_config()); | ||
let mut builder = CircuitBuilder::new(shrinking_config.clone()); | ||
let proof_with_pis_target = builder.add_virtual_proof_with_pis(&last.common); | ||
let last_vk = builder.constant_verifier_data(&last.verifier_only); | ||
builder.verify_proof::<C>(&proof_with_pis_target, &last_vk, &last.common); | ||
|
@@ -3058,7 +3083,7 @@ where | |
assert!( | ||
circuit.common.degree_bits() < last_degree_bits, | ||
"Couldn't shrink to expected recursion threshold of 2^{}; stalled at 2^{}", | ||
THRESHOLD_DEGREE_BITS, | ||
threshold_degree_bits, | ||
circuit.common.degree_bits() | ||
); | ||
shrinking_wrappers.push(PlonkWrapperCircuit { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,10 @@ use mpt_trie::{ | |
partial_trie::{HashedPartialTrie, Node, PartialTrie}, | ||
}; | ||
use plonky2::field::goldilocks_field::GoldilocksField; | ||
use plonky2::fri::reduction_strategies::FriReductionStrategy; | ||
use plonky2::fri::FriConfig; | ||
use plonky2::plonk::circuit_data::CircuitConfig; | ||
use starky::config::StarkConfig; | ||
|
||
pub use crate::cpu::kernel::cancun_constants::*; | ||
pub use crate::cpu::kernel::constants::global_exit_root::*; | ||
|
@@ -27,6 +31,44 @@ pub const EMPTY_NODE_HASH: H256 = H256(hex!( | |
"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" | ||
)); | ||
|
||
/// The recursion threshold when using test configurations | ||
pub const TEST_THRESHOLD_DEGREE_BITS: usize = 10; | ||
|
||
/// The recursion threshold for 2-to-1 block circuit. | ||
pub const TWO_TO_ONE_BLOCK_CIRCUIT_TEST_THRESHOLD_DEGREE_BITS: usize = 13; | ||
|
||
/// A fast STARK config for testing purposes only. | ||
pub const TEST_STARK_CONFIG: StarkConfig = StarkConfig { | ||
security_bits: 1, | ||
num_challenges: 1, | ||
fri_config: FriConfig { | ||
rate_bits: 1, | ||
cap_height: 4, | ||
proof_of_work_bits: 1, | ||
reduction_strategy: FriReductionStrategy::ConstantArityBits(4, 5), | ||
num_query_rounds: 1, | ||
}, | ||
}; | ||
|
||
/// A fast Circuit config for testing purposes only. | ||
pub const TEST_RECURSION_CONFIG: CircuitConfig = CircuitConfig { | ||
num_wires: 135, | ||
num_routed_wires: 80, | ||
num_constants: 2, | ||
use_base_arithmetic_gate: true, | ||
security_bits: 1, | ||
num_challenges: 1, | ||
zero_knowledge: false, | ||
max_quotient_degree_factor: 8, | ||
fri_config: FriConfig { | ||
rate_bits: 3, | ||
cap_height: 4, | ||
Comment on lines
+64
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. non-blocking, but is this the fastest test setup? I think increasing the cap size would just increase proof size, and reduce recursive verification? (though this may not matter much as you're adding a shrinking layer by default if the threshold is too small when testing, just wondering) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not increase the cap_height; it was 4 before. |
||
proof_of_work_bits: 1, | ||
reduction_strategy: FriReductionStrategy::ConstantArityBits(4, 5), | ||
num_query_rounds: 1, | ||
}, | ||
}; | ||
|
||
pub fn init_logger() { | ||
let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: quid of grouping this into a
RecursionParams
struct or similar?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will work on it in a separate PR.