Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support dummy PUSH0 #1

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod mload;
mod mstore;
mod number;
mod origin;
mod push0;
mod return_revert;
mod returndatacopy;
mod returndatasize;
Expand Down Expand Up @@ -91,6 +92,7 @@ use logs::Log;
use mload::Mload;
use mstore::Mstore;
use origin::Origin;
use push0::Push0;
use return_revert::ReturnRevert;
use returndatacopy::Returndatacopy;
use returndatasize::Returndatasize;
Expand Down Expand Up @@ -143,6 +145,9 @@ type FnGenAssociatedOps = fn(
) -> Result<Vec<ExecStep>, Error>;

fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps {
if opcode_id.is_push0() {
return Push0::gen_associated_ops;
}
if opcode_id.is_push() {
return StackOnlyOpcode::<0, 1>::gen_associated_ops;
}
Expand Down
27 changes: 27 additions & 0 deletions bus-mapping/src/evm/opcodes/push0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::Opcode;
use crate::{
circuit_input_builder::{CircuitInputStateRef, ExecStep},
Error,
};
use eth_types::{GethExecStep, U256};

#[derive(Clone, Copy, Debug)]
pub(crate) struct Push0;

impl Opcode for Push0 {
fn gen_associated_ops(
state: &mut CircuitInputStateRef,
geth_steps: &[GethExecStep],
) -> Result<Vec<ExecStep>, Error> {
let geth_step = &geth_steps[0];
let mut exec_step = state.new_step(geth_step)?;

state.stack_write(
&mut exec_step,
geth_steps[1].stack.last_filled(),
U256::zero(),
)?;

Ok(vec![exec_step])
}
}
9 changes: 9 additions & 0 deletions eth-types/src/evm_types/opcode_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub enum OpcodeId {
JUMPDEST,

// PUSHn
/// `PUSH0`
PUSH0,
/// `PUSH1`
PUSH1,
/// `PUSH2`
Expand Down Expand Up @@ -320,6 +322,11 @@ impl OpcodeId {
self.as_u8() >= Self::PUSH1.as_u8() && self.as_u8() <= Self::PUSH32.as_u8()
}

/// Returns `true` if the `OpcodeId` is a `PUSH0`.
pub fn is_push0(&self) -> bool {
self == &Self::PUSH0
}

/// Returns `true` if the `OpcodeId` is a `DUPn`.
pub fn is_dup(&self) -> bool {
self.as_u8() >= Self::DUP1.as_u8() && self.as_u8() <= Self::DUP16.as_u8()
Expand Down Expand Up @@ -402,6 +409,7 @@ impl OpcodeId {
OpcodeId::PC => 0x58u8,
OpcodeId::MSIZE => 0x59u8,
OpcodeId::JUMPDEST => 0x5bu8,
OpcodeId::PUSH0 => 0x5fu8,
OpcodeId::PUSH1 => 0x60u8,
OpcodeId::PUSH2 => 0x61u8,
OpcodeId::PUSH3 => 0x62u8,
Expand Down Expand Up @@ -580,6 +588,7 @@ impl OpcodeId {
OpcodeId::MSIZE => GasCost::QUICK,
OpcodeId::GAS => GasCost::QUICK,
OpcodeId::JUMPDEST => GasCost::ONE,
OpcodeId::PUSH0 => GasCost::QUICK,
OpcodeId::PUSH1 => GasCost::FASTEST,
OpcodeId::PUSH2 => GasCost::FASTEST,
OpcodeId::PUSH3 => GasCost::FASTEST,
Expand Down
6 changes: 4 additions & 2 deletions geth-utils/gethutil/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (a *Asm) PrintMnemonics(out io.Writer) {
for idx := 0; idx < len(a.bytecode); {
code := vm.OpCode(a.bytecode[idx])
if code.IsPush() {
n := int(code) - int(vm.PUSH1) + 1
n := int(code) - int(vm.PUSH0)
fmt.Fprintf(out, "%02d\t%s\t0x%x\n", idx, code.String(), a.bytecode[idx+1:idx+1+n])
idx += n + 1
} else {
Expand Down Expand Up @@ -121,6 +121,8 @@ func (a *Asm) MSize() *Asm { return a.appendByte(vm.MSIZE) }
func (a *Asm) Gas() *Asm { return a.appendByte(vm.GAS) }
func (a *Asm) JumpDest(label ...string) *Asm { return a.jumpDest(label...) }

func (a *Asm) Push0() *Asm { return a.appendByte(vm.PUSH0) }

// 0x60 range
func (a *Asm) PushX(val interface{}) *Asm { return a.push(val) }
func (a *Asm) DupX(x int) *Asm {
Expand Down Expand Up @@ -200,7 +202,7 @@ func (a *Asm) push(v ...interface{}) *Asm {
bytes := toBytes(v)

rangeCheck(len(bytes), 1, 32, "len(bytes)")
a.appendByte(int(vm.PUSH1) + len(bytes) - 1)
a.appendByte(int(vm.PUSH0) + len(bytes))

for _, b := range bytes {
a.appendByte(b)
Expand Down
4 changes: 4 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ mod origin;
mod pc;
mod pop;
mod push;
mod push0;
mod return_revert;
mod returndatacopy;
mod returndatasize;
Expand Down Expand Up @@ -165,6 +166,7 @@ use origin::OriginGadget;
use pc::PcGadget;
use pop::PopGadget;
use push::PushGadget;
use push0::DummyPush0Gadget;
use return_revert::ReturnRevertGadget;
use returndatacopy::ReturnDataCopyGadget;
use returndatasize::ReturnDataSizeGadget;
Expand Down Expand Up @@ -261,6 +263,7 @@ pub struct ExecutionConfig<F> {
pc_gadget: Box<PcGadget<F>>,
pop_gadget: Box<PopGadget<F>>,
push_gadget: Box<PushGadget<F>>,
push0_gadget: Box<DummyPush0Gadget<F>>,
return_revert_gadget: Box<ReturnRevertGadget<F>>,
sar_gadget: Box<SarGadget<F>>,
sdiv_smod_gadget: Box<SignedDivModGadget<F>>,
Expand Down Expand Up @@ -524,6 +527,7 @@ impl<F: Field> ExecutionConfig<F> {
pc_gadget: configure_gadget!(),
pop_gadget: configure_gadget!(),
push_gadget: configure_gadget!(),
push0_gadget: configure_gadget!(),
return_revert_gadget: configure_gadget!(),
sdiv_smod_gadget: configure_gadget!(),
selfbalance_gadget: configure_gadget!(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ mod test {
vec![0xf6],
vec![0xfe],
// Multiple invalid opcodes
vec![0x5c, 0x5e, 0x5f],
vec![0x5c, 0x5e],
];
}

Expand Down
66 changes: 66 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution/push0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::{
evm_circuit::{
execution::ExecutionGadget,
step::ExecutionState,
util::{
common_gadget::SameContextGadget,
constraint_builder::{EVMConstraintBuilder, StepStateTransition, Transition::Delta},
CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
util::Expr,
};
use eth_types::{evm_types::OpcodeId, Field};
use halo2_proofs::{circuit::Value, plonk::Error};

#[derive(Clone, Debug)]
pub(crate) struct DummyPush0Gadget<F> {
same_context: SameContextGadget<F>,
opcode: Cell<F>,
}

impl<F: Field> ExecutionGadget<F> for DummyPush0Gadget<F> {
const NAME: &'static str = "PUSH0";

const EXECUTION_STATE: ExecutionState = ExecutionState::PUSH0;

fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let opcode = cb.query_cell();
// The dummy gadget only push the zero value on the stack(increase the stack pointer by 1)
cb.stack_push(0.expr());

// State transition
// `program_counter` needs to be increased by number of bytes pushed + 1
let step_state_transition = StepStateTransition {
rw_counter: Delta(1.expr()),
program_counter: Delta(1.expr()),
stack_pointer: Delta((-1).expr()),
gas_left: Delta(-OpcodeId::PUSH0.constant_gas_cost().expr()),
..Default::default()
};
// SameContextGadget will increase the program_counter by 1
let same_context = SameContextGadget::construct(cb, opcode.clone(), step_state_transition);

Self {
same_context,
opcode,
}
}

fn assign_exec_step(
&self,
region: &mut CachedRegion<'_, '_, F>,
offset: usize,
_: &Block<F>,
_: &Transaction,
_: &Call,
step: &ExecStep,
) -> Result<(), Error> {
self.same_context.assign_exec_step(region, offset, step)?;
let opcode = step.opcode().unwrap();
self.opcode
.assign(region, offset, Value::known(F::from(opcode.as_u64())))?;
Ok(())
}
}
5 changes: 5 additions & 0 deletions zkevm-circuits/src/evm_circuit/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub enum ExecutionState {
MSIZE,
GAS,
JUMPDEST,
PUSH0,
PUSH, // PUSH1, PUSH2, ..., PUSH32
DUP, // DUP1, DUP2, ..., DUP16
SWAP, // SWAP1, SWAP2, ..., SWAP16
Expand Down Expand Up @@ -171,6 +172,9 @@ impl From<&ExecStep> for ExecutionState {
if op.is_dup() {
return ExecutionState::DUP;
}
if op.is_push0() {
return ExecutionState::PUSH0;
}
if op.is_push() {
return ExecutionState::PUSH;
}
Expand Down Expand Up @@ -379,6 +383,7 @@ impl ExecutionState {
Self::MSIZE => vec![OpcodeId::MSIZE],
Self::GAS => vec![OpcodeId::GAS],
Self::JUMPDEST => vec![OpcodeId::JUMPDEST],
Self::PUSH0 => vec![OpcodeId::PUSH0],
Self::PUSH => vec![
OpcodeId::PUSH1,
OpcodeId::PUSH2,
Expand Down