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

[proof chunk] refactor evm_circuit/state_circuit to support proof chunk #1641

Merged
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7a2d655
permutation circuit to support permutation fingerprint on rw_table
hero78119 Oct 3, 2023
043b70e
permutation chip implemetation
hero78119 Oct 4, 2023
554789c
simplify pi by exposing to pre/next instance columns
hero78119 Oct 4, 2023
43ed90e
reserve rw_table first row to be constraints by pi
hero78119 Oct 4, 2023
69680b8
compute next_fingerprints logic in witness block
hero78119 Oct 5, 2023
dd5c9bb
Padding step in RwMap
hero78119 Oct 5, 2023
f2e8a4a
debug variadic_size_check
hero78119 Oct 6, 2023
feab0b1
fix evm circuit lookup logic
hero78119 Oct 9, 2023
aab44aa
rw table sort chronological by rw counter
hero78119 Oct 9, 2023
79ba525
permutation gadget trade more columns with degree
hero78119 Oct 11, 2023
e5af744
fix unittest under statecircuit
hero78119 Oct 11, 2023
a186485
rename by_address_rw_table
hero78119 Oct 11, 2023
1595089
create begin/endchunk step
hero78119 Oct 13, 2023
fe73637
enable begin/end chunk virtual steps in single chunk
hero78119 Oct 16, 2023
d1508a0
add chunk_context and inner chunk rw_counter
hero78119 Oct 16, 2023
ce3c850
revamp constraints on first/last chunk
hero78119 Oct 17, 2023
c47ee95
code cosmetics
hero78119 Oct 17, 2023
b5a9ca1
fix end_block single chunk logic
hero78119 Oct 17, 2023
785a471
remove first chunk first step constraints
hero78119 Oct 17, 2023
6d4a780
chores: variable renaming
hero78119 Oct 18, 2023
a5542f0
add chunkctx table to support lookup chunkctx in execstep
hero78119 Oct 18, 2023
561f5ea
chores: revamp comments
hero78119 Oct 18, 2023
de55034
condense rw_table continuous across chunk via fingerprints
hero78119 Oct 19, 2023
d6be453
refactor global rw_counter to chunkctx_table & code cosmetics
hero78119 Oct 19, 2023
c9a1695
address comments by fixing gamme position bug
hero78119 Oct 20, 2023
1078587
refactor global rw_counter to chunkctx_table lookup
hero78119 Oct 23, 2023
88a6aeb
add testing for multiple chunk
hero78119 Oct 23, 2023
d6e5dbe
chores: make chunk_context as option, first attemp for multiple chunk…
hero78119 Oct 24, 2023
69570e4
set default chunkctx as one chunk
hero78119 Oct 24, 2023
47b4d06
more comment
hero78119 Oct 25, 2023
d263037
optimize state_circuit checking row range
hero78119 Oct 26, 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

132 changes: 112 additions & 20 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
mod access;
mod block;
mod call;
mod chunk;
mod execution;
mod input_state_ref;
#[cfg(test)]
Expand All @@ -14,13 +15,17 @@ use self::access::gen_state_access_trace;
use crate::{
error::Error,
evm::opcodes::{gen_associated_ops, gen_associated_steps},
operation::{CallContextField, Operation, RWCounter, StartOp, RW},
operation::{
CallContextField, Op, Operation, OperationContainer, PaddingOp, RWCounter, StartOp,
StepStateField, StepStateOp, RW,
},
rpc::GethClient,
state_db::{self, CodeDB, StateDB},
};
pub use access::{Access, AccessSet, AccessValue, CodeSource};
pub use block::{Block, BlockContext};
pub use call::{Call, CallContext, CallKind};
pub use chunk::ChunkContext;
use core::fmt::Debug;
use eth_types::{
self, geth_types,
Expand Down Expand Up @@ -131,6 +136,8 @@ pub struct CircuitInputBuilder<C: CircuitsParams> {
pub circuits_params: C,
/// Block Context
pub block_ctx: BlockContext,
/// Chunk Context
pub chunk_ctx: ChunkContext,
}

impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
Expand All @@ -143,6 +150,8 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
block,
circuits_params: params,
block_ctx: BlockContext::new(),
// TODO support multiple chunk
chunk_ctx: ChunkContext::new_one_chunk(),
}
}

Expand All @@ -159,6 +168,7 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
code_db: &mut self.code_db,
block: &mut self.block,
block_ctx: &mut self.block_ctx,
chunk_ctx: &mut self.chunk_ctx,
tx,
tx_ctx,
}
Expand Down Expand Up @@ -258,6 +268,51 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {

Ok(())
}

fn set_begin_chunk(&mut self) {
let mut dummy_tx = Transaction::default();
let mut dummy_tx_ctx = TransactionContext::default();
let tags = [
StepStateField::CodeHash,
StepStateField::CallID,
StepStateField::IsRoot,
StepStateField::IsCreate,
StepStateField::ProgramCounter,
StepStateField::StackPointer,
StepStateField::GasLeft,
StepStateField::MemoryWordSize,
StepStateField::ReversibleWriteCounter,
StepStateField::LogID,
];
let rw_counters = (0..tags.len())
.map(|_| self.block_ctx.rwc.inc_pre())
.collect::<Vec<RWCounter>>();
// just bump rwc in chunk_ctx as block_ctx rwc to assure same delta apply
let rw_counters_inner_chunk = (0..tags.len())
.map(|_| self.chunk_ctx.rwc.inc_pre())
.collect::<Vec<RWCounter>>();
let mut begin_chunk = self.block.block_steps.begin_chunk.clone();
let state = self.state_ref(&mut dummy_tx, &mut dummy_tx_ctx);

tags.iter()
.zip_eq(rw_counters)
.zip_eq(rw_counters_inner_chunk)
.for_each(|((tag, rw_counter), inner_rw_counter)| {
push_op(
&mut state.block.container,
&mut begin_chunk,
rw_counter,
inner_rw_counter,
RW::READ,
StepStateOp {
field: tag.clone(),
value: Word::zero(),
},
);
});

self.block.block_steps.begin_chunk = begin_chunk;
}
}

impl CircuitInputBuilder<FixedCParams> {
Expand All @@ -279,6 +334,9 @@ impl CircuitInputBuilder<FixedCParams> {
let mut end_block_last = self.block.block_steps.end_block_last.clone();
end_block_not_last.rwc = self.block_ctx.rwc;
end_block_last.rwc = self.block_ctx.rwc;
end_block_not_last.rwc_inner_chunk = self.chunk_ctx.rwc;
end_block_last.rwc_inner_chunk = self.chunk_ctx.rwc;
let is_first_chunk = self.chunk_ctx.chunk_index == 0;

let mut dummy_tx = Transaction::default();
let mut dummy_tx_ctx = TransactionContext::default();
Expand All @@ -293,14 +351,10 @@ impl CircuitInputBuilder<FixedCParams> {
);
}

let mut push_op = |step: &mut ExecStep, rwc: RWCounter, rw: RW, op: StartOp| {
let op_ref = state.block.container.insert(Operation::new(rwc, rw, op));
step.bus_mapping_instance.push(op_ref);
};

// rwc index start from 1
let total_rws = state.block_ctx.rwc.0 - 1;
// We need at least 1 extra Start row
// because total_rws exclude Rw::Start
#[allow(clippy::int_plus_one)]
{
assert!(
Expand All @@ -310,34 +364,68 @@ impl CircuitInputBuilder<FixedCParams> {
max_rws
);
}
let (padding_start, padding_end) = (1, max_rws - total_rws); // rw counter start from 1
push_op(
&mut end_block_last,
RWCounter(padding_start),
RW::READ,
StartOp {},
);
if padding_end != padding_start {

if is_first_chunk {
push_op(
&mut state.block.container,
&mut end_block_last,
RWCounter(padding_end),
RWCounter(1),
RWCounter(1),
RW::READ,
StartOp {},
);
}
// TODO fix below to adapt multiple chunk
if max_rws - total_rws > 1 {
let (padding_start, padding_end) = (total_rws + 1, max_rws - 1);
push_op(
&mut state.block.container,
&mut end_block_last,
RWCounter(padding_start),
RWCounter(padding_start),
RW::READ,
PaddingOp {},
);
if padding_end != padding_start {
push_op(
&mut state.block.container,
&mut end_block_last,
RWCounter(padding_end),
RWCounter(padding_end),
RW::READ,
PaddingOp {},
);
}
}

self.block.block_steps.end_block_not_last = end_block_not_last;
self.block.block_steps.end_block_last = end_block_last;
}
}

fn push_op<T: Op>(
container: &mut OperationContainer,
step: &mut ExecStep,
rwc: RWCounter,
rwc_inner_chunk: RWCounter,
rw: RW,
op: T,
) {
let op_ref = container.insert(Operation::new(rwc, rwc_inner_chunk, rw, op));
step.bus_mapping_instance.push(op_ref);
}

impl<C: CircuitsParams> CircuitInputBuilder<C> {
/// First part of handle_block, common for dynamic and static circuit parameters.
pub fn begin_handle_block(
&mut self,
eth_block: &EthBlock,
geth_traces: &[eth_types::GethExecTrace],
) -> Result<(), Error> {
if self.chunk_ctx.chunk_index > 0 {
self.set_begin_chunk();
}

// accumulates gas across all txs in the block
for (idx, tx) in eth_block.transactions.iter().enumerate() {
let geth_trace = &geth_traces[idx];
Expand Down Expand Up @@ -393,11 +481,14 @@ impl CircuitInputBuilder<DynamicCParams> {
* 2
+ 4; // disabled and unused rows.

let total_rws_before_padding: usize =
// TODO fix below logic for multiple rw_table chunks
let total_rws_before_end_block: usize =
<RWCounter as Into<usize>>::into(self.block_ctx.rwc) - 1; // -1 since rwc start from index `1`
let max_rws_after_padding = total_rws_before_padding
+ 1 // fill 1 to have exactly one StartOp padding in below `set_end_block`
+ if total_rws_before_padding > 0 { 1 /*end_block -> CallContextFieldTag::TxId lookup*/ } else { 0 };
let max_rws = total_rws_before_end_block
+ {
1 // +1 for reserving RW::Start at row 1 (offset 0)
+ if total_rws_before_end_block > 0 { 1 /*end_block -> CallContextFieldTag::TxId lookup*/ } else { 0 }
};
// Computing the number of rows for the EVM circuit requires the size of ExecStep,
// which is determined in the code of zkevm-circuits and cannot be imported here.
// When the evm circuit receives a 0 value it dynamically computes the minimum
Expand All @@ -409,7 +500,7 @@ impl CircuitInputBuilder<DynamicCParams> {
// needed.
let max_keccak_rows = 0;
FixedCParams {
max_rws: max_rws_after_padding,
max_rws,
max_txs,
max_calldata,
max_copy_rows,
Expand All @@ -425,6 +516,7 @@ impl CircuitInputBuilder<DynamicCParams> {
block: self.block,
circuits_params: c_params,
block_ctx: self.block_ctx,
chunk_ctx: self.chunk_ctx,
};

cib.set_end_block(c_params.max_rws);
Expand Down
21 changes: 20 additions & 1 deletion bus-mapping/src/circuit_input_builder/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Block-related utility module

use super::{execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent};
use super::{
chunk::ChunkContext, execution::ExecState, transaction::Transaction, CopyEvent, ExecStep,
ExpEvent,
};
use crate::{
operation::{OperationContainer, RWCounter},
Error,
Expand Down Expand Up @@ -47,6 +50,11 @@ pub struct BlockSteps {
pub end_block_not_last: ExecStep,
/// Last EndBlock step that appears in the last EVM row.
pub end_block_last: ExecStep,
/// TODO Define and move chunk related step to Chunk struct
/// Begin op of a chunk
pub begin_chunk: ExecStep,
/// End op of a chunk
pub end_chunk: Option<ExecStep>,
}

// TODO: Remove fields that are duplicated in`eth_block`
Expand Down Expand Up @@ -78,6 +86,8 @@ pub struct Block {
pub txs: Vec<Transaction>,
/// Block-wise steps
pub block_steps: BlockSteps,
/// Chunk context
pub chunk_context: ChunkContext,
/// Copy events in this block.
pub copy_events: Vec<CopyEvent>,
/// Inputs to the SHA3 opcode
Expand Down Expand Up @@ -122,6 +132,10 @@ impl Block {
container: OperationContainer::new(),
txs: Vec::new(),
block_steps: BlockSteps {
begin_chunk: ExecStep {
exec_state: ExecState::BeginChunk,
..ExecStep::default()
},
end_block_not_last: ExecStep {
exec_state: ExecState::EndBlock,
..ExecStep::default()
Expand All @@ -130,7 +144,12 @@ impl Block {
exec_state: ExecState::EndBlock,
..ExecStep::default()
},
end_chunk: Some(ExecStep {
exec_state: ExecState::EndChunk,
..ExecStep::default()
}),
},
chunk_context: ChunkContext::new(0, 1),
copy_events: Vec::new(),
exp_events: Vec::new(),
sha3_inputs: Vec::new(),
Expand Down
39 changes: 39 additions & 0 deletions bus-mapping/src/circuit_input_builder/chunk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::operation::RWCounter;

/// Context of a [`ChunkContext`].
#[derive(Debug, Clone)]
pub struct ChunkContext {
/// Used to track the inner chunk counter in every operation in the chunk.
/// Contains the next available value.
pub rwc: RWCounter,
/// index of current chunk, start from 0
pub chunk_index: usize,
/// number of chunks
pub total_chunks: usize,
}

impl Default for ChunkContext {
fn default() -> Self {
Self::new(0, 1)
}
}

impl ChunkContext {
/// Create a new Self
pub fn new(chunk_index: usize, total_chunks: usize) -> Self {
Self {
rwc: RWCounter::new(),
chunk_index,
total_chunks,
}
}

/// new Self with one chunk
pub fn new_one_chunk() -> Self {
Self {
rwc: RWCounter::new(),
chunk_index: 0,
total_chunks: 1,
}
}
}
8 changes: 8 additions & 0 deletions bus-mapping/src/circuit_input_builder/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub struct ExecStep {
pub call_index: usize,
/// The global counter when this step was executed.
pub rwc: RWCounter,
/// The inner chunk counter when this step was executed.
pub rwc_inner_chunk: RWCounter,
/// Reversible Write Counter. Counter of write operations in the call that
/// will need to be undone in case of a revert. Value at the beginning of
/// the step.
Expand All @@ -54,6 +56,7 @@ impl ExecStep {
step: &GethExecStep,
call_ctx: &CallContext,
rwc: RWCounter,
rwc_inner_chunk: RWCounter,
reversible_write_counter: usize,
log_id: usize,
) -> Self {
Expand All @@ -67,6 +70,7 @@ impl ExecStep {
gas_refund: step.refund,
call_index: call_ctx.index,
rwc,
rwc_inner_chunk,
reversible_write_counter,
reversible_write_counter_delta: 0,
log_id,
Expand Down Expand Up @@ -124,12 +128,16 @@ impl ExecStep {
pub enum ExecState {
/// EVM Opcode ID
Op(OpcodeId),
/// Virtual step Begin Chunk
BeginChunk,
/// Virtual step Begin Tx
BeginTx,
/// Virtual step End Tx
EndTx,
/// Virtual step End Block
EndBlock,
/// Virtual step End Chunk
EndChunk,
}

impl Default for ExecState {
Expand Down
Loading
Loading