Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ impl<P: JsonRpcClient> BuilderClient<P> {
) -> Result<(EthBlock, Vec<eth_types::GethExecTrace>), Error> {
let eth_block = self.cli.get_block_by_number(block_num.into()).await?;
let geth_traces = self.cli.trace_block_by_number(block_num.into()).await?;

Ok((eth_block, geth_traces))
}

Expand Down Expand Up @@ -352,12 +353,21 @@ impl<P: JsonRpcClient> BuilderClient<P> {
}

/// Perform all the steps to generate the circuit inputs
pub async fn gen_inputs(&self, block_num: u64) -> Result<CircuitInputBuilder, Error> {
Comment thread
pinkiebell marked this conversation as resolved.
pub async fn gen_inputs(
&self,
block_num: u64,
) -> Result<
(
CircuitInputBuilder,
eth_types::Block<eth_types::Transaction>,
),
Error,
> {
let (eth_block, geth_traces) = self.get_block(block_num).await?;
let access_set = self.get_state_accesses(&eth_block, &geth_traces)?;
let (proofs, codes) = self.get_state(block_num, access_set).await?;
let (state_db, code_db) = self.build_state_code_db(proofs, codes);
let builder = self.gen_inputs_from_state(state_db, code_db, &eth_block, &geth_traces)?;
Ok(builder)
Ok((builder, eth_block))
}
}
5 changes: 4 additions & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ serde_json = "1.0.66"
serde = {version = "1.0.130", features = ["derive"] }
bus-mapping = { path = "../bus-mapping"}
eth-types = { path = "../eth-types"}
zkevm-circuits = { path = "../zkevm-circuits", features = ["test"] }
zkevm-circuits = { path = "../zkevm-circuits", features = ["test", "dev"] }
tokio = { version = "1.13", features = ["macros", "rt-multi-thread"] }
url = "2.2.2"
pretty_assertions = "1.0.0"
log = "0.4.14"
env_logger = "0.9"
halo2_proofs = { version = "0.1.0-beta.1" }
ff = "0.11"
rand_chacha = "0.3"
group = "0.11"
paste = "1.0"

[dev-dependencies]
pretty_assertions = "1.0.0"
Expand Down
147 changes: 123 additions & 24 deletions integration-tests/tests/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,29 @@

use bus_mapping::circuit_input_builder::BuilderClient;
use bus_mapping::operation::OperationContainer;
use halo2_proofs::dev::MockProver;
use integration_tests::{get_client, log_init, GenDataOutput};
use eth_types::geth_types;
use group::{Curve, Group};
use halo2_proofs::arithmetic::BaseExt;
use halo2_proofs::{
arithmetic::{CurveAffine, Field},
dev::MockProver,
pairing::bn256::Fr,
};
use integration_tests::{get_client, log_init, GenDataOutput, CHAIN_ID};
use lazy_static::lazy_static;
use log::trace;
use paste::paste;
use rand_chacha::rand_core::SeedableRng;
use rand_chacha::ChaCha20Rng;
use std::marker::PhantomData;
use zkevm_circuits::bytecode_circuit::dev::test_bytecode_circuit;
use zkevm_circuits::copy_circuit::dev::test_copy_circuit;
use zkevm_circuits::evm_circuit::witness::RwMap;
use zkevm_circuits::evm_circuit::{test::run_test_circuit, witness::block_convert};
use zkevm_circuits::state_circuit::StateCircuit;
use zkevm_circuits::tx_circuit::{
sign_verify::SignVerifyChip, Secp256k1Affine, TxCircuit, POW_RAND_SIZE, VERIF_HEIGHT,
};

lazy_static! {
pub static ref GEN_DATA: GenDataOutput = GenDataOutput::load();
Expand All @@ -18,19 +34,17 @@ async fn test_evm_circuit_block(block_num: u64) {
log::info!("test evm circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(cli).await.unwrap();
let builder = cli.gen_inputs(block_num).await.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();

let block = block_convert(&builder.block, &builder.code_db);
run_test_circuit(block).expect("evm_circuit verification failed");
}

async fn test_state_circuit_block(block_num: u64) {
use halo2_proofs::pairing::bn256::Fr;

log::info!("test state circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(cli).await.unwrap();
let builder = cli.gen_inputs(block_num).await.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();

// Generate state proof
let stack_ops = builder.block.container.sorted_stack();
Expand Down Expand Up @@ -58,20 +72,108 @@ async fn test_state_circuit_block(block_num: u64) {
prover.verify().expect("state_circuit verification failed");
}

async fn test_tx_circuit_block(block_num: u64) {
const DEGREE: u32 = 20;
Comment on lines +75 to +76
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing this on each test, why don't we use a crate like: https://github.com/markhildreth/test-context to do test setup/teardown?


log::info!("test tx circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(cli).await.unwrap();

let (_, eth_block) = cli.gen_inputs(block_num).await.unwrap();
Comment thread
pinkiebell marked this conversation as resolved.
let txs: Vec<_> = eth_block
.transactions
.iter()
.map(geth_types::Transaction::from_eth_tx)
.collect();

let mut rng = ChaCha20Rng::seed_from_u64(2);
let aux_generator = <Secp256k1Affine as CurveAffine>::CurveExt::random(&mut rng).to_affine();

let randomness = Fr::random(&mut rng);
let mut instance: Vec<Vec<Fr>> = (1..POW_RAND_SIZE + 1)
.map(|exp| vec![randomness.pow(&[exp as u64, 0, 0, 0]); txs.len() * VERIF_HEIGHT])
.collect();

instance.push(vec![]);
let circuit = TxCircuit::<Fr, 4, { 4 * (4 + 32 + 32) }> {
sign_verify: SignVerifyChip {
aux_generator,
window_size: 2,
_marker: PhantomData,
},
randomness,
txs,
chain_id: CHAIN_ID,
};

let prover = MockProver::run(DEGREE, &circuit, instance).unwrap();

prover.verify().expect("tx_circuit verification failed");
}

pub async fn test_bytecode_circuit_block(block_num: u64) {
const DEGREE: u32 = 16;
let randomness = Fr::from(123456);

log::info!("test bytecode circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(cli).await.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();
let bytecodes: Vec<Vec<u8>> = builder.code_db.0.values().cloned().collect();

test_bytecode_circuit(DEGREE, bytecodes, randomness);
}

pub async fn test_copy_circuit_block(block_num: u64) {
const DEGREE: u32 = 16;

log::info!("test copy circuit, block number: {}", block_num);
let cli = get_client();
let cli = BuilderClient::new(cli).await.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();
let block = block_convert(&builder.block, &builder.code_db);

assert!(test_copy_circuit(DEGREE, block).is_ok());
}

macro_rules! declare_tests {
($test_evm_name:ident, $test_state_name:ident, $block_tag:expr) => {
#[tokio::test]
async fn $test_evm_name() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_evm_circuit_block(*block_num).await;
}
($name:ident, $block_tag:expr) => {
paste! {
#[tokio::test]
async fn [<serial_test_evm_ $name>]() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_evm_circuit_block(*block_num).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).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).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).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).await;
}

#[tokio::test]
async fn $test_state_name() {
log_init();
let block_num = GEN_DATA.blocks.get($block_tag).unwrap();
test_state_circuit_block(*block_num).await;
}
};
}
Expand All @@ -94,17 +196,14 @@ declare_tests!(
);
*/
declare_tests!(
test_evm_circuit_erc20_openzeppelin_transfer_fail,
test_state_circuit_erc20_openzeppelin_transfer_fail,
circuit_erc20_openzeppelin_transfer_fail,
"ERC20 OpenZeppelin transfer failed"
);
declare_tests!(
test_evm_circuit_erc20_openzeppelin_transfer_succeed,
test_state_circuit_erc20_openzeppelin_transfer_succeed,
circuit_erc20_openzeppelin_transfer_succeed,
"ERC20 OpenZeppelin transfer successful"
);
declare_tests!(
test_evm_circuit_multiple_erc20_openzeppelin_transfers,
test_state_circuit_multiple_erc20_openzeppelin_transfers,
circuit_multiple_erc20_openzeppelin_transfers,
"Multiple ERC20 OpenZeppelin transfers"
);
2 changes: 1 addition & 1 deletion prover/src/compute_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub async fn compute_proof(
let url = Http::from_str(rpc_url)?;
let geth_client = GethClient::new(url);
let builder = BuilderClient::new(geth_client).await?;
let builder = builder.gen_inputs(*block_num).await?;
let (builder, _) = builder.gen_inputs(*block_num).await?;

// TODO: only {evm,state}_proof are implemented right now
let evm_proof;
Expand Down
3 changes: 2 additions & 1 deletion zkevm-circuits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ harness = false

[features]
default = []
test = []
test = [ "dev" ]
dev = []
2 changes: 2 additions & 0 deletions zkevm-circuits/src/bytecode_circuit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! The bytecode circuit implementation.

pub(crate) mod bytecode_unroller;
/// Bytecode circuit tester
pub mod dev;
Comment thread
ChihChengLiang marked this conversation as resolved.
pub(crate) mod param;
Loading