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

Commit

Permalink
Pad StateCircuit to a fixed length (#558)
Browse files Browse the repository at this point in the history
* Add failing test

* Add Rw::Padding

* Add padding rows to state circuit to fix test

* Fix degree test and add comment

* Add rw_counter to Start for padding

* Ignore start test for now

* Remove Rw::Padding

* Fix test and cleanup

* Add rw_counter constraint for Rw::Start and comment

* Allow overrides in padding

* Update tests

* Make state circuit generic over N_ROWS and fix constraint names

* Fix tests and build

Co-authored-by: z2trillion <[email protected]>
  • Loading branch information
z2trillion and z2trillion authored Jun 21, 2022
1 parent 50c5194 commit 2aa9875
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 56 deletions.
2 changes: 1 addition & 1 deletion circuit-benchmarks/src/state_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod tests {
#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
fn bench_state_circuit_prover() {
let empty_circuit = StateCircuit::<Fr>::default();
let empty_circuit = StateCircuit::<Fr, { 1 << 16 }>::default();

// Initialize the polynomial commitment parameters
let rng = XorShiftRng::from_seed([
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async fn test_state_circuit_block(block_num: u64) {
});

let randomness = Fr::rand();
let circuit = StateCircuit::<Fr>::new(randomness, rw_map);
let circuit = StateCircuit::<Fr, { 1 << 16 }>::new(randomness, rw_map);
let power_of_randomness = circuit.instance();

use halo2_proofs::pairing::bn256::Fr as Fp;
Expand Down
3 changes: 2 additions & 1 deletion prover/src/compute_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ pub async fn compute_proof(

{
// generate state_circuit proof
let circuit = StateCircuit::new(block.randomness, block.rws);
const N_ROWS: usize = 1 << 16;
let circuit = StateCircuit::<Fr, N_ROWS>::new(block.randomness, block.rws);

// TODO: same quest like in the first scope
let vk = keygen_vk(params, &circuit)?;
Expand Down
24 changes: 13 additions & 11 deletions zkevm-circuits/src/evm_circuit/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ impl RwMap {

#[derive(Clone, Copy, Debug)]
pub enum Rw {
Start,
Start {
rw_counter: usize,
},
TxAccessListAccount {
rw_counter: usize,
is_write: bool,
Expand Down Expand Up @@ -675,8 +677,8 @@ impl Rw {

pub fn rw_counter(&self) -> usize {
match self {
Self::Start => 0,
Self::Memory { rw_counter, .. }
Self::Start { rw_counter }
| Self::Memory { rw_counter, .. }
| Self::Stack { rw_counter, .. }
| Self::AccountStorage { rw_counter, .. }
| Self::TxAccessListAccount { rw_counter, .. }
Expand All @@ -692,7 +694,7 @@ impl Rw {

pub fn is_write(&self) -> bool {
match self {
Self::Start => false,
Self::Start { .. } => false,
Self::Memory { is_write, .. }
| Self::Stack { is_write, .. }
| Self::AccountStorage { is_write, .. }
Expand All @@ -709,7 +711,7 @@ impl Rw {

pub fn tag(&self) -> RwTableTag {
match self {
Self::Start => RwTableTag::Start,
Self::Start { .. } => RwTableTag::Start,
Self::Memory { .. } => RwTableTag::Memory,
Self::Stack { .. } => RwTableTag::Stack,
Self::AccountStorage { .. } => RwTableTag::AccountStorage,
Expand All @@ -735,7 +737,7 @@ impl Rw {
Self::CallContext { call_id, .. }
| Self::Stack { call_id, .. }
| Self::Memory { call_id, .. } => Some(*call_id),
Self::Start | Self::Account { .. } | Self::AccountDestructed { .. } => None,
Self::Start { .. } | Self::Account { .. } | Self::AccountDestructed { .. } => None,
}
}

Expand Down Expand Up @@ -763,7 +765,7 @@ impl Rw {
Self::TxLog { log_id, index, .. } => {
Some((U256::from(*index as u64) + (U256::from(*log_id) << 8)).to_address())
}
Self::Start
Self::Start { .. }
| Self::CallContext { .. }
| Self::TxRefund { .. }
| Self::TxReceipt { .. } => None,
Expand All @@ -776,7 +778,7 @@ impl Rw {
Self::CallContext { field_tag, .. } => Some(*field_tag as u64),
Self::TxLog { field_tag, .. } => Some(*field_tag as u64),
Self::TxReceipt { field_tag, .. } => Some(*field_tag as u64),
Self::Start
Self::Start { .. }
| Self::Memory { .. }
| Self::Stack { .. }
| Self::AccountStorage { .. }
Expand All @@ -791,7 +793,7 @@ impl Rw {
match self {
Self::AccountStorage { storage_key, .. }
| Self::TxAccessListAccountStorage { storage_key, .. } => Some(*storage_key),
Self::Start
Self::Start { .. }
| Self::CallContext { .. }
| Self::Stack { .. }
| Self::Memory { .. }
Expand All @@ -806,7 +808,7 @@ impl Rw {

pub fn value_assignment<F: Field>(&self, randomness: F) -> F {
match self {
Self::Start => F::zero(),
Self::Start { .. } => F::zero(),
Self::CallContext {
field_tag, value, ..
} => {
Expand Down Expand Up @@ -861,7 +863,7 @@ impl Rw {
is_destructed_prev, ..
} => Some(F::from(*is_destructed_prev as u64)),
Self::TxRefund { value_prev, .. } => Some(F::from(*value_prev)),
Self::Start
Self::Start { .. }
| Self::Stack { .. }
| Self::Memory { .. }
| Self::CallContext { .. }
Expand Down
31 changes: 20 additions & 11 deletions zkevm-circuits/src/state_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ type Lookup<F> = (&'static str, Expression<F>, Expression<F>);

/// State Circuit for proving RwTable is valid
#[derive(Default)]
pub struct StateCircuit<F: Field> {
pub struct StateCircuit<F: Field, const N_ROWS: usize> {
pub(crate) randomness: F,
pub(crate) rows: Vec<Rw>,
#[cfg(test)]
overrides: HashMap<(test::AdviceColumn, usize), F>,
overrides: HashMap<(test::AdviceColumn, isize), F>,
}

impl<F: Field> StateCircuit<F> {
impl<F: Field, const N_ROWS: usize> StateCircuit<F, N_ROWS> {
/// make a new state circuit from an RwMap
pub fn new(randomness: F, rw_map: RwMap) -> Self {
let mut rows: Vec<_> = rw_map.0.into_values().flatten().collect();
Expand All @@ -95,12 +95,12 @@ impl<F: Field> StateCircuit<F> {
/// powers of randomness for instance columns
pub fn instance(&self) -> Vec<Vec<F>> {
(1..32)
.map(|exp| vec![self.randomness.pow(&[exp, 0, 0, 0]); self.rows.len() + 1])
.map(|exp| vec![self.randomness.pow(&[exp, 0, 0, 0]); N_ROWS])
.collect()
}
}

impl<F: Field> Circuit<F> for StateCircuit<F> {
impl<F: Field, const N_ROWS: usize> Circuit<F> for StateCircuit<F, N_ROWS> {
type Config = StateConfig<F>;
type FloorPlanner = SimpleFloorPlanner;

Expand Down Expand Up @@ -201,8 +201,12 @@ impl<F: Field> Circuit<F> for StateCircuit<F> {
layouter.assign_region(
|| "rw table",
|mut region| {
let rows = once(&Rw::Start).chain(&self.rows);
let prev_rows = once(&Rw::Start).chain(rows.clone());
let padding_length = N_ROWS - self.rows.len();
let padding = (1..=padding_length).map(|rw_counter| Rw::Start { rw_counter });

let rows = padding.chain(self.rows.iter().cloned());
let prev_rows = once(None).chain(rows.clone().map(Some));

for (offset, (row, prev_row)) in rows.zip(prev_rows).enumerate() {
region.assign_fixed(|| "selector", config.selector, offset, || Ok(F::one()))?;
config
Expand Down Expand Up @@ -244,8 +248,8 @@ impl<F: Field> Circuit<F> for StateCircuit<F> {
|| Ok(row.value_assignment(self.randomness)),
)?;

if offset != 0 {
lexicographic_ordering_chip.assign(&mut region, offset, row, prev_row)?;
if let Some(prev_row) = prev_row {
lexicographic_ordering_chip.assign(&mut region, offset, &row, &prev_row)?;

let id_change = F::from(row.id().unwrap_or_default() as u64)
- F::from(prev_row.id().unwrap_or_default() as u64);
Expand All @@ -267,9 +271,12 @@ impl<F: Field> Circuit<F> for StateCircuit<F> {
}

#[cfg(test)]
for ((column, offset), &f) in &self.overrides {
for ((column, row_offset), &f) in &self.overrides {
let advice_column = column.value(&config);
region.assign_advice(|| "override", advice_column, *offset, || Ok(f))?;
let offset =
usize::try_from(isize::try_from(padding_length).unwrap() + *row_offset)
.unwrap();
region.assign_advice(|| "override", advice_column, offset, || Ok(f))?;
}

Ok(())
Expand All @@ -281,6 +288,8 @@ impl<F: Field> Circuit<F> for StateCircuit<F> {
fn queries<F: Field>(meta: &mut VirtualCells<'_, F>, c: &StateConfig<F>) -> Queries<F> {
Queries {
selector: meta.query_fixed(c.selector, Rotation::cur()),
lexicographic_ordering_selector: meta
.query_fixed(c.lexicographic_ordering.selector, Rotation::cur()),
rw_counter: MpiQueries::new(meta, c.rw_counter),
is_write: meta.query_advice(c.is_write, Rotation::cur()),
tag: c.tag.value(Rotation::cur())(meta),
Expand Down
14 changes: 13 additions & 1 deletion zkevm-circuits/src/state_circuit/constraint_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use strum::IntoEnumIterator;
#[derive(Clone)]
pub struct Queries<F: Field> {
pub selector: Expression<F>,
pub lexicographic_ordering_selector: Expression<F>,
pub rw_counter: MpiQueries<F, N_LIMBS_RW_COUNTER>,
pub is_write: Expression<F>,
pub tag: Expression<F>,
Expand Down Expand Up @@ -104,7 +105,14 @@ impl<F: Field> ConstraintBuilder<F> {
}

fn build_start_constraints(&mut self, q: &Queries<F>) {
self.require_zero("rw_counter is 0 for Start", q.rw_counter.value.clone());
self.require_zero("field_tag is 0 for Start", q.field_tag());
self.require_zero("address is 0 for Start", q.address.value.clone());
self.require_zero("id is 0 for Start", q.id());
self.require_zero("storage_key is 0 for Start", q.storage_key.encoded.clone());
self.require_zero(
"rw_counter increases by 1 for every non-first row",
q.lexicographic_ordering_selector.clone() * (q.rw_counter_change() - 1.expr()),
);
}

fn build_memory_constraints(&mut self, q: &Queries<F>) {
Expand Down Expand Up @@ -308,6 +316,10 @@ impl<F: Field> Queries<F> {
fn address_change(&self) -> Expression<F> {
self.address.value.clone() - self.address.value_prev.clone()
}

fn rw_counter_change(&self) -> Expression<F> {
self.rw_counter.value.clone() - self.rw_counter.value_prev.clone()
}
}

fn from_digits<F: Field>(digits: &[Expression<F>], base: Expression<F>) -> Expression<F> {
Expand Down
Loading

0 comments on commit 2aa9875

Please sign in to comment.