Skip to content

Commit

Permalink
refactor & fix extcodecopy regarding bytelength gadget
Browse files Browse the repository at this point in the history
  • Loading branch information
DreamWuGit committed Aug 2, 2024
1 parent 63d0475 commit e7f490e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 25 deletions.
11 changes: 6 additions & 5 deletions zkevm-circuits/src/evm_circuit/execution/codesize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ 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());
let code_len_gadget = BytecodeLengthGadget::construct(
cb,
code_hash,
#[cfg(feature = "dual_bytecode")]
same_context.is_first_sub_bytecode(),
);

cb.require_equal(
"Constraint: bytecode length lookup == codesize",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,11 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {

fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let is_first_bytecode_table = cb.query_cell();
#[cfg(not(feature = "dual_bytecode"))]
let code_len_gadget = BytecodeLengthGadget::construct(cb, cb.curr.state.code_hash.clone());

#[cfg(feature = "dual_bytecode")]
let code_len_gadget = BytecodeLengthGadget::construct(
cb,
cb.curr.state.code_hash.clone(),
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table.expr(),
);

Expand Down
60 changes: 43 additions & 17 deletions zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
param::{N_BYTES_ACCOUNT_ADDRESS, N_BYTES_MEMORY_WORD_SIZE, N_BYTES_U64},
step::ExecutionState,
util::{
common_gadget::{SameContextGadget, WordByteCapGadget},
common_gadget::{BytecodeLengthGadget, SameContextGadget, WordByteCapGadget},
constraint_builder::{
ConstrainBuilderCommon, EVMConstraintBuilder, ReversionInfo, StepStateTransition,
Transition,
Expand Down Expand Up @@ -40,10 +40,12 @@ pub(crate) struct ExtcodecopyGadget<F> {
is_warm: Cell<F>,
code_hash: Cell<F>,
not_exists: IsZeroGadget<F>,
code_size: Cell<F>,
code_len_gadget: BytecodeLengthGadget<F>,
copy_rwc_inc: Cell<F>,
memory_expansion: MemoryExpansionGadget<F, 1, N_BYTES_MEMORY_WORD_SIZE>,
memory_copier_gas: MemoryCopierGasGadget<F, { GasCost::COPY }>,
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table: Cell<F>,
}

impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
Expand All @@ -53,16 +55,34 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {

fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let opcode = cb.query_cell();
let is_first_bytecode_table = cb.query_bool();

let external_address_word = cb.query_word_rlc();
let external_address =
from_bytes::expr(&external_address_word.cells[..N_BYTES_ACCOUNT_ADDRESS]);

let code_size = cb.query_cell();

//let code_size = cb.query_cell();
let memory_length = cb.query_word_rlc();
let memory_offset = cb.query_cell_phase2();
let code_offset = WordByteCapGadget::construct(cb, code_size.expr());

let code_hash = cb.query_cell_phase2();
let not_exists = IsZeroGadget::construct(cb, code_hash.clone().expr());
let exists = not::expr(not_exists.expr());

// the reason why not use `same_context.is_first_sub_bytecode` to construct `code_len_gadget` includes
// 1: `same_context` requires rw_counter_offset info, which depends on `code_offset` info, the latter relies on
// `code_len` of `code_len_gadget`
// 2: `same_context.is_first_sub_bytecode` returns current call bytecode info, in extcodecopy, code_hash is not
// necessary current call code hash.
let code_len_gadget = cb.condition(exists.expr(), |cb| {
BytecodeLengthGadget::construct(
cb,
code_hash.clone(),
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table.expr(),
)
});
let code_offset = WordByteCapGadget::construct(cb, code_len_gadget.code_length.expr());

cb.stack_pop(external_address_word.expr());
cb.stack_pop(memory_offset.expr());
Expand All @@ -80,19 +100,17 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
Some(&mut reversion_info),
);

let code_hash = cb.query_cell_phase2();
cb.account_read(
external_address.expr(),
AccountFieldTag::CodeHash,
code_hash.expr(),
);
let not_exists = IsZeroGadget::construct(cb, code_hash.expr());
let exists = not::expr(not_exists.expr());
cb.condition(exists.expr(), |cb| {
cb.bytecode_length(code_hash.expr(), code_size.expr());
});

cb.condition(not_exists.expr(), |cb| {
cb.require_zero("code_size is zero when non_exists", code_size.expr());
cb.require_zero(
"code_size is zero when non_exists",
code_len_gadget.code_length.expr(),
);
});

let memory_address = MemoryAddressGadget::construct(cb, memory_offset, memory_length);
Expand All @@ -115,7 +133,7 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
let src_addr = select::expr(
code_offset.lt_cap(),
code_offset.valid_value(),
code_size.expr(),
code_len_gadget.code_length.expr(),
);

cb.copy_table_lookup(
Expand All @@ -124,7 +142,7 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
cb.curr.state.call_id.expr(),
CopyDataType::Memory.expr(),
src_addr,
code_size.expr(),
code_len_gadget.code_length.expr(),
memory_address.offset(),
memory_address.length(),
0.expr(),
Expand Down Expand Up @@ -159,10 +177,12 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
is_warm,
code_hash,
not_exists,
code_size,
code_len_gadget,
copy_rwc_inc,
memory_expansion,
memory_copier_gas,
#[cfg(feature = "dual_bytecode")]
is_first_bytecode_table,
}
}

Expand Down Expand Up @@ -215,9 +235,9 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
.bytes
.len() as u64
};
self.code_size
.assign(region, offset, Value::known(F::from(code_size)))?;

self.code_len_gadget
.assign(region, offset, block, call, code_size)?;
self.code_offset
.assign(region, offset, code_offset, F::from(code_size))?;

Expand Down Expand Up @@ -245,6 +265,12 @@ impl<F: Field> ExecutionGadget<F> for ExtcodecopyGadget<F> {
memory_expansion_gas_cost,
)?;

#[cfg(feature = "dual_bytecode")]
self.is_first_bytecode_table.assign(
region,
offset,
Value::known(F::from(block.is_first_bytecode(&code_hash))),
)?;
Ok(())
}
}
Expand Down

0 comments on commit e7f490e

Please sign in to comment.