diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs index 58a31c2b2c..1505b4fcf3 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs @@ -4,11 +4,10 @@ use crate::{ param::N_BYTES_PROGRAM_COUNTER, step::ExecutionState, util::{ - and, - common_gadget::{CommonErrorGadget, WordByteRangeGadget}, + common_gadget::{CommonErrorGadget, WordByteCapGadget}, constraint_builder::ConstraintBuilder, - math_gadget::{IsEqualGadget, IsZeroGadget, LtGadget}, - select, CachedRegion, Cell, + math_gadget::{IsEqualGadget, IsZeroGadget}, + CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, }, @@ -21,11 +20,10 @@ use halo2_proofs::{circuit::Value, plonk::Error}; #[derive(Clone, Debug)] pub(crate) struct ErrorInvalidJumpGadget { opcode: Cell, - dest_word: WordByteRangeGadget, + dest: WordByteCapGadget, code_len: Cell, value: Cell, is_code: Cell, - dest_lt_code_len: LtGadget, is_jump_dest: IsEqualGadget, is_jumpi: IsEqualGadget, phase2_condition: Cell, @@ -39,12 +37,8 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { const EXECUTION_STATE: ExecutionState = ExecutionState::ErrorInvalidJump; fn configure(cb: &mut ConstraintBuilder) -> Self { - let dest_word = WordByteRangeGadget::construct(cb); - let dest = select::expr( - dest_word.within_range(), - dest_word.valid_value(), - u64::MAX.expr(), - ); + let code_len = cb.query_cell(); + let dest = WordByteCapGadget::construct(cb, code_len.expr()); let opcode = cb.query_cell(); let value = cb.query_cell(); @@ -67,7 +61,7 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { let is_condition_zero = IsZeroGadget::construct(cb, phase2_condition.expr()); // Pop the value from the stack - cb.stack_pop(dest_word.original_word()); + cb.stack_pop(dest.original_word()); cb.condition(is_jumpi.expr(), |cb| { cb.stack_pop(phase2_condition.expr()); @@ -76,38 +70,31 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { }); // Look up bytecode length - let code_len = cb.query_cell(); cb.bytecode_length(cb.curr.state.code_hash.expr(), code_len.expr()); - let dest_lt_code_len = LtGadget::construct(cb, dest.expr(), code_len.expr()); - // If destination is in valid range, lookup for the value. - cb.condition( - and::expr([dest_word.within_range(), dest_lt_code_len.expr()]), - |cb| { - cb.bytecode_lookup( - cb.curr.state.code_hash.expr(), - dest.expr(), - is_code.expr(), - value.expr(), - ); - cb.require_zero( - "is_code is false or not JUMPDEST", - is_code.expr() * is_jump_dest.expr(), - ); - }, - ); + cb.condition(dest.lt_cap(), |cb| { + cb.bytecode_lookup( + cb.curr.state.code_hash.expr(), + dest.valid_value(), + is_code.expr(), + value.expr(), + ); + cb.require_zero( + "is_code is false or not JUMPDEST", + is_code.expr() * is_jump_dest.expr(), + ); + }); let common_error_gadget = CommonErrorGadget::construct(cb, opcode.expr(), 3.expr() + is_jumpi.expr()); Self { opcode, - dest_word, + dest, code_len, value, is_code, - dest_lt_code_len, is_jump_dest, is_jumpi, phase2_condition, @@ -130,9 +117,6 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { self.opcode .assign(region, offset, Value::known(F::from(opcode.as_u64())))?; - let dest = block.rws[step.rw_indices[0]].stack_value(); - let dest_within_range = self.dest_word.assign(region, offset, dest)?; - let condition = if is_jumpi { block.rws[step.rw_indices[1]].stack_value() } else { @@ -148,13 +132,11 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { self.code_len .assign(region, offset, Value::known(F::from(code_len)))?; - let dest = if dest_within_range { - dest.as_u64() - } else { - u64::MAX - }; + let dest = block.rws[step.rw_indices[0]].stack_value(); + self.dest.assign(region, offset, dest, F::from(code_len))?; // set default value in case can not find value, is_code from bytecode table + let dest = u64::try_from(dest).unwrap_or(code_len); let mut code_pair = [0u8, 0u8]; if dest < code_len { // get real value from bytecode table @@ -172,9 +154,6 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { F::from(OpcodeId::JUMPDEST.as_u64()), )?; - self.dest_lt_code_len - .assign(region, offset, F::from(dest), F::from(code_len))?; - self.is_jumpi.assign( region, offset,