Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
chore: unify circuits in integration tests
Browse files Browse the repository at this point in the history
- unify circuit proving test in integration tests with a single generic function that takes a SubCircuit
- fix: Invalid `SubCircuit.instance()` implementation for TxCircuit
- allow setting the mock_randomness for the SuperCircuit externally
  • Loading branch information
ed255 committed Jan 24, 2023
1 parent bc23bc9 commit 3f4358c
Show file tree
Hide file tree
Showing 4 changed files with 320 additions and 304 deletions.
202 changes: 54 additions & 148 deletions integration-tests/src/integration_test_circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,47 @@ use std::collections::HashMap;
use std::sync::Mutex;
use zkevm_circuits::bytecode_circuit::bytecode_unroller::BytecodeCircuit;
use zkevm_circuits::copy_circuit::CopyCircuit;
use zkevm_circuits::evm_circuit::test::get_test_degree;
use zkevm_circuits::evm_circuit::{test::get_test_cicuit_from_block, witness::block_convert};
use zkevm_circuits::evm_circuit::witness::block_convert;
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;

/// TEST_MOCK_RANDOMNESS
pub const TEST_MOCK_RANDOMNESS: u64 = 0x100;

/// MAX_TXS
pub const MAX_TXS: usize = 4;
/// MAX_CALLDATA
pub const MAX_CALLDATA: usize = 512;
/// MAX_RWS
pub const MAX_RWS: usize = 5888;
/// MAX_BYTECODE
pub const MAX_BYTECODE: usize = 5000;
/// MAX_COPY_ROWS
pub const MAX_COPY_ROWS: usize = 5888;

const CIRCUITS_PARAMS: CircuitsParams = CircuitsParams {
max_rws: 16384,
max_txs: 4,
max_calldata: 4000,
max_bytecode: 4000,
max_copy_rows: 16384,
max_rws: MAX_RWS,
max_txs: MAX_TXS,
max_calldata: MAX_CALLDATA,
max_bytecode: MAX_BYTECODE,
max_copy_rows: MAX_COPY_ROWS,
keccak_padding: None,
};

const STATE_CIRCUIT_DEGREE: u32 = 17;
const TX_CIRCUIT_DEGREE: u32 = 20;
const BYTECODE_CIRCUIT_DEGREE: u32 = 16;
const COPY_CIRCUIT_DEGREE: u32 = 16;
/// EVM Circuit degree
pub const EVM_CIRCUIT_DEGREE: u32 = 18;
/// State Circuit degree
pub const STATE_CIRCUIT_DEGREE: u32 = 17;
/// Tx Circuit degree
pub const TX_CIRCUIT_DEGREE: u32 = 20;
/// Bytecode Circuit degree
pub const BYTECODE_CIRCUIT_DEGREE: u32 = 16;
/// Copy Circuit degree
pub const COPY_CIRCUIT_DEGREE: u32 = 16;
/// Super Circuit degree
pub const SUPER_CIRCUIT_DEGREE: u32 = 20;

lazy_static! {
/// Data generation.
Expand All @@ -61,7 +81,8 @@ lazy_static! {
}

lazy_static! {
static ref STATE_CIRCUIT_KEY: ProvingKey<G1Affine> = {
/// State Circuit proving key
pub static ref STATE_CIRCUIT_KEY: ProvingKey<G1Affine> = {
let block = new_empty_block();
let circuit = StateCircuit::<Fr>::new_from_block(&block);
let general_params = get_general_params(STATE_CIRCUIT_DEGREE);
Expand All @@ -70,7 +91,8 @@ lazy_static! {
keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail")
};
static ref TX_CIRCUIT_KEY: ProvingKey<G1Affine> = {
/// Tx Circuit proving key
pub static ref TX_CIRCUIT_KEY: ProvingKey<G1Affine> = {
let block = new_empty_block();
let circuit = TxCircuit::<Fr>::new_from_block(&block);
let general_params = get_general_params(TX_CIRCUIT_DEGREE);
Expand All @@ -79,7 +101,8 @@ lazy_static! {
keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail")
};
static ref BYTECODE_CIRCUIT_KEY: ProvingKey<G1Affine> = {
/// Bytecode Circuit proving key
pub static ref BYTECODE_CIRCUIT_KEY: ProvingKey<G1Affine> = {
let block = new_empty_block();
let circuit = BytecodeCircuit::<Fr>::new_from_block(&block);
let general_params = get_general_params(BYTECODE_CIRCUIT_DEGREE);
Expand All @@ -88,7 +111,8 @@ lazy_static! {
keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
keygen_pk(&general_params, verifying_key, &circuit).expect("keygen_pk should not fail")
};
static ref COPY_CIRCUIT_KEY: ProvingKey<G1Affine> = {
/// Copy Circuit proving key
pub static ref COPY_CIRCUIT_KEY: ProvingKey<G1Affine> = {
let block = new_empty_block();
let circuit = CopyCircuit::<Fr>::new_from_block(&block);
let general_params = get_general_params(COPY_CIRCUIT_DEGREE);
Expand Down Expand Up @@ -238,142 +262,24 @@ fn test_mock<C: Circuit<Fr>>(degree: u32, circuit: &C, instance: Vec<Vec<Fr>>) {
.expect("mock prover verification failed");
}

/// Integration test for evm circuit.
pub async fn test_evm_circuit_block(block_num: u64, actual: bool) {
log::info!("test evm circuit, block number: {}", block_num);
let (builder, _) = gen_inputs(block_num).await;

let block = block_convert(&builder.block, &builder.code_db).unwrap();

let degree = get_test_degree(&block);
let circuit = get_test_cicuit_from_block(block);

if actual {
test_actual(degree, circuit, vec![], None);
} else {
test_mock(degree, &circuit, vec![]);
}
}

/// Integration test for state circuit.
pub async fn test_state_circuit_block(block_num: u64, actual: bool) {
log::info!("test state circuit, block number: {}", block_num);

/// Integration test generic function
pub async fn test_circuit_at_block<C: SubCircuit<Fr> + Circuit<Fr>>(
circuit_name: &str,
degree: u32,
block_num: u64,
actual: bool,
proving_key: Option<ProvingKey<G1Affine>>,
) {
log::info!("test {} circuit, block number: {}", circuit_name, block_num);
let (builder, _) = gen_inputs(block_num).await;
let block = block_convert(&builder.block, &builder.code_db).unwrap();

let circuit = StateCircuit::<Fr>::new_from_block(&block);
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(
STATE_CIRCUIT_DEGREE,
circuit,
instance,
Some((*STATE_CIRCUIT_KEY).clone()),
);
test_actual(degree, circuit, instance, proving_key);
} else {
test_mock(STATE_CIRCUIT_DEGREE, &circuit, instance);
}
}

/// Integration test for tx circuit.
pub async fn test_tx_circuit_block(block_num: u64, actual: bool) {
log::info!("test tx circuit, block number: {}", block_num);

let (builder, _) = gen_inputs(block_num).await;

let block = block_convert(&builder.block, &builder.code_db).unwrap();
let circuit = TxCircuit::<Fr>::new_from_block(&block);

if actual {
test_actual(
TX_CIRCUIT_DEGREE,
circuit,
vec![vec![]],
Some((*TX_CIRCUIT_KEY).clone()),
);
} else {
test_mock(TX_CIRCUIT_DEGREE, &circuit, vec![vec![]]);
}
}

/// Integration test for bytecode circuit.
pub async fn test_bytecode_circuit_block(block_num: u64, actual: bool) {
log::info!("test bytecode circuit, block number: {}", block_num);
let (builder, _) = gen_inputs(block_num).await;

let block = block_convert(&builder.block, &builder.code_db).unwrap();
let circuit =
BytecodeCircuit::<Fr>::new_from_block_sized(&block, 2usize.pow(BYTECODE_CIRCUIT_DEGREE));

if actual {
test_actual(
BYTECODE_CIRCUIT_DEGREE,
circuit,
Vec::new(),
Some((*BYTECODE_CIRCUIT_KEY).clone()),
);
} else {
test_mock(BYTECODE_CIRCUIT_DEGREE, &circuit, Vec::new());
}
}

/// Integration test for copy circuit.
pub async fn test_copy_circuit_block(block_num: u64, actual: bool) {
log::info!("test copy circuit, block number: {}", block_num);
let (builder, _) = gen_inputs(block_num).await;
let block = block_convert(&builder.block, &builder.code_db).unwrap();

let circuit = CopyCircuit::<Fr>::new_from_block(&block);

if actual {
test_actual(
COPY_CIRCUIT_DEGREE,
circuit,
vec![],
Some((*COPY_CIRCUIT_KEY).clone()),
);
} else {
test_mock(COPY_CIRCUIT_DEGREE, &circuit, vec![]);
}
}

/// Integration test for super circuit.
pub async fn test_super_circuit_block(block_num: u64) {
const MAX_TXS: usize = 4;
const MAX_CALLDATA: usize = 512;
const MAX_RWS: usize = 5888;
const MAX_BYTECODE: usize = 5000;
const MAX_COPY_ROWS: usize = 5888;

log::info!("test super circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(
cli,
CircuitsParams {
max_rws: MAX_RWS,
max_txs: MAX_TXS,
max_calldata: MAX_CALLDATA,
max_bytecode: MAX_BYTECODE,
max_copy_rows: MAX_COPY_ROWS,
keccak_padding: None,
},
)
.await
.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();
let (k, circuit, instance) =
SuperCircuit::<Fr, MAX_TXS, MAX_CALLDATA, MAX_RWS, MAX_COPY_ROWS>::build_from_circuit_input_builder(
&builder,
)
.unwrap();
// TODO: add actual prover
let prover = MockProver::run(k, &circuit, instance).unwrap();
let res = prover.verify_par();
if let Err(err) = res {
eprintln!("Verification failures:");
eprintln!("{:#?}", err);
panic!("Failed verification");
test_mock(degree, &circuit, instance);
}
}
55 changes: 38 additions & 17 deletions integration-tests/tests/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,82 @@ macro_rules! declare_tests {
async fn [<serial_test_evm_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_evm_circuit_block(*block_num, $real_prover).await;
let pk = None;
test_circuit_at_block::<EvmCircuit::<Fr>>(
"evm", EVM_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}

#[tokio::test]
async fn [<serial_test_state_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_state_circuit_block(*block_num, $real_prover).await;
let pk = if $real_prover { Some((*STATE_CIRCUIT_KEY).clone()) } else { None };
test_circuit_at_block::<StateCircuit::<Fr>>
("state", STATE_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}

#[tokio::test]
async fn [<serial_test_tx_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_tx_circuit_block(*block_num, $real_prover).await;
let pk = if $real_prover { Some((*TX_CIRCUIT_KEY).clone()) } else { None };
test_circuit_at_block::<TxCircuit::<Fr>>
("tx", TX_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}

#[tokio::test]
async fn [<serial_test_bytecode_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_bytecode_circuit_block(*block_num, $real_prover).await;
let pk = if $real_prover { Some((*BYTECODE_CIRCUIT_KEY).clone()) } else { None };
test_circuit_at_block::<BytecodeCircuit::<Fr>>
("bytecode", BYTECODE_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}

#[tokio::test]
async fn [<serial_test_copy_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_copy_circuit_block(*block_num, $real_prover).await;
let pk = if $real_prover { Some((*COPY_CIRCUIT_KEY).clone()) } else { None };
test_circuit_at_block::<CopyCircuit::<Fr>>
("copy", COPY_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}

#[tokio::test]
async fn [<serial_test_super_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
let pk = None;
test_circuit_at_block::<SuperCircuit::<Fr, MAX_TXS, MAX_CALLDATA, MAX_RWS, MAX_COPY_ROWS, TEST_MOCK_RANDOMNESS>>
("super", SUPER_CIRCUIT_DEGREE, *block_num, $real_prover, pk).await;
}
}
};
}

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::bytecode_unroller::BytecodeCircuit,
copy_circuit::CopyCircuit
};
use halo2_proofs::halo2curves::bn256::Fr;
use integration_tests::integration_test_circuits::*;
use integration_tests::log_init;
mod real_prover {
use paste::paste;
use integration_tests::integration_test_circuits::{
test_bytecode_circuit_block, test_copy_circuit_block, test_evm_circuit_block,
test_state_circuit_block, test_tx_circuit_block, GEN_DATA,
};
use integration_tests::log_init;
use super::*;
$(
declare_tests! ($arg, true) ;
)*
}

mod mock_prover {
use paste::paste;
use integration_tests::integration_test_circuits::{
test_bytecode_circuit_block, test_copy_circuit_block, test_evm_circuit_block,
test_state_circuit_block, test_tx_circuit_block, GEN_DATA,
};
use integration_tests::log_init;
use super::*;
$(
declare_tests! ($arg, false) ;
)*
Expand Down
Loading

0 comments on commit 3f4358c

Please sign in to comment.