Skip to content

Commit

Permalink
Add CircuitTestBuilder for EVM & State tests (scroll-tech#1120)
Browse files Browse the repository at this point in the history
* chore: Migrate tests to use assert_satisfied

* feat: Add `CircuitTestBuilder` for EVM & State tests

This struct provides a builder-pattern which allows to generate an
entire circuit test for the EVM &/| State circuits with ease. Unifying
the way to test circuits in the crate.

Also, it defaults to the usage of `assert_satisfied` in the
verification of the Proofs.

Resolves: scroll-tech#1107, scroll-tech#1097

* chore: Migrate EVMCircuit test fns to CTB

* chore: Migrate `executor` mod to CTB usage

* chore: Migrate opcode impls to CircuitTestBuilder usage

* chore: Fix warnings left during impl

* chore: Allow for type complexity with Clippy

* chore: Remove `random_tx` test fn and use `mock` crate

* feat: Add docs for CircuitTestBuilder

* chore: Apply formatting

* chore: Fix warnings

* chore: Generate configs inside calls in executor

* chore: Use block_modifier when possible

* chore: Move standalone fns to corresp. impl blocks

* chore: Address small nits from 1st review

* chore: Introduce `new_from` instead of `empty` for CTB

* chore: prevent missusage of `params()`

* remove: BytecodeConfig is deleted due to unusage

* chore: Fix last nits

* chore: Leave testool untouched

* fix: Intra-doc links

* fix: testool tests passing

* remove: info! logs

* chore: Bump `halo2wrong` & `halo2_proofs` to latest release

* fix: use `at_rows` in neg test to speed them up

* feat: Include the possibility to use `at_rows` variant always

* fix: Allow type complexity for CTB

* chore: Add an extra tx to enable enough for testing

* fix: Impl Default for PublicData using `MOCK_CHAIN_ID`

* chore: Derive `Copy` for `CircuitsParams`

* chore: Update `max_rws` in callop tests

* fix: Fix rows being checked in EVMCircuit state tests

Co-authored-by: Eduard S. <[email protected]>

* fix: Clippy lints

* chore: Comment out callop failing tests

Filed scroll-tech#1132 as a follow-up PR as the problem seems non trivial to solve
in this PR and would make the diff and the review harder.

---------

Co-authored-by: Eduard S. <[email protected]>
  • Loading branch information
CPerezz and ed255 authored Feb 2, 2023
1 parent 3c621db commit 71ef264
Show file tree
Hide file tree
Showing 86 changed files with 916 additions and 1,063 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ members = [
]

[patch.crates-io]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }

# Definition of benchmarks profile to use.
[profile.bench]
Expand Down
2 changes: 1 addition & 1 deletion bus-mapping/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mock = { path = "../mock", optional = true }

ethers-core = "0.17.0"
ethers-providers = "0.17.0"
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
itertools = "0.10"
lazy_static = "1.4"
log = "0.4.14"
Expand Down
4 changes: 2 additions & 2 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use std::collections::HashMap;
pub use transaction::{Transaction, TransactionContext};

/// Circuit Setup Parameters
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub struct CircuitsParams {
/// Maximum number of rw operations in the state circuit (RwTable length /
/// nummber of rows). This must be at least the number of rw operations
Expand Down Expand Up @@ -544,7 +544,7 @@ impl<P: JsonRpcClient> BuilderClient<P> {
history_hashes,
prev_state_root,
eth_block,
self.circuits_params.clone(),
self.circuits_params,
)?;
let mut builder = CircuitInputBuilder::new(sdb, code_db, block);
builder.handle_block(eth_block, geth_traces)?;
Expand Down
2 changes: 1 addition & 1 deletion bus-mapping/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl BlockData {
self.history_hashes.clone(),
Word::default(),
&self.eth_block,
self.circuits_params.clone(),
self.circuits_params,
)
.unwrap(),
)
Expand Down
2 changes: 1 addition & 1 deletion circuit-benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
ark-std = { version = "0.3", features = ["print-trace"] }
zkevm-circuits = { path = "../zkevm-circuits", features = ["test"]}
keccak256 = { path = "../keccak256" }
Expand Down
4 changes: 1 addition & 3 deletions circuit-benchmarks/src/pi_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ mod tests {
use rand_chacha::ChaCha20Rng;
use rand_xorshift::XorShiftRng;
use zkevm_circuits::pi_circuit::{PiCircuit, PiTestCircuit, PublicData};
use zkevm_circuits::test_util::rand_tx;
use zkevm_circuits::util::SubCircuit;

use crate::bench_params::DEGREE;
Expand Down Expand Up @@ -108,14 +107,13 @@ mod tests {
}

fn generate_publicdata<const MAX_TXS: usize, const MAX_CALLDATA: usize>() -> PublicData {
let mut rng = ChaCha20Rng::seed_from_u64(2);
let mut public_data = PublicData::default();
let chain_id = 1337u64;
public_data.chain_id = Word::from(chain_id);

let n_tx = MAX_TXS;
for _ in 0..n_tx {
let eth_tx = eth_types::Transaction::from(&rand_tx(&mut rng, chain_id, true));
let eth_tx = eth_types::Transaction::from(mock::CORRECT_MOCK_TXS[0].clone());
public_data.transactions.push(eth_tx);
}
public_data
Expand Down
2 changes: 1 addition & 1 deletion eth-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ethers-core = "0.17.0"
ethers-signers = "0.17.0"
hex = "0.4"
lazy_static = "1.4"
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
regex = "1.5.4"
serde = {version = "1.0.130", features = ["derive"] }
serde_json = "1.0.66"
Expand Down
2 changes: 1 addition & 1 deletion gadgets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["The appliedzkp team"]
license = "MIT OR Apache-2.0"

[dependencies]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
sha3 = "0.7.2"
eth-types = { path = "../eth-types" }
digest = "0.7.6"
Expand Down
2 changes: 1 addition & 1 deletion gadgets/src/batched_is_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ mod test {
};
let k = 4;
let prover = MockProver::<Fr>::run(k, &circuit, vec![]).unwrap();
assert_eq!(prover.verify(), Ok(()));
prover.assert_satisfied_par()
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion gadgets/src/evm_word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ mod tests {
// Calculate word commitment and use it as public input.
let encoded: Fp = encode(word.to_repr().iter().rev().cloned(), r());
let prover = MockProver::<Fp>::run(9, &circuit, vec![vec![encoded]]).unwrap();
assert_eq!(prover.verify(), Ok(()))
prover.assert_satisfied_par()
}
}
}
27 changes: 7 additions & 20 deletions gadgets/src/is_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod test {
use std::marker::PhantomData;

macro_rules! try_test_circuit {
($values:expr, $checks:expr, $result:expr) => {{
($values:expr, $checks:expr) => {{
// let k = usize::BITS - $values.len().leading_zeros();

// TODO: remove zk blinding factors in halo2 to restore the
Expand All @@ -161,7 +161,7 @@ mod test {
_marker: PhantomData,
};
let prover = MockProver::<Fp>::run(k, &circuit, vec![]).unwrap();
assert_eq!(prover.verify(), $result);
prover.assert_satisfied_par()
}};
}

Expand All @@ -178,7 +178,7 @@ mod test {
_marker: PhantomData,
};
let prover = MockProver::<Fp>::run(k, &circuit, vec![]).unwrap();
assert!(prover.verify().is_err());
assert!(prover.verify_par().is_err());
}};
}

Expand Down Expand Up @@ -298,15 +298,10 @@ mod test {
}

// ok
try_test_circuit!(
vec![1, 2, 3, 4, 5],
vec![false, false, false, false],
Ok(())
);
try_test_circuit!(vec![1, 2, 3, 4, 5], vec![false, false, false, false]);
try_test_circuit!(
vec![1, 2, 2, 3, 3], //
vec![false, true, false, true],
Ok(())
vec![false, true, false, true]
);
// error
try_test_circuit_error!(vec![1, 2, 3, 4, 5], vec![true, true, true, true]);
Expand Down Expand Up @@ -432,16 +427,8 @@ mod test {
}

// ok
try_test_circuit!(
vec![(1, 2), (3, 4), (5, 6)],
vec![false, false, false],
Ok(())
);
try_test_circuit!(
vec![(1, 1), (3, 4), (6, 6)],
vec![true, false, true],
Ok(())
);
try_test_circuit!(vec![(1, 2), (3, 4), (5, 6)], vec![false, false, false]);
try_test_circuit!(vec![(1, 1), (3, 4), (6, 6)], vec![true, false, true]);
// error
try_test_circuit_error!(vec![(1, 2), (3, 4), (5, 6)], vec![true, true, true]);
try_test_circuit_error!(vec![(1, 1), (3, 4), (6, 6)], vec![false, true, false]);
Expand Down
6 changes: 5 additions & 1 deletion gadgets/src/monotone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ mod test {
vec![],
)
.unwrap();
assert_eq!(prover.verify(), result);
if result.is_err() {
assert_eq!(prover.verify_par(), result)
} else {
prover.assert_satisfied_par()
}
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion gadgets/src/mul_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ mod test {
_marker: PhantomData,
};
let prover = MockProver::<Fp>::run(k, &circuit, vec![]).unwrap();
assert!(prover.verify().is_ok());
prover.assert_satisfied_par()
}};
}

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ url = "2.2.2"
pretty_assertions = "1.0.0"
log = "0.4.14"
env_logger = "0.9"
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
rand_chacha = "0.3"
paste = "1.0"
rand_xorshift = "0.3.0"
Expand Down
10 changes: 9 additions & 1 deletion mock/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,15 @@ lazy_static! {
.value(word!("0x3e8"))
.gas_price(word!("0x4d2"))
.input(Bytes::from(b"hello"))
.build()]
.build(),
MockTransaction::default()
.from(AddrOrWallet::random(&mut rng))
.to(MOCK_ACCOUNTS[0])
.nonce(word!("0x106"))
.value(word!("0x3e8"))
.gas_price(word!("0x4d2"))
.input(Bytes::from(b"hello"))
.build(),]
};
}

Expand Down
2 changes: 1 addition & 1 deletion testool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ yaml-rust = "0.4.5"
zkevm-circuits = { path="../zkevm-circuits", features=["test"] }
rand_chacha = "0.3"
rand = "0.8"
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_01_20" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
urlencoding = "2.1.2"


Expand Down
69 changes: 50 additions & 19 deletions testool/src/statetest/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ use ethers_core::k256::ecdsa::SigningKey;
use ethers_core::types::TransactionRequest;
use ethers_signers::{LocalWallet, Signer};
use external_tracer::TraceConfig;
use halo2_proofs::dev::VerifyFailure;
use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
use std::{collections::HashMap, str::FromStr};
use thiserror::Error;
use zkevm_circuits::{super_circuit::SuperCircuit, test_util::BytecodeTestConfig};
use zkevm_circuits::evm_circuit::EvmCircuit;
use zkevm_circuits::state_circuit::StateCircuit;
use zkevm_circuits::super_circuit::SuperCircuit;
use zkevm_circuits::util::SubCircuit;
use zkevm_circuits::witness::{Block, Rw};

#[derive(PartialEq, Eq, Error, Debug)]
pub enum StateTestError {
Expand Down Expand Up @@ -245,32 +250,28 @@ pub fn run_test(
let mut builder;

if !circuits_config.super_circuit {
let circuits_params = CircuitsParams {
max_txs: 1,
max_rws: 55000,
max_calldata: 5000,
max_bytecode: 5000,
max_copy_rows: 55000,
keccak_padding: None,
};
let block_data = BlockData::new_from_geth_data_with_params(geth_data, circuits_params);
let block_data = BlockData::new_from_geth_data_with_params(
geth_data,
CircuitsParams {
max_txs: 1,
max_rws: 55000,
max_calldata: 5000,
max_bytecode: 5000,
max_copy_rows: 55000,
keccak_padding: None,
},
);

builder = block_data.new_circuit_input_builder();
builder
.handle_block(&eth_block, &geth_traces)
.map_err(|err| StateTestError::CircuitInput(err.to_string()))?;

let block =
let block: Block<Fr> =
zkevm_circuits::evm_circuit::witness::block_convert(&builder.block, &builder.code_db)
.unwrap();

let config = BytecodeTestConfig {
enable_evm_circuit_test: true,
enable_state_circuit_test: true,
gas_limit: u64::MAX,
};

zkevm_circuits::test_util::test_circuits_witness_block(block, config)
test_circuits_witness_block(block)
.map_err(|err| StateTestError::VerifierError(format!("{:#?}", err)))?;
} else {
geth_data.sign(&wallets);
Expand All @@ -294,9 +295,39 @@ pub fn run_test(
prover
.verify_par()
.map_err(|err| StateTestError::VerifierError(format!("{:#?}", err)))?;
}
};

check_post(&builder, &post)?;

Ok(())
}

pub(self) fn test_circuits_witness_block(block: Block<Fr>) -> Result<(), Vec<VerifyFailure>> {
// run evm circuit test
let degree = block.get_test_degree();
let (active_gate_rows, active_lookup_rows) = EvmCircuit::<Fr>::get_active_rows(&block);
let evm_circuit = EvmCircuit::<Fr>::get_test_cicuit_from_block(block.clone());

let prover = MockProver::<Fr>::run(degree, &evm_circuit, vec![]).unwrap();
prover.verify_at_rows_par(active_gate_rows.into_iter(), active_lookup_rows.into_iter())?;

// run state circuit test
// TODO: use randomness as one of the circuit public input, since randomness in
// state circuit and evm circuit must be same
const N_ROWS: usize = 1 << 16;
let state_circuit = StateCircuit::<Fr>::new(block.rws, N_ROWS);
let power_of_randomness = state_circuit.instance();
let prover = MockProver::<Fr>::run(18, &state_circuit, power_of_randomness).unwrap();
// Skip verification of Start rows to accelerate testing
let non_start_rows_len = state_circuit
.rows
.iter()
.filter(|rw| !matches!(rw, Rw::Start { .. }))
.count();
prover.verify_at_rows(
N_ROWS - non_start_rows_len..N_ROWS,
N_ROWS - non_start_rows_len..N_ROWS,
)?;

Ok(())
}
Loading

0 comments on commit 71ef264

Please sign in to comment.