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

Commit

Permalink
[Opcode] Jumpdest (#143)
Browse files Browse the repository at this point in the history
* implement jumpdest code

* fix fmt

* change format

* mark _step

Co-authored-by: Dream Wu <[email protected]>
  • Loading branch information
scroll-dev and DreamWuGit authored Nov 5, 2021
1 parent 197b41d commit 2a0c179
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bus-mapping/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ pub struct GasCost(u64);
impl GasCost {
/// Constant cost for free step
pub const ZERO: Self = Self(0);
/// Constant cost for jumpdest step, only it takes one gas
pub const ONE: Self = Self(1);
/// Constant cost for quick step
pub const QUICK: Self = Self(2);
/// Constant cost for fastest step
Expand Down
13 changes: 13 additions & 0 deletions zkevm-circuits/src/evm_circuit/op_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod arithmetic;
mod byte;
mod comparator;
mod dup;
mod jumpdest;
mod pc;
mod pop;
mod push;
Expand All @@ -29,6 +30,7 @@ use arithmetic::AddGadget;
use byte::ByteGadget;
use comparator::ComparatorGadget;
use dup::DupGadget;
use jumpdest::JumpdestGadget;
use pc::PcGadget;
use pop::PopGadget;
use push::PushGadget;
Expand Down Expand Up @@ -229,6 +231,7 @@ pub(crate) struct OpExecutionGadget<F> {
pc_gadget: PcGadget<F>,
signextend_gadget: SignextendGadget<F>,
swap_gadget: SwapGadget<F>,
jumpdest_gadget: JumpdestGadget<F>,
}

impl<F: FieldExt> OpExecutionGadget<F> {
Expand Down Expand Up @@ -291,6 +294,7 @@ impl<F: FieldExt> OpExecutionGadget<F> {
construct_op_gadget!(pc_gadget);
construct_op_gadget!(signextend_gadget);
construct_op_gadget!(swap_gadget);
construct_op_gadget!(jumpdest_gadget);
let _ = qs_op_idx;

for constraint in constraints.into_iter() {
Expand Down Expand Up @@ -335,6 +339,7 @@ impl<F: FieldExt> OpExecutionGadget<F> {
pc_gadget,
signextend_gadget,
swap_gadget,
jumpdest_gadget,
}
}

Expand Down Expand Up @@ -603,6 +608,14 @@ impl<F: FieldExt> OpExecutionGadget<F> {
(_, _, _, OpcodeId::SIGNEXTEND) => self
.signextend_gadget
.assign(region, offset, core_state, execution_step)?,

(_, _, _, OpcodeId::JUMPDEST) => self.jumpdest_gadget.assign(
region,
offset,
core_state,
execution_step,
)?,

_ => unimplemented!(),
}
}
Expand Down
138 changes: 138 additions & 0 deletions zkevm-circuits/src/evm_circuit/op_execution/jumpdest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use super::super::{Case, Cell, Constraint, ExecutionStep};
use super::utils;
use super::utils::common_cases::OutOfGasCase;
use super::utils::constraint_builder::ConstraintBuilder;
use super::{
CaseAllocation, CaseConfig, CoreStateInstance, OpExecutionState, OpGadget,
};
use crate::impl_op_gadget;
use crate::util::Expr;
use bus_mapping::evm::{GasCost, OpcodeId};
use halo2::plonk::Error;
use halo2::{arithmetic::FieldExt, circuit::Region};
use std::convert::TryInto;

const GC_DELTA: usize = 0;
const PC_DELTA: usize = 1;
const SP_DELTA: usize = 0;
const GAS: GasCost = GasCost::ONE;

impl_op_gadget!(
[JUMPDEST]
JumpdestGadget {
JumpdestSuccessCase(),
OutOfGasCase(GAS.as_usize()),
}
);

#[derive(Clone, Debug)]
struct JumpdestSuccessCase<F> {
case_selector: Cell<F>,
}

impl<F: FieldExt> JumpdestSuccessCase<F> {
pub(crate) const CASE_CONFIG: &'static CaseConfig = &CaseConfig {
case: Case::Success,
num_word: 0,
num_cell: 0,
will_halt: false,
};

pub(crate) fn construct(alloc: &mut CaseAllocation<F>) -> Self {
Self {
case_selector: alloc.selector.clone(),
}
}

pub(crate) fn constraint(
&self,
state_curr: &OpExecutionState<F>,
state_next: &OpExecutionState<F>,
name: &'static str,
) -> Constraint<F> {
let mut cb = ConstraintBuilder::default();
// State transitions
utils::StateTransitions {
gc_delta: Some(GC_DELTA.expr()),
sp_delta: Some(SP_DELTA.expr()),
pc_delta: Some(PC_DELTA.expr()),
gas_delta: Some(GAS.expr()),
}
.constraints(&mut cb, state_curr, state_next);

// Generate the constraint
cb.constraint(self.case_selector.expr(), name)
}

fn assign(
&self,
region: &mut Region<'_, F>,
offset: usize,
state: &mut CoreStateInstance,
_step: &ExecutionStep,
) -> Result<(), Error> {
state.global_counter += GC_DELTA;
state.program_counter += PC_DELTA;
state.stack_pointer += SP_DELTA;
state.gas_counter += GAS.as_usize();

self.case_selector
.assign(region, offset, Some(F::from_u64(1)))
.unwrap();
Ok(())
}
}

#[cfg(test)]
mod test {
use super::super::super::{
test::TestCircuit, Case, ExecutionStep, Operation,
};
use bus_mapping::{evm::OpcodeId, operation::Target};
use halo2::{arithmetic::FieldExt, dev::MockProver};
use num::BigUint;
use pasta_curves::pallas::Base;

macro_rules! try_test_circuit {
($execution_steps:expr, $operations:expr, $result:expr) => {{
let circuit =
TestCircuit::<Base>::new($execution_steps, $operations);
let prover = MockProver::<Base>::run(10, &circuit, vec![]).unwrap();
assert_eq!(prover.verify(), $result);
}};
}

#[test]
fn jumpdest_gadget() {
try_test_circuit!(
vec![
ExecutionStep {
opcode: OpcodeId::PUSH2,
case: Case::Success,
values: vec![
BigUint::from(0x02_03u64),
BigUint::from(0x01_01u64),
],
},
ExecutionStep {
// jumpdest
opcode: OpcodeId::JUMPDEST,
case: Case::Success,
values: vec![],
}
],
vec![Operation {
gc: 1,
target: Target::Stack,
is_write: true,
values: [
Base::zero(),
Base::from_u64(1023),
Base::from_u64(2 + 3),
Base::zero(),
]
}],
Ok(())
);
}
}

0 comments on commit 2a0c179

Please sign in to comment.