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

[MPT] Misc refactoring #972

Merged
merged 59 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
136f5c4
[MPT] Selectors refactor
Brechtpd Dec 7, 2022
2db02ad
More refactoring (branch)
Brechtpd Dec 13, 2022
132b924
Refactoring extension node
Brechtpd Dec 14, 2022
22e95d9
More extension node refactoring
Brechtpd Dec 15, 2022
d79e616
Continue extension node refactoring
Brechtpd Dec 16, 2022
eef8076
More refactoring
Brechtpd Dec 19, 2022
59f657c
Account leaf refactoring
Brechtpd Dec 21, 2022
2b21edc
Storage leaf refactoring
Brechtpd Dec 22, 2022
e00e388
Account leaf refactoring
Brechtpd Dec 23, 2022
e2196ae
refactoring storage leaf/proof chain
Brechtpd Dec 24, 2022
e7e6779
Refactor lookups/Unify config building
Brechtpd Dec 27, 2022
f351912
Start zero check refactoring
Brechtpd Dec 28, 2022
49b1876
Misc refactoring
Brechtpd Dec 29, 2022
0c077f6
Lookup optimizations/misc refactoring
Brechtpd Jan 3, 2023
5571974
Misc small improvements
Brechtpd Jan 4, 2023
d7993b6
Branch/misc improvements
Brechtpd Jan 5, 2023
2b203e5
Branch/extension improvements
Brechtpd Jan 6, 2023
cfe559a
Extension node/key improvements
Brechtpd Jan 7, 2023
0e771ef
Key/misc improvements
Brechtpd Jan 9, 2023
0233dcf
Account leaf/lookup improvements
Brechtpd Jan 10, 2023
73132c1
Account leaf improvements
Brechtpd Jan 11, 2023
740f187
Storage leaf key improvements
Brechtpd Jan 12, 2023
3fd3d1f
Storage leaf improvements
Brechtpd Jan 13, 2023
bb6c996
Split off reusable circuit tools
Brechtpd Jan 14, 2023
89c2203
Misc key/rlc improvements
Brechtpd Jan 16, 2023
5cfc1c9
Misc small improvements
Brechtpd Jan 17, 2023
1fe019e
General small improvements
Brechtpd Jan 18, 2023
574fabf
Small improvements
Brechtpd Jan 19, 2023
1e4380d
Non-existing/placeholder improvements
Brechtpd Jan 20, 2023
9ec19f7
drifted/modified/circuit tools improvements
Brechtpd Jan 21, 2023
90939a0
misc small improvements
Brechtpd Jan 23, 2023
56b19e4
Small improvements
Brechtpd Jan 24, 2023
ad3ef12
Small key improvements
Brechtpd Jan 26, 2023
2befb2d
Add missing constraints
Brechtpd Jan 27, 2023
b13b1bd
Feedback + small changes
Brechtpd Jan 30, 2023
c06991c
Start layout refactor
Brechtpd Feb 7, 2023
14359c4
Merge branch state
Brechtpd Feb 8, 2023
27a59dd
Reduce state machine to three states
Brechtpd Feb 9, 2023
c106ce0
StorageLeaf refactor
Brechtpd Feb 14, 2023
63ce1a9
Storage root improvements
Brechtpd Feb 15, 2023
4ecbd0f
More storage leaf improvements
Brechtpd Feb 16, 2023
4e6cc2b
Start account leaf layout refactoring
Brechtpd Feb 17, 2023
7896566
Account leaf refactor
Brechtpd Feb 20, 2023
1108e1e
branch refactor
Brechtpd Feb 27, 2023
00d1a89
Misc improvements
Brechtpd Feb 28, 2023
fb94d83
Misc small improvements
Brechtpd Mar 1, 2023
7c89e6f
Merge pull request #7 from Brechtpd/mpt-refactor-layout
Brechtpd Mar 1, 2023
fb2aef7
Better proof init
Brechtpd Mar 2, 2023
f3a8dcc
Proof type/consistency improvements
Brechtpd Mar 3, 2023
466121d
MPT lookup table data improvements
Brechtpd Mar 4, 2023
38838c2
Drifted/non-existing improvements
Brechtpd Mar 6, 2023
16bec41
Some RLP layout changes
Brechtpd Mar 8, 2023
5f65f65
Fix storage value/improve byte layout
Brechtpd Mar 9, 2023
05898c0
Split branch and extension logic
Brechtpd Mar 11, 2023
4fd1aaa
Reduce branch data and data per row (single RLP value)
Brechtpd Mar 13, 2023
4deaa7a
Fix branch parent check + partial RLP decoding sharing
Brechtpd Mar 14, 2023
b42b3d5
Re-enable byte range/zero checking
Brechtpd Mar 15, 2023
67d68e8
Misc small improvements/refactoring
Brechtpd Mar 16, 2023
c0adb10
Misc cleanup
Brechtpd Mar 23, 2023
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
62 changes: 49 additions & 13 deletions gadgets/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,34 @@ pub mod select {
}
}

/// Trait that implements functionality to get a scalar from
/// commonly used types.
pub trait Scalar<F: FieldExt> {
/// Returns a scalar for the type.
fn scalar(&self) -> F;
}

/// Implementation trait `Scalar` for type able to be casted to u64
#[macro_export]
macro_rules! impl_scalar {
($type:ty) => {
impl<F: halo2_proofs::arithmetic::FieldExt> $crate::util::Scalar<F> for $type {
#[inline]
fn scalar(&self) -> F {
F::from(*self as u64)
}
}
};
($type:ty, $method:path) => {
impl<F: halo2_proofs::arithmetic::FieldExt> $crate::util::Scalar<F> for $type {
#[inline]
fn scalar(&self) -> F {
F::from($method(self) as u64)
}
}
};
}

/// Trait that implements functionality to get a constant expression from
/// commonly used types.
pub trait Expr<F: FieldExt> {
Expand All @@ -143,6 +171,7 @@ pub trait Expr<F: FieldExt> {
#[macro_export]
macro_rules! impl_expr {
($type:ty) => {
$crate::impl_scalar!($type);
impl<F: halo2_proofs::arithmetic::FieldExt> $crate::util::Expr<F> for $type {
#[inline]
fn expr(&self) -> Expression<F> {
Expand All @@ -151,6 +180,7 @@ macro_rules! impl_expr {
}
};
($type:ty, $method:path) => {
$crate::impl_scalar!($type, $method);
impl<F: halo2_proofs::arithmetic::FieldExt> $crate::util::Expr<F> for $type {
#[inline]
fn expr(&self) -> Expression<F> {
Expand All @@ -164,34 +194,40 @@ impl_expr!(bool);
impl_expr!(u8);
impl_expr!(u64);
impl_expr!(usize);
impl_expr!(isize);
impl_expr!(OpcodeId, OpcodeId::as_u8);
impl_expr!(GasCost, GasCost::as_u64);

impl<F: FieldExt> Expr<F> for Expression<F> {
impl<F: FieldExt> Scalar<F> for i32 {
#[inline]
fn scalar(&self) -> F {
F::from(self.unsigned_abs() as u64)
* if self.is_negative() {
-F::one()
} else {
F::one()
}
}
}

impl<F: FieldExt> Expr<F> for i32 {
#[inline]
fn expr(&self) -> Expression<F> {
self.clone()
Expression::Constant(self.scalar())
}
}

impl<F: FieldExt> Expr<F> for &Expression<F> {
impl<F: FieldExt> Expr<F> for Expression<F> {
#[inline]
fn expr(&self) -> Expression<F> {
(*self).clone()
self.clone()
}
}

impl<F: FieldExt> Expr<F> for i32 {
impl<F: FieldExt> Expr<F> for &Expression<F> {
#[inline]
fn expr(&self) -> Expression<F> {
Expression::Constant(
F::from(self.unsigned_abs() as u64)
* if self.is_negative() {
-F::one()
} else {
F::one()
},
)
(*self).clone()
}
}

Expand Down
6 changes: 6 additions & 0 deletions zkevm-circuits/src/circuit_tools.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Circuit utilities
#[macro_use]
pub mod constraint_builder;
pub mod cell_manager;
pub mod gadgets;
pub mod memory;
254 changes: 254 additions & 0 deletions zkevm-circuits/src/circuit_tools/cell_manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
//! Cell manager
use crate::util::Expr;
use eth_types::Field;
use halo2_proofs::{
circuit::{AssignedCell, Region, Value},
plonk::{Advice, Column, Error, Expression, VirtualCells},
poly::Rotation,
};
use std::{any::Any, collections::BTreeMap};

#[derive(Clone)]
pub(crate) struct DataTransition<F> {
prev: Expression<F>,
cur: Expression<F>,
}

impl<F: Field> DataTransition<F> {
pub(crate) fn new(meta: &mut VirtualCells<F>, column: Column<Advice>) -> DataTransition<F> {
DataTransition {
prev: meta.query_advice(column, Rotation::prev()),
cur: meta.query_advice(column, Rotation::cur()),
}
}

pub(crate) fn new_with_rot(
meta: &mut VirtualCells<F>,
column: Column<Advice>,
rot_prev: i32,
rot_cur: i32,
) -> DataTransition<F> {
DataTransition {
prev: meta.query_advice(column, Rotation(rot_prev)),
cur: meta.query_advice(column, Rotation(rot_cur)),
}
}

pub(crate) fn from(prev: Expression<F>, cur: Expression<F>) -> DataTransition<F> {
DataTransition { prev, cur }
}

pub(crate) fn cur(&self) -> Expression<F> {
self.cur.clone()
}

pub(crate) fn prev(&self) -> Expression<F> {
self.prev.clone()
}

pub(crate) fn delta(&self) -> Expression<F> {
self.prev() - self.cur()
}
}

impl<F: Field> Expr<F> for DataTransition<F> {
fn expr(&self) -> Expression<F> {
self.cur.clone()
}
}

/// Trackable object
pub trait Trackable {
/// To allow downcasting
fn as_any(&self) -> &dyn Any;

/// Cloning
fn clone_box(&self) -> Box<dyn Trackable>;
}

// We can now implement Clone manually by forwarding to clone_box.
impl Clone for Box<dyn Trackable> {
fn clone(&self) -> Box<dyn Trackable> {
self.clone_box()
}
}

#[derive(Clone, Debug, Default)]
pub(crate) struct Cell<F> {
// expression for constraint
expression: Option<Expression<F>>,
column: Option<Column<Advice>>,
// relative position to selector for synthesis
rotation: usize,
}

impl<F: Field> Trackable for Cell<F> {
fn as_any(&self) -> &dyn Any {
self
}
fn clone_box(&self) -> Box<dyn Trackable> {
Box::new(self.clone())
}
}

impl<F: Field> Cell<F> {
pub(crate) fn new(meta: &mut VirtualCells<F>, column: Column<Advice>, rotation: usize) -> Self {
Self {
expression: Some(meta.query_advice(column, Rotation(rotation as i32))),
column: Some(column),
rotation,
}
}

pub(crate) fn assign(
&self,
region: &mut Region<'_, F>,
offset: usize,
value: F,
) -> Result<AssignedCell<F, F>, Error> {
region.assign_advice(
|| {
format!(
"Cell column: {:?} and rotation: {}",
self.column, self.rotation
)
},
self.column.unwrap(),
offset + self.rotation,
|| Value::known(value),
)
}
}

impl<F: Field> Expr<F> for Cell<F> {
fn expr(&self) -> Expression<F> {
self.expression.as_ref().unwrap().clone()
}
}

impl<F: Field> Expr<F> for &Cell<F> {
fn expr(&self) -> Expression<F> {
self.expression.as_ref().unwrap().clone()
}
}

/// CellType
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum CellType {
/// General
Storage,
}

/// CellColumn
#[derive(Clone, Debug)]
pub struct CellColumn<F> {
pub(crate) index: usize,
pub(crate) cell_type: CellType,
pub(crate) height: usize,
pub(crate) expr: Expression<F>,
}

impl<F: Field> Expr<F> for CellColumn<F> {
fn expr(&self) -> Expression<F> {
self.expr.clone()
}
}

/// CellManager
#[derive(Clone, Debug)]
pub struct CellManager<F> {
width: usize,
height: usize,
cells: Vec<Cell<F>>,
columns: Vec<CellColumn<F>>,
}

impl<F: Field> CellManager<F> {
pub(crate) fn new(meta: &mut VirtualCells<F>, advice_columns: &[Column<Advice>]) -> Self {
// Setup the columns and query the cells
let width = advice_columns.len();
let height = 32;
let mut cells = Vec::with_capacity(height * width);
let mut columns = Vec::with_capacity(width);
for c in 0..width {
for r in 0..height {
cells.push(Cell::new(meta, advice_columns[c], r));
}
columns.push(CellColumn {
index: c,
cell_type: CellType::Storage,
height: 0,
expr: cells[c * height].expr(),
});
}

Self {
width,
height,
cells,
columns,
}
}

pub(crate) fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec<Cell<F>> {
let mut cells = Vec::with_capacity(count);
while cells.len() < count {
let column_idx = self.next_column(cell_type);
let column = &mut self.columns[column_idx];
cells.push(self.cells[column_idx * self.height + column.height].clone());
column.height += 1;
}
cells
}

pub(crate) fn query_cell(&mut self, cell_type: CellType) -> Cell<F> {
self.query_cells(cell_type, 1)[0].clone()
}

pub(crate) fn reset(&mut self) {
for column in self.columns.iter_mut() {
column.height = 0;
}
}

fn next_column(&self, cell_type: CellType) -> usize {
let mut best_index: Option<usize> = None;
let mut best_height = self.height;
for column in self.columns.iter() {
if column.cell_type == cell_type && column.height < best_height {
best_index = Some(column.index);
best_height = column.height;
}
}
match best_index {
Some(index) => index,
None => unreachable!("not enough cells for query: {:?}", cell_type),
}
}

pub(crate) fn get_height(&self) -> usize {
self.columns
.iter()
.map(|column| column.height)
.max()
.unwrap()
}

/// Returns a map of CellType -> (width, height, num_cells)
pub(crate) fn get_stats(&self) -> BTreeMap<CellType, (usize, usize, usize)> {
let mut data = BTreeMap::new();
for column in self.columns.iter() {
let (mut count, mut height, mut num_cells) =
data.get(&column.cell_type).unwrap_or(&(0, 0, 0));
count += 1;
height = height.max(column.height);
num_cells += column.height;
data.insert(column.cell_type, (count, height, num_cells));
}
data
}

pub(crate) fn columns(&self) -> &[CellColumn<F>] {
&self.columns
}
}
Loading