From 320f64fe34fcef097e4ffc0198c6db5bc3a47513 Mon Sep 17 00:00:00 2001 From: Velaciela Date: Fri, 9 Jun 2023 01:28:40 +0000 Subject: [PATCH 1/9] parallelize bytecode circuit assignment --- circuit-benchmarks/src/bytecode_circuit.rs | 27 ++++ zkevm-circuits/Cargo.toml | 2 +- .../circuit/to_poseidon_hash.rs | 149 ++++++++++++++---- 3 files changed, 144 insertions(+), 34 deletions(-) diff --git a/circuit-benchmarks/src/bytecode_circuit.rs b/circuit-benchmarks/src/bytecode_circuit.rs index 2996f21312..bc4c1b1525 100644 --- a/circuit-benchmarks/src/bytecode_circuit.rs +++ b/circuit-benchmarks/src/bytecode_circuit.rs @@ -51,6 +51,10 @@ mod tests { // Contract code size exceeds 24576 bytes may not be deployable on Mainnet. let bytecode_len = std::cmp::min(MAX_CODE_SIZE as usize, max_bytecode_row_num); let bytecodes_num: usize = max_bytecode_row_num / bytecode_len; + println!( + "Bytecode length: {}, Bytecodes number: {}", + bytecode_len, bytecodes_num + ); // Create the circuit let bytecode_circuit = TestBytecodeCircuit::::new( @@ -71,10 +75,32 @@ mod tests { let verifier_params: ParamsVerifierKZG = general_params.verifier_params().clone(); end_timer!(start1); + std::env::set_var("ASSIGNMENT_TYPE", "default"); + let assign_var = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); //.into(); + println!("assign_var: {}", assign_var); + + let assignment_type = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); + let is_parallel_assignment = match assignment_type.as_str() { + "default" => false, + "parallel" => true, + &_ => todo!(), + }; + println!("is_parallel_assignment: {}", is_parallel_assignment); + // Initialize the proving key let vk = keygen_vk(&general_params, &bytecode_circuit).expect("keygen_vk should not fail"); let pk = keygen_pk(&general_params, vk, &bytecode_circuit).expect("keygen_pk should not fail"); + std::env::set_var("ASSIGNMENT_TYPE", "parallel"); + let assign_var = std::env::var("ASSIGNMENT_TYPE"); //.ok().unwrap_or_default().into(); + println!("assign_var: {:?}", assign_var); + let assignment_type = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); + let is_parallel_assignment = match assignment_type.as_str() { + "default" => false, + "parallel" => true, + &_ => todo!(), + }; + println!("is_parallel_assignment: {}", is_parallel_assignment); // Create a proof let mut transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); @@ -123,6 +149,7 @@ mod tests { ) .expect("failed to verify bench circuit"); end_timer!(start3); + std::env::set_var("ASSIGNMENT_TYPE", "default"); } /// fill bytecodes_num * bytecode_len bytes to the witness table diff --git a/zkevm-circuits/Cargo.toml b/zkevm-circuits/Cargo.toml index 60f7b75684..5a863c0b2b 100644 --- a/zkevm-circuits/Cargo.toml +++ b/zkevm-circuits/Cargo.toml @@ -58,7 +58,7 @@ serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.78" [features] -default = ["test", "test-circuits", "enable-sign-verify"] +default = ["test", "test-circuits", "enable-sign-verify", "scroll", "halo2_proofs/parallel_syn"] test = ["ethers-signers", "mock", "bus-mapping/test"] # even if "scroll" feature is enabled, unittests use l1 geth to generate execution traces, # which cannot pass some constraints related to poseidon hash since codehash there is keccak hash. diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index 92adbd6ffd..6d660ea338 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -18,7 +18,7 @@ use halo2_proofs::{ use itertools::Itertools; use log::trace; use mpt_zktrie::hash::HASHABLE_DOMAIN_SPEC; -use std::vec; +use std::{time::Instant, vec}; use super::{ super::bytecode_unroller::{BytecodeRow, UnrolledBytecode}, @@ -433,44 +433,125 @@ impl ToHashBlockCircuitConfig false, + "parallel" => true, + &_ => todo!(), + }; + println!("is_parallel_assignment: {}", is_parallel_assignment); + + let mut offset = 0; + if is_parallel_assignment { + let part1_timer = Instant::now(); + let offsets = layouter.assign_regions( + || "assign(regions) bytecode with poseidon hash extension(part1)", + witness + .iter() + .map(|bytecode| { + let push_data_left_is_zero_chip = + IsZeroChip::construct(base_conf.push_data_left_is_zero.clone()); + let index_length_diff_is_zero_chip = + IsZeroChip::construct(base_conf.index_length_diff_is_zero.clone()); + move |region: Region<'_, F>| { + // |mut region| { + let mut offset = 0; + let mut row_input = F::zero(); + let mut region = region; + let bytecode_offset_begin = offset; + base_conf.assign_bytecode( &mut region, - offset, - row, - row_input, - bytecode.bytes.len(), + bytecode, + challenges, + &push_data_left_is_zero_chip, + &index_length_diff_is_zero_chip, + empty_hash, + &mut offset, + last_row_offset, + fail_fast, )?; + + for (idx, row) in bytecode.rows.iter().enumerate() { + // if the base_conf's assignment not fail fast, + // we also avoid the failure of "NotEnoughRowsAvailable" + // in prover creation (so bytecode_incomplete test could pass) + let offset = bytecode_offset_begin + idx; + if offset <= last_row_offset { + row_input = self.assign_extended_row( + &mut region, + offset, + row, + row_input, + bytecode.bytes.len(), + )?; + } + } + // println!("offset: {}", offset); + Ok(offset) } + }) + .collect_vec(), + )?; + println!("part1_timer: {:?}", part1_timer.elapsed()); + println!("offsets: {:?}", offsets); + + offset = offsets.into_iter().fold(0, |acc, x| acc + x); + println!("offset: {}", offset); + } else { + offset = layouter.assign_region( + || "assign bytecode with poseidon hash extension(part1)", + |mut region| { + let mut offset = 0; + let mut row_input = F::zero(); + println!("witness len: {}", witness.len()); + let part1_timer = Instant::now(); + for bytecode in witness.iter() { + let bytecode_offset_begin = offset; + base_conf.assign_bytecode( + &mut region, + bytecode, + challenges, + &push_data_left_is_zero_chip, + &index_length_diff_is_zero_chip, + empty_hash, + &mut offset, + last_row_offset, + fail_fast, + )?; + + for (idx, row) in bytecode.rows.iter().enumerate() { + // if the base_conf's assignment not fail fast, + // we also avoid the failure of "NotEnoughRowsAvailable" + // in prover creation (so bytecode_incomplete test could pass) + let offset = bytecode_offset_begin + idx; + if offset <= last_row_offset { + row_input = self.assign_extended_row( + &mut region, + offset, + row, + row_input, + bytecode.bytes.len(), + )?; + } + } + + println!(" offset: {}", offset); } - } + println!("part1_timer: {:?}", part1_timer.elapsed()); + Ok(offset) + }, + )?; + } + layouter.assign_region( + || "assign bytecode with poseidon hash extension(part2)", + |mut region| { + let part2_timer = Instant::now(); // Padding - for idx in offset..=last_row_offset { + // for idx in offset..=last_row_offset { + for idx in 0..=(last_row_offset - offset) { base_conf.set_padding_row( &mut region, &push_data_left_is_zero_chip, @@ -481,9 +562,11 @@ impl ToHashBlockCircuitConfig Date: Mon, 12 Jun 2023 17:47:13 +0000 Subject: [PATCH 2/9] calculate offset for 1st pass, unit test --- .github/workflows/ci.yml | 6 +- circuit-benchmarks/src/bytecode_circuit.rs | 27 -- zkevm-circuits/Cargo.toml | 3 +- .../src/bytecode_circuit/circuit.rs | 41 +++ .../circuit/to_poseidon_hash.rs | 251 +++++++++++------- zkevm-circuits/src/bytecode_circuit/test.rs | 152 ++++++++++- 6 files changed, 354 insertions(+), 126 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 348aa2c1fe..3ab6651a91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -134,7 +134,11 @@ jobs: with: command: test args: --verbose --release --features scroll --all --exclude integration-tests --exclude circuit-benchmarks serial_ -- --ignored - + - name: Run parallel assignment tests + uses: actions-rs/cargo@v1 + with: + command: test + args: --package zkevm-circuits --lib bytecode_circuit::test::bytecode_circuit_parallel_assignment --features scroll,parallel_syn -- --nocapture build: needs: [skip_check] diff --git a/circuit-benchmarks/src/bytecode_circuit.rs b/circuit-benchmarks/src/bytecode_circuit.rs index bc4c1b1525..2996f21312 100644 --- a/circuit-benchmarks/src/bytecode_circuit.rs +++ b/circuit-benchmarks/src/bytecode_circuit.rs @@ -51,10 +51,6 @@ mod tests { // Contract code size exceeds 24576 bytes may not be deployable on Mainnet. let bytecode_len = std::cmp::min(MAX_CODE_SIZE as usize, max_bytecode_row_num); let bytecodes_num: usize = max_bytecode_row_num / bytecode_len; - println!( - "Bytecode length: {}, Bytecodes number: {}", - bytecode_len, bytecodes_num - ); // Create the circuit let bytecode_circuit = TestBytecodeCircuit::::new( @@ -75,32 +71,10 @@ mod tests { let verifier_params: ParamsVerifierKZG = general_params.verifier_params().clone(); end_timer!(start1); - std::env::set_var("ASSIGNMENT_TYPE", "default"); - let assign_var = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); //.into(); - println!("assign_var: {}", assign_var); - - let assignment_type = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); - let is_parallel_assignment = match assignment_type.as_str() { - "default" => false, - "parallel" => true, - &_ => todo!(), - }; - println!("is_parallel_assignment: {}", is_parallel_assignment); - // Initialize the proving key let vk = keygen_vk(&general_params, &bytecode_circuit).expect("keygen_vk should not fail"); let pk = keygen_pk(&general_params, vk, &bytecode_circuit).expect("keygen_pk should not fail"); - std::env::set_var("ASSIGNMENT_TYPE", "parallel"); - let assign_var = std::env::var("ASSIGNMENT_TYPE"); //.ok().unwrap_or_default().into(); - println!("assign_var: {:?}", assign_var); - let assignment_type = std::env::var("ASSIGNMENT_TYPE").ok().unwrap_or_default(); - let is_parallel_assignment = match assignment_type.as_str() { - "default" => false, - "parallel" => true, - &_ => todo!(), - }; - println!("is_parallel_assignment: {}", is_parallel_assignment); // Create a proof let mut transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); @@ -149,7 +123,6 @@ mod tests { ) .expect("failed to verify bench circuit"); end_timer!(start3); - std::env::set_var("ASSIGNMENT_TYPE", "default"); } /// fill bytecodes_num * bytecode_len bytes to the witness table diff --git a/zkevm-circuits/Cargo.toml b/zkevm-circuits/Cargo.toml index 5a863c0b2b..202497c3c2 100644 --- a/zkevm-circuits/Cargo.toml +++ b/zkevm-circuits/Cargo.toml @@ -58,7 +58,7 @@ serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.78" [features] -default = ["test", "test-circuits", "enable-sign-verify", "scroll", "halo2_proofs/parallel_syn"] +default = ["test", "test-circuits", "enable-sign-verify"] test = ["ethers-signers", "mock", "bus-mapping/test"] # even if "scroll" feature is enabled, unittests use l1 geth to generate execution traces, # which cannot pass some constraints related to poseidon hash since codehash there is keccak hash. @@ -77,3 +77,4 @@ zktrie = [] enable-sign-verify = [] reject-eip2718 = [] poseidon-codehash = [] +parallel_syn = ["halo2_proofs/parallel_syn"] diff --git a/zkevm-circuits/src/bytecode_circuit/circuit.rs b/zkevm-circuits/src/bytecode_circuit/circuit.rs index 6510c590ee..467af2beab 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit.rs @@ -609,6 +609,47 @@ impl BytecodeCircuitConfig { Ok(()) } + #[allow(clippy::too_many_arguments)] + fn set_shape_and_offset( + &self, + region: &mut Region<'_, F>, + bytecode: &UnrolledBytecode, + column: Column, + offset: &mut usize, + last_row_offset: usize, + fail_fast: bool, + ) -> Result<(), Error> { + // Calculate the region shape for 1st pass in `fn assign_region()` + // The the `offset` accumulation logic is consistent with `fn assign_bytecode()` + // This function avoids redundant operations, set the offset value to `region` via + // `region.assign_advice` + for _ in bytecode.rows.iter() { + if fail_fast && *offset > last_row_offset { + log::error!( + "Bytecode Circuit: offset={} > last_row_offset={}", + offset, + last_row_offset + ); + return Err(Error::Synthesis); + } + // Set the data for this row + if *offset < last_row_offset { + *offset += 1; + } + } + + let assign_offset = if *offset > 0 { *offset - 1 } else { *offset }; + + region.assign_advice( + || "dummy", + column, + assign_offset, + || Value::known(F::zero()), + )?; + + Ok(()) + } + #[allow(clippy::too_many_arguments)] fn assign_bytecode( &self, diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index 6d660ea338..d82a634b43 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -405,6 +405,53 @@ impl ToHashBlockCircuitConfig, + region: &mut Region<'_, F>, + bytecode: &UnrolledBytecode, + challenges: &Challenges>, + push_data_left_is_zero_chip: &IsZeroChip, + index_length_diff_is_zero_chip: &IsZeroChip, + empty_hash: Value, + row_input: &mut F, + offset: &mut usize, + last_row_offset: usize, + fail_fast: bool, + ) -> Result<(), Error> { + let bytecode_offset_begin = *offset; + base_conf.assign_bytecode( + region, + bytecode, + challenges, + push_data_left_is_zero_chip, + index_length_diff_is_zero_chip, + empty_hash, + offset, + last_row_offset, + fail_fast, + )?; + + for (idx, row) in bytecode.rows.iter().enumerate() { + // if the base_conf's assignment not fail fast, + // we also avoid the failure of "NotEnoughRowsAvailable" + // in prover creation (so bytecode_incomplete test could pass) + let offset = bytecode_offset_begin + idx; + if offset <= last_row_offset { + *row_input = self.assign_extended_row( + region, + offset, + row, + *row_input, + bytecode.bytes.len(), + )?; + } + } + + Ok(()) + } + pub(crate) fn assign_internal( &self, layouter: &mut impl Layouter, @@ -414,6 +461,28 @@ impl ToHashBlockCircuitConfig>, fail_fast: bool, ) -> Result<(), Error> { + let assignment_type = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") + .ok() + .unwrap_or_default(); + let is_force_serial_assignment = match assignment_type.as_str() { + "serial" => true, + &_ => false, + }; + let mut is_parallel_assignment = false; + #[cfg(feature = "parallel_syn")] + { + is_parallel_assignment = true; + } + log::debug!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assignment_type); + log::debug!("is_force_serial_assignment: {}", is_force_serial_assignment); + log::debug!("is_parallel_assignment: {}", is_parallel_assignment); + + if !is_force_serial_assignment && is_parallel_assignment { + return self.assign_internal_parallel( + layouter, size, witness, overwrite, challenges, fail_fast, + ); + } + let base_conf = &self.base_conf; let push_data_left_is_zero_chip = IsZeroChip::construct(base_conf.push_data_left_is_zero.clone()); @@ -433,124 +502,120 @@ impl ToHashBlockCircuitConfig false, - "parallel" => true, - &_ => todo!(), - }; - println!("is_parallel_assignment: {}", is_parallel_assignment); + // Padding + for idx in offset..=last_row_offset { + base_conf.set_padding_row( + &mut region, + &push_data_left_is_zero_chip, + &index_length_diff_is_zero_chip, + empty_hash, + idx, + last_row_offset, + )?; + self.set_header_row(&mut region, 0, idx)?; + } + + base_conf.assign_overwrite(&mut region, overwrite, challenges)?; + + Ok(()) + }, + ) + } + + pub(crate) fn assign_internal_parallel( + &self, + layouter: &mut impl Layouter, + size: usize, + witness: &[UnrolledBytecode], + overwrite: &UnrolledBytecode, + challenges: &Challenges>, + fail_fast: bool, + ) -> Result<(), Error> { + let base_conf = &self.base_conf; + let push_data_left_is_zero_chip = + IsZeroChip::construct(base_conf.push_data_left_is_zero.clone()); + let index_length_diff_is_zero_chip = + IsZeroChip::construct(base_conf.index_length_diff_is_zero.clone()); + + // Subtract the unusable rows from the size + assert!(size > base_conf.minimum_rows); + let last_row_offset = size - base_conf.minimum_rows + 1; + let empty_hash = Value::known(POSEIDON_CODE_HASH_ZERO.to_word().to_scalar().unwrap()); let mut offset = 0; - if is_parallel_assignment { - let part1_timer = Instant::now(); - let offsets = layouter.assign_regions( - || "assign(regions) bytecode with poseidon hash extension(part1)", - witness - .iter() - .map(|bytecode| { - let push_data_left_is_zero_chip = - IsZeroChip::construct(base_conf.push_data_left_is_zero.clone()); - let index_length_diff_is_zero_chip = - IsZeroChip::construct(base_conf.index_length_diff_is_zero.clone()); - move |region: Region<'_, F>| { - // |mut region| { - let mut offset = 0; - let mut row_input = F::zero(); - let mut region = region; - let bytecode_offset_begin = offset; - base_conf.assign_bytecode( + let mut first_pass_vec = vec![true; witness.len()]; + let offsets = layouter.assign_regions( + || "assign(regions) bytecode with poseidon hash extension(part1)", + witness + .iter() + .zip(first_pass_vec.iter_mut()) + .map(|(bytecode, first_pass)| { + let push_data_left_is_zero_chip = push_data_left_is_zero_chip.clone(); + let index_length_diff_is_zero_chip = index_length_diff_is_zero_chip.clone(); + move |region: Region<'_, F>| { + let mut offset = 0; + let mut region = region; + + if *first_pass { + *first_pass = false; + base_conf.set_shape_and_offset( &mut region, bytecode, - challenges, - &push_data_left_is_zero_chip, - &index_length_diff_is_zero_chip, - empty_hash, + self.field_input.clone(), &mut offset, last_row_offset, fail_fast, )?; - - for (idx, row) in bytecode.rows.iter().enumerate() { - // if the base_conf's assignment not fail fast, - // we also avoid the failure of "NotEnoughRowsAvailable" - // in prover creation (so bytecode_incomplete test could pass) - let offset = bytecode_offset_begin + idx; - if offset <= last_row_offset { - row_input = self.assign_extended_row( - &mut region, - offset, - row, - row_input, - bytecode.bytes.len(), - )?; - } - } - // println!("offset: {}", offset); - Ok(offset) + return Ok(offset); } - }) - .collect_vec(), - )?; - println!("part1_timer: {:?}", part1_timer.elapsed()); - println!("offsets: {:?}", offsets); - - offset = offsets.into_iter().fold(0, |acc, x| acc + x); - println!("offset: {}", offset); - } else { - offset = layouter.assign_region( - || "assign bytecode with poseidon hash extension(part1)", - |mut region| { - let mut offset = 0; - let mut row_input = F::zero(); - println!("witness len: {}", witness.len()); - let part1_timer = Instant::now(); - for bytecode in witness.iter() { - let bytecode_offset_begin = offset; - base_conf.assign_bytecode( + + let mut row_input = F::zero(); + self.assign_bytecode_and_extend( + base_conf, &mut region, bytecode, challenges, &push_data_left_is_zero_chip, &index_length_diff_is_zero_chip, empty_hash, + &mut row_input, &mut offset, last_row_offset, fail_fast, )?; - for (idx, row) in bytecode.rows.iter().enumerate() { - // if the base_conf's assignment not fail fast, - // we also avoid the failure of "NotEnoughRowsAvailable" - // in prover creation (so bytecode_incomplete test could pass) - let offset = bytecode_offset_begin + idx; - if offset <= last_row_offset { - row_input = self.assign_extended_row( - &mut region, - offset, - row, - row_input, - bytecode.bytes.len(), - )?; - } - } - - println!(" offset: {}", offset); + Ok(offset) } - println!("part1_timer: {:?}", part1_timer.elapsed()); - Ok(offset) - }, - )?; - } + }) + .collect_vec(), + )?; + offset = offsets.into_iter().fold(0, |acc, x| acc + x); layouter.assign_region( || "assign bytecode with poseidon hash extension(part2)", |mut region| { - let part2_timer = Instant::now(); // Padding - // for idx in offset..=last_row_offset { for idx in 0..=(last_row_offset - offset) { base_conf.set_padding_row( &mut region, @@ -562,11 +627,7 @@ impl ToHashBlockCircuitConfig::run(k, &circuit, Vec::new()).unwrap(); prover.assert_satisfied_par(); } + +/// fill bytecodes_num * bytecode_len bytes to the witness table +fn fillup_codebytes( + bytecodes_num: usize, + bytecode_len: usize, +) -> Vec> { + fn valid_or(base: OpcodeId, or: OpcodeId) -> OpcodeId { + match base { + OpcodeId::INVALID(_) => or, + _ => base, + } + } + + let mut codebytes = vec![]; + (0..bytecodes_num).for_each(|_| { + let bytecodes = (0..bytecode_len) + .map(|v| valid_or(OpcodeId::from(v as u8), OpcodeId::STOP).as_u8()) + .collect::>(); + let unrolled_bytes = unroll::(bytecodes); + codebytes.push(unrolled_bytes); + }); + codebytes +} + +fn set_unit_test_env_var(value: &str) { + std::env::set_var("UNIT_TEST_ASSIGNMENT_TYPE", value); + let assign_var = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") + .ok() + .unwrap_or_default(); + log::info!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assign_var); +} + +/// Bytecode circuit parallel assignment test +/// modiefied from `fn bench_bytecode_circuit_prover()` +/// in: circuit-benchmarks/src/bytecode_circuit.rs +/// +/// Run with: +/// `cargo test --package zkevm-circuits --lib +/// bytecode_circuit::test::bytecode_circuit_parallel_assignment --features scroll,parallel_syn -- +/// --nocapture` +#[test] +#[cfg(feature = "scroll")] +#[cfg(feature = "parallel_syn")] +fn bytecode_circuit_parallel_assignment() { + // Contract code size exceeds 24576 bytes may not be deployable on Mainnet. + const MAX_BYTECODE_LEN: usize = 4096; + + let degree: u32 = 15; + let num_rows = 1 << degree; + const NUM_BLINDING_ROWS: usize = 7 - 1; + let max_bytecode_row_num = num_rows - NUM_BLINDING_ROWS; + let bytecode_len = std::cmp::min(MAX_BYTECODE_LEN, max_bytecode_row_num); + let bytecodes_num: usize = max_bytecode_row_num / bytecode_len; + log::info!( + "Bytecode length: {}, Bytecodes number: {}", + bytecode_len, + bytecodes_num + ); + + // Create the circuit + let bytecode_circuit = TestBytecodeCircuit::::new( + fillup_codebytes(bytecodes_num, bytecode_len), + 2usize.pow(degree), + ); + + // Initialize the polynomial commitment parameters + let mut rng = XorShiftRng::from_seed([ + 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, + 0xe5, + ]); + + // Setup generation + log::info!( + "test bytecode circuit parallel assignment with degree = {}", + degree + ); + let general_params = ParamsKZG::::setup(degree, &mut rng); + let verifier_params: ParamsVerifierKZG = general_params.verifier_params().clone(); + + // Initialize the proving key + // The serial assignment is used to generate pk and vk, + // which are then used to verify the proof generated by the parallel assignment + set_unit_test_env_var("serial"); + let vk = keygen_vk(&general_params, &bytecode_circuit).expect("keygen_vk should not fail"); + let pk = keygen_pk(&general_params, vk, &bytecode_circuit).expect("keygen_pk should not fail"); + + // Create a proof + let mut transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); + + // Proof generation + // Set parallel assignment env var + set_unit_test_env_var("parallel"); + create_proof::< + KZGCommitmentScheme, + ProverSHPLONK<'_, Bn256>, + Challenge255, + XorShiftRng, + Blake2bWrite, G1Affine, Challenge255>, + TestBytecodeCircuit, + >( + &general_params, + &pk, + &[bytecode_circuit], + &[&[]], + rng, + &mut transcript, + ) + .expect("proof generation should not fail"); + let proof = transcript.finalize(); + + 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, + pk.get_vk(), + strategy, + &[&[]], + &mut verifier_transcript, + ) + .expect("failed to verify bench circuit"); + + set_unit_test_env_var(""); +} From 098b2b342a16d4f05a00ca6a9ce8193abf945cb4 Mon Sep 17 00:00:00 2001 From: Velaciela Date: Tue, 13 Jun 2023 01:30:38 +0000 Subject: [PATCH 3/9] dummy offset --- zkevm-circuits/src/bytecode_circuit/circuit.rs | 9 +-------- .../src/bytecode_circuit/circuit/to_poseidon_hash.rs | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/zkevm-circuits/src/bytecode_circuit/circuit.rs b/zkevm-circuits/src/bytecode_circuit/circuit.rs index 467af2beab..2ddfb24ae4 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit.rs @@ -638,14 +638,7 @@ impl BytecodeCircuitConfig { } } - let assign_offset = if *offset > 0 { *offset - 1 } else { *offset }; - - region.assign_advice( - || "dummy", - column, - assign_offset, - || Value::known(F::zero()), - )?; + region.assign_advice(|| "dummy", column, *offset - 1, || Value::known(F::zero()))?; Ok(()) } diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index d82a634b43..30a5f48f61 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -18,7 +18,7 @@ use halo2_proofs::{ use itertools::Itertools; use log::trace; use mpt_zktrie::hash::HASHABLE_DOMAIN_SPEC; -use std::{time::Instant, vec}; +use std::vec; use super::{ super::bytecode_unroller::{BytecodeRow, UnrolledBytecode}, @@ -406,6 +406,7 @@ impl ToHashBlockCircuitConfig, From b22004eddaf60ae9019a7f6dd48289c61cdf96ce Mon Sep 17 00:00:00 2001 From: Velaciela Date: Thu, 15 Jun 2023 08:03:45 +0000 Subject: [PATCH 4/9] simplify and lint --- .../circuit/to_poseidon_hash.rs | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index 30a5f48f61..18412419fc 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -405,7 +405,10 @@ impl ToHashBlockCircuitConfig ToHashBlockCircuitConfig Result<(), Error> { let bytecode_offset_begin = *offset; + base_conf.assign_bytecode( region, bytecode, @@ -462,26 +466,28 @@ impl ToHashBlockCircuitConfig>, fail_fast: bool, ) -> Result<(), Error> { - let assignment_type = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") - .ok() - .unwrap_or_default(); - let is_force_serial_assignment = match assignment_type.as_str() { - "serial" => true, - &_ => false, - }; - let mut is_parallel_assignment = false; + // if feature "parallel_syn" is enabled, we will use parallel assignment #[cfg(feature = "parallel_syn")] { - is_parallel_assignment = true; - } - log::debug!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assignment_type); - log::debug!("is_force_serial_assignment: {}", is_force_serial_assignment); - log::debug!("is_parallel_assignment: {}", is_parallel_assignment); - - if !is_force_serial_assignment && is_parallel_assignment { - return self.assign_internal_parallel( - layouter, size, witness, overwrite, challenges, fail_fast, - ); + // `is_force_serial_assignment` is used for unit test + // it's determined by the environment variable `UNIT_TEST_ASSIGNMENT_TYPE` + // if enabled, we will bypass the parallel assignment + // and use serial assignment instead + let assignment_type = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") + .ok() + .unwrap_or_default(); + let is_force_serial_assignment = match assignment_type.as_str() { + "serial" => true, + &_ => false, + }; + log::debug!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assignment_type); + log::debug!("is_force_serial_assignment: {}", is_force_serial_assignment); + + if !is_force_serial_assignment { + return self.assign_internal_parallel( + layouter, size, witness, overwrite, challenges, fail_fast, + ); + } } let base_conf = &self.base_conf; @@ -544,6 +550,7 @@ impl ToHashBlockCircuitConfig, @@ -564,26 +571,25 @@ impl ToHashBlockCircuitConfig| { let mut offset = 0; let mut region = region; - if *first_pass { - *first_pass = false; + if *is_first_time { + *is_first_time = false; base_conf.set_shape_and_offset( &mut region, bytecode, - self.field_input.clone(), + self.field_input, &mut offset, last_row_offset, fail_fast, @@ -611,8 +617,8 @@ impl ToHashBlockCircuitConfig(); layouter.assign_region( || "assign bytecode with poseidon hash extension(part2)", |mut region| { From 729dffe053cd6119064fa7a7ada4c362d0a2834c Mon Sep 17 00:00:00 2001 From: kunxian xia Date: Fri, 30 Jun 2023 21:14:42 +0800 Subject: [PATCH 5/9] bug fix: padding region's last_row_offset --- .../src/bytecode_circuit/circuit/to_poseidon_hash.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index 18412419fc..a50a910a72 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -623,7 +623,8 @@ impl ToHashBlockCircuitConfig Date: Wed, 5 Jul 2023 15:51:38 +0000 Subject: [PATCH 6/9] ci --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ab6651a91..450627be75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -134,12 +134,16 @@ jobs: with: command: test args: --verbose --release --features scroll --all --exclude integration-tests --exclude circuit-benchmarks serial_ -- --ignored - - name: Run parallel assignment tests + - name: Run parallel assignment tests(bytecode) uses: actions-rs/cargo@v1 with: command: test - args: --package zkevm-circuits --lib bytecode_circuit::test::bytecode_circuit_parallel_assignment --features scroll,parallel_syn -- --nocapture - + args: --release --package zkevm-circuits --lib bytecode_circuit::test --features scroll,parallel_syn -- --nocapture + - name: Run parallel assignment tests(state) + uses: actions-rs/cargo@v1 + with: + command: test + args: --release --package zkevm-circuits --lib state_circuit::test --features scroll,parallel_syn -- --nocapture build: needs: [skip_check] if: | From e3516e6c0016c6254db7bf6d930d0f8bab48be62 Mon Sep 17 00:00:00 2001 From: Velaciela Date: Wed, 5 Jul 2023 16:14:18 +0000 Subject: [PATCH 7/9] fix bytecode errors --- .../src/bytecode_circuit/circuit.rs | 65 ++---- .../circuit/to_poseidon_hash.rs | 215 ++++++++++-------- zkevm-circuits/src/bytecode_circuit/test.rs | 15 +- 3 files changed, 148 insertions(+), 147 deletions(-) diff --git a/zkevm-circuits/src/bytecode_circuit/circuit.rs b/zkevm-circuits/src/bytecode_circuit/circuit.rs index 87bd958fef..bf852f8a6b 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit.rs @@ -533,6 +533,7 @@ impl BytecodeCircuitConfig { &push_data_left_is_zero_chip, &index_length_diff_is_zero_chip, empty_hash, + 0, &mut offset, last_row_offset, fail_fast, @@ -610,40 +611,6 @@ impl BytecodeCircuitConfig { Ok(()) } - #[allow(clippy::too_many_arguments)] - fn set_shape_and_offset( - &self, - region: &mut Region<'_, F>, - bytecode: &UnrolledBytecode, - column: Column, - offset: &mut usize, - last_row_offset: usize, - fail_fast: bool, - ) -> Result<(), Error> { - // Calculate the region shape for 1st pass in `fn assign_region()` - // The the `offset` accumulation logic is consistent with `fn assign_bytecode()` - // This function avoids redundant operations, set the offset value to `region` via - // `region.assign_advice` - for _ in bytecode.rows.iter() { - if fail_fast && *offset > last_row_offset { - log::error!( - "Bytecode Circuit: offset={} > last_row_offset={}", - offset, - last_row_offset - ); - return Err(Error::Synthesis); - } - // Set the data for this row - if *offset < last_row_offset { - *offset += 1; - } - } - - region.assign_advice(|| "dummy", column, *offset - 1, || Value::known(F::zero()))?; - - Ok(()) - } - #[allow(clippy::too_many_arguments)] fn assign_bytecode( &self, @@ -653,6 +620,7 @@ impl BytecodeCircuitConfig { push_data_left_is_zero_chip: &IsZeroChip, index_length_diff_is_zero_chip: &IsZeroChip, empty_hash: Value, + offset_begin: usize, offset: &mut usize, last_row_offset: usize, fail_fast: bool, @@ -675,10 +643,13 @@ impl BytecodeCircuitConfig { }); for (idx, row) in bytecode.rows.iter().enumerate() { - if fail_fast && *offset > last_row_offset { + // for serial assignment api assign_region(), offset always begins with 0 + // `offset` == global_offset + let global_offset = *offset + offset_begin; + if fail_fast && global_offset > last_row_offset { log::error!( - "Bytecode Circuit: offset={} > last_row_offset={}", - offset, + "Bytecode Circuit: global_offset={} > last_row_offset={}", + global_offset, last_row_offset ); return Err(Error::Synthesis); @@ -704,14 +675,14 @@ impl BytecodeCircuitConfig { } // Set the data for this row - if *offset < last_row_offset { + if global_offset < last_row_offset { self.set_row( region, push_data_left_is_zero_chip, index_length_diff_is_zero_chip, *offset, true, - *offset == last_row_offset, + global_offset == last_row_offset, code_hash, row.tag, row.index, @@ -725,8 +696,8 @@ impl BytecodeCircuitConfig { /* trace!( "bytecode.set_row({}): last:{} h:{:?} t:{:?} i:{:?} c:{:?} v:{:?} pdl:{} rlc:{:?} l:{:?} pds:{:?}", - offset, - offset == last_row_offset, + global_offset, + global_offset == last_row_offset, code_hash, row.tag.get_lower_32(), row.index.get_lower_32(), @@ -742,14 +713,22 @@ impl BytecodeCircuitConfig { *offset += 1; push_data_left = next_push_data_left } - if *offset == last_row_offset { + + let global_offset = *offset + offset_begin; + if global_offset == last_row_offset { + // for serial assignment api assign_region(), offset always begins with 0 + // `offset` == global_offset, + // so set `offset` here is equivalent to set `last_row_offset` + // if assign_bytecode() is called by assign_regions() + // the rows are divided into multiple regions, + // so the maximum value is the accumulated offset self.set_padding_row( region, push_data_left_is_zero_chip, index_length_diff_is_zero_chip, empty_hash, *offset, - last_row_offset, + *offset, )?; } } diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index b89cbe002c..ec0b48b59c 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -24,6 +24,8 @@ use super::{ BytecodeCircuitConfig, BytecodeCircuitConfigArgs, }; +use itertools::Itertools; + #[derive(Clone, Debug)] /// Bytecode circuit (for hash block) configuration /// basically the BytecodeCircuit include two parts: @@ -405,58 +407,6 @@ impl ToHashBlockCircuitConfig, - region: &mut Region<'_, F>, - bytecode: &UnrolledBytecode, - challenges: &Challenges>, - push_data_left_is_zero_chip: &IsZeroChip, - index_length_diff_is_zero_chip: &IsZeroChip, - empty_hash: Value, - row_input: &mut F, - offset: &mut usize, - last_row_offset: usize, - fail_fast: bool, - ) -> Result<(), Error> { - let bytecode_offset_begin = *offset; - - base_conf.assign_bytecode( - region, - bytecode, - challenges, - push_data_left_is_zero_chip, - index_length_diff_is_zero_chip, - empty_hash, - offset, - last_row_offset, - fail_fast, - )?; - - for (idx, row) in bytecode.rows.iter().enumerate() { - // if the base_conf's assignment not fail fast, - // we also avoid the failure of "NotEnoughRowsAvailable" - // in prover creation (so bytecode_incomplete test could pass) - let offset = bytecode_offset_begin + idx; - if offset <= last_row_offset { - *row_input = self.assign_extended_row( - region, - offset, - row, - *row_input, - bytecode.bytes.len(), - )?; - } - } - - Ok(()) - } - pub(crate) fn assign_internal( &self, layouter: &mut impl Layouter, @@ -466,24 +416,24 @@ impl ToHashBlockCircuitConfig>, fail_fast: bool, ) -> Result<(), Error> { - // if feature "parallel_syn" is enabled, we will use parallel assignment #[cfg(feature = "parallel_syn")] { - // `is_force_serial_assignment` is used for unit test - // it's determined by the environment variable `UNIT_TEST_ASSIGNMENT_TYPE` - // if enabled, we will bypass the parallel assignment - // and use serial assignment instead - let assignment_type = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") + // if feature "parallel_syn" is enabled, + // `parallel` assignment is turned on by default + // we can turn it off by set the environment variable + // `CIRCUIT_ASSIGNMENT_TYPE=serial` + let assignment_type = std::env::var("CIRCUIT_ASSIGNMENT_TYPE") .ok() .unwrap_or_default(); - let is_force_serial_assignment = match assignment_type.as_str() { - "serial" => true, - &_ => false, + let is_parallel_assignment = match assignment_type.as_str() { + "serial" => false, + "parallel" => true, + &_ => true, }; - log::debug!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assignment_type); - log::debug!("is_force_serial_assignment: {}", is_force_serial_assignment); + log::debug!("CIRCUIT_ASSIGNMENT_TYPE: {}", assignment_type); + log::debug!("is_parallel_assignment: {}", is_parallel_assignment); - if !is_force_serial_assignment { + if is_parallel_assignment { return self.assign_internal_parallel( layouter, size, witness, overwrite, challenges, fail_fast, ); @@ -509,25 +459,55 @@ impl ToHashBlockCircuitConfig ToHashBlockCircuitConfig>(); + + //start from 0 + let offsets_prefix_sum = [0] + .iter() + .chain(offsets_of_each_witness.iter()) + .scan(0, |sum, &x| { + *sum += x; + Some(*sum) + }) + .collect::>(); + + layouter.assign_regions( + || "assign bytecode with poseidon hash extension(part1: regions)", witness .iter() .zip(is_first_time_vec.iter_mut()) - .map(|(bytecode, is_first_time)| { + .enumerate() + .map(|(idx, (bytecode, is_first_time))| { let push_data_left_is_zero_chip = push_data_left_is_zero_chip.clone(); let index_length_diff_is_zero_chip = index_length_diff_is_zero_chip.clone(); + let offsets_prefix_sum = offsets_prefix_sum.clone(); move |region: Region<'_, F>| { let mut offset = 0; let mut region = region; if *is_first_time { *is_first_time = false; - base_conf.set_shape_and_offset( + let mut dummy_offset = bytecode.rows.len() - 1; + // last witness + if idx == witness.len() - 1 { + dummy_offset = last_row_offset - offsets_prefix_sum[idx]; + } + base_conf.set_padding_row( &mut region, - bytecode, - self.field_input, - &mut offset, - last_row_offset, - fail_fast, + &push_data_left_is_zero_chip, + &index_length_diff_is_zero_chip, + empty_hash, + dummy_offset, + dummy_offset, )?; - return Ok(offset); + return Ok(()); } - let mut row_input = F::zero(); - self.assign_bytecode_and_extend( - base_conf, + base_conf.assign_bytecode( &mut region, bytecode, challenges, &push_data_left_is_zero_chip, &index_length_diff_is_zero_chip, empty_hash, - &mut row_input, + offsets_prefix_sum[idx], &mut offset, last_row_offset, fail_fast, )?; - Ok(offset) + let last_offset = last_row_offset - offsets_prefix_sum[idx]; + // last witness + if idx == witness.len() - 1 { + // Padding + for idx in offset..=last_offset { + base_conf.set_padding_row( + &mut region, + &push_data_left_is_zero_chip, + &index_length_diff_is_zero_chip, + empty_hash, + idx, + last_offset, + )?; + self.set_header_row(&mut region, 0, idx)?; + } + + base_conf.assign_overwrite(&mut region, overwrite, challenges)?; + } + + Ok(()) } }) .collect_vec(), )?; - let offset = offsets.into_iter().sum::(); layouter.assign_region( || "assign bytecode with poseidon hash extension(part2)", |mut region| { - // Padding - let last_row_offset = last_row_offset - offset; - for idx in 0..=last_row_offset { - base_conf.set_padding_row( - &mut region, - &push_data_left_is_zero_chip, - &index_length_diff_is_zero_chip, - empty_hash, - idx, - last_row_offset, - )?; - self.set_header_row(&mut region, 0, idx)?; + let mut row_input = F::zero(); + for (witness_idx, bytecode) in witness.iter().enumerate() { + for (idx, row) in bytecode.rows.iter().enumerate() { + // if the base_conf's assignment not fail fast, + // we also avoid the failure of "NotEnoughRowsAvailable" + // in prover creation (so bytecode_incomplete test could pass) + let offset = offsets_prefix_sum[witness_idx] + idx; + if offset <= last_row_offset { + row_input = self.assign_extended_row( + &mut region, + offset, + row, + row_input, + bytecode.bytes.len(), + )?; + } + } } - base_conf.assign_overwrite(&mut region, overwrite, challenges)?; Ok(()) }, ) diff --git a/zkevm-circuits/src/bytecode_circuit/test.rs b/zkevm-circuits/src/bytecode_circuit/test.rs index a009c6b14c..6043ae7e44 100644 --- a/zkevm-circuits/src/bytecode_circuit/test.rs +++ b/zkevm-circuits/src/bytecode_circuit/test.rs @@ -64,7 +64,6 @@ pub fn test_bytecode_circuit_unrolled( success: bool, ) { let circuit = BytecodeCircuit::::new(bytecodes, 2usize.pow(k)); - let prover = MockProver::::run(k, &circuit, Vec::new()).unwrap(); let result = prover.verify_par(); if let Err(failures) = &result { @@ -369,12 +368,12 @@ fn fillup_codebytes( codebytes } -fn set_unit_test_env_var(value: &str) { - std::env::set_var("UNIT_TEST_ASSIGNMENT_TYPE", value); - let assign_var = std::env::var("UNIT_TEST_ASSIGNMENT_TYPE") +fn set_assignment_env_var(value: &str) { + std::env::set_var("CIRCUIT_ASSIGNMENT_TYPE", value); + let assign_var = std::env::var("CIRCUIT_ASSIGNMENT_TYPE") .ok() .unwrap_or_default(); - log::info!("UNIT_TEST_ASSIGNMENT_TYPE: {}", assign_var); + log::info!("CIRCUIT_ASSIGNMENT_TYPE: {}", assign_var); } /// Bytecode circuit parallel assignment test @@ -427,7 +426,7 @@ fn bytecode_circuit_parallel_assignment() { // Initialize the proving key // The serial assignment is used to generate pk and vk, // which are then used to verify the proof generated by the parallel assignment - set_unit_test_env_var("serial"); + set_assignment_env_var("serial"); let vk = keygen_vk(&general_params, &bytecode_circuit).expect("keygen_vk should not fail"); let pk = keygen_pk(&general_params, vk, &bytecode_circuit).expect("keygen_pk should not fail"); @@ -436,7 +435,7 @@ fn bytecode_circuit_parallel_assignment() { // Proof generation // Set parallel assignment env var - set_unit_test_env_var("parallel"); + set_assignment_env_var("parallel"); create_proof::< KZGCommitmentScheme, ProverSHPLONK<'_, Bn256>, @@ -472,5 +471,5 @@ fn bytecode_circuit_parallel_assignment() { ) .expect("failed to verify bench circuit"); - set_unit_test_env_var(""); + set_assignment_env_var(""); } From d3bfc3c181097cb2248ecea7f44a8affa28830d1 Mon Sep 17 00:00:00 2001 From: Velaciela Date: Wed, 5 Jul 2023 17:23:24 +0000 Subject: [PATCH 8/9] lint --- zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs index ec0b48b59c..764b649d8d 100644 --- a/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs +++ b/zkevm-circuits/src/bytecode_circuit/circuit/to_poseidon_hash.rs @@ -292,7 +292,6 @@ impl ToHashBlockCircuitConfig, inp_i: usize| { debug_assert_eq!(PoseidonTable::INPUT_WIDTH, 2); From 82e1ffb5f3e91ea797077aa2a9cb941a63ecf9d0 Mon Sep 17 00:00:00 2001 From: Velaciela Date: Thu, 6 Jul 2023 03:42:12 +0000 Subject: [PATCH 9/9] update halo2 --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8db30a4681..6b89b0d6d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "halo2_proofs" version = "0.2.0" -source = "git+https://github.com/scroll-tech/halo2.git?branch=develop#aab39d5c107fdeec62ce7d2aeec6b72de681ba23" +source = "git+https://github.com/scroll-tech/halo2.git?branch=develop#103ce21d85e0c8624597d51907d3313fde424fff" dependencies = [ "ark-std", "blake2b_simd",