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

Improve supercircuit usage #994

Merged
merged 1 commit into from
Jan 5, 2023
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
2 changes: 1 addition & 1 deletion integration-tests/src/integration_test_circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ pub async fn test_super_circuit_block(block_num: u64) {
.unwrap();
let (builder, _) = cli.gen_inputs(block_num).await.unwrap();
let (k, circuit, instance) =
SuperCircuit::<_, MAX_TXS, MAX_CALLDATA, MAX_RWS>::build_from_circuit_input_builder(
SuperCircuit::<Fr, MAX_TXS, MAX_CALLDATA, MAX_RWS>::build_from_circuit_input_builder(
&builder,
)
.unwrap();
Expand Down
4 changes: 2 additions & 2 deletions testool/src/statetest/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ethers_core::k256::ecdsa::SigningKey;
use ethers_core::types::TransactionRequest;
use ethers_signers::{LocalWallet, Signer};
use external_tracer::TraceConfig;
use halo2_proofs::dev::MockProver;
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};
Expand Down Expand Up @@ -326,7 +326,7 @@ pub fn run_test(
geth_data.sign(&wallets);

let (k, circuit, instance, _builder) =
SuperCircuit::<_, 1, 32, 255>::build(geth_data).unwrap();
SuperCircuit::<Fr, 1, 32, 255>::build(geth_data).unwrap();
builder = _builder;

let prover = MockProver::run(k, &circuit, instance).unwrap();
Expand Down
9 changes: 9 additions & 0 deletions zkevm-circuits/src/bytecode_circuit/bytecode_unroller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,15 @@ impl<F: Field> SubCircuit<F> for BytecodeCircuit<F> {
Self::new_from_block_sized(block, bytecode_size)
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> usize {
block
.bytecodes
.values()
.map(|bytecode| bytecode.bytes.len() + 1)
.sum()
}

/// Make the assignments to the TxCircuit
fn synthesize_sub(
&self,
Expand Down
14 changes: 10 additions & 4 deletions zkevm-circuits/src/copy_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,11 @@ impl<F: Field> SubCircuit<F> for CopyCircuit<F> {
Self::new(block.circuits_params.max_txs, block.clone())
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> usize {
block.copy_events.iter().map(|c| c.bytes.len() * 2).sum()
}

/// Make the assignments to the CopyCircuit
fn synthesize_sub(
&self,
Expand Down Expand Up @@ -754,6 +759,7 @@ mod tests {
mock::BlockData,
};
use eth_types::{bytecode, geth_types::GethData, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use mock::test_ctx::helpers::account_0_code_account_1_no_code;
use mock::TestContext;

Expand Down Expand Up @@ -855,28 +861,28 @@ mod tests {
#[test]
fn copy_circuit_valid_calldatacopy() {
let builder = gen_calldatacopy_data();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_copy_circuit(14, block), Ok(()));
}

#[test]
fn copy_circuit_valid_codecopy() {
let builder = gen_codecopy_data();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_copy_circuit(10, block), Ok(()));
}

#[test]
fn copy_circuit_valid_sha3() {
let builder = gen_sha3_data();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_copy_circuit(20, block), Ok(()));
}

#[test]
fn copy_circuit_tx_log() {
let builder = gen_tx_log_data();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_copy_circuit(10, block), Ok(()));
}

Expand Down
77 changes: 44 additions & 33 deletions zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ pub(crate) mod util;
pub mod table;

use crate::table::{BlockTable, BytecodeTable, CopyTable, ExpTable, KeccakTable, RwTable, TxTable};
use crate::util::{Challenges, SubCircuit, SubCircuitConfig};
use crate::util::{log2_ceil, Challenges, SubCircuit, SubCircuitConfig};
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
pub use crate::witness;
use bus_mapping::evm::OpcodeId;
use eth_types::Field;
use execution::ExecutionConfig;
use itertools::Itertools;
Expand Down Expand Up @@ -211,6 +212,20 @@ impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
Self::new(block.clone())
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> usize {
let num_rows_required_for_execution_steps: usize =
EvmCircuit::<F>::get_num_rows_required(block);
let num_rows_required_for_fixed_table: usize = detect_fixed_table_tags(block)
.iter()
.map(|tag| tag.build::<F>().count())
.sum();
std::cmp::max(
num_rows_required_for_execution_steps,
num_rows_required_for_fixed_table,
)
}

/// Make the assignments to the EvmCircuit
fn synthesize_sub(
&self,
Expand All @@ -226,18 +241,42 @@ impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
}
}

/// create fixed_table_tags needed given witness block
pub(crate) fn detect_fixed_table_tags<F: Field>(block: &Block<F>) -> Vec<FixedTableTag> {
let need_bitwise_lookup = block.txs.iter().any(|tx| {
tx.steps.iter().any(|step| {
matches!(
step.opcode,
Some(OpcodeId::AND)
| Some(OpcodeId::OR)
| Some(OpcodeId::XOR)
| Some(OpcodeId::NOT)
)
})
});
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd | FixedTableTag::BitwiseOr | FixedTableTag::BitwiseXor
) || need_bitwise_lookup
})
.collect()
}

#[cfg(any(feature = "test", test))]
pub mod test {
use super::*;
use crate::{
evm_circuit::{table::FixedTableTag, witness::Block, EvmCircuitConfig},
evm_circuit::{witness::Block, EvmCircuitConfig},
exp_circuit::OFFSET_INCREMENT,
table::{BlockTable, BytecodeTable, CopyTable, ExpTable, KeccakTable, RwTable, TxTable},
util::{power_of_randomness_from_instance, Challenges},
witness::block_convert,
};
use bus_mapping::{circuit_input_builder::CircuitsParams, evm::OpcodeId, mock::BlockData};
use bus_mapping::{circuit_input_builder::CircuitsParams, mock::BlockData};
use eth_types::{geth_types::GethData, Field, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner, Value},
dev::{MockProver, VerifyFailure},
Expand All @@ -247,7 +286,6 @@ pub mod test {
distributions::uniform::{SampleRange, SampleUniform},
random, thread_rng, Rng,
};
use strum::IntoEnumIterator;

pub(crate) fn rand_range<T, R>(range: R) -> T
where
Expand All @@ -269,31 +307,6 @@ pub mod test {
Word::from_big_endian(&rand_bytes_array::<32>())
}

/// create fixed_table_tags needed given witness block
pub(crate) fn detect_fixed_table_tags<F: Field>(block: &Block<F>) -> Vec<FixedTableTag> {
let need_bitwise_lookup = block.txs.iter().any(|tx| {
tx.steps.iter().any(|step| {
matches!(
step.opcode,
Some(OpcodeId::AND)
| Some(OpcodeId::OR)
| Some(OpcodeId::XOR)
| Some(OpcodeId::NOT)
)
})
});
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd
| FixedTableTag::BitwiseOr
| FixedTableTag::BitwiseXor
) || need_bitwise_lookup
})
.collect()
}

impl<F: Field> Circuit<F> for EvmCircuit<F> {
type Config = EvmCircuitConfig<F>;
type FloorPlanner = SimpleFloorPlanner;
Expand Down Expand Up @@ -391,7 +404,7 @@ pub mod test {
builder
.handle_block(&block.eth_block, &block.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
run_test_circuit(block)
}

Expand All @@ -404,7 +417,7 @@ pub mod test {
builder
.handle_block(&block.eth_block, &block.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
run_test_circuit(block)
}

Expand Down Expand Up @@ -432,8 +445,6 @@ pub mod test {
.map(|e| e.steps.len() * OFFSET_INCREMENT)
.sum();

let log2_ceil = |n| u32::BITS - (n as u32).leading_zeros() - (n & (n - 1) == 0) as u32;

const NUM_BLINDING_ROWS: usize = 64;

let rows_needed: usize = itertools::max([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ mod test {
use eth_types::evm_types::OpcodeId;
use eth_types::geth_types::Account;
use eth_types::{address, bytecode, Address, ToWord, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use mock::TestContext;

fn test_invalid_jump(destination: usize, out_of_range: bool) {
Expand Down Expand Up @@ -448,7 +449,7 @@ mod test {
builder
.handle_block(&block_data.eth_block, &block_data.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(run_test_circuit(block), Ok(()));
}

Expand Down
3 changes: 2 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ mod test {
use eth_types::{address, bytecode};
use eth_types::{bytecode::Bytecode, evm_types::OpcodeId, geth_types::Account};
use eth_types::{Address, ToWord, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use itertools::Itertools;
use mock::TestContext;
use std::default::Default;
Expand Down Expand Up @@ -420,7 +421,7 @@ mod test {
builder
.handle_block(&block_data.eth_block, &block_data.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db);
let block = block_convert::<Fr>(&builder.block, &builder.code_db);
assert_eq!(run_test_circuit(block.unwrap()), Ok(()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ mod test {
builder
.handle_block(&block_data.eth_block, &block_data.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(run_test_circuit(block), Ok(()));
}

Expand Down
3 changes: 2 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/error_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ mod test {
use eth_types::{
self, address, bytecode, bytecode::Bytecode, geth_types::Account, Address, ToWord, Word,
};
use halo2_proofs::halo2curves::bn256::Fr;

use mock::TestContext;

Expand Down Expand Up @@ -320,7 +321,7 @@ mod test {
builder
.handle_block(&block_data.eth_block, &block_data.geth_traces)
.unwrap();
let block = block_convert(&builder.block, &builder.code_db);
let block = block_convert::<Fr>(&builder.block, &builder.code_db);
assert_eq!(run_test_circuit(block.unwrap()), Ok(()));
}

Expand Down
3 changes: 2 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ mod test {
};
use bus_mapping::mock::BlockData;
use eth_types::{address, bytecode, geth_types::GethData, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use mock::TestContext;

fn test_ok() {
Expand Down Expand Up @@ -150,7 +151,7 @@ mod test {
builder
.handle_block(&block.eth_block, &block.geth_traces)
.expect("could not handle block tx");
let mut block = block_convert(&builder.block, &builder.code_db).unwrap();
let mut block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();

// The above block has 2 steps (GAS and STOP). We forcefully assign a
// wrong `gas_left` value for the second step, to assert that
Expand Down
14 changes: 12 additions & 2 deletions zkevm-circuits/src/exp_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,15 @@ impl<F: Field> SubCircuit<F> for ExpCircuit<F> {
Self::new(block.clone())
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> usize {
block
.exp_events
.iter()
.map(|e| e.steps.len() * OFFSET_INCREMENT)
.sum()
}

/// Make the assignments to the ExpCircuit
fn synthesize_sub(
&self,
Expand Down Expand Up @@ -462,6 +471,7 @@ pub mod dev {
mod tests {
use bus_mapping::{circuit_input_builder::CircuitInputBuilder, evm::OpcodeId, mock::BlockData};
use eth_types::{bytecode, geth_types::GethData, Bytecode, Word};
use halo2_proofs::halo2curves::bn256::Fr;
use mock::TestContext;

use crate::{evm_circuit::witness::block_convert, exp_circuit::dev::test_exp_circuit};
Expand Down Expand Up @@ -499,14 +509,14 @@ mod tests {
fn test_ok(base: Word, exponent: Word, k: Option<u32>) {
let code = gen_code_single(base, exponent);
let builder = gen_data(code);
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_exp_circuit(k.unwrap_or(10), block), Ok(()));
}

fn test_ok_multiple(args: Vec<(Word, Word)>) {
let code = gen_code_multiple(args);
let builder = gen_data(code);
let block = block_convert(&builder.block, &builder.code_db).unwrap();
let block = block_convert::<Fr>(&builder.block, &builder.code_db).unwrap();
assert_eq!(test_exp_circuit(20, block), Ok(()));
}

Expand Down
12 changes: 11 additions & 1 deletion zkevm-circuits/src/keccak_circuit/keccak_packed_multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const THETA_C_LOOKUP_RANGE: usize = 6;
const RHO_PI_LOOKUP_RANGE: usize = 4;
const CHI_BASE_LOOKUP_RANGE: usize = 5;

fn get_num_rows_per_round() -> usize {
pub(crate) fn get_num_rows_per_round() -> usize {
var("KECCAK_ROWS")
.unwrap_or_else(|_| "5".to_string())
.parse()
Expand Down Expand Up @@ -370,6 +370,16 @@ impl<F: Field> SubCircuit<F> for KeccakCircuit<F> {
)
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> usize {
let rows_per_chunk = (NUM_ROUNDS + 1) * get_num_rows_per_round();
block
.keccak_inputs
.iter()
.map(|bytes| (bytes.len() as f64 / 136.0).ceil() as usize * rows_per_chunk)
.sum()
}

/// Make the assignments to the KeccakCircuit
fn synthesize_sub(
&self,
Expand Down
Loading