diff --git a/evm/src/cpu/kernel/asm/core/transfer.asm b/evm/src/cpu/kernel/asm/core/transfer.asm index 930c29f1..1f031eb8 100644 --- a/evm/src/cpu/kernel/asm/core/transfer.asm +++ b/evm/src/cpu/kernel/asm/core/transfer.asm @@ -97,7 +97,7 @@ global add_eth_new_account: PUSH 0 %append_to_trie_data // nonce %append_to_trie_data // balance // stack: addr, new_account_ptr, retdest - PUSH @EMPTY_NODE_HASH %append_to_trie_data // storage root + PUSH 0 %append_to_trie_data // storage root pointer PUSH @EMPTY_STRING_HASH %append_to_trie_data // code hash // stack: addr, new_account_ptr, retdest %addr_to_state_key diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index d9ea7d2c..d0052415 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -15,7 +15,7 @@ use crate::generation::prover_input::ProverInputFn; use crate::generation::state::GenerationState; use crate::generation::GenerationInputs; use crate::memory::segments::Segment; -use crate::witness::memory::{MemoryContextState, MemorySegmentState, MemoryState}; +use crate::witness::memory::{MemoryAddress, MemoryContextState, MemorySegmentState, MemoryState}; use crate::witness::util::stack_peek; type F = GoldilocksField; @@ -25,22 +25,11 @@ const DEFAULT_HALT_OFFSET: usize = 0xdeadbeef; impl MemoryState { fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 { - let value = self.contexts[context].segments[segment as usize].get(offset); - assert!( - value.bits() <= segment.bit_range(), - "Value read from memory exceeds expected range of {:?} segment", - segment - ); - value + self.get(MemoryAddress::new(context, segment, offset)) } fn mstore_general(&mut self, context: usize, segment: Segment, offset: usize, value: U256) { - assert!( - value.bits() <= segment.bit_range(), - "Value written to memory exceeds expected range of {:?} segment", - segment - ); - self.contexts[context].segments[segment as usize].set(offset, value) + self.set(MemoryAddress::new(context, segment, offset), value); } } @@ -735,13 +724,6 @@ impl<'a> Interpreter<'a> { let segment = Segment::all()[self.pop().as_usize()]; let offset = self.pop().as_usize(); let value = self.pop(); - assert!( - value.bits() <= segment.bit_range(), - "Value {} exceeds {:?} range of {} bits", - value, - segment, - segment.bit_range() - ); self.generation_state .memory .mstore_general(context, segment, offset, value); diff --git a/evm/src/witness/memory.rs b/evm/src/witness/memory.rs index 967c1bf1..578b6f6c 100644 --- a/evm/src/witness/memory.rs +++ b/evm/src/witness/memory.rs @@ -11,7 +11,6 @@ pub enum MemoryChannel { use MemoryChannel::{Code, GeneralPurpose}; use crate::memory::segments::Segment; -use crate::util::u256_saturating_cast_usize; impl MemoryChannel { pub fn index(&self) -> usize { @@ -42,10 +41,17 @@ impl MemoryAddress { } pub(crate) fn new_u256s(context: U256, segment: U256, virt: U256) -> Self { + assert!(context.bits() <= 32, "context too large: {}", context); + assert!( + segment < Segment::COUNT.into(), + "segment too large: {}", + segment + ); + assert!(virt.bits() <= 32, "virt too large: {}", virt); Self { - context: u256_saturating_cast_usize(context), - segment: u256_saturating_cast_usize(segment), - virt: u256_saturating_cast_usize(virt), + context: context.as_usize(), + segment: segment.as_usize(), + virt: virt.as_usize(), } } @@ -136,10 +142,27 @@ impl MemoryState { } pub fn get(&self, address: MemoryAddress) -> U256 { - self.contexts[address.context].segments[address.segment].get(address.virt) + let segment = Segment::all()[address.segment]; + let val = self.contexts[address.context].segments[address.segment].get(address.virt); + assert!( + val.bits() <= segment.bit_range(), + "Value {} exceeds {:?} range of {} bits", + val, + segment, + segment.bit_range() + ); + val } pub fn set(&mut self, address: MemoryAddress, val: U256) { + let segment = Segment::all()[address.segment]; + assert!( + val.bits() <= segment.bit_range(), + "Value {} exceeds {:?} range of {} bits", + val, + segment, + segment.bit_range() + ); self.contexts[address.context].segments[address.segment].set(address.virt, val); } } diff --git a/evm/src/witness/operation.rs b/evm/src/witness/operation.rs index d58ad186..5c00b9a5 100644 --- a/evm/src/witness/operation.rs +++ b/evm/src/witness/operation.rs @@ -190,11 +190,8 @@ pub(crate) fn generate_jump( state.traces.push_memory(log_in0); state.traces.push_cpu(row); + // TODO: First check if it's a valid JUMPDEST state.registers.program_counter = u256_saturating_cast_usize(dst); - log::debug!( - "Jumping to {}", - KERNEL.offset_name(state.registers.program_counter) - ); // TODO: Set other cols like input0_upper_sum_inv. Ok(()) } @@ -211,12 +208,8 @@ pub(crate) fn generate_jumpi( state.registers.program_counter = if cond.is_zero() { state.registers.program_counter + 1 } else { - let dst_usize = u256_saturating_cast_usize(dst); - log::debug!( - "Jumping to {}", - KERNEL.offset_name(state.registers.program_counter) - ); - dst_usize + // TODO: First check if it's a valid JUMPDEST + u256_saturating_cast_usize(dst) }; // TODO: Set other cols like input0_upper_sum_inv. Ok(()) diff --git a/evm/tests/transfer_to_new_addr.rs b/evm/tests/transfer_to_new_addr.rs index 67e9aefc..88d129a3 100644 --- a/evm/tests/transfer_to_new_addr.rs +++ b/evm/tests/transfer_to_new_addr.rs @@ -107,8 +107,8 @@ fn test_simple_transfer() -> anyhow::Result<()> { } fn eth_to_wei(eth: U256) -> U256 { - // 1 ether = 2^18 wei. - eth << 18 + // 1 ether = 10^18 wei. + eth * U256::from(10).pow(18.into()) } fn init_logger() {