Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.
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
12 changes: 12 additions & 0 deletions bus-mapping/src/circuit_input_builder/input_state_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ impl<'a> CircuitInputStateRef<'a> {
.ok_or(Error::CodeNotFound(code_hash))
}

/// Reference to the caller's Call
pub fn caller(&self) -> Result<&Call, Error> {
self.tx_ctx
.caller_index()
.map(|caller_idx| &self.tx.calls()[caller_idx])
}

/// Reference to the current Call
pub fn call(&self) -> Result<&Call, Error> {
self.tx_ctx
Expand All @@ -384,6 +391,11 @@ impl<'a> CircuitInputStateRef<'a> {
.map(|call_idx| &mut self.tx.calls_mut()[call_idx])
}

/// Reference to the current CallContext
pub fn caller_ctx(&self) -> Result<&CallContext, Error> {
self.tx_ctx.caller_ctx()
}

/// Reference to the current CallContext
pub fn call_ctx(&self) -> Result<&CallContext, Error> {
self.tx_ctx.call_ctx()
Expand Down
14 changes: 12 additions & 2 deletions bus-mapping/src/circuit_input_builder/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,24 @@ impl TransactionContext {
&self.calls
}

/// Return the index of the caller (the second last call in the call stack).
pub(crate) fn caller_index(&self) -> Result<usize, Error> {
self.caller_ctx().map(|call| call.index)
}

/// Return the index of the current call (the last call in the call stack).
pub(crate) fn call_index(&self) -> Result<usize, Error> {
self.call_ctx().map(|call| call.index)
}

pub(crate) fn caller_ctx(&self) -> Result<&CallContext, Error> {
self.calls
.last()
.len()
.checked_sub(2)
.map(|idx| &self.calls[idx])
.ok_or(Error::InvalidGethExecTrace(
"Call stack is empty but call is used",
))
.map(|call| call.index)
}

pub(crate) fn call_ctx(&self) -> Result<&CallContext, Error> {
Expand Down
14 changes: 9 additions & 5 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod mload;
mod mstore;
mod number;
mod origin;
mod r#return;
Comment thread
ed255 marked this conversation as resolved.
mod selfbalance;
mod sload;
mod sstore;
Expand All @@ -56,6 +57,7 @@ use logs::Log;
use mload::Mload;
use mstore::Mstore;
use origin::Origin;
use r#return::Return;
use selfbalance::Selfbalance;
use sload::Sload;
use sstore::Sstore;
Expand Down Expand Up @@ -200,13 +202,15 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps {
// OpcodeId::CREATE => {},
OpcodeId::CALL => Call::gen_associated_ops,
// OpcodeId::CALLCODE => {},
// TODO: Handle RETURN by its own gen_associated_ops.
OpcodeId::RETURN => Stop::gen_associated_ops,
// OpcodeId::RETURN => {},
// OpcodeId::DELEGATECALL => {},
// OpcodeId::CREATE2 => {},
// OpcodeId::STATICCALL => {},
// TODO: Handle REVERT by its own gen_associated_ops.
OpcodeId::REVERT => Stop::gen_associated_ops,
// OpcodeId::REVERT => {},
OpcodeId::REVERT | OpcodeId::RETURN => {
warn!("Using dummy gen_associated_ops for opcode {:?}", opcode_id);
Comment thread
ed255 marked this conversation as resolved.
Return::gen_associated_ops
}
OpcodeId::SELFDESTRUCT => {
warn!("Using dummy gen_selfdestruct_ops for opcode SELFDESTRUCT");
dummy_gen_selfdestruct_ops
Expand Down Expand Up @@ -375,7 +379,7 @@ pub fn gen_begin_tx_ops(state: &mut CircuitInputStateRef) -> Result<ExecStep, Er
(CallContextField::LastCalleeReturnDataLength, 0.into()),
(CallContextField::IsRoot, 1.into()),
(CallContextField::IsCreate, 0.into()),
(CallContextField::CodeSource, code_hash.to_word()),
(CallContextField::CodeHash, code_hash.to_word()),
] {
state.push_op(
&mut exec_step,
Expand Down
4 changes: 2 additions & 2 deletions bus-mapping/src/evm/opcodes/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl Opcode for Call {
),
(CallContextField::MemorySize, next_memory_word_size.into()),
(
CallContextField::StateWriteCounter,
CallContextField::ReversibleWriteCounter,
(exec_step.reversible_write_counter + 1).into(),
),
] {
Expand Down Expand Up @@ -220,7 +220,7 @@ impl Opcode for Call {
(CallContextField::LastCalleeReturnDataLength, 0.into()),
(CallContextField::IsRoot, 0.into()),
(CallContextField::IsCreate, 0.into()),
(CallContextField::CodeSource, call.code_hash.to_word()),
(CallContextField::CodeHash, call.code_hash.to_word()),
] {
state.call_context_read(&mut exec_step, call.call_id, field, value);
}
Expand Down
4 changes: 2 additions & 2 deletions bus-mapping/src/evm/opcodes/codesize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ impl Opcode for Codesize {
let geth_step = &geth_steps[0];
let mut exec_step = state.new_step(geth_step)?;

let code_source = state.call()?.code_hash;
let code = state.code(code_source)?;
let code_hash = state.call()?.code_hash;
let code = state.code(code_hash)?;
let codesize = code.len();

debug_assert_eq!(codesize, geth_steps[1].stack.last()?.as_usize());
Expand Down
24 changes: 24 additions & 0 deletions bus-mapping/src/evm/opcodes/return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::Opcode;
use crate::circuit_input_builder::{CircuitInputStateRef, ExecStep};
use crate::Error;
use eth_types::GethExecStep;

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the [`OpcodeId::RETURN`](crate::evm::OpcodeId::RETURN).
#[derive(Debug, Copy, Clone)]
pub(crate) struct Return;

impl Opcode for Return {
fn gen_associated_ops(
state: &mut CircuitInputStateRef,
geth_steps: &[GethExecStep],
) -> Result<Vec<ExecStep>, Error> {
let geth_step = &geth_steps[0];
let exec_step = state.new_step(geth_step)?;
Comment thread
ed255 marked this conversation as resolved.

// TODO: Generate associated operations of RETURN

state.handle_return(geth_step)?;
Ok(vec![exec_step])
}
}
103 changes: 99 additions & 4 deletions bus-mapping/src/evm/opcodes/stop.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::Opcode;
use crate::circuit_input_builder::{CircuitInputStateRef, ExecStep};
use crate::Error;
use eth_types::GethExecStep;
use crate::{
circuit_input_builder::{CircuitInputStateRef, ExecStep},
operation::{CallContextField, CallContextOp, RW},
Error,
};
use eth_types::{GethExecStep, ToWord};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the [`OpcodeId::STOP`](crate::evm::OpcodeId::STOP)
Expand All @@ -18,8 +21,100 @@ impl Opcode for Stop {
geth_steps: &[GethExecStep],
) -> Result<Vec<ExecStep>, Error> {
let geth_step = &geth_steps[0];
let exec_step = state.new_step(geth_step)?;
let mut exec_step = state.new_step(geth_step)?;

let call = state.call()?.clone();

state.push_op(
&mut exec_step,
RW::READ,
CallContextOp {
call_id: call.call_id,
field: CallContextField::IsSuccess,
value: 1.into(),
},
);

if call.is_root {
state.push_op(
&mut exec_step,
RW::READ,
CallContextOp {
call_id: call.call_id,
field: CallContextField::IsPersistent,
value: 1.into(),
},
);
} else {
// The following part corresponds to
// Instruction.step_state_transition_to_restored_context
// in python spec, and should be reusable among all expected halting opcodes or
// exceptions. TODO: Refactor it as a helper function.
let caller = state.caller()?.clone();
Comment thread
ed255 marked this conversation as resolved.
state.push_op(
&mut exec_step,
RW::READ,
CallContextOp {
call_id: call.call_id,
field: CallContextField::CallerId,
value: caller.call_id.into(),
},
);

let geth_step_next = &geth_steps[1];
let caller_gas_left = geth_step_next.gas.0 - geth_step.gas.0;
for (field, value) in [
(CallContextField::IsRoot, (caller.is_root as u64).into()),
(
CallContextField::IsCreate,
(caller.is_create() as u64).into(),
),
(CallContextField::CodeHash, caller.code_hash.to_word()),
(CallContextField::ProgramCounter, geth_step_next.pc.0.into()),
(
CallContextField::StackPointer,
geth_step_next.stack.stack_pointer().0.into(),
),
(CallContextField::GasLeft, caller_gas_left.into()),
(
CallContextField::MemorySize,
geth_step_next.memory.word_size().into(),
),
(
CallContextField::ReversibleWriteCounter,
state.caller_ctx()?.reversible_write_counter.into(),
),
] {
state.push_op(
&mut exec_step,
RW::READ,
CallContextOp {
call_id: caller.call_id,
field,
value,
},
);
}

for (field, value) in [
(CallContextField::LastCalleeId, call.call_id.into()),
(CallContextField::LastCalleeReturnDataOffset, 0.into()),
(CallContextField::LastCalleeReturnDataLength, 0.into()),
] {
state.push_op(
&mut exec_step,
RW::WRITE,
CallContextOp {
call_id: caller.call_id,
field,
value,
},
);
}
}

state.handle_return(geth_step)?;

Ok(vec![exec_step])
}
}
8 changes: 4 additions & 4 deletions bus-mapping/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,8 @@ pub enum CallContextField {
IsRoot,
/// IsCreate
IsCreate,
/// CodeSource
CodeSource,
/// CodeHash
CodeHash,
/// ProgramCounter
ProgramCounter,
/// StackPointer
Expand All @@ -707,8 +707,8 @@ pub enum CallContextField {
GasLeft,
/// MemorySize
MemorySize,
/// StateWriteCounter
StateWriteCounter,
/// ReversibleWriteCounter
ReversibleWriteCounter,
}

/// Represents an CallContext read/write operation.
Expand Down
14 changes: 9 additions & 5 deletions zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ pub mod test {
)
}

fn load_bytecodes(
fn load_bytecodes<'a>(
&self,
layouter: &mut impl Layouter<F>,
bytecodes: &[Bytecode],
bytecodes: impl IntoIterator<Item = &'a Bytecode> + Clone,
randomness: F,
) -> Result<(), Error> {
layouter.assign_region(
Expand All @@ -290,7 +290,7 @@ pub mod test {
}
offset += 1;

for bytecode in bytecodes.iter() {
for bytecode in bytecodes.clone() {
for row in bytecode.table_assignments(randomness) {
for (column, value) in self.bytecode_table.iter().zip_eq(row) {
region.assign_advice(
Expand Down Expand Up @@ -420,7 +420,11 @@ pub mod test {
config.evm_circuit.load_byte_table(&mut layouter)?;
config.load_txs(&mut layouter, &self.block.txs, self.block.randomness)?;
config.load_rws(&mut layouter, &self.block.rws, self.block.randomness)?;
config.load_bytecodes(&mut layouter, &self.block.bytecodes, self.block.randomness)?;
config.load_bytecodes(
&mut layouter,
self.block.bytecodes.values(),
self.block.randomness,
)?;
config.load_block(&mut layouter, &self.block.context, self.block.randomness)?;
config
.evm_circuit
Expand Down Expand Up @@ -459,7 +463,7 @@ pub mod test {
let k = k.max(log2_ceil(
64 + block
.bytecodes
.iter()
.values()
.map(|bytecode| bytecode.bytes.len())
.sum::<usize>(),
));
Expand Down
Loading