From cb1b6cbb39d2bc85810478377ae903edffc47814 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Wed, 30 Nov 2022 21:30:21 -0800 Subject: [PATCH] Generate memory ops --- evm/src/cpu/membus.rs | 2 +- evm/src/witness/operation.rs | 55 +++++++++++++++++++++++++++++++++++ evm/src/witness/transition.rs | 49 ++++++++++++++++++++++++------- evm/src/witness/util.rs | 2 ++ 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/evm/src/cpu/membus.rs b/evm/src/cpu/membus.rs index 1ec7b3e3..08cae757 100644 --- a/evm/src/cpu/membus.rs +++ b/evm/src/cpu/membus.rs @@ -8,7 +8,7 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer use crate::cpu::columns::CpuColumnsView; /// General-purpose memory channels; they can read and write to all contexts/segments/addresses. -pub const NUM_GP_CHANNELS: usize = 4; +pub const NUM_GP_CHANNELS: usize = 5; pub mod channel_indices { use std::ops::Range; diff --git a/evm/src/witness/operation.rs b/evm/src/witness/operation.rs index 8f25ae6c..445e445a 100644 --- a/evm/src/witness/operation.rs +++ b/evm/src/witness/operation.rs @@ -355,3 +355,58 @@ pub(crate) fn generate_exit_kernel( Ok(registers_state) } + +pub(crate) fn generate_mload_general( + mut registers_state: RegistersState, + memory_state: &MemoryState, + traces: &mut Traces, + mut row: CpuColumnsView, +) -> Result { + let [(context, log_in0), (segment, log_in1), (virt, log_in2)] = + stack_pop_with_log_and_fill::<3, _>(&mut registers_state, memory_state, traces, &mut row)?; + + // If virt won't fit in a usize, don't try to convert it, just return 0. + let val = if virt > usize::MAX.into() { + U256::zero() + } else { + memory_state.get(MemoryAddress { + context: context.as_usize(), + segment: segment.as_usize(), + virt: virt.as_usize(), + }) + }; + + let log_out = stack_push_log_and_fill(&mut registers_state, traces, &mut row, val)?; + + traces.push_memory(log_in0); + traces.push_memory(log_in1); + traces.push_memory(log_in2); + traces.push_memory(log_out); + traces.push_cpu(row); + Ok(registers_state) +} + +pub(crate) fn generate_mstore_general( + mut registers_state: RegistersState, + memory_state: &MemoryState, + traces: &mut Traces, + mut row: CpuColumnsView, +) -> Result { + let [(context, log_in0), (segment, log_in1), (virt, log_in2), (val, log_in3)] = + stack_pop_with_log_and_fill::<4, _>(&mut registers_state, memory_state, traces, &mut row)?; + + let address = MemoryAddress { + context: context.as_usize(), + segment: segment.as_usize(), + virt: virt.as_usize(), + }; + let log_write = mem_write_gp_log_and_fill(4, address, traces, &mut row, val); + + traces.push_memory(log_in0); + traces.push_memory(log_in1); + traces.push_memory(log_in2); + traces.push_memory(log_in3); + traces.push_memory(log_write); + traces.push_cpu(row); + Ok(registers_state) +} diff --git a/evm/src/witness/transition.rs b/evm/src/witness/transition.rs index 64b52fe5..78a86dd6 100644 --- a/evm/src/witness/transition.rs +++ b/evm/src/witness/transition.rs @@ -4,11 +4,7 @@ use crate::cpu::columns::CpuColumnsView; use crate::memory::segments::Segment; use crate::witness::errors::ProgramError; use crate::witness::memory::{MemoryAddress, MemoryState}; -use crate::witness::operation::{ - generate_binary_arithmetic_op, generate_binary_logic_op, generate_dup, generate_eq, - generate_exit_kernel, generate_iszero, generate_not, generate_push, generate_swap, - generate_syscall, generate_ternary_arithmetic_op, Operation, -}; +use crate::witness::operation::*; use crate::witness::state::RegistersState; use crate::witness::traces::Traces; use crate::witness::util::mem_read_code_with_log_and_fill; @@ -153,9 +149,9 @@ fn fill_op_flag(op: Operation, row: &mut CpuColumnsView) { Operation::Swap(_) => &mut flags.swap, Operation::Iszero => &mut flags.iszero, Operation::Not => &mut flags.not, + Operation::Byte => &mut flags.byte, Operation::Syscall(_) => &mut flags.syscall, Operation::Eq => &mut flags.eq, - Operation::ExitKernel => &mut flags.exit_kernel, Operation::BinaryLogic(logic::Op::And) => &mut flags.and, Operation::BinaryLogic(logic::Op::Or) => &mut flags.or, Operation::BinaryLogic(logic::Op::Xor) => &mut flags.xor, @@ -168,9 +164,25 @@ fn fill_op_flag(op: Operation, row: &mut CpuColumnsView) { Operation::BinaryArithmetic(arithmetic::BinaryOperator::Gt) => &mut flags.gt, Operation::BinaryArithmetic(arithmetic::BinaryOperator::Shl) => &mut flags.shl, Operation::BinaryArithmetic(arithmetic::BinaryOperator::Shr) => &mut flags.shr, + Operation::BinaryArithmetic(arithmetic::BinaryOperator::AddFp254) => &mut flags.addfp254, + Operation::BinaryArithmetic(arithmetic::BinaryOperator::MulFp254) => &mut flags.mulfp254, + Operation::BinaryArithmetic(arithmetic::BinaryOperator::SubFp254) => &mut flags.subfp254, Operation::TernaryArithmetic(arithmetic::TernaryOperator::AddMod) => &mut flags.addmod, Operation::TernaryArithmetic(arithmetic::TernaryOperator::MulMod) => &mut flags.mulmod, - _ => panic!("operation not implemented: {:?}", op), + Operation::KeccakGeneral => &mut flags.keccak_general, + Operation::ProverInput => &mut flags.prover_input, + Operation::Pop => &mut flags.pop, + Operation::Jump => &mut flags.jump, + Operation::Jumpi => &mut flags.jumpi, + Operation::Pc => &mut flags.pc, + Operation::Gas => &mut flags.gas, + Operation::Jumpdest => &mut flags.jumpdest, + Operation::GetContext => &mut flags.get_context, + Operation::SetContext => &mut flags.set_context, + Operation::ConsumeGas => &mut flags.consume_gas, + Operation::ExitKernel => &mut flags.exit_kernel, + Operation::MloadGeneral => &mut flags.mload_general, + Operation::MstoreGeneral => &mut flags.mstore_general, } = F::ONE; } @@ -187,11 +199,11 @@ fn perform_op( Operation::Swap(n) => generate_swap(n, registers_state, memory_state, traces, row)?, Operation::Iszero => generate_iszero(registers_state, memory_state, traces, row)?, Operation::Not => generate_not(registers_state, memory_state, traces, row)?, + Operation::Byte => todo!(), Operation::Syscall(opcode) => { generate_syscall(opcode, registers_state, memory_state, traces, row)? } Operation::Eq => generate_eq(registers_state, memory_state, traces, row)?, - Operation::ExitKernel => generate_exit_kernel(registers_state, memory_state, traces, row)?, Operation::BinaryLogic(binary_logic_op) => { generate_binary_logic_op(binary_logic_op, registers_state, memory_state, traces, row)? } @@ -201,7 +213,24 @@ fn perform_op( Operation::TernaryArithmetic(op) => { generate_ternary_arithmetic_op(op, registers_state, memory_state, traces, row)? } - _ => panic!("operation not implemented: {:?}", op), + Operation::KeccakGeneral => todo!(), + Operation::ProverInput => todo!(), + Operation::Pop => todo!(), + Operation::Jump => todo!(), + Operation::Jumpi => todo!(), + Operation::Pc => todo!(), + Operation::Gas => todo!(), + Operation::Jumpdest => todo!(), + Operation::GetContext => todo!(), + Operation::SetContext => todo!(), + Operation::ConsumeGas => todo!(), + Operation::ExitKernel => generate_exit_kernel(registers_state, memory_state, traces, row)?, + Operation::MloadGeneral => { + generate_mload_general(registers_state, memory_state, traces, row)? + } + Operation::MstoreGeneral => { + generate_mstore_general(registers_state, memory_state, traces, row)? + } }; new_registers_state.program_counter += match op { @@ -230,7 +259,7 @@ fn try_perform_instruction( registers_state.program_counter ); // TODO: Temporarily slowing down so we can view logs easily. - std::thread::sleep(std::time::Duration::from_millis(200)); + std::thread::sleep(std::time::Duration::from_millis(10)); fill_op_flag(op, &mut row); perform_op(op, registers_state, memory_state, traces, row) diff --git a/evm/src/witness/util.rs b/evm/src/witness/util.rs index d6c06473..cf4b6044 100644 --- a/evm/src/witness/util.rs +++ b/evm/src/witness/util.rs @@ -74,6 +74,7 @@ pub(crate) fn mem_read_gp_with_log_and_fill( let val_limbs: [u64; 4] = val.0; let channel = &mut row.mem_channels[n]; + assert_eq!(channel.used, F::ZERO); channel.used = F::ONE; channel.is_read = F::ONE; channel.addr_context = F::from_canonical_usize(address.context); @@ -98,6 +99,7 @@ pub(crate) fn mem_write_gp_log_and_fill( let val_limbs: [u64; 4] = val.0; let channel = &mut row.mem_channels[n]; + assert_eq!(channel.used, F::ZERO); channel.used = F::ONE; channel.is_read = F::ZERO; channel.addr_context = F::from_canonical_usize(address.context);