1
1
//! Cell manager
2
+ use super :: constraint_builder:: ConstraintBuilder ;
2
3
use crate :: {
3
4
circuit_tools:: cached_region:: CachedRegion ,
5
+ evm_circuit:: util:: rlc,
6
+ table:: LookupTable ,
4
7
util:: { query_expression, word:: Word , Expr } ,
5
8
} ;
6
-
7
- use crate :: table:: LookupTable ;
8
9
use eth_types:: Field ;
9
10
use halo2_proofs:: {
10
11
circuit:: { AssignedCell , Value } ,
@@ -113,47 +114,39 @@ impl<F: Field> WordCell<F> {
113
114
#[ derive( Clone , Debug ) ]
114
115
pub struct CellConfig < C : CellType > {
115
116
pub cell_type : C ,
116
- pub num_columns : usize ,
117
117
pub phase : u8 ,
118
118
pub is_permute : bool ,
119
119
}
120
120
121
- impl < C : CellType > From < ( C , usize , u8 , bool ) > for CellConfig < C > {
122
- fn from ( ( cell_type, num_columns , phase, is_permute ) : ( C , usize , u8 , bool ) ) -> Self {
121
+ impl < C : CellType > CellConfig < C > {
122
+ fn new ( cell_type : C , phase : u8 , is_permute : bool ) -> Self {
123
123
Self {
124
124
cell_type,
125
- num_columns,
126
125
phase,
127
126
is_permute,
128
127
}
129
128
}
130
- }
131
129
132
- impl < C : CellType > CellConfig < C > {
133
- pub fn init_columns < F : Field > ( & self , meta : & mut ConstraintSystem < F > ) -> Vec < Column < Advice > > {
134
- let mut columns = Vec :: with_capacity ( self . num_columns ) ;
135
- for _ in 0 ..self . num_columns {
136
- let tmp = match self . phase {
137
- 1 => meta. advice_column_in ( FirstPhase ) ,
138
- 2 => meta. advice_column_in ( SecondPhase ) ,
139
- 3 => meta. advice_column_in ( ThirdPhase ) ,
140
- _ => unreachable ! ( ) ,
141
- } ;
142
- columns. push ( tmp) ;
143
- }
130
+ pub fn init_column < F : Field > ( & self , meta : & mut ConstraintSystem < F > ) -> Column < Advice > {
131
+ let column = match self . phase {
132
+ 0 => meta. advice_column_in ( FirstPhase ) ,
133
+ 1 => meta. advice_column_in ( SecondPhase ) ,
134
+ 2 => meta. advice_column_in ( ThirdPhase ) ,
135
+ _ => unreachable ! ( ) ,
136
+ } ;
144
137
if self . is_permute {
145
- let _ = columns
146
- . iter ( )
147
- . map ( |c| meta. enable_equality ( * c) )
148
- . collect :: < Vec < ( ) > > ( ) ;
138
+ meta. enable_equality ( column) ;
149
139
}
150
- columns
140
+ column
151
141
}
152
142
}
153
143
154
144
pub trait CellType :
155
145
Clone + Copy + Debug + PartialEq + Eq + PartialOrd + Ord + Hash + Default
156
146
{
147
+ /// This is the table type for lookups
148
+ type TableType : Clone + Copy + Debug + PartialEq + Eq + PartialOrd + Ord + Hash ;
149
+
157
150
fn byte_type ( ) -> Option < Self > ;
158
151
159
152
// The phase that given `Expression` becomes evaluateable.
@@ -171,6 +164,12 @@ pub trait CellType:
171
164
/// Return the storage phase of phase
172
165
fn storage_for_phase ( phase : u8 ) -> Self ;
173
166
167
+ /// Creates a type from a unique id
168
+ fn create_type ( id : usize ) -> Self ;
169
+
170
+ /// Returns the table type of the lookup (if it's a lookup)
171
+ fn lookup_table_type ( & self ) -> Option < Self :: TableType > ;
172
+
174
173
/// Return the storage cell of the expression
175
174
fn storage_for_expr < F : Field > ( expr : & Expression < F > ) -> Self {
176
175
Self :: storage_for_phase ( Self :: expr_phase :: < F > ( expr) )
@@ -184,36 +183,48 @@ pub enum DefaultCellType {
184
183
StoragePhase3 ,
185
184
}
186
185
186
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
187
+ pub enum DefaultLookupType { }
188
+
187
189
impl Default for DefaultCellType {
188
190
fn default ( ) -> Self {
189
191
Self :: StoragePhase1
190
192
}
191
193
}
192
194
193
195
impl CellType for DefaultCellType {
196
+ type TableType = DefaultLookupType ;
197
+
194
198
fn byte_type ( ) -> Option < Self > {
195
199
Some ( DefaultCellType :: StoragePhase1 )
196
200
}
197
201
198
202
fn storage_for_phase ( phase : u8 ) -> Self {
199
- // println!("phase: {}", phase);
200
203
match phase {
201
- 1 => DefaultCellType :: StoragePhase1 ,
202
- 2 => DefaultCellType :: StoragePhase2 ,
203
- 3 => DefaultCellType :: StoragePhase3 ,
204
+ 0 => DefaultCellType :: StoragePhase1 ,
205
+ 1 => DefaultCellType :: StoragePhase2 ,
206
+ 2 => DefaultCellType :: StoragePhase3 ,
204
207
_ => unreachable ! ( ) ,
205
208
}
206
209
}
210
+
211
+ fn create_type ( _id : usize ) -> Self {
212
+ unreachable ! ( )
213
+ }
214
+
215
+ fn lookup_table_type ( & self ) -> Option < Self :: TableType > {
216
+ None
217
+ }
207
218
}
208
219
209
220
#[ derive( Clone , Debug ) ]
210
221
pub ( crate ) struct CellColumn < F , C : CellType > {
211
222
pub ( crate ) column : Column < Advice > ,
212
- index : usize ,
213
223
pub ( crate ) cell_type : C ,
214
- height : usize ,
215
- cells : Vec < Cell < F > > ,
224
+ pub ( crate ) cells : Vec < Cell < F > > ,
216
225
pub ( crate ) expr : Expression < F > ,
226
+ pub ( super ) height : usize ,
227
+ pub ( super ) index : usize ,
217
228
}
218
229
219
230
impl < F : Field , C : CellType > PartialEq for CellColumn < F , C > {
@@ -244,51 +255,74 @@ impl<F: Field, C: CellType> Expr<F> for CellColumn<F, C> {
244
255
}
245
256
}
246
257
247
- #[ derive( Clone , Debug ) ]
258
+ #[ derive( Clone , Debug , Default ) ]
248
259
pub struct CellManager < F , C : CellType > {
249
260
configs : Vec < CellConfig < C > > ,
250
261
columns : Vec < CellColumn < F , C > > ,
251
262
height : usize ,
252
263
height_limit : usize ,
264
+ offset : usize ,
253
265
}
254
266
255
267
impl < F : Field , C : CellType > CellManager < F , C > {
256
- pub ( crate ) fn new (
257
- meta : & mut ConstraintSystem < F > ,
258
- configs : Vec < ( C , usize , u8 , bool ) > ,
259
- offset : usize ,
260
- max_height : usize ,
261
- ) -> Self {
262
- let configs = configs
263
- . into_iter ( )
264
- . map ( |c| c. into ( ) )
265
- . collect :: < Vec < CellConfig < C > > > ( ) ;
268
+ pub ( crate ) fn new ( max_height : usize , offset : usize ) -> Self {
269
+ Self {
270
+ configs : Vec :: new ( ) ,
271
+ columns : Vec :: new ( ) ,
272
+ height : max_height,
273
+ height_limit : max_height,
274
+ offset,
275
+ }
276
+ }
266
277
267
- let mut columns = Vec :: new ( ) ;
268
- for config in configs . iter ( ) {
269
- let cols = config . init_columns ( meta ) ;
270
- for col in cols . iter ( ) {
271
- let mut cells = Vec :: new ( ) ;
272
- for r in 0 ..max_height {
273
- query_expression ( meta , |meta| {
274
- cells . push ( Cell :: new ( meta , * col , offset + r ) ) ;
275
- } ) ;
276
- }
277
- columns . push ( CellColumn {
278
- column : * col ,
279
- index : columns . len ( ) ,
280
- cell_type : config . cell_type ,
281
- height : 0 ,
282
- expr : cells [ 0 ] . expr ( ) ,
283
- cells,
278
+ pub ( crate ) fn add_columns (
279
+ & mut self ,
280
+ meta : & mut ConstraintSystem < F > ,
281
+ cb : & mut ConstraintBuilder < F , C > ,
282
+ cell_type : C ,
283
+ phase : u8 ,
284
+ permutable : bool ,
285
+ num_columns : usize ,
286
+ ) {
287
+ for _ in 0 ..num_columns {
288
+ // Add a column of the specified type
289
+ let config = CellConfig :: new ( cell_type , phase , permutable ) ;
290
+ let col = config . init_column ( meta ) ;
291
+ let mut cells = Vec :: new ( ) ;
292
+ for r in 0 .. self . height_limit {
293
+ query_expression ( meta , |meta| {
294
+ cells. push ( Cell :: new ( meta , col , self . offset + r ) ) ;
284
295
} ) ;
285
296
}
297
+ let column_expr = cells[ 0 ] . expr ( ) ;
298
+ self . columns . push ( CellColumn {
299
+ column : col,
300
+ index : self . columns . len ( ) ,
301
+ cell_type : config. cell_type ,
302
+ height : 0 ,
303
+ expr : column_expr. expr ( ) ,
304
+ cells,
305
+ } ) ;
306
+ self . configs . push ( config) ;
307
+
308
+ // For cell types that are lookups, generate the lookup here
309
+ if let Some ( table) = cell_type. lookup_table_type ( ) {
310
+ cb. add_lookup (
311
+ format ! ( "{:?}" , table) ,
312
+ vec ! [ column_expr. expr( ) ] ,
313
+ vec ! [ rlc:: expr(
314
+ & cb. table( table) ,
315
+ cb. lookup_challenge. clone( ) . unwrap( ) ,
316
+ ) ] ,
317
+ ) ;
318
+ }
286
319
}
287
- Self {
288
- configs,
289
- columns,
290
- height : max_height,
291
- height_limit : max_height,
320
+ }
321
+
322
+ pub ( crate ) fn restart ( & mut self ) {
323
+ self . height = self . height_limit ;
324
+ for col in self . columns . iter_mut ( ) {
325
+ col. height = 0 ;
292
326
}
293
327
}
294
328
0 commit comments