diff --git a/bus-mapping/src/circuit_input_builder.rs b/bus-mapping/src/circuit_input_builder.rs index 19d845ae15..b4d473e703 100644 --- a/bus-mapping/src/circuit_input_builder.rs +++ b/bus-mapping/src/circuit_input_builder.rs @@ -52,6 +52,12 @@ pub struct CircuitsParams { pub max_exp_steps: usize, /// Maximum number of bytes supported in the Bytecode Circuit pub max_bytecode: usize, + /// Pad evm circuit number of rows. + /// When 0, the EVM circuit number of row will be dynamically calculated, so + /// the same circuit will not be able to proof different witnesses. In this + /// case it will contain as many rows for all steps + 1 row + /// for EndBlock. + pub max_evm_rows: usize, // TODO: Rename for consistency /// Pad the keccak circuit with this number of invocations to a static /// capacity. Number of keccak_f that the Keccak circuit will support. @@ -70,6 +76,7 @@ impl Default for CircuitsParams { max_copy_rows: 1000, max_exp_steps: 1000, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, } } diff --git a/circuit-benchmarks/src/super_circuit.rs b/circuit-benchmarks/src/super_circuit.rs index 51ea5b2fb5..6a4e879cfb 100644 --- a/circuit-benchmarks/src/super_circuit.rs +++ b/circuit-benchmarks/src/super_circuit.rs @@ -84,6 +84,7 @@ mod tests { max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; let (_, circuit, instance, _) = diff --git a/integration-tests/src/integration_test_circuits.rs b/integration-tests/src/integration_test_circuits.rs index 18d65f6555..c6068992f4 100644 --- a/integration-tests/src/integration_test_circuits.rs +++ b/integration-tests/src/integration_test_circuits.rs @@ -2,6 +2,7 @@ use crate::{get_client, GenDataOutput}; use bus_mapping::circuit_input_builder::{BuilderClient, CircuitInputBuilder, CircuitsParams}; use bus_mapping::mock::BlockData; use eth_types::geth_types::GethData; +use halo2_proofs::dev::CellValue; use halo2_proofs::plonk::{ create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ProvingKey, VerifyingKey, }; @@ -17,33 +18,38 @@ use halo2_proofs::{ }, }; use lazy_static::lazy_static; -use mock::test_ctx::TestContext; +use mock::TestContext; use rand_chacha::rand_core::SeedableRng; use rand_core::RngCore; use rand_xorshift::XorShiftRng; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Mutex; +use tokio::sync::Mutex as TokioMutex; use zkevm_circuits::bytecode_circuit::circuit::BytecodeCircuit; use zkevm_circuits::copy_circuit::CopyCircuit; -use zkevm_circuits::evm_circuit::witness::block_convert; +use zkevm_circuits::evm_circuit::EvmCircuit; use zkevm_circuits::state_circuit::StateCircuit; +use zkevm_circuits::super_circuit::SuperCircuit; use zkevm_circuits::tx_circuit::TxCircuit; use zkevm_circuits::util::SubCircuit; -use zkevm_circuits::witness::Block; +use zkevm_circuits::witness::{block_convert, Block}; /// TEST_MOCK_RANDOMNESS -pub const TEST_MOCK_RANDOMNESS: u64 = 0x100; +const TEST_MOCK_RANDOMNESS: u64 = 0x100; /// MAX_TXS -pub const MAX_TXS: usize = 4; +const MAX_TXS: usize = 4; /// MAX_CALLDATA -pub const MAX_CALLDATA: usize = 512; +const MAX_CALLDATA: usize = 512; /// MAX_RWS -pub const MAX_RWS: usize = 5888; +const MAX_RWS: usize = 5888; /// MAX_BYTECODE -pub const MAX_BYTECODE: usize = 5000; +const MAX_BYTECODE: usize = 5000; /// MAX_COPY_ROWS -pub const MAX_COPY_ROWS: usize = 5888; +const MAX_COPY_ROWS: usize = 5888; +/// MAX_EVM_ROWS +const MAX_EVM_ROWS: usize = 10000; /// MAX_EXP_STEPS pub const MAX_EXP_STEPS: usize = 1000; @@ -53,26 +59,27 @@ const CIRCUITS_PARAMS: CircuitsParams = CircuitsParams { max_calldata: MAX_CALLDATA, max_bytecode: MAX_BYTECODE, max_copy_rows: MAX_COPY_ROWS, + max_evm_rows: MAX_EVM_ROWS, max_exp_steps: MAX_EXP_STEPS, keccak_padding: None, }; /// EVM Circuit degree -pub const EVM_CIRCUIT_DEGREE: u32 = 18; +const EVM_CIRCUIT_DEGREE: u32 = 18; /// State Circuit degree -pub const STATE_CIRCUIT_DEGREE: u32 = 17; +const STATE_CIRCUIT_DEGREE: u32 = 17; /// Tx Circuit degree -pub const TX_CIRCUIT_DEGREE: u32 = 20; +const TX_CIRCUIT_DEGREE: u32 = 20; /// Bytecode Circuit degree -pub const BYTECODE_CIRCUIT_DEGREE: u32 = 16; +const BYTECODE_CIRCUIT_DEGREE: u32 = 16; /// Copy Circuit degree -pub const COPY_CIRCUIT_DEGREE: u32 = 16; +const COPY_CIRCUIT_DEGREE: u32 = 16; /// Super Circuit degree -pub const SUPER_CIRCUIT_DEGREE: u32 = 20; +const SUPER_CIRCUIT_DEGREE: u32 = 20; lazy_static! { /// Data generation. - pub static ref GEN_DATA: GenDataOutput = GenDataOutput::load(); + static ref GEN_DATA: GenDataOutput = GenDataOutput::load(); static ref RNG: XorShiftRng = XorShiftRng::from_seed([ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, @@ -84,46 +91,203 @@ lazy_static! { } lazy_static! { - /// State Circuit proving key - pub static ref STATE_CIRCUIT_KEY: ProvingKey = { - let block = new_empty_block(); - let circuit = StateCircuit::::new_from_block(&block); - let general_params = get_general_params(STATE_CIRCUIT_DEGREE); - - let verifying_key = - keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); - keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail") - }; - /// Tx Circuit proving key - pub static ref TX_CIRCUIT_KEY: ProvingKey = { - let block = new_empty_block(); - let circuit = TxCircuit::::new_from_block(&block); - let general_params = get_general_params(TX_CIRCUIT_DEGREE); - - let verifying_key = - keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); - keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail") - }; - /// Bytecode Circuit proving key - pub static ref BYTECODE_CIRCUIT_KEY: ProvingKey = { - let block = new_empty_block(); - let circuit = BytecodeCircuit::::new_from_block(&block); - let general_params = get_general_params(BYTECODE_CIRCUIT_DEGREE); - - let verifying_key = - keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); - keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail") - }; - /// Copy Circuit proving key - pub static ref COPY_CIRCUIT_KEY: ProvingKey = { - let block = new_empty_block(); - let circuit = CopyCircuit::::new_from_block(&block); - let general_params = get_general_params(COPY_CIRCUIT_DEGREE); - - let verifying_key = - keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); - keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail") - }; + /// Integration test for EVM circuit + pub static ref EVM_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("EVM", EVM_CIRCUIT_DEGREE)); + + /// Integration test for State circuit + pub static ref STATE_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("State", STATE_CIRCUIT_DEGREE)); + + /// Integration test for State circuit + pub static ref TX_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("Tx", TX_CIRCUIT_DEGREE)); + + /// Integration test for Bytecode circuit + pub static ref BYTECODE_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("Bytecode", BYTECODE_CIRCUIT_DEGREE)); + + /// Integration test for Copy circuit + pub static ref COPY_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("Copy", COPY_CIRCUIT_DEGREE)); + + /// Integration test for Copy circuit + pub static ref SUPER_CIRCUIT_TEST: TokioMutex>> = + TokioMutex::new(IntegrationTest::new("Super", SUPER_CIRCUIT_DEGREE)); +} + +/// Generic implementation for integration tests +pub struct IntegrationTest + Circuit> { + name: &'static str, + degree: u32, + key: Option>, + fixed: Option>>>, + _marker: PhantomData, +} + +impl + Circuit> IntegrationTest { + fn new(name: &'static str, degree: u32) -> Self { + Self { + name, + degree, + key: None, + fixed: None, + _marker: PhantomData, + } + } + + fn get_key(&mut self) -> ProvingKey { + match self.key.clone() { + Some(key) => key, + None => { + let block = new_empty_block(); + let circuit = C::new_from_block(&block); + let general_params = get_general_params(self.degree); + + let verifying_key = + keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); + let key = keygen_pk(&general_params, verifying_key, &circuit) + .expect("keygen_pk should not fail"); + self.key = Some(key.clone()); + key + } + } + } + + fn test_actual(&self, circuit: C, instance: Vec>, proving_key: ProvingKey) { + fn test_gen_proof, R: RngCore>( + rng: R, + circuit: C, + general_params: &ParamsKZG, + proving_key: &ProvingKey, + mut transcript: Blake2bWrite, G1Affine, Challenge255>, + instances: &[&[Fr]], + ) -> Vec { + create_proof::< + KZGCommitmentScheme, + ProverSHPLONK<'_, Bn256>, + Challenge255, + R, + Blake2bWrite, G1Affine, Challenge255>, + C, + >( + general_params, + proving_key, + &[circuit], + &[instances], + rng, + &mut transcript, + ) + .expect("proof generation should not fail"); + + transcript.finalize() + } + + fn test_verify( + general_params: &ParamsKZG, + verifier_params: &ParamsKZG, + verifying_key: &VerifyingKey, + proof: &[u8], + instances: &[&[Fr]], + ) { + let mut verifier_transcript = Blake2bRead::<_, G1Affine, Challenge255<_>>::init(proof); + let strategy = SingleStrategy::new(general_params); + + verify_proof::< + KZGCommitmentScheme, + VerifierSHPLONK<'_, Bn256>, + Challenge255, + Blake2bRead<&[u8], G1Affine, Challenge255>, + SingleStrategy<'_, Bn256>, + >( + verifier_params, + verifying_key, + strategy, + &[instances], + &mut verifier_transcript, + ) + .expect("failed to verify circuit"); + } + + let general_params = get_general_params(self.degree); + let verifier_params: ParamsVerifierKZG = general_params.verifier_params().clone(); + + let transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); + + // change instace to slice + let instance: Vec<&[Fr]> = instance.iter().map(|v| v.as_slice()).collect(); + + let proof = test_gen_proof( + RNG.clone(), + circuit, + &general_params, + &proving_key, + transcript, + &instance, + ); + + let verifying_key = proving_key.get_vk(); + test_verify( + &general_params, + &verifier_params, + verifying_key, + &proof, + &instance, + ); + } + + fn test_mock(&mut self, circuit: &C, instance: Vec>) { + let mock_prover = MockProver::::run(self.degree, circuit, instance).unwrap(); + + self.test_variadic(&mock_prover); + + mock_prover + .verify_par() + .expect("mock prover verification failed"); + } + + fn test_variadic(&mut self, mock_prover: &MockProver) { + let fixed = mock_prover.fixed(); + + match self.fixed.clone() { + Some(prev_fixed) => { + assert!( + fixed.eq(&prev_fixed), + "circuit fixed columns are not constant for different witnesses" + ); + } + None => { + self.fixed = Some(fixed.clone()); + } + }; + + // TODO: check mock_prover.permutation(), currently the returning type + // is private so cannot store. + } + + /// Run integration test at a block identified by a tag. + pub async fn test_at_block_tag(&mut self, block_tag: &str, actual: bool) { + let block_num = *GEN_DATA.blocks.get(block_tag).unwrap(); + let (builder, _) = gen_inputs(block_num).await; + + log::info!( + "test {} circuit, block: #{} - {}", + self.name, + block_num, + block_tag + ); + let mut block = block_convert(&builder.block, &builder.code_db).unwrap(); + block.randomness = Fr::from(TEST_MOCK_RANDOMNESS); + let circuit = C::new_from_block(&block); + let instance = circuit.instance(); + + if actual { + let key = self.get_key(); + self.test_actual(circuit, instance, key); + } else { + self.test_mock(&circuit, instance); + } + } } fn new_empty_block() -> Block { @@ -150,6 +314,7 @@ fn get_general_params(degree: u32) -> ParamsKZG { } } +/// returns gen_inputs for a block number async fn gen_inputs( block_num: u64, ) -> ( @@ -161,128 +326,3 @@ async fn gen_inputs( cli.gen_inputs(block_num).await.unwrap() } - -fn test_actual>( - degree: u32, - circuit: C, - instance: Vec>, - proving_key: Option>, -) { - fn test_gen_proof, R: RngCore>( - rng: R, - circuit: C, - general_params: &ParamsKZG, - proving_key: &ProvingKey, - mut transcript: Blake2bWrite, G1Affine, Challenge255>, - instances: &[&[Fr]], - ) -> Vec { - create_proof::< - KZGCommitmentScheme, - ProverSHPLONK<'_, Bn256>, - Challenge255, - R, - Blake2bWrite, G1Affine, Challenge255>, - C, - >( - general_params, - proving_key, - &[circuit], - &[instances], - rng, - &mut transcript, - ) - .expect("proof generation should not fail"); - - transcript.finalize() - } - - fn test_verify( - general_params: &ParamsKZG, - verifier_params: &ParamsKZG, - verifying_key: &VerifyingKey, - proof: &[u8], - instances: &[&[Fr]], - ) { - let mut verifier_transcript = Blake2bRead::<_, G1Affine, Challenge255<_>>::init(proof); - let strategy = SingleStrategy::new(general_params); - - verify_proof::< - KZGCommitmentScheme, - VerifierSHPLONK<'_, Bn256>, - Challenge255, - Blake2bRead<&[u8], G1Affine, Challenge255>, - SingleStrategy<'_, Bn256>, - >( - verifier_params, - verifying_key, - strategy, - &[instances], - &mut verifier_transcript, - ) - .expect("failed to verify circuit"); - } - - let general_params = get_general_params(degree); - let verifier_params: ParamsVerifierKZG = general_params.verifier_params().clone(); - - let proving_key = match proving_key { - Some(pk) => pk, - None => { - let verifying_key = - keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail"); - keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail") - } - }; - - let transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); - - // change instace to slice - let instance: Vec<&[Fr]> = instance.iter().map(|v| v.as_slice()).collect(); - - let proof = test_gen_proof( - RNG.clone(), - circuit, - &general_params, - &proving_key, - transcript, - &instance, - ); - - let verifying_key = proving_key.get_vk(); - test_verify( - &general_params, - &verifier_params, - verifying_key, - &proof, - &instance, - ); -} - -fn test_mock>(degree: u32, circuit: &C, instance: Vec>) { - let mock_prover = MockProver::::run(degree, circuit, instance).unwrap(); - mock_prover - .verify_par() - .expect("mock prover verification failed"); -} - -/// Integration test generic function -pub async fn test_circuit_at_block + Circuit>( - circuit_name: &str, - degree: u32, - block_num: u64, - actual: bool, - proving_key: Option>, -) { - log::info!("test {} circuit, block number: {}", circuit_name, block_num); - let (builder, _) = gen_inputs(block_num).await; - let mut block = block_convert(&builder.block, &builder.code_db).unwrap(); - block.randomness = Fr::from(TEST_MOCK_RANDOMNESS); - let circuit = C::new_from_block(&block); - let instance = circuit.instance(); - - if actual { - test_actual(degree, circuit, instance, proving_key); - } else { - test_mock(degree, &circuit, instance); - } -} diff --git a/integration-tests/tests/circuit_input_builder.rs b/integration-tests/tests/circuit_input_builder.rs index 38a50485b1..fb98f4645f 100644 --- a/integration-tests/tests/circuit_input_builder.rs +++ b/integration-tests/tests/circuit_input_builder.rs @@ -19,6 +19,7 @@ async fn test_circuit_input_builder_block(block_num: u64) { max_calldata: 4000, max_bytecode: 4000, max_copy_rows: 16384, + max_evm_rows: 0, max_exp_steps: 1000, keccak_padding: None, }, diff --git a/integration-tests/tests/circuits.rs b/integration-tests/tests/circuits.rs index ce0a7bd4e2..7929eb1c47 100644 --- a/integration-tests/tests/circuits.rs +++ b/integration-tests/tests/circuits.rs @@ -1,58 +1,43 @@ +macro_rules! run_test { + ($test_instance:expr, $block_tag:expr, $real_prover:expr) => { + log_init(); + + let mut test = $test_instance.lock().await; + test.test_at_block_tag($block_tag, $real_prover).await; + }; +} + macro_rules! declare_tests { (($name:ident, $block_tag:expr),$real_prover:expr) => { paste! { #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = None; - test_circuit_at_block::>( - "evm", EVM_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (EVM_CIRCUIT_TEST, $block_tag, $real_prover); } #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = if $real_prover { Some((*STATE_CIRCUIT_KEY).clone()) } else { None }; - test_circuit_at_block::> - ("state", STATE_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (STATE_CIRCUIT_TEST, $block_tag, $real_prover); } #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = if $real_prover { Some((*TX_CIRCUIT_KEY).clone()) } else { None }; - test_circuit_at_block::> - ("tx", TX_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (TX_CIRCUIT_TEST, $block_tag, $real_prover); } #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = if $real_prover { Some((*BYTECODE_CIRCUIT_KEY).clone()) } else { None }; - test_circuit_at_block::> - ("bytecode", BYTECODE_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (BYTECODE_CIRCUIT_TEST, $block_tag, $real_prover); } #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = if $real_prover { Some((*COPY_CIRCUIT_KEY).clone()) } else { None }; - test_circuit_at_block::> - ("copy", COPY_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (COPY_CIRCUIT_TEST, $block_tag, $real_prover); } #[tokio::test] async fn []() { - log_init(); - let block_num = GEN_DATA.blocks.get($block_tag).unwrap(); - let pk = None; - test_circuit_at_block::> - ("super", SUPER_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await; + run_test! (SUPER_CIRCUIT_TEST, $block_tag, $real_prover); } } }; @@ -61,16 +46,14 @@ macro_rules! declare_tests { macro_rules! unroll_tests { ($($arg:tt),*) => { use paste::paste; - use zkevm_circuits::{ - state_circuit::StateCircuit, - super_circuit::SuperCircuit, - tx_circuit::TxCircuit, - evm_circuit::EvmCircuit, - bytecode_circuit::circuit::BytecodeCircuit, - copy_circuit::CopyCircuit + use integration_tests::integration_test_circuits::{ + EVM_CIRCUIT_TEST, + STATE_CIRCUIT_TEST, + TX_CIRCUIT_TEST, + BYTECODE_CIRCUIT_TEST, + COPY_CIRCUIT_TEST, + SUPER_CIRCUIT_TEST }; - use halo2_proofs::halo2curves::bn256::Fr; - use integration_tests::integration_test_circuits::*; use integration_tests::log_init; mod real_prover { use super::*; diff --git a/testool/src/statetest/executor.rs b/testool/src/statetest/executor.rs index ef391767b3..7c3d029d29 100644 --- a/testool/src/statetest/executor.rs +++ b/testool/src/statetest/executor.rs @@ -259,6 +259,7 @@ pub fn run_test( max_calldata: 5000, max_bytecode: 5000, max_copy_rows: 55000, + max_evm_rows: 0, max_exp_steps: 5000, keccak_padding: None, }; @@ -284,6 +285,7 @@ pub fn run_test( max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; let (k, circuit, instance, _builder) = diff --git a/zkevm-circuits/src/evm_circuit.rs b/zkevm-circuits/src/evm_circuit.rs index e611c52337..6c0496444d 100644 --- a/zkevm-circuits/src/evm_circuit.rs +++ b/zkevm-circuits/src/evm_circuit.rs @@ -202,20 +202,25 @@ impl EvmCircuit { } pub fn get_num_rows_required(block: &Block) -> usize { - // Start at 1 so we can be sure there is an unused `next` row available - let mut num_rows = 1; - let evm_rows = block.evm_circuit_pad_to; + let evm_rows = block.circuits_params.max_evm_rows; if evm_rows == 0 { - for transaction in &block.txs { - for step in &transaction.steps { - num_rows += step.execution_state.get_step_height(); - } - } - num_rows += 1; // EndBlock + Self::get_min_num_rows_required(block) } else { - num_rows += block.evm_circuit_pad_to; + // It must have at least one unused row. + block.circuits_params.max_evm_rows + 1 } - num_rows + } + + pub fn get_min_num_rows_required(block: &Block) -> usize { + let mut num_rows = 0; + for transaction in &block.txs { + for step in &transaction.steps { + num_rows += step.execution_state.get_step_height(); + } + } + + // It must have one row for EndBlock and at least one unused one + num_rows + 2 } } @@ -238,7 +243,7 @@ impl SubCircuit for EvmCircuit { num_rows_required_for_execution_steps, num_rows_required_for_fixed_table, ), - block.evm_circuit_pad_to, + block.circuits_params.max_evm_rows, ) } @@ -429,7 +434,9 @@ mod evm_circuit_stats { CircuitTestBuilder::new_from_test_ctx( TestContext::<0, 0>::new(None, |_| {}, |_, _| {}, |b, _| b).unwrap(), ) - .block_modifier(Box::new(|block| block.evm_circuit_pad_to = (1 << 18) - 100)) + .block_modifier(Box::new(|block| { + block.circuits_params.max_evm_rows = (1 << 18) - 100 + })) .run(); } diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index 9494d6a323..fc1b9f8c9d 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -847,7 +847,7 @@ impl ExecutionConfig { .chain(std::iter::once((&dummy_tx, &last_call, end_block_not_last))) .peekable(); - let evm_rows = block.evm_circuit_pad_to; + let evm_rows = block.circuits_params.max_evm_rows; let no_padding = evm_rows == 0; // part1: assign real steps diff --git a/zkevm-circuits/src/evm_circuit/execution/end_block.rs b/zkevm-circuits/src/evm_circuit/execution/end_block.rs index 9cdac65d2e..2a39bdbbf0 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_block.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_block.rs @@ -158,7 +158,7 @@ mod test { // finish required tests using this witness block CircuitTestBuilder::<2, 1>::new_from_test_ctx(ctx) .block_modifier(Box::new(move |block| { - block.evm_circuit_pad_to = evm_circuit_pad_to + block.circuits_params.max_evm_rows = evm_circuit_pad_to })) .run(); } diff --git a/zkevm-circuits/src/root_circuit.rs b/zkevm-circuits/src/root_circuit.rs index ae036352f9..8547d80268 100644 --- a/zkevm-circuits/src/root_circuit.rs +++ b/zkevm-circuits/src/root_circuit.rs @@ -172,6 +172,7 @@ mod test { max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; let (k, circuit, instance, _) = diff --git a/zkevm-circuits/src/super_circuit.rs b/zkevm-circuits/src/super_circuit.rs index 63f95ce819..a6054bd7c3 100644 --- a/zkevm-circuits/src/super_circuit.rs +++ b/zkevm-circuits/src/super_circuit.rs @@ -597,6 +597,7 @@ pub(crate) mod super_circuit_tests { max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; test_super_circuit::(block, circuits_params); @@ -614,6 +615,7 @@ pub(crate) mod super_circuit_tests { max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; test_super_circuit::(block, circuits_params); @@ -631,6 +633,7 @@ pub(crate) mod super_circuit_tests { max_copy_rows: 256, max_exp_steps: 256, max_bytecode: 512, + max_evm_rows: 0, keccak_padding: None, }; test_super_circuit::(block, circuits_params); diff --git a/zkevm-circuits/src/test_util.rs b/zkevm-circuits/src/test_util.rs index e7feaed531..ee01046c3b 100644 --- a/zkevm-circuits/src/test_util.rs +++ b/zkevm-circuits/src/test_util.rs @@ -67,7 +67,7 @@ fn init_env_logger() { /// .unwrap(); /// /// CircuitTestBuilder::new_from_test_ctx(ctx) -/// .block_modifier(Box::new(|block| block.evm_circuit_pad_to = (1 << 18) - 100)) +/// .block_modifier(Box::new(|block| block.circuits_params.max_evm_rows = (1 << 18) - 100)) /// .state_checks(Box::new(|prover, evm_rows, lookup_rows| assert!(prover.verify_at_rows_par(evm_rows.iter().cloned(), lookup_rows.iter().cloned()).is_err()))) /// .run(); /// ``` diff --git a/zkevm-circuits/src/witness/block.rs b/zkevm-circuits/src/witness/block.rs index eca2169e72..fe9a4d14c2 100644 --- a/zkevm-circuits/src/witness/block.rs +++ b/zkevm-circuits/src/witness/block.rs @@ -37,11 +37,6 @@ pub struct Block { pub copy_events: Vec, /// Exponentiation traces for the exponentiation circuit's table. pub exp_events: Vec, - // TODO: Rename to `max_evm_rows`, maybe move to CircuitsParams - /// Pad evm circuit to make selectors fixed, so vk/pk can be universal. - /// When 0, the EVM circuit contains as many rows for all steps + 1 row - /// for EndBlock. - pub evm_circuit_pad_to: usize, /// Pad exponentiation circuit to make selectors fixed. pub exp_circuit_pad_to: usize, /// Circuit Setup Parameters @@ -267,7 +262,6 @@ pub fn block_convert( exp_events: block.exp_events.clone(), sha3_inputs: block.sha3_inputs.clone(), circuits_params: block.circuits_params, - evm_circuit_pad_to: ::default(), exp_circuit_pad_to: ::default(), prev_state_root: block.prev_state_root, keccak_inputs: circuit_input_builder::keccak_inputs(block, code_db)?,