Skip to content

Commit

Permalink
add BytecodeLengthGadget handle bytelen lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
DreamWuGit committed Aug 1, 2024
1 parent 03fc234 commit 900c336
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 19 deletions.
16 changes: 13 additions & 3 deletions zkevm-circuits/src/evm_circuit/execution/codecopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ impl<F: Field> ExecutionGadget<F> for CodeCopyGadget<F> {
// Fetch the hash of bytecode running in current environment.
let code_hash = cb.curr.state.code_hash.clone();

// Fetch the bytecode length from the bytecode table.
cb.bytecode_length(code_hash.expr(), code_size.expr());

// Calculate the next memory size and the gas cost for this memory
// access. This also accounts for the dynamic gas required to copy bytes to
// memory.
Expand Down Expand Up @@ -128,6 +125,19 @@ impl<F: Field> ExecutionGadget<F> for CodeCopyGadget<F> {
};
let same_context = SameContextGadget::construct(cb, opcode, step_state_transition);

// Fetch the bytecode length from the bytecode table.
#[cfg(not(feature = "dual_bytecode"))]
cb.bytecode_length(cb.curr.state.code_hash.expr(), code_size.expr());
#[cfg(feature = "dual_bytecode")]
{
cb.condition(same_context.is_first_sub_bytecode(), |cb| {
cb.bytecode_length(cb.curr.state.code_hash.expr(), code_size.expr());
});
cb.condition(not::expr(same_context.is_first_sub_bytecode()), |cb| {
cb.bytecode2_length(cb.curr.state.code_hash.expr(), code_size.expr());
});
}

Self {
same_context,
code_offset,
Expand Down
32 changes: 17 additions & 15 deletions zkevm-circuits/src/evm_circuit/execution/codesize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use crate::{
evm_circuit::{
step::ExecutionState,
util::{
common_gadget::SameContextGadget,
common_gadget::{BytecodeLengthGadget, SameContextGadget},
constraint_builder::{
ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition,
},
from_bytes, CachedRegion, Cell,
from_bytes, not, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
Expand All @@ -24,7 +24,7 @@ use super::ExecutionGadget;
pub(crate) struct CodesizeGadget<F> {
same_context: SameContextGadget<F>,
codesize_bytes: [Cell<F>; 8],
codesize: Cell<F>,
code_len_gadget: BytecodeLengthGadget<F>,
}

impl<F: Field> ExecutionGadget<F> for CodesizeGadget<F> {
Expand All @@ -38,14 +38,6 @@ impl<F: Field> ExecutionGadget<F> for CodesizeGadget<F> {
let codesize_bytes = array_init(|_| cb.query_byte());

let code_hash = cb.curr.state.code_hash.clone();
let codesize = cb.query_cell();
cb.bytecode_length(code_hash.expr(), codesize.expr());

cb.require_equal(
"Constraint: bytecode length lookup == codesize",
from_bytes::expr(&codesize_bytes),
codesize.expr(),
);

cb.stack_push(cb.word_rlc(codesize_bytes.clone().map(|c| c.expr())));

Expand All @@ -57,11 +49,22 @@ impl<F: Field> ExecutionGadget<F> for CodesizeGadget<F> {
..Default::default()
};
let same_context = SameContextGadget::construct(cb, opcode, step_state_transition);
#[cfg(not(feature = "dual_bytecode"))]
let code_len_gadget = BytecodeLengthGadget::construct(cb, code_hash);
#[cfg(feature = "dual_bytecode")]
let code_len_gadget =
BytecodeLengthGadget::construct(cb, code_hash, same_context.is_first_sub_bytecode());

cb.require_equal(
"Constraint: bytecode length lookup == codesize",
from_bytes::expr(&codesize_bytes),
code_len_gadget.code_length.expr(),
);

Self {
same_context,
codesize_bytes,
codesize,
code_len_gadget,
}
}

Expand All @@ -87,9 +90,8 @@ impl<F: Field> ExecutionGadget<F> for CodesizeGadget<F> {
c.assign(region, offset, Value::known(F::from(*b as u64)))?;
}

self.codesize
.assign(region, offset, Value::known(F::from(codesize)))?;

self.code_len_gadget
.assign(region, offset, block, call, codesize)?;
Ok(())
}
}
Expand Down
1 change: 0 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ impl<F: Field> ExecutionGadget<F> for StopGadget<F> {
let opcode = cb.query_cell();
#[cfg(feature = "dual_bytecode")]
let is_first_bytecode_table = cb.query_bool();

#[cfg(not(feature = "dual_bytecode"))]
cb.bytecode_length(cb.curr.state.code_hash.expr(), code_length.expr());

Expand Down
52 changes: 52 additions & 0 deletions zkevm-circuits/src/evm_circuit/util/common_gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,58 @@ impl<F: Field> SameContextGadget<F> {
}
}

#[derive(Clone, Debug)]
pub(crate) struct BytecodeLengthGadget<F> {
pub(crate) code_length: Cell<F>,
// indicates current op code belongs to first or second bytecode table.
// should be bool type.
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table: Expression<F>,
}

impl<F: Field> BytecodeLengthGadget<F> {
pub(crate) fn construct(
cb: &mut EVMConstraintBuilder<F>,
code_hash: Cell<F>,
#[cfg(feature = "dual_bytecode")] is_first_bytecode_table: Expression<F>,
) -> Self {
// Fetch the bytecode length from the bytecode table.
let code_length = cb.query_cell();
#[cfg(not(feature = "dual_bytecode"))]
cb.bytecode_length(code_hash.expr(), code_length.expr());

#[cfg(feature = "dual_bytecode")]
{
cb.condition(is_first_bytecode_table.clone(), |cb| {
cb.bytecode_length(code_hash.expr(), code_length.expr());
});
cb.condition(not::expr(is_first_bytecode_table.clone()), |cb| {
cb.bytecode2_length(code_hash.expr(), code_length.expr());
});
}
Self {
code_length,
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table,
}
}

pub(crate) fn assign(
&self,
region: &mut CachedRegion<'_, '_, F>,
offset: usize,
block: &Block,
call: &Call,
code_len: u64,
) -> Result<(), Error> {
// TODO: get code length dynamically here ?
self.code_length
.assign(region, offset, Value::known(F::from(code_len)))?;

Ok(())
}
}

/// Construction of step state transition that restores caller's state.
#[derive(Clone, Debug)]
pub(crate) struct RestoreContextGadget<F> {
Expand Down

0 comments on commit 900c336

Please sign in to comment.