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

Commit 26bf6ba

Browse files
Remove deprecated, unreachable_code and add docs to Evm circuit (#1524)
### Description - rm deprecated, unreachable_code - doc some parts. ### Issue Link part of #1494 ### Type of change - [ ] New feature (non-breaking change which adds functionality)
1 parent 0403a04 commit 26bf6ba

File tree

9 files changed

+146
-67
lines changed

9 files changed

+146
-67
lines changed

zkevm-circuits/src/evm_circuit.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! The EVM circuit implementation.
22
3-
#![allow(missing_docs)]
43
use halo2_proofs::{
54
circuit::{Layouter, SimpleFloorPlanner, Value},
65
plonk::*,
@@ -41,6 +40,7 @@ pub struct EvmCircuitConfig<F> {
4140
fixed_table: [Column<Fixed>; 4],
4241
u8_table: UXTable<8>,
4342
u16_table: UXTable<16>,
43+
/// The execution config
4444
pub execution: Box<ExecutionConfig<F>>,
4545
// External tables
4646
tx_table: TxTable,
@@ -183,26 +183,29 @@ impl<F: Field> EvmCircuit<F> {
183183
fixed_table_tags: FixedTableTag::iter().collect(),
184184
}
185185
}
186-
187-
pub fn get_test_cicuit_from_block(block: Block<F>) -> Self {
186+
#[cfg(feature = "test-circuits")]
187+
/// Construct the EvmCircuit with only subset of Fixed table tags required by tests to save
188+
/// testing time
189+
pub(crate) fn get_test_circuit_from_block(block: Block<F>) -> Self {
188190
let fixed_table_tags = detect_fixed_table_tags(&block);
189191
Self {
190192
block: Some(block),
191193
fixed_table_tags,
192194
}
193195
}
194-
196+
#[cfg(feature = "test-circuits")]
195197
/// Calculate which rows are "actually" used in the circuit
196-
pub fn get_active_rows(block: &Block<F>) -> (Vec<usize>, Vec<usize>) {
198+
pub(crate) fn get_active_rows(block: &Block<F>) -> (Vec<usize>, Vec<usize>) {
197199
let max_offset = Self::get_num_rows_required(block);
198200
// some gates are enabled on all rows
199201
let gates_row_ids = (0..max_offset).collect();
200202
// lookups are enabled at "q_step" rows and byte lookup rows
201203
let lookup_row_ids = (0..max_offset).collect();
202204
(gates_row_ids, lookup_row_ids)
203205
}
204-
205-
pub fn get_num_rows_required(block: &Block<F>) -> usize {
206+
/// Get the minimum number of rows required to process the block
207+
/// If unspecified, then compute it
208+
pub(crate) fn get_num_rows_required(block: &Block<F>) -> usize {
206209
let evm_rows = block.circuits_params.max_evm_rows;
207210
if evm_rows == 0 {
208211
Self::get_min_num_rows_required(block)
@@ -211,8 +214,8 @@ impl<F: Field> EvmCircuit<F> {
211214
block.circuits_params.max_evm_rows + 1
212215
}
213216
}
214-
215-
pub fn get_min_num_rows_required(block: &Block<F>) -> usize {
217+
/// Compute the minimum number of rows required to process the block
218+
fn get_min_num_rows_required(block: &Block<F>) -> usize {
216219
let mut num_rows = 0;
217220
for transaction in &block.txs {
218221
for step in transaction.steps() {
@@ -343,8 +346,8 @@ pub(crate) mod cached {
343346
}
344347

345348
impl EvmCircuitCached {
346-
pub fn get_test_cicuit_from_block(block: Block<Fr>) -> Self {
347-
Self(EvmCircuit::<Fr>::get_test_cicuit_from_block(block))
349+
pub(crate) fn get_test_circuit_from_block(block: Block<Fr>) -> Self {
350+
Self(EvmCircuit::<Fr>::get_test_circuit_from_block(block))
348351
}
349352
}
350353
}
@@ -495,7 +498,7 @@ mod evm_circuit_stats {
495498
let block = block_convert::<Fr>(&builder).unwrap();
496499
let k = block.get_test_degree();
497500

498-
let circuit = EvmCircuit::<Fr>::get_test_cicuit_from_block(block);
501+
let circuit = EvmCircuit::<Fr>::get_test_circuit_from_block(block);
499502
let prover1 = MockProver::<Fr>::run(k, &circuit, vec![]).unwrap();
500503

501504
let code = bytecode! {
@@ -516,7 +519,7 @@ mod evm_circuit_stats {
516519
.unwrap();
517520
let block = block_convert::<Fr>(&builder).unwrap();
518521
let k = block.get_test_degree();
519-
let circuit = EvmCircuit::<Fr>::get_test_cicuit_from_block(block);
522+
let circuit = EvmCircuit::<Fr>::get_test_circuit_from_block(block);
520523
let prover2 = MockProver::<Fr>::run(k, &circuit, vec![]).unwrap();
521524

522525
assert_eq!(prover1.fixed(), prover2.fixed());

zkevm-circuits/src/evm_circuit/param.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! Constants and parameters for the EVM circuit
12
use super::table::Table;
23
use crate::evm_circuit::{step::ExecutionState, EvmCircuit};
34
use halo2_proofs::{
@@ -22,12 +23,14 @@ pub const N_PHASE2_COLUMNS: usize = 1;
2223
pub const N_PHASE1_COLUMNS: usize =
2324
STEP_WIDTH - EVM_LOOKUP_COLS - N_PHASE2_COLUMNS - N_COPY_COLUMNS - N_U8_LOOKUPS - N_U16_LOOKUPS;
2425

25-
// Number of copy columns
26+
/// Number of copy columns
2627
pub const N_COPY_COLUMNS: usize = 2;
2728

29+
/// Number of columns reserved for u8 lookup
2830
pub const N_U8_LOOKUPS: usize = 24;
2931

3032
// TODO shift #column/2 from u8 to u16
33+
/// Number of columns reserved for u16 lookup
3134
pub const N_U16_LOOKUPS: usize = 0;
3235

3336
/// Amount of lookup columns in the EVM circuit dedicated to lookups.

zkevm-circuits/src/evm_circuit/step.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//! EVM execution state. We model the EVM execution as a finite state machine. The execution of a
2+
//! EVM block goes from one state to another, but never at an undefined state. The EVM circuit
3+
//! enables the selectors and thus activates the constraints for the state that the execution
4+
//! reaches.
5+
16
use super::{
27
param::MAX_STEP_HEIGHT,
38
util::{evm_cm_distribute_advice, CachedRegion, Cell, CellType},
@@ -27,27 +32,37 @@ use std::{fmt::Display, iter};
2732
use strum::IntoEnumIterator;
2833
use strum_macros::EnumIter;
2934

35+
#[allow(missing_docs, reason = "some docs here are tedious and not helpful")]
3036
#[allow(non_camel_case_types)]
3137
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, EnumIter)]
38+
/// All the possible execution states that the computation of EVM can arrive.
39+
/// Some states are shared by multiple opcodes.
3240
pub enum ExecutionState {
3341
// Internal state
3442
BeginTx,
3543
EndTx,
3644
EndBlock,
3745
// Opcode successful cases
3846
STOP,
39-
ADD_SUB, // ADD, SUB
40-
MUL_DIV_MOD, // MUL, DIV, MOD
41-
SDIV_SMOD, // SDIV, SMOD
42-
SHL_SHR, // SHL, SHR
47+
/// ADD and SUB opcodes share this state
48+
ADD_SUB,
49+
/// MUL, DIV, MOD
50+
MUL_DIV_MOD,
51+
/// SDIV, SMOD
52+
SDIV_SMOD,
53+
/// SHL, SHR
54+
SHL_SHR,
4355
ADDMOD,
4456
MULMOD,
4557
EXP,
4658
SIGNEXTEND,
47-
CMP, // LT, GT, EQ
48-
SCMP, // SLT, SGT
59+
/// LT, GT, EQ
60+
CMP,
61+
/// SLT, SGT
62+
SCMP,
4963
ISZERO,
50-
BITWISE, // AND, OR, XOR
64+
/// AND, OR, XOR
65+
BITWISE,
5166
NOT,
5267
BYTE,
5368
SAR,
@@ -69,11 +84,13 @@ pub enum ExecutionState {
6984
RETURNDATACOPY,
7085
EXTCODEHASH,
7186
BLOCKHASH,
72-
BLOCKCTX, // TIMESTAMP, NUMBER, GASLIMIT, COINBASE, DIFFICULTY, BASEFEE
87+
/// TIMESTAMP, NUMBER, GASLIMIT, COINBASE, DIFFICULTY, BASEFEE
88+
BLOCKCTX,
7389
CHAINID,
7490
SELFBALANCE,
7591
POP,
76-
MEMORY, // MLOAD, MSTORE, MSTORE8
92+
/// MLOAD, MSTORE, MSTORE8
93+
MEMORY,
7794
SLOAD,
7895
SSTORE,
7996
JUMP,
@@ -82,13 +99,18 @@ pub enum ExecutionState {
8299
MSIZE,
83100
GAS,
84101
JUMPDEST,
85-
PUSH, // PUSH1, PUSH2, ..., PUSH32
86-
DUP, // DUP1, DUP2, ..., DUP16
87-
SWAP, // SWAP1, SWAP2, ..., SWAP16
88-
LOG, // LOG0, LOG1, ..., LOG4
102+
/// PUSH1, PUSH2, ..., PUSH32
103+
PUSH,
104+
/// DUP1, DUP2, ..., DUP16
105+
DUP,
106+
/// SWAP1, SWAP2, ..., SWAP16
107+
SWAP,
108+
/// LOG0, LOG1, ..., LOG4
109+
LOG,
89110
CREATE,
90-
CALL_OP, // CALL, CALLCODE, DELEGATECALL, STATICCALL
91-
RETURN_REVERT, // RETURN, REVERT
111+
/// CALL, CALLCODE, DELEGATECALL, STATICCALL
112+
CALL_OP,
113+
RETURN_REVERT,
92114
CREATE2,
93115
SELFDESTRUCT,
94116
// Error cases
@@ -283,7 +305,7 @@ impl From<&ExecStep> for ExecutionState {
283305
}
284306
}
285307

286-
pub trait HasExecutionState {
308+
pub(crate) trait HasExecutionState {
287309
fn execution_state(&self) -> ExecutionState;
288310
}
289311

@@ -334,6 +356,7 @@ impl ExecutionState {
334356
|| self.halts_in_exception()
335357
}
336358

359+
/// Get the opocdes that are related to the execution state
337360
pub fn responsible_opcodes(&self) -> Vec<ResponsibleOp> {
338361
if matches!(self, Self::ErrorStack) {
339362
return OpcodeId::valid_opcodes()
@@ -498,11 +521,12 @@ impl ExecutionState {
498521
.collect()
499522
}
500523

524+
/// Get the state hight
501525
pub fn get_step_height_option(&self) -> Option<usize> {
502526
EXECUTION_STATE_HEIGHT_MAP.get(self).copied()
503527
}
504528

505-
pub fn get_step_height(&self) -> usize {
529+
pub(crate) fn get_step_height(&self) -> usize {
506530
self.get_step_height_option()
507531
.unwrap_or_else(|| panic!("Execution state unknown: {:?}", self))
508532
}
@@ -525,6 +549,7 @@ impl From<OpcodeId> for ResponsibleOp {
525549
}
526550

527551
impl ResponsibleOp {
552+
/// Get the opcode
528553
pub fn opcode(&self) -> OpcodeId {
529554
*match self {
530555
ResponsibleOp::Op(opcode) => opcode,

zkevm-circuits/src/evm_circuit/table.rs

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Fixed lookup tables and dynamic lookup tables for the EVM circuit
2+
13
use crate::{
24
evm_circuit::step::{ExecutionState, ResponsibleOp},
35
impl_expr,
@@ -11,28 +13,46 @@ use strum::IntoEnumIterator;
1113
use strum_macros::EnumIter;
1214

1315
#[derive(Clone, Copy, Debug, EnumIter)]
16+
/// Tags for different fixed tables
1417
pub enum FixedTableTag {
18+
/// x == 0
1519
Zero = 0,
20+
/// 0 <= x < 5
1621
Range5,
22+
/// 0 <= x < 16
1723
Range16,
24+
/// 0 <= x < 32
1825
Range32,
26+
/// 0 <= x < 64
1927
Range64,
28+
/// 0 <= x < 128
2029
Range128,
30+
/// 0 <= x < 256
2131
Range256,
32+
/// 0 <= x < 512
2233
Range512,
34+
/// 0 <= x < 1024
2335
Range1024,
36+
/// -128 <= x < 128
2437
SignByte,
38+
/// bitwise AND
2539
BitwiseAnd,
40+
/// bitwise OR
2641
BitwiseOr,
42+
/// bitwise XOR
2743
BitwiseXor,
44+
/// lookup for corresponding opcode
2845
ResponsibleOpcode,
46+
/// power of 2
2947
Pow2,
48+
/// Lookup constant gas cost for opcodes
3049
ConstantGasCost,
3150
}
3251
impl_expr!(FixedTableTag);
3352

3453
impl FixedTableTag {
35-
pub fn build<F: Field>(&self) -> Box<dyn Iterator<Item = [F; 4]>> {
54+
/// build up the fixed table row values
55+
pub(crate) fn build<F: Field>(&self) -> Box<dyn Iterator<Item = [F; 4]>> {
3656
let tag = F::from(*self as u64);
3757
match self {
3858
Self::Zero => Box::new((0..1).map(move |_| [tag, F::ZERO, F::ZERO, F::ZERO])),
@@ -122,33 +142,57 @@ impl FixedTableTag {
122142
}
123143

124144
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, EnumIter)]
145+
/// Each item represents the lookup table to query
125146
pub enum Table {
147+
/// The range check table for u8
126148
U8,
149+
/// The range check table for u16
127150
U16,
151+
/// The rest of the fixed table. See [`FixedTableTag`]
128152
Fixed,
153+
/// Lookup for transactions
129154
Tx,
155+
/// Lookup for read write operations
130156
Rw,
157+
/// Lookup for bytecode table
131158
Bytecode,
159+
/// Lookup for block constants
132160
Block,
161+
/// Lookup for copy table
133162
Copy,
163+
/// Lookup for keccak table
134164
Keccak,
165+
/// Lookup for exp table
135166
Exp,
136167
}
137168

138169
#[derive(Clone, Debug)]
139-
pub struct RwValues<F> {
140-
pub id: Expression<F>,
141-
pub address: Expression<F>,
142-
pub field_tag: Expression<F>,
143-
pub storage_key: Word<Expression<F>>,
144-
pub value: Word<Expression<F>>,
145-
pub value_prev: Word<Expression<F>>,
146-
pub init_val: Word<Expression<F>>,
170+
/// Read-Write Table fields
171+
pub(crate) struct RwValues<F> {
172+
/// The unique identifier for the Read or Write. Depending on context, this field could be used
173+
/// for Transaction ID or call ID
174+
id: Expression<F>,
175+
/// The position to Stack, Memory, or account, where the read or write takes place, depending
176+
/// on the cell value of the [`bus_mapping::operation::Target`].
177+
address: Expression<F>,
178+
/// Could be [`crate::table::CallContextFieldTag`], [`crate::table::AccountFieldTag`],
179+
/// [`crate::table::TxLogFieldTag`], or [`crate::table::TxReceiptFieldTag`] depending on
180+
/// the cell value of the [`bus_mapping::operation::Target`]
181+
field_tag: Expression<F>,
182+
/// Storage key of two limbs
183+
storage_key: Word<Expression<F>>,
184+
/// The current storage value
185+
value: Word<Expression<F>>,
186+
/// The previous storage value
187+
value_prev: Word<Expression<F>>,
188+
/// The initial storage value before the current transaction
189+
init_val: Word<Expression<F>>,
147190
}
148191

149192
impl<F: Field> RwValues<F> {
193+
/// Constructor for RwValues
150194
#[allow(clippy::too_many_arguments)]
151-
pub fn new(
195+
pub(crate) fn new(
152196
id: Expression<F>,
153197
address: Expression<F>,
154198
field_tag: Expression<F>,
@@ -167,6 +211,15 @@ impl<F: Field> RwValues<F> {
167211
init_val,
168212
}
169213
}
214+
215+
pub(crate) fn revert_value(&self) -> Self {
216+
let new_self = self.clone();
217+
Self {
218+
value_prev: new_self.value,
219+
value: new_self.value_prev,
220+
..new_self
221+
}
222+
}
170223
}
171224

172225
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)